diff --git a/.circleci/config.yml b/.circleci/config.yml index 1784ba1ea19e89810a83d939c69d4199c39573c5..61e508e4d713f193edc10668849548a039c39b58 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,6 +25,13 @@ jobs: - run: name: Add i386 arch command: dpkg --add-architecture i386 + - run: + name: Add STJr PPA + command: | + apt-get -qq update + apt-get -qq -y install dirmngr + apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0B1702D71499D9C25F986507F240F4449D3B0EC6 + echo "deb http://ppa.launchpad.net/stjr/srb2/ubuntu trusty main" >> /etc/apt/sources.list - run: name: Update APT listing command: apt-get -qq update @@ -36,7 +43,8 @@ jobs: - v1-SRB2-APT - run: name: Install SDK - command: apt-get -qq -y --no-install-recommends install git build-essential nasm libpng-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 gettext ccache wget gcc-multilib upx openssh-client + command: apt-get -qq -y --no-install-recommends install git build-essential nasm libpng-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 libopenmpt-dev:i386 gettext ccache wget gcc-multilib upx openssh-client + - save_cache: key: v1-SRB2-APT paths: @@ -63,4 +71,4 @@ jobs: - save_cache: key: v1-SRB2-{{ .Branch }}-{{ checksum "objs/Linux/SDL/Release/depend.dep" }} paths: - - /root/.ccache + - /root/.ccache \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 6d2e8cddfc1d55810123c5da2a083197dc2cec9f..f2ed43000addf70ea07416fad3d5281472eec927 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,11 +18,14 @@ matrix: - os: linux addons: apt: + sources: + - sourceline: 'ppa:stjr/srb2' packages: - libsdl2-mixer-dev - libpng-dev - libgl1-mesa-dev - libgme-dev + - libopenmpt-dev - p7zip-full - gcc-4.4 compiler: gcc-4.4 @@ -32,11 +35,14 @@ matrix: - os: linux addons: apt: + sources: + - sourceline: 'ppa:stjr/srb2' packages: - libsdl2-mixer-dev - libpng-dev - libgl1-mesa-dev - libgme-dev + - libopenmpt-dev - p7zip-full - gcc-4.6 compiler: gcc-4.6 @@ -46,11 +52,14 @@ matrix: - os: linux addons: apt: + sources: + - sourceline: 'ppa:stjr/srb2' packages: - libsdl2-mixer-dev - libpng-dev - libgl1-mesa-dev - libgme-dev + - libopenmpt-dev - p7zip-full - gcc-4.7 compiler: gcc-4.7 @@ -67,11 +76,13 @@ matrix: apt: sources: - ubuntu-toolchain-r-test + - sourceline: 'ppa:stjr/srb2' packages: - libsdl2-mixer-dev - libpng-dev - libgl1-mesa-dev - libgme-dev + - libopenmpt-dev - p7zip-full - gcc-4.8 compiler: gcc-4.8 @@ -83,11 +94,13 @@ matrix: apt: sources: - ubuntu-toolchain-r-test + - sourceline: 'ppa:stjr/srb2' packages: - libsdl2-mixer-dev - libpng-dev - libgl1-mesa-dev - libgme-dev + - libopenmpt-dev - p7zip-full - gcc-7 compiler: gcc-7 @@ -99,11 +112,13 @@ matrix: apt: sources: - ubuntu-toolchain-r-test + - sourceline: 'ppa:stjr/srb2' packages: - libsdl2-mixer-dev - libpng-dev - libgl1-mesa-dev - libgme-dev + - libopenmpt-dev - p7zip-full - gcc-8 compiler: gcc-8 @@ -119,11 +134,13 @@ matrix: apt: sources: - llvm-toolchain-precise-3.5 + - sourceline: 'ppa:stjr/srb2' packages: - libsdl2-mixer-dev - libpng-dev - libgl1-mesa-dev - libgme-dev + - libopenmpt-dev - p7zip-full - clang-3.5 compiler: clang-3.5 @@ -135,11 +152,13 @@ matrix: sources: - llvm-toolchain-precise-3.6 - ubuntu-toolchain-r-test + - sourceline: 'ppa:stjr/srb2' packages: - libsdl2-mixer-dev - libpng-dev - libgl1-mesa-dev - libgme-dev + - libopenmpt-dev - p7zip-full - clang-3.6 compiler: clang-3.6 @@ -151,11 +170,13 @@ matrix: sources: - llvm-toolchain-precise-3.7 - ubuntu-toolchain-r-test + - sourceline: 'ppa:stjr/srb2' packages: - libsdl2-mixer-dev - libpng-dev - libgl1-mesa-dev - libgme-dev + - libopenmpt-dev - p7zip-full - clang-3.7 compiler: clang-3.7 @@ -167,11 +188,13 @@ matrix: sources: - llvm-toolchain-precise-3.8 - ubuntu-toolchain-r-test + - sourceline: 'ppa:stjr/srb2' packages: - libsdl2-mixer-dev - libpng-dev - libgl1-mesa-dev - libgme-dev + - libopenmpt-dev - p7zip-full - clang-3.8 compiler: clang-3.8 @@ -183,11 +206,13 @@ matrix: sources: - llvm-toolchain-precise-3.9 - ubuntu-toolchain-r-test + - sourceline: 'ppa:stjr/srb2' packages: - libsdl2-mixer-dev - libpng-dev - libgl1-mesa-dev - libgme-dev + - libopenmpt-dev - p7zip-full - clang-3.9 compiler: clang-3.9 @@ -199,11 +224,13 @@ matrix: # sources: # - llvm-toolchain-precise-4.0 # - ubuntu-toolchain-r-test +# - sourceline: 'ppa:stjr/srb2' # packages: # - libsdl2-mixer-dev # - libpng-dev # - libgl1-mesa-dev # - libgme-dev +# - libopenmpt-dev # - p7zip-full # - clang-4.0 # compiler: clang-4.0 @@ -215,11 +242,13 @@ matrix: # sources: # - llvm-toolchain-precise-5.0 # - ubuntu-toolchain-r-test +# - sourceline: 'ppa:stjr/srb2' # packages: # - libsdl2-mixer-dev # - libpng-dev # - libgl1-mesa-dev # - libgme-dev +# - libopenmpt-dev # - p7zip-full # - clang-5.0 # compiler: clang-5.0 @@ -561,12 +590,15 @@ cache: addons: apt: + sources: + - sourceline: 'ppa:stjr/srb2' packages: - libsdl2-mixer-dev - libpng-dev - libgl1-mesa-dev - libgme-dev - zlib1g-dev + - libopenmpt-dev - p7zip-full homebrew: taps: @@ -575,6 +607,7 @@ addons: - sdl2_mixer - game-music-emu - p7zip + - libopenmpt - cmake update: true diff --git a/README.md b/README.md index 7d92ab303fe06f475738b63b66bbb041f81bdbbb..8a5ca1a1ff0193df4aeeb9d59f5b38ae65869458 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ - SDL2-Mixer (Linux/OS X only) - libupnp (Linux/OS X only) - libgme (Linux/OS X only) +- libopenmpt (Linux/OS X only) ## Compiling diff --git a/bin/DC/.gitignore b/bin/DC/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/DC/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/Mingw/Release/.gitignore b/bin/Mingw/Release/.gitignore index 834f313e3eae612617885430c8071e6e41483d88..3458ff7648f27c14076ff2aee101446a323f5a04 100644 --- a/bin/Mingw/Release/.gitignore +++ b/bin/Mingw/Release/.gitignore @@ -1,3 +1,4 @@ *.exe *.mo r_opengl.dll +*.bat diff --git a/bin/PS3/Debug/.gitignore b/bin/PS3/Debug/.gitignore deleted file mode 100644 index c4dcd19e5bb9dda4a40bac1684e0c0979543e53f..0000000000000000000000000000000000000000 --- a/bin/PS3/Debug/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/*.elf -/*.self -/*.pkg -/*.BIN -/pkg diff --git a/bin/PS3/Release/.gitignore b/bin/PS3/Release/.gitignore deleted file mode 100644 index c4dcd19e5bb9dda4a40bac1684e0c0979543e53f..0000000000000000000000000000000000000000 --- a/bin/PS3/Release/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/*.elf -/*.self -/*.pkg -/*.BIN -/pkg diff --git a/bin/PSP/Release/.gitignore b/bin/PSP/Release/.gitignore deleted file mode 100644 index 98d08e695f8a77d0e857b148c94b9e6629de5e54..0000000000000000000000000000000000000000 --- a/bin/PSP/Release/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/EBOOT.PBP -/PARAM.SFO -/SRB2PSP.PBP -/SRB2PSP.elf diff --git a/bin/Wii/Debug/.gitignore b/bin/Wii/Debug/.gitignore deleted file mode 100644 index 200eea51f36e6a94c21258089396b2db20725c8d..0000000000000000000000000000000000000000 --- a/bin/Wii/Debug/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/*.elf -/*.dol -/apps diff --git a/bin/Wii/Release/.gitignore b/bin/Wii/Release/.gitignore deleted file mode 100644 index 200eea51f36e6a94c21258089396b2db20725c8d..0000000000000000000000000000000000000000 --- a/bin/Wii/Release/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/*.elf -/*.dol -/apps diff --git a/bin/WinCE/ARMV4Dbg/.gitignore b/bin/WinCE/ARMV4Dbg/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/ARMV4Dbg/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/ARMV4IDbg/.gitignore b/bin/WinCE/ARMV4IDbg/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/ARMV4IDbg/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/ARMV4IRel/.gitignore b/bin/WinCE/ARMV4IRel/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/ARMV4IRel/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/ARMV4Rel/.gitignore b/bin/WinCE/ARMV4Rel/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/ARMV4Rel/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/ARMV4TDbg/.gitignore b/bin/WinCE/ARMV4TDbg/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/ARMV4TDbg/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/ARMV4TRel/.gitignore b/bin/WinCE/ARMV4TRel/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/ARMV4TRel/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPS16Dbg/.gitignore b/bin/WinCE/MIPS16Dbg/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/MIPS16Dbg/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPS16Rel/.gitignore b/bin/WinCE/MIPS16Rel/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/MIPS16Rel/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPSIIDbg/.gitignore b/bin/WinCE/MIPSIIDbg/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/MIPSIIDbg/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPSIIRel/.gitignore b/bin/WinCE/MIPSIIRel/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/MIPSIIRel/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPSII_FPDbg/.gitignore b/bin/WinCE/MIPSII_FPDbg/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/MIPSII_FPDbg/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPSII_FPRel/.gitignore b/bin/WinCE/MIPSII_FPRel/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/MIPSII_FPRel/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPSIVDbg/.gitignore b/bin/WinCE/MIPSIVDbg/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/MIPSIVDbg/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPSIVRel/.gitignore b/bin/WinCE/MIPSIVRel/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/MIPSIVRel/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPSIV_FPDbg/.gitignore b/bin/WinCE/MIPSIV_FPDbg/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/MIPSIV_FPDbg/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPSIV_FPRel/.gitignore b/bin/WinCE/MIPSIV_FPRel/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/MIPSIV_FPRel/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/Release/.gitignore b/bin/WinCE/Release/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/SH3Dbg/.gitignore b/bin/WinCE/SH3Dbg/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/SH3Dbg/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/SH3Rel/.gitignore b/bin/WinCE/SH3Rel/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/SH3Rel/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/SH4Dbg/.gitignore b/bin/WinCE/SH4Dbg/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/SH4Dbg/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/SH4Rel/.gitignore b/bin/WinCE/SH4Rel/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/SH4Rel/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/X86Dbg/.gitignore b/bin/WinCE/X86Dbg/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/X86Dbg/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/X86Rel/.gitignore b/bin/WinCE/X86Rel/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/X86Rel/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/emulatorDbg/.gitignore b/bin/WinCE/emulatorDbg/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/emulatorDbg/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/WinCE/emulatorRel/.gitignore b/bin/WinCE/emulatorRel/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/bin/WinCE/emulatorRel/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/nds/Debug/.gitignore b/bin/nds/Debug/.gitignore deleted file mode 100644 index 9bfc4a51d72ddd27e96051872491fc380c080f22..0000000000000000000000000000000000000000 --- a/bin/nds/Debug/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.arm9 -*.elf* -*.nds diff --git a/bin/nds/Release/.gitignore b/bin/nds/Release/.gitignore deleted file mode 100644 index 9bfc4a51d72ddd27e96051872491fc380c080f22..0000000000000000000000000000000000000000 --- a/bin/nds/Release/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.arm9 -*.elf* -*.nds diff --git a/cmake/Modules/FindOPENMPT.cmake b/cmake/Modules/FindOPENMPT.cmake new file mode 100644 index 0000000000000000000000000000000000000000..2d334b6f04e3b262c200a0ea0f4bc0b895940879 --- /dev/null +++ b/cmake/Modules/FindOPENMPT.cmake @@ -0,0 +1,23 @@ +include(LibFindMacros) + +libfind_pkg_check_modules(OPENMPT_PKGCONF OPENMPT) + +find_path(OPENMPT_INCLUDE_DIR + NAMES libopenmpt.h + PATHS + ${OPENMPT_PKGCONF_INCLUDE_DIRS} + "/usr/include/libopenmpt" + "/usr/local/include/libopenmpt" +) + +find_library(OPENMPT_LIBRARY + NAMES openmpt + PATHS + ${OPENMPT_PKGCONF_LIBRARY_DIRS} + "/usr/lib" + "/usr/local/lib" +) + +set(OPENMPT_PROCESS_INCLUDES OPENMPT_INCLUDE_DIR) +set(OPENMPT_PROCESS_LIBS OPENMPT_LIBRARY) +libfind_process(OPENMPT) \ No newline at end of file diff --git a/libs/DLL-README.txt b/libs/DLL-README.txt index 058ec06857776433f042da0b888e1f7efa24a259..45680c535667c5b7a32bc4f686991742efa6a551 100644 --- a/libs/DLL-README.txt +++ b/libs/DLL-README.txt @@ -7,6 +7,7 @@ Here are the required DLLs, per build. For each architecture, copy all the binar * libs\dll-binaries\[i686/x86_64] * libs\SDL2\[i686/x86_64]...\bin * libs\SDL2_mixer\[i686/x86_64]...\bin +* libs\libopenmpt\[x86/x86_64]...\bin\mingw and don't forget to build r_opengl.dll for srb2dd. @@ -17,6 +18,7 @@ and don't forget to build r_opengl.dll for srb2dd. * libs\dll-binaries\i686\mgwhelp.dll (depend for exchndl.dll) * libs\SDL2\i686-w64-mingw32\bin\SDL2.dll * libs\SDL2_mixer\i686-w64-mingw32\bin\*.dll (get everything) +* libs\libopenmpt\x86\bin\mingw\libopenmpt.dll ## srb2win, 64-bit @@ -25,6 +27,7 @@ and don't forget to build r_opengl.dll for srb2dd. * libs\dll-binaries\x86_64\mgwhelp.dll (depend for exchndl.dll) * libs\SDL2\x86_64-w64-mingw32\bin\SDL2.dll * libs\SDL2_mixer\x86_64-w64-mingw32\bin\*.dll (get everything) +* libs\libopenmpt\x86_64\bin\mingw\libopenmpt.dll ## srb2dd, 32-bit diff --git a/libs/libopenmpt.props b/libs/libopenmpt.props new file mode 100644 index 0000000000000000000000000000000000000000..8825907b63e33d145b1bf5f605e1b8f80c9bb10d --- /dev/null +++ b/libs/libopenmpt.props @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <IncludePath>$(SolutionDir)libs\libopenmpt\inc;$(IncludePath)</IncludePath> + <LibraryPath Condition="'$(Platform)' == 'Win32'">$(SolutionDir)libs\libopenmpt\lib\x86;$(LibraryPath)</LibraryPath> + <LibraryPath Condition="'$(Platform)' == 'x64'">$(SolutionDir)libs\libopenmpt\lib\x86_64;$(LibraryPath)</LibraryPath> + </PropertyGroup> + <ItemDefinitionGroup> + <Link> + <AdditionalDependencies>libopenmpt.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup /> +</Project> \ No newline at end of file diff --git a/libs/libopenmpt/LICENSE.txt b/libs/libopenmpt/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..e0f012166dcc5c0ec131866434bc7497eb318a26 --- /dev/null +++ b/libs/libopenmpt/LICENSE.txt @@ -0,0 +1,26 @@ +Copyright (c) 2004-2019, OpenMPT contributors +Copyright (c) 1997-2003, Olivier Lapicque +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the OpenMPT project nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/libs/libopenmpt/Licenses/License.Vorbis.txt b/libs/libopenmpt/Licenses/License.Vorbis.txt new file mode 100644 index 0000000000000000000000000000000000000000..153b926a152a6bdd3230f64c0583a146d797f52e --- /dev/null +++ b/libs/libopenmpt/Licenses/License.Vorbis.txt @@ -0,0 +1,28 @@ +Copyright (c) 2002-2018 Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libs/libopenmpt/Licenses/License.mpg123.Authors.txt b/libs/libopenmpt/Licenses/License.mpg123.Authors.txt new file mode 100644 index 0000000000000000000000000000000000000000..c1eac976db60f180058fddedc83992f0b88ab14d --- /dev/null +++ b/libs/libopenmpt/Licenses/License.mpg123.Authors.txt @@ -0,0 +1,175 @@ +This is an attempt to give credit to the people who contributed in some way to the mpg123 project. +There are names and email addresses listed. Please use these addresses only to contact contributors with some question about their mpg123 contribution. +You are explicitly not allowed to send them unwanted business offers or to question the quality of their sex life. +-------------------- + +Being on the list of contributing authors not necessarily means that there +is significant copyright in parts of the source code. There are obviously +contributions of differing complexity. I try to mention people who motivated +changes at least by suggesting some definite code changes, even if their +code did not enter the mpg123 source verbatim. Trivial changes like pointing +out ovbious syntax errors that make compilers cry do not land here. + +-------------------- + +Current maintainers with various sorts of contributions: + Thomas Orgis <thomas@orgis.org> + Patrick Dehne <patrick@steidle.net> + Jonathan Yong <10walls@gmail.com> + Taihei Momma <tmkk@mac.com> + +Co-initiator of the revived mpg123 project, but not that involved anymore: + Nicholas J Humfrey <njh@ecs.soton.ac.uk> + +Special thanks go to Taihei, the person who keeps the assembly optimisations alive +and takes care of portability to OSX/iOS platforms. + +Generic address pointing to the current maintainer (hopefully still works in future in case maintainership will change again): <maintainer@mpg123.org> + +The creator: Michael Hipp (email: hippm@informatik.uni-tuebingen.de - please bother maintainers first) + +Contributions/ideas Thomas Orgis era (includes backports from mhipp trunk): + +Won-Kyu Park <wkpark@gmail.com>: patch to get rid of asm textrels (x86 PIC) +Michael Weiser <michaelweiser@users.sf.net>: update of coreaudio output to AudioComponents API +Bent Bisballe Nyeng <bbn@dynastrom.com>: patch for MPG123_NO_PEEK_END and MPG123_FORCE_SEEKABLE +Eric S. Raymond <esr@thyrsus.com>: man page fixes +Tobias Weber <tobiw@suprafluid.com>: patch for --disable-equalizer +Hans de Goede <j.w.r.degoede@gmail.com>: patch to skip APE tags +Stephan Vedder <stephan.vedder@gmail.com>: MSVC++ 2013 port update +Rajeev V. Pillai <rajeevvp@users.sf.net>: pointing out/patching issues in HTTP code and behaviour of mpg123 remote/terminal control +Jarno Lehtinen <lehtinen@sci.fi>: tinyalsa output +Anthony Wells <borgboyone@yahoo.com>: initial version of ID3v2 APIC patch +David Wohlferd <limegreensocks@yahoo.com>: Win32 WaveOut buffer destructor fix. +Mike Gorchak <mike.gorchak.qnx@gmail.com>: QNX native audio output (QSA) +Dan McGee <dpmcgee@gmail.com>: various patches (also for test suite) +Jonathan Yong (jon_y) <10walls@gmail.com>: win32 hacking, win32 wasapi audio. +Malcolm Boczek <MBoczek@terraindustries.com>: Common language runtime wrapper +Elbert Pol (TeLLie) <elbert.pol@gmail.com>: OS/2 port fixup +Jeroen Valkonet <jvalkon@xs4all.nl>: motivate pitch control, suggestive patch for pitch command in generic control interface +Andy Hefner <ahefner@gmail.com>: patch for that second UTF16 issue +Taihei Monma <tmkk@mac.com>: A whole lot of new/improved assembler code, including Altivec! +Christian Weisgerber <naddy@openbsd.org>, Brad Smith: sndio output +Patrick Dehne (P4tr3ck) <patrick@steidle.net>: more MSVC++ porting, patch to handle missing bit reservoirs +Thorsten Glaser <tg@mirbsd.de>: icy2utf8, suggest utf8 locale stuff +Dan Smith <dan@algenta.com>: ABI fixes for ensuring stack alignment (esp. for MinGW-built DLL with MSVC) +Michael Ryzhykh <mclroy@gmail.com>: mpg123.spec.in +Stefan Lenselink <Stefan@lenselink.org>: initial aRts output +Sergej Kvachonok <ravenexp@gmail.com>: win32 audio rewrite +Winston: SunOS-4.1.4/gcc-2.7.0 testing and suggestions for fixes (legacy Makefile, integer type headers) +Mika Tiainen: pointing out the fix for the UTF to ASCII filtering of tags to actually work +Nick Kurshev <nickols_k@mail.ru>: extended 3dnow (from mplayer) +Zuxy Meng <zuxy.meng@gmail.com>: SSE (from mplayer) +Honza <cundrak@quick.cz>: idea and prototype patch for ICY meta data support +Petr Baudis <pasky@ucw.cz>: patches: term sigcont, id3 display unicode fallback and condensed output +Petr Salinger <Petr.Salinger@seznam.cz>: i486 enhancement +mpdavig@users.sourceforge.net: linux-ppc-nas Makefile.legacy entry +Adrian Bacon <adrian.bacon@xs4all.nl>: patched decode_i586_dither (noise shaped float/int rounding) +Cool Feet Audio project <nutcase@dtfm.org>: realtime equalizer control +Steve Grundell <www@grundell.u-net.com>: clean stdout in control mode with stdout decoding +Romain Dolbeau <romain@dolbeau.org>: Altivec support (taken from mplayer) +higway <higway@mednet.md>: MMX Patch +Clemens Ladisch <clemens@ladisch.de>: ALSA 0.9/1.0 support + +Debian Daniel Kobras <kobras@debian.org> era: + +Steve Kemp <skx@debian.org> +Dan Olson <theoddone33@icculus.org> +Syuuhei Kashiyama <squash@mb.kcom.ne.jp> +Rupert Levene <rupert.debian@hotpop.com> +Andreas Dilger <adilger@turbolinux.com> +Erik B. Andersen <andersee@debian.org> +Chris Butler <chrisb@debian.org> +Martin Sjogren <md9ms@mdstud.chalmers.se> +Chet Hosey <chosey@budapress.com> +Roland Rosenfeld <roland@spinnaker.de> + + +Debian Colin Watson <cjwatson@debian.org> era: + +Helge Deller <deller@gmx.de> +Chet Hosey <chosey@budapress.com> +Christopher C. Chimelis <chris@debian.org> +Roland Rosenfeld <roland@spinnaker.de> +Marcelo E. Magallon <mmagallo@debian.org> + + +Initial Debianers: + +Tommi Virtanen <tv@debian.org> +Paul Haggart <phaggart@debian.org> + + +Contributions/ideas Michael Hipp era: + +Mikko Tommila: DCT9 +Oliver Fromme <oliver.fromme@heim3.tu-clausthal.de> +MPEG Software Simulation Group: reference decoder package +Tobias Bading: idea for DCT64 in subband synthesis from maplay package +Jeff Tsay and Mikko Tommila: MDCT36 from maplay package +Philipp Knirsch <phil@mpik-tueb.mpg.de>: DCT36/manual unroll idea +Thomas Woerner: SGI Audio +Damien Clermonte: HP-UX audio fixes +Niclas Lindstrom <nil@wineasy.se>: OS2 port +Stefan Bieschewski <stb@acm.org>: Pentium optimizations, decode_i586.s +Martin Denn <mdenn@unix-ag.uni-kl.de>: NAS port +Niklas Beisert <nbeisert@physik.tu-muenchen.de>: MPEG 2.5 tables +<mycroft@NetBSD.ORG> and <augustss@cs.chalmers.se>: NetBSD Patch(es) +Kevin Brintnall <kbrint@visi.com>: BSD patch +Tony Million: win32 port +Steven Tiger Lang: advanced shuffle +Eric B. Mitchell: esd port +Ryan R. Prosser <prosser@geocities.com>: esd port for Solaris +Andreas Neuhaus: initial generic control interface + +(additionally fetched from changelog:) + +Ralf Hildebrandt <R.Hildebrandt@TU-BS.DE>: audio_alib changes +<sms@moe.2bsd.com>: BSDOS 4.0 with gcc added to Makefile +Bertrand Petit <elrond@phoe.netdev.net>: frontend changes +Erik Mouw <J.A.K.Mouw@its.tudelft.nl>: SGI audio fix for non RAD machines +Daniel O'Connor <darius@guppy.dons.net.au>: freebsd-esd make-entry +D. Skarda <0rfelyus@atrey.karlin.mff.cuni.cz>: enhanced head_check +Wilson, Jeff D <jeff.wilson@wilcom.com>: xterm-title +Robert Bihlmeyer <robbe@orcus.priv.at>: esd changes +Hannu Napari's <Hannu.Napari@hut.fi>: SGI audio patches +<Juergen.Schoew@unix-ag.uni-siegen.de>: native AIX support +<psst@euskalnet.net>: playlist patch +Gilles Zunino <Gilles.Zunino@hei.fupl.asso.fr>: SGI audio patches +Matthew Parslow <roy@alpha.alphalink.com.au>: esdserver patch +<dlux@dlux.sch.bme.hu>: equalizer patch (equalfile setting) +Ducroquet Erwan <ducroque@ufr-info-p7.ibp.fr>: HPUX/ALib support +Shane Wegner <shane@CM.NU>: genrepatch +Samuel Audet <guardia@step.polymtl.ca>: wav-File patch +"J. Dean Brederson" <jdb@cs.utah.edu>: SGI-RAD support +Chou Ye-chi <is84002@cis.nctu.edu.tw>: sajberplay/FreeBSD patch +Fabrice Bellard <bellard@email.enst.fr>: 486 optimizations +A. Hermansen <ahermans@vf.telia.no> and J. Kysela <perex@jcu.cz>: ALSA output +KIMURA Takuhiro <kim@hannah.ipc.miyakyo-u.ac.jp>: K6-3DNow +Petr Stehlik <stehlik@cas3.zlin.vutbr.cz>: MINT +Andy <andy@snoogie.demon.co.uk>: float2int speed up proposal +Brian Foutz <foutz@anise.ee.cornell.edu>: TK3Play +Thomas Niederreiter <tn@tarantel.rz.fh-muenchen.de>: RIFF header fix +Stefan Gybas <cab@studbox.uni-stuttgart.de>: m68k patch +Grant Erickson <eric0139@tc.umn.edu>: Linux PPC patch +Peter Berger <peterb@hoopoe.psc.edu>: BSDi patch +Henrik P Johnson <king@one.se>: HTTP auth +Steven Tiger Lang <tiger@tyger.org>: advanced shuffle +"Brian J. Swetland" <swetland@uiuc.edu>: front-end (remote) patch +<leo@zycad.com> +Tillmann Steinbrecher <tst@gmx.de>: shuffle patch +M.Stekelenburg <m.stekelenburg@student.utwente.nl>: i386-getbits +Antti Andreimann <anttix@cyberix.edu.ee>: outburst patch +Hur TaeSung <saturn@arari.snu.ac.kr>: 'http accept' patch + +(from post-0.59 changes that yet have to go into new trunk:) + +Hans Schwengeler <schweng@astro.unibas.ch>: audio_dec additions +Wojciech Bara�ski's Mp3Play (check the tools folder): Mp3Play frontend +Daniel Koukola: audio_oss.c patch +Munechika SUMIKAWA <sumikawa@ebina.hitachi.co.jp>: IPv6 +TEMNOTA <temnota@kmv.ru>: HTTP,FTP patch/playlist fix +Peter Surda <shurdeek@panorama.sth.ac.at>: VBR patch +Ben <ben@blaukopf.com>: ARM startup time improvements +Dave MacKenzie <djm@pix.net>: init_output() patch +pasky's <pasky@ju.cz>: close-on-stop patch diff --git a/libs/libopenmpt/Licenses/License.mpg123.txt b/libs/libopenmpt/Licenses/License.mpg123.txt new file mode 100644 index 0000000000000000000000000000000000000000..d7bb85fc3be6d8a00bc8e875569d30deb9f0dceb --- /dev/null +++ b/libs/libopenmpt/Licenses/License.mpg123.txt @@ -0,0 +1,772 @@ +This is the file that contains the terms of use, copying, etc. for the mpg123 distribution package. + +Main message, to include in "About ..." boxes, etc: + + Copyright (c) 1995-2013 by Michael Hipp and others, + free software under the terms of the LGPL v2.1 + +There is an attempt to cover the actual list of authors in the AUTHORS file. +Project maintainer since 2006 is Thomas Orgis and many people have contributed +since the Michael Hipp era, but he stays the initial source and it would +be impractical to count them all individually, so it's "and others". +Source files contain the phrase "the mpg123 project" to the same effect +in their license boilerplate; especially those that were added after +maintainership changed. The person mainly responsible for the first version +is usually named in the phrase "initially written by ...". + +All files in the distribution that don't carry a license note on their own are +licensed under the terms of the LGPL 2.1; exceptions may apply, especially to +files not in the official distribution but in the revision control repository. + +The formal license text follows. + +======================= +1. The LGPL version 2.1 +======================= + + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + +==================== +2. The GPL version 2 +==================== + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/libs/libopenmpt/Licenses/License.ogg.txt b/libs/libopenmpt/Licenses/License.ogg.txt new file mode 100644 index 0000000000000000000000000000000000000000..6111c6c5a6b95057e43d36b7c217b073bf5f9b22 --- /dev/null +++ b/libs/libopenmpt/Licenses/License.ogg.txt @@ -0,0 +1,28 @@ +Copyright (c) 2002, Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libs/libopenmpt/Licenses/License.zlib.txt b/libs/libopenmpt/Licenses/License.zlib.txt new file mode 100644 index 0000000000000000000000000000000000000000..51106de4753292ad59de03de9e634e6814eeb7a2 --- /dev/null +++ b/libs/libopenmpt/Licenses/License.zlib.txt @@ -0,0 +1,115 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.2.11 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and +rfc1952 (gzip format). + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file test/example.c which also tests that +the library is working correctly. Another example is given in the file +test/minigzip.c. The compression library itself is composed of all source +files in the root directory. + +To compile all files and run the test program, follow the instructions given at +the top of Makefile.in. In short "./configure; make test", and if that goes +well, "make install" should work for most flavors of Unix. For Windows, use +one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use +make_vms.com. + +Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant +<info@winimage.com> for the Windows DLL version. The zlib home page is +http://zlib.net/ . Before reporting a problem, please check this site to +verify that you have the latest version of zlib; otherwise get the latest +version and check whether the problem still exists or not. + +PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. + +Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available at +http://marknelson.us/1997/01/01/zlib-engine/ . + +The changes made in version 1.2.11 are documented in the file ChangeLog. + +Unsupported third party contributions are provided in directory contrib/ . + +zlib is available in Java using the java.util.zip package, documented at +http://java.sun.com/developer/technicalArticles/Programming/compression/ . + +A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is available +at CPAN (Comprehensive Perl Archive Network) sites, including +http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . + +A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is +available in Python 1.5 and later versions, see +http://docs.python.org/library/zlib.html . + +zlib is built into tcl: http://wiki.tcl.tk/4610 . + +An experimental package to read and write files in .zip format, written on top +of zlib by Gilles Vollant <info@winimage.com>, is available in the +contrib/minizip directory of zlib. + + +Notes for some targets: + +- For Windows DLL versions, please see win32/DLL_FAQ.txt + +- For 64-bit Irix, deflate.c must be compiled without any optimization. With + -O, one libpng test fails. The test works in 32 bit mode (with the -n32 + compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works + when compiled with cc. + +- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is + necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with + other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS or BEOS. + +- For PalmOs, see http://palmzlib.sourceforge.net/ + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate and + zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; they + are too numerous to cite here. + +Copyright notice: + + (C) 1995-2017 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. diff --git a/libs/libopenmpt/SRB2NOTE-DEBIAN.md b/libs/libopenmpt/SRB2NOTE-DEBIAN.md new file mode 100644 index 0000000000000000000000000000000000000000..7e050d29a648772e6c7bab503db2a10a37320a00 --- /dev/null +++ b/libs/libopenmpt/SRB2NOTE-DEBIAN.md @@ -0,0 +1,90 @@ +# libopenmpt Debian backport info + +Backported libopenmpt 0.4.0 packages are available at ppa:stjr/srb2 +for Ubuntu Disco, Cosmic, Bionic, Xenial, and Trusty as of 2019/01/04. + +Debian Jessie users should use the Trusty package. Later Debian versions +may use Disco or another working version. + +* libopenmpt 0.4.0 source package: http://archive.ubuntu.com/ubuntu/pool/universe/libo/libopenmpt/libopenmpt_0.4.0-1.dsc + +# Backporting from Disco to Cosmic and Bionic + +Cosmic and Bionic require no changes to the source package. They have +the prerequisite `debhelper` and `dpkg-dev` versions, a matching +`automake` version (1.15), as well as G++ > 5. + +Use the `backportpackage` script to automatically tag the package to +Cosmic and Bionic, then upload to PPA: + +``` +sudo apt install ubuntu-dev-tools +export UBUMAIL="John Doe <email@com.com>" # Name and email associated with your PGP sign key +backportpackage -d [cosmic/bionic] -u [path-to-ppa] --key=[key-fingerprint] http://archive.ubuntu.com/ubuntu/pool/universe/libo/libopenmpt/libopenmpt_0.4.0-1.dsc +``` + +# Backporting from Disco to Xenial + +Download the package: + +``` +dget http://archive.ubuntu.com/ubuntu/pool/universe/libo/libopenmpt/libopenmpt_0.4.0-1.dsc +``` + +Xenial has an earlier `debhelper` version, but the rest of the prerequisites +are available. + +The required changes (see patch `debian/libopenmpt-0.4.0-xenial-backport.diff` in this directory): + +* `debian/control` + * Add `automake` to Build-Depends + * Change `debhelper` version to `(>= 9.0~)` +* `debian/compat` + * Change to `10` + +Then run these commands: + +``` +dch -i # Edit the changelog; make sure the Name and email match the PGP sign key and that the changelog targets xenial +debuild -s -d -k0x[key-fingerprint] # Build the updated package +dput [path-to-ppa] [path-to-changes-file] # Upload to PPA +``` + +# Backporting from Disco to Trusty + +Download the package: + +``` +dget http://archive.ubuntu.com/ubuntu/pool/universe/libo/libopenmpt/libopenmpt_0.4.0-1.dsc +``` + +Trusty requires more changes because it uses G++ 4.8 whereas the source +package expects G++ >= 5. Automake is an earlier version as well -- +1.14 vs 1.15 -- so `autoreconf` needs to be run at build time. + +The required changes (see patch `debian/libopenmpt-0.4.0-trusty-backport.diff` in this directory): + +* `debian/control` + * Add `automake` and `libtool` to Build-Depends + * Change `debhelper` version to `(>= 9.0~)` + * Change `dpkg-dev` version to `(>= 1.17.0)` +* `debian/compat` + * Change to `10` +* `debian/rules` + * Under `override_dh_auto_configure`, input this line as the first command: + `autoreconf --force --install` + * This re-configures the package for Automake 1.14 +* `debian/libopenmpt-modplug1.symbols` and `debian/libopenmpt0.symbols` + * Delete these files + * The C++ ABI for G++ 4.8 is incompatible with G++ >= 5, so the + generated symbols will be different than the expected symbols + in the `*.symbols` files. Deleting these files will skip the + symbol check. + +Then run these commands: + +``` +dch -i # Edit the changelog; make sure the Name and email match the PGP sign key and that the changelog targets trusty +debuild -s -d -k0x[key-fingerprint] # Build the updated package +dput [path-to-ppa] [path-to-changes-file] # Upload to PPA +``` diff --git a/libs/libopenmpt/SRB2NOTE.md b/libs/libopenmpt/SRB2NOTE.md new file mode 100644 index 0000000000000000000000000000000000000000..d664ddd7e49930e69cdf6c81d7981568fb2e3d78 --- /dev/null +++ b/libs/libopenmpt/SRB2NOTE.md @@ -0,0 +1,54 @@ +# libopenmpt mingw-w64 binary info + +Current built version as of 2019/05/23 is 0.4.4+r11531.pkg + +* mingw binaries (.dll): `bin/[x86 or x86_64]/mingw` +* mingw import libraries (.dll.a): `lib/[x86 or x86_64]/mingw` + +# Building libopenmpt with mingw-w64 + +libopenmpt must be built from the Makefile / Android dev package in the +[Downloads page](https://lib.openmpt.org/libopenmpt/download/#all-downloads) + +Use the mingw-w64 distributions from +[SourceForge](https://sourceforge.net/projects/mingw-w64/files/#readme). + +You can download the appropriate 7-zip archive, extract to a folder of +your choice, remove any existing mingw directories from your PATH, +then call `mingw32-make.exe` from its direct location. + +FOR LIBOPENMPT, YOU MUST USE A MINGW PACKAGE THAT SUPPORTS THE POSIX +THREADING MODEL! DO NOT COMPILE WITH A WIN32 THREADING MODEL! + +I use GCC 7.3.0: + +* [x86_64-posix-seh](https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/7.3.0/threads-posix/seh/x86_64-7.3.0-release-posix-seh-rt_v5-rev0.7z) +* [i686-posix-dwarf](https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/7.3.0/threads-posix/dwarf/i686-7.3.0-release-posix-dwarf-rt_v5-rev0.7z) + +## x86 build instructions + +``` +set CFLAGS=-march=pentium -static-libgcc +set CXXFLAGS=-march=pentium -static-libgcc -static-libstdc++ +set LDFLAGS=-Wl,--out-implib,bin/libopenmpt.dll.a -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,-Bdynamic,--no-whole-archive + +cd [libopenmpt-make-src] +[x86-mingw-w64-bin]/mingw32-make.exe CONFIG=mingw64-win32 +``` + +`libopenmpt.dll` and `libopenmpt.dll.a` will be built in the +`bin/` folder. + +## x86_64 build instructions + +``` +set CFLAGS=-march=nocona -static-libgcc +set CXXFLAGS=-march=nocona -static-libgcc -static-libstdc++ +set LDFLAGS=-Wl,--out-implib,bin/libopenmpt.dll.a -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,-Bdynamic,--no-whole-archive + +cd [libopenmpt-make-src] +[x86_64-mingw-w64-bin]/mingw32-make.exe CONFIG=mingw64-win64 +``` + +`libopenmpt.dll` and `libopenmpt.dll.a` will be built in the +`bin/` folder. \ No newline at end of file diff --git a/libs/libopenmpt/bin/x86/libopenmpt.dll b/libs/libopenmpt/bin/x86/libopenmpt.dll new file mode 100644 index 0000000000000000000000000000000000000000..0fc9e7656d5681b59df4a605b5f39ffe59fd55a9 Binary files /dev/null and b/libs/libopenmpt/bin/x86/libopenmpt.dll differ diff --git a/libs/libopenmpt/bin/x86/mingw/libopenmpt.dll b/libs/libopenmpt/bin/x86/mingw/libopenmpt.dll new file mode 100644 index 0000000000000000000000000000000000000000..5fa3642566039530a3ddf633d45617ef9d93f9bd Binary files /dev/null and b/libs/libopenmpt/bin/x86/mingw/libopenmpt.dll differ diff --git a/libs/libopenmpt/bin/x86/openmpt-mpg123.dll b/libs/libopenmpt/bin/x86/openmpt-mpg123.dll new file mode 100644 index 0000000000000000000000000000000000000000..79148a40ef3cef8e0f745ff14d1ccc1ac4aab025 Binary files /dev/null and b/libs/libopenmpt/bin/x86/openmpt-mpg123.dll differ diff --git a/libs/libopenmpt/bin/x86/openmpt-ogg.dll b/libs/libopenmpt/bin/x86/openmpt-ogg.dll new file mode 100644 index 0000000000000000000000000000000000000000..6b5a42e8f1fd11353588880cd36c649993eebe9e Binary files /dev/null and b/libs/libopenmpt/bin/x86/openmpt-ogg.dll differ diff --git a/libs/libopenmpt/bin/x86/openmpt-vorbis.dll b/libs/libopenmpt/bin/x86/openmpt-vorbis.dll new file mode 100644 index 0000000000000000000000000000000000000000..486b30731c234696ad1feb3ca9740eebbd390668 Binary files /dev/null and b/libs/libopenmpt/bin/x86/openmpt-vorbis.dll differ diff --git a/libs/libopenmpt/bin/x86/openmpt-zlib.dll b/libs/libopenmpt/bin/x86/openmpt-zlib.dll new file mode 100644 index 0000000000000000000000000000000000000000..b6e028ab4f31b40c620983e73b76b747f9f3249e Binary files /dev/null and b/libs/libopenmpt/bin/x86/openmpt-zlib.dll differ diff --git a/libs/libopenmpt/bin/x86_64/libopenmpt.dll b/libs/libopenmpt/bin/x86_64/libopenmpt.dll new file mode 100644 index 0000000000000000000000000000000000000000..536492798e9167241fc526d010f6ed25e9d0686e Binary files /dev/null and b/libs/libopenmpt/bin/x86_64/libopenmpt.dll differ diff --git a/libs/libopenmpt/bin/x86_64/mingw/libopenmpt.dll b/libs/libopenmpt/bin/x86_64/mingw/libopenmpt.dll new file mode 100644 index 0000000000000000000000000000000000000000..3f6bea95f72b0a8ee68a41128f8bb700918d568d Binary files /dev/null and b/libs/libopenmpt/bin/x86_64/mingw/libopenmpt.dll differ diff --git a/libs/libopenmpt/bin/x86_64/openmpt-mpg123.dll b/libs/libopenmpt/bin/x86_64/openmpt-mpg123.dll new file mode 100644 index 0000000000000000000000000000000000000000..f96d446f25c61df1368c4219324e3a2bf6138723 Binary files /dev/null and b/libs/libopenmpt/bin/x86_64/openmpt-mpg123.dll differ diff --git a/libs/libopenmpt/bin/x86_64/openmpt-ogg.dll b/libs/libopenmpt/bin/x86_64/openmpt-ogg.dll new file mode 100644 index 0000000000000000000000000000000000000000..3fd9514147973966faf77c7c2e08fb61c3fa4878 Binary files /dev/null and b/libs/libopenmpt/bin/x86_64/openmpt-ogg.dll differ diff --git a/libs/libopenmpt/bin/x86_64/openmpt-vorbis.dll b/libs/libopenmpt/bin/x86_64/openmpt-vorbis.dll new file mode 100644 index 0000000000000000000000000000000000000000..56047c82fbf4ff4eecc148718ed2b9fc1882a9da Binary files /dev/null and b/libs/libopenmpt/bin/x86_64/openmpt-vorbis.dll differ diff --git a/libs/libopenmpt/bin/x86_64/openmpt-zlib.dll b/libs/libopenmpt/bin/x86_64/openmpt-zlib.dll new file mode 100644 index 0000000000000000000000000000000000000000..562d8e6a9e89b933d2ea4ef30ae2d7e500e35c97 Binary files /dev/null and b/libs/libopenmpt/bin/x86_64/openmpt-zlib.dll differ diff --git a/libs/libopenmpt/changelog.md b/libs/libopenmpt/changelog.md new file mode 100644 index 0000000000000000000000000000000000000000..9847be1197908bc6962277f54d7a68f0b7d95a79 --- /dev/null +++ b/libs/libopenmpt/changelog.md @@ -0,0 +1,791 @@ + +Changelog {#changelog} +========= + +For fully detailed change log, please see the source repository directly. This +is just a high-level summary. + +### libopenmpt 0.4.4 (2019-04-07) + + * [**Bug**] Channel VU meters were swapped. + + * Startrekker: Clamp speed to 31 ticks per row. + * MTM: Ignore unused Exy commands on import. Command E5x (Set Finetune) is now + applied correctly. + * MOD: Sample swapping was always enabled since it has been separated from the + ProTracker 1/2 compatibility flag. Now it is always enabled for Amiga-style + modules and otherwise the old heuristic is used again. + + * stb_vorbis: Update to v1.16 (2019-03-05). + +### libopenmpt 0.4.3 (2019-02-11) + + * [**Sec**] Possible crash due to null-pointer access when doing a portamento + from an OPL instrument to an empty instrument note map slot (r11348). + + * [**Bug**] libopenmpt did not compile on Apple platforms in C++17 mode. + + * IT: Various fixes for note-off + instrument number in Old Effects mode. + * MO3: Import IT row highlights as written by MO3 2.4.1.2 or newer. Required + for modules using modern tempo mode. + + * miniz: Update to v2.0.8 (2018-09-19). + * stb_vorbis: Update to v1.15 (2019-02-07). + +### libopenmpt 0.4.2 (2019-01-22) + + * [**Sec**] DSM: Assertion failure during file parsing with debug STLs + (r11209). + * [**Sec**] J2B: Assertion failure during file parsing with debug STLs + (r11216). + + * S3M: Allow volume change of OPL instruments after Note Cut. + +### libopenmpt 0.4.1 (2019-01-06) + + * [**Bug**] Binaries compiled for winold (Windows XP, Vista, 7, for CPUs + without SSE2 support) did not actually work on CPUs without SSE2 support. + * [**Bug**] libmodplug: Public symbols of the C++ API had `visibility=hidden` + set on non-MSVC systems, which made them not publicly accessible. + * [**Bug**] Project files for Windows 10 desktop builds on ARM and ARM64 + (`build/vs2017win10`) were missing from Windows source package. + * [**Bug**] MSVC project files in Windows source package lacked additional + files required to build DLLs. + + * MO3: Apply playback changes based on "ModPlug-made" header flag. + + * minimp3: Update to commit e9df0760e94044caded36a55d70ab4152134adc5 + (2018-12-23). + +### libopenmpt 0.4.0 (2018-12-23) + + * [**New**] libopenmpt now includes emulation of the OPL chip and thus plays + OPL instruments in S3M, C67 and MPTM files. OPL chip emulation volume can be + changed with the new ctl `render.opl.volume_factor`. + * [**New**] libopenmpt now supports CDFM / Composer 670 module files. + * [**New**] Autotools `configure` and plain `Makefile` now honor the variable + `CXXSTDLIB_PCLIBSPRIVATE` which serves the sole purpose of listing the + standard library (or libraries) required for static linking. The contents of + this variable will be put in `libopenmpt.pc` `Libs.private` and used for + nothing else. See \ref libopenmpt_c_staticlinking . + * [**New**] foo_openmpt: foo_openmpt now also works on Windows XP. + * [**New**] libopenmpt Emscripten builds now ship with MP3 support by + default, based on minimp3 by Lion (github.com/lieff). + * [**New**] libopenmpt: New ctl `play.at_end` can be used to change what + happens when the song end is reached: + * "fadeout": Fades the module out for a short while. Subsequent reads + after the fadeout will return 0 rendered frames. This is the default and + identical to the behaviour in previous libopenmpt versions. + * "continue": Returns 0 rendered frames when the song end is reached. + Subsequent reads will continue playing from the song start or loop + start. This can be used for custom loop logic, such as loop + auto-detection and longer fadeouts. + * "stop": Returns 0 rendered frames when the song end is reached. + Subsequent reads will return 0 rendered frames. + * [**New**] Add new metadata fields `"originaltype"` and `"originaltype_long"` + which allow more clearly reflecting what is going on with converted formats + like MO3 and GDM. + * [**New**] `Makefile` `CONFIG=emscripten` now can generate WebAssembly via + the additional option `EMSCRIPTEN_TARGET=wasm`. + * [**New**] Compiling for DOS is now experimentally supported via DJGPP GCC + 7.2 or later. + + * [**Change**] minimp3: Instead of the LGPL-2.1-licensed minimp3 by KeyJ, + libopenmpt now uses the CC0-1.0-licensed minimp3 by Lion (github.com/lieff) + as a fallback if libmpg123 is unavailable. The `USE_MINIMP3` `Makefile` + option is gone and minimp3 will be used automatically in the `Makefile` + build system if libmpg123 is not available. + * [**Change**] openmpt123: openmpt123 now rejects `--output-type` in `--ui` + and `--batch` modes and also rejects `--output` in `--render` mode. These + combinations of options really made no sense and were rather confusing. + * [**Change**] Android NDK build system now uses libc++ (`c++_shared`) instead + of GNU libstdc++ (`gnustl_shared`), as recommended by Android NDK r16b. + * [**Change**] xmp-openmpt: `openmpt-mpg123.dll` is no longer optional and + must be placed into the same directory as `xmp-openmpt.dll`. + * [**Change**] in_openmpt: `openmpt-mpg123.dll` is no longer optional and must + be placed either into the directory of the player itself or into the same + directory as `in_openmpt.dll`. This is dependent on how the player loads its + plugins. For WinAMP 5, `openmpt-mpg123.dll` needs to be in the directory + which contains `winamp.exe`. `in_openmpt.dll` needs to be in the `Plugins` + directory. + * [**Change**] foo_openmpt: foo_openmpt is now packaged as a fb2k-component + package for easier installation. + * [**Change**] When building libopenmpt with MinGW-w64, it is now recommended + to use the posix thread model (as opposed to the win32 threading model), + because the former does support std::mutex while the latter does not. When + building with win32 threading model with the Autotools build system, it is + recommended to provide the `mingw-std-threads` package. Building libopenmpt + with MinGW-w64 without any `std::thread`/`std::mutex` support is deprecated + and support for such configurations will be removed in libopenmpt 0.5. + * [**Change**] `Makefile` `CONFIG=emscripten` now has 4 `EMSCRIPTEN_TARGET=` + settings: `wasm` generates WebAssembly, `asmjs128m` generates asm.js with a + fixed size 128MB heap, `asmjs` generates asm.js with a fixed default size + heap (as of Emscripten 1.38.11, this amounts to 16MB), `js` generates + JavaScript with dynamic heap growth and with compatibility for older VMs. + * [**Change**] libmodplug: Update public headers to libmodplug 0.8.8.5. This + adds support for kind-of automatic MODPLUG_EXPORT decoration on Windows. + + * [**Regression**] Support for Clang 3.4, 3.5 has been removed. + * [**Regression**] Building with Android NDK older than NDK r16b is not + supported any more. + * [**Regression**] Support for Emscripten versions older than 1.38.5 has been + removed. + * [**Regression**] Support for libmpg123 older than 1.14.0 has been removed. + * [**Regression**] Using MediaFoundation to decode MP3 samples is no longer + supported. Use libmpg123 or minimp3 instead. + * [**Regression**] libmodplug: Support for emulating libmodplug 0.8.7 API/ABI + has been removed. + + * [**Bug**] xmp-openmpt: Sample rate and number of output channels were not + applied correctly when using per-file settings. + * [**Bug**] Internal mixer state was not initialized properly when initially + rendering in 44100kHz stereo format. + * [**Bug**] openmpt123: Prevent libsdl2 and libsdl from being enabled at the + same time because they conflict with each other. + * [**Bug**] libmodplug: Setting `SNDMIX_NORESAMPLING` in the C++ API always + resulted in linear interpolation instead of nearest neighbour + + * IT: In Compatible Gxx mode, allow sample changes next to a tone portamento + effect if a previous sample has already stopped playing. + * IT: Fix broken volume envelopes with negative values as found in breakdwn.it + by Elysis. + * MOD: Slides and delayed notes are executed on every repetition of a row with + row delay (fixes "ode to protracker"). + * XM: If the sustain point of the panning envelope is reached before key-off, + it is never released. + * XM: Do not default recall volume / panning for delayed instrument-less notes + * XM :E60 loop bug was not considered in song length calucation. + * S3M: Notes without instrument number use previous note's sample offset. + * Tighten M15 and MOD file rejection heuristics. + * J2B: Ignore frequency limits from file header. Fixes Medivo.j2b, broken + since libopenmpt-0.2.6401-beta17. + * STM: More accurate tempo calculation. + * STM: Better support for early format revisions (no such files have been + found in the wild, though). + * STM: Last character of sample name was missing. + * SFX: Work around bad conversions of the "Operation Stealth" soundtrack by + turning pattern breaks into note stops. + * IMF: Filter cutoff was upside down and the cutoff range was too small. + * ParamEq plugin center frequency was not limited correctly. + * Keep track of active SFx macro during seeking. + * The "note cut" duplicate note action did not volume-ramp the previously + playing sample. + * A song starting with non-existing patterns could not be played. + * DSM: Support restart position and 16-bit samples. + * DTM: Import global volume. + * MOD: Support notes in octave 2, like in FastTracker 2 (fixes DOPE.MOD). + * Do not apply Amiga playback heuristics to MOD files that have clearly been + written with a PC tracker. + * MPTM: More logical release node behaviour. + * Subsong search is now less thorough. It could previously find many subsongs + that are technically correct (unplayed rows at the beginning of patterns + that have been jumped over due to pattern breaks), but so far no real-world + module that would require such a thorough subsong detection was found. The + old mechanism caused way more false positives than intended with real-world + modules, though. + * Restrict the unpacked size of compressed DMF, IT, MDL and MO3 samples to + avoid huge allocations with malformed small files. + +### libopenmpt 0.3 (2017-09-27) + + * [**New**] New error handling functionality in the C API, which in particular + allows distinguishing potentially transient out-of-memory errors from parse + errors during module loading. + * [**New**] New API `openmpt::module::get_selected_subsong()` (C++) and + `openmpt_module_get_selected_subsong()` (C). + * [**New**] Faster file header probing API `openmpt::probe_file_header()` and + `openmpt::probe_file_header_get_recommended_size` (C++), and + `openmpt_probe_file_header()`, + `openmpt_probe_file_header_without_filesize()`, + `openmpt_probe_file_header_from_stream()` and + `openmpt_probe_file_header_get_recommended_size()` (C). + * [**New**] New API `openmpt::could_open_probability()` (C++) and + `openmpt_could_open_probability()` (C). This fixes a spelling error in the + old 0.2 API. + * [**New**] openmpt123: openmpt123 can now open M3U, M3U8, M3UEXT, M3U8EXT and + PLSv2 playlists via the `--playlist` option. + * [**New**] openmpt123: openmpt123 now supports very fast file header probing + via the `--probe` option. + * [**New**] Libopenmpt now supports building for Windows 10 Universal (Windows + Store 8.2) APIs with MSVC, and also for the older Windows Runtime APIs with + MinGW-w64. + * [**New**] New API header `libopenmpt_ext.h` which implements the libopenmpt + extension APIs also for the C interface. + * [**New**] The Reverb effect (S99 in S3M/IT/MPTM, and X99 in XM) is now + implemented in libopenmpt. + * [**New**] For Amiga modules, a new resampler based on the Amiga's sound + characteristics has been added. It can be activated by passing the + `render.resampler.emulate_amiga` ctl with a value of `1`. Non-Amiga modules + are not affected by this, and setting the ctl overrides the resampler choice + specified by `OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH` or + `openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH`. Support for the MOD + command E0x (Set LED Filter) is also available when the Amiga resampler is + enabled. + + * [**Change**] libopenmpt versioning changed and follows the more conventional + major.minor.patch as well as the recommendations of the + [SemVer](http://semver.org/) scheme now. In addition to the SemVer + requirements, pre-1.0.0 versions will also honor API and ABI stability in + libopenmpt (i.e. libopenmpt ignores SemVer Clause 4). + * [**Change**] The output directories of the MSVC build system were changed to + `bin/vs2015-shared/x86-64-win7/` (and similar) layout which allows building + in the same tree with different compiler versions without overwriting other + outputs. + * [**Change**] The emscripten build now exports libopenmpt as 'libopenmpt' + instead of the default 'Module'. + * [**Change**] Android: The build system changed. The various Android.mk files + have been merged into a single one which can be controlled using command + line options. + * [**Change**] The `Makefile` build system now passes `std=c++11` to the + compiler by default. Older compilers may still work if you pass + `STDCXX=c++0x` to the `make` invocation. + * [**Change**] The `Makefile` option `ANCIENT=1` is gone. + * [**Change**] The optional dependencies on `libltdl` or `libdl` are gone. + They are no longer needed for any functionality. + + * [**Regression**] Compiling client code using the C++ API now requires a + compiler running in C++11 mode. + * [**Regression**] Support for GCC 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7 has been + removed. + * [**Regression**] Support for Clang 3.0, 3.1, 3.2, 3.3 has been removed. + * [**Regression**] Support for Emscripten versions older than 1.31.0 has been + removed. + * [**Regression**] Support for Android NDK versions older than 11 has been + removed. + * [**Regression**] Visual Studio 2008, 2010, 2012, 2013 support has been + removed. + * [**Regression**] Dynamic run-time loading of libmpg123 is no longer + supported. Libmpg123 must be linked at link-time now. + * [**Regression**] xmp-openmpt: xmp-openmpt now requires XMPlay 3.8 or later + and compiling xmp-openmpt requires an appropriate XMPlay SDK with + `XMPIN_FACE` >= `4`. + * [**Regression**] Support for libmpg123 older than 1.13.0 has been removed. + * [**Regression**] Un4seen unmo3 support has been removed. + + * [**Bug**] C++ API: `openmpt::exception` did not define copy and move + constructors or copy and move assignment operators in libopenmpt 0.2. The + compiler-generated ones were not adequate though. libopenmpt 0.3 adds the + appropriate special member functions. This adds the respective symbol names + to the exported ABI, which, depending on the compiler, might or might not + have been there in libopenmpt 0.2. The possibly resulting possible ODR + violation only affects cases that did crash in the libopenmpt 0.2 API anyway + due to memory double-free, and does not cause any further problems in + practice for all known platforms and compilers. + * [**Bug**] The C API could crash instead of failing gracefully in + out-of-memory situations. + * [**Bug**] The test suite could fail on MacOSX or FreeBSD in non-fatal ways + when no locale was active. + * [**Bug**] `libopenmpt_stream_callbacks_fd.h` and + `libopenmpt_stream_callbacks_file.h` were missing in Windows development + packages. + * [**Bug**] libopenmpt on Windows did not properly guard against current + working directory DLL injection attacks. + * [**Bug**] localtime() was used to determine the version of Schism Tracker + used to save IT and S3M files. This function is not guaranteed to be + thread-safe by the standard and is now no longer used. + * [**Bug**] Possible crashes with malformed IT, ITP, AMS, MDL, MED, MPTM, PSM + and Startrekker files. + * [**Bug**] Possible hangs with malformed DBM, MPTM and PSM files. + * [**Bug**] Possible hangs with malformed files containing cyclic plugin + routings. + * [**Bug**] Excessive loading times with malformed ITP / truncated AMS files. + * [**Bug**] Plugins did not work correctly when changing the sample rate + between two render calls. + * [**Bug**] Possible NULL-pointer dereference read during obscure + out-of-memory situations while handling exceptions in the C API. + * [**Bug**] libmodplug: `libmodplug.pc` was wrong. + * [**Bug**] Cross-compiling libopenmpt with autotools for Windows now properly + sets `-municode` and `-mconsole` as well as all required Windows system + libraries. + * [**Bug**] foo_openmpt: Interpolation filter and volume ramping settings were + confused in previous versions. This version resets both to the defaults. + * [**Bug**] libmodplug: The CSoundFile::Read function in the emulated + libmodplug C++ API returned the wrong value, causing qmmp (and possibly + other software) to crash. + + * Support for SoundTracker Pro II (STP) and Digital Tracker (DTM) modules. + * Increased accuracy of the sample position and sample rate to drift less when + playing very long samples. + * Various playback improvements for IT and XM files. + * Channel frequency could wrap around after some excessive portamento / down + in some formats since libopenmpt 0.2-beta17. + * Playback improvements for S3M files made with Impulse Tracker and + Schism Tracker. + * ParamEq plugin emulation didn't do anything at full gain (+15dB). + * All standard DMO effects are now also emulated on non-Windows and non-MSVC + systems. + * Added `libopenmpt_stream_callbacks_buffer.h` which adds + `openmpt_stream_callbacks` support for in-memory buffers, possibly even only + using a truncated prefix view into a bigger file which is useful for + probing. + * Avoid enabling some ProTracker-specific quirks for MOD files most likely + created with ScreamTracker 3. + * Tremolo effect only had half the intended strength in MOD files. + * Pattern loops ending on the last row a pattern were not executed correctly + in S3M files. + * Work-around for reading MIDI macros and plugin settings in some malformed IT + files written by old UNMO3 versions. + * Improve tracker detection in IT format. + * Playback fixes for 8-channel MED files + * Do not set note volume to 0 on out-of-range offset in XM files. + * Better import of some slide commands in SFX files. + * Sample 15 in "Crew Generation" by Necros requires short loops at the + beginning of the sample to not be ignored. Since we need to ignore them in + some (non-ProTracker) modules, we heuristically disable the old loop + sanitization behaviour based on the module channel count. + * Both normal and percentage offset in PLM files were handled as percentage + offset. + * MT2 files with instruments that had both sample and plugin assignments were + not read correctly. + * Some valid FAR files were rejected erroneously. + * Support for VBlank timing flag and comment field in PT36 files. + * Improved accuracy of vibrato command in DIGI / DBM files. + * STM: Add support for "WUZAMOD!" magic bytes and allow some slightly + malformed STM files to load which were previously rejected. + * Detect whether "hidden" patterns in the order list of SoundTracker modules + should be taken into account or not. + * Tighten heuristics for rejecting invalid 669, M15, MOD and ICE files and + loosen them in other places to allow some valid MOD files to load. + * Improvements to seeking: Channel panning was not always updated from + instruments / samples when seeking, and out-of-range global volume was not + applied correctly in some formats. + * seek.sync_samples=1 did not apply PTM reverse offset effect and the volume + slide part of combined volume slide + vibrato commands. + * If the order list was longer than 256 items and there was a pattern break + effect without a position jump on the last pattern of the sequence, it did + not jump to the correct restart order. + * `Makefile` has now explicit support for FreeBSD with no special option or + configuration required. + * openmpt123: Improved section layout in man page. + * libmodplug: Added all missing C++ API symbols that are accessible via the + public libmodplug header file. + * Autotools build system now has options `--disable-openmpt123`, + `--disable-tests` and `--disable-examples` which may be desireable when + cross-compiling. + * Windows binary packages now ship with libmpg123 included. + +### libopenmpt 0.2-beta20 (2016-08-07) + + * [**Bug**] PSM loader was broken on big-endian platforms since forever. + * [**Bug**] `load.skip_samples` ctl did not work for PSM16 modules. + + * There is a new `subsong` ctl, which can return the currently selected + subsong. + * More accurate ProTracker arpeggio wrap-around emulation. + * More accurate sample tuning in PSM16 files. + * Samples in DSM files were sometimes detuned and some pattern commands were + not imported correctly. + * More accurate import of MDL 7-bit panning command. + * Only import pattern commands supported by the UltraTracker version that was + used to save ULT files. Add support for command 5-C (end loop). + * DMF sample loop lengths were off by one. + * Unis 669 pan slide effect was too deep. + * Several valid (but slightly corrupted possibly due to disk failures or data + transfer errors) SoundTracker files were no longer loading since libopenmpt + 0.2-beta18. + +### libopenmpt 0.2-beta19 (2016-07-23) + + * [**Change**] libopenmpt now uses C++14 `[[deprecated]]` attribute instead + of compiler-specific solutions when appropriate. + * [**Change**] libopenmpt C++ header now uses C++11 `noexcept` instead of + C++98 `throw()` exception specification when supported. `throw()` is + deprecated since C++11. This does not change API or ABI as they are + equivalent. Use `LIBOPENMPT_ASSUME_CPLUSPLUS_NOEXCEPT` to override the + default. + * [**Change**] The preprocessor macro `LIBOPENMPT_ANCIENT_COMPILER_STDINT` is + gone. Please use `LIBOPENMPT_ASSUME_CPLUSPLUS_CSTDINT instead`. + Additionally, the typedefs moved from illegal namespace ::std into somewhat + less dangerous namespace ::openmpt::std. You can test + `#ifdef LIBOPENMPT_QUIRK_NO_CSTDINT` client-side to check whether + `libopenmpt.hpp` used the non-standard types. (Note: Of all supported + compilers, this change only affects the 3 compilers with only limited + support: MSVC 2008, GCC 4.1, GCC 4.2.) + + * [**Bug**] xmp-openmpt: Crash when viewing sample texts. + + * The public libopenmpt C++ header has auto-detection logic for the used C++ + standard now. In case your client code compiler misreports the standard + version or you want to override it for other reasons, + `#define LIBOPENMPT_ASSUME_CPLUSPLUS` to the value of the standard version + you desire to be used. There is also a macro for each individual aspect, + like `LIBOPENMPT_ASSUME_CPLUSPLUS_CSTDINT`, + `LIBOPENMPT_ASSUME_CPLUSPLUS_DEPRECATED`, + `LIBOPENMPT_ASSUME_CPLUSPLUS_NOEXCEPT` which take precedence over the + general macro. + * Portamento with sample swap behaviour was wrong for ProTracker MODs. + * Rewritten loader and various playback fixes for MDL files. + * libopenmpt 0.2-beta18 broke import of many pattern commands in DBM, DMF and + ULT files. + * ADPCM samples in MOD files were broken since libopenmpt 0.2-beta17. + +### libopenmpt 0.2-beta18 (2016-07-11) + + * [**Change**] openmpt123: Add PulseAudio output support. Autotools and + `Makefile` build systems now depend on `libpulse` and `libpulse-simple` by + default. Disable with `--without-pulseaudio` or `NO_PULSEAUDIO=1` + respectively. When enabled, PulseAudio will be the default output driver, + * [**Change**] xmp-openmpt: Settings are now stored in xmplay.ini like with + every other plugin. + + * [**Regression**] openmpt123: Support for FLAC < 1.3.0 has been removed. FLAC + before 1.3.0 is broken beyond repair as it provides `assert.h` in the + include path. + + * [**Bug**] Generated pkg-config file libopenmpt.pc by both `Makefile` and + Autotools build systems was totally broken. + * [**Bug**] libopenmpt no longer uses the non-thread-safe global std::rand() + function. + * [**Bug**] Sample loops in GDM modules did not work when using Emscripten. + * [**Bug**] XM and MO3 loaders could crash due to unaligned memory accesses. + * [**Bug**] Fixed incorrect handling of custom MPTM tunings on big endian + platforms. + * [**Bug**] Fixed various problems found with clang 3.8 static analyzer, + address sanitizer and undefined behaviour sanitizer. + * [**Bug**] File header probing functionality was broken for most formats. + * [**Bug**] With non-seekable streams, the entire file was almost always + cached even if it was not of any supported module type. + + * Seeking in allsubsongs-mode now works correctly. + * openmpt123: Added subsong support. + * Various playback fixes for 669, IT, MT2 and MTM files. + * Some MOD files with more than 128 patterns (e.g. NIETNU.MOD) were not loaded + correctly. + * A new example `libopenmpt_example_c_probe` has been added which demonstrates + the usage and flexibility of openmpt_could_open_propability() in the C API + under various constraints. + +### libopenmpt 0.2-beta17 (2016-05-21) + + * [**Change**] The Makefile and Autotools build systems now require to + explicitly specify `NO_LTDL=1` or `--without-ltdl` respectively if no + support for dynamic loading of third party libraries via libtool libltdl is + desired. + * [**Change**] In the Makefile build system option `USE_MO3` and the Autotools + build system option `--enable-mo3` are gone. Dynamic loading of un4seen + unmo3 is now always enabled when dynamic loading is possible and built-in + MO3 support is not possible because either a MP3 or a Vorbis decoder is + missing. + * [**Change**] The MSVC build system changed. The `libopenmptDLL` project is + gone. Use the new `ReleaseShared` configuration of the `libopenmpt` project + instead. libopenmpt now links against zlib by default. A separate project + with smaller footprint linking against miniz is still available as + `libopenmpt-small`. + * [**Change**] The constants used to query library information from + `openmpt_get_string()` and `openmpt::string::get()` (i.e. OPENMPT_STRING_FOO + and openmpt::string::FOO) have been deprecated because having syntactic + constants for theses keys makes extending the API in a backwards and + forwards compatible way harder than it should be. Please just use the string + literals directly. + * [**Change**] Deprecated API identifiers will now cause deprecation warnings + with MSVC, GCC and clang. `#define LIBOPENMPT_NO_DEPRECATE` to disable the + warnings. + * [**Change**] openmpt123: `--[no-]shuffle` option has been renamed to + `--[no-]randomize`. A new `--[no-]shuffle` option has been added which + shuffles randomly through the playlist as opposed to randomizing the + playlist upfront. + * [**Change**] Support for Un4seen unmo3 has generally been deprecated in + favour of the new internal mo3 decoder. Un4seen unmo3 support will be + removed on 2018-01-01. + + * [**Bug**] Memory consumption during loading has been reduced by about 1/3 in + case a seekable input stream is provided (either via C API callback open + functions or via C++ API iostream constructors). + * [**Bug**] Some samples in AMS modules were detuned when using Emscripten. + * [**Bug**] Possible crash with excessive portamento down in some formats. + * [**Bug**] Possible crashes with malformed AMF, AMS, DBM, IT, MDL, MED, MPTM, + MT2, PSM and MMCMP-, XPK- and PP20-compressed files. + * [**Bug**] `openmpt::module::format_pattern_row_channel` with `width == 0` + was returning an empty string instead of an string with unconstrained + length. + + * Support for ProTracker 3.6 IFF-style modules and SoundFX / MultiMedia Sound + (SFX / MMS) modules. + * libopenmpt now has support for DMO plugins on Windows when built with MSVC. + Additionally, the DMO Compression, Distortion, Echo, Gargle, ParamEQ and + WavesReverb DSPs are emulated on on all other platforms. + * libopenmpt now supports the DigiBooster Echo DSP. + * To avoid any of the aforementioned plugins to be used, the load.skip_plugins + ctl can be passed when loading a module. + * libopenmpt got native MO3 support with MP3 decoding either via libmpg123 or + MediaFoundation (on Windows 7 and up) and Vorbis decoding via libogg, + libvorbis, libvorbisfile or stb_vorbis. + * libopenmpt MSVC builds with Visual Studio 2010 or later on Windows 7 or + later now use an internal MO3 decoder with libogg, libvorbis, libvorbisfile, + and libmpg123 or minimp3 or MediaFoundation suppport by default. Visual + Studio 2008 builds still use unmo3.dll by default but also support the + built-in decoder in which case libmpg123 is required. + * libopenmpt with Makefile or Autotools build system can now also use + glibc/libdl instead of libtool/libltdl for dynamic loading of third-party + libraries. Options `NO_DL=1` and `--without-dl` have been added + respectively. + * The `Makefile` build system got 4 new options NO_MPG123, NO_OGG, NO_VORBIS, + NO_VORBISFILE. The default is to use the new dependencies automatically. + * The `Autotools` build system got 4 new options --without-mpg123, + --without-ogg, --without-vorbis, --without-vorbisfile. The default is to use + the new dependencies automatically. + * Makefile and Android builds got support for using minimp3 instead of + libmpg123. For Android, use `Android-minimp3-stbvorbis.mk`, for Makefile use + `USE_MINIMP3=1`. You have to download + [minimp3](http://keyj.emphy.de/minimp3/) yourself and put its contents into + `include/minimp3/`. + * `"source_url"`, `"source_date"` and `"build_compiler"` keys have been added + to `openmpt_string_get()` and `openmpt::string::get()`. + * openmpt123: Add new `--[no-]restart]` option which restarts the playlist + when finished. + * Improved Ultimate SoundTracker version detection heuristics. + * Playing a sample at a sample rate close to the mix rate could lead to small + clicks when using vibrato. + * More fine-grained internal legacy module compatibility settings to correctly + play back modules made with older versions of OpenMPT and a few other + trackers. + * The tail of compressed MDL samples was slightly off. + * Some probably hex-edited XM files (e.g. cybernostra weekend.xm) were not + loaded correctly. + * Countless other playback fixes for MOD, XM, S3M, IT and MT2 files. + +### libopenmpt 0.2-beta16 (2015-11-22) + + * [**Change**] The Autotools build system does strict checking of all + dependencies now. Instead of best effort auto-magic detection of all + potentially optional dependencies, the default set of dependencies is now + enforced unless each individual dependency gets explicitely disabled via + `--without-foo` or `--disable-foo` `./configure` switches. Run + `./configure --help` for the full list of options. + + * [**Bug**] Some MOD files were erroneously detected as 669 files. + * [**Bug**] Some malformed AMF files could result in very long loading times. + * [**Bug**] Fixed crashes in IMF and MT2 loaders. + * [**Bug**] MTM files generated by UNMO3 were not loaded properly. + + * Improved MTM playback. + * `make CONFIG=haiku` for Haiku has been added. + * Language bindings for FreeBASIC have been added (see + `libopenmpt/bindings/`). + +### libopenmpt 0.2-beta15 (2015-10-31) + + * [**Change**] openmpt123: SDL2 is now supported and preferred to SDL1 if + available with the `Makefile` build system. + + * [**Bug**] Emscripten support for older emscripten versions broke in -beta14. + These are now supported again when using `make CONFIG=emscripten-old`. + * [**Bug**] Fixed crashes in MED loader. + + * Playback improvements and loader fixes for MOD, MT2 and MED. + +### libopenmpt 0.2-beta14 (2015-09-13) + + * [**Change**] The C++ API example now uses the PortAudio C++ bindings + instead of the C API. + * [**Change**] Default compiler options for Emscripten have been changed to + more closely match the Emscripten recommendations. + + * [**Bug**] Client code compilation with C89 compilers was broken in beta13. + * [**Bug**] Test suite failed on certain Emscripten/node.js combinations. + * [**Bug**] Fixed various crashes or hangs in DMF, OKT, PLM, IT and MPTM + loaders. + + * Implemented error handling in the libopenmpt API examples. + * Various playback improvements and fixes for OKT, IT and MOD. + +### libopenmpt 0.2-beta13 (2015-08-16) + + * [**Change**] The MSVC build system has been redone. Solutions are now + located in `build/vsVERSION/`. + + * [**Bug**] get_current_channel_vu_left and get_current_channel_vu_right only + return the volume of the front left and right channels now. + get_current_channel_vu_rear_left and get_current_channel_vu_rear_right + do now actually work and return non-zero values. + * [**Bug**] Fix crashes and hangs in MED and MDL loaders and with some + truncated compressed IT samples. + * [**Bug**] Fix crash when playing extremely high-pitched samples. + + * Completed C and C++ documentation + * Added new key for openmpt::module::get_metadata, "message_raw", which + returns an empty string if there is no song message rather than a list of + instrument names. + * in_openmpt: Support for compiling with VS2008. + * xmp-openmpt: Support for compiling with VS2008. + * in_openmpt: Add a more readable file information window. + +### libopenmpt 0.2-beta12 (2015-04-19) + + * Playback fix when row delay effect is used together with offset command. + * A couple of fixes for the seek.sync_samples=1 case. + * IT compatibility fix for IT note delay. + * ProTracker MOD playback compatibility improvement. + +### libopenmpt 0.2-beta11 (2015-04-18) + + * [**Change**] openmpt_stream_seek_func() now gets called with + OPENMPT_STREAM_SEEK_SET, OPENMPT_STREAM_SEEK_CUR and + OPENMPT_STREAM_SEEK_END whence parameter instead of SEEK_SET, SEEK_CUR and + SEEK_END. These are defined to 0, 1 and 2 respectively which corresponds to + the definition in all common C libraries. If your C library uses different + constants, this theoretically breaks binary compatibility. The old + libopenmpt code, however, never actually called the seek function, thus, + there will be no problem in practice. + * [**Change**] openmpt123: When both SDL1.2 and PortAudio are available, + SDL is now the preferred backend because SDL is more widespread and better + tested on all kinds of different platforms, and in general, SDL is just + more reliable. + + * [**Bug**] libopenmpt now also compiles with GCC 4.3. + + * libopenmpt now supports PLM (Disorder Tracker 2) files. + * Various playback improvements and fixes for IT, S3M, XM, MOD, PTM and 669 + files. + +### libopenmpt 0.2-beta10 (2015-02-17) + + * [**Change**] Makefile configuration filenames changed from + `build/make/Makefile.config.*` to `build/make/config-*.mk`. + * [**Change**] libopenmpt for Android now supports unmo3 from un4seen. See + `build/android_ndk/README.AndroidNDK.txt` for details. + + * [**Bug**] Fix out-of-bounds read in mixer code for ProTracker-compatible + MOD files which was introduced back in r4223 / beta6. + + * Vibrato effect was too weak in beta8 and beta9 in IT linear slide mode. + * Very small fine portamento was wrong in beta8 and beta9 in IT linear slide + mode. + * Tiny IT playback compatibility improvements. + * STM playback improvements. + +### libopenmpt 0.2-beta9 (2014-12-21) + + * [**Bug**] libopenmpt_ext.hpp was missing from the Windows binary zip files. + +### libopenmpt 0.2-beta8 (2014-12-21) + + * [**Change**] foo_openmpt: Settings are now accessible via foobar2000 + advanced settings. + * [**Change**] Autotools based build now supports libunmo3. Specify + --enable-unmo3. + * [**Change**] Support for dynamic loading of libunmo3 on MacOS X. + * [**Change**] libopenmpt now uses libltld (from libtool) for dynamic loading + of libunmo3 on all non-Windows platforms. + * [**Change**] Support for older compilers: + * GCC 4.1.x to 4.3.x (use `make ANCIENT=1`) + * Microsoft Visual Studio 2008 (with latest Service Pack) + (see `build/vs2008`) + * [**Change**] libopenmpt_ext.hpp is now distributed by default. The API is + still considered experimental and not guaranteed to stay API or ABI + compatible. + * [**Change**] xmp-openmpt / in_openmpt: No more libopenmpt_settings.dll. + The settings dialog now uses a statically linked copy of MFC. + + * [**Bug**] The -autotools tarballs were not working at all. + + * Vastly improved MT2 loader. + * Improved S3M playback compatibility. + * Added openmpt::ext::interactive, an extension which adds a whole bunch of + new functionality to change playback in some way or another. + * Added possibility to sync sample playback when using + openmpt::module::set_position_* by setting the ctl value + seek.sync_samples=1 + * Support for "hidden" subsongs has been added. + They are accessible through the same interface as ordinary subsongs, i.e. + use openmpt::module::select_subsong to switch between any kind of subsongs. + * All subsongs can now be played consecutively by passing -1 as the subsong + index in openmpt::module::select_subsong. + * Added documentation for a couple of more functions. + +### libopenmpt 0.2-beta7 (2014-09-07) + + * [**Change**] libopenmpt now has an GNU Autotools based build system (in + addition to all previously supported ways of building libopenmpt). + Autotools support is packaged separately as tarballs ending in + `-autotools.tar.gz`. + + * [**Bug**] The distributed windows .zip file did not include pugixml. + + * [**Regression**] openmpt123: Support for writing WavPack (.wv) files has + been removed. + + Reasoning: + 1. WavPack support was incomplete and did not include support for writing + WavPack metadata at all. + 2. openmpt123 already supports libSndFile which can be used to write + uncompressed lossless WAV files which can then be encoded to whatever + format the user desires with other tools. + +### libopenmpt 0.2-beta6 (2014-09-06) + + * [**Change**] openmpt123: SDL is now also used by default if availble, in + addition to PortAudio. + * [**Change**] Support for emscripten is no longer experimental. + * [**Change**] libopenmpt itself can now also be compiled with VS2008. + + * [**Bug**] Fix all known crashes on platforms that do not support unaligned + memory access. + * [**Bug**] openmpt123: Effect column was always missing in pattern display. + +### libopenmpt 0.2-beta5 (2014-06-15) + + * [**Change**] Add unmo3 support for non-Windows builds. + * [**Change**] Namespace all internal functions in order to allow statically + linking against libopenmpt without risking duplicate symbols. + * [**Change**] Iconv is now completely optional and only used on Linux + systems by default. + * [**Change**] Added libopenmpt_example_c_stdout.c, an example without + requiring PortAudio. + * [**Change**] Add experimental support for building libopenmpt with + emscripten. + + * [**Bug**] Fix ping-pong loop behaviour which broke in 0.2-beta3. + * [**Bug**] Fix crashes when accessing invalid patterns through libopenmpt + API. + * [**Bug**] Makefile: Support building with missing optional dependencies + without them being stated explicitely. + * [**Bug**] openmpt123: Crash when quitting while playback is stopped. + * [**Bug**] openmpt123: Crash when writing output to a file in interactive UI + mode. + * [**Bug**] openmpt123: Wrong FLAC output filename in --render mode. + + * Various smaller playback accuracy improvements. + +### libopenmpt 0.2-beta4 (2014-02-25) + + * [**Bug**] Makefile: Dependency tracking for the test suite did not work. + +### libopenmpt 0.2-beta3 (2014-02-21) + + * [**Change**] The test suite is now built by default with Makefile based + builds. Use `TEST=0` to skip building the tests. `make check` runs the test + suite. + + * [**Bug**] Crash in MOD and XM loaders on architectures not supporting + unaligned memory access. + * [**Bug**] MMCMP, PP20 and XPK unpackers should now work on non-x86 hardware + and implement proper bounds checking. + * [**Bug**] openmpt_module_get_num_samples() returned the wrong value. + * [**Bug**] in_openmpt: DSP plugins did not work properly. + * [**Bug**] in_openmpt/xmp-openmpt: Setting name for stereo separation was + misspelled. This version will revert your stereo separation settings to + default. + * [**Bug**] Crash when loading some corrupted modules with stereo samples. + + * Support building on Android NDK. + * Avoid clicks in sample loops when using interpolation. + * IT filters are now done in integer instead of floating point. This improves + performance, especially on architectures with no or a slow FPU. + * MOD pattern break handling fixes. + * Various XM playback improvements. + * Improved and switchable dithering when using 16bit integer API. + +### libopenmpt 0.2-beta2 (2014-01-12) + + * [**Bug**] MT2 loader crash. + * [**Bug**] Saving settings in in_openmpt and xmp-openmpt did not work. + * [**Bug**] Load libopenmpt_settings.dll also from below Plugins directory in + Winamp. + + * DBM playback improvements. + +### libopenmpt 0.2-beta1 (2013-12-31) + + * First release. + diff --git a/libs/libopenmpt/debian/libopenmpt-0.4.0-trusty-backport.diff b/libs/libopenmpt/debian/libopenmpt-0.4.0-trusty-backport.diff new file mode 100644 index 0000000000000000000000000000000000000000..1c9b56ba53d2e0ef17ee1f8c9d224294c82504e1 --- /dev/null +++ b/libs/libopenmpt/debian/libopenmpt-0.4.0-trusty-backport.diff @@ -0,0 +1,550 @@ +diff -uraN ../../orig/libopenmpt-0.4.0/debian/changelog ./debian/changelog +--- ../../orig/libopenmpt-0.4.0/debian/changelog 2018-12-24 16:43:58.000000000 -0500 ++++ ./debian/changelog 2019-01-04 17:56:35.024725537 -0500 +@@ -1,3 +1,38 @@ ++libopenmpt (0.4.0-ubuntu14.04.1~ppa14) trusty; urgency=medium ++ ++ * Remove debian symbols files due to gcc 4.8 - 5 C++ abi incompatibility ++ ++ -- Sonic Team Junior <stjr@srb2.org> Fri, 04 Jan 2019 17:56:01 -0500 ++ ++libopenmpt (0.4.0-ubuntu14.04.1~ppa13) trusty; urgency=medium ++ ++ * autoreconf libtool ++ ++ -- Sonic Team Junior <stjr@srb2.org> Fri, 04 Jan 2019 17:10:45 -0500 ++ ++libopenmpt (0.4.0-ubuntu14.04.1~ppa12) trusty; urgency=medium ++ ++ * debian/rules autoreconf ++ ++ -- Sonic Team Junior <stjr@srb2.org> Fri, 04 Jan 2019 17:03:19 -0500 ++ ++libopenmpt (0.4.0-ubuntu14.04.1~ppa11) trusty; urgency=medium ++ ++ * debian/rules autoreconf ++ ++ -- Sonic Team Junior <stjr@srb2.org> Fri, 04 Jan 2019 16:59:08 -0500 ++ ++libopenmpt (0.4.0-ubuntu14.04.1~ppa10) trusty; urgency=medium ++ ++ * Backport to trusty ++ * Added automake build depend ++ * Adjusted debhelper depend to >= 9.0~ ++ * Adjusted dpkg-dev depend to >= 1.17.0 ++ * Adjusted debian/compat to 10 ++ * autoreconf --force --install ++ ++ -- Sonic Team Junior <stjr@srb2.org> Fri, 04 Jan 2019 16:54:04 -0500 ++ + libopenmpt (0.4.0-1) unstable; urgency=medium + + * New upstream release. +diff -uraN ../../orig/libopenmpt-0.4.0/debian/compat ./debian/compat +--- ../../orig/libopenmpt-0.4.0/debian/compat 2018-12-24 16:43:58.000000000 -0500 ++++ ./debian/compat 2019-01-04 16:39:17.613976357 -0500 +@@ -1 +1 @@ +-11 ++10 +diff -uraN ../../orig/libopenmpt-0.4.0/debian/control ./debian/control +--- ../../orig/libopenmpt-0.4.0/debian/control 2018-12-24 16:43:58.000000000 -0500 ++++ ./debian/control 2019-01-04 17:10:42.008523333 -0500 +@@ -4,10 +4,12 @@ + Maintainer: Debian Multimedia Maintainers <debian-multimedia@lists.debian.org> + Uploaders: James Cowgill <jcowgill@debian.org> + Build-Depends: +- debhelper (>= 11.1~), ++ automake, ++ libtool, ++ debhelper (>= 9.0~), + dh-exec, + doxygen, +- dpkg-dev (>= 1.18.0), ++ dpkg-dev (>= 1.17.0), + libflac-dev, + libmpg123-dev, + libogg-dev, +diff -uraN ../../orig/libopenmpt-0.4.0/debian/files ./debian/files +--- ../../orig/libopenmpt-0.4.0/debian/files 1969-12-31 19:00:00.000000000 -0500 ++++ ./debian/files 2019-01-04 17:56:47.813250880 -0500 +@@ -0,0 +1 @@ ++libopenmpt_0.4.0-ubuntu14.04.1~ppa14_source.buildinfo libs optional +diff -uraN ../../orig/libopenmpt-0.4.0/debian/libopenmpt0.symbols ./debian/libopenmpt0.symbols +--- ../../orig/libopenmpt-0.4.0/debian/libopenmpt0.symbols 2018-12-24 16:43:58.000000000 -0500 ++++ ./debian/libopenmpt0.symbols 1969-12-31 19:00:00.000000000 -0500 +@@ -1,256 +0,0 @@ +-libopenmpt.so.0 libopenmpt0 #MINVER# +-* Build-Depends-Package: libopenmpt-dev +-# Ignore std:: template instantiations +- (regex|optional)"^_ZN?K?S" 0.2.7025~beta20.1 +- _ZN7openmpt10module_ext13get_interfaceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt10module_extC1EPKcjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt10module_extC1EPKcmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt10module_extC1EPKvjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt10module_extC1EPKvmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt10module_extC1ERKS0_@Base 0.2.7025~beta20.1 +- _ZN7openmpt10module_extC1ERKSt6vectorIcSaIcEERSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcES2_EESC_St4lessISC_ESaISt4pairIKSC_SC_EEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt10module_extC1ERSiRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_St4lessIS9_ESaISt4pairIKS9_S9_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt10module_extC2EPKcjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt10module_extC2EPKcmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt10module_extC2EPKvjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt10module_extC2EPKvmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt10module_extC2ERKS0_@Base 0.2.7025~beta20.1 +- _ZN7openmpt10module_extC2ERKSt6vectorIcSaIcEERSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcES2_EESC_St4lessISC_ESaISt4pairIKSC_SC_EEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt10module_extC2ERSiRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_St4lessIS9_ESaISt4pairIKS9_S9_EEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt10module_extD0Ev@Base 0.2.7025~beta20.1 +- _ZN7openmpt10module_extD1Ev@Base 0.2.7025~beta20.1 +- _ZN7openmpt10module_extD2Ev@Base 0.2.7025~beta20.1 +- _ZN7openmpt10module_extaSERKS0_@Base 0.2.7025~beta20.1 +- _ZN7openmpt16get_core_versionEv@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt17probe_file_headerEyPKhj@Base 0.3.0 +- (arch-bits=64)_ZN7openmpt17probe_file_headerEmPKhm@Base 0.3.0 +- (arch-bits=32)_ZN7openmpt17probe_file_headerEyPKhjy@Base 0.3.0 +- (arch-bits=64)_ZN7openmpt17probe_file_headerEmPKhmm@Base 0.3.0 +- (arch-bits=32)_ZN7openmpt17probe_file_headerEyRSi@Base 0.3.0 +- (arch-bits=64)_ZN7openmpt17probe_file_headerEmRSi@Base 0.3.0 +- _ZN7openmpt19get_library_versionEv@Base 0.2.7025~beta20.1 +- _ZN7openmpt22could_open_probabilityERSidRSo@Base 0.3.0 +- _ZN7openmpt22could_open_propabilityERSidRSo@Base 0.2.7025~beta20.1 +- _ZN7openmpt22is_extension_supportedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt24get_supported_extensionsB5cxx11Ev@Base 0.2.7025~beta20.1 +- _ZN7openmpt38probe_file_header_get_recommended_sizeEv@Base 0.3.0 +- _ZN7openmpt6module14select_subsongEi@Base 0.2.7025~beta20.1 +- _ZN7openmpt6module16set_render_paramEii@Base 0.2.7025~beta20.1 +- _ZN7openmpt6module16set_repeat_countEi@Base 0.2.7025~beta20.1 +- _ZN7openmpt6module20set_position_secondsEd@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt6module21read_interleaved_quadEijPf@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt6module21read_interleaved_quadEimPf@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt6module21read_interleaved_quadEijPs@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt6module21read_interleaved_quadEimPs@Base 0.2.7025~beta20.1 +- _ZN7openmpt6module22set_position_order_rowEii@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt6module23read_interleaved_stereoEijPf@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt6module23read_interleaved_stereoEimPf@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt6module23read_interleaved_stereoEijPs@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt6module23read_interleaved_stereoEimPs@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt6module4readEijPf@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt6module4readEimPf@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt6module4readEijPfS1_@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt6module4readEimPfS1_@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt6module4readEijPfS1_S1_S1_@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt6module4readEimPfS1_S1_S1_@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt6module4readEijPs@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt6module4readEimPs@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt6module4readEijPsS1_@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt6module4readEimPsS1_@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt6module4readEijPsS1_S1_S1_@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt6module4readEimPsS1_S1_S1_@Base 0.2.7025~beta20.1 +- _ZN7openmpt6module7ctl_setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_@Base 0.2.7025~beta20.1 +- _ZN7openmpt6module8set_implEPNS_11module_implE@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleC1EPKcS2_RSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt6moduleC1EPKcjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt6moduleC1EPKcmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleC1EPKhS2_RSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt6moduleC1EPKhjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt6moduleC1EPKhmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt6moduleC1EPKvjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt6moduleC1EPKvmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleC1ERKS0_@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleC1ERKSt6vectorIcSaIcEERSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcES2_EESC_St4lessISC_ESaISt4pairIKSC_SC_EEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleC1ERKSt6vectorIhSaIhEERSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_St4lessISD_ESaISt4pairIKSD_SD_EEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleC1ERSiRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_St4lessIS9_ESaISt4pairIKS9_S9_EEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleC1Ev@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleC2EPKcS2_RSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt6moduleC2EPKcjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt6moduleC2EPKcmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleC2EPKhS2_RSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt6moduleC2EPKhjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt6moduleC2EPKhmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZN7openmpt6moduleC2EPKvjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZN7openmpt6moduleC2EPKvmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleC2ERKS0_@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleC2ERKSt6vectorIcSaIcEERSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcES2_EESC_St4lessISC_ESaISt4pairIKSC_SC_EEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleC2ERKSt6vectorIhSaIhEERSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_St4lessISD_ESaISt4pairIKSD_SD_EEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleC2ERSiRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_St4lessIS9_ESaISt4pairIKS9_S9_EEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleC2Ev@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleD0Ev@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleD1Ev@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleD2Ev@Base 0.2.7025~beta20.1 +- _ZN7openmpt6moduleaSERKS0_@Base 0.2.7025~beta20.1 +- _ZN7openmpt6string3getERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt9exceptionC1EOS0_@Base 0.3.0 +- _ZN7openmpt9exceptionC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt9exceptionC1ERKS0_@Base 0.3.0 +- _ZN7openmpt9exceptionC2EOS0_@Base 0.3.0 +- _ZN7openmpt9exceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@Base 0.2.7025~beta20.1 +- _ZN7openmpt9exceptionC2ERKS0_@Base 0.3.0 +- _ZN7openmpt9exceptionD0Ev@Base 0.2.7025~beta20.1 +- _ZN7openmpt9exceptionD1Ev@Base 0.2.7025~beta20.1 +- _ZN7openmpt9exceptionD2Ev@Base 0.2.7025~beta20.1 +- _ZN7openmpt9exceptionaSEOS0_@Base 0.3.0 +- _ZN7openmpt9exceptionaSERKS0_@Base 0.3.0 +- _ZNK7openmpt6module12get_metadataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module14get_num_ordersEv@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module15get_current_rowEv@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module15get_num_samplesEv@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module15get_order_namesB5cxx11Ev@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module16get_num_channelsEv@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module16get_num_patternsEv@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module16get_num_subsongsEv@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module16get_render_paramEi@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module16get_repeat_countEv@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module16get_sample_namesB5cxx11Ev@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module17get_channel_namesB5cxx11Ev@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module17get_current_orderEv@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module17get_current_speedEv@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module17get_current_tempoEv@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module17get_metadata_keysB5cxx11Ev@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module17get_order_patternEi@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module17get_pattern_namesB5cxx11Ev@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module17get_subsong_namesB5cxx11Ev@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module19get_current_patternEv@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module19get_num_instrumentsEv@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module20get_duration_secondsEv@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module20get_instrument_namesB5cxx11Ev@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module20get_pattern_num_rowsEi@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module20get_position_secondsEv@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module20get_selected_subsongEv@Base 0.3.0 +- (arch-bits=32)_ZNK7openmpt6module26format_pattern_row_channelB5cxx11Eiiijb@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZNK7openmpt6module26format_pattern_row_channelB5cxx11Eiiimb@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module27get_current_channel_vu_leftEi@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module27get_current_channel_vu_monoEi@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module28get_current_channel_vu_rightEi@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module28get_current_playing_channelsEv@Base 0.2.7025~beta20.1 +- (arch-bits=32)_ZNK7openmpt6module29highlight_pattern_row_channelB5cxx11Eiiijb@Base 0.2.7025~beta20.1 +- (arch-bits=64)_ZNK7openmpt6module29highlight_pattern_row_channelB5cxx11Eiiimb@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module31get_pattern_row_channel_commandEiiii@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module32get_current_channel_vu_rear_leftEi@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module33get_current_channel_vu_rear_rightEi@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module34format_pattern_row_channel_commandB5cxx11Eiiii@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module37highlight_pattern_row_channel_commandB5cxx11Eiiii@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module7ctl_getERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@Base 0.2.7025~beta20.1 +- _ZNK7openmpt6module8get_ctlsB5cxx11Ev@Base 0.2.7025~beta20.1 +- _ZNK7openmpt9exception4whatEv@Base 0.2.7025~beta20.1 +- _ZTIN7openmpt10module_extE@Base 0.2.7025~beta20.1 +- _ZTIN7openmpt6moduleE@Base 0.2.7025~beta20.1 +- _ZTIN7openmpt9exceptionE@Base 0.2.7025~beta20.1 +- (optional=weak)_ZTISt11_Mutex_baseILN9__gnu_cxx12_Lock_policyE2EE@Base 0.2.7025~beta20.1 +- (optional=weak)_ZTISt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE@Base 0.2.7025~beta20.1 +- _ZTSN7openmpt10module_extE@Base 0.2.7025~beta20.1 +- _ZTSN7openmpt6moduleE@Base 0.2.7025~beta20.1 +- _ZTSN7openmpt9exceptionE@Base 0.2.7025~beta20.1 +- (optional=weak)_ZTSSt11_Mutex_baseILN9__gnu_cxx12_Lock_policyE2EE@Base 0.2.7025~beta20.1 +- (optional=weak)_ZTSSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE@Base 0.2.7025~beta20.1 +- (optional=weak)_ZTSSt19_Sp_make_shared_tag@Base 0.2.7025~beta20.1 +- _ZTVN7openmpt10module_extE@Base 0.2.7025~beta20.1 +- _ZTVN7openmpt6moduleE@Base 0.2.7025~beta20.1 +- _ZTVN7openmpt9exceptionE@Base 0.2.7025~beta20.1 +- (optional=weak)_ZZNSt19_Sp_make_shared_tag5_S_tiEvE5__tag@Base 0.4.0 +- openmpt_could_open_probability2@Base 0.3.0 +- openmpt_could_open_probability@Base 0.3.0 +- openmpt_could_open_propability@Base 0.2.7025~beta20.1 +- openmpt_error_func_default@Base 0.3.0 +- openmpt_error_func_errno@Base 0.3.0 +- openmpt_error_func_errno_userdata@Base 0.3.0 +- openmpt_error_func_ignore@Base 0.3.0 +- openmpt_error_func_log@Base 0.3.0 +- openmpt_error_func_store@Base 0.3.0 +- openmpt_error_is_transient@Base 0.3.0 +- openmpt_error_string@Base 0.3.0 +- openmpt_free_string@Base 0.2.7025~beta20.1 +- openmpt_get_core_version@Base 0.2.7025~beta20.1 +- openmpt_get_library_version@Base 0.2.7025~beta20.1 +- openmpt_get_string@Base 0.2.7025~beta20.1 +- openmpt_get_supported_extensions@Base 0.2.7025~beta20.1 +- openmpt_is_extension_supported@Base 0.2.7025~beta20.1 +- openmpt_log_func_default@Base 0.2.7025~beta20.1 +- openmpt_log_func_silent@Base 0.2.7025~beta20.1 +- openmpt_module_create2@Base 0.3.0 +- openmpt_module_create@Base 0.2.7025~beta20.1 +- openmpt_module_create_from_memory2@Base 0.3.0 +- openmpt_module_create_from_memory@Base 0.2.7025~beta20.1 +- openmpt_module_ctl_get@Base 0.2.7025~beta20.1 +- openmpt_module_ctl_set@Base 0.2.7025~beta20.1 +- openmpt_module_destroy@Base 0.2.7025~beta20.1 +- openmpt_module_error_clear@Base 0.3.0 +- openmpt_module_error_get_last@Base 0.3.0 +- openmpt_module_error_get_last_message@Base 0.3.0 +- openmpt_module_error_set_last@Base 0.3.0 +- openmpt_module_ext_create@Base 0.3.0 +- openmpt_module_ext_create_from_memory@Base 0.3.0 +- openmpt_module_ext_destroy@Base 0.3.0 +- openmpt_module_ext_get_interface@Base 0.3.0 +- openmpt_module_ext_get_module@Base 0.3.0 +- openmpt_module_format_pattern_row_channel@Base 0.2.7025~beta20.1 +- openmpt_module_format_pattern_row_channel_command@Base 0.2.7025~beta20.1 +- openmpt_module_get_channel_name@Base 0.2.7025~beta20.1 +- openmpt_module_get_ctls@Base 0.2.7025~beta20.1 +- openmpt_module_get_current_channel_vu_left@Base 0.2.7025~beta20.1 +- openmpt_module_get_current_channel_vu_mono@Base 0.2.7025~beta20.1 +- openmpt_module_get_current_channel_vu_rear_left@Base 0.2.7025~beta20.1 +- openmpt_module_get_current_channel_vu_rear_right@Base 0.2.7025~beta20.1 +- openmpt_module_get_current_channel_vu_right@Base 0.2.7025~beta20.1 +- openmpt_module_get_current_order@Base 0.2.7025~beta20.1 +- openmpt_module_get_current_pattern@Base 0.2.7025~beta20.1 +- openmpt_module_get_current_playing_channels@Base 0.2.7025~beta20.1 +- openmpt_module_get_current_row@Base 0.2.7025~beta20.1 +- openmpt_module_get_current_speed@Base 0.2.7025~beta20.1 +- openmpt_module_get_current_tempo@Base 0.2.7025~beta20.1 +- openmpt_module_get_duration_seconds@Base 0.2.7025~beta20.1 +- openmpt_module_get_instrument_name@Base 0.2.7025~beta20.1 +- openmpt_module_get_metadata@Base 0.2.7025~beta20.1 +- openmpt_module_get_metadata_keys@Base 0.2.7025~beta20.1 +- openmpt_module_get_num_channels@Base 0.2.7025~beta20.1 +- openmpt_module_get_num_instruments@Base 0.2.7025~beta20.1 +- openmpt_module_get_num_orders@Base 0.2.7025~beta20.1 +- openmpt_module_get_num_patterns@Base 0.2.7025~beta20.1 +- openmpt_module_get_num_samples@Base 0.2.7025~beta20.1 +- openmpt_module_get_num_subsongs@Base 0.2.7025~beta20.1 +- openmpt_module_get_order_name@Base 0.2.7025~beta20.1 +- openmpt_module_get_order_pattern@Base 0.2.7025~beta20.1 +- openmpt_module_get_pattern_name@Base 0.2.7025~beta20.1 +- openmpt_module_get_pattern_num_rows@Base 0.2.7025~beta20.1 +- openmpt_module_get_pattern_row_channel_command@Base 0.2.7025~beta20.1 +- openmpt_module_get_position_seconds@Base 0.2.7025~beta20.1 +- openmpt_module_get_render_param@Base 0.2.7025~beta20.1 +- openmpt_module_get_repeat_count@Base 0.2.7025~beta20.1 +- openmpt_module_get_sample_name@Base 0.2.7025~beta20.1 +- openmpt_module_get_selected_subsong@Base 0.3.0 +- openmpt_module_get_subsong_name@Base 0.2.7025~beta20.1 +- openmpt_module_highlight_pattern_row_channel@Base 0.2.7025~beta20.1 +- openmpt_module_highlight_pattern_row_channel_command@Base 0.2.7025~beta20.1 +- openmpt_module_read_float_mono@Base 0.2.7025~beta20.1 +- openmpt_module_read_float_quad@Base 0.2.7025~beta20.1 +- openmpt_module_read_float_stereo@Base 0.2.7025~beta20.1 +- openmpt_module_read_interleaved_float_quad@Base 0.2.7025~beta20.1 +- openmpt_module_read_interleaved_float_stereo@Base 0.2.7025~beta20.1 +- openmpt_module_read_interleaved_quad@Base 0.2.7025~beta20.1 +- openmpt_module_read_interleaved_stereo@Base 0.2.7025~beta20.1 +- openmpt_module_read_mono@Base 0.2.7025~beta20.1 +- openmpt_module_read_quad@Base 0.2.7025~beta20.1 +- openmpt_module_read_stereo@Base 0.2.7025~beta20.1 +- openmpt_module_select_subsong@Base 0.2.7025~beta20.1 +- openmpt_module_set_error_func@Base 0.3.0 +- openmpt_module_set_log_func@Base 0.3.0 +- openmpt_module_set_position_order_row@Base 0.2.7025~beta20.1 +- openmpt_module_set_position_seconds@Base 0.2.7025~beta20.1 +- openmpt_module_set_render_param@Base 0.2.7025~beta20.1 +- openmpt_module_set_repeat_count@Base 0.2.7025~beta20.1 +- openmpt_probe_file_header@Base 0.3.0 +- openmpt_probe_file_header_from_stream@Base 0.3.0 +- openmpt_probe_file_header_get_recommended_size@Base 0.3.0 +- openmpt_probe_file_header_without_filesize@Base 0.3.0 +diff -uraN ../../orig/libopenmpt-0.4.0/debian/libopenmpt-modplug1.symbols ./debian/libopenmpt-modplug1.symbols +--- ../../orig/libopenmpt-0.4.0/debian/libopenmpt-modplug1.symbols 2018-12-24 16:43:58.000000000 -0500 ++++ ./debian/libopenmpt-modplug1.symbols 1969-12-31 19:00:00.000000000 -0500 +@@ -1,200 +0,0 @@ +-libopenmpt_modplug.so.1 libopenmpt-modplug1 #MINVER# +-* Build-Depends-Package: libopenmpt-modplug-dev +- LIBOPENMPT_MODPLUG1@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_ExportIT@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_ExportMOD@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_ExportS3M@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_ExportXM@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_GetCurrentOrder@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_GetCurrentPattern@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_GetCurrentRow@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_GetCurrentSpeed@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_GetCurrentTempo@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_GetLength@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_GetMasterVolume@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_GetMessage@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_GetModuleType@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_GetName@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_GetPattern@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_GetPlayingChannels@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_GetSettings@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_InitMixerCallback@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_InstrumentName@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_Load@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_NumChannels@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_NumInstruments@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_NumPatterns@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_NumSamples@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_Read@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_SampleName@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_Seek@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_SeekOrder@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_SetMasterVolume@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_SetSettings@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_Unload@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- ModPlug_UnloadMixerCallback@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile10FreeSampleEPv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile10InitPlayerEb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile10NoteChangeEjibb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile10PackSampleERii@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile10ProcessAGCEi@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile10ProcessRowEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile10ReadSampleEP14_MODINSTRUMENTjPKcj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile10RetrigNoteEjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile10gdwSysInfoE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile10gnCPUUsageE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile10gnChannelsE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile11DoFreqSlideEP11_MODCHANNELi@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile11FineVibratoEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile11FreePatternEPv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile11InitSysInfoEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile11LoopPatternEii@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile11PatternLoopEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile11VolumeSlideEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile12FineVolumeUpEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile12ITInstrToMPTEPKvP17_INSTRUMENTHEADERj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile12IsSampleUsedEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile12PanningSlideEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile12PortamentoUpEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile12ResetMidiCfgEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile12SetMixConfigEjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile12gnReverbTypeE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile12gpSndMixHookE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile13CanPackSampleEPcjjPh@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile13CheckCPUUsageEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile13DestroySampleEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile13ResetChannelsEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile13SetCurrentPosEj@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile13SetWaveConfigEjjjb@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile13gdwMixingFreqE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile13gdwSoundSetupE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile13m_nXBassDepthE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile13m_nXBassRangeE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile14AllocateSampleEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile14FineVolumeDownEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile14GlobalFadeSongEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile14GlobalVolSlideEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile14LoadMixPluginsEPKvj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile14PortamentoDownEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile14ProcessEffectsEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile14SaveMixPluginsEP8_IO_FILEb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile14SetPatternNameEjPKc@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile14TonePortamentoEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile14m_nReverbDelayE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile14m_nReverbDepthE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile15AllocatePatternEjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile15ChannelVolSlideEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile15CreateStereoMixEi@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile15GetSongCommentsEPcjj@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile15SetCurrentOrderEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile15SetMasterVolumeEjb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile15SetWaveConfigExEbbbbbbb@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile15gnBitsPerSampleE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile15m_nStreamVolumeE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile16AdjustSampleLoopEP14_MODINSTRUMENT@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile16FinePortamentoUpEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile16InstrumentChangeEP11_MODCHANNELjbbb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile16IsInstrumentUsedEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile16ProcessMidiMacroEjPKcj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile16m_nProLogicDelayE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile16m_nProLogicDepthE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile17DestroyInstrumentEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile17MapMidiInstrumentEjjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile17SetResamplingModeEj@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile17m_nMaxMixChannelsE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile18FinePortamentoDownEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile18GetRawSongCommentsEPcjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile18ReadSampleFromSongEjPS_j@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile18SetXBassParametersEjj@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile19DetectUnusedSamplesEPb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile19ExtendedMODCommandsEjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile19ExtendedS3MCommandsEjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile19SetReverbParametersEjj@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile19gnVolumeRampSamplesE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile19m_nStereoSeparationE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile20FrequencyToTransposeEP14_MODINSTRUMENT@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile20FrequencyToTransposeEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile20Normalize24BitBufferEPhjjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile20TransposeToFrequencyEii@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile21ExtendedChannelEffectEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile21ExtraFinePortamentoUpEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile21RemoveSelectedSamplesEPb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile21SetSurroundParametersEjj@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile21gpMixPluginCreateProcE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile22ReadInstrumentFromSongEjPS_j@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile23ExtraFinePortamentoDownEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile23RemoveInstrumentSamplesEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile4ReadEPvj@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile5gnAGCE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile6CreateEPKhj@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile6KeyOffEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile6ReadITEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile6ReadXMEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile6SetAGCEb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7DestroyEv@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile7NoteCutEjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7Read669EPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadABCEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadAMFEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadAMSEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadDBMEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadDMFEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadDSMEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadFAREPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadJ2BEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadMDLEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadMIDEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadMT2EPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadMTMEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadMedEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadModEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadOKTEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadPATEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadPSMEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadPTMEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadS3MEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadSTMEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadUMXEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadUltEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7ReadWavEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7TestABCEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7TestMIDEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7TestPATEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7TremoloEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile7VibratoEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile8CheckNNAEjjib@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile8FadeSongEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile8ReadAMS2EPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile8ReadNoteEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile8ResetAGCEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile8SetSpeedEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile8SetTempoEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile9GetLengthEbb@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFile9PanbrelloEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZN10CSoundFile9gnVUMeterE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFileC1Ev@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFileC2Ev@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFileD1Ev@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZN10CSoundFileD2Ev@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZNK10CSoundFile10S3MConvertEP11_MODCOMMANDb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile13GetCurrentPosEv@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZNK10CSoundFile13GetNNAChannelEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile13GetSampleNameEjPc@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile14GetMaxPositionEv@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3 +- _ZNK10CSoundFile14GetNumChannelsEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile14GetNumPatternsEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile14GetPatternNameEjPcj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile14GetSaveFormatsEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile14IsSongFinishedEjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile14ModSaveCommandEPK11_MODCOMMANDb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile14S3MSaveConvertEPjS0_b@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile17ConvertModCommandEP11_MODCOMMAND@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile17CutOffToFrequencyEji@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile17GetBestSaveFormatEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile17GetFreqFromPeriodEjji@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile17GetInstrumentNameEjPc@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile17GetNoteFromPeriodEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile17GetNumInstrumentsEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile17GetPeriodFromNoteEjij@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile18SetupChannelFilterEP11_MODCHANNELbi@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +- _ZNK10CSoundFile19IsValidBackwardJumpEjjjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5 +diff -uraN ../../orig/libopenmpt-0.4.0/debian/rules ./debian/rules +--- ../../orig/libopenmpt-0.4.0/debian/rules 2018-12-24 16:43:58.000000000 -0500 ++++ ./debian/rules 2019-01-04 17:03:16.206691071 -0500 +@@ -11,9 +11,10 @@ + dh $@ + + override_dh_autoreconf: +- dh_autoreconf --as-needed ++ autoreconf --force --install + + override_dh_auto_configure: ++ debian/rules override_dh_autoreconf + dh_auto_configure -- --disable-static --enable-libopenmpt_modplug + + override_dh_auto_build: diff --git a/libs/libopenmpt/debian/libopenmpt-0.4.0-xenial-backport.diff b/libs/libopenmpt/debian/libopenmpt-0.4.0-xenial-backport.diff new file mode 100644 index 0000000000000000000000000000000000000000..9cb88b748600c1d97fe276bce8a77a7da5759145 --- /dev/null +++ b/libs/libopenmpt/debian/libopenmpt-0.4.0-xenial-backport.diff @@ -0,0 +1,40 @@ +diff -uraN ../../orig/libopenmpt-0.4.0/debian/changelog ./debian/changelog +--- ../../orig/libopenmpt-0.4.0/debian/changelog 2018-12-24 16:43:58.000000000 -0500 ++++ ./debian/changelog 2019-01-04 16:37:08.788775423 -0500 +@@ -1,3 +1,12 @@ ++libopenmpt (0.4.0-ubuntu16.04.1~ppa10) xenial; urgency=medium ++ ++ * Backport to Xenial ++ * automake build depend added ++ * debhelper depend adjusted to >= 9.0~ ++ * deb compat level adjusted to 10 ++ ++ -- Sonic Team Junior <stjr@srb2.org> Fri, 04 Jan 2019 16:35:08 -0500 ++ + libopenmpt (0.4.0-1) unstable; urgency=medium + + * New upstream release. +diff -uraN ../../orig/libopenmpt-0.4.0/debian/compat ./debian/compat +--- ../../orig/libopenmpt-0.4.0/debian/compat 2018-12-24 16:43:58.000000000 -0500 ++++ ./debian/compat 2019-01-04 16:34:31.830370437 -0500 +@@ -1 +1 @@ +-11 ++10 +diff -uraN ../../orig/libopenmpt-0.4.0/debian/control ./debian/control +--- ../../orig/libopenmpt-0.4.0/debian/control 2018-12-24 16:43:58.000000000 -0500 ++++ ./debian/control 2019-01-04 16:34:59.339499384 -0500 +@@ -4,7 +4,8 @@ + Maintainer: Debian Multimedia Maintainers <debian-multimedia@lists.debian.org> + Uploaders: James Cowgill <jcowgill@debian.org> + Build-Depends: +- debhelper (>= 11.1~), ++ automake, ++ debhelper (>= 9.0~), + dh-exec, + doxygen, + dpkg-dev (>= 1.18.0), +diff -uraN ../../orig/libopenmpt-0.4.0/debian/files ./debian/files +--- ../../orig/libopenmpt-0.4.0/debian/files 1969-12-31 19:00:00.000000000 -0500 ++++ ./debian/files 2019-01-04 16:37:20.001229883 -0500 +@@ -0,0 +1 @@ ++libopenmpt_0.4.0-ubuntu16.04.1~ppa10_source.buildinfo libs optional diff --git a/libs/libopenmpt/inc/libopenmpt/libopenmpt.h b/libs/libopenmpt/inc/libopenmpt/libopenmpt.h new file mode 100644 index 0000000000000000000000000000000000000000..d41324885e5255d0573597f610172b934c7e38e6 --- /dev/null +++ b/libs/libopenmpt/inc/libopenmpt/libopenmpt.h @@ -0,0 +1,1449 @@ +/* + * libopenmpt.h + * ------------ + * Purpose: libopenmpt public c interface + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + +#ifndef LIBOPENMPT_H +#define LIBOPENMPT_H + +#include "libopenmpt_config.h" +#include <stddef.h> +#include <stdint.h> + +/*! + * \page libopenmpt_c_overview C API + * + * \section libopenmpt_c_error Error Handling + * + * - Functions with no return value in the corresponding C++ API return 0 on + * failure and 1 on success. + * - Functions that return a string in the corresponding C++ API return a + * dynamically allocated const char *. In case of failure or memory allocation + * failure, a NULL pointer is returned. + * - Functions that return integer values signal error condition by returning + * an invalid value (-1 in most cases, 0 in some cases). + * - All functions that work on an \ref openmpt_module object will call an + * \ref openmpt_error_func and depending on the value returned by this function + * log the error code and/xor/or store it inside the openmpt_module object. + * Stored error codes can be accessed with the openmpt_module_error_get_last() + * and openmpt_module_error_get_last_message(). Stored errors will not get + * cleared automatically and should be reset with openmpt_module_error_clear(). + * - Some functions not directly related to an \ref openmpt_module object take + * an explicit \ref openmpt_error_func error function callback and a pointer to + * an int and behave analog to the functions working on an \ref openmpt_module + * object. + * + * \section libopenmpt_c_strings Strings + * + * - All strings returned from libopenmpt are encoded in UTF-8. + * - All strings passed to libopenmpt should also be encoded in UTF-8. + * Behaviour in case of invalid UTF-8 is unspecified. + * - libopenmpt does not enforce or expect any particular Unicode + * normalization form. + * - All strings returned from libopenmpt are dynamically allocated and must + * be freed with openmpt_free_string(). Do NOT use the C standard library + * free() for libopenmpt strings as that would make your code invalid on + * windows when dynamically linking against libopenmpt which itself statically + * links to the C runtime. + * - All strings passed to libopenmpt are copied. No ownership is assumed or + * transferred. + * + * \section libopenmpt_c_fileio File I/O + * + * libopenmpt can use 3 different strategies for file I/O. + * + * - openmpt_module_create_from_memory2() will load the module from the provided + * memory buffer, which will require loading all data upfront by the library + * caller. + * - openmpt_module_create2() with a seekable stream will load the module via + * callbacks to the stream interface. libopenmpt will not implement an + * additional buffering layer in this case which means the callbacks are assumed + * to be performant even with small i/o sizes. + * - openmpt_module_create2() with an unseekable stream will load the module via + * callbacks to the stream interface. libopempt will make an internal copy as + * it goes along, and sometimes have to pre-cache the whole file in case it + * needs to know the complete file size. This strategy is intended to be used + * if the file is located on a high latency network. + * + * | create function | speed | memory consumption | + * | ----------------------------------------------: | :----: | :----------------: | + * | openmpt_module_create_from_memory2() | <p style="background-color:green" >fast </p> | <p style="background-color:yellow">medium</p> | + * | openmpt_module_create2() with seekable stream | <p style="background-color:red" >slow </p> | <p style="background-color:green" >low </p> | + * | openmpt_module_create2() with unseekable stream | <p style="background-color:yellow">medium</p> | <p style="background-color:red" >high </p> | + * + * In all cases, the data or stream passed to the create function is no longer + * needed after the openmpt_module has been created and can be freed by the + * caller. + * + * \section libopenmpt_c_outputformat Output Format + * + * libopenmpt supports a wide range of PCM output formats: + * [8000..192000]/[mono|stereo|quad]/[f32|i16]. + * + * Unless you have some very specific requirements demanding a particular aspect + * of the output format, you should always prefer 48000/stereo/f32 as the + * libopenmpt PCM format. + * + * - Please prefer 48000Hz unless the user explicitly demands something else. + * Practically all audio equipment and file formats use 48000Hz nowadays. + * - Practically all module formats are made for stereo output. Mono will not + * give you any measurable speed improvements and can trivially be obtained from + * the stereo output anyway. Quad is not expected by almost all modules and even + * if they do use surround effects, they expect the effects to be mixed to + * stereo. + * - Floating point output provides headroom instead of hard clipping if the + * module is louder than 0dBFs, will give you a better signal-to-noise ratio + * than int16 output, and avoid the need to apply an additional dithering to the + * output by libopenmpt. Unless your platform has no floating point unit at all, + * floating point will thus also be slightly faster. + * + * \section libopenmpt_c_threads libopenmpt in multi-threaded environments + * + * - libopenmpt is thread-aware. + * - Individual libopenmpt objects are not thread-safe. + * - libopenmpt itself does not spawn any user-visible threads but may spawn + * threads for internal use. + * - You must ensure to only ever access a particular libopenmpt object from a + * single thread at a time. + * - Consecutive accesses can happen from different threads. + * - Different objects can be accessed concurrently from different threads. + * + * \section libopenmpt_c_staticlinking Statically linking to libopenmpt + * + * libopenmpt is implemented in C++. This implies that linking to libopenmpt + * statically requires linking to the C++ runtime and standard library. The + * **highly preferred and recommended** way to do this is by using the C++ + * compiler instead of the platform linker to do the linking. This will do all + * necessary things that are C++ specific (in particular, it will pull in the + * appropriate runtime and/or library). If for whatever reason it is not + * possible to use the C++ compiler for statically linking against libopenmpt, + * the libopenmpt build system can list the required libraries in the pkg-config + * file `libopenmpt.pc`. However, there is no reliable way to determine the name + * of the required library or libraries from within the build system. The + * libopenmpt autotools `configure` and plain `Makefile` honor the custom + * variable `CXXSTDLIB_PCLIBSPRIVATE` which serves the sole purpose of listing + * the standard library (or libraries) required for static linking. The contents + * of this variable will be put in `libopenmpt.pc` `Libs.private` and used for + * nothing else. + * + * This problem is inherent to libraries implemented in C++ that can also be used + * without a C++ compiler. Other libraries try to solve that by listing + * `-lstdc++` unconditionally in `Libs.private`. However, that will break + * platforms that use a different C++ standard library (in particular FreeBSD). + * + * See https://lists.freedesktop.org/archives/pkg-config/2016-August/001055.html . + * + * Dymically linking to libopenmpt does not require anything special and will + * work as usual (and exactly as done for libraries implemented in C). + * + * Note: This section does not apply when using Microsoft Visual Studio or + * Andriod NDK ndk-build build systems. + * + * \section libopenmpt_c_detailed Detailed documentation + * + * \ref libopenmpt_c + * + * In case a function is not documented here, you might want to look at the + * \ref libopenmpt_cpp documentation. The C and C++ APIs are kept semantically + * as close as possible. + * + * \section libopenmpt_c_examples Examples + * + * \subsection libopenmpt_c_example_unsafe Unsafe, simplified example without any error checking to get a first idea of the API + * \include libopenmpt_example_c_unsafe.c + * \subsection libopenmpt_c_example_file FILE* + * \include libopenmpt_example_c.c + * \subsection libopenmpt_c_example_inmemory in memory + * \include libopenmpt_example_c_mem.c + * \subsection libopenmpt_c_example_stdout reading FILE* and writing PCM data to STDOUT (usable without PortAudio) + * \include libopenmpt_example_c_stdout.c + * + */ + +/*! \defgroup libopenmpt_c libopenmpt C */ + +/*! \addtogroup libopenmpt_c + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \brief Get the libopenmpt version number + * + * Returns the libopenmpt version number. + * \return The value represents (major << 24 + minor << 16 + patch << 0). + * \remarks libopenmpt < 0.3.0-pre used the following scheme: (major << 24 + minor << 16 + revision). + */ +LIBOPENMPT_API uint32_t openmpt_get_library_version(void); + +/*! \brief Get the core version number + * + * Return the OpenMPT core version number. + * \return The value represents (majormajor << 24 + major << 16 + minor << 8 + minorminor). + */ +LIBOPENMPT_API uint32_t openmpt_get_core_version(void); + +/*! Return a verbose library version string from openmpt_get_string(). \deprecated Please use `"library_version"` directly. */ +#define OPENMPT_STRING_LIBRARY_VERSION LIBOPENMPT_DEPRECATED_STRING( "library_version" ) +/*! Return a verbose library features string from openmpt_get_string(). \deprecated Please use `"library_features"` directly. */ +#define OPENMPT_STRING_LIBRARY_FEATURES LIBOPENMPT_DEPRECATED_STRING( "library_features" ) +/*! Return a verbose OpenMPT core version string from openmpt_get_string(). \deprecated Please use `"core_version"` directly. */ +#define OPENMPT_STRING_CORE_VERSION LIBOPENMPT_DEPRECATED_STRING( "core_version" ) +/*! Return information about the current build (e.g. the build date or compiler used) from openmpt_get_string(). \deprecated Please use `"build"` directly. */ +#define OPENMPT_STRING_BUILD LIBOPENMPT_DEPRECATED_STRING( "build" ) +/*! Return all contributors from openmpt_get_string(). \deprecated Please use `"credits"` directly. */ +#define OPENMPT_STRING_CREDITS LIBOPENMPT_DEPRECATED_STRING( "credits" ) +/*! Return contact information about libopenmpt from openmpt_get_string(). \deprecated Please use `"contact"` directly. */ +#define OPENMPT_STRING_CONTACT LIBOPENMPT_DEPRECATED_STRING( "contact" ) +/*! Return the libopenmpt license from openmpt_get_string(). \deprecated Please use `"license"` directly. */ +#define OPENMPT_STRING_LICENSE LIBOPENMPT_DEPRECATED_STRING( "license" ) + +/*! \brief Free a string returned by libopenmpt + * + * Frees any string that got returned by libopenmpt. + */ +LIBOPENMPT_API void openmpt_free_string( const char * str ); + +/*! \brief Get library related metadata. + * + * \param key Key to query. + * Possible keys are: + * - "library_version": verbose library version string + * - "library_version_is_release": "1" if the version is an officially released version + * - "library_features": verbose library features string + * - "core_version": verbose OpenMPT core version string + * - "source_url": original source code URL + * - "source_date": original source code date + * - "source_revision": original source code revision + * - "source_is_modified": "1" if the original source has been modified + * - "source_has_mixed_revisions": "1" if the original source has been compiled from different various revision + * - "source_is_package": "1" if the original source has been obtained from a source pacakge instead of source code version control + * - "build": information about the current build (e.g. the build date or compiler used) + * - "build_compiler": information about the compiler used to build libopenmpt + * - "credits": all contributors + * - "contact": contact information about libopenmpt + * - "license": the libopenmpt license + * - "url": libopenmpt website URL + * - "support_forum_url": libopenmpt support and discussions forum URL + * - "bugtracker_url": libopenmpt bug and issue tracker URL + * \return A (possibly multi-line) string containing the queried information. If no information is available, the string is empty. + */ +LIBOPENMPT_API const char * openmpt_get_string( const char * key ); + +/*! \brief Get a list of supported file extensions + * + * \return The semicolon-separated list of extensions supported by this libopenmpt build. The extensions are returned lower-case without a leading dot. + */ +LIBOPENMPT_API const char * openmpt_get_supported_extensions(void); + +/*! \brief Query whether a file extension is supported + * + * \param extension file extension to query without a leading dot. The case is ignored. + * \return 1 if the extension is supported by libopenmpt, 0 otherwise. + */ +LIBOPENMPT_API int openmpt_is_extension_supported( const char * extension ); + +/*! Seek to the given offset relative to the beginning of the file. */ +#define OPENMPT_STREAM_SEEK_SET 0 +/*! Seek to the given offset relative to the current position in the file. */ +#define OPENMPT_STREAM_SEEK_CUR 1 +/*! Seek to the given offset relative to the end of the file. */ +#define OPENMPT_STREAM_SEEK_END 2 + +/*! \brief Read bytes from stream + * + * Read bytes data from stream to dst. + * \param stream Stream to read data from + * \param dst Target where to copy data. + * \param bytes Number of bytes to read. + * \return Number of bytes actually read and written to dst. + * \retval 0 End of stream or error. + * \remarks Short reads are allowed as long as they return at least 1 byte if EOF is not reached. + */ +typedef size_t (*openmpt_stream_read_func)( void * stream, void * dst, size_t bytes ); + +/*! \brief Seek stream position + * + * Seek to stream position offset at whence. + * \param stream Stream to operate on. + * \param offset Offset to seek to. + * \param whence OPENMPT_STREAM_SEEK_SET, OPENMPT_STREAM_SEEK_CUR, OPENMPT_STREAM_SEEK_END. See C89 documentation. + * \return Returns 0 on success. + * \retval 0 Success. + * \retval -1 Failure. Position does not get updated. + * \remarks libopenmpt will not try to seek beyond the file size, thus it is not important whether you allow for virtual positioning after the file end, or return an error in that case. The position equal to the file size needs to be seekable to. + */ +typedef int (*openmpt_stream_seek_func)( void * stream, int64_t offset, int whence ); + +/*! \brief Tell stream position + * + * Tell position of stream. + * \param stream Stream to operate on. + * \return Current position in stream. + * \retval -1 Failure. + */ +typedef int64_t (*openmpt_stream_tell_func)( void * stream ); + +/*! \brief Stream callbacks + * + * Stream callbacks used by libopenmpt for stream operations. + * \sa openmpt_stream_get_file_callbacks + * \sa openmpt_stream_get_fd_callbacks + * \sa openmpt_stream_get_buffer_callbacks + */ +typedef struct openmpt_stream_callbacks { + + /*! \brief Read callback. + * + * \sa openmpt_stream_read_func + */ + openmpt_stream_read_func read; + + /*! \brief Seek callback. + * + * Seek callback can be NULL if seeking is not supported. + * \sa openmpt_stream_seek_func + */ + openmpt_stream_seek_func seek; + + /*! \brief Tell callback. + * + * Tell callback can be NULL if seeking is not supported. + * \sa openmpt_stream_tell_func + */ + openmpt_stream_tell_func tell; + +} openmpt_stream_callbacks; + +/*! \brief Logging function + * + * \param message UTF-8 encoded log message. + * \param user User context that was passed to openmpt_module_create2(), openmpt_module_create_from_memory2() or openmpt_could_open_probability2(). + */ +typedef void (*openmpt_log_func)( const char * message, void * user ); + +/*! \brief Default logging function + * + * Default logging function that logs anything to stderr. + */ +LIBOPENMPT_API void openmpt_log_func_default( const char * message, void * user ); + +/*! \brief Silent logging function + * + * Silent logging function that throws any log message away. + */ +LIBOPENMPT_API void openmpt_log_func_silent( const char * message, void * user ); + +/*! No error. \since 0.3.0 */ +#define OPENMPT_ERROR_OK 0 + +/*! Lowest value libopenmpt will use for any of its own error codes. \since 0.3.0 */ +#define OPENMPT_ERROR_BASE 256 + +/*! Unknown internal error. \since 0.3.0 */ +#define OPENMPT_ERROR_UNKNOWN ( OPENMPT_ERROR_BASE + 1 ) + +/*! Unknown internal C++ exception. \since 0.3.0 */ +#define OPENMPT_ERROR_EXCEPTION ( OPENMPT_ERROR_BASE + 11 ) + +/*! Out of memory. \since 0.3.0 */ +#define OPENMPT_ERROR_OUT_OF_MEMORY ( OPENMPT_ERROR_BASE + 21 ) + +/*! Runtime error. \since 0.3.0 */ +#define OPENMPT_ERROR_RUNTIME ( OPENMPT_ERROR_BASE + 30 ) +/*! Range error. \since 0.3.0 */ +#define OPENMPT_ERROR_RANGE ( OPENMPT_ERROR_BASE + 31 ) +/*! Arithmetic overflow. \since 0.3.0 */ +#define OPENMPT_ERROR_OVERFLOW ( OPENMPT_ERROR_BASE + 32 ) +/*! Arithmetic underflow. \since 0.3.0 */ +#define OPENMPT_ERROR_UNDERFLOW ( OPENMPT_ERROR_BASE + 33 ) + +/*! Logic error. \since 0.3.0 */ +#define OPENMPT_ERROR_LOGIC ( OPENMPT_ERROR_BASE + 40 ) +/*! Value domain error. \since 0.3.0 */ +#define OPENMPT_ERROR_DOMAIN ( OPENMPT_ERROR_BASE + 41 ) +/*! Maximum supported size exceeded. \since 0.3.0 */ +#define OPENMPT_ERROR_LENGTH ( OPENMPT_ERROR_BASE + 42 ) +/*! Argument out of range. \since 0.3.0 */ +#define OPENMPT_ERROR_OUT_OF_RANGE ( OPENMPT_ERROR_BASE + 43 ) +/*! Invalid argument. \since 0.3.0 */ +#define OPENMPT_ERROR_INVALID_ARGUMENT ( OPENMPT_ERROR_BASE + 44 ) + +/*! General libopenmpt error. \since 0.3.0 */ +#define OPENMPT_ERROR_GENERAL ( OPENMPT_ERROR_BASE + 101 ) +/*! openmpt_module * is invalid. \since 0.3.0 */ +#define OPENMPT_ERROR_INVALID_MODULE_POINTER ( OPENMPT_ERROR_BASE + 102 ) +/*! NULL pointer argument. \since 0.3.0 */ +#define OPENMPT_ERROR_ARGUMENT_NULL_POINTER ( OPENMPT_ERROR_BASE + 103 ) + +/*! \brief Check whether the error is transient + * + * Checks whether an error code represents a transient error which may not occur again in a later try if for example memory has been freed up after an out-of-memory error. + * \param error Error code. + * \retval 0 Error is not transient. + * \retval 1 Error is transient. + * \sa OPENMPT_ERROR_OUT_OF_MEMORY + * \since 0.3.0 + */ +LIBOPENMPT_API int openmpt_error_is_transient( int error ); + +/*! \brief Convert error code to text + * + * Converts an error code into a text string describing the error. + * \param error Error code. + * \return Allocated string describing the error. + * \retval NULL Not enough memory to allocate the string. + * \since 0.3.0 + */ +LIBOPENMPT_API const char * openmpt_error_string( int error ); + +/*! Do not log or store the error. \since 0.3.0 */ +#define OPENMPT_ERROR_FUNC_RESULT_NONE 0 +/*! Log the error. \since 0.3.0 */ +#define OPENMPT_ERROR_FUNC_RESULT_LOG ( 1 << 0 ) +/*! Store the error. \since 0.3.0 */ +#define OPENMPT_ERROR_FUNC_RESULT_STORE ( 1 << 1 ) +/*! Log and store the error. \since 0.3.0 */ +#define OPENMPT_ERROR_FUNC_RESULT_DEFAULT ( OPENMPT_ERROR_FUNC_RESULT_LOG | OPENMPT_ERROR_FUNC_RESULT_STORE ) + +/*! \brief Error function + * + * \param error Error code. + * \param user User context that was passed to openmpt_module_create2(), openmpt_module_create_from_memory2() or openmpt_could_open_probability2(). + * \return Mask of OPENMPT_ERROR_FUNC_RESULT_LOG and OPENMPT_ERROR_FUNC_RESULT_STORE. + * \retval OPENMPT_ERROR_FUNC_RESULT_NONE Do not log or store the error. + * \retval OPENMPT_ERROR_FUNC_RESULT_LOG Log the error. + * \retval OPENMPT_ERROR_FUNC_RESULT_STORE Store the error. + * \retval OPENMPT_ERROR_FUNC_RESULT_DEFAULT Log and store the error. + * \sa OPENMPT_ERROR_FUNC_RESULT_NONE + * \sa OPENMPT_ERROR_FUNC_RESULT_LOG + * \sa OPENMPT_ERROR_FUNC_RESULT_STORE + * \sa OPENMPT_ERROR_FUNC_RESULT_DEFAULT + * \sa openmpt_error_func_default + * \sa openmpt_error_func_log + * \sa openmpt_error_func_store + * \sa openmpt_error_func_ignore + * \sa openmpt_error_func_errno + * \since 0.3.0 + */ +typedef int (*openmpt_error_func)( int error, void * user ); + +/*! \brief Default error function + * + * Causes all errors to be logged and stored. + * \param error Error code. + * \param user Ignored. + * \retval OPENMPT_ERROR_FUNC_RESULT_DEFAULT Always. + * \since 0.3.0 + */ +LIBOPENMPT_API int openmpt_error_func_default( int error, void * user ); + +/*! \brief Log error function + * + * Causes all errors to be logged. + * \param error Error code. + * \param user Ignored. + * \retval OPENMPT_ERROR_FUNC_RESULT_LOG Always. + * \since 0.3.0 + */ +LIBOPENMPT_API int openmpt_error_func_log( int error, void * user ); + +/*! \brief Store error function + * + * Causes all errors to be stored. + * \param error Error code. + * \param user Ignored. + * \retval OPENMPT_ERROR_FUNC_RESULT_STORE Always. + * \since 0.3.0 + */ +LIBOPENMPT_API int openmpt_error_func_store( int error, void * user ); + +/*! \brief Ignore error function + * + * Causes all errors to be neither logged nor stored. + * \param error Error code. + * \param user Ignored. + * \retval OPENMPT_ERROR_FUNC_RESULT_NONE Always. + * \since 0.3.0 + */ +LIBOPENMPT_API int openmpt_error_func_ignore( int error, void * user ); + +/*! \brief Errno error function + * + * Causes all errors to be stored in the pointer passed in as user. + * \param error Error code. + * \param user Pointer to an int as generated by openmpt_error_func_errno_userdata. + * \retval OPENMPT_ERROR_FUNC_RESULT_NONE user is not NULL. + * \retval OPENMPT_ERROR_FUNC_RESULT_DEFAULT user is NULL. + * \since 0.3.0 + */ +LIBOPENMPT_API int openmpt_error_func_errno( int error, void * user ); + +/*! \brief User pointer for openmpt_error_func_errno + * + * Provides a suitable user pointer argument for openmpt_error_func_errno. + * \param error Pointer to an integer value to be used as output by openmpt_error_func_errno. + * \retval (void*)error. + * \since 0.3.0 + */ +LIBOPENMPT_API void * openmpt_error_func_errno_userdata( int * error ); + +/*! \brief Roughly scan the input stream to find out whether libopenmpt might be able to open it + * + * \param stream_callbacks Input stream callback operations. + * \param stream Input stream to scan. + * \param effort Effort to make when validating stream. Effort 0.0 does not even look at stream at all and effort 1.0 completely loads the file from stream. A lower effort requires less data to be loaded but only gives a rough estimate answer. Use an effort of 0.25 to only verify the header data of the module file. + * \param logfunc Logging function where warning and errors are written. May be NULL. + * \param user Logging function user context. Used to pass any user-defined data associated with this module to the logging function. + * \return Probability between 0.0 and 1.0. + * \remarks openmpt_could_open_probability() can return any value between 0.0 and 1.0. Only 0.0 and 1.0 are definitive answers, all values in between are just estimates. In general, any return value >0.0 means that you should try loading the file, and any value below 1.0 means that loading may fail. If you want a threshold above which you can be reasonably sure that libopenmpt will be able to load the file, use >=0.5. If you see the need for a threshold below which you could reasonably outright reject a file, use <0.25 (Note: Such a threshold for rejecting on the lower end is not recommended, but may be required for better integration into some other framework's probe scoring.). + * \remarks openmpt_could_open_probability() expects the complete file data to be eventually available to it, even if it is asked to just parse the header. Verification will be unreliable (both false positives and false negatives), if you pretend that the file is just some few bytes of initial data threshold in size. In order to really just access the first bytes of a file, check in your callback functions whether data or seeking is requested beyond your initial data threshold, and in that case, return an error. openmpt_could_open_probability() will treat this as any other I/O error and return 0.0. You must not expect the correct result in this case. You instead must remember that it asked for more data than you currently want to provide to it and treat this situation as if openmpt_could_open_probability() returned 0.5. + * \sa \ref libopenmpt_c_fileio + * \sa openmpt_stream_callbacks + * \deprecated Please use openmpt_could_open_probability2(). + * \since 0.3.0 + */ +LIBOPENMPT_API LIBOPENMPT_DEPRECATED double openmpt_could_open_probability( openmpt_stream_callbacks stream_callbacks, void * stream, double effort, openmpt_log_func logfunc, void * user ); + +/*! \brief Roughly scan the input stream to find out whether libopenmpt might be able to open it + * + * \param stream_callbacks Input stream callback operations. + * \param stream Input stream to scan. + * \param effort Effort to make when validating stream. Effort 0.0 does not even look at stream at all and effort 1.0 completely loads the file from stream. A lower effort requires less data to be loaded but only gives a rough estimate answer. Use an effort of 0.25 to only verify the header data of the module file. + * \param logfunc Logging function where warning and errors are written. May be NULL. + * \param user Logging function user context. Used to pass any user-defined data associated with this module to the logging function. + * \return Probability between 0.0 and 1.0. + * \remarks openmpt_could_open_probability() can return any value between 0.0 and 1.0. Only 0.0 and 1.0 are definitive answers, all values in between are just estimates. In general, any return value >0.0 means that you should try loading the file, and any value below 1.0 means that loading may fail. If you want a threshold above which you can be reasonably sure that libopenmpt will be able to load the file, use >=0.5. If you see the need for a threshold below which you could reasonably outright reject a file, use <0.25 (Note: Such a threshold for rejecting on the lower end is not recommended, but may be required for better integration into some other framework's probe scoring.). + * \remarks openmpt_could_open_probability() expects the complete file data to be eventually available to it, even if it is asked to just parse the header. Verification will be unreliable (both false positives and false negatives), if you pretend that the file is just some few bytes of initial data threshold in size. In order to really just access the first bytes of a file, check in your callback functions whether data or seeking is requested beyond your initial data threshold, and in that case, return an error. openmpt_could_open_probability() will treat this as any other I/O error and return 0.0. You must not expect the correct result in this case. You instead must remember that it asked for more data than you currently want to provide to it and treat this situation as if openmpt_could_open_probability() returned 0.5. + * \sa \ref libopenmpt_c_fileio + * \sa openmpt_stream_callbacks + * \deprecated Please use openmpt_could_open_probability2(). + */ +LIBOPENMPT_API LIBOPENMPT_DEPRECATED double openmpt_could_open_propability( openmpt_stream_callbacks stream_callbacks, void * stream, double effort, openmpt_log_func logfunc, void * user ); + +/*! \brief Roughly scan the input stream to find out whether libopenmpt might be able to open it + * + * \param stream_callbacks Input stream callback operations. + * \param stream Input stream to scan. + * \param effort Effort to make when validating stream. Effort 0.0 does not even look at stream at all and effort 1.0 completely loads the file from stream. A lower effort requires less data to be loaded but only gives a rough estimate answer. Use an effort of 0.25 to only verify the header data of the module file. + * \param logfunc Logging function where warning and errors are written. May be NULL. + * \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function. + * \param errfunc Error function to define error behaviour. May be NULL. + * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. + * \param error Pointer to an integer where an error may get stored. May be NULL. + * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. + * \return Probability between 0.0 and 1.0. + * \remarks openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize() provide a simpler and faster interface that fits almost all use cases better. It is recommended to use openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize() instead of openmpt_could_open_probability(). + * \remarks openmpt_could_open_probability2() can return any value between 0.0 and 1.0. Only 0.0 and 1.0 are definitive answers, all values in between are just estimates. In general, any return value >0.0 means that you should try loading the file, and any value below 1.0 means that loading may fail. If you want a threshold above which you can be reasonably sure that libopenmpt will be able to load the file, use >=0.5. If you see the need for a threshold below which you could reasonably outright reject a file, use <0.25 (Note: Such a threshold for rejecting on the lower end is not recommended, but may be required for better integration into some other framework's probe scoring.). + * \remarks openmpt_could_open_probability2() expects the complete file data to be eventually available to it, even if it is asked to just parse the header. Verification will be unreliable (both false positives and false negatives), if you pretend that the file is just some few bytes of initial data threshold in size. In order to really just access the first bytes of a file, check in your callback functions whether data or seeking is requested beyond your initial data threshold, and in that case, return an error. openmpt_could_open_probability2() will treat this as any other I/O error and return 0.0. You must not expect the correct result in this case. You instead must remember that it asked for more data than you currently want to provide to it and treat this situation as if openmpt_could_open_probability2() returned 0.5. \include libopenmpt_example_c_probe.c + * \sa \ref libopenmpt_c_fileio + * \sa openmpt_stream_callbacks + * \sa openmpt_probe_file_header + * \sa openmpt_probe_file_header_without_filesize + * \since 0.3.0 + */ +LIBOPENMPT_API double openmpt_could_open_probability2( openmpt_stream_callbacks stream_callbacks, void * stream, double effort, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message ); + +/*! \brief Get recommended header size for successfull format probing + * + * \sa openmpt_probe_file_header() + * \sa openmpt_probe_file_header_without_filesize() + * \since 0.3.0 + */ +LIBOPENMPT_API size_t openmpt_probe_file_header_get_recommended_size(void); + +/*! Probe for module formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0 */ +#define OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES 0x1ul +/*! Probe for module-specific container formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0 */ +#define OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS 0x2ul + +/*! Probe for the default set of formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0 */ +#define OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT ( OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES | OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS ) +/*! Probe for no formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0 */ +#define OPENMPT_PROBE_FILE_HEADER_FLAGS_NONE 0x0ul + +/*! Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0 */ +#define OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS 1 +/*! Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0 */ +#define OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE 0 +/*! Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0 */ +#define OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA (-1) +/*! Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0 */ +#define OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR (-255) + +/*! \brief Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it + * + * \param flags Ored mask of OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES and OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS, or OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT. + * \param data Beginning of the file data. + * \param size Size of the beginning of the file data. + * \param filesize Full size of the file data on disk. + * \param logfunc Logging function where warning and errors are written. May be NULL. + * \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function. + * \param errfunc Error function to define error behaviour. May be NULL. + * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. + * \param error Pointer to an integer where an error may get stored. May be NULL. + * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. + * \remarks It is recommended to provide openmpt_probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size and filesize to the file's size. + * \remarks openmpt_could_open_probability2() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt_probe_file_header() though, if possible. + * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS The file will most likely be supported by libopenmpt. + * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE The file is not supported by libopenmpt. + * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA An answer could not be determined with the amount of data provided. + * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR An internal error occurred. + * \sa openmpt_probe_file_header_get_recommended_size() + * \sa openmpt_probe_file_header_without_filesize() + * \sa openmpt_probe_file_header_from_stream() + * \sa openmpt_could_open_probability2() + * \since 0.3.0 + */ +LIBOPENMPT_API int openmpt_probe_file_header( uint64_t flags, const void * data, size_t size, uint64_t filesize, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message ); +/*! \brief Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it + * + * \param flags Ored mask of OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES and OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS, or OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT. + * \param data Beginning of the file data. + * \param size Size of the beginning of the file data. + * \param logfunc Logging function where warning and errors are written. May be NULL. + * \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function. + * \param errfunc Error function to define error behaviour. May be NULL. + * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. + * \param error Pointer to an integer where an error may get stored. May be NULL. + * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. + * \remarks It is recommended to use openmpt_probe_file_header() and provide the acutal file's size as a parameter if at all possible. libopenmpt can provide more accurate answers if the filesize is known. + * \remarks It is recommended to provide openmpt_probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size to the file's size. + * \remarks openmpt_could_open_probability2() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt_probe_file_header() though, if possible. + * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS The file will most likely be supported by libopenmpt. + * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE The file is not supported by libopenmpt. + * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA An answer could not be determined with the amount of data provided. + * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR An internal error occurred. + * \sa openmpt_probe_file_header_get_recommended_size() + * \sa openmpt_probe_file_header() + * \sa openmpt_probe_file_header_from_stream() + * \sa openmpt_could_open_probability2() + * \since 0.3.0 + */ +LIBOPENMPT_API int openmpt_probe_file_header_without_filesize( uint64_t flags, const void * data, size_t size, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message ); + +/*! \brief Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it + * + * \param flags Ored mask of OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES and OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS, or OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT. + * \param stream_callbacks Input stream callback operations. + * \param stream Input stream to scan. + * \param logfunc Logging function where warning and errors are written. May be NULL. + * \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function. + * \param errfunc Error function to define error behaviour. May be NULL. + * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. + * \param error Pointer to an integer where an error may get stored. May be NULL. + * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. + * \remarks The stream is left in an unspecified state when this function returns. + * \remarks It is recommended to provide openmpt_probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size and filesize to the file's size. + * \remarks openmpt_could_open_probability2() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt_probe_file_header() though, if possible. + * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS The file will most likely be supported by libopenmpt. + * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE The file is not supported by libopenmpt. + * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA An answer could not be determined with the amount of data provided. + * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR An internal error occurred. + * \sa openmpt_probe_file_header_get_recommended_size() + * \sa openmpt_probe_file_header() + * \sa openmpt_probe_file_header_without_filesize() + * \sa openmpt_could_open_probability2() + * \since 0.3.0 + */ +LIBOPENMPT_API int openmpt_probe_file_header_from_stream( uint64_t flags, openmpt_stream_callbacks stream_callbacks, void * stream, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message ); + + +/*! \brief Opaque type representing a libopenmpt module + */ +typedef struct openmpt_module openmpt_module; + +typedef struct openmpt_module_initial_ctl { + const char * ctl; + const char * value; +} openmpt_module_initial_ctl; + +/*! \brief Construct an openmpt_module + * + * \param stream_callbacks Input stream callback operations. + * \param stream Input stream to load the module from. + * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. May be NULL. + * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) + * \param ctls A map of initial ctl values. See openmpt_module_get_ctls() + * \return A pointer to the constructed openmpt_module, or NULL on failure. + * \remarks The input data can be discarded after an openmpt_module has been constructed successfully. + * \sa openmpt_stream_callbacks + * \sa \ref libopenmpt_c_fileio + * \deprecated Please use openmpt_module_create2(). + */ +LIBOPENMPT_API LIBOPENMPT_DEPRECATED openmpt_module * openmpt_module_create( openmpt_stream_callbacks stream_callbacks, void * stream, openmpt_log_func logfunc, void * loguser, const openmpt_module_initial_ctl * ctls ); + +/*! \brief Construct an openmpt_module + * + * \param stream_callbacks Input stream callback operations. + * \param stream Input stream to load the module from. + * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. May be NULL. + * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) + * \param errfunc Error function to define error behaviour. May be NULL. + * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. + * \param error Pointer to an integer where an error may get stored. May be NULL. + * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. + * \param ctls A map of initial ctl values. See openmpt_module_get_ctls() + * \return A pointer to the constructed openmpt_module, or NULL on failure. + * \remarks The input data can be discarded after an openmpt_module has been constructed successfully. + * \sa openmpt_stream_callbacks + * \sa \ref libopenmpt_c_fileio + * \since 0.3.0 + */ +LIBOPENMPT_API openmpt_module * openmpt_module_create2( openmpt_stream_callbacks stream_callbacks, void * stream, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message, const openmpt_module_initial_ctl * ctls ); + +/*! \brief Construct an openmpt_module + * + * \param filedata Data to load the module from. + * \param filesize Amount of data available. + * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. + * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) + * \param ctls A map of initial ctl values. See openmpt_module_get_ctls() + * \return A pointer to the constructed openmpt_module, or NULL on failure. + * \remarks The input data can be discarded after an openmpt_module has been constructed successfully. + * \sa \ref libopenmpt_c_fileio + * \deprecated Please use openmpt_module_create_from_memory2(). + */ +LIBOPENMPT_API LIBOPENMPT_DEPRECATED openmpt_module * openmpt_module_create_from_memory( const void * filedata, size_t filesize, openmpt_log_func logfunc, void * loguser, const openmpt_module_initial_ctl * ctls ); + +/*! \brief Construct an openmpt_module + * + * \param filedata Data to load the module from. + * \param filesize Amount of data available. + * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. + * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) + * \param errfunc Error function to define error behaviour. May be NULL. + * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. + * \param error Pointer to an integer where an error may get stored. May be NULL. + * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. + * \param ctls A map of initial ctl values. See openmpt_module_get_ctls() + * \return A pointer to the constructed openmpt_module, or NULL on failure. + * \remarks The input data can be discarded after an openmpt_module has been constructed successfully. + * \sa \ref libopenmpt_c_fileio + * \since 0.3.0 + */ +LIBOPENMPT_API openmpt_module * openmpt_module_create_from_memory2( const void * filedata, size_t filesize, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message, const openmpt_module_initial_ctl * ctls ); + +/*! \brief Unload a previously created openmpt_module from memory. + * + * \param mod The module to unload. + */ +LIBOPENMPT_API void openmpt_module_destroy( openmpt_module * mod ); + +/*! \brief Set logging function. + * + * Set the logging function of an already constructed openmpt_module. + * \param mod The module handle to work on. + * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. + * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) + * \since 0.3.0 + */ +LIBOPENMPT_API void openmpt_module_set_log_func( openmpt_module * mod, openmpt_log_func logfunc, void * loguser ); + +/*! \brief Set error function. + * + * Set the error function of an already constructed openmpt_module. + * \param mod The module handle to work on. + * \param errfunc Error function to define error behaviour. May be NULL. + * \param erruser Error function user context. + * \since 0.3.0 + */ +LIBOPENMPT_API void openmpt_module_set_error_func( openmpt_module * mod, openmpt_error_func errfunc, void * erruser ); + +/*! \brief Get last error. + * + * Return the error currently stored in an openmpt_module. The stored error is not cleared. + * \param mod The module handle to work on. + * \return The error currently stored. + * \sa openmpt_module_error_get_last_message + * \sa openmpt_module_error_set_last + * \sa openmpt_module_error_clear + * \since 0.3.0 + */ +LIBOPENMPT_API int openmpt_module_error_get_last( openmpt_module * mod ); + +/*! \brief Get last error message. + * + * Return the error message currently stored in an openmpt_module. The stored error is not cleared. + * \param mod The module handle to work on. + * \return The error message currently stored. + * \sa openmpt_module_error_set_last + * \sa openmpt_module_error_clear + * \since 0.3.0 + */ +LIBOPENMPT_API const char * openmpt_module_error_get_last_message( openmpt_module * mod ); + +/*! \brief Set last error. + * + * Set the error currently stored in an openmpt_module. + * \param mod The module handle to work on. + * \param error Error to be stored. + * \sa openmpt_module_error_get_last + * \sa openmpt_module_error_clear + * \since 0.3.0 + */ +LIBOPENMPT_API void openmpt_module_error_set_last( openmpt_module * mod, int error ); + +/*! \brief Clear last error. + * + * Set the error currently stored in an openmpt_module to OPPENMPT_ERROR_OK. + * \param mod The module handle to work on. + * \sa openmpt_module_error_get_last + * \sa openmpt_module_error_set_last + * \since 0.3.0 + */ +LIBOPENMPT_API void openmpt_module_error_clear( openmpt_module * mod ); + +/** + * \defgroup openmpt_module_render_param Render param indices + * + * \brief Parameter index to use with openmpt_module_get_render_param() and openmpt_module_set_render_param() + * @{ + */ +/*! \brief Master Gain + * + * The related value represents a relative gain in milliBel.\n + * The default value is 0.\n + * The supported value range is unlimited.\n + */ +#define OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL 1 +/*! \brief Stereo Separation + * + * The related value represents the stereo separation generated by the libopenmpt mixer in percent.\n + * The default value is 100.\n + * The supported value range is [0,200].\n + */ +#define OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT 2 +/*! \brief Interpolation Filter + * + * The related value represents the interpolation filter length used by the libopenmpt mixer.\n + * The default value is 0, which indicates a recommended default value.\n + * The supported value range is [0,inf). Values greater than the implementation limit are clamped to the maximum supported value.\n + * Currently supported values: + * - 0: internal default + * - 1: no interpolation (zero order hold) + * - 2: linear interpolation + * - 4: cubic interpolation + * - 8: windowed sinc with 8 taps + */ +#define OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH 3 +/*! \brief Volume Ramping Strength + * + * The related value represents the amount of volume ramping done by the libopenmpt mixer.\n + * The default value is -1, which indicates a recommended default value.\n + * The meaningful value range is [-1..10].\n + * A value of 0 completely disables volume ramping. This might cause clicks in sound output.\n + * Higher values imply slower/softer volume ramps. + */ +#define OPENMPT_MODULE_RENDER_VOLUMERAMPING_STRENGTH 4 +/** @}*/ + +/** + * \defgroup openmpt_module_command_index Pattern cell indices + * + * \brief Parameter index to use with openmpt_module_get_pattern_row_channel_command(), openmpt_module_format_pattern_row_channel_command() and openmpt_module_highlight_pattern_row_channel_command() + * @{ + */ +#define OPENMPT_MODULE_COMMAND_NOTE 0 +#define OPENMPT_MODULE_COMMAND_INSTRUMENT 1 +#define OPENMPT_MODULE_COMMAND_VOLUMEEFFECT 2 +#define OPENMPT_MODULE_COMMAND_EFFECT 3 +#define OPENMPT_MODULE_COMMAND_VOLUME 4 +#define OPENMPT_MODULE_COMMAND_PARAMETER 5 +/** @}*/ + +/*! \brief Select a sub-song from a multi-song module + * + * \param mod The module handle to work on. + * \param subsong Index of the sub-song. -1 plays all sub-songs consecutively. + * \return 1 on success, 0 on failure. + * \sa openmpt_module_get_num_subsongs, openmpt_module_get_selected_subsong, openmpt_module_get_subsong_name + * \remarks Whether subsong -1 (all subsongs consecutively), subsong 0 or some other subsong is selected by default, is an implementation detail and subject to change. If you do not want to care about subsongs, it is recommended to just not call openmpt_module_select_subsong() at all. + */ +LIBOPENMPT_API int openmpt_module_select_subsong( openmpt_module * mod, int32_t subsong ); +/*! \brief Get currently selected sub-song from a multi-song module + * + * \param mod The module handle to work on. + * \return Currently selected sub-song. -1 for all subsongs consecutively, 0 or greater for the current sub-song index. + * \sa openmpt_module_get_num_subsongs, openmpt_module_select_subsong, openmpt_module_get_subsong_name + * \since 0.3.0 + */ +LIBOPENMPT_API int32_t openmpt_module_get_selected_subsong( openmpt_module * mod ); +/*! \brief Set Repeat Count + * + * \param mod The module handle to work on. + * \param repeat_count Repeat Count + * - -1: repeat forever + * - 0: play once, repeat zero times (the default) + * - n>0: play once and repeat n times after that + * \return 1 on success, 0 on failure. + * \sa openmpt_module_get_repeat_count + */ +LIBOPENMPT_API int openmpt_module_set_repeat_count( openmpt_module * mod, int32_t repeat_count ); +/*! \brief Get Repeat Count + * + * \param mod The module handle to work on. + * \return Repeat Count + * - -1: repeat forever + * - 0: play once, repeat zero times (the default) + * - n>0: play once and repeat n times after that + * \sa openmpt_module_set_repeat_count + */ +LIBOPENMPT_API int32_t openmpt_module_get_repeat_count( openmpt_module * mod ); + +/*! \brief approximate song duration + * + * \param mod The module handle to work on. + * \return Approximate duration of current sub-song in seconds. + */ +LIBOPENMPT_API double openmpt_module_get_duration_seconds( openmpt_module * mod ); + +/*! \brief Set approximate current song position + * + * \param mod The module handle to work on. + * \param seconds Seconds to seek to. If seconds is out of range, the position gets set to song start or end respectively. + * \return Approximate new song position in seconds. + * \sa openmpt_module_get_position_seconds + */ +LIBOPENMPT_API double openmpt_module_set_position_seconds( openmpt_module * mod, double seconds ); +/*! \brief Get current song position + * + * \param mod The module handle to work on. + * \return Current song position in seconds. + * \sa openmpt_module_set_position_seconds + */ +LIBOPENMPT_API double openmpt_module_get_position_seconds( openmpt_module * mod ); + +/*! \brief Set approximate current song position + * + * If order or row are out of range, to position is not modified and the current position is returned. + * \param mod The module handle to work on. + * \param order Pattern order number to seek to. + * \param row Pattern row number to seek to. + * \return Approximate new song position in seconds. + * \sa openmpt_module_set_position_seconds + * \sa openmpt_module_get_position_seconds + */ +LIBOPENMPT_API double openmpt_module_set_position_order_row( openmpt_module * mod, int32_t order, int32_t row ); + +/*! \brief Get render parameter + * + * \param mod The module handle to work on. + * \param param Parameter to query. See \ref openmpt_module_render_param + * \param value Pointer to the variable that receives the current value of the parameter. + * \return 1 on success, 0 on failure (invalid param or value is NULL). + * \sa OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL + * \sa OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT + * \sa OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH + * \sa OPENMPT_MODULE_RENDER_VOLUMERAMPING_STRENGTH + * \sa openmpt_module_set_render_param + */ +LIBOPENMPT_API int openmpt_module_get_render_param( openmpt_module * mod, int param, int32_t * value ); +/*! \brief Set render parameter + * + * \param mod The module handle to work on. + * \param param Parameter to set. See \ref openmpt_module_render_param + * \param value The value to set param to. + * \return 1 on success, 0 on failure (invalid param). + * \sa OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL + * \sa OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT + * \sa OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH + * \sa OPENMPT_MODULE_RENDER_VOLUMERAMPING_STRENGTH + * \sa openmpt_module_get_render_param + */ +LIBOPENMPT_API int openmpt_module_set_render_param( openmpt_module * mod, int param, int32_t value ); + +/*@{*/ +/*! \brief Render audio data + * + * \param mod The module handle to work on. + * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + * \param count Number of audio frames to render per channel. + * \param mono Pointer to a buffer of at least count elements that receives the mono/center output. + * \return The number of frames actually rendered. + * \retval 0 The end of song has been reached. + * \remarks The output buffers are only written to up to the returned number of elements. + * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + * \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. + * \sa \ref libopenmpt_c_outputformat + */ +LIBOPENMPT_API size_t openmpt_module_read_mono( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * mono ); +/*! \brief Render audio data + * + * \param mod The module handle to work on. + * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + * \param count Number of audio frames to render per channel. + * \param left Pointer to a buffer of at least count elements that receives the left output. + * \param right Pointer to a buffer of at least count elements that receives the right output. + * \return The number of frames actually rendered. + * \retval 0 The end of song has been reached. + * \remarks The output buffers are only written to up to the returned number of elements. + * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + * \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. + * \sa \ref libopenmpt_c_outputformat + */ +LIBOPENMPT_API size_t openmpt_module_read_stereo( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * left, int16_t * right ); +/*! \brief Render audio data + * + * \param mod The module handle to work on. + * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + * \param count Number of audio frames to render per channel. + * \param left Pointer to a buffer of at least count elements that receives the left output. + * \param right Pointer to a buffer of at least count elements that receives the right output. + * \param rear_left Pointer to a buffer of at least count elements that receives the rear left output. + * \param rear_right Pointer to a buffer of at least count elements that receives the rear right output. + * \return The number of frames actually rendered. + * \retval 0 The end of song has been reached. + * \remarks The output buffers are only written to up to the returned number of elements. + * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + * \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. + * \sa \ref libopenmpt_c_outputformat + */ +LIBOPENMPT_API size_t openmpt_module_read_quad( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * left, int16_t * right, int16_t * rear_left, int16_t * rear_right ); +/*! \brief Render audio data + * + * \param mod The module handle to work on. + * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + * \param count Number of audio frames to render per channel. + * \param mono Pointer to a buffer of at least count elements that receives the mono/center output. + * \return The number of frames actually rendered. + * \retval 0 The end of song has been reached. + * \remarks The output buffers are only written to up to the returned number of elements. + * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + * \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. + * \sa \ref libopenmpt_c_outputformat + */ +LIBOPENMPT_API size_t openmpt_module_read_float_mono( openmpt_module * mod, int32_t samplerate, size_t count, float * mono ); +/*! \brief Render audio data + * + * \param mod The module handle to work on. + * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + * \param count Number of audio frames to render per channel. + * \param left Pointer to a buffer of at least count elements that receives the left output. + * \param right Pointer to a buffer of at least count elements that receives the right output. + * \return The number of frames actually rendered. + * \retval 0 The end of song has been reached. + * \remarks The output buffers are only written to up to the returned number of elements. + * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + * \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. + * \sa \ref libopenmpt_c_outputformat + */ +LIBOPENMPT_API size_t openmpt_module_read_float_stereo( openmpt_module * mod, int32_t samplerate, size_t count, float * left, float * right ); +/*! \brief Render audio data + * + * \param mod The module handle to work on. + * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + * \param count Number of audio frames to render per channel. + * \param left Pointer to a buffer of at least count elements that receives the left output. + * \param right Pointer to a buffer of at least count elements that receives the right output. + * \param rear_left Pointer to a buffer of at least count elements that receives the rear left output. + * \param rear_right Pointer to a buffer of at least count elements that receives the rear right output. + * \return The number of frames actually rendered. + * \retval 0 The end of song has been reached. + * \remarks The output buffers are only written to up to the returned number of elements. + * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + * \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. + * \sa \ref libopenmpt_c_outputformat + */ +LIBOPENMPT_API size_t openmpt_module_read_float_quad( openmpt_module * mod, int32_t samplerate, size_t count, float * left, float * right, float * rear_left, float * rear_right ); +/*! \brief Render audio data + * + * \param mod The module handle to work on. + * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + * \param count Number of audio frames to render per channel. + * \param interleaved_stereo Pointer to a buffer of at least count*2 elements that receives the interleaved stereo output in the order (L,R). + * \return The number of frames actually rendered. + * \retval 0 The end of song has been reached. + * \remarks The output buffers are only written to up to the returned number of elements. + * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + * \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. + * \sa \ref libopenmpt_c_outputformat + */ +LIBOPENMPT_API size_t openmpt_module_read_interleaved_stereo( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * interleaved_stereo ); +/*! \brief Render audio data + * + * \param mod The module handle to work on. + * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + * \param count Number of audio frames to render per channel. + * \param interleaved_quad Pointer to a buffer of at least count*4 elements that receives the interleaved suad surround output in the order (L,R,RL,RR). + * \return The number of frames actually rendered. + * \retval 0 The end of song has been reached. + * \remarks The output buffers are only written to up to the returned number of elements. + * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + * \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. + * \sa \ref libopenmpt_c_outputformat + */ +LIBOPENMPT_API size_t openmpt_module_read_interleaved_quad( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * interleaved_quad ); +/*! \brief Render audio data + * + * \param mod The module handle to work on. + * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + * \param count Number of audio frames to render per channel. + * \param interleaved_stereo Pointer to a buffer of at least count*2 elements that receives the interleaved stereo output in the order (L,R). + * \return The number of frames actually rendered. + * \retval 0 The end of song has been reached. + * \remarks The output buffers are only written to up to the returned number of elements. + * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + * \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. + * \sa \ref libopenmpt_c_outputformat + */ +LIBOPENMPT_API size_t openmpt_module_read_interleaved_float_stereo( openmpt_module * mod, int32_t samplerate, size_t count, float * interleaved_stereo ); +/*! \brief Render audio data + * + * \param mod The module handle to work on. + * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + * \param count Number of audio frames to render per channel. + * \param interleaved_quad Pointer to a buffer of at least count*4 elements that receives the interleaved suad surround output in the order (L,R,RL,RR). + * \return The number of frames actually rendered. + * \retval 0 The end of song has been reached. + * \remarks The output buffers are only written to up to the returned number of elements. + * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + * \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. + * \sa \ref libopenmpt_c_outputformat +*/ +LIBOPENMPT_API size_t openmpt_module_read_interleaved_float_quad( openmpt_module * mod, int32_t samplerate, size_t count, float * interleaved_quad ); +/*@}*/ + +/*! \brief Get the list of supported metadata item keys + * + * \param mod The module handle to work on. + * \return Metadata item keys supported by openmpt_module_get_metadata, as a semicolon-separated list. + * \sa openmpt_module_get_metadata + */ +LIBOPENMPT_API const char * openmpt_module_get_metadata_keys( openmpt_module * mod ); +/*! \brief Get a metadata item value + * + * \param mod The module handle to work on. + * \param key Metadata item key to query. Use openmpt_module_get_metadata_keys to check for available keys. + * Possible keys are: + * - type: Module format extension (e.g. it) + * - type_long: Format name associated with the module format (e.g. Impulse Tracker) + * - originaltype: Module format extension (e.g. it) of the original module in case the actual type is a converted format (e.g. mo3 or gdm) + * - originaltype_long: Format name associated with the module format (e.g. Impulse Tracker) of the original module in case the actual type is a converted format (e.g. mo3 or gdm) + * - container: Container format the module file is embedded in, if any (e.g. umx) + * - container_long: Full container name if the module is embedded in a container (e.g. Unreal Music) + * - tracker: Tracker that was (most likely) used to save the module file, if known + * - artist: Author of the module + * - title: Module title + * - date: Date the module was last saved, in ISO-8601 format. + * - message: Song message. If the song message is empty or the module format does not support song messages, a list of instrument and sample names is returned instead. + * - message_raw: Song message. If the song message is empty or the module format does not support song messages, an empty string is returned. + * - warnings: A list of warnings that were generated while loading the module. + * \return The associated value for key. + * \sa openmpt_module_get_metadata_keys + */ +LIBOPENMPT_API const char * openmpt_module_get_metadata( openmpt_module * mod, const char * key ); + +/*! \brief Get the current speed + * + * \param mod The module handle to work on. + * \return The current speed in ticks per row. + */ +LIBOPENMPT_API int32_t openmpt_module_get_current_speed( openmpt_module * mod ); +/*! \brief Get the current tempo + * + * \param mod The module handle to work on. + * \return The current tempo in tracker units. The exact meaning of this value depends on the tempo mode being used. + */ +LIBOPENMPT_API int32_t openmpt_module_get_current_tempo( openmpt_module * mod ); +/*! \brief Get the current order + * + * \param mod The module handle to work on. + * \return The current order at which the module is being played back. + */ +LIBOPENMPT_API int32_t openmpt_module_get_current_order( openmpt_module * mod ); +/*! \brief Get the current pattern + * + * \param mod The module handle to work on. + * \return The current pattern that is being played. + */ +LIBOPENMPT_API int32_t openmpt_module_get_current_pattern( openmpt_module * mod ); +/*! \brief Get the current row + * + * \param mod The module handle to work on. + * \return The current row at which the current pattern is being played. + */ +LIBOPENMPT_API int32_t openmpt_module_get_current_row( openmpt_module * mod ); +/*! \brief Get the current amount of playing channels. + * + * \param mod The module handle to work on. + * \return The amount of sample channels that are currently being rendered. + */ +LIBOPENMPT_API int32_t openmpt_module_get_current_playing_channels( openmpt_module * mod ); + +/*! \brief Get an approximate indication of the channel volume. + * + * \param mod The module handle to work on. + * \param channel The channel whose volume should be retrieved. + * \return The approximate channel volume. + * \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. + */ +LIBOPENMPT_API float openmpt_module_get_current_channel_vu_mono( openmpt_module * mod, int32_t channel ); +/*! \brief Get an approximate indication of the channel volume on the front-left speaker. + * + * \param mod The module handle to work on. + * \param channel The channel whose volume should be retrieved. + * \return The approximate channel volume. + * \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. + */ +LIBOPENMPT_API float openmpt_module_get_current_channel_vu_left( openmpt_module * mod, int32_t channel ); +/*! \brief Get an approximate indication of the channel volume on the front-right speaker. + * + * \param mod The module handle to work on. + * \param channel The channel whose volume should be retrieved. + * \return The approximate channel volume. + * \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. + */ +LIBOPENMPT_API float openmpt_module_get_current_channel_vu_right( openmpt_module * mod, int32_t channel ); +/*! \brief Get an approximate indication of the channel volume on the rear-left speaker. + * + * \param mod The module handle to work on. + * \param channel The channel whose volume should be retrieved. + * \return The approximate channel volume. + * \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. + */ +LIBOPENMPT_API float openmpt_module_get_current_channel_vu_rear_left( openmpt_module * mod, int32_t channel ); +/*! \brief Get an approximate indication of the channel volume on the rear-right speaker. + * + * \param mod The module handle to work on. + * \param channel The channel whose volume should be retrieved. + * \return The approximate channel volume. + * \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. + */ +LIBOPENMPT_API float openmpt_module_get_current_channel_vu_rear_right( openmpt_module * mod, int32_t channel ); + +/*! \brief Get the number of sub-songs + * + * \param mod The module handle to work on. + * \return The number of sub-songs in the module. This includes any "hidden" songs (songs that share the same sequence, but start at different order indices) and "normal" sub-songs or "sequences" (if the format supports them). + * \sa openmpt_module_get_subsong_name, openmpt_module_select_subsong, openmpt_module_get_selected_subsong + */ +LIBOPENMPT_API int32_t openmpt_module_get_num_subsongs( openmpt_module * mod ); +/*! \brief Get the number of pattern channels + * + * \param mod The module handle to work on. + * \return The number of pattern channels in the module. Not all channels do necessarily contain data. + * \remarks The number of pattern channels is completely independent of the number of output channels. libopenmpt can render modules in mono, stereo or quad surround, but the choice of which of the three modes to use must not be made based on the return value of this function, which may be any positive integer amount. Only use this function for informational purposes. + */ +LIBOPENMPT_API int32_t openmpt_module_get_num_channels( openmpt_module * mod ); +/*! \brief Get the number of orders + * + * \param mod The module handle to work on. + * \return The number of orders in the current sequence of the module. + */ +LIBOPENMPT_API int32_t openmpt_module_get_num_orders( openmpt_module * mod ); +/*! \brief Get the number of patterns + * + * \param mod The module handle to work on. + * \return The number of distinct patterns in the module. + */ +LIBOPENMPT_API int32_t openmpt_module_get_num_patterns( openmpt_module * mod ); +/*! \brief Get the number of instruments + * + * \param mod The module handle to work on. + * \return The number of instrument slots in the module. Instruments are a layer on top of samples, and are not supported by all module formats. + */ +LIBOPENMPT_API int32_t openmpt_module_get_num_instruments( openmpt_module * mod ); +/*! \brief Get the number of samples + * + * \param mod The module handle to work on. + * \return The number of sample slots in the module. + */ +LIBOPENMPT_API int32_t openmpt_module_get_num_samples( openmpt_module * mod ); + +/*! \brief Get a sub-song name + * + * \param mod The module handle to work on. + * \param index The sub-song whose name should be retrieved + * \return The sub-song name. + * \sa openmpt_module_get_num_subsongs, openmpt_module_select_subsong, openmpt_module_get_selected_subsong + */ +LIBOPENMPT_API const char * openmpt_module_get_subsong_name( openmpt_module * mod, int32_t index ); +/*! \brief Get a channel name + * + * \param mod The module handle to work on. + * \param index The channel whose name should be retrieved + * \return The channel name. + * \sa openmpt_module_get_num_channels + */ +LIBOPENMPT_API const char * openmpt_module_get_channel_name( openmpt_module * mod, int32_t index ); +/*! \brief Get an order name + * + * \param mod The module handle to work on. + * \param index The order whose name should be retrieved + * \return The order name. + * \sa openmpt_module_get_num_orders + */ +LIBOPENMPT_API const char * openmpt_module_get_order_name( openmpt_module * mod, int32_t index ); +/*! \brief Get a pattern name + * + * \param mod The module handle to work on. + * \param index The pattern whose name should be retrieved + * \return The pattern name. + * \sa openmpt_module_get_num_patterns + */ +LIBOPENMPT_API const char * openmpt_module_get_pattern_name( openmpt_module * mod, int32_t index ); +/*! \brief Get an instrument name + * + * \param mod The module handle to work on. + * \param index The instrument whose name should be retrieved + * \return The instrument name. + * \sa openmpt_module_get_num_instruments + */ +LIBOPENMPT_API const char * openmpt_module_get_instrument_name( openmpt_module * mod, int32_t index ); +/*! \brief Get a sample name + * + * \param mod The module handle to work on. + * \param index The sample whose name should be retrieved + * \return The sample name. + * \sa openmpt_module_get_num_samples + */ +LIBOPENMPT_API const char * openmpt_module_get_sample_name( openmpt_module * mod, int32_t index ); + +/*! \brief Get pattern at order position + * + * \param mod The module handle to work on. + * \param order The order item whose pattern index should be retrieved. + * \return The pattern index found at the given order position of the current sequence. + */ +LIBOPENMPT_API int32_t openmpt_module_get_order_pattern( openmpt_module * mod, int32_t order ); +/*! \brief Get the number of rows in a pattern + * + * \param mod The module handle to work on. + * \param pattern The pattern whose row count should be retrieved. + * \return The number of rows in the given pattern. If the pattern does not exist, 0 is returned. + */ +LIBOPENMPT_API int32_t openmpt_module_get_pattern_num_rows( openmpt_module * mod, int32_t pattern ); + +/*! \brief Get raw pattern content + * + * \param mod The module handle to work on. + * \param pattern The pattern whose data should be retrieved. + * \param row The row from which the data should be retrieved. + * \param channel The channel from which the data should be retrieved. + * \param command The cell index at which the data should be retrieved. See \ref openmpt_module_command_index + * \return The internal, raw pattern data at the given pattern position. + */ +LIBOPENMPT_API uint8_t openmpt_module_get_pattern_row_channel_command( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, int command ); + +/*! \brief Get formatted (human-readable) pattern content + * + * \param mod The module handle to work on. + * \param pattern The pattern whose data should be retrieved. + * \param row The row from which the data should be retrieved. + * \param channel The channel from which the data should be retrieved. + * \param command The cell index at which the data should be retrieved. + * \return The formatted pattern data at the given pattern position. See \ref openmpt_module_command_index + * \sa openmpt_module_highlight_pattern_row_channel_command + */ +LIBOPENMPT_API const char * openmpt_module_format_pattern_row_channel_command( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, int command ); +/*! \brief Get highlighting information for formatted pattern content + * + * \param mod The module handle to work on. + * \param pattern The pattern whose data should be retrieved. + * \param row The row from which the data should be retrieved. + * \param channel The channel from which the data should be retrieved. + * \param command The cell index at which the data should be retrieved. See \ref openmpt_module_command_index + * \return The highlighting string for the formatted pattern data as retrieved by openmpt_module_get_pattern_row_channel_command at the given pattern position. + * \remarks The returned string will map each character position of the string returned by openmpt_module_get_pattern_row_channel_command to a highlighting instruction. + * Possible highlighting characters are: + * - " " : empty/space + * - "." : empty/dot + * - "n" : generic note + * - "m" : special note + * - "i" : generic instrument + * - "u" : generic volume column effect + * - "v" : generic volume column parameter + * - "e" : generic effect column effect + * - "f" : generic effect column parameter + * \sa openmpt_module_get_pattern_row_channel_command + */ +LIBOPENMPT_API const char * openmpt_module_highlight_pattern_row_channel_command( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, int command ); + +/*! \brief Get formatted (human-readable) pattern content + * + * \param mod The module handle to work on. + * \param pattern The pattern whose data should be retrieved. + * \param row The row from which the data should be retrieved. + * \param channel The channel from which the data should be retrieved. + * \param width The maximum number of characters the string should contain. 0 means no limit. + * \param pad If true, the string will be resized to the exact length provided in the width parameter. + * \return The formatted pattern data at the given pattern position. + * \sa openmpt_module_highlight_pattern_row_channel + */ +LIBOPENMPT_API const char * openmpt_module_format_pattern_row_channel( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, size_t width, int pad ); +/*! \brief Get highlighting information for formatted pattern content + * + * \param mod The module handle to work on. + * \param pattern The pattern whose data should be retrieved. + * \param row The row from which the data should be retrieved. + * \param channel The channel from which the data should be retrieved. + * \param width The maximum number of characters the string should contain. 0 means no limit. + * \param pad If true, the string will be resized to the exact length provided in the width parameter. + * \return The highlighting string for the formatted pattern data as retrieved by openmpt_module_format_pattern_row_channel at the given pattern position. + * \sa openmpt_module_format_pattern_row_channel + */ +LIBOPENMPT_API const char * openmpt_module_highlight_pattern_row_channel( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, size_t width, int pad ); + +/*! \brief Retrieve supported ctl keys + * + * \param mod The module handle to work on. + * \return A semicolon-separated list containing all supported ctl keys. + * \remarks Currently supported ctl values are: + * - load.skip_samples: Set to "1" to avoid loading samples into memory + * - load.skip_patterns: Set to "1" to avoid loading patterns into memory + * - load.skip_plugins: Set to "1" to avoid loading plugins + * - load.skip_subsongs_init: Set to "1" to avoid pre-initializing sub-songs. Skipping results in faster module loading but slower seeking. + * - seek.sync_samples: Set to "1" to sync sample playback when using openmpt_module_set_position_seconds or openmpt_module_set_position_order_row. + * - subsong: The current subsong. Setting it has identical semantics as openmpt_module_select_subsong(), getting it returns the currently selected subsong. + * - play.at_end: Chooses the behaviour when the end of song is reached: + * - "fadeout": Fades the module out for a short while. Subsequent reads after the fadeout will return 0 rendered frames. + * - "continue": Returns 0 rendered frames when the song end is reached. Subsequent reads will continue playing from the song start or loop start. + * - "stop": Returns 0 rendered frames when the song end is reached. Subsequent reads will return 0 rendered frames. + * - play.tempo_factor: Set a floating point tempo factor. "1.0" is the default tempo. + * - play.pitch_factor: Set a floating point pitch factor. "1.0" is the default pitch. + * - render.resampler.emulate_amiga: Set to "1" to enable the Amiga resampler for Amiga modules. This emulates the sound characteristics of the Paula chip and overrides the selected interpolation filter. Non-Amiga module formats are not affected by this setting. + * - render.opl.volume_factor: Set volume factor applied to synthesized OPL sounds, relative to the default OPL volume. + * - dither: Set the dither algorithm that is used for the 16 bit versions of openmpt_module_read. Supported values are: + * - 0: No dithering. + * - 1: Default mode. Chosen by OpenMPT code, might change. + * - 2: Rectangular, 0.5 bit depth, no noise shaping (original ModPlug Tracker). + * - 3: Rectangular, 1 bit depth, simple 1st order noise shaping + */ +LIBOPENMPT_API const char * openmpt_module_get_ctls( openmpt_module * mod ); +/*! \brief Get current ctl value + * + * \param mod The module handle to work on. + * \param ctl The ctl key whose value should be retrieved. + * \return The associated ctl value, or NULL on failure. + * \sa openmpt_module_get_ctls + */ +LIBOPENMPT_API const char * openmpt_module_ctl_get( openmpt_module * mod, const char * ctl ); +/*! \brief Set ctl value + * + * \param mod The module handle to work on. + * \param ctl The ctl key whose value should be set. + * \param value The value that should be set. + * \return 1 if successful, 0 in case the value is not sensible (e.g. negative tempo factor) or the ctl is not recognized. + * \sa openmpt_module_get_ctls + */ +LIBOPENMPT_API int openmpt_module_ctl_set( openmpt_module * mod, const char * ctl, const char * value ); + +/* remember to add new functions to both C and C++ interfaces and to increase OPENMPT_API_VERSION_MINOR */ + +#ifdef __cplusplus +} +#endif + +/*! + * @} + */ + +#endif /* LIBOPENMPT_H */ + diff --git a/libs/libopenmpt/inc/libopenmpt/libopenmpt.hpp b/libs/libopenmpt/inc/libopenmpt/libopenmpt.hpp new file mode 100644 index 0000000000000000000000000000000000000000..55097f8303a6ccc06ec9db58b7da1c454bcab453 --- /dev/null +++ b/libs/libopenmpt/inc/libopenmpt/libopenmpt.hpp @@ -0,0 +1,1015 @@ +/* + * libopenmpt.hpp + * -------------- + * Purpose: libopenmpt public c++ interface + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + +#ifndef LIBOPENMPT_HPP +#define LIBOPENMPT_HPP + +#include "libopenmpt_config.h" + +#include <exception> +#include <iosfwd> +#include <iostream> +#include <map> +#include <string> +#include <vector> + +#include <cstdint> + +/*! + * \page libopenmpt_cpp_overview C++ API + * + * \section libopenmpt_cpp_error Error Handling + * + * libopenmpt C++ uses C++ exception handling for errror reporting. + * + * Unless otherwise noted, any libopenmpt function may throw exceptions and + * all exceptions thrown by libopenmpt itself are derived from + * openmpt::exception. + * In addition, any libopenmpt function may also throw any exception specified + * by the C++ language and C++ standard library. These are all derived from + * std::exception. + * + * \section libopenmpt_cpp_strings Strings + * + * - All strings returned from libopenmpt are encoded in UTF-8. + * - All strings passed to libopenmpt should also be encoded in UTF-8. + * Behaviour in case of invalid UTF-8 is unspecified. + * - libopenmpt does not enforce or expect any particular Unicode + * normalization form. + * + * \section libopenmpt_cpp_fileio File I/O + * + * libopenmpt can use 3 different strategies for file I/O. + * + * - openmpt::module::module() with any kind of memory buffer as parameter will + * load the module from the provided memory buffer, which will require loading + * all data upfront by the library + * caller. + * - openmpt::module::module() with a seekable std::istream as parameter will + * load the module via the stream interface. libopenmpt will not implement an + * additional buffering layer in this case whih means the callbacks are assumed + * to be performant even with small i/o sizes. + * - openmpt::module::module() with an unseekable std::istream as parameter + * will load the module via the stream interface. libopempt will make an + * internal copy as it goes along, and sometimes have to pre-cache the whole + * file in case it needs to know the complete file size. This strategy is + * intended to be used if the file is located on a high latency network. + * + * | constructor | speed | memory consumption | + * | ----------------: | :----: | :----------------: | + * | memory buffer | <p style="background-color:green" >fast </p> | <p style="background-color:yellow">medium</p> | + * | seekable stream | <p style="background-color:red" >slow </p> | <p style="background-color:green" >low </p> | + * | unseekable stream | <p style="background-color:yellow">medium</p> | <p style="background-color:red" >high </p> | + * + * In all cases, the data or stream passed to the constructor is no longer + * needed after the openmpt::module has been constructed and can be destroyed + * by the caller. + * + * \section libopenmpt_cpp_outputformat Output Format + * + * libopenmpt supports a wide range of PCM output formats: + * [8000..192000]/[mono|stereo|quad]/[f32|i16]. + * + * Unless you have some very specific requirements demanding a particular aspect + * of the output format, you should always prefer 48000/stereo/f32 as the + * libopenmpt PCM format. + * + * - Please prefer 48000Hz unless the user explicitly demands something else. + * Practically all audio equipment and file formats use 48000Hz nowadays. + * - Practically all module formats are made for stereo output. Mono will not + * give you any measurable speed improvements and can trivially be obtained from + * the stereo output anyway. Quad is not expected by almost all modules and even + * if they do use surround effects, they expect the effects to be mixed to + * stereo. + * - Floating point output provides headroom instead of hard clipping if the + * module is louder than 0dBFs, will give you a better signal-to-noise ratio + * than int16 output, and avoid the need to apply an additional dithering to the + * output by libopenmpt. Unless your platform has no floating point unit at all, + * floating point will thus also be slightly faster. + * + * \section libopenmpt_cpp_threads libopenmpt in multi-threaded environments + * + * - libopenmpt is thread-aware. + * - Individual libopenmpt objects are not thread-safe. + * - libopenmpt itself does not spawn any user-visible threads but may spawn + * threads for internal use. + * - You must ensure to only ever access a particular libopenmpt object via + * non-const member functions from a single thread at a time. + * - You may access a particular libopenmpt objects concurrently from different + * threads when using only const member functions from all threads. + * - Consecutive accesses can happen from different threads. + * - Different objects can be accessed concurrently from different threads. + * + * \section libopenmpt-cpp-windows Windows support + * + * Using the libopenmpt C++ API when libopenmpt is compiled as a DLL on Windows + * requires `#define LIBOPENMPT_USE_DLL` (or some equivalent build system + * configuration) before `#include <libopenmpt/libopenmpt.hpp>` in order to + * correctly import the symbols from the DLL. + * + * \section libopenmpt-cpp-detailed Detailed documentation + * + * \ref libopenmpt_cpp + * + * \section libopenmpt_cpp_examples Example + * + * \include libopenmpt_example_cxx.cpp + * + */ + +/*! \defgroup libopenmpt_cpp libopenmpt C++ */ + +/*! \addtogroup libopenmpt_cpp + @{ +*/ + +namespace openmpt { + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4275) +#endif +//! libopenmpt exception base class +/*! + Base class used for all exceptions that are thrown by libopenmpt itself. Libopenmpt may additionally throw any exception thrown by the standard library which are all derived from std::exception. + \sa \ref libopenmpt_cpp_error +*/ +class LIBOPENMPT_CXX_API exception : public std::exception { +private: + char * text; +public: + exception( const std::string & text ) noexcept; + exception( const exception & other ) noexcept; + exception( exception && other ) noexcept; + exception & operator = ( const exception & other ) noexcept; + exception & operator = ( exception && other ) noexcept; + virtual ~exception() noexcept; + const char * what() const noexcept override; +}; // class exception +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +//! Get the libopenmpt version number +/*! + Returns the libopenmpt version number. + \return The value represents (major << 24 + minor << 16 + patch << 0). + \remarks libopenmpt < 0.3.0-pre used the following scheme: (major << 24 + minor << 16 + revision). +*/ +LIBOPENMPT_CXX_API std::uint32_t get_library_version(); + +//! Get the core version number +/*! + Return the OpenMPT core version number. + \return The value represents (majormajor << 24 + major << 16 + minor << 8 + minorminor). +*/ +LIBOPENMPT_CXX_API std::uint32_t get_core_version(); + +namespace string { + +//! Return a verbose library version string from openmpt::string::get(). \deprecated Please use `"library_version"` directly. +LIBOPENMPT_DEPRECATED static const char library_version LIBOPENMPT_ATTR_DEPRECATED [] = "library_version"; +//! Return a verbose library features string from openmpt::string::get(). \deprecated Please use `"library_features"` directly. +LIBOPENMPT_DEPRECATED static const char library_features LIBOPENMPT_ATTR_DEPRECATED [] = "library_features"; +//! Return a verbose OpenMPT core version string from openmpt::string::get(). \deprecated Please use `"core_version"` directly. +LIBOPENMPT_DEPRECATED static const char core_version LIBOPENMPT_ATTR_DEPRECATED [] = "core_version"; +//! Return information about the current build (e.g. the build date or compiler used) from openmpt::string::get(). \deprecated Please use `"build"` directly. +LIBOPENMPT_DEPRECATED static const char build LIBOPENMPT_ATTR_DEPRECATED [] = "build"; +//! Return all contributors from openmpt::string::get(). \deprecated Please use `"credits"` directly. +LIBOPENMPT_DEPRECATED static const char credits LIBOPENMPT_ATTR_DEPRECATED [] = "credits"; +//! Return contact information about libopenmpt from openmpt::string::get(). \deprecated Please use `"contact"` directly. +LIBOPENMPT_DEPRECATED static const char contact LIBOPENMPT_ATTR_DEPRECATED [] = "contact"; +//! Return the libopenmpt license from openmpt::string::get(). \deprecated Please use `"license"` directly. +LIBOPENMPT_DEPRECATED static const char license LIBOPENMPT_ATTR_DEPRECATED [] = "license"; + +//! Get library related metadata. +/*! + \param key Key to query. + Possible keys are: + - "library_version": verbose library version string + - "library_version_major": libopenmpt major version number + - "library_version_minor": libopenmpt minor version number + - "library_version_patch": libopenmpt patch version number + - "library_version_prerel": libopenmpt pre-release version string + - "library_version_is_release": "1" if the version is an officially released version + - "library_features": verbose library features string + - "core_version": verbose OpenMPT core version string + - "source_url": original source code URL + - "source_date": original source code date + - "source_revision": original source code revision + - "source_is_modified": "1" if the original source has been modified + - "source_has_mixed_revisions": "1" if the original source has been compiled from different various revision + - "source_is_package": "1" if the original source has been obtained from a source pacakge instead of source code version control + - "build": information about the current build (e.g. the build date or compiler used) + - "build_compiler": information about the compiler used to build libopenmpt + - "credits": all contributors + - "contact": contact information about libopenmpt + - "license": the libopenmpt license + - "url": libopenmpt website URL + - "support_forum_url": libopenmpt support and discussions forum URL + - "bugtracker_url": libopenmpt bug and issue tracker URL + + \return A (possibly multi-line) string containing the queried information. If no information is available, the string is empty. +*/ +LIBOPENMPT_CXX_API std::string get( const std::string & key ); + +} // namespace string + +//! Get a list of supported file extensions +/*! + \return The list of extensions supported by this libopenmpt build. The extensions are returned lower-case without a leading dot. +*/ +LIBOPENMPT_CXX_API std::vector<std::string> get_supported_extensions(); + +//! Query whether a file extension is supported +/*! + \param extension file extension to query without a leading dot. The case is ignored. + \return true if the extension is supported by libopenmpt, false otherwise. +*/ +LIBOPENMPT_CXX_API bool is_extension_supported( const std::string & extension ); + +//! Roughly scan the input stream to find out whether libopenmpt might be able to open it +/*! + \param stream Input stream to scan. + \param effort Effort to make when validating stream. Effort 0.0 does not even look at stream at all and effort 1.0 completely loads the file from stream. A lower effort requires less data to be loaded but only gives a rough estimate answer. Use an effort of 0.25 to only verify the header data of the module file. + \param log Log where warning and errors are written. + \return Probability between 0.0 and 1.0. + \remarks openmpt::probe_file_header() provides a simpler and faster interface that fits almost all use cases better. It is recommended to use openmpt::probe_file_header() instead of openmpt::could_open_probability(). + \remarks openmpt::could_open_probability() can return any value between 0.0 and 1.0. Only 0.0 and 1.0 are definitive answers, all values in between are just estimates. In general, any return value >0.0 means that you should try loading the file, and any value below 1.0 means that loading may fail. If you want a threshold above which you can be reasonably sure that libopenmpt will be able to load the file, use >=0.5. If you see the need for a threshold below which you could reasonably outright reject a file, use <0.25 (Note: Such a threshold for rejecting on the lower end is not recommended, but may be required for better integration into some other framework's probe scoring.). + \remarks openmpt::could_open_probability() expects the complete file data to be eventually available to it, even if it is asked to just parse the header. Verification will be unreliable (both false positives and false negatives), if you pretend that the file is just some few bytes of initial data threshold in size. In order to really just access the first bytes of a file, check in your std::istream implementation whether data or seeking is requested beyond your initial data threshold, and in that case, return an error. openmpt::could_open_probability() will treat this as any other I/O error and return 0.0. You must not expect the correct result in this case. You instead must remember that it asked for more data than you currently want to provide to it and treat this situation as if openmpt::could_open_probability() returned 0.5. + \sa \ref libopenmpt_c_fileio + \sa openmpt::probe_file_header() + \since 0.3.0 +*/ +LIBOPENMPT_CXX_API double could_open_probability( std::istream & stream, double effort = 1.0, std::ostream & log = std::clog ); + +//! Roughly scan the input stream to find out whether libopenmpt might be able to open it +/*! + \deprecated Please use openmpt::module::could_open_probability(). +*/ +LIBOPENMPT_ATTR_DEPRECATED LIBOPENMPT_CXX_API LIBOPENMPT_DEPRECATED double could_open_propability( std::istream & stream, double effort = 1.0, std::ostream & log = std::clog ); + +//! Get recommended header size for successfull format probing +/*! + \sa openmpt::probe_file_header() + \since 0.3.0 +*/ +LIBOPENMPT_CXX_API std::size_t probe_file_header_get_recommended_size(); + +//! Probe for module formats in openmpt::probe_file_header(). \since 0.3.0 +static const std::uint64_t probe_file_header_flags_modules = 0x1ul; + +//! Probe for module-specific container formats in openmpt::probe_file_header(). \since 0.3.0 +static const std::uint64_t probe_file_header_flags_containers = 0x2ul; + +//! Probe for the default set of formats in openmpt::probe_file_header(). \since 0.3.0 +static const std::uint64_t probe_file_header_flags_default = probe_file_header_flags_modules | probe_file_header_flags_containers; + +//! Probe for no formats in openmpt::probe_file_header(). \since 0.3.0 +static const std::uint64_t probe_file_header_flags_none = 0x0ul; + +//! Possible return values for openmpt::probe_file_header(). \since 0.3.0 +enum probe_file_header_result { + probe_file_header_result_success = 1, + probe_file_header_result_failure = 0, + probe_file_header_result_wantmoredata = -1 +}; + +//! Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it +/*! + \param flags Ored mask of openmpt::probe_file_header_flags_modules and openmpt::probe_file_header_flags_containers, or openmpt::probe_file_header_flags_default. + \param data Beginning of the file data. + \param size Size of the beginning of the file data. + \param filesize Full size of the file data on disk. + \remarks It is recommended to provide openmpt::probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size and filesize to the file's size. + \remarks openmpt::could_open_probability() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt::probe_file_header() though, if possible. + \retval probe_file_header_result_success The file will most likely be supported by libopenmpt. + \retval probe_file_header_result_failure The file is not supported by libopenmpt. + \retval probe_file_header_result_wantmoredata An answer could not be determined with the amount of data provided. + \sa openmpt::probe_file_header_get_recommended_size() + \sa openmpt::could_open_probability() + \since 0.3.0 +*/ +LIBOPENMPT_CXX_API int probe_file_header( std::uint64_t flags, const std::uint8_t * data, std::size_t size, std::uint64_t filesize ); + +//! Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it +/*! + \param flags Ored mask of openmpt::probe_file_header_flags_modules and openmpt::probe_file_header_flags_containers, or openmpt::probe_file_header_flags_default. + \param data Beginning of the file data. + \param size Size of the beginning of the file data. + \remarks It is recommended to use the overload of this function that also takes the filesize as parameter if at all possile. libopenmpt can provide more accurate answers if the filesize is known. + \remarks It is recommended to provide openmpt::probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size to the file's size. + \remarks openmpt::could_open_probability() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt::probe_file_header() though, if possible. + \retval probe_file_header_result_success The file will most likely be supported by libopenmpt. + \retval probe_file_header_result_failure The file is not supported by libopenmpt. + \retval probe_file_header_result_wantmoredata An answer could not be determined with the amount of data provided. + \sa openmpt::probe_file_header_get_recommended_size() + \sa openmpt::could_open_probability() + \since 0.3.0 +*/ +LIBOPENMPT_CXX_API int probe_file_header( std::uint64_t flags, const std::uint8_t * data, std::size_t size ); + +//! Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it +/*! + \param flags Ored mask of openmpt::probe_file_header_flags_modules and openmpt::probe_file_header_flags_containers, or openmpt::probe_file_header_flags_default. + \param stream Input stream to scan. + \remarks stream is left in an unspecified state when this function returns. + \remarks openmpt::could_open_probability() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt::probe_file_header() though, if possible. + \retval probe_file_header_result_success The file will most likely be supported by libopenmpt. + \retval probe_file_header_result_failure The file is not supported by libopenmpt. + \retval probe_file_header_result_wantmoredata An answer could not be determined with the amount of data provided. + \sa openmpt::probe_file_header_get_recommended_size() + \sa openmpt::could_open_probability() + \since 0.3.0 +*/ +LIBOPENMPT_CXX_API int probe_file_header( std::uint64_t flags, std::istream & stream ); + +class module_impl; + +class module_ext; + +namespace detail { + +typedef std::map< std::string, std::string > initial_ctls_map; + +} // namespace detail + +class LIBOPENMPT_CXX_API module { + + friend class module_ext; + +public: + + //! Parameter index to use with openmpt::module::get_render_param and openmpt::module::set_render_param + enum render_param { + //! Master Gain + /*! + The related value represents a relative gain in milliBel.\n + The default value is 0.\n + The supported value range is unlimited.\n + */ + RENDER_MASTERGAIN_MILLIBEL = 1, + //! Stereo Separation + /*! + The related value represents the stereo separation generated by the libopenmpt mixer in percent.\n + The default value is 100.\n + The supported value range is [0,200].\n + */ + RENDER_STEREOSEPARATION_PERCENT = 2, + //! Interpolation Filter + /*! + The related value represents the interpolation filter length used by the libopenmpt mixer.\n + The default value is 0, which indicates a recommended default value.\n + The supported value range is [0,inf). Values greater than the implementation limit are clamped to the maximum supported value.\n + Currently supported values: + - 0: internal default + - 1: no interpolation (zero order hold) + - 2: linear interpolation + - 4: cubic interpolation + - 8: windowed sinc with 8 taps + */ + RENDER_INTERPOLATIONFILTER_LENGTH = 3, + //! Volume Ramping Strength + /*! + The related value represents the amount of volume ramping done by the libopenmpt mixer.\n + The default value is -1, which indicates a recommended default value.\n + The meaningful value range is [-1..10].\n + A value of 0 completely disables volume ramping. This might cause clicks in sound output.\n + Higher values imply slower/softer volume ramps. + */ + RENDER_VOLUMERAMPING_STRENGTH = 4 + }; + + //! Parameter index to use with openmpt::module::get_pattern_row_channel_command, openmpt::module::format_pattern_row_channel_command and openmpt::module::highlight_pattern_row_channel_command + enum command_index { + command_note = 0, + command_instrument = 1, + command_volumeffect = 2, + command_effect = 3, + command_volume = 4, + command_parameter = 5 + }; + +private: + module_impl * impl; +private: + // non-copyable + module( const module & ); + void operator = ( const module & ); +private: + // for module_ext + module(); + void set_impl( module_impl * i ); +public: + //! Construct an openmpt::module + /*! + \param stream Input stream from which the module is loaded. After the constructor has finished successfully, the input position of stream is set to the byte after the last byte that has been read. If the constructor fails, the state of the input position of stream is undefined. + \param log Log where any warnings or errors are printed to. The lifetime of the reference has to be as long as the lifetime of the module instance. + \param ctls A map of initial ctl values, see openmpt::module::get_ctls. + \throws openmpt::exception Throws an exception derived from openmpt::exception in case the provided file cannot be opened. + \remarks The input data can be discarded after an openmpt::module has been constructed successfully. + \sa \ref libopenmpt_cpp_fileio + */ + module( std::istream & stream, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); + /*! + \param data Data to load the module from. + \param log Log where any warnings or errors are printed to. The lifetime of the reference has to be as long as the lifetime of the module instance. + \param ctls A map of initial ctl values, see openmpt::module::get_ctls. + \throws openmpt::exception Throws an exception derived from openmpt::exception in case the provided file cannot be opened. + \remarks The input data can be discarded after an openmpt::module has been constructed successfully. + \sa \ref libopenmpt_cpp_fileio + */ + module( const std::vector<std::uint8_t> & data, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); + /*! + \param beg Begin of data to load the module from. + \param end End of data to load the module from. + \param log Log where any warnings or errors are printed to. The lifetime of the reference has to be as long as the lifetime of the module instance. + \param ctls A map of initial ctl values, see openmpt::module::get_ctls. + \throws openmpt::exception Throws an exception derived from openmpt::exception in case the provided file cannot be opened. + \remarks The input data can be discarded after an openmpt::module has been constructed successfully. + \sa \ref libopenmpt_cpp_fileio + */ + module( const std::uint8_t * beg, const std::uint8_t * end, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); + /*! + \param data Data to load the module from. + \param size Amount of data available. + \param log Log where any warnings or errors are printed to. The lifetime of the reference has to be as long as the lifetime of the module instance. + \param ctls A map of initial ctl values, see openmpt::module::get_ctls. + \throws openmpt::exception Throws an exception derived from openmpt::exception in case the provided file cannot be opened. + \remarks The input data can be discarded after an openmpt::module has been constructed successfully. + \sa \ref libopenmpt_cpp_fileio + */ + module( const std::uint8_t * data, std::size_t size, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); + /*! + \param data Data to load the module from. + \param log Log where any warnings or errors are printed to. The lifetime of the reference has to be as long as the lifetime of the module instance. + \param ctls A map of initial ctl values, see openmpt::module::get_ctls. + \throws openmpt::exception Throws an exception derived from openmpt::exception in case the provided file cannot be opened. + \remarks The input data can be discarded after an openmpt::module has been constructed successfully. + \sa \ref libopenmpt_cpp_fileio + */ + module( const std::vector<char> & data, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); + /*! + \param beg Begin of data to load the module from. + \param end End of data to load the module from. + \param log Log where any warnings or errors are printed to. The lifetime of the reference has to be as long as the lifetime of the module instance. + \param ctls A map of initial ctl values, see openmpt::module::get_ctls. + \throws openmpt::exception Throws an exception derived from openmpt::exception in case the provided file cannot be opened. + \remarks The input data can be discarded after an openmpt::module has been constructed successfully. + \sa \ref libopenmpt_cpp_fileio + */ + module( const char * beg, const char * end, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); + /*! + \param data Data to load the module from. + \param size Amount of data available. + \param log Log where any warnings or errors are printed to. The lifetime of the reference has to be as long as the lifetime of the module instance. + \param ctls A map of initial ctl values, see openmpt::module::get_ctls. + \throws openmpt::exception Throws an exception derived from openmpt::exception in case the provided file cannot be opened. + \remarks The input data can be discarded after an openmpt::module has been constructed successfully. + \sa \ref libopenmpt_cpp_fileio + */ + module( const char * data, std::size_t size, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); + /*! + \param data Data to load the module from. + \param size Amount of data available. + \param log Log where any warnings or errors are printed to. The lifetime of the reference has to be as long as the lifetime of the module instance. + \param ctls A map of initial ctl values, see openmpt::module::get_ctls. + \throws openmpt::exception Throws an exception derived from openmpt::exception in case the provided file cannot be opened. + \remarks The input data can be discarded after an openmpt::module has been constructed successfully. + \sa \ref libopenmpt_cpp_fileio + */ + module( const void * data, std::size_t size, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); + virtual ~module(); +public: + + //! Select a sub-song from a multi-song module + /*! + \param subsong Index of the sub-song. -1 plays all sub-songs consecutively. + \throws openmpt::exception Throws an exception derived from openmpt::exception if sub-song is not in range [-1,openmpt::module::get_num_subsongs()[ + \sa openmpt::module::get_num_subsongs, openmpt::module::get_selected_subsong, openmpt::module::get_subsong_names + \remarks Whether subsong -1 (all subsongs consecutively), subsong 0 or some other subsong is selected by default, is an implementation detail and subject to change. If you do not want to care about subsongs, it is recommended to just not call openmpt::module::select_subsong() at all. + */ + void select_subsong( std::int32_t subsong ); + //! Get currently selected sub-song from a multi-song module + /*! + \return Currently selected sub-song. -1 for all subsongs consecutively, 0 or greater for the current sub-song index. + \sa openmpt::module::get_num_subsongs, openmpt::module::select_subsong, openmpt::module::get_subsong_names + \since 0.3.0 + */ + std::int32_t get_selected_subsong() const; + //! Set Repeat Count + /*! + \param repeat_count Repeat Count + - -1: repeat forever + - 0: play once, repeat zero times (the default) + - n>0: play once and repeat n times after that + \sa openmpt::module::get_repeat_count + */ + void set_repeat_count( std::int32_t repeat_count ); + //! Get Repeat Count + /*! + \return Repeat Count + - -1: repeat forever + - 0: play once, repeat zero times (the default) + - n>0: play once and repeat n times after that + \sa openmpt::module::set_repeat_count + */ + std::int32_t get_repeat_count() const; + + //! Get approximate song duration + /*! + \return Approximate duration of current sub-song in seconds. + */ + double get_duration_seconds() const; + + //! Set approximate current song position + /*! + \param seconds Seconds to seek to. If seconds is out of range, the position gets set to song start or end respectively. + \return Approximate new song position in seconds. + \sa openmpt::module::get_position_seconds + */ + double set_position_seconds( double seconds ); + //! Get current song position + /*! + \return Current song position in seconds. + \sa openmpt::module::set_position_seconds + */ + double get_position_seconds() const; + + //! Set approximate current song position + /*! + If order or row are out of range, to position is not modified and the current position is returned. + \param order Pattern order number to seek to. + \param row Pattern row number to seek to. + \return Approximate new song position in seconds. + \sa openmpt::module::set_position_seconds + \sa openmpt::module::get_position_seconds + */ + double set_position_order_row( std::int32_t order, std::int32_t row ); + + //! Get render parameter + /*! + \param param Parameter to query. See openmpt::module::render_param. + \return The current value of the parameter. + \throws openmpt::exception Throws an exception derived from openmpt::exception if param is invalid. + \sa openmpt::module::render_param + \sa openmpt::module::set_render_param + */ + std::int32_t get_render_param( int param ) const; + //! Set render parameter + /*! + \param param Parameter to set. See openmpt::module::render_param. + \param value The value to set param to. + \throws openmpt::exception Throws an exception derived from openmpt::exception if param is invalid or value is out of range. + \sa openmpt::module::render_param + \sa openmpt::module::get_render_param + */ + void set_render_param( int param, std::int32_t value ); + + /*@{*/ + //! Render audio data + /*! + \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + \param count Number of audio frames to render per channel. + \param mono Pointer to a buffer of at least count elements that receives the mono/center output. + \return The number of frames actually rendered. + \retval 0 The end of song has been reached. + \remarks The output buffers are only written to up to the returned number of elements. + \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. + \sa \ref libopenmpt_cpp_outputformat + */ + std::size_t read( std::int32_t samplerate, std::size_t count, std::int16_t * mono ); + //! Render audio data + /*! + \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + \param count Number of audio frames to render per channel. + \param left Pointer to a buffer of at least count elements that receives the left output. + \param right Pointer to a buffer of at least count elements that receives the right output. + \return The number of frames actually rendered. + \retval 0 The end of song has been reached. + \remarks The output buffers are only written to up to the returned number of elements. + \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. + \sa \ref libopenmpt_cpp_outputformat + */ + std::size_t read( std::int32_t samplerate, std::size_t count, std::int16_t * left, std::int16_t * right ); + //! Render audio data + /*! + \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + \param count Number of audio frames to render per channel. + \param left Pointer to a buffer of at least count elements that receives the left output. + \param right Pointer to a buffer of at least count elements that receives the right output. + \param rear_left Pointer to a buffer of at least count elements that receives the rear left output. + \param rear_right Pointer to a buffer of at least count elements that receives the rear right output. + \return The number of frames actually rendered. + \retval 0 The end of song has been reached. + \remarks The output buffers are only written to up to the returned number of elements. + \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. + \sa \ref libopenmpt_cpp_outputformat + */ + std::size_t read( std::int32_t samplerate, std::size_t count, std::int16_t * left, std::int16_t * right, std::int16_t * rear_left, std::int16_t * rear_right ); + //! Render audio data + /*! + \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + \param count Number of audio frames to render per channel. + \param mono Pointer to a buffer of at least count elements that receives the mono/center output. + \return The number of frames actually rendered. + \retval 0 The end of song has been reached. + \remarks The output buffers are only written to up to the returned number of elements. + \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. + \sa \ref libopenmpt_cpp_outputformat + */ + std::size_t read( std::int32_t samplerate, std::size_t count, float * mono ); + //! Render audio data + /*! + \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + \param count Number of audio frames to render per channel. + \param left Pointer to a buffer of at least count elements that receives the left output. + \param right Pointer to a buffer of at least count elements that receives the right output. + \return The number of frames actually rendered. + \retval 0 The end of song has been reached. + \remarks The output buffers are only written to up to the returned number of elements. + \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. + \sa \ref libopenmpt_cpp_outputformat + */ + std::size_t read( std::int32_t samplerate, std::size_t count, float * left, float * right ); + //! Render audio data + /*! + \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + \param count Number of audio frames to render per channel. + \param left Pointer to a buffer of at least count elements that receives the left output. + \param right Pointer to a buffer of at least count elements that receives the right output. + \param rear_left Pointer to a buffer of at least count elements that receives the rear left output. + \param rear_right Pointer to a buffer of at least count elements that receives the rear right output. + \return The number of frames actually rendered. + \retval 0 The end of song has been reached. + \remarks The output buffers are only written to up to the returned number of elements. + \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. + \sa \ref libopenmpt_cpp_outputformat + */ + std::size_t read( std::int32_t samplerate, std::size_t count, float * left, float * right, float * rear_left, float * rear_right ); + //! Render audio data + /*! + \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + \param count Number of audio frames to render per channel. + \param interleaved_stereo Pointer to a buffer of at least count*2 elements that receives the interleaved stereo output in the order (L,R). + \return The number of frames actually rendered. + \retval 0 The end of song has been reached. + \remarks The output buffers are only written to up to the returned number of elements. + \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. + \sa \ref libopenmpt_cpp_outputformat + */ + std::size_t read_interleaved_stereo( std::int32_t samplerate, std::size_t count, std::int16_t * interleaved_stereo ); + //! Render audio data + /*! + \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + \param count Number of audio frames to render per channel. + \param interleaved_quad Pointer to a buffer of at least count*4 elements that receives the interleaved suad surround output in the order (L,R,RL,RR). + \return The number of frames actually rendered. + \retval 0 The end of song has been reached. + \remarks The output buffers are only written to up to the returned number of elements. + \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping. + \sa \ref libopenmpt_cpp_outputformat + */ + std::size_t read_interleaved_quad( std::int32_t samplerate, std::size_t count, std::int16_t * interleaved_quad ); + //! Render audio data + /*! + \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + \param count Number of audio frames to render per channel. + \param interleaved_stereo Pointer to a buffer of at least count*2 elements that receives the interleaved stereo output in the order (L,R). + \return The number of frames actually rendered. + \retval 0 The end of song has been reached. + \remarks The output buffers are only written to up to the returned number of elements. + \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. + \sa \ref libopenmpt_cpp_outputformat + */ + std::size_t read_interleaved_stereo( std::int32_t samplerate, std::size_t count, float * interleaved_stereo ); + //! Render audio data + /*! + \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced. + \param count Number of audio frames to render per channel. + \param interleaved_quad Pointer to a buffer of at least count*4 elements that receives the interleaved suad surround output in the order (L,R,RL,RR). + \return The number of frames actually rendered. + \retval 0 The end of song has been reached. + \remarks The output buffers are only written to up to the returned number of elements. + \remarks You can freely switch between any of the "read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module. + \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot. + \sa \ref libopenmpt_cpp_outputformat + */ + std::size_t read_interleaved_quad( std::int32_t samplerate, std::size_t count, float * interleaved_quad ); + /*@}*/ + + //! Get the list of supported metadata item keys + /*! + \return Metadata item keys supported by openmpt::module::get_metadata + \sa openmpt::module::get_metadata + */ + std::vector<std::string> get_metadata_keys() const; + //! Get a metadata item value + /*! + \param key Metadata item key to query. Use openmpt::module::get_metadata_keys to check for available keys. + Possible keys are: + - type: Module format extension (e.g. it) + - type_long: Format name associated with the module format (e.g. Impulse Tracker) + - originaltype: Module format extension (e.g. it) of the original module in case the actual type is a converted format (e.g. mo3 or gdm) + - originaltype_long: Format name associated with the module format (e.g. Impulse Tracker) of the original module in case the actual type is a converted format (e.g. mo3 or gdm) + - container: Container format the module file is embedded in, if any (e.g. umx) + - container_long: Full container name if the module is embedded in a container (e.g. Unreal Music) + - tracker: Tracker that was (most likely) used to save the module file, if known + - artist: Author of the module + - title: Module title + - date: Date the module was last saved, in ISO-8601 format. + - message: Song message. If the song message is empty or the module format does not support song messages, a list of instrument and sample names is returned instead. + - message_raw: Song message. If the song message is empty or the module format does not support song messages, an empty string is returned. + - warnings: A list of warnings that were generated while loading the module. + \return The associated value for key. + \sa openmpt::module::get_metadata_keys + */ + std::string get_metadata( const std::string & key ) const; + + //! Get the current speed + /*! + \return The current speed in ticks per row. + */ + std::int32_t get_current_speed() const; + //! Get the current tempo + /*! + \return The current tempo in tracker units. The exact meaning of this value depends on the tempo mode being used. + */ + std::int32_t get_current_tempo() const; + //! Get the current order + /*! + \return The current order at which the module is being played back. + */ + std::int32_t get_current_order() const; + //! Get the current pattern + /*! + \return The current pattern that is being played. + */ + std::int32_t get_current_pattern() const; + //! Get the current row + /*! + \return The current row at which the current pattern is being played. + */ + std::int32_t get_current_row() const; + //! Get the current amount of playing channels. + /*! + \return The amount of sample channels that are currently being rendered. + */ + std::int32_t get_current_playing_channels() const; + + //! Get an approximate indication of the channel volume. + /*! + \param channel The channel whose volume should be retrieved. + \return The approximate channel volume. + \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. + */ + float get_current_channel_vu_mono( std::int32_t channel ) const; + //! Get an approximate indication of the channel volume on the front-left speaker. + /*! + \param channel The channel whose volume should be retrieved. + \return The approximate channel volume. + \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. + */ + float get_current_channel_vu_left( std::int32_t channel ) const; + //! Get an approximate indication of the channel volume on the front-right speaker. + /*! + \param channel The channel whose volume should be retrieved. + \return The approximate channel volume. + \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. + */ + float get_current_channel_vu_right( std::int32_t channel ) const; + //! Get an approximate indication of the channel volume on the rear-left speaker. + /*! + \param channel The channel whose volume should be retrieved. + \return The approximate channel volume. + \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. + */ + float get_current_channel_vu_rear_left( std::int32_t channel ) const; + //! Get an approximate indication of the channel volume on the rear-right speaker. + /*! + \param channel The channel whose volume should be retrieved. + \return The approximate channel volume. + \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account. + */ + float get_current_channel_vu_rear_right( std::int32_t channel ) const; + + //! Get the number of sub-songs + /*! + \return The number of sub-songs in the module. This includes any "hidden" songs (songs that share the same sequence, but start at different order indices) and "normal" sub-songs or "sequences" (if the format supports them). + \sa openmpt::module::get_subsong_names, openmpt::module::select_subsong, openmpt::module::get_selected_subsong + */ + std::int32_t get_num_subsongs() const; + //! Get the number of pattern channels + /*! + \return The number of pattern channels in the module. Not all channels do necessarily contain data. + \remarks The number of pattern channels is completely independent of the number of output channels. libopenmpt can render modules in mono, stereo or quad surround, but the choice of which of the three modes to use must not be made based on the return value of this function, which may be any positive integer amount. Only use this function for informational purposes. + */ + std::int32_t get_num_channels() const; + //! Get the number of orders + /*! + \return The number of orders in the current sequence of the module. + */ + std::int32_t get_num_orders() const; + //! Get the number of patterns + /*! + \return The number of distinct patterns in the module. + */ + std::int32_t get_num_patterns() const; + //! Get the number of instruments + /*! + \return The number of instrument slots in the module. Instruments are a layer on top of samples, and are not supported by all module formats. + */ + std::int32_t get_num_instruments() const; + //! Get the number of samples + /*! + \return The number of sample slots in the module. + */ + std::int32_t get_num_samples() const; + + //! Get a list of sub-song names + /*! + \return All sub-song names. + \sa openmpt::module::get_num_subsongs, openmpt::module::select_subsong, openmpt::module::get_selected_subsong + */ + std::vector<std::string> get_subsong_names() const; + //! Get a list of channel names + /*! + \return All channel names. + \sa openmpt::module::get_num_channels + */ + std::vector<std::string> get_channel_names() const; + //! Get a list of order names + /*! + \return All order names. + \sa openmpt::module::get_num_orders + */ + std::vector<std::string> get_order_names() const; + //! Get a list of pattern names + /*! + \return All pattern names. + \sa openmpt::module::get_num_patterns + */ + std::vector<std::string> get_pattern_names() const; + //! Get a list of instrument names + /*! + \return All instrument names. + \sa openmpt::module::get_num_instruments + */ + std::vector<std::string> get_instrument_names() const; + //! Get a list of sample names + /*! + \return All sample names. + \sa openmpt::module::get_num_samples + */ + std::vector<std::string> get_sample_names() const; + + //! Get pattern at order position + /*! + \param order The order item whose pattern index should be retrieved. + \return The pattern index found at the given order position of the current sequence. + */ + std::int32_t get_order_pattern( std::int32_t order ) const; + + //! Get the number of rows in a pattern + /*! + \param pattern The pattern whose row count should be retrieved. + \return The number of rows in the given pattern. If the pattern does not exist, 0 is returned. + */ + std::int32_t get_pattern_num_rows( std::int32_t pattern ) const; + + //! Get raw pattern content + /*! + \param pattern The pattern whose data should be retrieved. + \param row The row from which the data should be retrieved. + \param channel The channel from which the data should be retrieved. + \param command The cell index at which the data should be retrieved. See openmpt::module::command_index + \return The internal, raw pattern data at the given pattern position. + */ + std::uint8_t get_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const; + + //! Get formatted (human-readable) pattern content + /*! + \param pattern The pattern whose data should be retrieved. + \param row The row from which the data should be retrieved. + \param channel The channel from which the data should be retrieved. + \param command The cell index at which the data should be retrieved. + \return The formatted pattern data at the given pattern position. See openmpt::module::command_index + \sa openmpt::module::highlight_pattern_row_channel_command + */ + std::string format_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const; + + //! Get highlighting information for formatted pattern content + /*! + \param pattern The pattern whose data should be retrieved. + \param row The row from which the data should be retrieved. + \param channel The channel from which the data should be retrieved. + \param command The cell index at which the data should be retrieved. See openmpt::module::command_index + \return The highlighting string for the formatted pattern data as retrieved by openmpt::module::get_pattern_row_channel_command at the given pattern position. + \remarks The returned string will map each character position of the string returned by openmpt::module::get_pattern_row_channel_command to a highlighting instruction. + Possible highlighting characters are: + - " " : empty/space + - "." : empty/dot + - "n" : generic note + - "m" : special note + - "i" : generic instrument + - "u" : generic volume column effect + - "v" : generic volume column parameter + - "e" : generic effect column effect + - "f" : generic effect column parameter + \sa openmpt::module::get_pattern_row_channel_command + */ + std::string highlight_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const; + + //! Get formatted (human-readable) pattern content + /*! + \param pattern The pattern whose data should be retrieved. + \param row The row from which the data should be retrieved. + \param channel The channel from which the data should be retrieved. + \param width The maximum number of characters the string should contain. 0 means no limit. + \param pad If true, the string will be resized to the exact length provided in the width parameter. + \return The formatted pattern data at the given pattern position. + \sa openmpt::module::highlight_pattern_row_channel + */ + std::string format_pattern_row_channel( std::int32_t pattern, std::int32_t row, std::int32_t channel, std::size_t width = 0, bool pad = true ) const; + //! Get highlighting information for formatted pattern content + /*! + \param pattern The pattern whose data should be retrieved. + \param row The row from which the data should be retrieved. + \param channel The channel from which the data should be retrieved. + \param width The maximum number of characters the string should contain. 0 means no limit. + \param pad If true, the string will be resized to the exact length provided in the width parameter. + \return The highlighting string for the formatted pattern data as retrieved by openmpt::module::format_pattern_row_channel at the given pattern position. + \sa openmpt::module::format_pattern_row_channel + */ + std::string highlight_pattern_row_channel( std::int32_t pattern, std::int32_t row, std::int32_t channel, std::size_t width = 0, bool pad = true ) const; + + //! Retrieve supported ctl keys + /*! + \return A vector containing all supported ctl keys. + \remarks Currently supported ctl values are: + - load.skip_samples: Set to "1" to avoid loading samples into memory + - load.skip_patterns: Set to "1" to avoid loading patterns into memory + - load.skip_plugins: Set to "1" to avoid loading plugins + - load.skip_subsongs_init: Set to "1" to avoid pre-initializing sub-songs. Skipping results in faster module loading but slower seeking. + - seek.sync_samples: Set to "1" to sync sample playback when using openmpt::module::set_position_seconds or openmpt::module::set_position_order_row. + - subsong: The current subsong. Setting it has identical semantics as openmpt::module::select_subsong(), getting it returns the currently selected subsong. + - play.at_end: Chooses the behaviour when the end of song is reached: + - "fadeout": Fades the module out for a short while. Subsequent reads after the fadeout will return 0 rendered frames. + - "continue": Returns 0 rendered frames when the song end is reached. Subsequent reads will continue playing from the song start or loop start. + - "stop": Returns 0 rendered frames when the song end is reached. Subsequent reads will return 0 rendered frames. + - play.tempo_factor: Set a floating point tempo factor. "1.0" is the default tempo. + - play.pitch_factor: Set a floating point pitch factor. "1.0" is the default pitch. + - render.resampler.emulate_amiga: Set to "1" to enable the Amiga resampler for Amiga modules. This emulates the sound characteristics of the Paula chip and overrides the selected interpolation filter. Non-Amiga module formats are not affected by this setting. + - render.opl.volume_factor: Set volume factor applied to synthesized OPL sounds, relative to the default OPL volume. + - dither: Set the dither algorithm that is used for the 16 bit versions of openmpt::module::read. Supported values are: + - 0: No dithering. + - 1: Default mode. Chosen by OpenMPT code, might change. + - 2: Rectangular, 0.5 bit depth, no noise shaping (original ModPlug Tracker). + - 3: Rectangular, 1 bit depth, simple 1st order noise shaping + + An exclamation mark ("!") or a question mark ("?") can be appended to any ctl key in order to influence the behaviour in case of an unknown ctl key. "!" causes an exception to be thrown; "?" causes the ctl to be silently ignored. In case neither is appended to the key name, unknown init_ctls are ignored by default and other ctls throw an exception by default. + */ + std::vector<std::string> get_ctls() const; + + //! Get current ctl value + /*! + \param ctl The ctl key whose value should be retrieved. + \return The associated ctl value. + \sa openmpt::module::get_ctls + */ + std::string ctl_get( const std::string & ctl ) const; + //! Set ctl value + /*! + \param ctl The ctl key whose value should be set. + \param value The value that should be set. + \throws openmpt::exception Throws an exception derived from openmpt::exception in case the value is not sensible (e.g. negative tempo factor) or under the circumstances outlined in openmpt::module::get_ctls. + \sa openmpt::module::get_ctls + */ + void ctl_set( const std::string & ctl, const std::string & value ); + + // remember to add new functions to both C and C++ interfaces and to increase OPENMPT_API_VERSION_MINOR + +}; // class module + +} // namespace openmpt + +/*! + @} +*/ + +#endif // LIBOPENMPT_HPP diff --git a/libs/libopenmpt/inc/libopenmpt/libopenmpt_config.h b/libs/libopenmpt/inc/libopenmpt/libopenmpt_config.h new file mode 100644 index 0000000000000000000000000000000000000000..0323ab1e082833f36cde2be9acfffa25db18d2c5 --- /dev/null +++ b/libs/libopenmpt/inc/libopenmpt/libopenmpt_config.h @@ -0,0 +1,204 @@ +/* + * libopenmpt_config.h + * ------------------- + * Purpose: libopenmpt public interface configuration + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + +#ifndef LIBOPENMPT_CONFIG_H +#define LIBOPENMPT_CONFIG_H + +/*! \defgroup libopenmpt libopenmpt */ + +/*! \addtogroup libopenmpt + @{ +*/ + +/* provoke warnings if already defined */ +#define LIBOPENMPT_API +#undef LIBOPENMPT_API +#define LIBOPENMPT_CXX_API +#undef LIBOPENMPT_CXX_API + +/*! \brief Defined if libopenmpt/libopenmpt_stream_callbacks_buffer.h exists. */ +#define LIBOPENMPT_STREAM_CALLBACKS_BUFFER + +/*! \brief Defined if libopenmpt/libopenmpt_stream_callbacks_fd.h exists. + * \since 0.3 + * \remarks + * Use the following to check for availability: + * \code + * #include <libopenmpt/libopenmpt.h> + * #if defined(LIBOPENMPT_STREAM_CALLBACKS_FD) || ((OPENMPT_API_VERSION_MAJOR == 0) && ((OPENMPT_API_VERSION_MINOR == 2) || (OPENMPT_API_VERSION_MINOR == 1))) + * #include <libopenmpt/libopenmpt_stream_callbacks_fd.h> + * #endif + * \endcode + */ +#define LIBOPENMPT_STREAM_CALLBACKS_FD + +/*! \brief Defined if libopenmpt/libopenmpt_stream_callbacks_file.h exists. + * \since 0.3 + * \remarks + * Use the following to check for availability: + * \code + * #include <libopenmpt/libopenmpt.h> + * #if defined(LIBOPENMPT_STREAM_CALLBACKS_FILE) || ((OPENMPT_API_VERSION_MAJOR == 0) && ((OPENMPT_API_VERSION_MINOR == 2) || (OPENMPT_API_VERSION_MINOR == 1))) + * #include <libopenmpt/libopenmpt_stream_callbacks_file.h> + * #endif + * \endcode + */ +#define LIBOPENMPT_STREAM_CALLBACKS_FILE + +#if defined(__DOXYGEN__) + +#define LIBOPENMPT_API_HELPER_EXPORT +#define LIBOPENMPT_API_HELPER_IMPORT +#define LIBOPENMPT_API_HELPER_PUBLIC +#define LIBOPENMPT_API_HELPER_LOCAL + +#elif defined(_MSC_VER) + +#define LIBOPENMPT_API_HELPER_EXPORT __declspec(dllexport) +#define LIBOPENMPT_API_HELPER_IMPORT __declspec(dllimport) +#define LIBOPENMPT_API_HELPER_PUBLIC +#define LIBOPENMPT_API_HELPER_LOCAL + +#elif defined(__EMSCRIPTEN__) + +#define LIBOPENMPT_API_HELPER_EXPORT __attribute__((visibility("default"))) __attribute__((used)) +#define LIBOPENMPT_API_HELPER_IMPORT __attribute__((visibility("default"))) __attribute__((used)) +#define LIBOPENMPT_API_HELPER_PUBLIC __attribute__((visibility("default"))) __attribute__((used)) +#define LIBOPENMPT_API_HELPER_LOCAL __attribute__((visibility("hidden"))) + +#elif (defined(__GNUC__) || defined(__clang__)) && defined(_WIN32) + +#define LIBOPENMPT_API_HELPER_EXPORT __declspec(dllexport) +#define LIBOPENMPT_API_HELPER_IMPORT __declspec(dllimport) +#define LIBOPENMPT_API_HELPER_PUBLIC __attribute__((visibility("default"))) +#define LIBOPENMPT_API_HELPER_LOCAL __attribute__((visibility("hidden"))) + +#elif defined(__GNUC__) || defined(__clang__) + +#define LIBOPENMPT_API_HELPER_EXPORT __attribute__((visibility("default"))) +#define LIBOPENMPT_API_HELPER_IMPORT __attribute__((visibility("default"))) +#define LIBOPENMPT_API_HELPER_PUBLIC __attribute__((visibility("default"))) +#define LIBOPENMPT_API_HELPER_LOCAL __attribute__((visibility("hidden"))) + +#elif defined(_WIN32) + +#define LIBOPENMPT_API_HELPER_EXPORT __declspec(dllexport) +#define LIBOPENMPT_API_HELPER_IMPORT __declspec(dllimport) +#define LIBOPENMPT_API_HELPER_PUBLIC +#define LIBOPENMPT_API_HELPER_LOCAL + +#else + +#define LIBOPENMPT_API_HELPER_EXPORT +#define LIBOPENMPT_API_HELPER_IMPORT +#define LIBOPENMPT_API_HELPER_PUBLIC +#define LIBOPENMPT_API_HELPER_LOCAL + +#endif + +#if defined(LIBOPENMPT_BUILD_DLL) +#define LIBOPENMPT_API LIBOPENMPT_API_HELPER_EXPORT +#elif defined(LIBOPENMPT_USE_DLL) +#define LIBOPENMPT_API LIBOPENMPT_API_HELPER_IMPORT +#else +#define LIBOPENMPT_API LIBOPENMPT_API_HELPER_PUBLIC +#endif + +#ifdef __cplusplus + +#define LIBOPENMPT_CXX_API LIBOPENMPT_API + +#if defined(LIBOPENMPT_USE_DLL) +#if defined(_MSC_VER) && !defined(_DLL) +#error "C++ interface is disabled if libopenmpt is built as a DLL and the runtime is statically linked. This is not supported by microsoft and cannot possibly work. Ever." +#undef LIBOPENMPT_CXX_API +#define LIBOPENMPT_CXX_API LIBOPENMPT_API_HELPER_LOCAL +#endif +#endif + +#if defined(__EMSCRIPTEN__) + +/* Only the C API is supported for emscripten. Disable the C++ API. */ +#undef LIBOPENMPT_CXX_API +#define LIBOPENMPT_CXX_API LIBOPENMPT_API_HELPER_LOCAL +#endif + +#endif + +/*! + @} +*/ + + +/* C */ + +#if !defined(LIBOPENMPT_NO_DEPRECATE) +#if defined(__clang__) +#define LIBOPENMPT_DEPRECATED __attribute__((deprecated)) +#elif defined(__GNUC__) +#define LIBOPENMPT_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +#define LIBOPENMPT_DEPRECATED __declspec(deprecated) +#else +#define LIBOPENMPT_DEPRECATED +#endif +#endif + +#ifndef __cplusplus +#if !defined(LIBOPENMPT_NO_DEPRECATE) +LIBOPENMPT_DEPRECATED static const int LIBOPENMPT_DEPRECATED_STRING_CONSTANT = 0; +#define LIBOPENMPT_DEPRECATED_STRING( str ) ( LIBOPENMPT_DEPRECATED_STRING_CONSTANT ? ( str ) : ( str ) ) +#else +#define LIBOPENMPT_DEPRECATED_STRING( str ) str +#endif +#endif + + +/* C++ */ + +#ifdef __cplusplus + +#ifndef LIBOPENMPT_ASSUME_CPLUSPLUS_DEPRECATED +/* handle known broken compilers here by defining LIBOPENMPT_ASSUME_CPLUSPLUS_DEPRECATED appropriately */ +#endif + +#if defined(LIBOPENMPT_ASSUME_CPLUSPLUS) +#ifndef LIBOPENMPT_ASSUME_CPLUSPLUS_DEPRECATED +#define LIBOPENMPT_ASSUME_CPLUSPLUS_DEPRECATED LIBOPENMPT_ASSUME_CPLUSPLUS +#endif +#endif + +#if !defined(LIBOPENMPT_NO_DEPRECATE) +#if defined(LIBOPENMPT_ASSUME_CPLUSPLUS_DEPRECATED) +#if (LIBOPENMPT_ASSUME_CPLUSPLUS_DEPRECATED >= 201402L) +#define LIBOPENMPT_ATTR_DEPRECATED [[deprecated]] +#undef LIBOPENMPT_DEPRECATED +#define LIBOPENMPT_DEPRECATED +#else +#define LIBOPENMPT_ATTR_DEPRECATED +#endif +#elif (__cplusplus >= 201402L) +#define LIBOPENMPT_ATTR_DEPRECATED [[deprecated]] +#undef LIBOPENMPT_DEPRECATED +#define LIBOPENMPT_DEPRECATED +#else +#define LIBOPENMPT_ATTR_DEPRECATED +#endif +#else +#undef LIBOPENMPT_DEPRECATED +#define LIBOPENMPT_DEPRECATED +#define LIBOPENMPT_ATTR_DEPRECATED +#endif + +#endif + + +#include "libopenmpt_version.h" + +#endif /* LIBOPENMPT_CONFIG_H */ diff --git a/libs/libopenmpt/inc/libopenmpt/libopenmpt_ext.h b/libs/libopenmpt/inc/libopenmpt/libopenmpt_ext.h new file mode 100644 index 0000000000000000000000000000000000000000..e76f758de2f8c62acf1d18b5e8771037070dcd6c --- /dev/null +++ b/libs/libopenmpt/inc/libopenmpt/libopenmpt_ext.h @@ -0,0 +1,318 @@ +/* + * libopenmpt_ext.h + * ---------------- + * Purpose: libopenmpt public c interface for libopenmpt extensions + * Notes : + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + +#ifndef LIBOPENMPT_EXT_H +#define LIBOPENMPT_EXT_H + +#include "libopenmpt_config.h" +#include "libopenmpt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * \page libopenmpt_ext_c_overview libopenmpt_ext C API + * + * libopenmpt_ext is included in all builds by default. + * + * \section libopenmpt-ext-c-detailed Detailed documentation + * + * \ref libopenmpt_ext_c + * + */ + +/*! \defgroup libopenmpt_ext_c libopenmpt_ext C */ + +/*! \addtogroup libopenmpt_ext_c + * @{ + */ + +/*! \brief Opaque type representing a libopenmpt extension module + */ +typedef struct openmpt_module_ext openmpt_module_ext; + +/*! \brief Construct an openmpt_module_ext + * + * \param stream_callbacks Input stream callback operations. + * \param stream Input stream to load the module from. + * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module_ext. May be NULL. + * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) + * \param errfunc Error function to define error behaviour. May be NULL. + * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. + * \param error Pointer to an integer where an error may get stored. May be NULL. + * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. + * \param ctls A map of initial ctl values, see openmpt_module_get_ctls. + * \return A pointer to the constructed openmpt_module_ext, or NULL on failure. + * \remarks The input data can be discarded after an openmpt_module_ext has been constructed successfully. + * \sa openmpt_stream_callbacks + * \sa \ref libopenmpt_c_fileio + * \since 0.3.0 + */ +LIBOPENMPT_API openmpt_module_ext * openmpt_module_ext_create( openmpt_stream_callbacks stream_callbacks, void * stream, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message, const openmpt_module_initial_ctl * ctls ); + +/*! \brief Construct an openmpt_module_ext + * + * \param filedata Data to load the module from. + * \param filesize Amount of data available. + * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module_ext. + * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc) + * \param errfunc Error function to define error behaviour. May be NULL. + * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function. + * \param error Pointer to an integer where an error may get stored. May be NULL. + * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL. + * \param ctls A map of initial ctl values, see openmpt_module_get_ctls. + * \return A pointer to the constructed openmpt_module_ext, or NULL on failure. + * \remarks The input data can be discarded after an openmpt_module_ext has been constructed successfully. + * \sa \ref libopenmpt_c_fileio + * \since 0.3.0 + */ +LIBOPENMPT_API openmpt_module_ext * openmpt_module_ext_create_from_memory( const void * filedata, size_t filesize, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message, const openmpt_module_initial_ctl * ctls ); + +/*! \brief Unload a previously created openmpt_module_ext from memory. + * + * \param mod_ext The module to unload. + */ +LIBOPENMPT_API void openmpt_module_ext_destroy( openmpt_module_ext * mod_ext ); + +/*! \brief Retrieve the openmpt_module handle from an openmpt_module_ext handle. + * + * \param mod_ext The extension module handle to convert + * \return An equivalent openmpt_module handle to pass to standard libopenmpt functions + * \since 0.3.0 + */ +LIBOPENMPT_API openmpt_module * openmpt_module_ext_get_module( openmpt_module_ext * mod_ext ); + +/*! Retrieve a libopenmpt extension. + * + * \param mod_ext The module handle to work on. + * \param interface_id The name of the extension interface to retrieve (e.g. LIBOPENMPT_EXT_C_INTERFACE_PATTERN_VIS). + * \param interface Appropriate structure of interface function pointers which is to be filled by this function (e.g. a pointer to a openmpt_module_ext_interface_pattern_vis structure). + * \param interface_size Size of the interface's structure of function pointers (e.g. sizeof(openmpt_module_ext_interface_pattern_vis)). + * \return 1 on success, 0 if the interface was not found. + * \since 0.3.0 + */ +LIBOPENMPT_API int openmpt_module_ext_get_interface( openmpt_module_ext * mod_ext, const char * interface_id, void * interface, size_t interface_size ); + + + +#ifndef LIBOPENMPT_EXT_C_INTERFACE_PATTERN_VIS +#define LIBOPENMPT_EXT_C_INTERFACE_PATTERN_VIS "pattern_vis" +#endif + +/*! Pattern command type */ +#define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_UNKNOWN 0 +#define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_GENERAL 1 +#define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_GLOBAL 2 +#define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_VOLUME 3 +#define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_PANNING 4 +#define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_PITCH 5 + +typedef struct openmpt_module_ext_interface_pattern_vis { + /*! Get pattern command type for pattern highlighting + * + * \param mod_ext The module handle to work on. + * \param pattern The pattern whose data should be retrieved. + * \param row The row from which the data should be retrieved. + * \param channel The channel from which the data should be retrieved. + * \return The command type in the effect column at the given pattern position (see OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_*) + * \sa openmpt_module_ext_interface_pattern_vis::get_pattern_row_channel_volume_effect_type + */ + int ( * get_pattern_row_channel_volume_effect_type ) ( openmpt_module_ext * mod_ext, int32_t pattern, int32_t row, int32_t channel ); + + /*! Get pattern command type for pattern highlighting + * + * \param mod_ext The module handle to work on. + * \param pattern The pattern whose data should be retrieved. + * \param row The row from which the data should be retrieved. + * \param channel The channel from which the data should be retrieved. + * \return The command type in the effect column at the given pattern position (see OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_*) + * \sa openmpt_module_ext_interface_pattern_vis::get_pattern_row_channel_volume_effect_type + */ + int ( * get_pattern_row_channel_effect_type ) ( openmpt_module_ext * mod_ext, int32_t pattern, int32_t row, int32_t channel ); +} openmpt_module_ext_interface_pattern_vis; + + + +#ifndef LIBOPENMPT_EXT_C_INTERFACE_INTERACTIVE +#define LIBOPENMPT_EXT_C_INTERFACE_INTERACTIVE "interactive" +#endif + +typedef struct openmpt_module_ext_interface_interactive { + /*! Set the current ticks per row (speed) + * + * \param mod_ext The module handle to work on. + * \param speed The new tick count in range [1, 65535]. + * \return 1 on success, 0 on failure. + * \remarks The tick count may be reset by pattern commands at any time. + * \sa openmpt_module_get_current_speed + */ + int ( * set_current_speed ) ( openmpt_module_ext * mod_ext, int32_t speed ); + + /*! Set the current module tempo + * + * \param mod_ext The module handle to work on. + * \param tempo The new tempo in range [32, 512]. The exact meaning of the value depends on the tempo mode used by the module. + * \return 1 on success, 0 on failure. + * \remarks The tempo may be reset by pattern commands at any time. Use openmpt_module_ext_interface_interactive::set_tempo_factor to apply a tempo factor that is independent of pattern commands. + * \sa openmpt_module_get_current_tempo + */ + int ( * set_current_tempo ) ( openmpt_module_ext * mod_ext, int32_t tempo ); + + /*! Set the current module tempo factor without affecting playback pitch + * + * \param mod_ext The module handle to work on. + * \param factor The new tempo factor in range ]0.0, 4.0] - 1.0 means unmodified tempo. + * \return 1 on success, 0 on failure. + * \remarks Modifying the tempo without applying the same pitch factor using openmpt_module_ext_interface_interactive::set_pitch_factor may cause rhythmic samples (e.g. drum loops) to go out of sync. + * \sa openmpt_module_ext_interface_interactive::get_tempo_factor + */ + int ( * set_tempo_factor ) ( openmpt_module_ext * mod_ext, double factor ); + + /*! Gets the current module tempo factor + * + * \param mod_ext The module handle to work on. + * \return The current tempo factor. + * \sa openmpt_module_ext_interface_interactive::set_tempo_factor + */ + double ( * get_tempo_factor ) ( openmpt_module_ext * mod_ext ); + + /*! Set the current module pitch factor without affecting playback speed + * + * \param mod_ext The module handle to work on. + * \param factor The new pitch factor in range ]0.0, 4.0] - 1.0 means unmodified pitch. + * \return 1 on success, 0 on failure. + * \remarks Modifying the pitch without applying the the same tempo factor using openmpt_module_ext_interface_interactive::set_tempo_factor may cause rhythmic samples (e.g. drum loops) to go out of sync. + * \remarks To shift the pich by `n` semitones, the parameter can be calculated as follows: `pow( 2.0, n / 12.0 )` + * \sa openmpt_module_ext_interface_interactive::get_pitch_factor + */ + int ( * set_pitch_factor ) ( openmpt_module_ext * mod_ext, double factor ); + + /*! Gets the current module pitch factor + * + * \param mod_ext The module handle to work on. + * \return The current pitch factor. + * \sa openmpt_module_ext_interface_interactive::set_pitch_factor + */ + double ( * get_pitch_factor ) ( openmpt_module_ext * mod_ext ); + + /*! Set the current global volume + * + * \param mod_ext The module handle to work on. + * \param volume The new global volume in range [0.0, 1.0] + * \return 1 on success, 0 on failure. + * \remarks The global volume may be reset by pattern commands at any time. Use openmpt_module_set_render_param to apply a global overall volume factor that is independent of pattern commands. + * \sa openmpt_module_ext_interface_interactive::get_global_volume + */ + int ( * set_global_volume ) ( openmpt_module_ext * mod_ext, double volume ); + + /*! Get the current global volume + * + * \param mod_ext The module handle to work on. + * \return The current global volume in range [0.0, 1.0] + * \sa openmpt_module_ext_interface_interactive::set_global_volume + */ + double ( * get_global_volume ) ( openmpt_module_ext * mod_ext ); + + /*! Set the current channel volume for a channel + * + * \param mod_ext The module handle to work on. + * \param channel The channel whose volume should be set, in range [0, openmpt_module_get_num_channels()[ + * \param volume The new channel volume in range [0.0, 1.0] + * \return 1 on success, 0 on failure (channel out of range). + * \remarks The channel volume may be reset by pattern commands at any time. + * \sa openmpt_module_ext_interface_interactive::get_channel_volume + */ + int ( * set_channel_volume ) ( openmpt_module_ext * mod_ext, int32_t channel, double volume ); + + /*! Get the current channel volume for a channel + * + * \param mod_ext The module handle to work on. + * \param channel The channel whose volume should be retrieved, in range [0, openmpt_module_get_num_channels()[ + * \return The current channel volume in range [0.0, 1.0] + * \sa openmpt_module_ext_interface_interactive::set_channel_volume + */ + double ( * get_channel_volume ) ( openmpt_module_ext * mod_ext, int32_t channel ); + + /*! Set the current mute status for a channel + * + * \param mod_ext The module handle to work on. + * \param channel The channel whose mute status should be set, in range [0, openmpt_module_get_num_channels()[ + * \param mute The new mute status. true is muted, false is unmuted. + * \return 1 on success, 0 on failure (channel out of range). + * \sa openmpt_module_ext_interface_interactive::get_channel_mute_status + */ + int ( * set_channel_mute_status ) ( openmpt_module_ext * mod_ext, int32_t channel, int mute ); + + /*! Get the current mute status for a channel + * + * \param mod_ext The module handle to work on. + * \param channel The channel whose mute status should be retrieved, in range [0, openmpt_module_get_num_channels()[ + * \return The current channel mute status. 1 is muted, 0 is unmuted, -1 means the instrument was out of range + * \sa openmpt_module_ext_interface_interactive::set_channel_mute_status + */ + int ( * get_channel_mute_status ) ( openmpt_module_ext * mod_ext, int32_t channel ); + + /*! Set the current mute status for an instrument + * + * \param mod_ext The module handle to work on. + * \param instrument The instrument whose mute status should be set, in range [0, openmpt_module_get_num_instruments()[ if openmpt_module_get_num_instruments is not 0, otherwise in [0, openmpt_module_get_num_samples()[ + * \param mute The new mute status. true is muted, false is unmuted. + * \return 1 on success, 0 on failure (instrument out of range). + * \sa openmpt_module_ext_interface_interactive::get_instrument_mute_status + */ + int ( * set_instrument_mute_status ) ( openmpt_module_ext * mod_ext, int32_t instrument, int mute ); + + /*! Get the current mute status for an instrument + * + * \param mod_ext The module handle to work on. + * \param instrument The instrument whose mute status should be retrieved, in range [0, openmpt_module_get_num_instruments()[ if openmpt_module_get_num_instruments is not 0, otherwise in [0, openmpt_module_get_num_samples()[ + * \return The current instrument mute status. 1 is muted, 0 is unmuted, -1 means the instrument was out of range + * \sa openmpt_module_ext_interface_interactive::set_instrument_mute_status + */ + int ( * get_instrument_mute_status ) ( openmpt_module_ext * mod_ext, int32_t instrument ); + + /*! Play a note using the specified instrument + * + * \param mod_ext The module handle to work on. + * \param instrument The instrument that should be played, in range [0, openmpt_module_get_num_instruments()[ if openmpt_module_get_num_instruments is not 0, otherwise in [0, openmpt_module_get_num_samples()[ + * \param note The note to play, in rage [0, 119]. 60 is the middle C. + * \param volume The volume at which the note should be triggered, in range [0.0, 1.0] + * \param panning The panning position at which the note should be triggered, in range [-1.0, 1.0], 0.0 is center. + * \return The channel on which the note is played. This can pe be passed to openmpt_module_ext_interface_interactive::stop_note to stop the note. -1 means that no channel could be allocated and the note is not played. + * \sa openmpt_module_ext_interface_interactive::stop_note + */ + int32_t ( * play_note ) ( openmpt_module_ext * mod_ext, int32_t instrument, int32_t note, double volume, double panning ); + + /*! Stop the note playing on the specified channel + * + * \param mod_ext The module handle to work on. + * \param channel The channel on which the note should be stopped. + * \return 1 on success, 0 on failure (channel out of range). + * \sa openmpt_module_ext_interface_interactive::play_note + */ + int ( * stop_note ) ( openmpt_module_ext * mod_ext, int32_t channel ); +} openmpt_module_ext_interface_interactive; + + + +/* add stuff here */ + + + +#ifdef __cplusplus +} +#endif + +/*! + * @} + */ + +#endif /* LIBOPENMPT_EXT_H */ + diff --git a/libs/libopenmpt/inc/libopenmpt/libopenmpt_ext.hpp b/libs/libopenmpt/inc/libopenmpt/libopenmpt_ext.hpp new file mode 100644 index 0000000000000000000000000000000000000000..686eaeeedb93a5705433a07de5fc5f07e5a12764 --- /dev/null +++ b/libs/libopenmpt/inc/libopenmpt/libopenmpt_ext.hpp @@ -0,0 +1,306 @@ +/* + * libopenmpt_ext.hpp + * ------------------ + * Purpose: libopenmpt public c++ interface for libopenmpt extensions + * Notes : + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + +#ifndef LIBOPENMPT_EXT_HPP +#define LIBOPENMPT_EXT_HPP + +#include "libopenmpt_config.h" +#include "libopenmpt.hpp" + +/*! + * \page libopenmpt_ext_cpp_overview libopenmpt_ext C++ API + * + * libopenmpt_ext is now included in all builds by default. + * + * \section libopenmpt-ext-cpp-detailed Detailed documentation + * + * \ref libopenmpt_ext_cpp + * + */ + +/*! \defgroup libopenmpt_ext_cpp libopenmpt_ext C++ */ + +/*! \addtogroup libopenmpt_ext_cpp + @{ +*/ + +namespace openmpt { + +class module_ext_impl; + +class LIBOPENMPT_CXX_API module_ext : public module { + +private: + module_ext_impl * ext_impl; +private: + // non-copyable + module_ext( const module_ext & ); + void operator = ( const module_ext & ); +public: + module_ext( std::istream & stream, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); + module_ext( const std::vector<char> & data, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); + module_ext( const char * data, std::size_t size, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); + module_ext( const void * data, std::size_t size, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() ); + virtual ~module_ext(); + +public: + + //! Retrieve a libopenmpt extension. + /*! Example: Retrieving the interactive extension to change the tempo of a module: + \code{.cpp} + openmpt::module_ext *mod = new openmpt::module_ext( stream ); + #ifdef LIBOPENMPT_EXT_INTERFACE_INTERACTIVE + openmpt::ext::interactive *interactive = static_cast<openmpt::ext::interactive *>( self->mod->get_interface( openmpt::ext::interactive_id ) ); + if ( interactive ) { + interactive->set_tempo_factor( 2.0 ); // play module at double speed + } else { + // interface not available + } + #else + // interfae not available + #endif + \endcode + \param interface_id The name of the extension interface to retrieve. + \return The interface object. This may be a nullptr if the extension was not found. + */ + void * get_interface( const std::string & interface_id ); + +}; // class module_ext + +namespace ext { + +#define LIBOPENMPT_DECLARE_EXT_CXX_INTERFACE(name) \ + static const char name ## _id [] = # name ; \ + class name; \ +/**/ + +#define LIBOPENMPT_EXT_CXX_INTERFACE(name) \ + protected: \ + name () {} \ + virtual ~ name () {} \ + public: \ +/**/ + + +#ifndef LIBOPENMPT_EXT_INTERFACE_PATTERN_VIS +#define LIBOPENMPT_EXT_INTERFACE_PATTERN_VIS +#endif + +LIBOPENMPT_DECLARE_EXT_CXX_INTERFACE(pattern_vis) + +class pattern_vis { + + LIBOPENMPT_EXT_CXX_INTERFACE(pattern_vis) + + //! Pattern command type + enum effect_type { + + effect_unknown = 0, + effect_general = 1, + effect_global = 2, + effect_volume = 3, + effect_panning = 4, + effect_pitch = 5 + + }; // enum effect_type + + //! Get pattern command type for pattern highlighting + /*! + \param pattern The pattern whose data should be retrieved. + \param row The row from which the data should be retrieved. + \param channel The channel from which the data should be retrieved. + \return The command type in the effect column at the given pattern position (see openmpt::ext::pattern_vis::effect_type) + \sa openmpt::ext::pattern_vis::get_pattern_row_channel_effect_type + */ + virtual effect_type get_pattern_row_channel_volume_effect_type( std::int32_t pattern, std::int32_t row, std::int32_t channel ) const = 0; + + //! Get pattern command type for pattern highlighting + /*! + \param pattern The pattern whose data should be retrieved. + \param row The row from which the data should be retrieved. + \param channel The channel from which the data should be retrieved. + \return The command type in the volume column at the given pattern position (see openmpt::ext::pattern_vis::effect_type) + \sa openmpt::ext::pattern_vis::get_pattern_row_channel_volume_effect_type + */ + virtual effect_type get_pattern_row_channel_effect_type( std::int32_t pattern, std::int32_t row, std::int32_t channel ) const = 0; + +}; // class pattern_vis + + +#ifndef LIBOPENMPT_EXT_INTERFACE_INTERACTIVE +#define LIBOPENMPT_EXT_INTERFACE_INTERACTIVE +#endif + +LIBOPENMPT_DECLARE_EXT_CXX_INTERFACE(interactive) + +class interactive { + + LIBOPENMPT_EXT_CXX_INTERFACE(interactive) + + //! Set the current ticks per row (speed) + /*! + \param speed The new tick count in range [1, 65535]. + \throws openmpt::exception Throws an exception derived from openmpt::exception if the speed is outside the specified range. + \remarks The tick count may be reset by pattern commands at any time. + \sa openmpt::module::get_current_speed + */ + virtual void set_current_speed( std::int32_t speed ) = 0; + + //! Set the current module tempo + /*! + \param tempo The new tempo in range [32, 512]. The exact meaning of the value depends on the tempo mode used by the module. + \throws openmpt::exception Throws an exception derived from openmpt::exception if the tempo is outside the specified range. + \remarks The tempo may be reset by pattern commands at any time. Use openmpt::ext:interactive::set_tempo_factor to apply a tempo factor that is independent of pattern commands. + \sa openmpt::module::get_current_tempo + */ + virtual void set_current_tempo( std::int32_t tempo ) = 0; + + //! Set the current module tempo factor without affecting playback pitch + /*! + \param factor The new tempo factor in range ]0.0, 4.0] - 1.0 means unmodified tempo. + \throws openmpt::exception Throws an exception derived from openmpt::exception if the factor is outside the specified range. + \remarks Modifying the tempo without applying the same pitch factor using openmpt::ext::interactive::set_pitch_factor may cause rhythmic samples (e.g. drum loops) to go out of sync. + \sa openmpt::ext::interactive::get_tempo_factor + */ + virtual void set_tempo_factor( double factor ) = 0; + + //! Gets the current module tempo factor + /*! + \return The current tempo factor. + \sa openmpt::ext::interactive::set_tempo_factor + */ + virtual double get_tempo_factor( ) const = 0; + + //! Set the current module pitch factor without affecting playback speed + /*! + \param factor The new pitch factor in range ]0.0, 4.0] - 1.0 means unmodified pitch. + \throws openmpt::exception Throws an exception derived from openmpt::exception if the factor is outside the specified range. + \remarks Modifying the pitch without applying the the same tempo factor using openmpt::ext::interactive::set_tempo_factor may cause rhythmic samples (e.g. drum loops) to go out of sync. + \remarks To shift the pich by `n` semitones, the parameter can be calculated as follows: `pow( 2.0, n / 12.0 )` + \sa openmpt::ext::interactive::get_pitch_factor + */ + virtual void set_pitch_factor( double factor ) = 0; + + //! Gets the current module pitch factor + /*! + \return The current pitch factor. + \sa openmpt::ext::interactive::set_pitch_factor + */ + virtual double get_pitch_factor( ) const = 0; + + //! Set the current global volume + /*! + \param volume The new global volume in range [0.0, 1.0] + \throws openmpt::exception Throws an exception derived from openmpt::exception if the volume is outside the specified range. + \remarks The global volume may be reset by pattern commands at any time. Use openmpt::module::set_render_param to apply a global overall volume factor that is independent of pattern commands. + \sa openmpt::ext::interactive::get_global_volume + */ + virtual void set_global_volume( double volume ) = 0; + + //! Get the current global volume + /*! + \return The current global volume in range [0.0, 1.0] + \sa openmpt::ext::interactive::set_global_volume + */ + virtual double get_global_volume( ) const = 0; + + //! Set the current channel volume for a channel + /*! + \param channel The channel whose volume should be set, in range [0, openmpt::module::get_num_channels()[ + \param volume The new channel volume in range [0.0, 1.0] + \throws openmpt::exception Throws an exception derived from openmpt::exception if the channel or volume is outside the specified range. + \remarks The channel volume may be reset by pattern commands at any time. + \sa openmpt::ext::interactive::get_channel_volume + */ + virtual void set_channel_volume( std::int32_t channel, double volume ) = 0; + + //! Get the current channel volume for a channel + /*! + \param channel The channel whose volume should be retrieved, in range [0, openmpt::module::get_num_channels()[ + \return The current channel volume in range [0.0, 1.0] + \throws openmpt::exception Throws an exception derived from openmpt::exception if the channel is outside the specified range. + \sa openmpt::ext::interactive::set_channel_volume + */ + virtual double get_channel_volume( std::int32_t channel ) const = 0; + + //! Set the current mute status for a channel + /*! + \param channel The channel whose mute status should be set, in range [0, openmpt::module::get_num_channels()[ + \param mute The new mute status. true is muted, false is unmuted. + \throws openmpt::exception Throws an exception derived from openmpt::exception if the channel is outside the specified range. + \sa openmpt::ext::interactive::get_channel_mute_status + */ + virtual void set_channel_mute_status( std::int32_t channel, bool mute ) = 0; + + //! Get the current mute status for a channel + /*! + \param channel The channel whose mute status should be retrieved, in range [0, openmpt::module::get_num_channels()[ + \return The current channel mute status. true is muted, false is unmuted. + \throws openmpt::exception Throws an exception derived from openmpt::exception if the channel is outside the specified range. + \sa openmpt::ext::interactive::set_channel_mute_status + */ + virtual bool get_channel_mute_status( std::int32_t channel ) const = 0; + + //! Set the current mute status for an instrument + /*! + \param instrument The instrument whose mute status should be set, in range [0, openmpt::module::get_num_instruments()[ if openmpt::module::get_num_instruments is not 0, otherwise in [0, openmpt::module::get_num_samples()[ + \param mute The new mute status. true is muted, false is unmuted. + \throws openmpt::exception Throws an exception derived from openmpt::exception if the instrument is outside the specified range. + \sa openmpt::ext::interactive::get_instrument_mute_status + */ + virtual void set_instrument_mute_status( std::int32_t instrument, bool mute ) = 0; + + //! Get the current mute status for an instrument + /*! + \param instrument The instrument whose mute status should be retrieved, in range [0, openmpt::module::get_num_instruments()[ if openmpt::module::get_num_instruments is not 0, otherwise in [0, openmpt::module::get_num_samples()[ + \return The current instrument mute status. true is muted, false is unmuted. + \throws openmpt::exception Throws an exception derived from openmpt::exception if the instrument is outside the specified range. + \sa openmpt::ext::interactive::set_instrument_mute_status + */ + virtual bool get_instrument_mute_status( std::int32_t instrument ) const = 0; + + //! Play a note using the specified instrument + /*! + \param instrument The instrument that should be played, in range [0, openmpt::module::get_num_instruments()[ if openmpt::module::get_num_instruments is not 0, otherwise in [0, openmpt::module::get_num_samples()[ + \param note The note to play, in rage [0, 119]. 60 is the middle C. + \param volume The volume at which the note should be triggered, in range [0.0, 1.0] + \param panning The panning position at which the note should be triggered, in range [-1.0, 1.0], 0.0 is center. + \return The channel on which the note is played. This can pe be passed to openmpt::ext::interactive::stop_note to stop the note. + \throws openmpt::exception Throws an exception derived from openmpt::exception if the instrument or note is outside the specified range. + \sa openmpt::ext::interactive::stop_note + */ + virtual std::int32_t play_note( std::int32_t instrument, std::int32_t note, double volume, double panning ) = 0; + + //! Stop the note playing on the specified channel + /*! + \param channel The channel on which the note should be stopped. + \throws openmpt::exception Throws an exception derived from openmpt::exception if the channel index is invalid. + \sa openmpt::ext::interactive::play_note + */ + virtual void stop_note( std::int32_t channel ) = 0; + +}; // class interactive + + +/* add stuff here */ + + + +#undef LIBOPENMPT_DECLARE_EXT_CXX_INTERFACE +#undef LIBOPENMPT_EXT_CXX_INTERFACE + +} // namespace ext + +} // namespace openmpt + +/*! + @} +*/ + +#endif // LIBOPENMPT_EXT_HPP diff --git a/libs/libopenmpt/inc/libopenmpt/libopenmpt_stream_callbacks_buffer.h b/libs/libopenmpt/inc/libopenmpt/libopenmpt_stream_callbacks_buffer.h new file mode 100644 index 0000000000000000000000000000000000000000..575049e4d97789549a99be6cb8fe6463845fcb17 --- /dev/null +++ b/libs/libopenmpt/inc/libopenmpt/libopenmpt_stream_callbacks_buffer.h @@ -0,0 +1,198 @@ +/* + * libopenmpt_stream_callbacks_buffer.h + * ------------------------------------ + * Purpose: libopenmpt public c interface + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + +#ifndef LIBOPENMPT_STREAM_CALLBACKS_BUFFER_H +#define LIBOPENMPT_STREAM_CALLBACKS_BUFFER_H + +#include "libopenmpt.h" + +/* The use of this header requires: + +#include <libopenmpt/libopenmpt.h> +#if defined( LIBOPENMPT_STREAM_CALLBACKS_BUFFER ) +#include <libopenmpt/libopenmpt_stream_callbacks_buffer.h> +#else +#error "libopenmpt too old." +#endif + +*/ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +/*! \addtogroup libopenmpt_c + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct openmpt_stream_buffer { + const void * file_data; /* or prefix data IFF prefix_size < file_size */ + int64_t file_size; + int64_t file_pos; + int64_t prefix_size; + int overflow; +} openmpt_stream_buffer; + +static size_t openmpt_stream_buffer_read_func( void * stream, void * dst, size_t bytes ) { + openmpt_stream_buffer * s = (openmpt_stream_buffer*)stream; + int64_t offset = 0; + int64_t begpos = 0; + int64_t endpos = 0; + size_t valid_bytes = 0; + if ( !s ) { + return 0; + } + offset = bytes; + begpos = s->file_pos; + endpos = s->file_pos; + valid_bytes = 0; + endpos = (uint64_t)endpos + (uint64_t)offset; + if ( ( offset > 0 ) && !( (uint64_t)endpos > (uint64_t)begpos ) ) { + /* integer wrapped */ + return 0; + } + if ( bytes == 0 ) { + return 0; + } + if ( begpos >= s->file_size ) { + return 0; + } + if ( endpos > s->file_size ) { + /* clip to eof */ + bytes = bytes - (size_t)( endpos - s->file_size ); + endpos = endpos - ( endpos - s->file_size ); + } + memset( dst, 0, bytes ); + if ( begpos >= s->prefix_size ) { + s->overflow = 1; + valid_bytes = 0; + } else if ( endpos > s->prefix_size ) { + s->overflow = 1; + valid_bytes = bytes - (size_t)( endpos - s->prefix_size ); + } else { + valid_bytes = bytes; + } + memcpy( dst, (const char*)s->file_data + s->file_pos, valid_bytes ); + s->file_pos = s->file_pos + bytes; + return bytes; +} + +static int openmpt_stream_buffer_seek_func( void * stream, int64_t offset, int whence ) { + openmpt_stream_buffer * s = (openmpt_stream_buffer*)stream; + int result = -1; + if ( !s ) { + return -1; + } + switch ( whence ) { + case OPENMPT_STREAM_SEEK_SET: + if ( offset < 0 ) { + return -1; + } + if ( offset > s->file_size ) { + return -1; + } + s->file_pos = offset; + result = 0; + break; + case OPENMPT_STREAM_SEEK_CUR: + do { + int64_t oldpos = s->file_pos; + int64_t pos = s->file_pos; + pos = (uint64_t)pos + (uint64_t)offset; + if ( ( offset > 0 ) && !( (uint64_t)pos > (uint64_t)oldpos ) ) { + /* integer wrapped */ + return -1; + } + if ( ( offset < 0 ) && !( (uint64_t)pos < (uint64_t)oldpos ) ) { + /* integer wrapped */ + return -1; + } + s->file_pos = pos; + } while(0); + result = 0; + break; + case OPENMPT_STREAM_SEEK_END: + if ( offset > 0 ) { + return -1; + } + do { + int64_t oldpos = s->file_pos; + int64_t pos = s->file_pos; + pos = s->file_size; + pos = (uint64_t)pos + (uint64_t)offset; + if ( ( offset < 0 ) && !( (uint64_t)pos < (uint64_t)oldpos ) ) { + /* integer wrapped */ + return -1; + } + s->file_pos = pos; + } while(0); + result = 0; + break; + } + return result; +} + +static int64_t openmpt_stream_buffer_tell_func( void * stream ) { + openmpt_stream_buffer * s = (openmpt_stream_buffer*)stream; + if ( !s ) { + return -1; + } + return s->file_pos; +} + +static void openmpt_stream_buffer_init( openmpt_stream_buffer * buffer, const void * file_data, int64_t file_size ) { + memset( buffer, 0, sizeof( openmpt_stream_buffer ) ); + buffer->file_data = file_data; + buffer->file_size = file_size; + buffer->file_pos = 0; + buffer->prefix_size = file_size; + buffer->overflow = 0; +} + +#define openmpt_stream_buffer_init_prefix_only( buffer_, prefix_data_, prefix_size_, file_size_ ) do { \ + openmpt_stream_buffer_init( (buffer_), (prefix_data_), (file_size_) ); \ + (buffer_)->prefix_size = (prefix_size_); \ +} while(0) + +#define openmpt_stream_buffer_overflowed( buffer_ ) ( (buffer_)->overflow ) + +/*! \brief Provide openmpt_stream_callbacks for in-memoy buffers + * + * Fills openmpt_stream_callbacks suitable for passing an in-memory buffer as a stream parameter to functions doing file input/output. + * + * \remarks The stream argument must be passed as `(void*)(openmpt_stream_buffer*)stream_buffer`. + * \sa \ref libopenmpt_c_fileio + * \sa openmpt_stream_callbacks + * \sa openmpt_could_open_probability2 + * \sa openmpt_probe_file_header_from_stream + * \sa openmpt_module_create2 + */ +static openmpt_stream_callbacks openmpt_stream_get_buffer_callbacks(void) { + openmpt_stream_callbacks retval; + memset( &retval, 0, sizeof( openmpt_stream_callbacks ) ); + retval.read = openmpt_stream_buffer_read_func; + retval.seek = openmpt_stream_buffer_seek_func; + retval.tell = openmpt_stream_buffer_tell_func; + return retval; +} + +#ifdef __cplusplus +} +#endif + +/*! + * @} + */ + +#endif /* LIBOPENMPT_STREAM_CALLBACKS_BUFFER_H */ + diff --git a/libs/libopenmpt/inc/libopenmpt/libopenmpt_stream_callbacks_fd.h b/libs/libopenmpt/inc/libopenmpt/libopenmpt_stream_callbacks_fd.h new file mode 100644 index 0000000000000000000000000000000000000000..46b39f12981ba3bb73b3b644a8d7e69f67bbc000 --- /dev/null +++ b/libs/libopenmpt/inc/libopenmpt/libopenmpt_stream_callbacks_fd.h @@ -0,0 +1,101 @@ +/* + * libopenmpt_stream_callbacks_fd.h + * -------------------------------- + * Purpose: libopenmpt public c interface + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + +#ifndef LIBOPENMPT_STREAM_CALLBACKS_FD_H +#define LIBOPENMPT_STREAM_CALLBACKS_FD_H + +#include "libopenmpt.h" + +#ifdef _MSC_VER +#include <io.h> +#endif +#include <limits.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#ifndef _MSC_VER +#include <unistd.h> +#endif + +/*! \addtogroup libopenmpt_c + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* This stuff has to be in a header file because of possibly different MSVC CRTs which cause problems for fd crossing CRT boundaries. */ + +static size_t openmpt_stream_fd_read_func( void * stream, void * dst, size_t bytes ) { + int fd = 0; + #if defined(_MSC_VER) + size_t retval = 0; + int to_read = 0; + int ret_read = 0; + #else + ssize_t retval = 0; + #endif + fd = (int)(uintptr_t)stream; + if ( fd < 0 ) { + return 0; + } + #if defined(_MSC_VER) + retval = 0; + while ( bytes > 0 ) { + to_read = 0; + if ( bytes < (size_t)INT_MAX ) { + to_read = (int)bytes; + } else { + to_read = INT_MAX; + } + ret_read = _read( fd, dst, to_read ); + if ( ret_read <= 0 ) { + return retval; + } + bytes -= ret_read; + retval += ret_read; + } + #else + retval = read( fd, dst, bytes ); + #endif + if ( retval <= 0 ) { + return 0; + } + return retval; +} + +/*! \brief Provide openmpt_stream_callbacks for standard POSIX file descriptors + * + * Fills openmpt_stream_callbacks suitable for passing a POSIX filer descriptor as a stream parameter to functions doing file input/output. + * + * \remarks The stream argument must be passed as `(void*)(uintptr_t)(int)fd`. + * \sa \ref libopenmpt_c_fileio + * \sa openmpt_stream_callbacks + * \sa openmpt_could_open_probability2 + * \sa openmpt_probe_file_header_from_stream + * \sa openmpt_module_create2 + */ +static openmpt_stream_callbacks openmpt_stream_get_fd_callbacks(void) { + openmpt_stream_callbacks retval; + memset( &retval, 0, sizeof( openmpt_stream_callbacks ) ); + retval.read = openmpt_stream_fd_read_func; + return retval; +} + +#ifdef __cplusplus +} +#endif + +/*! + * @} + */ + +#endif /* LIBOPENMPT_STREAM_CALLBACKS_FD_H */ + diff --git a/libs/libopenmpt/inc/libopenmpt/libopenmpt_stream_callbacks_file.h b/libs/libopenmpt/inc/libopenmpt/libopenmpt_stream_callbacks_file.h new file mode 100644 index 0000000000000000000000000000000000000000..643049153e75fb233104c2cb5ad6eb0b9005dfe7 --- /dev/null +++ b/libs/libopenmpt/inc/libopenmpt/libopenmpt_stream_callbacks_file.h @@ -0,0 +1,132 @@ +/* + * libopenmpt_stream_callbacks_file.h + * ---------------------------------- + * Purpose: libopenmpt public c interface + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + +#ifndef LIBOPENMPT_STREAM_CALLBACKS_FILE_H +#define LIBOPENMPT_STREAM_CALLBACKS_FILE_H + +#include "libopenmpt.h" + +#include <limits.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#ifdef _MSC_VER +#include <wchar.h> /* off_t */ +#endif + +/*! \addtogroup libopenmpt_c + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* This stuff has to be in a header file because of possibly different MSVC CRTs which cause problems for FILE * crossing CRT boundaries. */ + +static size_t openmpt_stream_file_read_func( void * stream, void * dst, size_t bytes ) { + FILE * f = 0; + size_t retval = 0; + f = (FILE*)stream; + if ( !f ) { + return 0; + } + retval = fread( dst, 1, bytes, f ); + if ( retval <= 0 ) { + return 0; + } + return retval; +} + +static int openmpt_stream_file_seek_func( void * stream, int64_t offset, int whence ) { + FILE * f = 0; + int fwhence = 0; + f = (FILE*)stream; + if ( !f ) { + return -1; + } + switch ( whence ) { +#if defined(SEEK_SET) + case OPENMPT_STREAM_SEEK_SET: + fwhence = SEEK_SET; + break; +#endif +#if defined(SEEK_CUR) + case OPENMPT_STREAM_SEEK_CUR: + fwhence = SEEK_CUR; + break; +#endif +#if defined(SEEK_END) + case OPENMPT_STREAM_SEEK_END: + fwhence = SEEK_END; + break; +#endif + default: + return -1; + break; + } + #if defined(_MSC_VER) + return _fseeki64( f, offset, fwhence ) ? -1 : 0; + #elif defined(_POSIX_SOURCE) && (_POSIX_SOURCE == 1) + return fseeko( f, offset, fwhence ) ? -1 : 0; + #else + return fseek( f, offset, fwhence ) ? -1 : 0; + #endif +} + +static int64_t openmpt_stream_file_tell_func( void * stream ) { + FILE * f = 0; + int64_t retval = 0; + f = (FILE*)stream; + if ( !f ) { + return -1; + } + #if defined(_MSC_VER) + retval = _ftelli64( f ); + #elif defined(_POSIX_SOURCE) && (_POSIX_SOURCE == 1) + retval = ftello( f ); + #else + retval = ftell( f ); + #endif + if ( retval < 0 ) { + return -1; + } + return retval; +} + +/*! \brief Provide openmpt_stream_callbacks for standard C FILE objects + * + * Fills openmpt_stream_callbacks suitable for passing a standard C FILE object as a stream parameter to functions doing file input/output. + * + * \remarks The stream argument must be passed as `(void*)(FILE*)file`. + * \sa \ref libopenmpt_c_fileio + * \sa openmpt_stream_callbacks + * \sa openmpt_could_open_probability2 + * \sa openmpt_probe_file_header_from_stream + * \sa openmpt_module_create2 + */ +static openmpt_stream_callbacks openmpt_stream_get_file_callbacks(void) { + openmpt_stream_callbacks retval; + memset( &retval, 0, sizeof( openmpt_stream_callbacks ) ); + retval.read = openmpt_stream_file_read_func; + retval.seek = openmpt_stream_file_seek_func; + retval.tell = openmpt_stream_file_tell_func; + return retval; +} + +#ifdef __cplusplus +} +#endif + +/*! + * @} + */ + +#endif /* LIBOPENMPT_STREAM_CALLBACKS_FILE_H */ + diff --git a/libs/libopenmpt/inc/libopenmpt/libopenmpt_version.h b/libs/libopenmpt/inc/libopenmpt/libopenmpt_version.h new file mode 100644 index 0000000000000000000000000000000000000000..5ca7f21d0ff4a776d8011fc72b67d140aa237b9d --- /dev/null +++ b/libs/libopenmpt/inc/libopenmpt/libopenmpt_version.h @@ -0,0 +1,75 @@ +/* + * libopenmpt_version.h + * -------------------- + * Purpose: libopenmpt public interface version + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + +#ifndef LIBOPENMPT_VERSION_H +#define LIBOPENMPT_VERSION_H + +/*! \addtogroup libopenmpt + @{ +*/ + +/*! \brief libopenmpt major version number */ +#define OPENMPT_API_VERSION_MAJOR 0 +/*! \brief libopenmpt minor version number */ +#define OPENMPT_API_VERSION_MINOR 4 +/*! \brief libopenmpt patch version number */ +#define OPENMPT_API_VERSION_PATCH 4 +/*! \brief libopenmpt pre-release tag */ +#define OPENMPT_API_VERSION_PREREL "" +/*! \brief libopenmpt pre-release flag */ +#define OPENMPT_API_VERSION_IS_PREREL 0 + +/*! \brief libopenmpt version number as a single integer value + * \since 0.3 + * \remarks Use the following shim if you need to support earlier libopenmpt versions: + * \code + * #include <libopenmpt/libopenmpt_version.h> + * #if !defined(OPENMPT_API_VERSION_MAKE) + * #define OPENMPT_API_VERSION_MAKE(major, minor, patch) (((major)<<24)|((minor)<<16)|((patch)<<0)) + * #endif + * \endcode + */ +#define OPENMPT_API_VERSION_MAKE(major, minor, patch) (((major)<<24)|((minor)<<16)|((patch)<<0)) + +/*! \brief libopenmpt API version number */ +#define OPENMPT_API_VERSION OPENMPT_API_VERSION_MAKE(OPENMPT_API_VERSION_MAJOR, OPENMPT_API_VERSION_MINOR, OPENMPT_API_VERSION_PATCH) + +/*! \brief Check whether the libopenmpt API is at least the provided version + * \since 0.3 + * \remarks Use the following shim if you need to support earlier libopenmpt versions: + * \code + * #include <libopenmpt/libopenmpt_version.h> + * #if !defined(OPENMPT_API_VERSION_AT_LEAST) + * #define OPENMPT_API_VERSION_AT_LEAST(major, minor, patch) (OPENMPT_API_VERSION >= OPENMPT_API_VERSION_MAKE((major), (minor), (patch))) + * #endif + * \endcode + */ +#define OPENMPT_API_VERSION_AT_LEAST(major, minor, patch) (OPENMPT_API_VERSION >= OPENMPT_API_VERSION_MAKE((major), (minor), (patch))) + +/*! \brief Check whether the libopenmpt API is before the provided version + * \since 0.3 + * \remarks Use the following shim if you need to support earlier libopenmpt versions: + * \code + * #include <libopenmpt/libopenmpt_version.h> + * #if !defined(OPENMPT_API_VERSION_BEFORE) + * #define OPENMPT_API_VERSION_BEFORE(major, minor, patch) (OPENMPT_API_VERSION < OPENMPT_API_VERSION_MAKE((major), (minor), (patch))) + * #endif + * \endcode + */ +#define OPENMPT_API_VERSION_BEFORE(major, minor, patch) (OPENMPT_API_VERSION < OPENMPT_API_VERSION_MAKE((major), (minor), (patch))) + +#define OPENMPT_API_VERSION_HELPER_STRINGIZE(x) #x +#define OPENMPT_API_VERSION_STRINGIZE(x) OPENMPT_API_VERSION_HELPER_STRINGIZE(x) +#define OPENMPT_API_VERSION_STRING OPENMPT_API_VERSION_STRINGIZE(OPENMPT_API_VERSION_MAJOR) "." OPENMPT_API_VERSION_STRINGIZE(OPENMPT_API_VERSION_MINOR) "." OPENMPT_API_VERSION_STRINGIZE(OPENMPT_API_VERSION_PATCH) OPENMPT_API_VERSION_PREREL + +/*! + @} +*/ + +#endif /* LIBOPENMPT_VERSION_H */ diff --git a/libs/libopenmpt/lib/x86/libopenmpt.lib b/libs/libopenmpt/lib/x86/libopenmpt.lib new file mode 100644 index 0000000000000000000000000000000000000000..3f814528acc851cec1e764547570756c24d65225 Binary files /dev/null and b/libs/libopenmpt/lib/x86/libopenmpt.lib differ diff --git a/libs/libopenmpt/lib/x86/mingw/libopenmpt.dll.a b/libs/libopenmpt/lib/x86/mingw/libopenmpt.dll.a new file mode 100644 index 0000000000000000000000000000000000000000..e3fa0c58fcd082319ea3b6365cb566dd7a3efa24 Binary files /dev/null and b/libs/libopenmpt/lib/x86/mingw/libopenmpt.dll.a differ diff --git a/libs/libopenmpt/lib/x86_64/libopenmpt.lib b/libs/libopenmpt/lib/x86_64/libopenmpt.lib new file mode 100644 index 0000000000000000000000000000000000000000..75e3849fac966542b457684ca6f55a41237211d3 Binary files /dev/null and b/libs/libopenmpt/lib/x86_64/libopenmpt.lib differ diff --git a/libs/libopenmpt/lib/x86_64/mingw/libopenmpt.dll.a b/libs/libopenmpt/lib/x86_64/mingw/libopenmpt.dll.a new file mode 100644 index 0000000000000000000000000000000000000000..72940372211829f26b413075496f7e201d5fb357 Binary files /dev/null and b/libs/libopenmpt/lib/x86_64/mingw/libopenmpt.dll.a differ diff --git a/objs/DC/SDL/Debug/.gitignore b/objs/DC/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/objs/DC/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/DC/SDL/Release/.gitignore b/objs/DC/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/objs/DC/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/PS3/SDL/Debug/.gitignore b/objs/PS3/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/objs/PS3/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/PS3/SDL/Release/.gitignore b/objs/PS3/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/objs/PS3/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/PSP/SDL/Release/.gitignore b/objs/PSP/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/objs/PSP/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Wii/SDL/Debug/.gitignore b/objs/Wii/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/objs/Wii/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Wii/SDL/Release/.gitignore b/objs/Wii/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/objs/Wii/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/WinCE/SDL/Release/.gitignore b/objs/WinCE/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/objs/WinCE/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/XBOX/SDL/Debug/.gitignore b/objs/XBOX/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/objs/XBOX/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/XBOX/SDL/Release/.gitignore b/objs/XBOX/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/objs/XBOX/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/nds/Debug/.gitignore b/objs/nds/Debug/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/objs/nds/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/nds/Release/.gitignore b/objs/nds/Release/.gitignore deleted file mode 100644 index 42c6dc2c662642792a8860e166dfd81126695e8f..0000000000000000000000000000000000000000 --- a/objs/nds/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 85cda35f665e6a6f4bf0293f107e0e3740429107..fb1bd8afb14c03f35ef3f891dad0761d3da8c88e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -123,6 +123,7 @@ set(SRB2_CORE_RENDER_SOURCES r_sky.c r_splats.c r_things.c + r_portal.c r_bsp.h r_data.h @@ -136,6 +137,7 @@ set(SRB2_CORE_RENDER_SOURCES r_splats.h r_state.h r_things.h + r_portal.h ) set(SRB2_CORE_GAME_SOURCES @@ -218,6 +220,8 @@ set(SRB2_CONFIG_HAVE_ZLIB ON CACHE BOOL "Enable zlib support.") set(SRB2_CONFIG_HAVE_GME ON CACHE BOOL "Enable GME support.") +set(SRB2_CONFIG_HAVE_OPENMPT ON CACHE BOOL + "Enable OpenMPT support.") set(SRB2_CONFIG_HWRENDER ON CACHE BOOL "Enable hardware rendering through OpenGL.") set(SRB2_CONFIG_USEASM OFF CACHE BOOL @@ -230,7 +234,7 @@ set(SRB2_CONFIG_STATIC_OPENGL OFF CACHE BOOL ### use internal libraries? if(${CMAKE_SYSTEM} MATCHES "Windows") ###set on Windows only set(SRB2_CONFIG_USE_INTERNAL_LIBRARIES OFF CACHE BOOL - "Use SRB2's internal copies of required dependencies (SDL2, PNG, zlib, GME).") + "Use SRB2's internal copies of required dependencies (SDL2, PNG, zlib, GME, OpenMPT).") endif() if(${SRB2_CONFIG_HAVE_BLUA}) @@ -340,6 +344,26 @@ if(${SRB2_CONFIG_HAVE_GME}) endif() endif() +if(${SRB2_CONFIG_HAVE_OPENMPT}) + if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES}) + set(OPENMPT_FOUND ON) + set(OPENMPT_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/libopenmpt/inc) + if(${SRB2_SYSTEM_BITS} EQUAL 64) + set(OPENMPT_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/libopenmpt/lib/x86_64/mingw -lopenmpt") + else() # 32-bit + set(OPENMPT_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/libopenmpt/lib/x86/mingw -lopenmpt") + endif() + else() + find_package(OPENMPT) + endif() + if(${OPENMPT_FOUND}) + set(SRB2_HAVE_OPENMPT ON) + add_definitions(-DHAVE_OPENMPT) + else() + message(WARNING "You have specified that OpenMPT is available but it was not found.") + endif() +endif() + if(${SRB2_CONFIG_HAVE_ZLIB}) if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES}) set(ZLIB_FOUND ON) diff --git a/src/Makefile b/src/Makefile index 6f7927077b61f69ffd0a4bb3cd42f17d556761cb..e43c38f677b4ffe6c4504f602154647f2f7eb1b1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -34,8 +34,6 @@ # compile all HW render and 3D sound DLLs for the set # opengl_dll # Pure Mingw only, compile OpenGL HW render DLL -# minigl_dll -# Pure Mingw only, compile MiniGL HW render DLL # ds3d_dll # Pure Mingw only, compile DirectX DirectSound HW sound DLL # fmod_dll @@ -74,6 +72,7 @@ # Compile without BSD API, add 'NONET=1' # Compile without IPX/SPX, add 'NOIPX=1' # Compile Mingw/SDL with S_DS3S, add 'DS3D=1' +# Compile without libopenmpt, add 'NOOPENMPT=1' # Compile with S_FMOD3D, add 'FMOD=1' (WIP) # Compile with S_OPENAL, add 'OPENAL=1' (WIP) # To link with the whole SDL_Image lib to load Icons, add 'SDL_IMAGE=1' but it isn't not realy needed @@ -83,7 +82,7 @@ # SRB2 data files D_DIR?=../bin/Resources -D_FILES=$(D_DIR)/srb2.srb \ +D_FILES=$(D_DIR)/srb2.pk3 \ $(D_DIR)/player.dta \ $(D_DIR)/rings.wpn \ $(D_DIR)/drill.dta \ @@ -93,10 +92,6 @@ D_FILES=$(D_DIR)/srb2.srb \ PKG_CONFIG?=pkg-config -ifdef WIILINUX -LINUX=1 -endif - ifdef PANDORA LINUX=1 endif @@ -120,12 +115,6 @@ ifdef HAIKU SDL=1 endif -ifdef NDS -# Include this before the main Makefile.cfg -EXENAME?=srb2.elf -include nds/Makefile.cfg -endif - include Makefile.cfg ifdef DUMMY @@ -152,36 +141,20 @@ PNG_CFLAGS?= PNG_LDFLAGS?=-lpng endif -ifdef WIILINUX -NONX86=1 -NOTERMIOS=1 -NOHW=1 -CFLAGS+=-DWMINPUT -NOTERMIOS=1 -NOPOSTPROCESSING=1 -endif - ifdef PANDORA NONX86=1 NOHW=1 NOHS=1 endif -ifdef WII -NONX86=1 -NOHW=1 -NOPOSTPROCESSING=1 -endif - -ifdef PS3N -NONX86=1 -NOHW=1 -endif - ifdef DJGPPDOS include djgppdos/Makefile.cfg endif +ifndef NOOPENMPT +HAVE_OPENMPT=1 +endif + ifdef MINGW include win32/Makefile.cfg endif #ifdef MINGW @@ -209,27 +182,8 @@ ifdef MACOSX UNIXCOMMON=1 endif -ifdef NDS -NOPNG=1 -NOZLIB=1 -NONET=1 -#NOHW=1 -NOHS=1 -NOASM=1 -NOIPX=1 -NONX86=1 -OBJS+=$(OBJDIR)/i_video.o -LIBS+=-lm -endif - ifdef SDL -#SDL 2.0 -ifndef SDL12 include sdl/Makefile.cfg -#SDL 1.2 -else - include sdl12/Makefile.cfg -endif #ifndef SDL12 endif #ifdef SDL ifdef DISTCC @@ -251,11 +205,7 @@ ifndef ECHO OBJDUMP:=@$(OBJDUMP) STRIP:=@$(STRIP) WINDRES:=@$(WINDRES) - CP:=@$(CP) MKDIR:=@$(MKDIR) - MKISOFS:=@$(MKISOFS) - DD:=@$(DD) - NDSTOOL:=@$(NDSTOOL) GZIP:=@$(GZIP) MSGFMT:=@$(MSGFMT) UPX:=@$(UPX) @@ -273,10 +223,8 @@ endif ifdef NOHW OPTS+=-DNOHW else -ifndef DC #Hurdler: not really supported and not tested recently #OPTS+=-DUSE_PALETTED_TEXTURE -endif OPTS+=-DHWRENDER OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \ $(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o \ @@ -354,6 +302,17 @@ LIBS+=$(LIBGME_LDFLAGS) CFLAGS+=$(LIBGME_CFLAGS) endif +ifdef HAVE_OPENMPT +OPTS+=-DHAVE_OPENMPT + +LIBOPENMPT_PKGCONFIG?=libopenmpt +LIBOPENMPT_CFLAGS?=$(shell $(PKG_CONFIG) $(LIBOPENMPT_PKGCONFIG) --cflags) +LIBOPENMPT_LDFLAGS?=$(shell $(PKG_CONFIG) $(LIBOPENMPT_PKGCONFIG) --libs) + +LIBS+=$(LIBOPENMPT_LDFLAGS) +CFLAGS+=$(LIBOPENMPT_CFLAGS) +endif + ifndef NOZLIB OPTS+=-DHAVE_ZLIB ZLIB_PKGCONFIG?=zlib @@ -392,14 +351,6 @@ else OBJS:=$(OBJDIR)/md5.o $(OBJS) endif -ifdef FAKEDC - OPTS+=-DDC -endif - -ifdef FAKEPSP - OPTS+=-DPSP -endif - ifdef NOPOSTPROCESSING OPTS+=-DNOPOSTPROCESSING endif @@ -521,6 +472,7 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/r_sky.o \ $(OBJDIR)/r_splats.o \ $(OBJDIR)/r_things.o \ + $(OBJDIR)/r_portal.o \ $(OBJDIR)/screen.o \ $(OBJDIR)/v_video.o \ $(OBJDIR)/s_sound.o \ @@ -552,49 +504,20 @@ ifdef DJGPPDOS all: pre-build $(BIN)/$(EXENAME) endif -ifdef XBOX -all: pre-build $(BIN)/$(BINNAME) -endif - -ifdef PS3N -all: pre-build $(BIN)/$(PKGNAME) -endif - -ifdef WII -all: pre-build $(BIN)/$(DOLNAME) -endif - ifdef PANDORA all: pre-build $(BIN)/$(PNDNAME) endif -ifdef PSP -all: pre-build $(BIN)/$(BINNAME) post-build -endif - -ifdef DC -all: pre-build $(BIN)/$(BINNAME) post-build -endif -ifndef DC -ifndef PSP -ifndef XBOX ifdef MINGW ifndef SDL all: pre-build $(BIN)/$(EXENAME) dll endif endif -endif -endif ifdef SDL all: pre-build $(BIN)/$(EXENAME) endif -endif - -ifdef NDS -all: $(BIN)/$(EXENAME:.elf=.nds) -endif ifdef DUMMY all: $(BIN)/$(EXENAME) @@ -648,12 +571,10 @@ endif # mac os x lsdlsrb2 does not like objcopy ifndef MACOSX -ifndef PSP $(OBJCOPY) $(BIN)/$(EXENAME) $(BIN)/$(DBGNAME) $(OBJCOPY) --strip-debug $(BIN)/$(EXENAME) -$(OBJCOPY) --add-gnu-debuglink=$(BIN)/$(DBGNAME) $(BIN)/$(EXENAME) endif -endif ifndef NOUPX -$(UPX) $(UPX_OPTS) $(BIN)/$(EXENAME) endif @@ -678,7 +599,7 @@ else dll : opengl_dll endif ifdef MINGW -all_dll: opengl_dll minigl_dll ds3d_dll fmod_dll openal_dll +all_dll: opengl_dll ds3d_dll fmod_dll openal_dll opengl_dll: $(BIN)/r_opengl.dll $(BIN)/r_opengl.dll: $(OBJDIR)/ogl_win.o $(OBJDIR)/r_opengl.o @@ -689,12 +610,6 @@ ifndef NOUPX -$(UPX) $(UPX_OPTS) $@ endif -minigl_dll: $(BIN)/r_minigl.dll -$(BIN)/r_minigl.dll: $(OBJDIR)/r_minigl.o - -$(MKDIR) $(BIN) - @echo Linking R_MiniGL.dll... - $(CC) --shared $^ -o $@ -g -Wl,--add-stdcall-alias -lgdi32 - ds3d_dll: $(BIN)/s_ds3d.dll $(BIN)/s_ds3d.dll: $(OBJDIR)/s_ds3d.o @echo Linking S_DS3d.dll... @@ -774,16 +689,6 @@ endif $(REMOVE) $(OBJDIR)/depend.ped @echo "Created dependency file, depend.dep" -ifdef DC -$(OBJDIR)/v_video.o: v_video.c doomdef.h doomtype.h g_state.h m_swap.h r_local.h \ - tables.h m_fixed.h screen.h command.h m_bbox.h r_main.h d_player.h \ - p_pspr.h info.h d_think.h sounds.h p_mobj.h doomdata.h d_ticcmd.h \ - r_data.h r_defs.h r_state.h r_bsp.h r_segs.h r_plane.h r_sky.h \ - r_things.h r_draw.h v_video.h hu_stuff.h d_event.h w_wad.h console.h \ - i_video.h z_zone.h doomstat.h d_clisrv.h d_netcmd.h - $(CC) $(CFLAGS) -fno-omit-frame-pointer $(WFLAGS) -c $< -o $@ -endif - ifdef VALGRIND $(OBJDIR)/z_zone.o: z_zone.c $(CC) $(CFLAGS) $(WFLAGS) -DHAVE_VALGRIND $(VALGRIND_CFLAGS) -c $< -o $@ @@ -825,70 +730,6 @@ $(OBJDIR)/%.o: %.s $(OBJDIR)/SRB2.res: win32/Srb2win.rc win32/afxres.h win32/resource.h $(WINDRES) -i $< -O rc $(WINDRESFLAGS) --include-dir=win32 -o $@ -O coff -ifdef DC -$(OBJDIR)/romdisk.img: - $(KOS_GENROMFS) -f romdisk.img -d ../data -v - -$(OBJDIR)/romdisk.o: romdisk.img - $(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk.o - -$(OBJDIR)/dchelp.o: $(INTERFACE)/SRB2DC/dchelp.c - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/i_udp.o: $(INTERFACE)/SRB2DC/i_udp.c - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(BIN)/IP.BIN: $(INTERFACE)/SRB2DC/IP.BIN - $(CP) $< $@ - -$(BIN)/SRB2DC.cdi.pass1: $(INTERFACE)/SRB2DC/SELFBOOT.BIN - $(CP) $< $@ - -$(BIN)/$(BINNAME): $(BIN)/$(EXENAME) - $(KOS_OBJCOPY) -R .stack -O binary $< $@ - -$(BIN)/1ST_READ.BIN: $(BIN)/$(BINNAME) $(BIN)/scramble - $(BIN)/scramble $< $@ - -$(BIN)/scramble: $(INTERFACE)/SRB2DC/scramble.c - -$(MKDIR) $(BIN) - $(HOSTCC) $< -o $@ - -iso: $(BIN)/SRB2DC.iso -cdi: $(BIN)/SRB2DC.cdi - -$(BIN)/SRB2DC.iso.pass1: $(BIN)/1ST_READ.BIN $(BIN)/IP.BIN - -$(MKDIR) $(BIN)/cdrom - $(CP) $(BIN)/1ST_READ.BIN $(D_FILES) $(BIN)/cdrom - $(MKISOFS) -l -r -o $@ $(BIN)/cdrom - -$(BIN)/SRB2DC.iso.pass2: $(BIN)/SRB2DC.iso.pass1 - $(DD) if=$< of=$@ bs=2048 skip=16 status=noxfer - -$(BIN)/SRB2DC.iso: $(BIN)/SRB2DC.iso.pass2 $(BIN)/IP.BIN - @cat $(BIN)/IP.BIN $(BIN)/SRB2DC.iso.pass2 > $@ - -$(BIN)/SRB2DC.cdi: $(BIN)/SRB2DC.iso.pass2 $(BIN)/SRB2DC.cdi.pass1 $(BIN)/IP.BIN - @cat $(BIN)/SRB2DC.cdi.pass1 $(BIN)/IP.BIN $(BIN)/SRB2DC.iso.pass2 > $@ - -post-build: $(BIN)/1ST_READ.BIN -endif - -ifdef XBOX -$(OBJDIR)/xboxhelp.o: $(INTERFACE)/SRB2XBOX/xboxhelp.c - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(BIN)/$(BINNAME): $(BIN)/$(EXENAME) - $(CXBE) -OUT:"$@" -DUMPINFO:"$(BIN)/SRB2XBOX.cxbe" -TITLE:"Sonic Robo Blast 2" $< -endif - -ifdef NDS -$(BIN)/$(EXENAME:.elf=.nds): $(BIN)/$(EXENAME:.elf=.arm9) - $(NDSTOOL) -c $@ -9 $(BIN)/$(EXENAME:.elf=.arm9) - -%.arm9: %.elf - $(OBJCOPY) -O binary $< $@ -endif ifdef MINGW ifndef SDL @@ -910,15 +751,6 @@ $(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \ am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@ - -$(OBJDIR)/r_minigl.o: hardware/r_minigl/r_minigl.c hardware/r_opengl/r_opengl.h \ - doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ - command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ - hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ - am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ - p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h - $(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@ endif ifndef NOHS @@ -968,25 +800,6 @@ $(OBJDIR)/s_openal.o: hardware/s_openal/s_openal.c hardware/hw3dsdrv.h \ hardware/hw_dll.h $(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_openal.o -DHW3SOUND -DUNIXCOMMON -shared -nostartfiles -c hardware/s_openal/s_openal.c endif - -ifdef FILTERS -$(OBJDIR)/%.o: $(INTERFACE)/filter/%.c - @echo $< needs deps - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/filters.o: $(INTERFACE)/filter/filters.c $(INTERFACE)/filter/filters.c \ - $(INTERFACE)/filter/filters.h - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/hq2x.o: $(INTERFACE)/filter/hq2x.c $(INTERFACE)/filter/hq2x.c \ - $(INTERFACE)/filter/filters.h - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/lq2x.o: $(INTERFACE)/filter/lq2x.c $(INTERFACE)/filter/lq2x.c \ - $(INTERFACE)/filter/filters.h $(INTERFACE)/filter/interp.h \ - $(INTERFACE)/filter/hq2x.h $(INTERFACE)/filter/lq2x.h - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ -endif endif ############################################################# diff --git a/src/Makefile.cfg b/src/Makefile.cfg index a0398154a5c14a80b0e408c1413e4f48597cac74..2b05b70970881b83886f0b6001e40579f9283cc4 100644 --- a/src/Makefile.cfg +++ b/src/Makefile.cfg @@ -96,10 +96,6 @@ ifdef GCC295 GCC29=1 endif -ifdef DC -NOCASTALIGNWARN=1 -endif - OLDWFLAGS:=$(WFLAGS) # -W -Wno-unused WFLAGS=-Wall @@ -159,15 +155,11 @@ endif ifdef GCC40 WFLAGS+=-Wold-style-definition endif -ifndef XBOX WFLAGS+=-Wmissing-prototypes -Wmissing-declarations -endif ifdef GCC40 WFLAGS+=-Wmissing-field-initializers endif -ifndef XBOX WFLAGS+=-Wmissing-noreturn -endif #WFLAGS+=-Wmissing-format-attribute #WFLAGS+=-Wno-multichar #WFLAGS+=-Wno-deprecated-declarations @@ -235,19 +227,12 @@ endif #indicate platform and what interface use with -ifndef WINCE -ifndef XBOX -ifndef PSP -ifndef DC -ifndef WII -ifndef PS3N ifndef LINUX ifndef FREEBSD ifndef CYGWIN32 ifndef MINGW ifndef MINGW64 ifndef SDL -ifndef NDS ifndef DUMMY DJGPPDOS=1 endif @@ -257,13 +242,6 @@ endif endif endif endif -endif -endif -endif -endif -endif -endif -endif #determine the interface directory (where you put all i_*.c) i_cdmus_o=$(OBJDIR)/i_cdmus.o @@ -281,10 +259,7 @@ else NASM?=nasm endif REMOVE?=rm -f -CP?=cp MKDIR?=mkdir -p -MKISOFS?=mkisofs -DD?=dd GZIP?=gzip GZIP_OPTS?=-9 -f -n GZIP_OPT2=$(GZIP_OPTS) --rsyncable @@ -351,86 +326,11 @@ ifdef MINGW64 OBJDIR:=$(OBJDIR)/Mingw64 BIN:=$(BIN)/Mingw64 else -ifdef WII - INTERFACE=sdl12 - NONX86=1 - STATIC=1 - PREFIX?=powerpc-eabi - SDL=1 - SDL12=1 - SDLMAIN=1 - OBJDIR:=$(OBJDIR)/Wii - BIN:=$(BIN)/Wii - NOUPX=1 -else -ifdef PS3N - INTERFACE=sdl12 - NONX86=1 - STATIC=1 - PREFIX?=ppu - SDL=1 - SDL12=1 - # unsure? - #SDLMAIN=1 - # can't compile SDL_mixer for ps3... - NOMIXER=1 - OBJDIR:=$(OBJDIR)/PS3 - BIN:=$(BIN)/PS3 -else ifdef MINGW INTERFACE=win32 NASMFORMAT=win32 OBJDIR:=$(OBJDIR)/Mingw BIN:=$(BIN)/Mingw -else -ifdef XBOX - INTERFACE=sdl12 - NASMFORMAT=win32 - PREFIX?=/usr/local/openxdk/bin/i386-pc-xbox - SDL=1 - SDL12=1 - OBJDIR:=$(OBJDIR)/XBOX - BIN:=$(BIN)/XBOX -else -ifdef PSP - INTERFACE=sdl12 - NONX86=1 - SDL=1 - SDL12=1 - OBJDIR:=$(OBJDIR)/PSP - BIN:=$(BIN)/PSP - NOUPX=1 -else -ifdef DC - INTERFACE=sdl12 - NONX86=1 - SDL=1 - SDL12=1 - OBJDIR:=$(OBJDIR)/DC - BIN:=$(BIN)/DC - NOUPX=1 -else -ifdef WINCE - INTERFACE=sdl12 - NONX86=1 - PREFIX?=arm-wince-pe - SDL=1 - SDL12=1 - OBJDIR:=$(OBJDIR)/WinCE - BIN:=$(BIN)/WinCE -else -ifdef NDS - INTERFACE=nds - OBJDIR:=$(OBJDIR)/nds - BIN:=$(BIN)/nds - NOUPX=1 -endif -endif -endif -endif -endif -endif -endif endif endif endif @@ -440,12 +340,6 @@ endif endif endif -ifdef GP2X -ifdef SDL - SDL12=1 -endif -endif - ifdef ARCHNAME OBJDIR:=$(OBJDIR)/$(ARCHNAME) BIN:=$(BIN)/$(ARCHNAME) @@ -479,13 +373,7 @@ OBJDUMP_OPTS?=--wide --source --line-numbers LD=$(CC) ifdef SDL -# SDL 2.0 -ifndef SDL12 INTERFACE=sdl -# SDL 1.2 -else - INTERFACE=sdl12 -endif OBJDIR:=$(OBJDIR)/SDL endif diff --git a/src/am_map.c b/src/am_map.c index 5e73d2ec45880c2d1741442b97436f669ef1f296..6d7042f1c9009720d8cd8aa73bdefd08996f7fa7 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -43,10 +43,6 @@ static const UINT8 NOCLIMBBROWNS = (2*16); static const UINT8 NOCLIMBYELLOWS = (11*16); -#ifdef _NDS -#undef BACKGROUND -#endif - // Automap colors #define BACKGROUND DBLACK #define WALLCOLORS (REDS + REDRANGE/2) diff --git a/src/b_bot.c b/src/b_bot.c index a6d07895bb8751d6463e26c553af64dd0570376a..17211b3532d2ace7448fd3a7f1cafac82a1bef9e 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -41,12 +41,13 @@ static inline void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cm return; #endif - if (tails->player->pflags & (PF_MACESPIN|PF_ITEMHANG)) + if (tails->player->powers[pw_carry] == CR_MACESPIN || tails->player->powers[pw_carry] == CR_GENERIC) { + boolean isrelevant = (sonic->player->powers[pw_carry] == CR_MACESPIN || sonic->player->powers[pw_carry] == CR_GENERIC); dist = P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y); - if (sonic->player->cmd.buttons & BT_JUMP && sonic->player->pflags & (PF_JUMPED|PF_MACESPIN|PF_ITEMHANG)) + if (sonic->player->cmd.buttons & BT_JUMP && (sonic->player->pflags & PF_JUMPED) && isrelevant) cmd->buttons |= BT_JUMP; - if (sonic->player->pflags & (PF_MACESPIN|PF_ITEMHANG)) + if (isrelevant) { cmd->forwardmove = sonic->player->cmd.forwardmove; cmd->angleturn = abs((signed)(tails->angle - sonic->angle))>>16; @@ -211,8 +212,9 @@ boolean B_CheckRespawn(player_t *player) // Check if Sonic is busy first. // If he's doing any of these things, he probably doesn't want to see us. - if (sonic->player->pflags & (PF_ROPEHANG|PF_GLIDING|PF_CARRIED|PF_SLIDING|PF_ITEMHANG|PF_MACESPIN|PF_NIGHTSMODE) - || (sonic->player->panim != PA_IDLE && sonic->player->panim != PA_WALK)) + if (sonic->player->pflags & (PF_GLIDING|PF_SLIDING|PF_BOUNCING) + || (sonic->player->panim != PA_IDLE && sonic->player->panim != PA_WALK) + || (sonic->player->powers[pw_carry])) return false; // Low ceiling, do not want! @@ -269,15 +271,20 @@ void B_RespawnBot(INT32 playernum) player->powers[pw_spacetime] = sonic->player->powers[pw_spacetime]; player->powers[pw_gravityboots] = sonic->player->powers[pw_gravityboots]; player->powers[pw_nocontrol] = sonic->player->powers[pw_nocontrol]; + player->acceleration = sonic->player->acceleration; + player->accelstart = sonic->player->accelstart; + player->thrustfactor = sonic->player->thrustfactor; + player->normalspeed = sonic->player->normalspeed; + player->pflags |= PF_AUTOBRAKE|(sonic->player->pflags & PF_DIRECTIONCHAR); P_TeleportMove(tails, x, y, z); if (player->charability == CA_FLY) { - P_SetPlayerMobjState(tails, S_PLAY_ABL1); + P_SetPlayerMobjState(tails, S_PLAY_FLY); tails->player->powers[pw_tailsfly] = (UINT16)-1; } else - P_SetPlayerMobjState(tails, S_PLAY_FALL1); + P_SetPlayerMobjState(tails, S_PLAY_FALL); P_SetScale(tails, sonic->scale); tails->destscale = sonic->destscale; } diff --git a/src/blua/Makefile.cfg b/src/blua/Makefile.cfg index b1131eaca7fe1ebc3b12a7d410b7a38f97a3038b..8d2e7371428db75ced4042be0f33167a594d65f3 100644 --- a/src/blua/Makefile.cfg +++ b/src/blua/Makefile.cfg @@ -39,7 +39,6 @@ OBJS:=$(OBJS) \ $(OBJDIR)/lvm.o \ $(OBJDIR)/lua_script.o \ $(OBJDIR)/lua_baselib.o \ - $(OBJDIR)/lua_blockmaplib.o \ $(OBJDIR)/lua_mathlib.o \ $(OBJDIR)/lua_hooklib.o \ $(OBJDIR)/lua_consolelib.o \ @@ -49,4 +48,5 @@ OBJS:=$(OBJS) \ $(OBJDIR)/lua_skinlib.o \ $(OBJDIR)/lua_thinkerlib.o \ $(OBJDIR)/lua_maplib.o \ + $(OBJDIR)/lua_blockmaplib.o \ $(OBJDIR)/lua_hudlib.o diff --git a/src/command.c b/src/command.c index de5a99d510ecff134622c9f1459007bfdc9bbfee..600803cdbc49033ab7ab7ecdcbb0a77efa8fd551 100644 --- a/src/command.c +++ b/src/command.c @@ -1204,7 +1204,16 @@ found: var->value = (INT32)(d * FRACUNIT); } else - var->value = atoi(var->string); + { + if (var == &cv_forceskin) + { + var->value = R_SkinAvailable(var->string); + if (!R_SkinUsable(-1, var->value)) + var->value = -1; + } + else + var->value = atoi(var->string); + } finish: // See the note above. @@ -1270,7 +1279,7 @@ static void Got_NetVar(UINT8 **p, INT32 playernum) if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -1289,9 +1298,6 @@ static void Got_NetVar(UINT8 **p, INT32 playernum) CONS_Alert(CONS_WARNING, "Netvar not found with netid %hu\n", netid); return; } -#if 0 //defined (GP2X) || defined (PSP) - CONS_Printf("Netvar received: %s [netid=%d] value %s\n", cvar->name, netid, svalue); -#endif DEBFILE(va("Netvar received: %s [netid=%d] value %s\n", cvar->name, netid, svalue)); Setvalue(cvar, svalue, stealth); @@ -1390,7 +1396,7 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth) if (var->flags & CV_NETVAR) { // send the value of the variable - XBOXSTATIC UINT8 buf[128]; + UINT8 buf[128]; UINT8 *p = buf; if (!(server || (IsPlayerAdmin(consoleplayer)))) { @@ -1398,6 +1404,16 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth) return; } + if (var == &cv_forceskin) + { + INT32 skin = R_SkinAvailable(value); + if ((stricmp(value, "None")) && ((skin == -1) || !R_SkinUsable(-1, skin))) + { + CONS_Printf("Please provide a valid skin name (\"None\" disables).\n"); + return; + } + } + // Only add to netcmd buffer if in a netgame, otherwise, just change it. if (netgame || multiplayer) { @@ -1431,6 +1447,30 @@ void CV_StealthSet(consvar_t *var, const char *value) CV_SetCVar(var, value, true); } +/** Sets a numeric value to a variable, sometimes calling its callback + * function. + * + * \param var The variable. + * \param value The numeric value, converted to a string before setting. + * \param stealth Do we call the callback function or not? + */ +static void CV_SetValueMaybeStealth(consvar_t *var, INT32 value, boolean stealth) +{ + char val[32]; + + if (var == &cv_forceskin) // Special handling. + { + if ((value < 0) || (value >= numskins)) + sprintf(val, "None"); + else + sprintf(val, "%s", skins[value].name); + } + else + sprintf(val, "%d", value); + + CV_SetCVar(var, val, stealth); +} + /** Sets a numeric value to a variable without calling its callback * function. * @@ -1440,10 +1480,7 @@ void CV_StealthSet(consvar_t *var, const char *value) */ void CV_StealthSetValue(consvar_t *var, INT32 value) { - char val[32]; - - sprintf(val, "%d", value); - CV_SetCVar(var, val, true); + CV_SetValueMaybeStealth(var, value, true); } // New wrapper for what used to be CV_Set() @@ -1461,10 +1498,7 @@ void CV_Set(consvar_t *var, const char *value) */ void CV_SetValue(consvar_t *var, INT32 value) { - char val[32]; - - sprintf(val, "%d", value); - CV_SetCVar(var, val, false); + CV_SetValueMaybeStealth(var, value, false); } /** Adds a value to a console variable. @@ -1484,7 +1518,23 @@ void CV_AddValue(consvar_t *var, INT32 increment) // count pointlimit better if (var == &cv_pointlimit && (gametype == GT_MATCH)) increment *= 50; - newvalue = var->value + increment; + + if (var == &cv_forceskin) // Special handling. + { + INT32 oldvalue = var->value; + newvalue = oldvalue; + do + { + newvalue += increment; + if (newvalue < -1) + newvalue = (numskins - 1); + else if (newvalue >= numskins) + newvalue = -1; + } while ((oldvalue != newvalue) + && !(R_SkinUsable(-1, newvalue))); + } + else + newvalue = var->value + increment; if (var->PossibleValue) { @@ -1554,34 +1604,27 @@ void CV_AddValue(consvar_t *var, INT32 increment) if (var == &cv_chooseskin) { // Special case for the chooseskin variable, used only directly from the menu - if (increment > 0) // Going up! + newvalue = var->value - 1; + do { - newvalue = var->value - 1; - do + if (increment > 0) // Going up! { newvalue++; if (newvalue == MAXSKINS) newvalue = 0; - } while (var->PossibleValue[newvalue].strvalue == NULL); - var->value = newvalue + 1; - var->string = var->PossibleValue[newvalue].strvalue; - var->func(); - return; - } - else if (increment < 0) // Going down! - { - newvalue = var->value - 1; - do + } + else if (increment < 0) // Going down! { newvalue--; if (newvalue == -1) newvalue = MAXSKINS-1; - } while (var->PossibleValue[newvalue].strvalue == NULL); - var->value = newvalue + 1; - var->string = var->PossibleValue[newvalue].strvalue; - var->func(); - return; - } + } + } while (var->PossibleValue[newvalue].strvalue == NULL); + + var->value = newvalue + 1; + var->string = var->PossibleValue[newvalue].strvalue; + var->func(); + return; } #ifdef PARANOIA if (currentindice == -1) diff --git a/src/config.h.in b/src/config.h.in index 1e6a7f514939491a6428b08c840679a1d14f4d2f..fc32aef823e27f61abf1e22859073112646158ef 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -11,12 +11,11 @@ #ifdef CMAKECONFIG -#define ASSET_HASH_SRB2_SRB "${SRB2_ASSET_srb2.srb_HASH}" +#define ASSET_HASH_SRB2_PK3 "${SRB2_ASSET_srb2.pk3_HASH}" #define ASSET_HASH_PLAYER_DTA "${SRB2_ASSET_player.dta_HASH}" -#define ASSET_HASH_RINGS_DTA "${SRB2_ASSET_rings.dta_HASH}" #define ASSET_HASH_ZONES_DTA "${SRB2_ASSET_zones.dta_HASH}" #ifdef USE_PATCH_DTA -#define ASSET_HASH_PATCH_DTA "${SRB2_ASSET_patch.dta_HASH}" +#define ASSET_HASH_PATCH_PK3 "${SRB2_ASSET_patch.pk3_HASH}" #endif #define SRB2_COMP_REVISION "${SRB2_COMP_REVISION}" @@ -28,14 +27,13 @@ /* Manually defined asset hashes for non-CMake builds * Last updated 2015 / 05 / 03 - v2.1.15 - main assets - * Last updated 2018 / 12 / 23 - v2.1.22 - patch.dta + * Last updated 2018 / ?? / ?? - v2.2 - patch.pk3 */ -#define ASSET_HASH_SRB2_SRB "c1b9577687f8a795104aef4600720ea7" +#define ASSET_HASH_SRB2_PK3 "c1b9577687f8a795104aef4600720ea7" #define ASSET_HASH_ZONES_DTA "303838c6c534d9540288360fa49cca60" #define ASSET_HASH_PLAYER_DTA "cfca0f1c73023cbbd8f844f45480f799" -#define ASSET_HASH_RINGS_DTA "85901ad4bf94637e5753d2ac2c03ea26" #ifdef USE_PATCH_DTA -#define ASSET_HASH_PATCH_DTA "b04fd9624bfd94dc96dcf4f400f7deb4" +#define ASSET_HASH_PATCH_PK3 "dbbf8bc6121618ee3be2d5b14650429b" #endif #endif diff --git a/src/console.c b/src/console.c index 91baf25fcfe4fbfd6c2240258a8eccda23bebd8a..c1c5557b9d680dbf765f8559dca6a3321c1b55d2 100644 --- a/src/console.c +++ b/src/console.c @@ -12,9 +12,6 @@ #ifdef __GNUC__ #include <unistd.h> -#ifdef _XBOX -#include <openxdk/debug.h> -#endif #endif #include "doomdef.h" @@ -139,6 +136,7 @@ static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Black"}, { {18,"Lavender"}, {0, NULL}}; + consvar_t cons_backcolor = {"con_backcolor", "Green", CV_CALL|CV_SAVE, backcolor_cons_t, CONS_backcolor_Change, 0, NULL, NULL, 0, 0, NULL}; static void CON_Print(char *msg); @@ -229,108 +227,139 @@ static void CONS_Bind_f(void) // Font colormap colors // TODO: This could probably be improved somehow... // These colormaps are 99% identical, with just a few changed bytes -UINT8 *yellowmap; -UINT8 *purplemap; -UINT8 *lgreenmap; -UINT8 *bluemap; -UINT8 *graymap; -UINT8 *redmap; -UINT8 *orangemap; +// This could EASILY be handled by modifying a centralised colormap +// for software depending on the prior state - but yknow, OpenGL... +UINT8 *yellowmap, *magentamap, *lgreenmap, *bluemap, *graymap, *redmap, *orangemap, *skymap, *purplemap, *aquamap, *peridotmap, *azuremap, *brownmap, *rosymap, *invertmap; // Console BG color UINT8 *consolebgmap = NULL; +UINT8 *promptbgmap = NULL; +static UINT8 promptbgcolor = UINT8_MAX; -void CON_SetupBackColormap(void) +void CON_SetupBackColormapEx(INT32 color, boolean prompt) { UINT16 i, palsum; UINT8 j, palindex; UINT8 *pal = W_CacheLumpName(GetPalette(), PU_CACHE); INT32 shift = 6; - if (!consolebgmap) - consolebgmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); + if (color == INT32_MAX) + color = cons_backcolor.value; - switch (cons_backcolor.value) + shift = 6; // 12 colors -- shift of 7 means 6 colors + + switch (color) { case 0: palindex = 15; break; // White - case 1: palindex = 31; break; // Gray - case 2: palindex = 47; break; // Sepia - case 3: palindex = 63; break; // Brown - case 4: palindex = 150; shift = 7; break; // Pink - case 5: palindex = 127; shift = 7; break; // Raspberry - case 6: palindex = 143; break; // Red - case 7: palindex = 86; shift = 7; break; // Creamsicle - case 8: palindex = 95; break; // Orange - case 9: palindex = 119; shift = 7; break; // Gold - case 10: palindex = 111; break; // Yellow - case 11: palindex = 191; shift = 7; break; // Emerald - case 12: palindex = 175; break; // Green - case 13: palindex = 219; break; // Cyan - case 14: palindex = 207; shift = 7; break; // Steel - case 15: palindex = 230; shift = 7; break; // Periwinkle - case 16: palindex = 239; break; // Blue - case 17: palindex = 199; shift = 7; break; // Purple - case 18: palindex = 255; shift = 7; break; // Lavender + case 1: palindex = 31; break; // Black + case 2: palindex = 251; break; // Sepia + case 3: palindex = 239; break; // Brown + case 4: palindex = 215; shift = 7; break; // Pink + case 5: palindex = 37; shift = 7; break; // Raspberry + case 6: palindex = 47; shift = 7; break; // Red + case 7: palindex = 53; shift = 7; break; // Creamsicle + case 8: palindex = 63; break; // Orange + case 9: palindex = 56; shift = 7; break; // Gold + case 10: palindex = 79; shift = 7; break; // Yellow + case 11: palindex = 119; shift = 7; break; // Emerald + case 12: palindex = 111; break; // Green + case 13: palindex = 136; shift = 7; break; // Cyan + case 14: palindex = 175; shift = 7; break; // Steel + case 15: palindex = 166; shift = 7; break; // Periwinkle + case 16: palindex = 159; break; // Blue + case 17: palindex = 187; shift = 7; break; // Purple + case 18: palindex = 199; shift = 7; break; // Lavender // Default green - default: palindex = 175; break; + default: palindex = 111; break; + } -} + if (prompt) + { + if (!promptbgmap) + promptbgmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); + + if (color == promptbgcolor) + return; + else + promptbgcolor = color; + } + else if (!consolebgmap) + consolebgmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); // setup background colormap for (i = 0, j = 0; i < 768; i += 3, j++) { palsum = (pal[i] + pal[i+1] + pal[i+2]) >> shift; - consolebgmap[j] = (UINT8)(palindex - palsum); + if (prompt) + promptbgmap[j] = (UINT8)(palindex - palsum); + else + consolebgmap[j] = (UINT8)(palindex - palsum); } } +void CON_SetupBackColormap(void) +{ + CON_SetupBackColormapEx(cons_backcolor.value, false); + CON_SetupBackColormapEx(1, true); // default to gray +} + static void CONS_backcolor_Change(void) { - CON_SetupBackColormap(); + CON_SetupBackColormapEx(cons_backcolor.value, false); } static void CON_SetupColormaps(void) { INT32 i; - - yellowmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - graymap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - purplemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - lgreenmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - bluemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - redmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - orangemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); + UINT8 *memorysrc = (UINT8 *)Z_Malloc((256*15), PU_STATIC, NULL); + + magentamap = memorysrc; + yellowmap = (magentamap+256); + lgreenmap = (yellowmap+256); + bluemap = (lgreenmap+256); + redmap = (bluemap+256); + graymap = (redmap+256); + orangemap = (graymap+256); + skymap = (orangemap+256); + purplemap = (skymap+256); + aquamap = (purplemap+256); + peridotmap = (aquamap+256); + azuremap = (peridotmap+256); + brownmap = (azuremap+256); + rosymap = (brownmap+256); + invertmap = (rosymap+256); // setup the other colormaps, for console text // these don't need to be aligned, unless you convert the // V_DrawMappedPatch() into optimised asm. - for (i = 0; i < 256; i++) - { - yellowmap[i] = (UINT8)i; // remap each color to itself... - graymap[i] = (UINT8)i; - purplemap[i] = (UINT8)i; - lgreenmap[i] = (UINT8)i; - bluemap[i] = (UINT8)i; - redmap[i] = (UINT8)i; - orangemap[i] = (UINT8)i; - } - - yellowmap[3] = (UINT8)103; - yellowmap[9] = (UINT8)115; - purplemap[3] = (UINT8)195; - purplemap[9] = (UINT8)198; - lgreenmap[3] = (UINT8)162; - lgreenmap[9] = (UINT8)170; - bluemap[3] = (UINT8)228; - bluemap[9] = (UINT8)238; - graymap[3] = (UINT8)10; - graymap[9] = (UINT8)15; - redmap[3] = (UINT8)124; - redmap[9] = (UINT8)127; - orangemap[3] = (UINT8)85; - orangemap[9] = (UINT8)90; + for (i = 0; i < (256*15); i++, ++memorysrc) + *memorysrc = (UINT8)(i & 0xFF); // remap each color to itself... + +#define colset(map, a, b, c) \ + map[1] = (UINT8)a;\ + map[3] = (UINT8)b;\ + map[9] = (UINT8)c + + colset(magentamap, 177, 178, 184); + colset(yellowmap, 82, 73, 66); + colset(lgreenmap, 97, 98, 106); + colset(bluemap, 146, 147, 155); + colset(redmap, 210, 32, 39); + colset(graymap, 6, 8, 14); + colset(orangemap, 51, 52, 57); + colset(skymap, 129, 130, 133); + colset(purplemap, 160, 161, 163); + colset(aquamap, 120, 121, 123); + colset(peridotmap, 88, 188, 190); + colset(azuremap, 144, 145, 170); + colset(brownmap, 219, 221, 224); + colset(rosymap, 200, 201, 203); + colset(invertmap, 27, 26, 22); + invertmap[26] = (UINT8)3; + +#undef colset // Init back colormap CON_SetupBackColormap(); @@ -338,12 +367,7 @@ static void CON_SetupColormaps(void) // Setup the console text buffer // -// for WII, libogc already has a CON_Init function, we must rename it here -#ifdef _WII -void CON_InitWii(void) -#else void CON_Init(void) -#endif { INT32 i; @@ -1053,10 +1077,10 @@ boolean CON_Responder(event_t *ev) // allow people to use keypad in console (good for typing IP addresses) - Calum if (key >= KEY_KEYPAD7 && key <= KEY_KPADDEL) { - XBOXSTATIC char keypad_translation[] = {'7','8','9','-', - '4','5','6','+', - '1','2','3', - '0','.'}; + char keypad_translation[] = {'7','8','9','-', + '4','5','6','+', + '1','2','3', + '0','.'}; key = keypad_translation[key - KEY_KEYPAD7]; } @@ -1203,7 +1227,7 @@ static void CON_Print(char *msg) void CON_LogMessage(const char *msg) { - XBOXSTATIC char txt[8192], *t; + char txt[8192], *t; const char *p = msg, *e = txt+sizeof (txt)-2; for (t = txt; *p != '\0'; p++) @@ -1239,15 +1263,10 @@ void CONS_Printf(const char *fmt, ...) va_end(argptr); // echo console prints to log file -#ifndef _arch_dreamcast DEBFILE(txt); -#endif if (!con_started) { -#if defined (_XBOX) && defined (__GNUC__) - if (!keyboard_started) debugPrint(txt); -#endif #ifdef PC_DOS CON_LogMessage(txt); free(txt); @@ -1268,7 +1287,7 @@ void CONS_Printf(const char *fmt, ...) // if not in display loop, force screen update if (con_startup) { -#if (defined (_WINDOWS)) || (defined (__OS2__) && !defined (HAVE_SDL)) +#ifdef _WINDOWS patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_CACHE); // Jimita: CON_DrawBackpic just called V_DrawScaledPatch @@ -1419,34 +1438,34 @@ static void CON_DrawInput(void) { x -= charwidth*3; if (input_sel < c) - V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 107 | V_NOSCALESTART); + V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 77 | V_NOSCALESTART); for (i = 0; i < 3; ++i, x += charwidth) - V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true); } else - V_DrawCharacter(x-charwidth, y, CON_PROMPTCHAR | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(x-charwidth, y, CON_PROMPTCHAR | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true); for (cend = c + clen; c < cend; ++c, x += charwidth) { if ((input_sel > c && input_cur <= c) || (input_sel <= c && input_cur > c)) { - V_DrawFill(x, y, charwidth, (10 * con_scalefactor), 107 | V_NOSCALESTART); - V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_YELLOWMAP | V_NOSCALESTART, !cv_allcaps.value); + V_DrawFill(x, y, charwidth, (10 * con_scalefactor), 77 | V_NOSCALESTART); + V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_YELLOWMAP | V_NOSCALESTART, true); } else - V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, true); if (c == input_cur && con_tick >= 4) - V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, true); } if (cend == input_cur && con_tick >= 4) - V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, true); if (rellip) { if (input_sel > cend) - V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 107 | V_NOSCALESTART); + V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 77 | V_NOSCALESTART); for (i = 0; i < 3; ++i, x += charwidth) - V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true); } } @@ -1492,11 +1511,11 @@ static void CON_DrawHudlines(void) else { //charwidth = SHORT(hu_font['A'-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true); } } - //V_DrawCharacter(x, y, (p[c]&0xff) | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + //V_DrawCharacter(x, y, (p[c]&0xff) | cv_constextsize.value | V_NOSCALESTART, true); y += charheight; } @@ -1567,7 +1586,7 @@ static void CON_DrawConsole(void) charflags = (*p & 0x7f) << V_CHARCOLORSHIFT; p++; } - V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true); } } @@ -1588,6 +1607,8 @@ void CON_Drawer(void) if (con_curlines > 0) CON_DrawConsole(); - else if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE || gamestate == GS_CREDITS) + else if (gamestate == GS_LEVEL + || gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE + || gamestate == GS_CREDITS || gamestate == GS_EVALUATION) CON_DrawHudlines(); } diff --git a/src/console.h b/src/console.h index 7f448f5feacddd410734275ed42f2da720c0a503..f628080330f80a6b855af539f3e7e73efb83150e 100644 --- a/src/console.h +++ b/src/console.h @@ -13,11 +13,7 @@ #include "d_event.h" #include "command.h" -#ifdef _WII -void CON_InitWii(void); -#else void CON_Init(void); -#endif boolean CON_Responder(event_t *ev); @@ -38,11 +34,13 @@ extern UINT32 con_scalefactor; // console text scale factor extern consvar_t cons_backcolor; -extern UINT8 *yellowmap, *purplemap, *lgreenmap, *bluemap, *graymap, *redmap, *orangemap; +extern UINT8 *yellowmap, *magentamap, *lgreenmap, *bluemap, *graymap, *redmap, *orangemap, *skymap, *purplemap, *aquamap, *peridotmap, *azuremap, *brownmap, *rosymap, *invertmap; // Console bg color (auto updated to match) extern UINT8 *consolebgmap; +extern UINT8 *promptbgmap; +void CON_SetupBackColormapEx(INT32 color, boolean prompt); void CON_SetupBackColormap(void); void CON_ClearHUD(void); // clear heads up messages diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 58fa54f287a0f4023a6ec9f680718f5d4e3c0b2e..4352413e878ed96852da4ecb437bb8ba7bcead98 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -10,9 +10,7 @@ /// \file d_clisrv.c /// \brief SRB2 Network game communication and protocol, all OS independent parts. -#if !defined (UNDER_CE) #include <time.h> -#endif #ifdef __GNUC__ #include <unistd.h> //for unlink #endif @@ -51,10 +49,6 @@ #include "f_finale.h" #endif -#ifdef _XBOX -#include "sdl12/SRB2XBOX/xboxhelp.h" -#endif - // // NETWORKING // @@ -394,7 +388,7 @@ static void ExtraDataTicker(void) { if (server) { - XBOXSTATIC UINT8 buf[3]; + UINT8 buf[3]; buf[0] = (UINT8)i; buf[1] = KICK_MSG_CON_FAIL; @@ -519,7 +513,8 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->powers[j] = (UINT16)SHORT(players[i].powers[j]); // Score is resynched in the rspfirm resync packet - rsp->health = 0; // resynched with mo health + rsp->rings = SHORT(players[i].rings); + rsp->spheres = SHORT(players[i].spheres); rsp->lives = players[i].lives; rsp->continues = players[i].continues; rsp->scoreadd = players[i].scoreadd; @@ -528,8 +523,11 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->skincolor = players[i].skincolor; rsp->skin = LONG(players[i].skin); + rsp->availabilities = LONG(players[i].availabilities); // Just in case Lua does something like // modify these at runtime + rsp->camerascale = (fixed_t)LONG(players[i].camerascale); + rsp->shieldscale = (fixed_t)LONG(players[i].shieldscale); rsp->normalspeed = (fixed_t)LONG(players[i].normalspeed); rsp->runspeed = (fixed_t)LONG(players[i].runspeed); rsp->thrustfactor = players[i].thrustfactor; @@ -541,13 +539,15 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->thokitem = (UINT32)LONG(players[i].thokitem); //mobjtype_t rsp->spinitem = (UINT32)LONG(players[i].spinitem); //mobjtype_t rsp->revitem = (UINT32)LONG(players[i].revitem); //mobjtype_t + rsp->followitem = (UINT32)LONG(players[i].followitem); //mobjtype_t rsp->actionspd = (fixed_t)LONG(players[i].actionspd); rsp->mindash = (fixed_t)LONG(players[i].mindash); rsp->maxdash = (fixed_t)LONG(players[i].maxdash); rsp->jumpfactor = (fixed_t)LONG(players[i].jumpfactor); + rsp->playerheight = (fixed_t)LONG(players[i].height); + rsp->playerspinheight = (fixed_t)LONG(players[i].spinheight); rsp->speed = (fixed_t)LONG(players[i].speed); - rsp->jumping = players[i].jumping; rsp->secondjump = players[i].secondjump; rsp->fly1 = players[i].fly1; rsp->glidetime = (tic_t)LONG(players[i].glidetime); @@ -555,6 +555,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->deadtimer = players[i].deadtimer; rsp->exiting = (tic_t)LONG(players[i].exiting); rsp->homing = players[i].homing; + rsp->dashmode = (tic_t)LONG(players[i].dashmode); rsp->skidtime = (tic_t)LONG(players[i].skidtime); rsp->cmomx = (fixed_t)LONG(players[i].cmomx); rsp->cmomy = (fixed_t)LONG(players[i].cmomy); @@ -573,7 +574,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->maxlink = LONG(players[i].maxlink); rsp->dashspeed = (fixed_t)LONG(players[i].dashspeed); - rsp->dashtime = LONG(players[i].dashtime); rsp->angle_pos = (angle_t)LONG(players[i].angle_pos); rsp->old_angle_pos = (angle_t)LONG(players[i].old_angle_pos); rsp->bumpertime = (tic_t)LONG(players[i].bumpertime); @@ -602,7 +602,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->hasmo = true; rsp->health = LONG(players[i].mo->health); - rsp->angle = (angle_t)LONG(players[i].mo->angle); rsp->x = LONG(players[i].mo->x); rsp->y = LONG(players[i].mo->y); @@ -645,7 +644,8 @@ static void resynch_read_player(resynch_pak *rsp) players[i].powers[j] = (UINT16)SHORT(rsp->powers[j]); // Score is resynched in the rspfirm resync packet - players[i].health = rsp->health; + players[i].rings = SHORT(rsp->rings); + players[i].spheres = SHORT(rsp->spheres); players[i].lives = rsp->lives; players[i].continues = rsp->continues; players[i].scoreadd = rsp->scoreadd; @@ -654,8 +654,11 @@ static void resynch_read_player(resynch_pak *rsp) players[i].skincolor = rsp->skincolor; players[i].skin = LONG(rsp->skin); + players[i].availabilities = LONG(rsp->availabilities); // Just in case Lua does something like // modify these at runtime + players[i].camerascale = (fixed_t)LONG(rsp->camerascale); + players[i].shieldscale = (fixed_t)LONG(rsp->shieldscale); players[i].normalspeed = (fixed_t)LONG(rsp->normalspeed); players[i].runspeed = (fixed_t)LONG(rsp->runspeed); players[i].thrustfactor = rsp->thrustfactor; @@ -667,13 +670,15 @@ static void resynch_read_player(resynch_pak *rsp) players[i].thokitem = (UINT32)LONG(rsp->thokitem); //mobjtype_t players[i].spinitem = (UINT32)LONG(rsp->spinitem); //mobjtype_t players[i].revitem = (UINT32)LONG(rsp->revitem); //mobjtype_t + players[i].followitem = (UINT32)LONG(rsp->followitem); //mobjtype_t players[i].actionspd = (fixed_t)LONG(rsp->actionspd); players[i].mindash = (fixed_t)LONG(rsp->mindash); players[i].maxdash = (fixed_t)LONG(rsp->maxdash); players[i].jumpfactor = (fixed_t)LONG(rsp->jumpfactor); + players[i].height = (fixed_t)LONG(rsp->playerheight); + players[i].spinheight = (fixed_t)LONG(rsp->playerspinheight); players[i].speed = (fixed_t)LONG(rsp->speed); - players[i].jumping = rsp->jumping; players[i].secondjump = rsp->secondjump; players[i].fly1 = rsp->fly1; players[i].glidetime = (tic_t)LONG(rsp->glidetime); @@ -681,6 +686,7 @@ static void resynch_read_player(resynch_pak *rsp) players[i].deadtimer = rsp->deadtimer; players[i].exiting = (tic_t)LONG(rsp->exiting); players[i].homing = rsp->homing; + players[i].dashmode = (tic_t)LONG(rsp->dashmode); players[i].skidtime = (tic_t)LONG(rsp->skidtime); players[i].cmomx = (fixed_t)LONG(rsp->cmomx); players[i].cmomy = (fixed_t)LONG(rsp->cmomy); @@ -699,7 +705,6 @@ static void resynch_read_player(resynch_pak *rsp) players[i].maxlink = LONG(rsp->maxlink); players[i].dashspeed = (fixed_t)LONG(rsp->dashspeed); - players[i].dashtime = LONG(rsp->dashtime); players[i].angle_pos = (angle_t)LONG(rsp->angle_pos); players[i].old_angle_pos = (angle_t)LONG(rsp->old_angle_pos); players[i].bumpertime = (tic_t)LONG(rsp->bumpertime); @@ -761,8 +766,16 @@ static void resynch_read_player(resynch_pak *rsp) players[i].mo->scalespeed = LONG(rsp->scalespeed); // And finally, SET THE MOBJ SKIN damn it. - players[i].mo->skin = &skins[players[i].skin]; - players[i].mo->color = players[i].skincolor; + if ((players[i].powers[pw_carry] == CR_NIGHTSMODE) && (skins[players[i].skin].sprites[SPR2_NGT0].numframes == 0)) + { + players[i].mo->skin = &skins[DEFAULTNIGHTSSKIN]; + players[i].mo->color = skins[DEFAULTNIGHTSSKIN].prefcolor; // this will be corrected by thinker to super flash + } + else + { + players[i].mo->skin = &skins[players[i].skin]; + players[i].mo->color = players[i].skincolor; // this will be corrected by thinker to super flash/mario star + } P_SetThingPosition(players[i].mo); } @@ -876,6 +889,7 @@ static inline void resynch_write_others(resynchend_pak *rst) UINT8 i; rst->ingame = 0; + rst->outofcoop = 0; for (i = 0; i < MAXPLAYERS; ++i) { @@ -892,6 +906,8 @@ static inline void resynch_write_others(resynchend_pak *rst) if (!players[i].spectator) rst->ingame |= (1<<i); + if (players[i].outofcoop) + rst->outofcoop |= (1<<i); rst->ctfteam[i] = (INT32)LONG(players[i].ctfteam); rst->score[i] = (UINT32)LONG(players[i].score); rst->numboxes[i] = SHORT(players[i].numboxes); @@ -908,11 +924,13 @@ static inline void resynch_read_others(resynchend_pak *p) { UINT8 i; UINT32 loc_ingame = (UINT32)LONG(p->ingame); + UINT32 loc_outofcoop = (UINT32)LONG(p->outofcoop); for (i = 0; i < MAXPLAYERS; ++i) { // We don't care if they're in the game or not, just write all the data. players[i].spectator = !(loc_ingame & (1<<i)); + players[i].outofcoop = (loc_outofcoop & (1<<i)); players[i].ctfteam = (INT32)LONG(p->ctfteam[i]); // no, 0 does not mean spectator, at least not in Match players[i].score = (UINT32)LONG(p->score[i]); players[i].numboxes = SHORT(p->numboxes[i]); @@ -1007,7 +1025,7 @@ static void SV_SendResynch(INT32 node) if (resynch_score[node] > (unsigned)cv_resynchattempts.value*250) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)nodetoplayer[node]; buf[1] = KICK_MSG_CON_FAIL; SendNetXCmd(XD_KICK, &buf, 2); @@ -1109,7 +1127,8 @@ static inline void CL_DrawConnectionStatus(void) INT32 ccstime = I_GetTime(); // Draw background fade - V_DrawFadeScreen(); + if (!menuactive) // menu already draws its own fade + V_DrawFadeScreen(0xFF00, 16); // force default // Draw the bottom box. M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-24-8, 32, 1); @@ -1118,7 +1137,7 @@ static inline void CL_DrawConnectionStatus(void) if (cl_mode != CL_DOWNLOADFILES) { INT32 i, animtime = ((ccstime / 4) & 15) + 16; - UINT8 palstart = (cl_mode == CL_SEARCHING) ? 128 : 160; + UINT8 palstart = (cl_mode == CL_SEARCHING) ? 32 : 96; // 15 pal entries total. const char *cltext; @@ -1165,8 +1184,8 @@ static inline void CL_DrawConnectionStatus(void) dldlength = (INT32)((file->currentsize/(double)file->totalsize) * 256); if (dldlength > 256) dldlength = 256; - V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 175); - V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, dldlength, 8, 160); + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 111); + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, dldlength, 8, 96); memset(tempname, 0, sizeof(tempname)); // offset filename to just the name only part @@ -1327,7 +1346,7 @@ static void SV_SendPlayerInfo(INT32 node) netbuffer->u.playerinfo[i].skin = (UINT8)players[i].skin; // Extra data - netbuffer->u.playerinfo[i].data = players[i].skincolor; + netbuffer->u.playerinfo[i].data = 0; //players[i].skincolor; if (players[i].pflags & PF_TAGIT) netbuffer->u.playerinfo[i].data |= 0x20; @@ -1371,6 +1390,7 @@ static boolean SV_SendServerConfig(INT32 node) // which is nice and easy for us to detect memset(netbuffer->u.servercfg.playerskins, 0xFF, sizeof(netbuffer->u.servercfg.playerskins)); memset(netbuffer->u.servercfg.playercolor, 0xFF, sizeof(netbuffer->u.servercfg.playercolor)); + memset(netbuffer->u.servercfg.playeravailabilities, 0xFF, sizeof(netbuffer->u.servercfg.playeravailabilities)); memset(netbuffer->u.servercfg.adminplayers, -1, sizeof(netbuffer->u.servercfg.adminplayers)); @@ -1382,6 +1402,7 @@ static boolean SV_SendServerConfig(INT32 node) continue; netbuffer->u.servercfg.playerskins[i] = (UINT8)players[i].skin; netbuffer->u.servercfg.playercolor[i] = (UINT8)players[i].skincolor; + netbuffer->u.servercfg.playeravailabilities[i] = (UINT32)LONG(players[i].availabilities); } memcpy(netbuffer->u.servercfg.server_context, server_context, 8); @@ -1499,7 +1520,7 @@ static void SV_SavedGame(void) { size_t length; UINT8 *savebuffer; - XBOXSTATIC char tmpsave[256]; + char tmpsave[256]; if (!cv_dumpconsistency.value) return; @@ -1541,7 +1562,7 @@ static void CL_LoadReceivedSavegame(void) { UINT8 *savebuffer = NULL; size_t length, decompressedlen; - XBOXSTATIC char tmpsave[256]; + char tmpsave[256]; sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home); @@ -1982,6 +2003,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic #ifdef CLIENT_LOADINGSCREEN if (client && cl_mode != CL_CONNECTED && cl_mode != CL_ABORTED) { + F_MenuPresTicker(true); // title sky F_TitleScreenTicker(true); F_TitleScreenDrawer(); CL_DrawConnectionStatus(); @@ -2014,7 +2036,7 @@ static void CL_ConnectToServer(boolean viams) tic_t asksent; #endif #ifdef JOININGAME - XBOXSTATIC char tmpsave[256]; + char tmpsave[256]; sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home); #endif @@ -2259,7 +2281,8 @@ static void Command_connect(void) CONS_Printf(M_GetText( "Connect <serveraddress> (port): connect to a server\n" "Connect ANY: connect to the first lan server found\n" - "Connect SELF: connect to your own server.\n")); + //"Connect SELF: connect to your own server.\n" + )); return; } @@ -2273,7 +2296,7 @@ static void Command_connect(void) // we don't request a restart unless the filelist differs server = false; - +/* if (!stricmp(COM_Argv(1), "self")) { servernode = 0; @@ -2282,6 +2305,7 @@ static void Command_connect(void) //SV_SpawnServer(); } else +*/ { // used in menu to connect to a server in the list if (netgame && !stricmp(COM_Argv(1), "node")) @@ -2305,10 +2329,13 @@ static void Command_connect(void) if (!stricmp(COM_Argv(1), "any")) servernode = BROADCASTADDR; - else if (I_NetMakeNodewPort && COM_Argc() >= 3) - servernode = I_NetMakeNodewPort(COM_Argv(1), COM_Argv(2)); else if (I_NetMakeNodewPort) - servernode = I_NetMakeNode(COM_Argv(1)); + { + if (COM_Argc() >= 3) // address AND port + servernode = I_NetMakeNodewPort(COM_Argv(1), COM_Argv(2)); + else // address only, or address:port + servernode = I_NetMakeNode(COM_Argv(1)); + } else { CONS_Alert(CONS_ERROR, M_GetText("There is no server identification with this network driver\n")); @@ -2338,12 +2365,7 @@ static void ResetNode(INT32 node); void CL_ClearPlayer(INT32 playernum) { if (players[playernum].mo) - { - // Don't leave a NiGHTS ghost! - if ((players[playernum].pflags & PF_NIGHTSMODE) && players[playernum].mo->tracer) - P_RemoveMobj(players[playernum].mo->tracer); P_RemoveMobj(players[playernum].mo); - } memset(&players[playernum], 0, sizeof (player_t)); } @@ -2377,11 +2399,11 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason) if (gametype == GT_CTF) P_PlayerFlagBurst(&players[playernum], false); // Don't take the flag with you! - // If in a special stage, redistribute the player's rings across + // If in a special stage, redistribute the player's spheres across // the remaining players. if (G_IsSpecialStage(gamemap)) { - INT32 i, count, increment, rings; + INT32 i, count, increment, spheres; for (i = 0, count = 0; i < MAXPLAYERS; i++) { @@ -2390,19 +2412,19 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason) } count--; - rings = players[playernum].health - 1; - increment = rings/count; + spheres = players[playernum].spheres; + increment = spheres/count; for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i] && i != playernum) { - if (rings < increment) - P_GivePlayerRings(&players[i], rings); + if (spheres < increment) + P_GivePlayerSpheres(&players[i], spheres); else - P_GivePlayerRings(&players[i], increment); + P_GivePlayerSpheres(&players[i], increment); - rings -= increment; + spheres -= increment; } } } @@ -2573,7 +2595,7 @@ static void Command_Ban(void) if (server || IsPlayerAdmin(consoleplayer)) { - XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH]; + UINT8 buf[3 + MAX_REASONLENGTH]; UINT8 *p = buf; const SINT8 pn = nametonum(COM_Argv(1)); const INT32 node = playernode[(INT32)pn]; @@ -2678,7 +2700,7 @@ static void Command_Kick(void) if (server || IsPlayerAdmin(consoleplayer)) { - XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH]; + UINT8 buf[3 + MAX_REASONLENGTH]; UINT8 *p = buf; const SINT8 pn = nametonum(COM_Argv(1)); @@ -2730,7 +2752,7 @@ static void Command_Kick(void) static void Got_KickCmd(UINT8 **p, INT32 playernum) { INT32 pnum, msg; - XBOXSTATIC char buf[3 + MAX_REASONLENGTH]; + char buf[3 + MAX_REASONLENGTH]; char *reason = buf; kickreason_t kickreason = KR_KICK; @@ -3132,7 +3154,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) CONS_Alert(CONS_WARNING, M_GetText("Illegal add player command received from %s\n"), player_names[playernum]); if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -3200,7 +3222,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) static boolean SV_AddWaitingPlayers(void) { INT32 node, n, newplayer = false; - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; UINT8 newplayernum = 0; // What is the reason for this? Why can't newplayernum always be 0? @@ -3313,7 +3335,7 @@ void CL_AddSplitscreenPlayer(void) void CL_RemoveSplitscreenPlayer(void) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; if (cl_mode != CL_CONNECTED) return; @@ -3678,10 +3700,12 @@ static void HandlePacketFromAwayNode(SINT8 node) for (j = 0; j < MAXPLAYERS; j++) { if (netbuffer->u.servercfg.playerskins[j] == 0xFF - && netbuffer->u.servercfg.playercolor[j] == 0xFF) + && netbuffer->u.servercfg.playercolor[j] == 0xFF + && netbuffer->u.servercfg.playeravailabilities[j] == 0xFFFFFFFF) continue; // not in game playeringame[j] = true; + players[j].availabilities = (UINT32)LONG(netbuffer->u.servercfg.playeravailabilities[j]); SetPlayerSkinByNum(j, (INT32)netbuffer->u.servercfg.playerskins[j]); players[j].skincolor = netbuffer->u.servercfg.playercolor[j]; } @@ -3756,11 +3780,10 @@ static void HandlePacketFromAwayNode(SINT8 node) * */ static void HandlePacketFromPlayer(SINT8 node) -{FILESTAMP - XBOXSTATIC INT32 netconsole; - XBOXSTATIC tic_t realend, realstart; - XBOXSTATIC UINT8 *pak, *txtpak, numtxtpak; -FILESTAMP +{ + INT32 netconsole; + tic_t realend, realstart; + UINT8 *pak, *txtpak, numtxtpak; txtpak = NULL; @@ -3834,7 +3857,7 @@ FILESTAMP if (netcmds[maketic%BACKUPTICS][netconsole].forwardmove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][netconsole].forwardmove < -MAXPLMOVE || netcmds[maketic%BACKUPTICS][netconsole].sidemove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][netconsole].sidemove < -MAXPLMOVE) { - XBOXSTATIC char buf[2]; + char buf[2]; CONS_Alert(CONS_WARNING, M_GetText("Illegal movement value received from node %d\n"), netconsole); //D_Clearticcmd(k); @@ -3877,7 +3900,7 @@ FILESTAMP } else { - XBOXSTATIC UINT8 buf[3]; + UINT8 buf[3]; buf[0] = (UINT8)netconsole; buf[1] = KICK_MSG_CON_FAIL; @@ -3968,7 +3991,7 @@ FILESTAMP nodewaiting[node] = 0; if (netconsole != -1 && playeringame[netconsole]) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)netconsole; if (netbuffer->packettype == PT_NODETIMEOUT) buf[1] = KICK_MSG_TIMEOUT; @@ -3996,7 +4019,7 @@ FILESTAMP if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)node; buf[1] = KICK_MSG_CON_FAIL; SendNetXCmd(XD_KICK, &buf, 2); @@ -4021,7 +4044,7 @@ FILESTAMP if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)node; buf[1] = KICK_MSG_CON_FAIL; SendNetXCmd(XD_KICK, &buf, 2); @@ -4088,7 +4111,7 @@ FILESTAMP if (server) { - XBOXSTATIC char buf[2]; + char buf[2]; buf[0] = (char)node; buf[1] = KICK_MSG_CON_FAIL; SendNetXCmd(XD_KICK, &buf, 2); @@ -4108,7 +4131,7 @@ FILESTAMP if (server) { - XBOXSTATIC char buf[2]; + char buf[2]; buf[0] = (char)node; buf[1] = KICK_MSG_CON_FAIL; SendNetXCmd(XD_KICK, &buf, 2); @@ -4138,7 +4161,7 @@ FILESTAMP if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)node; buf[1] = KICK_MSG_CON_FAIL; SendNetXCmd(XD_KICK, &buf, 2); @@ -4161,9 +4184,8 @@ FILESTAMP * */ static void GetPackets(void) -{FILESTAMP - XBOXSTATIC SINT8 node; // The packet sender -FILESTAMP +{ + SINT8 node; // The packet sender player_joining = false; @@ -4683,7 +4705,7 @@ static inline void PingUpdate(void) { if (playeringame[i] && laggers[i]) { - XBOXSTATIC char buf[2]; + char buf[2]; buf[0] = (char)i; buf[1] = KICK_MSG_PING_HIGH; @@ -4755,9 +4777,9 @@ void NetUpdate(void) if (server) CL_SendClientCmd(); // send it -FILESTAMP + GetPackets(); // get packet from client or from server -FILESTAMP + // client send the command after a receive of the server // the server send before because in single player is beter diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 8443b3fc0e72ca6600daca61244d484e355fe9cf..4ed7ff95725d9af2c8afe07bf53a25171869bafd 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -136,6 +136,7 @@ typedef struct fixed_t flagz[2]; UINT32 ingame; // Spectator bit for each player + UINT32 outofcoop; // outofcoop bit for each player INT32 ctfteam[MAXPLAYERS]; // Which team? (can't be 1 bit, since in regular Match there are no teams) // Resynch game scores and the like all at once @@ -163,7 +164,8 @@ typedef struct UINT16 powers[NUMPOWERS]; // Score is resynched in the confirm resync packet - INT32 health; + INT16 rings; + INT16 spheres; SINT8 lives; SINT8 continues; UINT8 scoreadd; @@ -172,8 +174,11 @@ typedef struct UINT8 skincolor; INT32 skin; + UINT32 availabilities; // Just in case Lua does something like // modify these at runtime + fixed_t camerascale; + fixed_t shieldscale; fixed_t normalspeed; fixed_t runspeed; UINT8 thrustfactor; @@ -185,13 +190,15 @@ typedef struct UINT32 thokitem; // mobjtype_t UINT32 spinitem; // mobjtype_t UINT32 revitem; // mobjtype_t + UINT32 followitem; // mobjtype_t fixed_t actionspd; fixed_t mindash; fixed_t maxdash; fixed_t jumpfactor; + fixed_t playerheight; + fixed_t playerspinheight; fixed_t speed; - UINT8 jumping; UINT8 secondjump; UINT8 fly1; tic_t glidetime; @@ -199,6 +206,7 @@ typedef struct INT32 deadtimer; tic_t exiting; UINT8 homing; + tic_t dashmode; tic_t skidtime; fixed_t cmomx; fixed_t cmomy; @@ -217,7 +225,6 @@ typedef struct INT32 maxlink; fixed_t dashspeed; - INT32 dashtime; angle_t angle_pos; angle_t old_angle_pos; tic_t bumpertime; @@ -240,6 +247,7 @@ typedef struct //player->mo stuff UINT8 hasmo; // Boolean + INT32 health; angle_t angle; fixed_t x; fixed_t y; @@ -279,6 +287,7 @@ typedef struct // 0xFF == not in game; else player skin num UINT8 playerskins[MAXPLAYERS]; UINT8 playercolor[MAXPLAYERS]; + UINT32 playeravailabilities[MAXPLAYERS]; UINT8 gametype; UINT8 modifiedgame; diff --git a/src/d_main.c b/src/d_main.c index 23817750ca4dcfb6685d540e607b2bb02f36adb9..527eecd20fd0b60f78126214a3a799b7e05e6c6b 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -30,16 +30,12 @@ int snprintf(char *str, size_t n, const char *fmt, ...); //int vsnprintf(char *str, size_t n, const char *fmt, va_list ap); #endif -#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) +#ifdef _WIN32 #include <direct.h> #include <malloc.h> #endif -#if !defined (UNDER_CE) #include <time.h> -#elif defined (_XBOX) -#define NO_TIME -#endif #include "doomdef.h" #include "am_map.h" @@ -75,6 +71,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #include "fastcmp.h" #include "keys.h" #include "filesrch.h" // refreshdirmenu, mainwadstally +#include "g_input.h" // tutorial mode control scheming #ifdef CMAKECONFIG #include "config.h" @@ -82,10 +79,6 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #include "config.h.in" #endif -#ifdef _XBOX -#include "sdl12/SRB2XBOX/xboxhelp.h" -#endif - #ifdef HWRENDER #include "hardware/hw_main.h" // 3D View Rendering #endif @@ -108,8 +101,6 @@ UINT8 window_notinfocus = false; // // DEMO LOOP // -//static INT32 demosequence; -static const char *pagename = "MAP1PIC"; static char *startupwadfiles[MAX_WADFILES]; boolean devparm = false; // started game with -devparm @@ -125,27 +116,17 @@ INT32 postimgparam2; // These variables are only true if // whether the respective sound system is disabled // or they're init'ed, but the player just toggled them -#ifdef _XBOX -boolean midi_disabled = true, sound_disabled = true; -boolean digital_disabled = true; -#else boolean midi_disabled = false; boolean sound_disabled = false; boolean digital_disabled = false; -#endif boolean advancedemo; #ifdef DEBUGFILE INT32 debugload = 0; #endif -#ifdef _arch_dreamcast -char srb2home[256] = "/cd"; -char srb2path[256] = "/cd"; -#else char srb2home[256] = "."; char srb2path[256] = "."; -#endif boolean usehome = true; const char *pandf = "%s" PATHSEP "%s"; @@ -224,6 +205,9 @@ void D_ProcessEvents(void) // wipegamestate can be set to -1 to force a wipe on the next draw // added comment : there is a wipe eatch change of the gamestate gamestate_t wipegamestate = GS_LEVEL; +// -1: Default; 0-n: Wipe index; INT16_MAX: do not wipe +INT16 wipetypepre = -1; +INT16 wipetypepost = -1; static void D_Display(void) { @@ -257,7 +241,7 @@ static void D_Display(void) // save the current screen if about to wipe wipe = (gamestate != wipegamestate); - if (wipe) + if (wipe && wipetypepre != INT16_MAX) { // set for all later wipedefindex = gamestate; // wipe_xxx_toblack @@ -269,25 +253,41 @@ static void D_Display(void) wipedefindex = wipe_multinter_toblack; } + if (wipetypepre < 0 || !F_WipeExists(wipetypepre)) + wipetypepre = wipedefs[wipedefindex]; + if (rendermode != render_none) { // Fade to black first - if (gamestate != GS_LEVEL // fades to black on its own timing, always - && wipedefs[wipedefindex] != UINT8_MAX) + if ((wipegamestate == (gamestate_t)FORCEWIPE || + (wipegamestate != (gamestate_t)FORCEWIPEOFF + && !(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))) + ) // fades to black on its own timing, always + && wipetypepre != UINT8_MAX) { F_WipeStartScreen(); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); F_WipeEndScreen(); - F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK); + F_RunWipe(wipetypepre, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN); } F_WipeStartScreen(); } + + wipetypepre = -1; } + else + wipetypepre = -1; // do buffered drawing switch (gamestate) { + case GS_TITLESCREEN: + if (!titlemapinaction || !curbghide) { + F_TitleScreenDrawer(); + break; + } + // Intentional fall-through case GS_LEVEL: if (!gametic) break; @@ -322,6 +322,7 @@ static void D_Display(void) case GS_EVALUATION: F_GameEvaluationDrawer(); + HU_Erase(); HU_Drawer(); break; @@ -335,10 +336,6 @@ static void D_Display(void) HU_Drawer(); break; - case GS_TITLESCREEN: - F_TitleScreenDrawer(); - break; - case GS_WAITINGPLAYERS: // The clientconnect drawer is independent... case GS_DEDICATEDSERVER: @@ -346,80 +343,96 @@ static void D_Display(void) break; } - if (gamestate == GS_LEVEL) + // STUPID race condition... + if (wipegamestate == GS_INTRO && gamestate == GS_TITLESCREEN) + wipegamestate = FORCEWIPEOFF; + else { - // draw the view directly - if (cv_renderview.value && !automapactive) + wipegamestate = gamestate; + + // clean up border stuff + // see if the border needs to be initially drawn + if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide)) { - if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) - { - topleft = screens[0] + viewwindowy*vid.width + viewwindowx; - objectsdrawn = 0; -#ifdef HWRENDER - if (rendermode != render_soft) - HWR_RenderPlayerView(0, &players[displayplayer]); - else -#endif - if (rendermode != render_none) - R_RenderPlayerView(&players[displayplayer]); - } + // draw the view directly - // render the second screen - if (splitscreen && players[secondarydisplayplayer].mo) + if (!automapactive && !dedicated && cv_renderview.value) { -#ifdef HWRENDER - if (rendermode != render_soft) - HWR_RenderPlayerView(1, &players[secondarydisplayplayer]); - else -#endif - if (rendermode != render_none) + if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) { - viewwindowy = vid.height / 2; - M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0])); - topleft = screens[0] + viewwindowy*vid.width + viewwindowx; + objectsdrawn = 0; + #ifdef HWRENDER + if (rendermode != render_soft) + HWR_RenderPlayerView(0, &players[displayplayer]); + else + #endif + if (rendermode != render_none) + R_RenderPlayerView(&players[displayplayer]); + } - R_RenderPlayerView(&players[secondarydisplayplayer]); + // render the second screen + if (splitscreen && players[secondarydisplayplayer].mo) + { + #ifdef HWRENDER + if (rendermode != render_soft) + HWR_RenderPlayerView(1, &players[secondarydisplayplayer]); + else + #endif + if (rendermode != render_none) + { + viewwindowy = vid.height / 2; + M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0])); + + topleft = screens[0] + viewwindowy*vid.width + viewwindowx; + + R_RenderPlayerView(&players[secondarydisplayplayer]); + + viewwindowy = 0; + M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0])); + } + } - viewwindowy = 0; - M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0])); + // Image postprocessing effect + if (rendermode == render_soft) + { + if (postimgtype) + V_DoPostProcessor(0, postimgtype, postimgparam); + if (postimgtype2) + V_DoPostProcessor(1, postimgtype2, postimgparam2); } } - // Image postprocessing effect - if (rendermode == render_soft) + if (lastdraw) { - if (postimgtype) - V_DoPostProcessor(0, postimgtype, postimgparam); - if (postimgtype2) - V_DoPostProcessor(1, postimgtype2, postimgparam2); + if (rendermode == render_soft) + { + VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); + usebuffer = true; + } + lastdraw = false; } - } - if (lastdraw) - { - if (rendermode == render_soft) + if (gamestate == GS_LEVEL) { - VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); - usebuffer = true; + ST_Drawer(); + F_TextPromptDrawer(); + HU_Drawer(); } - lastdraw = false; + else + F_TitleScreenDrawer(); } - - ST_Drawer(); - HU_Drawer(); } // change gamma if needed // (GS_LEVEL handles this already due to level-specific palettes) - if (forcerefresh && gamestate != GS_LEVEL) + if (forcerefresh && !(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))) V_SetPalette(0); - wipegamestate = gamestate; - // draw pause pic if (paused && cv_showhud.value && (!menuactive || netgame)) { +#if 0 INT32 py; patch_t *patch; if (automapactive) @@ -428,6 +441,11 @@ static void D_Display(void) py = viewwindowy + 4; patch = W_CachePatchName("M_PAUSE", PU_CACHE); V_DrawScaledPatch(viewwindowx + (BASEVIDWIDTH - SHORT(patch->width))/2, py, 0, patch); +#else + INT32 y = ((automapactive) ? (32) : (BASEVIDHEIGHT/2)); + M_DrawTextBox((BASEVIDWIDTH/2) - (60), y - (16), 13, 2); + V_DrawCenteredString(BASEVIDWIDTH/2, y - (4), V_YELLOWMAP, "Game Paused"); +#endif } // vid size change is now finished if it was on... @@ -443,16 +461,19 @@ static void D_Display(void) // // wipe update // - if (wipe) + if (wipe && wipetypepost != INT16_MAX) { // note: moved up here because NetUpdate does input changes // and input during wipe tends to mess things up wipedefindex += WIPEFINALSHIFT; + if (wipetypepost < 0 || !F_WipeExists(wipetypepost)) + wipetypepost = wipedefs[wipedefindex]; + if (rendermode != render_none) { F_WipeEndScreen(); - F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK); + F_RunWipe(wipetypepost, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN); } // reset counters so timedemo doesn't count the wipe duration @@ -461,7 +482,11 @@ static void D_Display(void) framecount = 0; demostarttime = I_GetTime(); } + + wipetypepost = -1; } + else + wipetypepost = -1; NetUpdate(); // send out any new accumulation @@ -651,6 +676,9 @@ void D_AdvanceDemo(void) void D_StartTitle(void) { INT32 i; + + S_StopMusic(); + if (netgame) { if (gametype == GT_COOP) @@ -686,6 +714,7 @@ void D_StartTitle(void) botskin = 0; cv_debug = 0; emeralds = 0; + lastmaploaded = 0; // In case someone exits out at the same time they start a time attack run, // reset modeattacking @@ -694,17 +723,40 @@ void D_StartTitle(void) // empty maptol so mario/etc sounds don't play in sound test when they shouldn't maptol = 0; + // reset to default player stuff + COM_BufAddText (va("%s \"%s\"\n",cv_playername.name,cv_defaultplayername.string)); + COM_BufAddText (va("%s \"%s\"\n",cv_skin.name,cv_defaultskin.string)); + COM_BufAddText (va("%s \"%s\"\n",cv_playercolor.name,cv_defaultplayercolor.string)); + COM_BufAddText (va("%s \"%s\"\n",cv_playername2.name,cv_defaultplayername2.string)); + COM_BufAddText (va("%s \"%s\"\n",cv_skin2.name,cv_defaultskin2.string)); + COM_BufAddText (va("%s \"%s\"\n",cv_playercolor2.name,cv_defaultplayercolor2.string)); + gameaction = ga_nothing; displayplayer = consoleplayer = 0; - //demosequence = -1; gametype = GT_COOP; paused = false; advancedemo = false; + F_InitMenuPresValues(); F_StartTitleScreen(); + currentMenu = &MainDef; // reset the current menu ID + // Reset the palette if (rendermode != render_none) V_SetPaletteLump("PLAYPAL"); + + // The title screen is obviously not a tutorial! (Unless I'm mistaken) + if (tutorialmode && tutorialgcs) + { + G_CopyControls(gamecontrol, gamecontroldefault[gcs_custom], gcl_tutorial_full, num_gcl_tutorial_full); // using gcs_custom as temp storage + CV_SetValue(&cv_usemouse, tutorialusemouse); + CV_SetValue(&cv_alwaysfreelook, tutorialfreelook); + CV_SetValue(&cv_mousemove, tutorialmousemove); + CV_SetValue(&cv_analog, tutorialanalog); + M_StartMessage("Do you want to \x82save the recommended \x82movement controls?\x80\n\nPress 'Y' or 'Enter' to confirm\nPress 'N' or any key to keep \nyour current controls", + M_TutorialSaveControlResponse, MM_YESNO); + } + tutorialmode = false; } // @@ -744,11 +796,11 @@ static inline void D_CleanFile(void) static void IdentifyVersion(void) { - char *srb2wad1, *srb2wad2; + char *srb2wad; const char *srb2waddir = NULL; #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) - // change to the directory where 'srb2.srb' is found + // change to the directory where 'srb2.pk3' is found srb2waddir = I_LocateWad(); #endif @@ -759,17 +811,11 @@ static void IdentifyVersion(void) } else { -#if !defined(_WIN32_WCE) && !defined(_PS3) if (getcwd(srb2path, 256) != NULL) srb2waddir = srb2path; else -#endif { -#ifdef _arch_dreamcast - srb2waddir = "/cd"; -#else srb2waddir = "."; -#endif } } @@ -779,31 +825,24 @@ static void IdentifyVersion(void) srb2waddir = I_GetWadDir(); #endif // Commercial. - srb2wad1 = malloc(strlen(srb2waddir)+1+8+1); - srb2wad2 = malloc(strlen(srb2waddir)+1+8+1); - if (srb2wad1 == NULL && srb2wad2 == NULL) + srb2wad = malloc(strlen(srb2waddir)+1+8+1); + if (srb2wad == NULL) I_Error("No more free memory to look in %s", srb2waddir); - if (srb2wad1 != NULL) - sprintf(srb2wad1, pandf, srb2waddir, "srb2.srb"); - if (srb2wad2 != NULL) - sprintf(srb2wad2, pandf, srb2waddir, "srb2.wad"); + else + sprintf(srb2wad, pandf, srb2waddir, "srb2.pk3"); // will be overwritten in case of -cdrom or unix/win home snprintf(configfile, sizeof configfile, "%s" PATHSEP CONFIGFILENAME, srb2waddir); configfile[sizeof configfile - 1] = '\0'; // Load the IWAD - if (srb2wad2 != NULL && FIL_ReadFileOK(srb2wad2)) - D_AddFile(srb2wad2); - else if (srb2wad1 != NULL && FIL_ReadFileOK(srb2wad1)) - D_AddFile(srb2wad1); + if (srb2wad != NULL && FIL_ReadFileOK(srb2wad)) + D_AddFile(srb2wad); else - I_Error("SRB2.SRB/SRB2.WAD not found! Expected in %s, ss files: %s or %s\n", srb2waddir, srb2wad1, srb2wad2); + I_Error("srb2.pk3 not found! Expected in %s, ss file: %s\n", srb2waddir, srb2wad); - if (srb2wad1) - free(srb2wad1); - if (srb2wad2) - free(srb2wad2); + if (srb2wad) + free(srb2wad); // if you change the ordering of this or add/remove a file, be sure to update the md5 // checking in D_SRB2Main @@ -814,12 +853,9 @@ static void IdentifyVersion(void) // Add the players D_AddFile(va(pandf,srb2waddir, "player.dta")); - // Add the weapons - D_AddFile(va(pandf,srb2waddir,"rings.dta")); - #ifdef USE_PATCH_DTA // Add our crappy patches to fix our bugs - D_AddFile(va(pandf,srb2waddir,"patch.dta")); + D_AddFile(va(pandf,srb2waddir,"patch.pk3")); #endif #if !defined (HAVE_SDL) || defined (HAVE_MIXER) @@ -834,36 +870,18 @@ static void IdentifyVersion(void) I_Error("File "str" has been modified with non-music/sound lumps"); \ } -#if defined (DC) && 0 - MUSICTEST("music_dc.dta") -#else MUSICTEST("music.dta") +#ifdef DEVELOP // remove when music_new.dta is merged into music.dta + MUSICTEST("music_new.dta") #endif } #endif } +#ifdef PC_DOS /* ======================================================================== */ -// Just print the nice red titlebar like the original SRB2 for DOS. +// Code for printing SRB2's title bar in DOS /* ======================================================================== */ -#ifdef PC_DOS -static inline void D_Titlebar(char *title1, char *title2) -{ - // SRB2 banner - clrscr(); - textattr((BLUE<<4)+WHITE); - clreol(); - cputs(title1); - - // standard srb2 banner - textattr((RED<<4)+WHITE); - clreol(); - gotoxy((80-strlen(title2))/2, 2); - cputs(title2); - normvideo(); - gotoxy(1,3); -} -#endif // // Center the title string, then add the date and time of compilation. @@ -892,6 +910,31 @@ static inline void D_MakeTitleString(char *s) strcpy(s, temp); } +static inline void D_Titlebar(void) +{ + char title1[82]; // srb2 title banner + char title2[82]; + + strcpy(title1, "Sonic Robo Blast 2"); + strcpy(title2, "Sonic Robo Blast 2"); + + D_MakeTitleString(title1); + + // SRB2 banner + clrscr(); + textattr((BLUE<<4)+WHITE); + clreol(); + cputs(title1); + + // standard srb2 banner + textattr((RED<<4)+WHITE); + clreol(); + gotoxy((80-strlen(title2))/2, 2); + cputs(title2); + normvideo(); + gotoxy(1,3); +} +#endif // // D_SRB2Main @@ -899,8 +942,6 @@ static inline void D_MakeTitleString(char *s) void D_SRB2Main(void) { INT32 p; - char srb2[82]; // srb2 title banner - char title[82]; INT32 pstartmap = 1; boolean autostart = false; @@ -920,7 +961,7 @@ void D_SRB2Main(void) "in this program.\n\n"); // keep error messages until the final flush(stderr) -#if !defined (PC_DOS) && !defined (_WIN32_WCE) && !defined(NOTERMIOS) +#if !defined (PC_DOS) && !defined(NOTERMIOS) if (setvbuf(stderr, NULL, _IOFBF, 1000)) I_OutputMsg("setvbuf didnt work\n"); #endif @@ -942,11 +983,11 @@ void D_SRB2Main(void) // identify the main IWAD file to use IdentifyVersion(); -#if !defined (_WIN32_WCE) && !defined(NOTERMIOS) +#if !defined(NOTERMIOS) setbuf(stdout, NULL); // non-buffered output #endif -#if defined (_WIN32_WCE) //|| defined (_DEBUG) || defined (GP2X) +#if 0 //defined (_DEBUG) devparm = M_CheckParm("-nodebug") == 0; #else devparm = M_CheckParm("-debug") != 0; @@ -957,20 +998,8 @@ void D_SRB2Main(void) dedicated = M_CheckParm("-dedicated") != 0; #endif - strcpy(title, "Sonic Robo Blast 2"); - strcpy(srb2, "Sonic Robo Blast 2"); - D_MakeTitleString(srb2); - #ifdef PC_DOS - D_Titlebar(srb2, title); -#endif - -#if defined (__OS2__) && !defined (HAVE_SDL) - // set PM window title - snprintf(pmData->title, sizeof (pmData->title), - "Sonic Robo Blast 2" VERSIONSTRING ": %s", - title); - pmData->title[sizeof (pmData->title) - 1] = '\0'; + D_Titlebar(); #endif if (devparm) @@ -984,13 +1013,8 @@ void D_SRB2Main(void) if (!userhome) { -#if ((defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON)) && !defined (__CYGWIN__) && !defined (DC) && !defined (PSP) && !defined(GP2X) +#if ((defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON)) && !defined (__CYGWIN__) I_Error("Please set $HOME to your home directory\n"); -#elif defined (_WIN32_WCE) && 0 - if (dedicated) - snprintf(configfile, sizeof configfile, "/Storage Card/SRB2DEMO/d"CONFIGFILENAME); - else - snprintf(configfile, sizeof configfile, "/Storage Card/SRB2DEMO/"CONFIGFILENAME); #else if (dedicated) snprintf(configfile, sizeof configfile, "d"CONFIGFILENAME); @@ -1027,10 +1051,6 @@ void D_SRB2Main(void) } configfile[sizeof configfile - 1] = '\0'; - -#ifdef _arch_dreamcast - strcpy(downloaddir, "/ram"); // the dreamcast's TMP -#endif } // rand() needs seeded regardless of password @@ -1092,6 +1112,13 @@ void D_SRB2Main(void) // adapt tables to SRB2's needs, including extra slots for dehacked file support P_PatchInfoTables(); + // initiate menu metadata before SOCcing them + M_InitMenuPresTables(); + + // init title screen display params + if (M_CheckParm("-connect")) + F_InitMenuPresValues(); + //---------------------------------------------------- READY TIME // we need to check for dedicated before initialization of some subsystems @@ -1101,54 +1128,52 @@ void D_SRB2Main(void) // Make backups of some SOCcable tables. P_BackupTables(); - // Setup default unlockable conditions - M_SetupDefaultConditionSets(); - // Setup character tables // Have to be done here before files are loaded M_InitCharacterTables(); - // load wad, including the main wad file - CONS_Printf("W_InitMultipleFiles(): Adding IWAD and main PWADs.\n"); - if (!W_InitMultipleFiles(startupwadfiles)) -#ifdef _DEBUG - CONS_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n"); -#else - I_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n"); -#endif - D_CleanFile(); - mainwads = 0; #ifndef DEVELOP // md5s last updated 12/14/14 // Check MD5s of autoloaded files - W_VerifyFileMD5(mainwads++, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad + W_VerifyFileMD5(mainwads++, ASSET_HASH_SRB2_PK3); // srb2.pk3 W_VerifyFileMD5(mainwads++, ASSET_HASH_ZONES_DTA); // zones.dta W_VerifyFileMD5(mainwads++, ASSET_HASH_PLAYER_DTA); // player.dta - W_VerifyFileMD5(mainwads++, ASSET_HASH_RINGS_DTA); // rings.dta #ifdef USE_PATCH_DTA W_VerifyFileMD5(mainwads++, ASSET_HASH_PATCH_DTA); // patch.dta #endif // don't check music.dta because people like to modify it, and it doesn't matter if they do // ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for. //mainwads++; // music.dta does not increment mainwads (see <= 2.1.21) - + //mainwads++; // neither does music_new.dta #else - mainwads++; // srb2.srb/srb2.wad + mainwads++; // srb2.pk3 mainwads++; // zones.dta mainwads++; // player.dta - mainwads++; // rings.dta #ifdef USE_PATCH_DTA mainwads++; // patch.dta #endif //mainwads++; // music.dta does not increment mainwads (see <= 2.1.21) + //mainwads++; // neither does music_new.dta + + // load wad, including the main wad file + CONS_Printf("W_InitMultipleFiles(): Adding IWAD and main PWADs.\n"); + if (!W_InitMultipleFiles(startupwadfiles, mainwads)) +#ifdef _DEBUG + CONS_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n"); +#else + I_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n"); +#endif + D_CleanFile(); #endif //ifndef DEVELOP mainwadstally = packetsizetally; + mainwadstally = packetsizetally; + cht_Init(); //---------------------------------------------------- READY SCREEN @@ -1166,12 +1191,7 @@ void D_SRB2Main(void) HU_Init(); COM_Init(); - // libogc has a CON_Init function, we must rename SRB2's CON_Init in WII/libogc -#ifndef _WII CON_Init(); -#else - CON_InitWii(); -#endif D_RegisterServerCommands(); D_RegisterClientCommands(); // be sure that this is called before D_CheckNetGame @@ -1319,6 +1339,19 @@ void D_SRB2Main(void) ultimatemode = true; } + // rei/miru: bootmap (Idea: starts the game on a predefined map) + if (bootmap && !(M_CheckParm("-warp") && M_IsNextParm())) + { + pstartmap = bootmap; + + if (pstartmap < 1 || pstartmap > NUMMAPS) + I_Error("Cannot warp to map %d (out of range)\n", pstartmap); + else + { + autostart = true; + } + } + if (autostart || netgame) { gameaction = ga_nothing; @@ -1365,11 +1398,14 @@ void D_SRB2Main(void) else if (!dedicated && M_MapLocked(pstartmap)) I_Error("You need to unlock this level before you can warp to it!\n"); else + { D_MapChange(pstartmap, gametype, ultimatemode, true, 0, false, false); + } } } else if (M_CheckParm("-skipintro")) { + F_InitMenuPresValues(); F_StartTitleScreen(); } else @@ -1379,7 +1415,6 @@ void D_SRB2Main(void) if (dedicated && server) { - pagename = "TITLESKY"; levelstarttic = gametic; G_SetGamestate(GS_LEVEL); if (!P_SetupLevel(false)) @@ -1394,26 +1429,19 @@ const char *D_Home(void) #ifdef ANDROID return "/data/data/org.srb2/"; #endif -#ifdef _arch_dreamcast - char VMUHOME[] = "HOME=/vmu/a1"; - putenv(VMUHOME); //don't use I_PutEnv -#endif if (M_CheckParm("-home") && M_IsNextParm()) userhome = M_GetNextParm(); else { -#if defined (GP2X) - usehome = false; //let use the CWD - return NULL; -#elif !((defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON)) && !defined (__APPLE__) && !defined(_WIN32_WCE) +#if !((defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON)) && !defined (__APPLE__) if (FIL_FileOK(CONFIGFILENAME)) usehome = false; // Let's NOT use home else #endif userhome = I_GetEnv("HOME"); //Alam: my new HOME for srb2 } -#if defined (_WIN32) && !defined(_WIN32_WCE) //Alam: only Win32 have APPDATA and USERPROFILE +#ifdef _WIN32 //Alam: only Win32 have APPDATA and USERPROFILE if (!userhome && usehome) //Alam: Still not? { char *testhome = NULL; diff --git a/src/d_net.c b/src/d_net.c index cdd63ea32a0649fbd5cfc86ed9adcd8d1dc361df..9f68c187c472e7cf73175c0f1ed55dcaccdba31b 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -1360,11 +1360,6 @@ boolean D_CheckNetGame(void) netbuffer = (doomdata_t *)(void *)&doomcom->data; #ifdef DEBUGFILE -#ifdef _arch_dreamcast - //debugfile = stderr; - if (debugfile) - CONS_Printf(M_GetText("debug output to: %s\n"), "STDERR"); -#else if (M_CheckParm("-debugfile")) { char filename[21]; @@ -1382,7 +1377,6 @@ boolean D_CheckNetGame(void) else CONS_Alert(CONS_WARNING, M_GetText("cannot debug output to file %s!\n"), va("%s" PATHSEP "%s", srb2home, filename)); } -#endif #endif D_ClientServerInit(); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 689576018c225fd0fbf61593227b8ae88bcc0e26..98267869b425aa511f2b263c5c45eefda35abbf4 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -62,9 +62,6 @@ static void Got_WeaponPref(UINT8 **cp, INT32 playernum); static void Got_Mapcmd(UINT8 **cp, INT32 playernum); static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum); static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum); -#ifdef DELFILE -static void Got_Delfilecmd(UINT8 **cp, INT32 playernum); -#endif static void Got_Addfilecmd(UINT8 **cp, INT32 playernum); static void Got_Pause(UINT8 **cp, INT32 playernum); static void Got_Suicide(UINT8 **cp, INT32 playernum); @@ -86,6 +83,9 @@ static void TeamScramble_OnChange(void); static void NetTimeout_OnChange(void); static void JoinTimeout_OnChange(void); +static void CoopStarposts_OnChange(void); +static void CoopLives_OnChange(void); + static void Ringslinger_OnChange(void); static void Gravity_OnChange(void); static void ForceSkin_OnChange(void); @@ -113,9 +113,6 @@ static void Command_ResetCamera_f(void); static void Command_Addfile(void); static void Command_ListWADS_f(void); -#ifdef DELFILE -static void Command_Delfile(void); -#endif static void Command_RunSOC(void); static void Command_Pause(void); static void Command_Suicide(void); @@ -187,22 +184,20 @@ static CV_PossibleValue_t joyport_cons_t[] = {{1, "/dev/js0"}, {2, "/dev/js1"}, #define usejoystick_cons_t NULL #endif -static CV_PossibleValue_t autobalance_cons_t[] = {{0, "MIN"}, {4, "MAX"}, {0, NULL}}; static CV_PossibleValue_t teamscramble_cons_t[] = {{0, "Off"}, {1, "Random"}, {2, "Points"}, {0, NULL}}; static CV_PossibleValue_t startingliveslimit_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}}; static CV_PossibleValue_t sleeping_cons_t[] = {{-1, "MIN"}, {1000/TICRATE, "MAX"}, {0, NULL}}; -static CV_PossibleValue_t competitionboxes_cons_t[] = {{0, "Normal"}, {1, "Random"}, {2, "Teleports"}, +static CV_PossibleValue_t competitionboxes_cons_t[] = {{0, "Normal"}, {1, "Mystery"}, //{2, "Teleport"}, {3, "None"}, {0, NULL}}; -static CV_PossibleValue_t matchboxes_cons_t[] = {{0, "Normal"}, {1, "Random"}, {2, "Non-Random"}, +static CV_PossibleValue_t matchboxes_cons_t[] = {{0, "Normal"}, {1, "Mystery"}, {2, "Unchanging"}, {3, "None"}, {0, NULL}}; static CV_PossibleValue_t chances_cons_t[] = {{0, "MIN"}, {9, "MAX"}, {0, NULL}}; -static CV_PossibleValue_t match_scoring_cons_t[] = {{0, "Normal"}, {1, "Classic"}, {0, NULL}}; static CV_PossibleValue_t pause_cons_t[] = {{0, "Server"}, {1, "All"}, {0, NULL}}; -static CV_PossibleValue_t timetic_cons_t[] = {{0, "Normal"}, {1, "Tics"}, {2, "Centiseconds"}, {0, NULL}}; +consvar_t cv_showinputjoy = {"showinputjoy", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef NETGAME_DEVMODE static consvar_t cv_fishcake = {"fishcake", "Off", CV_CALL|CV_NOSHOWHELP|CV_RESTRICT, CV_OnOff, Fishcake_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -218,7 +213,7 @@ consvar_t cv_startinglives = {"startinglives", "3", CV_NETVAR|CV_CHEAT, starting static CV_PossibleValue_t respawntime_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}}; consvar_t cv_respawntime = {"respawndelay", "3", CV_NETVAR|CV_CHEAT, respawntime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_competitionboxes = {"competitionboxes", "Random", CV_NETVAR|CV_CHEAT, competitionboxes_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_competitionboxes = {"competitionboxes", "Mystery", CV_NETVAR|CV_CHEAT, competitionboxes_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef SEENAMES static CV_PossibleValue_t seenames_cons_t[] = {{0, "Off"}, {1, "Colorless"}, {2, "Team"}, {3, "Ally/Foe"}, {0, NULL}}; @@ -226,9 +221,9 @@ consvar_t cv_seenames = {"seenames", "Ally/Foe", CV_SAVE, seenames_cons_t, 0, 0, consvar_t cv_allowseenames = {"allowseenames", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif -// these are just meant to be saved to the config -consvar_t cv_playername = {"name", "Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_playername2 = {"name2", "Tails", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +// names +consvar_t cv_playername = {"name", "Sonic", CV_CALL|CV_NOINIT, NULL, Name_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_playername2 = {"name2", "Tails", CV_CALL|CV_NOINIT, NULL, Name2_OnChange, 0, NULL, NULL, 0, 0, NULL}; // player colors consvar_t cv_playercolor = {"color", "Blue", CV_CALL|CV_NOINIT, Color_cons_t, Color_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_playercolor2 = {"color2", "Orange", CV_CALL|CV_NOINIT, Color_cons_t, Color2_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -236,6 +231,14 @@ consvar_t cv_playercolor2 = {"color2", "Orange", CV_CALL|CV_NOINIT, Color_cons_t consvar_t cv_skin = {"skin", DEFAULTSKIN, CV_CALL|CV_NOINIT, NULL, Skin_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_skin2 = {"skin2", DEFAULTSKIN2, CV_CALL|CV_NOINIT, NULL, Skin2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +// saved versions of the above six +consvar_t cv_defaultplayername = {"defaultname", "Sonic", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_defaultplayername2 = {"defaultname2", "Tails", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_defaultplayercolor = {"defaultcolor", "Blue", CV_SAVE, Color_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_defaultplayercolor2 = {"defaultcolor2", "Orange", CV_SAVE, Color_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_defaultskin = {"defaultskin", DEFAULTSKIN, CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_defaultskin2 = {"defaultskin2", DEFAULTSKIN2, CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; + consvar_t cv_skipmapcheck = {"skipmapcheck", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; INT32 cv_debug; @@ -243,22 +246,10 @@ INT32 cv_debug; consvar_t cv_usemouse = {"use_mouse", "On", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_usemouse2 = {"use_mouse2", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse2, 0, NULL, NULL, 0, 0, NULL}; -#if defined (DC) || defined (_XBOX) || defined (WMINPUT) || defined (_WII) || defined(HAVE_SDL) || defined(_WINDOWS) //joystick 1 and 2 consvar_t cv_usejoystick = {"use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_usejoystick2 = {"use_joystick2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick2, 0, NULL, NULL, 0, 0, NULL}; -#elif defined (PSP) || defined (GP2X) || defined (_NDS) //only one joystick -consvar_t cv_usejoystick = {"use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t, - I_InitJoystick, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_usejoystick2 = {"use_joystick2", "0", CV_SAVE|CV_CALL, usejoystick_cons_t, - I_InitJoystick2, 0, NULL, NULL, 0, 0, NULL}; -#else //all esle, no joystick -consvar_t cv_usejoystick = {"use_joystick", "0", CV_SAVE|CV_CALL, usejoystick_cons_t, - I_InitJoystick, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_usejoystick2 = {"use_joystick2", "0", CV_SAVE|CV_CALL, usejoystick_cons_t, - I_InitJoystick2, 0, NULL, NULL, 0, 0, NULL}; -#endif #if (defined (LJOYSTICK) || defined (HAVE_SDL)) #ifdef LJOYSTICK consvar_t cv_joyport = {"joyport", "/dev/js0", CV_SAVE, joyport_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -306,7 +297,7 @@ consvar_t cv_countdowntime = {"countdowntime", "60", CV_NETVAR|CV_CHEAT, minitim consvar_t cv_touchtag = {"touchtag", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_hidetime = {"hidetime", "30", CV_NETVAR|CV_CALL, minitimelimit_cons_t, Hidetime_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_autobalance = {"autobalance", "0", CV_NETVAR|CV_CALL, autobalance_cons_t, AutoBalance_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_autobalance = {"autobalance", "Off", CV_NETVAR|CV_CALL, CV_OnOff, AutoBalance_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_teamscramble = {"teamscramble", "Off", CV_NETVAR|CV_CALL|CV_NOINIT, teamscramble_cons_t, TeamScramble_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_scrambleonchange = {"scrambleonchange", "Off", CV_NETVAR, teamscramble_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -314,12 +305,16 @@ consvar_t cv_friendlyfire = {"friendlyfire", "Off", CV_NETVAR, CV_OnOff, NULL, 0 consvar_t cv_itemfinder = {"itemfinder", "Off", CV_CALL, CV_OnOff, ItemFinder_OnChange, 0, NULL, NULL, 0, 0, NULL}; // Scoring type options -consvar_t cv_match_scoring = {"matchscoring", "Normal", CV_NETVAR|CV_CHEAT, match_scoring_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_overtime = {"overtime", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_rollingdemos = {"rollingdemos", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_timetic = {"timerres", "Normal", CV_SAVE, timetic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display +static CV_PossibleValue_t timetic_cons_t[] = {{0, "Classic"}, {1, "Centiseconds"}, {2, "Mania"}, {3, "Tics"}, {0, NULL}}; +consvar_t cv_timetic = {"timerres", "Classic", CV_SAVE, timetic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + +static CV_PossibleValue_t powerupdisplay_cons_t[] = {{0, "Never"}, {1, "First-person only"}, {2, "Always"}, {0, NULL}}; +consvar_t cv_powerupdisplay = {"powerupdisplay", "First-person only", CV_SAVE, powerupdisplay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + static CV_PossibleValue_t pointlimit_cons_t[] = {{0, "MIN"}, {999999990, "MAX"}, {0, NULL}}; consvar_t cv_pointlimit = {"pointlimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -334,7 +329,7 @@ consvar_t cv_usemapnumlaps = {"usemaplaps", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, // log elemental hazards -- not a netvar, is local to current player consvar_t cv_hazardlog = {"hazardlog", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_forceskin = {"forceskin", "-1", CV_NETVAR|CV_CALL|CV_CHEAT, NULL, ForceSkin_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_forceskin = {"forceskin", "None", CV_NETVAR|CV_CALL|CV_CHEAT, NULL, ForceSkin_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_downloading = {"downloading", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_allowexitlevel = {"allowexitlevel", "No", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -350,12 +345,18 @@ consvar_t cv_maxping = {"maxping", "0", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NUL #endif // Intermission time Tails 04-19-2002 static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}}; -consvar_t cv_inttime = {"inttime", "20", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_inttime = {"inttime", "10", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + +static CV_PossibleValue_t coopstarposts_cons_t[] = {{0, "Per-player"}, {1, "Shared"}, {2, "Teamwork"}, {0, NULL}}; +consvar_t cv_coopstarposts = {"coopstarposts", "Teamwork", CV_NETVAR|CV_CALL|CV_CHEAT, coopstarposts_cons_t, CoopStarposts_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +static CV_PossibleValue_t cooplives_cons_t[] = {{0, "Infinite"}, {1, "Per-player"}, {2, "Avoid Game Over"}, {3, "Single pool"}, {0, NULL}}; +consvar_t cv_cooplives = {"cooplives", "Avoid Game Over", CV_NETVAR|CV_CALL|CV_CHEAT, cooplives_cons_t, CoopLives_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}}; consvar_t cv_advancemap = {"advancemap", "Next", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t playersforexit_cons_t[] = {{0, "One"}, {1, "All"}, {0, NULL}}; -consvar_t cv_playersforexit = {"playersforexit", "One", CV_NETVAR, playersforexit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t playersforexit_cons_t[] = {{0, "One"}, {1, "1/4"}, {2, "Half"}, {3, "3/4"}, {4, "All"}, {0, NULL}}; +consvar_t cv_playersforexit = {"playersforexit", "All", CV_NETVAR, playersforexit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_runscripts = {"runscripts", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -394,7 +395,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] = "RANDOMSEED", "RUNSOC", "REQADDFILE", - "DELFILE", + "DELFILE", // replace next time we add an XD "SETMOTD", "SUICIDE", #ifdef HAVE_BLUA @@ -430,9 +431,6 @@ void D_RegisterServerCommands(void) RegisterNetXCmd(XD_EXITLEVEL, Got_ExitLevelcmd); RegisterNetXCmd(XD_ADDFILE, Got_Addfilecmd); RegisterNetXCmd(XD_REQADDFILE, Got_RequestAddfilecmd); -#ifdef DELFILE - RegisterNetXCmd(XD_DELFILE, Got_Delfilecmd); -#endif RegisterNetXCmd(XD_PAUSE, Got_Pause); RegisterNetXCmd(XD_SUICIDE, Got_Suicide); RegisterNetXCmd(XD_RUNSOC, Got_RunSOCcmd); @@ -468,9 +466,6 @@ void D_RegisterServerCommands(void) COM_AddCommand("addfile", Command_Addfile); COM_AddCommand("listwad", Command_ListWADS_f); -#ifdef DELFILE - COM_AddCommand("delfile", Command_Delfile); -#endif COM_AddCommand("runsoc", Command_RunSOC); COM_AddCommand("pause", Command_Pause); COM_AddCommand("suicide", Command_Suicide); @@ -503,7 +498,6 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_itemrespawntime); CV_RegisterVar(&cv_itemrespawn); CV_RegisterVar(&cv_flagtime); - CV_RegisterVar(&cv_suddendeath); // misc CV_RegisterVar(&cv_friendlyfire); @@ -528,6 +522,9 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_forceskin); CV_RegisterVar(&cv_downloading); + CV_RegisterVar(&cv_coopstarposts); + CV_RegisterVar(&cv_cooplives); + CV_RegisterVar(&cv_specialrings); CV_RegisterVar(&cv_powerstones); CV_RegisterVar(&cv_competitionboxes); @@ -551,7 +548,6 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_startinglives); CV_RegisterVar(&cv_countdowntime); CV_RegisterVar(&cv_runscripts); - CV_RegisterVar(&cv_match_scoring); CV_RegisterVar(&cv_overtime); CV_RegisterVar(&cv_pause); CV_RegisterVar(&cv_mute); @@ -633,6 +629,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_screenshot_option); CV_RegisterVar(&cv_screenshot_folder); + CV_RegisterVar(&cv_screenshot_colorprofile); CV_RegisterVar(&cv_moviemode); // PNG variables CV_RegisterVar(&cv_zlib_level); @@ -661,6 +658,13 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_playername2); CV_RegisterVar(&cv_playercolor2); CV_RegisterVar(&cv_skin2); + // saved versions of the above six + CV_RegisterVar(&cv_defaultplayername); + CV_RegisterVar(&cv_defaultplayercolor); + CV_RegisterVar(&cv_defaultskin); + CV_RegisterVar(&cv_defaultplayername2); + CV_RegisterVar(&cv_defaultplayercolor2); + CV_RegisterVar(&cv_defaultskin2); #ifdef SEENAMES CV_RegisterVar(&cv_seenames); @@ -674,7 +678,9 @@ void D_RegisterClientCommands(void) // HUD CV_RegisterVar(&cv_timetic); + CV_RegisterVar(&cv_powerupdisplay); CV_RegisterVar(&cv_itemfinder); + CV_RegisterVar(&cv_showinputjoy); // time attack ghost options are also saved to config CV_RegisterVar(&cv_ghost_bestscore); @@ -686,7 +692,29 @@ void D_RegisterClientCommands(void) COM_AddCommand("displayplayer", Command_Displayplayer_f); // FIXME: not to be here.. but needs be done for config loading - CV_RegisterVar(&cv_usegamma); + CV_RegisterVar(&cv_globalgamma); + CV_RegisterVar(&cv_globalsaturation); + + CV_RegisterVar(&cv_rhue); + CV_RegisterVar(&cv_yhue); + CV_RegisterVar(&cv_ghue); + CV_RegisterVar(&cv_chue); + CV_RegisterVar(&cv_bhue); + CV_RegisterVar(&cv_mhue); + + CV_RegisterVar(&cv_rgamma); + CV_RegisterVar(&cv_ygamma); + CV_RegisterVar(&cv_ggamma); + CV_RegisterVar(&cv_cgamma); + CV_RegisterVar(&cv_bgamma); + CV_RegisterVar(&cv_mgamma); + + CV_RegisterVar(&cv_rsaturation); + CV_RegisterVar(&cv_ysaturation); + CV_RegisterVar(&cv_gsaturation); + CV_RegisterVar(&cv_csaturation); + CV_RegisterVar(&cv_bsaturation); + CV_RegisterVar(&cv_msaturation); // m_menu.c CV_RegisterVar(&cv_compactscoreboard); @@ -703,6 +731,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_alwaysfreelook2); CV_RegisterVar(&cv_chasefreelook); CV_RegisterVar(&cv_chasefreelook2); + CV_RegisterVar(&cv_tutorialprompt); // g_input.c CV_RegisterVar(&cv_sideaxis); @@ -764,8 +793,15 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_useranalog); CV_RegisterVar(&cv_useranalog2); + // deez New User eXperiences + CV_RegisterVar(&cv_directionchar); + CV_RegisterVar(&cv_directionchar2); + CV_RegisterVar(&cv_autobrake); + CV_RegisterVar(&cv_autobrake2); + // s_sound.c CV_RegisterVar(&cv_soundvolume); + CV_RegisterVar(&cv_closedcaptioning); CV_RegisterVar(&cv_digmusicvolume); CV_RegisterVar(&cv_midimusicvolume); CV_RegisterVar(&cv_numChannels); @@ -788,6 +824,7 @@ void D_RegisterClientCommands(void) COM_AddCommand("writethings", Command_Writethings_f); CV_RegisterVar(&cv_speed); CV_RegisterVar(&cv_opflags); + CV_RegisterVar(&cv_ophoopflags); CV_RegisterVar(&cv_mapthingnum); // CV_RegisterVar(&cv_grid); // CV_RegisterVar(&cv_snapto); @@ -1030,7 +1067,7 @@ static void SetPlayerName(INT32 playernum, char *newname) CONS_Printf(M_GetText("Player %d sent a bad name change\n"), playernum+1); if (server && netgame) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -1046,7 +1083,7 @@ UINT8 CanChangeSkin(INT32 playernum) return true; // Force skin in effect. - if (client && (cv_forceskin.value != -1) && !(IsPlayerAdmin(playernum) && serverplayer == -1)) + if ((cv_forceskin.value != -1) || (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0')) return false; // Can change skin in intermission and whatnot. @@ -1110,7 +1147,7 @@ static INT32 snacpending = 0, snac2pending = 0, chmappending = 0; // static void SendNameAndColor(void) { - XBOXSTATIC char buf[MAXPLAYERNAME+2]; + char buf[MAXPLAYERNAME+2]; char *p; p = buf; @@ -1144,6 +1181,8 @@ static void SendNameAndColor(void) if (!Playing()) return; + players[consoleplayer].availabilities = R_GetSkinAvailabilities(); + // If you're not in a netgame, merely update the skin, color, and name. if (!netgame) { @@ -1162,7 +1201,7 @@ static void SendNameAndColor(void) SetPlayerSkinByNum(consoleplayer, 0); CV_StealthSet(&cv_skin, skins[0].name); } - else if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1) + else if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1 && R_SkinUsable(consoleplayer, foundskin)) { boolean notsame; @@ -1177,7 +1216,7 @@ static void SendNameAndColor(void) { CV_StealthSetValue(&cv_playercolor, skins[cv_skin.value].prefcolor); - players[consoleplayer].skincolor = (cv_playercolor.value&0x1F) % MAXSKINCOLORS; + players[consoleplayer].skincolor = cv_playercolor.value % MAXSKINCOLORS; if (players[consoleplayer].mo) players[consoleplayer].mo->color = (UINT8)players[consoleplayer].skincolor; @@ -1209,7 +1248,7 @@ static void SendNameAndColor(void) // check if player has the skin loaded (cv_skin may have // the name of a skin that was available in the previous game) cv_skin.value = R_SkinAvailable(cv_skin.string); - if (cv_skin.value < 0) + if ((cv_skin.value < 0) || !R_SkinUsable(consoleplayer, cv_skin.value)) { CV_StealthSet(&cv_skin, DEFAULTSKIN); cv_skin.value = 0; @@ -1217,6 +1256,7 @@ static void SendNameAndColor(void) // Finally write out the complete packet and send it off. WRITESTRINGN(p, cv_playername.zstring, MAXPLAYERNAME); + WRITEUINT32(p, (UINT32)players[consoleplayer].availabilities); WRITEUINT8(p, (UINT8)cv_playercolor.value); WRITEUINT8(p, (UINT8)cv_skin.value); SendNetXCmd(XD_NAMEANDCOLOR, buf, p - buf); @@ -1259,6 +1299,8 @@ static void SendNameAndColor2(void) if (!Playing()) return; + players[secondplaya].availabilities = R_GetSkinAvailabilities(); + // If you're not in a netgame, merely update the skin, color, and name. if (botingame) { @@ -1287,7 +1329,7 @@ static void SendNameAndColor2(void) SetPlayerSkinByNum(secondplaya, forcedskin); CV_StealthSet(&cv_skin2, skins[forcedskin].name); } - else if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1) + else if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1 && R_SkinUsable(secondplaya, foundskin)) { boolean notsame; @@ -1301,7 +1343,7 @@ static void SendNameAndColor2(void) { CV_StealthSetValue(&cv_playercolor2, skins[players[secondplaya].skin].prefcolor); - players[secondplaya].skincolor = (cv_playercolor2.value&0x1F) % MAXSKINCOLORS; + players[secondplaya].skincolor = cv_playercolor2.value % MAXSKINCOLORS; if (players[secondplaya].mo) players[secondplaya].mo->color = players[secondplaya].skincolor; @@ -1342,6 +1384,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) #endif READSTRINGN(*cp, name, MAXPLAYERNAME); + p->availabilities = READUINT32(*cp); color = READUINT8(*cp); skin = READUINT8(*cp); @@ -1358,6 +1401,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) if (server && (p != &players[consoleplayer] && p != &players[secondarydisplayplayer])) { boolean kick = false; + INT32 s; // team colors if (G_GametypeHasTeams()) @@ -1372,9 +1416,19 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) if (!p->skincolor) kick = true; + // availabilities + for (s = 0; s < MAXSKINS; s++) + { + if (!skins[s].availability && (p->availabilities & (1 << s))) + { + kick = true; + break; + } + } + if (kick) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; CONS_Alert(CONS_WARNING, M_GetText("Illegal color change received from %s (team: %d), color: %d)\n"), player_names[playernum], p->ctfteam, p->skincolor); buf[0] = (UINT8)playernum; @@ -1401,25 +1455,33 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) void SendWeaponPref(void) { - XBOXSTATIC UINT8 buf[1]; + UINT8 buf[1]; buf[0] = 0; if (cv_flipcam.value) buf[0] |= 1; if (cv_analog.value) buf[0] |= 2; + if (cv_directionchar.value) + buf[0] |= 4; + if (cv_autobrake.value) + buf[0] |= 8; SendNetXCmd(XD_WEAPONPREF, buf, 1); } void SendWeaponPref2(void) { - XBOXSTATIC UINT8 buf[1]; + UINT8 buf[1]; buf[0] = 0; if (cv_flipcam2.value) buf[0] |= 1; if (cv_analog2.value) buf[0] |= 2; + if (cv_directionchar2.value) + buf[0] |= 4; + if (cv_autobrake2.value) + buf[0] |= 8; SendNetXCmd2(XD_WEAPONPREF, buf, 1); } @@ -1427,11 +1489,15 @@ static void Got_WeaponPref(UINT8 **cp,INT32 playernum) { UINT8 prefs = READUINT8(*cp); - players[playernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE); + players[playernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE); if (prefs & 1) players[playernum].pflags |= PF_FLIPCAM; if (prefs & 2) players[playernum].pflags |= PF_ANALOGMODE; + if (prefs & 4) + players[playernum].pflags |= PF_DIRECTIONCHAR; + if (prefs & 8) + players[playernum].pflags |= PF_AUTOBRAKE; } void D_SendPlayerConfig(void) @@ -1579,23 +1645,20 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese { static char buf[2+MAX_WADPATH+1+4]; static char *buf_p = buf; - // The supplied data are assumed to be good. I_Assert(delay >= 0 && delay <= 2); - + if (mapnum != -1) + CV_SetValue(&cv_nextmap, mapnum); CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d gametype=%d ultmode=%d resetplayers=%d delay=%d skipprecutscene=%d\n", mapnum, newgametype, pultmode, resetplayers, delay, skipprecutscene); - - if (netgame || multiplayer) + if ((netgame || multiplayer) && !((gametype == newgametype) && (newgametype == GT_COOP))) FLS = false; if (delay != 2) { UINT8 flags = 0; const char *mapname = G_BuildMapName(mapnum); - I_Assert(W_CheckNumForName(mapname) != LUMPERROR); - buf_p = buf; if (pultmode) flags |= 1; @@ -1743,9 +1806,19 @@ static void Command_Map_f(void) } } + // 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)) + { + CONS_Alert(CONS_NOTICE, M_GetText("You need to unlock this level before you can warp to it!\n")); + return; + } + // don't use a gametype the map doesn't support if (cv_debug || COM_CheckParm("-force") || cv_skipmapcheck.value) - ; // The player wants us to trek on anyway. Do so. + fromlevelselect = false; // The player wants us to trek on anyway. Do so. // G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer // Alternatively, bail if the map header is completely missing anyway. else if (!mapheaderinfo[newmapnum-1] @@ -1763,19 +1836,20 @@ static void Command_Map_f(void) CONS_Alert(CONS_WARNING, M_GetText("%s doesn't support %s mode!\n(Use -force to override)\n"), mapname, gametypestring); return; } + else + fromlevelselect = ((netgame || multiplayer) && ((gametype == newgametype) && (newgametype == GT_COOP))); - // Prevent warping to locked levels - // ... unless you're in a dedicated server. Yes, technically this means you can view any level by - // running a dedicated server and joining it yourself, but that's better than making dedicated server's - // lives hell. - if (!dedicated && M_MapLocked(newmapnum)) + if (tutorialmode && tutorialgcs) { - CONS_Alert(CONS_NOTICE, M_GetText("You need to unlock this level before you can warp to it!\n")); - return; + G_CopyControls(gamecontrol, gamecontroldefault[gcs_custom], gcl_tutorial_full, num_gcl_tutorial_full); // using gcs_custom as temp storage + CV_SetValue(&cv_usemouse, tutorialusemouse); + CV_SetValue(&cv_alwaysfreelook, tutorialfreelook); + CV_SetValue(&cv_mousemove, tutorialmousemove); + CV_SetValue(&cv_analog, tutorialanalog); } + tutorialmode = false; // warping takes us out of tutorial mode - fromlevelselect = false; - D_MapChange(newmapnum, newgametype, false, newresetplayers, 0, false, false); + D_MapChange(newmapnum, newgametype, false, newresetplayers, 0, false, fromlevelselect); } /** Receives a map command and changes the map. @@ -1800,7 +1874,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) CONS_Alert(CONS_WARNING, M_GetText("Illegal map change received from %s\n"), player_names[playernum]); if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -1845,10 +1919,14 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) if (demoplayback && !timingdemo) precache = false; - if (resetplayer) + if (resetplayer && !FLS) + emeralds = 0; + + if (modeattacking) { - if (!FLS || (netgame || multiplayer)) - emeralds = 0; + SetPlayerSkinByNum(0, cv_chooseskin.value-1); + players[0].skincolor = skins[players[0].skin].prefcolor; + CV_StealthSetValue(&cv_playercolor, players[0].skincolor); } #ifdef HAVE_BLUA @@ -1856,22 +1934,12 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) LUAh_MapChange(mapnumber); #endif - G_InitNew(ultimatemode, mapname, resetplayer, skipprecutscene); + G_InitNew(ultimatemode, mapname, resetplayer, skipprecutscene, FLS); if (demoplayback && !timingdemo) precache = true; if (timingdemo) G_DoneLevelLoad(); - if (modeattacking) - { - SetPlayerSkinByNum(0, cv_chooseskin.value-1); - players[0].skincolor = skins[players[0].skin].prefcolor; - CV_StealthSetValue(&cv_playercolor, players[0].skincolor); - - // a copy of color - if (players[0].mo) - players[0].mo->color = players[0].skincolor; - } if (metalrecording) G_BeginMetal(); if (demorecording) // Okay, level loaded, character spawned and skinned, @@ -1881,7 +1949,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) static void Command_Pause(void) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; UINT8 *cp = buf; if (COM_Argc() > 1) @@ -1917,7 +1985,7 @@ static void Got_Pause(UINT8 **cp, INT32 playernum) CONS_Alert(CONS_WARNING, M_GetText("Illegal pause command received from %s\n"), player_names[playernum]); if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -1960,7 +2028,7 @@ static void Got_Pause(UINT8 **cp, INT32 playernum) // Command for stuck characters in netgames, griefing, etc. static void Command_Suicide(void) { - XBOXSTATIC UINT8 buf[4]; + UINT8 buf[4]; UINT8 *cp = buf; WRITEINT32(cp, consoleplayer); @@ -1997,7 +2065,7 @@ static void Got_Suicide(UINT8 **cp, INT32 playernum) CONS_Alert(CONS_WARNING, M_GetText("Illegal suicide command received from %s\n"), player_names[playernum]); if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -2007,7 +2075,7 @@ static void Got_Suicide(UINT8 **cp, INT32 playernum) } if (players[suicideplayer].mo) - P_DamageMobj(players[suicideplayer].mo, NULL, NULL, 10000); + P_DamageMobj(players[suicideplayer].mo, NULL, NULL, 1, DMG_INSTAKILL); } /** Deals with an ::XD_RANDOMSEED message in a netgame. @@ -2066,7 +2134,7 @@ static void Got_Clearscores(UINT8 **cp, INT32 playernum) CONS_Alert(CONS_WARNING, M_GetText("Illegal clear scores command received from %s\n"), player_names[playernum]); if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -2419,7 +2487,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]); if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -2434,7 +2502,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]); if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -2473,7 +2541,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]); if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -2526,7 +2594,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) if (server && ((NetPacket.packet.newteam < 0 || NetPacket.packet.newteam > 3) || error)) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -2538,7 +2606,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) if (players[playernum].mo) { if (!players[playernum].spectator) - P_DamageMobj(players[playernum].mo, NULL, NULL, 10000); + P_DamageMobj(players[playernum].mo, NULL, NULL, 1, DMG_INSTAKILL); else { P_RemoveMobj(players[playernum].mo); @@ -2557,12 +2625,12 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) { players[playernum].spectator = true; players[playernum].pflags &= ~PF_TAGIT; - players[playernum].pflags &= ~PF_TAGGED; + players[playernum].pflags &= ~PF_GAMETYPEOVER; } else if (NetPacket.packet.newteam != 3) // .newteam == 1 or 2. { players[playernum].spectator = false; - players[playernum].pflags &= ~PF_TAGGED;//Just in case. + players[playernum].pflags &= ~PF_GAMETYPEOVER; //Just in case. if (NetPacket.packet.newteam == 1) //Make the player IT. players[playernum].pflags |= PF_TAGIT; @@ -2653,8 +2721,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) // Clear player score and rings if a spectator. if (players[playernum].spectator) { - players[playernum].score = 0; - players[playernum].health = 1; + players[playernum].score = players[playernum].rings = 0; if (players[playernum].mo) players[playernum].mo->health = 1; } @@ -2677,7 +2744,7 @@ static void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, (void)salt; memset(dest, 0, 16); #else - XBOXSTATIC char tmpbuf[256]; + char tmpbuf[256]; const size_t sl = strlen(salt); if (len > 256-sl) @@ -2734,7 +2801,7 @@ static void Command_Login_f(void) // If we have no MD5 support then completely disable XD_LOGIN responses for security. CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n"); #else - XBOXSTATIC UINT8 finalmd5[16]; + UINT8 finalmd5[16]; const char *pw; if (!netgame) @@ -2843,7 +2910,7 @@ void RemoveAdminPlayer(INT32 playernum) static void Command_Verify_f(void) { - XBOXSTATIC char buf[8]; // Should be plenty + char buf[8]; // Should be plenty char *temp; INT32 playernum; @@ -2886,7 +2953,7 @@ static void Got_Verification(UINT8 **cp, INT32 playernum) CONS_Alert(CONS_WARNING, M_GetText("Illegal verification received from %s (serverplayer is %s)\n"), player_names[playernum], player_names[serverplayer]); if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -2905,7 +2972,7 @@ static void Got_Verification(UINT8 **cp, INT32 playernum) static void Command_RemoveAdmin_f(void) { - XBOXSTATIC char buf[8]; // Should be plenty + char buf[8]; // Should be plenty char *temp; INT32 playernum; @@ -2942,7 +3009,7 @@ static void Got_Removal(UINT8 **cp, INT32 playernum) CONS_Alert(CONS_WARNING, M_GetText("Illegal demotion received from %s (serverplayer is %s)\n"), player_names[playernum], player_names[serverplayer]); if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -3022,7 +3089,7 @@ static void Got_MotD_f(UINT8 **cp, INT32 playernum) CONS_Alert(CONS_WARNING, M_GetText("Illegal motd change received from %s\n"), player_names[playernum]); if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -3043,7 +3110,7 @@ static void Got_MotD_f(UINT8 **cp, INT32 playernum) static void Command_RunSOC(void) { const char *fn; - XBOXSTATIC char buf[255]; + char buf[255]; size_t length = 0; if (COM_Argc() != 2) @@ -3085,7 +3152,7 @@ static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum) CONS_Alert(CONS_WARNING, M_GetText("Illegal runsoc command received from %s\n"), player_names[playernum]); if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -3128,7 +3195,7 @@ static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum) static void Command_Addfile(void) { const char *fn, *p; - XBOXSTATIC char buf[256]; + char buf[256]; char *buf_p = buf; INT32 i; int musiconly; // W_VerifyNMUSlumps isn't boolean @@ -3171,6 +3238,7 @@ static void Command_Addfile(void) if (*p == '\\' || *p == '/' || *p == ':') break; ++p; + // check total packet size and no of files currently loaded // See W_LoadWadFile in w_wad.c if ((numwadfiles >= MAX_WADFILES) @@ -3219,42 +3287,6 @@ static void Command_Addfile(void) SendNetXCmd(XD_ADDFILE, buf, buf_p - buf); } -#ifdef DELFILE -/** removes the last added pwad at runtime. - * Searches for sounds, maps, music and images to remove - */ -static void Command_Delfile(void) -{ - if (gamestate == GS_LEVEL) - { - CONS_Printf(M_GetText("You must NOT be in a level to use this.\n")); - return; - } - - if (netgame && !(server || adminplayer == consoleplayer)) - { - CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); - return; - } - - if (numwadfiles <= mainwads) - { - CONS_Printf(M_GetText("No additional WADs are loaded.\n")); - return; - } - - if (!(netgame || multiplayer)) - { - P_DelWadFile(); - if (mainwads == numwadfiles && modifiedgame) - modifiedgame = false; - return; - } - - SendNetXCmd(XD_DELFILE, NULL, 0); -} -#endif - static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum) { char filename[241]; @@ -3282,7 +3314,7 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum) if ((playernum != serverplayer && !IsPlayerAdmin(playernum)) || kick) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; CONS_Alert(CONS_WARNING, M_GetText("Illegal addfile command received from %s\n"), player_names[playernum]); @@ -3324,33 +3356,6 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum) COM_BufAddText(va("addfile %s\n", filename)); } -#ifdef DELFILE -static void Got_Delfilecmd(UINT8 **cp, INT32 playernum) -{ - if (playernum != serverplayer && playernum != adminplayer) - { - CONS_Alert(CONS_WARNING, M_GetText("Illegal delfile command received from %s\n"), player_names[playernum]); - if (server) - { - XBOXSTATIC UINT8 buf[2]; - - buf[0] = (UINT8)playernum; - buf[1] = KICK_MSG_CON_FAIL; - SendNetXCmd(XD_KICK, &buf, 2); - } - return; - } - (void)cp; - - if (numwadfiles <= mainwads) //sanity - return; - - P_DelWadFile(); - if (mainwads == numwadfiles && modifiedgame) - modifiedgame = false; -} -#endif - static void Got_Addfilecmd(UINT8 **cp, INT32 playernum) { char filename[241]; @@ -3365,7 +3370,7 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum) CONS_Alert(CONS_WARNING, M_GetText("Illegal addfile command received from %s\n"), player_names[playernum]); if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -3417,6 +3422,8 @@ static void Command_ListWADS_f(void) CONS_Printf("\x82 IWAD\x80: %s\n", tempname); else if (i <= mainwads) CONS_Printf("\x82 * %.2d\x80: %s\n", i, tempname); + else if (!wadfiles[i]->important) + CONS_Printf("\x86 %.2d: %s\n", i, tempname); else CONS_Printf(" %.2d: %s\n", i, tempname); } @@ -3600,6 +3607,102 @@ static void JoinTimeout_OnChange(void) jointimeout = (tic_t)cv_jointimeout.value; } +static void CoopStarposts_OnChange(void) +{ + INT32 i; + + if (!(netgame || multiplayer) || gametype != GT_COOP) + return; + + switch (cv_coopstarposts.value) + { + case 0: + CONS_Printf(M_GetText("Starposts are now per-player.\n")); + break; + case 1: + CONS_Printf(M_GetText("Starposts are now shared between players.\n")); + break; + case 2: + CONS_Printf(M_GetText("Players now only spawn when starposts are hit.\n")); + return; + } + + if (G_IsSpecialStage(gamemap)) + return; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (!players[i].spectator) + continue; + + if (players[i].lives <= 0) + continue; + + break; + } + + if (i == MAXPLAYERS) + return; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (!players[i].spectator) + continue; + + if (players[i].lives <= 0 && (cv_cooplives.value == 1)) + continue; + + P_SpectatorJoinGame(&players[i]); + } +} + +static void CoopLives_OnChange(void) +{ + INT32 i; + + if (!(netgame || multiplayer) || gametype != GT_COOP) + return; + + switch (cv_cooplives.value) + { + case 0: + CONS_Printf(M_GetText("Players can now respawn indefinitely.\n")); + return; + case 1: + CONS_Printf(M_GetText("Lives are now per-player.\n")); + return; + case 2: + CONS_Printf(M_GetText("Players can now steal lives to avoid game over.\n")); + break; + case 3: + CONS_Printf(M_GetText("Lives are now shared between players.\n")); + break; + } + + if (cv_coopstarposts.value == 2) + return; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (!players[i].spectator) + continue; + + if (players[i].lives > 0) + continue; + + P_SpectatorJoinGame(&players[i]); + } +} + UINT32 timelimitintics = 0; /** Deals with a timelimit change by printing the change to the console. @@ -3888,7 +3991,7 @@ retryscramble: { if (red == maxcomposition) newteam = 2; - else if (blue == maxcomposition) + else //if (blue == maxcomposition) newteam = 1; repick = false; @@ -3929,14 +4032,11 @@ retryscramble: newteam = (INT16)((M_RandomByte() % 2) + 1); repick = false; } - else + else if (i != 2) // Mystic's secret sauce - ABBA is better than ABAB, so team B doesn't get worse players all around { // We will only randomly pick the team for the first guy. // Otherwise, just alternate back and forth, distributing players. - if (newteam == 1) - newteam = 2; - else - newteam = 1; + newteam = 3 - newteam; } scrambleteams[i] = newteam; @@ -4035,7 +4135,7 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum) CONS_Alert(CONS_WARNING, M_GetText("Illegal exitlevel command received from %s\n"), player_names[playernum]); if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 5054345419cd68495656dc40aac36a8b9461eebe..c73f17618e913ad486d84d6665118e649eec7883 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -25,6 +25,13 @@ extern consvar_t cv_skin; extern consvar_t cv_playername2; extern consvar_t cv_playercolor2; extern consvar_t cv_skin2; +// saved versions of the above six +extern consvar_t cv_defaultplayername; +extern consvar_t cv_defaultplayercolor; +extern consvar_t cv_defaultskin; +extern consvar_t cv_defaultplayername2; +extern consvar_t cv_defaultplayercolor2; +extern consvar_t cv_defaultskin2; #ifdef SEENAMES extern consvar_t cv_seenames, cv_allowseenames; @@ -51,7 +58,6 @@ extern consvar_t cv_itemrespawntime; extern consvar_t cv_itemrespawn; extern consvar_t cv_flagtime; -extern consvar_t cv_suddendeath; extern consvar_t cv_touchtag; extern consvar_t cv_hidetime; @@ -90,9 +96,7 @@ extern consvar_t cv_recycler; extern consvar_t cv_itemfinder; -extern consvar_t cv_inttime, cv_advancemap, cv_playersforexit; -extern consvar_t cv_soniccd; -extern consvar_t cv_match_scoring; +extern consvar_t cv_inttime, cv_coopstarposts, cv_cooplives, cv_advancemap, cv_playersforexit; extern consvar_t cv_overtime; extern consvar_t cv_startinglives; @@ -135,7 +139,7 @@ typedef enum XD_RANDOMSEED, // 15 XD_RUNSOC, // 16 XD_REQADDFILE, // 17 - XD_DELFILE, // 18 + XD_DELFILE, // 18 - replace next time we add an XD XD_SETMOTD, // 19 XD_SUICIDE, // 20 XD_DEMOTED, // 21 diff --git a/src/d_netfil.c b/src/d_netfil.c index deb04fbe14fa5bd64213129a8ce8ed4979317f14..db9fa12e4957c86be3bd0579907bb9ea33af8230 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -11,21 +11,14 @@ /// \brief Transfer a file using HSendPacket. #include <stdio.h> -#ifndef _WIN32_WCE -#ifdef __OS2__ -#include <sys/types.h> -#endif // __OS2__ #include <sys/stat.h> -#endif -#if !defined (UNDER_CE) #include <time.h> -#endif -#if ((defined (_WIN32) && !defined (_WIN32_WCE)) || defined (__DJGPP__)) && !defined (_XBOX) +#if defined (_WIN32) || defined (__DJGPP__) #include <io.h> #include <direct.h> -#elif !defined (_WIN32_WCE) && !(defined (_XBOX) && !defined (__GNUC__)) +#else #include <sys/types.h> #include <dirent.h> #include <utime.h> @@ -34,7 +27,7 @@ #ifdef __GNUC__ #include <unistd.h> #include <limits.h> -#elif defined (_WIN32) && !defined (_WIN32_WCE) +#elif defined (_WIN32) #include <sys/utime.h> #endif #ifdef __DJGPP__ @@ -104,7 +97,7 @@ INT32 lastfilenum = -1; /** Fills a serverinfo packet with information about wad files loaded. * * \todo Give this function a better name since it is in global scope. - * Used to have size limiting built in - now handed via W_LoadWadFile in w_wad.c + * Used to have size limiting built in - now handled via W_LoadWadFile in w_wad.c * */ UINT8 *PutFileNeeded(void) @@ -336,7 +329,7 @@ INT32 CL_CheckFiles(void) // return 1; // the first is the iwad (the main wad file) - // we don't care if it's called srb2.srb or srb2.wad. + // we don't care if it's called srb2.pk3 or not. // Never download the IWAD, just assume it's there and identical fileneeded[0].status = FS_OPEN; @@ -350,7 +343,7 @@ INT32 CL_CheckFiles(void) { if (j < numwadfiles && !wadfiles[j]->important) { - // Unimportant on our side. still don't care. + // Unimportant on our side. ++j; continue; } @@ -755,11 +748,11 @@ void Got_Filetxpak(void) char *filename = file->filename; static INT32 filetime = 0; - if (!(strcmp(filename, "srb2.srb") + if (!(strcmp(filename, "srb2.pk3") + && strcmp(filename, "srb2.srb") && strcmp(filename, "srb2.wad") && strcmp(filename, "zones.dta") && strcmp(filename, "player.dta") - && strcmp(filename, "rings.dta") && strcmp(filename, "patch.dta") && strcmp(filename, "music.dta") )) @@ -902,9 +895,9 @@ void nameonly(char *s) ns = &(s[j+1]); len = strlen(ns); #if 0 - M_Memcpy(s, ns, len+1); + M_Memcpy(s, ns, len+1); #else - memmove(s, ns, len+1); + memmove(s, ns, len+1); #endif return; } @@ -928,7 +921,7 @@ size_t nameonlylength(const char *s) filestatus_t checkfilemd5(char *filename, const UINT8 *wantedmd5sum) { -#if defined (NOMD5) || defined (_arch_dreamcast) +#if defined (NOMD5) (void)wantedmd5sum; (void)filename; #else @@ -980,11 +973,7 @@ filestatus_t findfile(char *filename, const UINT8 *wantedmd5sum, boolean complet // if not found at all, just move on without doing anything // finally check "." directory -#ifdef _arch_dreamcast - homecheck = filesearch(filename, "/cd", wantedmd5sum, completepath, 10); -#else homecheck = filesearch(filename, ".", wantedmd5sum, completepath, 10); -#endif if (homecheck != FS_NOTFOUND) // if not found this time, fall back on the below return statement return homecheck; // otherwise return the result we got diff --git a/src/d_player.h b/src/d_player.h index 7c5ac6890b22ce3b243fd307ab04af1729c2f11f..cdc899f5eea0dd4c29d6598bc3cc97f51489f51d 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -32,13 +32,22 @@ // Extra abilities/settings for skins (combinable stuff) typedef enum { - SF_SUPER = 1, // Can turn super in singleplayer/co-op mode. - SF_SUPERANIMS = 1<<1, // If super, use the super sonic animations - SF_SUPERSPIN = 1<<2, // Should spin frames be played while super? - SF_HIRES = 1<<3, // Draw the sprite 2x as small? + SF_SUPER = 1, // Can turn super in singleplayer/co-op mode? + SF_NOSUPERSPIN = 1<<1, // Should spin frames be played while super? + SF_NOSPINDASHDUST = 1<<2, // Spawn dust particles when charging a spindash? + SF_HIRES = 1<<3, // Draw the sprite at different size? SF_NOSKID = 1<<4, // No skid particles etc SF_NOSPEEDADJUST = 1<<5, // Skin-specific version of disablespeedadjust SF_RUNONWATER = 1<<6, // Run on top of water FOFs? + SF_NOJUMPSPIN = 1<<7, // SPR2_JUMP defaults to SPR2_SPRG instead of SPR2_ROLL, falling states used, and player height is full when jumping? + SF_NOJUMPDAMAGE = 1<<8, // Don't damage enemies, etc whilst jumping? + SF_STOMPDAMAGE = 1<<9, // Always damage enemies, etc by landing on them, no matter your vunerability? + SF_MARIODAMAGE = SF_NOJUMPDAMAGE|SF_STOMPDAMAGE, // The Mario method of being able to damage enemies, etc. + SF_MACHINE = 1<<10, // Beep boop. Are you a robot? + SF_DASHMODE = 1<<11, // Sonic Advance 2 style top speed increase? + SF_FASTEDGE = 1<<12, // Faster edge teeter? + SF_MULTIABILITY = 1<<13, // Revenge of Final Demo. + // free up to and including 1<<31 } skinflags_t; //Primary and secondary skin abilities @@ -57,7 +66,9 @@ typedef enum CA_FALLSWITCH, CA_JUMPBOOST, CA_AIRDRILL, - CA_JUMPTHOK + CA_JUMPTHOK, + CA_BOUNCE, + CA_TWINSPIN } charability_t; //Secondary skin abilities @@ -65,7 +76,8 @@ typedef enum { CA2_NONE=0, CA2_SPINDASH, - CA2_MULTIABILITY + CA2_GUNSLINGER, + CA2_MELEE } charability2_t; // @@ -86,74 +98,60 @@ typedef enum // typedef enum { - // Flip camera angle with gravity flip prefrence. - PF_FLIPCAM = 1, + // Cvars + PF_FLIPCAM = 1, // Flip camera angle with gravity flip prefrence. + PF_ANALOGMODE = 1<<1, // Analog mode? + PF_DIRECTIONCHAR = 1<<2, // Directional character sprites? + PF_AUTOBRAKE = 1<<3, // Autobrake? // Cheats - PF_GODMODE = 1<<1, - PF_NOCLIP = 1<<2, - PF_INVIS = 1<<3, + PF_GODMODE = 1<<4, + PF_NOCLIP = 1<<5, + PF_INVIS = 1<<6, // True if button down last tic. - PF_ATTACKDOWN = 1<<4, - PF_USEDOWN = 1<<5, - PF_JUMPDOWN = 1<<6, - PF_WPNDOWN = 1<<7, + PF_ATTACKDOWN = 1<<7, + PF_USEDOWN = 1<<8, + PF_JUMPDOWN = 1<<9, + PF_WPNDOWN = 1<<10, // Unmoving states - PF_STASIS = 1<<8, // Player is not allowed to move - PF_JUMPSTASIS = 1<<9, // and that includes jumping. + PF_STASIS = 1<<11, // Player is not allowed to move + PF_JUMPSTASIS = 1<<12, // and that includes jumping. PF_FULLSTASIS = PF_STASIS|PF_JUMPSTASIS, - // Did you get a time-over? - PF_TIMEOVER = 1<<10, - - // Ready for Super? - PF_SUPERREADY = 1<<11, + // Applying autobrake? + PF_APPLYAUTOBRAKE = 1<<13, // Character action status - PF_JUMPED = 1<<12, - PF_SPINNING = 1<<13, - PF_STARTDASH = 1<<14, - PF_THOKKED = 1<<15, + PF_STARTJUMP = 1<<14, + PF_JUMPED = 1<<15, + PF_NOJUMPDAMAGE = 1<<16, - // Are you gliding? - PF_GLIDING = 1<<16, + PF_SPINNING = 1<<17, + PF_STARTDASH = 1<<18, - // Tails pickup! - PF_CARRIED = 1<<17, + PF_THOKKED = 1<<19, + PF_SHIELDABILITY = 1<<20, + PF_GLIDING = 1<<21, + PF_BOUNCING = 1<<22, // Sliding (usually in water) like Labyrinth/Oil Ocean - PF_SLIDING = 1<<18, - - // Hanging on a rope - PF_ROPEHANG = 1<<19, - - // Hanging on an item of some kind - zipline, chain, etc. (->tracer) - PF_ITEMHANG = 1<<20, + PF_SLIDING = 1<<23, - // On the mace chain spinning around (->tracer) - PF_MACESPIN = 1<<21, - - /*** NIGHTS STUFF ***/ - // Is the player in NiGHTS mode? - PF_NIGHTSMODE = 1<<22, - PF_TRANSFERTOCLOSEST = 1<<23, - - // Spill rings after falling - PF_NIGHTSFALL = 1<<24, + // NiGHTS stuff + PF_TRANSFERTOCLOSEST = 1<<24, PF_DRILLING = 1<<25, - PF_SKIDDOWN = 1<<26, - /*** TAG STUFF ***/ - PF_TAGGED = 1<<27, // Player has been tagged and awaits the next round in hide and seek. - PF_TAGIT = 1<<28, // The player is it! For Tag Mode + // Gametype-specific stuff + PF_GAMETYPEOVER = 1<<26, // Race time over, or H&S out-of-game + PF_TAGIT = 1<<27, // The player is it! For Tag Mode /*** misc ***/ - PF_FORCESTRAFE = 1<<29, // Turning inputs are translated into strafing inputs - PF_ANALOGMODE = 1<<30, // Analog mode? + PF_FORCESTRAFE = 1<<28, // Turning inputs are translated into strafing inputs + PF_CANCARRY = 1<<29, // Can carry another player? - // free: 1<<30 and 1<<31 + // up to 1<<31 is free } pflags_t; typedef enum @@ -161,35 +159,82 @@ typedef enum // Are animation frames playing? PA_ETC=0, PA_IDLE, + PA_EDGE, PA_WALK, PA_RUN, + PA_DASH, + PA_PAIN, PA_ROLL, + PA_JUMP, + PA_SPRING, PA_FALL, - PA_ABILITY + PA_ABILITY, + PA_ABILITY2, + PA_RIDE } panim_t; +// +// All of the base srb2 shields are either a single constant, +// or use damagetype-protecting flags applied to a constant, +// or are the force shield (which does everything weirdly). +// +// Base flags by themselves aren't used so modders can make +// abstract, ability-less shields should they so choose. +// typedef enum { SH_NONE = 0, - // Standard shields - SH_JUMP, - SH_ATTRACT, - SH_ELEMENTAL, - SH_BOMB, - // Stupid useless unimplimented Sonic 3 shields - SH_BUBBLEWRAP, - SH_THUNDERCOIN, - SH_FLAMEAURA, - // Pity shield: the world's most basic shield ever, given to players who suck at Match - SH_PITY, - // The fireflower is special, it combines with other shields. - SH_FIREFLOWER = 0x100, - // The force shield uses the lower 8 bits to count how many hits are left. - SH_FORCE = 0x200, - - SH_STACK = SH_FIREFLOWER, + + // Shield flags + SH_PROTECTFIRE = 0x400, + SH_PROTECTWATER = 0x800, + SH_PROTECTELECTRIC = 0x1000, + SH_PROTECTSPIKE = 0x2000, // cactus shield one day? thanks, subarashii + //SH_PROTECTNUKE = 0x4000, // intentionally no hardcoded defense against nukes + + // Indivisible shields + SH_PITY = 1, // the world's most basic shield ever, given to players who suck at Match + SH_WHIRLWIND, + SH_ARMAGEDDON, + + // Normal shields that use flags + SH_ATTRACT = SH_PITY|SH_PROTECTELECTRIC, + SH_ELEMENTAL = SH_PITY|SH_PROTECTFIRE|SH_PROTECTWATER, + + // Sonic 3 shields + SH_FLAMEAURA = SH_PITY|SH_PROTECTFIRE, + SH_BUBBLEWRAP = SH_PITY|SH_PROTECTWATER, + SH_THUNDERCOIN = SH_WHIRLWIND|SH_PROTECTELECTRIC, + + // The force shield uses the lower 8 bits to count how many extra hits are left. + SH_FORCE = 0x100, + SH_FORCEHP = 0xFF, // to be used as a bitmask only + + // Mostly for use with Mario mode. + SH_FIREFLOWER = 0x200, + + SH_STACK = SH_FIREFLOWER, // second-layer shields SH_NOSTACK = ~SH_STACK -} shieldtype_t; +} shieldtype_t; // pw_shield + +typedef enum +{ + CR_NONE = 0, + // The generic case is suitable for most objects. + CR_GENERIC, + // Tails carry. + CR_PLAYER, + // NiGHTS mode. Not technically a CARRYING, but doesn't stack with any of the others, so might as well go here. + CR_NIGHTSMODE, + CR_NIGHTSFALL, + // Old Brak sucks hard, but this gimmick could be used for something better, so we might as well continue supporting it. + CR_BRAKGOOP, + // Specific level gimmicks. + CR_ZOOMTUBE, + CR_ROPEHANG, + CR_MACESPIN, + CR_MINECART +} carrytype_t; // pw_carry // Player powers. (don't edit this comment) typedef enum @@ -198,10 +243,12 @@ typedef enum pw_sneakers, pw_flashing, pw_shield, + pw_carry, pw_tailsfly, // tails flying pw_underwater, // underwater timer pw_spacetime, // In space, no one can hear you spin! pw_extralife, // Extra Life timer + pw_pushing, pw_super, // Are you super? pw_gravityboots, // gravity boots @@ -223,9 +270,7 @@ typedef enum pw_nights_helper, pw_nights_linkfreeze, - //for linedef exec 427 - pw_nocontrol, - pw_ingoop, // In goop + pw_nocontrol, //for linedef exec 427 NUMPOWERS } powertype_t; @@ -261,6 +306,8 @@ typedef struct player_s playerstate_t playerstate; // Determine POV, including viewpoint bobbing during movement. + fixed_t camerascale; + fixed_t shieldscale; // Focal origin above r.z fixed_t viewz; // Base height above floor for viewz. @@ -274,10 +321,12 @@ typedef struct player_s // It is updated with cmd->aiming. angle_t aiming; - // This is only used between levels, - // mo->health is used during levels. - /// \todo Remove this. We don't need a second health definition for players. - INT32 health; + // fun thing for player sprite + angle_t drawangle; + + // player's ring count + INT16 rings; + INT16 spheres; SINT8 pity; // i pity the fool. INT32 currentweapon; // current weapon selected. @@ -301,10 +350,10 @@ typedef struct player_s UINT8 skincolor; INT32 skin; + UINT32 availabilities; UINT32 score; // player score fixed_t dashspeed; // dashing speed - INT32 dashtime; // tics dashing, used for rev sound fixed_t normalspeed; // Normal ground fixed_t runspeed; // Speed you break into the run animation @@ -322,6 +371,8 @@ typedef struct player_s mobjtype_t thokitem; // Object # to spawn for the thok mobjtype_t spinitem; // Object # to spawn for spindash/spinning mobjtype_t revitem; // Object # to spawn for spindash/spinning + mobjtype_t followitem; // Object # to spawn for Smiles + mobj_t *followmobj; // Smiles all around fixed_t actionspd; // Speed of thok/glide/fly fixed_t mindash; // Minimum spindash speed @@ -329,15 +380,17 @@ typedef struct player_s fixed_t jumpfactor; // How high can the player jump? - SINT8 lives; + fixed_t height; // Bounding box changes. + fixed_t spinheight; + + SINT8 lives; // number of lives - if == INFLIVES, the player has infinite lives SINT8 continues; // continues that player has acquired SINT8 xtralife; // Ring Extra Life counter UINT8 gotcontinue; // Got continue from this stage? fixed_t speed; // Player's speed (distance formula of MOMX and MOMY values) - UINT8 jumping; // Jump counter - UINT8 secondjump; + UINT8 secondjump; // Jump counter UINT8 fly1; // Tails flying UINT8 scoreadd; // Used for multiple enemy attack bonus @@ -347,6 +400,7 @@ typedef struct player_s tic_t exiting; // Exitlevel timer UINT8 homing; // Are you homing? + tic_t dashmode; // counter for dashmode ability tic_t skidtime; // Skid timer @@ -402,16 +456,28 @@ typedef struct player_s UINT8 drilldelay; boolean bonustime; // Capsule destroyed, now it's bonus time! mobj_t *capsule; // Go inside the capsule + mobj_t *drone; // Move center to the drone + fixed_t oldscale; // Pre-Nightserize scale UINT8 mare; // Current mare + UINT8 marelap; // Current mare lap + UINT8 marebonuslap; // Current mare lap starting from bonus time // Statistical purposes. tic_t marebegunat; // Leveltime when mare begun tic_t startedtime; // Time which you started this mare with. tic_t finishedtime; // Time it took you to finish the mare (used for display) - INT16 finishedrings; // The rings you had left upon finishing the mare + tic_t lapbegunat; // Leveltime when lap begun + tic_t lapstartedtime; // Time which you started this lap with. + INT16 finishedspheres; // The spheres you had left upon finishing the mare + INT16 finishedrings; // The rings/stars you had left upon finishing the mare UINT32 marescore; // score for this nights stage UINT32 lastmarescore; // score for the last mare + UINT32 totalmarescore; // score for all mares UINT8 lastmare; // previous mare + UINT8 lastmarelap; // previous mare lap + UINT8 lastmarebonuslap; // previous mare bonus lap + UINT8 totalmarelap; // total mare lap + UINT8 totalmarebonuslap; // total mare bonus lap INT32 maxlink; // maximum link obtained UINT8 texttimer; // nights_texttime should not be local UINT8 textvar; // which line of NiGHTS text to show -- let's not use cheap hacks @@ -428,6 +494,7 @@ typedef struct player_s angle_t awayviewaiming; // Used for cut-away view boolean spectator; + boolean outofcoop; UINT8 bot; tic_t jointime; // Timer when player joins game to change skin/color @@ -436,4 +503,7 @@ typedef struct player_s #endif } player_t; +// Value for infinite lives +#define INFLIVES 0x7F + #endif diff --git a/src/dehacked.c b/src/dehacked.c index bda0c38f73a73a7682424eab7ddb284d49386b22..8057f26d8eccd24485bc1f21de404e99bf6ae7bb 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -66,11 +66,13 @@ memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\ static mobjtype_t get_mobjtype(const char *word); static statenum_t get_state(const char *word); static spritenum_t get_sprite(const char *word); +static playersprite_t get_sprite2(const char *word); static sfxenum_t get_sfx(const char *word); #ifdef MUSICSLOT_COMPATIBILITY static UINT16 get_mus(const char *word, UINT8 dehacked_mode); #endif static hudnum_t get_huditem(const char *word); +static menutype_t get_menutype(const char *word); #ifndef HAVE_BLUA static powertype_t get_power(const char *word); #endif @@ -79,97 +81,8 @@ boolean deh_loaded = false; static int dbg_line; static boolean gamedataadded = false; - -#ifdef DELFILE -typedef struct undehacked_s -{ - char *undata; - struct undehacked_s *next; -} undehacked_t; - -static UINT16 unsocwad; -static undehacked_t *unsocdata[MAX_WADFILES]; -static boolean disableundo = false; - -void DEH_WriteUndoline(const char *value, const char *data, undotype_f flags) -{ - const char *eqstr = " = "; - const char *space = " "; - const char *pader = eqstr; - undehacked_t *newdata; - - if (disableundo || !unsocwad) - return; - - if ((newdata = malloc(sizeof(*newdata))) == NULL) - I_Error("Out of memory for unsoc line"); - - if (flags & UNDO_SPACE) - pader = space; - - if (flags & UNDO_ENDTEXT && !data) - data = space; - - if (value) - { - const size_t plen = strlen(pader); - const char *pound = "#"; - char *undata = NULL; - const size_t elen = strlen(pound); - size_t vlen = strlen(value), dlen = 0, len = 1; - - if (*(value+vlen-1) == '\n') - vlen--; // lnet not copy the ending \n - - if (flags & UNDO_ENDTEXT) - len += elen; // let malloc more space - - if (flags & UNDO_NEWLINE) - len++; // more space for the beginning \n - - if (data) - { - dlen = strlen(data); - if (flags & UNDO_CUTLINE && *(data+dlen-1) == '\n') - dlen--; // let not copy the ending \n - newdata->undata = malloc(vlen+plen+dlen+len); - newdata->undata[vlen+plen+dlen+len-1] = '\0'; - } - else - { - newdata->undata = malloc(vlen+len); - newdata->undata[vlen+len-1] = '\0'; - } - - if (newdata->undata) - { - undata = newdata->undata; - *undata = '\0'; - } - else - { - free(newdata); - I_Error("Out of memory for unsoc data"); - } - - if (flags & UNDO_NEWLINE) // let start with \n - strcat(undata, "\n"); - - strncat(undata, value, vlen); - - if (data) // value+pader+data - strncat(strncat(undata, pader, plen), data, dlen); - - if (flags & UNDO_ENDTEXT) // let end the text - strncat(undata, pound, elen); - } - else - newdata->undata = NULL; - - newdata->next = unsocdata[unsocwad]; - unsocdata[unsocwad] = newdata; -} -#endif +static boolean titlechanged = false; +static boolean introchanged = false; ATTRINLINE static FUNCINLINE char myfget_color(MYFILE *f) { @@ -254,9 +167,14 @@ static char *myhashfgets(char *buf, size_t bufsize, MYFILE *f) if (c == '\n') // Ensure debug line is right... dbg_line++; if (c == '#') + { + if (i > 0) // don't let i wrap past 0 + i--; // don't include hash char in string break; + } } - i++; + if (buf[i] != '#') // don't include hash char in string + i++; buf[i] = '\0'; return buf; @@ -373,7 +291,9 @@ static void clear_levels(void) // (no need to set num to 0, we're freeing the entire header shortly) Z_Free(mapheaderinfo[i]->customopts); + P_DeleteFlickies(i); P_DeleteGrades(i); + Z_Free(mapheaderinfo[i]); mapheaderinfo[i] = NULL; } @@ -382,68 +302,20 @@ static void clear_levels(void) P_AllocMapHeader(gamemap-1); } -/* -// Edits an animated texture slot on the array -// Tails 12-27-2003 -static void readAnimTex(MYFILE *f, INT32 num) -{ - char s[MAXLINELEN]; - char *word; - char *word2; - INT32 i; - - do { - if (myfgets(s, sizeof s, f) != NULL) - { - if (s[0] == '\n') break; - - tmp = strchr(s, '#'); - if (tmp) - *tmp = '\0'; - // set the value in the appropriate field - - word = strtok(s, " "); - if (word) - strupr(word); - else - break; - - word2 = strtok(NULL, " = "); - if (word2) - strupr(word2); - else - break; - - if (word2[strlen(word2)-1] == '\n') - word2[strlen(word2)-1] = '\0'; - - i = atoi(word2); - - if (fastcmp(word, "START")) - strncpy(harddefs[num].startname, word2, 8); - if (fastcmp(word, "END")) - strncpy(harddefs[num].endname, word2, 8); - else if (fastcmp(word, "SPEED")) harddefs[num].speed = i; - else if (fastcmp(word, "ISTEXTURE")) harddefs[num].istexture = i; - - else deh_warning("readAnimTex %d: unknown word '%s'", num, word); - } - } while (s[0] != '\n' && !myfeof(f)); //finish when the line is empty -} -*/ - static boolean findFreeSlot(INT32 *num) { // Send the character select entry to a free slot. - while (*num < MAXSKINS && PlayerMenu[*num].status != IT_DISABLED) + while (*num < MAXSKINS && (description[*num].used)) *num = *num+1; // No more free slots. :( if (*num >= MAXSKINS) return false; + description[*num].picname[0] = '\0'; // Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...) + // Found one! ^_^ - return true; + return (description[*num].used = true); } // Reads a player. @@ -456,8 +328,6 @@ static void readPlayer(MYFILE *f, INT32 num) INT32 i; boolean slotfound = false; - DEH_WriteUndoline("PLAYERTEXT", description[num].notes, UNDO_ENDTEXT); - do { if (myfgets(s, MAXLINELEN, f)) @@ -477,7 +347,6 @@ static void readPlayer(MYFILE *f, INT32 num) if (!slotfound && (slotfound = findFreeSlot(&num)) == false) goto done; - PlayerMenu[num].status = IT_CALL; for (i = 0; i < MAXLINELEN-3; i++) { @@ -523,66 +392,32 @@ static void readPlayer(MYFILE *f, INT32 num) word2[strlen(word2)-1] = '\0'; i = atoi(word2); - /*if (fastcmp(word, "PLAYERNAME")) - { - if (!slotfound && (slotfound = findFreeSlot(&num)) == false) - goto done; - DEH_WriteUndoline(word, description[num].text, UNDO_NONE); - strlcpy(description[num].text, word2, sizeof (description[num].text)); - for (word2 = description[num].text; *word2; word2++) - if (*word2 == '_') - *word2 = ' '; - PlayerMenu[num].text = description[num].text; - }*/ -/* else if (fastcmp(word, "MENUPOSITION")) - { // Make sure you make MENUPOSITION the first thing under CHARACTER if you're using it! - // This is to manually choose a slot and overwrite existing characters! It is NOT necessary for most individual character wads!! -#ifdef DELFILE - if (disableundo) -#endif - { - slotfound = true; - num = i; - } - } */ - /*else*/ if (fastcmp(word, "PICNAME")) + if (fastcmp(word, "PICNAME")) { if (!slotfound && (slotfound = findFreeSlot(&num)) == false) goto done; - DEH_WriteUndoline(word, &description[num].picname[0], UNDO_NONE); - PlayerMenu[num].status = IT_CALL; + strncpy(description[num].picname, word2, 8); } else if (fastcmp(word, "STATUS")) { - // Limit the status to only IT_DISABLED and IT_CALL - if (i) - i = IT_CALL; - else - i = IT_DISABLED; - /* You MAY disable previous entries if you so desire... But try to enable something that's already enabled and you will be sent to a free slot. - Because of this, you are allowed to edit any previous entrys you like, but only if you + Because of this, you are allowed to edit any previous entries you like, but only if you signal that you are purposely doing so by disabling and then reenabling the slot. - - ... Or use MENUPOSITION first, that works too. Hell, you could edit multiple character - slots in a single section that way, due to how SOC editing works. */ - if (i != IT_DISABLED && !slotfound && (slotfound = findFreeSlot(&num)) == false) + if (i && !slotfound && (slotfound = findFreeSlot(&num)) == false) goto done; - DEH_WriteUndoline(word, va("%d", PlayerMenu[num].status), UNDO_NONE); - PlayerMenu[num].status = (INT16)i; + + description[num].used = (!!i); } else if (fastcmp(word, "SKINNAME")) { // Send to free slot. if (!slotfound && (slotfound = findFreeSlot(&num)) == false) goto done; - DEH_WriteUndoline(word, description[num].skinname, UNDO_NONE); - PlayerMenu[num].status = IT_CALL; strlcpy(description[num].skinname, word2, sizeof description[num].skinname); strlwr(description[num].skinname); @@ -592,11 +427,6 @@ static void readPlayer(MYFILE *f, INT32 num) } } while (!myfeof(f)); // finish when the line is empty -#ifdef DELFILE - if (slotfound) - DEH_WriteUndoline("MENUPOSITION", va("%d", num), UNDO_NONE); -#endif - done: Z_Free(s); } @@ -675,6 +505,22 @@ static void readfreeslots(MYFILE *f) break; } } + else if (fastcmp(type, "SPR2")) + { + // Search if we already have an SPR2 by that name... + for (i = SPR2_FIRSTFREESLOT; i < (int)free_spr2; i++) + if (memcmp(spr2names[i],word,4) == 0) + break; + // We found it? (Two mods using the same SPR2 name?) Then don't allocate another one. + if (i < (int)free_spr2) + continue; + // Copy in the spr2 name and increment free_spr2. + if (free_spr2 < NUMPLAYERSPRITES) { + strncpy(spr2names[free_spr2],word,4); + spr2names[free_spr2++][4] = 0; + } else + CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n"); + } else deh_warning("Freeslots: unknown enum class '%s' for '%s_%s'", type, type, word); } @@ -718,122 +564,98 @@ static void readthing(MYFILE *f, INT32 num) if (fastcmp(word, "MAPTHINGNUM") || fastcmp(word, "DOOMEDNUM")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].doomednum), UNDO_NONE); mobjinfo[num].doomednum = (INT32)atoi(word2); } else if (fastcmp(word, "SPAWNSTATE")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].spawnstate), UNDO_NONE); mobjinfo[num].spawnstate = get_number(word2); } else if (fastcmp(word, "SPAWNHEALTH")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].spawnhealth), UNDO_NONE); mobjinfo[num].spawnhealth = (INT32)get_number(word2); } else if (fastcmp(word, "SEESTATE")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].seestate), UNDO_NONE); mobjinfo[num].seestate = get_number(word2); } else if (fastcmp(word, "SEESOUND")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].seesound), UNDO_NONE); mobjinfo[num].seesound = get_number(word2); } else if (fastcmp(word, "REACTIONTIME")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].reactiontime), UNDO_NONE); mobjinfo[num].reactiontime = (INT32)get_number(word2); } else if (fastcmp(word, "ATTACKSOUND")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].attacksound), UNDO_NONE); mobjinfo[num].attacksound = get_number(word2); } else if (fastcmp(word, "PAINSTATE")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].painstate), UNDO_NONE); mobjinfo[num].painstate = get_number(word2); } else if (fastcmp(word, "PAINCHANCE")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].painchance), UNDO_NONE); mobjinfo[num].painchance = (INT32)get_number(word2); } else if (fastcmp(word, "PAINSOUND")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].painsound), UNDO_NONE); mobjinfo[num].painsound = get_number(word2); } else if (fastcmp(word, "MELEESTATE")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].meleestate), UNDO_NONE); mobjinfo[num].meleestate = get_number(word2); } else if (fastcmp(word, "MISSILESTATE")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].missilestate), UNDO_NONE); mobjinfo[num].missilestate = get_number(word2); } else if (fastcmp(word, "DEATHSTATE")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].deathstate), UNDO_NONE); mobjinfo[num].deathstate = get_number(word2); } else if (fastcmp(word, "DEATHSOUND")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].deathsound), UNDO_NONE); mobjinfo[num].deathsound = get_number(word2); } else if (fastcmp(word, "XDEATHSTATE")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].xdeathstate), UNDO_NONE); mobjinfo[num].xdeathstate = get_number(word2); } else if (fastcmp(word, "SPEED")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].speed), UNDO_NONE); mobjinfo[num].speed = get_number(word2); } else if (fastcmp(word, "RADIUS")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].radius), UNDO_NONE); mobjinfo[num].radius = get_number(word2); } else if (fastcmp(word, "HEIGHT")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].height), UNDO_NONE); mobjinfo[num].height = get_number(word2); } else if (fastcmp(word, "DISPOFFSET")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].dispoffset), UNDO_NONE); mobjinfo[num].dispoffset = get_number(word2); } else if (fastcmp(word, "MASS")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].mass), UNDO_NONE); mobjinfo[num].mass = (INT32)get_number(word2); } else if (fastcmp(word, "DAMAGE")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].damage), UNDO_NONE); mobjinfo[num].damage = (INT32)get_number(word2); } else if (fastcmp(word, "ACTIVESOUND")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].activesound), UNDO_NONE); mobjinfo[num].activesound = get_number(word2); } else if (fastcmp(word, "FLAGS")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].flags), UNDO_NONE); mobjinfo[num].flags = (INT32)get_number(word2); } else if (fastcmp(word, "RAISESTATE")) { - DEH_WriteUndoline(word, va("%d", mobjinfo[num].raisestate), UNDO_NONE); mobjinfo[num].raisestate = get_number(word2); } else @@ -877,37 +699,30 @@ static void readlight(MYFILE *f, INT32 num) if (fastcmp(word, "TYPE")) { - DEH_WriteUndoline(word, va("%d", lspr[num].type), UNDO_NONE); lspr[num].type = (UINT16)value; } else if (fastcmp(word, "OFFSETX")) { - DEH_WriteUndoline(word, va("%f", lspr[num].light_xoffset), UNDO_NONE); lspr[num].light_xoffset = fvalue; } else if (fastcmp(word, "OFFSETY")) { - DEH_WriteUndoline(word, va("%f", lspr[num].light_yoffset), UNDO_NONE); lspr[num].light_yoffset = fvalue; } else if (fastcmp(word, "CORONACOLOR")) { - DEH_WriteUndoline(word, va("%u", lspr[num].corona_color), UNDO_NONE); lspr[num].corona_color = value; } else if (fastcmp(word, "CORONARADIUS")) { - DEH_WriteUndoline(word, va("%f", lspr[num].corona_radius), UNDO_NONE); lspr[num].corona_radius = fvalue; } else if (fastcmp(word, "DYNAMICCOLOR")) { - DEH_WriteUndoline(word, va("%u", lspr[num].dynamic_color), UNDO_NONE); lspr[num].dynamic_color = value; } else if (fastcmp(word, "DYNAMICRADIUS")) { - DEH_WriteUndoline(word, va("%f", lspr[num].dynamic_radius), UNDO_NONE); lspr[num].dynamic_radius = fvalue; /// \note Update the sqrradius! unnecessary? @@ -954,7 +769,6 @@ static void readspritelight(MYFILE *f, INT32 num) INT32 oldvar; for (oldvar = 0; t_lspr[num] != &lspr[oldvar]; oldvar++) ; - DEH_WriteUndoline(word, va("%d", oldvar), UNDO_NONE); t_lspr[num] = &lspr[value]; } else @@ -966,6 +780,49 @@ static void readspritelight(MYFILE *f, INT32 num) } #endif // HWRENDER +static void readsprite2(MYFILE *f, INT32 num) +{ + char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); + char *word, *word2; + char *tmp; + + do + { + if (myfgets(s, MAXLINELEN, f)) + { + if (s[0] == '\n') + break; + + tmp = strchr(s, '#'); + if (tmp) + *tmp = '\0'; + if (s == tmp) + continue; // Skip comment lines, but don't break. + + word = strtok(s, " "); + if (word) + strupr(word); + else + break; + + word2 = strtok(NULL, " = "); + if (word2) + strupr(word2); + else + break; + if (word2[strlen(word2)-1] == '\n') + word2[strlen(word2)-1] = '\0'; + + if (fastcmp(word, "DEFAULT")) + spr2defaults[num] = get_number(word2); + else + deh_warning("Sprite2 %s: unknown word '%s'", spr2names[num], word); + } + } while (!myfeof(f)); // finish when the line is empty + + Z_Free(s); +} + static const struct { const char *name; const UINT16 flag; @@ -999,6 +856,36 @@ static const struct { {NULL, 0} }; +static const struct { + const char *name; + const mobjtype_t type; +} FLICKYTYPES[] = { + {"BLUEBIRD", MT_FLICKY_01}, // Flicky (Flicky) + {"RABBIT", MT_FLICKY_02}, // Pocky (1) + {"CHICKEN", MT_FLICKY_03}, // Cucky (1) + {"SEAL", MT_FLICKY_04}, // Rocky (1) + {"PIG", MT_FLICKY_05}, // Picky (1) + {"CHIPMUNK", MT_FLICKY_06}, // Ricky (1) + {"PENGUIN", MT_FLICKY_07}, // Pecky (1) + {"FISH", MT_FLICKY_08}, // Nicky (CD) + {"RAM", MT_FLICKY_09}, // Flocky (CD) + {"PUFFIN", MT_FLICKY_10}, // Wicky (CD) + {"COW", MT_FLICKY_11}, // Macky (SRB2) + {"RAT", MT_FLICKY_12}, // Micky (2) + {"BEAR", MT_FLICKY_13}, // Becky (2) + {"DOVE", MT_FLICKY_14}, // Docky (CD) + {"CAT", MT_FLICKY_15}, // Nyannyan (Flicky) + {"CANARY", MT_FLICKY_16}, // Lucky (CD) + {"a", 0}, // End of normal flickies - a lower case character so will never fastcmp valid with uppercase tmp + //{"FLICKER", MT_FLICKER}, // Flacky (SRB2) + {"SPIDER", MT_SECRETFLICKY_01}, // Sticky (SRB2) + {"BAT", MT_SECRETFLICKY_02}, // Backy (SRB2) + {"SEED", MT_SEED}, // Seed (CD) + {NULL, 0} +}; + +#define MAXFLICKIES 64 + static void readlevelheader(MYFILE *f, INT32 num) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); @@ -1009,8 +896,6 @@ static void readlevelheader(MYFILE *f, INT32 num) INT32 i; // Reset all previous map header information - // This call automatically saves all previous information when DELFILE is defined. - // We don't need to do it ourselves. P_AllocMapHeader((INT16)(num-1)); do @@ -1100,8 +985,82 @@ static void readlevelheader(MYFILE *f, INT32 num) // Now go to uppercase strupr(word2); + // List of flickies that are be freed in this map + if (fastcmp(word, "FLICKYLIST") || fastcmp(word, "ANIMALLIST")) + { + if (fastcmp(word2, "NONE")) + P_DeleteFlickies(num-1); + else if (fastcmp(word2, "DEMO")) + P_SetDemoFlickies(num-1); + else if (fastcmp(word2, "ALL")) + { + mobjtype_t tmpflickies[MAXFLICKIES]; + + for (mapheaderinfo[num-1]->numFlickies = 0; + ((mapheaderinfo[num-1]->numFlickies < MAXFLICKIES) && FLICKYTYPES[mapheaderinfo[num-1]->numFlickies].type); + mapheaderinfo[num-1]->numFlickies++) + tmpflickies[mapheaderinfo[num-1]->numFlickies] = FLICKYTYPES[mapheaderinfo[num-1]->numFlickies].type; + + if (mapheaderinfo[num-1]->numFlickies) // just in case... + { + size_t newsize = sizeof(mobjtype_t) * mapheaderinfo[num-1]->numFlickies; + mapheaderinfo[num-1]->flickies = Z_Realloc(mapheaderinfo[num-1]->flickies, newsize, PU_STATIC, NULL); + M_Memcpy(mapheaderinfo[num-1]->flickies, tmpflickies, newsize); + } + } + else + { + mobjtype_t tmpflickies[MAXFLICKIES]; + mapheaderinfo[num-1]->numFlickies = 0; + tmp = strtok(word2,","); + // get up to the first MAXFLICKIES flickies + do { + if (mapheaderinfo[num-1]->numFlickies == MAXFLICKIES) // never going to get above that number + { + deh_warning("Level header %d: too many flickies\n", num); + break; + } + + if (fastncmp(tmp, "MT_", 3)) // support for specified mobjtypes... + { + i = get_mobjtype(tmp); + if (!i) + { + //deh_warning("Level header %d: unknown flicky mobj type %s\n", num, tmp); -- no need for this line as get_mobjtype complains too + continue; + } + tmpflickies[mapheaderinfo[num-1]->numFlickies] = i; + } + else // ...or a quick, limited selection of default flickies! + { + for (i = 0; FLICKYTYPES[i].name; i++) + if (fastcmp(tmp, FLICKYTYPES[i].name)) + break; + + if (!FLICKYTYPES[i].name) + { + deh_warning("Level header %d: unknown flicky selection %s\n", num, tmp); + continue; + } + tmpflickies[mapheaderinfo[num-1]->numFlickies] = FLICKYTYPES[i].type; + } + mapheaderinfo[num-1]->numFlickies++; + } while ((tmp = strtok(NULL,",")) != NULL); + + if (mapheaderinfo[num-1]->numFlickies) + { + size_t newsize = sizeof(mobjtype_t) * mapheaderinfo[num-1]->numFlickies; + mapheaderinfo[num-1]->flickies = Z_Realloc(mapheaderinfo[num-1]->flickies, newsize, PU_STATIC, NULL); + // now we add them to the list! + M_Memcpy(mapheaderinfo[num-1]->flickies, tmpflickies, newsize); + } + else + deh_warning("Level header %d: no valid flicky types found\n", num); + } + } + // NiGHTS grades - if (fastncmp(word, "GRADES", 6)) + else if (fastncmp(word, "GRADES", 6)) { UINT8 mare = (UINT8)atoi(word + 6); @@ -1119,6 +1078,12 @@ static void readlevelheader(MYFILE *f, INT32 num) { deh_strlcpy(mapheaderinfo[num-1]->lvlttl, word2, sizeof(mapheaderinfo[num-1]->lvlttl), va("Level header %d: levelname", num)); + strlcpy(mapheaderinfo[num-1]->selectheading, word2, sizeof(mapheaderinfo[num-1]->selectheading)); // not deh_ so only complains once + } + else if (fastcmp(word, "SELECTHEADING")) + { + deh_strlcpy(mapheaderinfo[num-1]->selectheading, word2, + sizeof(mapheaderinfo[num-1]->selectheading), va("Level header %d: selectheading", num)); } else if (fastcmp(word, "SCRIPTNAME")) { @@ -1248,25 +1213,17 @@ static void readlevelheader(MYFILE *f, INT32 num) else if (fastcmp(word2, "NORMAL")) i = 0; else if (fastcmp(word2, "BOSS")) i = 1; else if (fastcmp(word2, "ERZ3")) i = 2; + else if (fastcmp(word2, "NIGHTS")) i = 3; + else if (fastcmp(word2, "NIGHTSLINK")) i = 4; - if (i >= -1 && i <= 2) // -1 for no bonus. Max is 2. + if (i >= -1 && i <= 4) // -1 for no bonus. Max is 4. mapheaderinfo[num-1]->bonustype = (SINT8)i; else deh_warning("Level header %d: invalid bonus type number %d", num, i); } - else if (fastcmp(word, "SAVEOVERRIDE")) - { - if (fastcmp(word2, "DEFAULT")) i = SAVE_DEFAULT; - else if (fastcmp(word2, "ALWAYS")) i = SAVE_ALWAYS; - else if (fastcmp(word2, "NEVER")) i = SAVE_NEVER; - - if (i >= SAVE_NEVER && i <= SAVE_ALWAYS) - mapheaderinfo[num-1]->saveoverride = (SINT8)i; - else - deh_warning("Level header %d: invalid save override number %d", num, i); - } - + else if (fastcmp(word, "MAXBONUSLIVES")) + mapheaderinfo[num-1]->maxbonuslives = (SINT8)i; else if (fastcmp(word, "LEVELFLAGS")) mapheaderinfo[num-1]->levelflags = (UINT8)i; else if (fastcmp(word, "MENUFLAGS")) @@ -1308,6 +1265,20 @@ static void readlevelheader(MYFILE *f, INT32 num) else mapheaderinfo[num-1]->levelflags &= ~LF_NOZONE; } + else if (fastcmp(word, "SAVEGAME")) + { + if (i || word2[0] == 'T' || word2[0] == 'Y') + mapheaderinfo[num-1]->levelflags |= LF_SAVEGAME; + else + mapheaderinfo[num-1]->levelflags &= ~LF_SAVEGAME; + } + else if (fastcmp(word, "MIXNIGHTSCOUNTDOWN")) + { + if (i || word2[0] == 'T' || word2[0] == 'Y') + mapheaderinfo[num-1]->levelflags |= LF_MIXNIGHTSCOUNTDOWN; + else + mapheaderinfo[num-1]->levelflags &= ~LF_MIXNIGHTSCOUNTDOWN; + } // Individual triggers for menu flags else if (fastcmp(word, "HIDDEN")) @@ -1345,6 +1316,15 @@ static void readlevelheader(MYFILE *f, INT32 num) else mapheaderinfo[num-1]->menuflags &= ~LF2_NOVISITNEEDED; } + else if (fastcmp(word, "WIDEICON")) + { + if (i || word2[0] == 'T' || word2[0] == 'Y') + mapheaderinfo[num-1]->menuflags |= LF2_WIDEICON; + else + mapheaderinfo[num-1]->menuflags &= ~LF2_WIDEICON; + } + else if (fastcmp(word, "STARTRINGS")) + mapheaderinfo[num-1]->startrings = (UINT16)i; else deh_warning("Level header %d: unknown word '%s'", num, word); } @@ -1353,6 +1333,8 @@ static void readlevelheader(MYFILE *f, INT32 num) Z_Free(s); } +#undef MAXFLICKIES + static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) { char *s = Z_Calloc(MAXLINELEN, PU_STATIC, NULL); @@ -1362,8 +1344,6 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) UINT16 usi; UINT8 picid; - DEH_WriteUndoline("SCENETEXT", cutscenes[num]->scene[scenenum].text, UNDO_ENDTEXT); - do { if (myfgets(s, MAXLINELEN, f)) @@ -1440,7 +1420,6 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) if (fastcmp(word, "NUMBEROFPICS")) { - DEH_WriteUndoline(word, va("%d", cutscenes[num]->scene[scenenum].numpics), UNDO_NONE); cutscenes[num]->scene[scenenum].numpics = (UINT8)i; } else if (fastncmp(word, "PIC", 3)) @@ -1455,27 +1434,22 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) if (fastcmp(word+4, "NAME")) { - DEH_WriteUndoline(word, cutscenes[num]->scene[scenenum].picname[picid], UNDO_NONE); strncpy(cutscenes[num]->scene[scenenum].picname[picid], word2, 8); } else if (fastcmp(word+4, "HIRES")) { - DEH_WriteUndoline(word, va("%d", cutscenes[num]->scene[scenenum].pichires[picid]), UNDO_NONE); cutscenes[num]->scene[scenenum].pichires[picid] = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y'); } else if (fastcmp(word+4, "DURATION")) { - DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].picduration[picid]), UNDO_NONE); cutscenes[num]->scene[scenenum].picduration[picid] = usi; } else if (fastcmp(word+4, "XCOORD")) { - DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].xcoord[picid]), UNDO_NONE); cutscenes[num]->scene[scenenum].xcoord[picid] = usi; } else if (fastcmp(word+4, "YCOORD")) { - DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].ycoord[picid]), UNDO_NONE); cutscenes[num]->scene[scenenum].ycoord[picid] = usi; } else @@ -1483,14 +1457,12 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) } else if (fastcmp(word, "MUSIC")) { - DEH_WriteUndoline(word, cutscenes[num]->scene[scenenum].musswitch, UNDO_NONE); strncpy(cutscenes[num]->scene[scenenum].musswitch, word2, 7); cutscenes[num]->scene[scenenum].musswitch[6] = 0; } #ifdef MUSICSLOT_COMPATIBILITY else if (fastcmp(word, "MUSICSLOT")) { - DEH_WriteUndoline(word, cutscenes[num]->scene[scenenum].musswitch, UNDO_NONE); i = get_mus(word2, true); if (i && i <= 1035) snprintf(cutscenes[num]->scene[scenenum].musswitch, 7, "%sM", G_BuildMapName(i)); @@ -1503,42 +1475,34 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) #endif else if (fastcmp(word, "MUSICTRACK")) { - DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musswitchflags), UNDO_NONE); cutscenes[num]->scene[scenenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK; } else if (fastcmp(word, "MUSICPOS")) { - DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musswitchposition), UNDO_NONE); cutscenes[num]->scene[scenenum].musswitchposition = (UINT32)get_number(word2); } else if (fastcmp(word, "MUSICLOOP")) { - DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musicloop), UNDO_NONE); cutscenes[num]->scene[scenenum].musicloop = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y'); } else if (fastcmp(word, "TEXTXPOS")) { - DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].textxpos), UNDO_NONE); cutscenes[num]->scene[scenenum].textxpos = usi; } else if (fastcmp(word, "TEXTYPOS")) { - DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].textypos), UNDO_NONE); cutscenes[num]->scene[scenenum].textypos = usi; } else if (fastcmp(word, "FADEINID")) { - DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].fadenum), UNDO_NONE); cutscenes[num]->scene[scenenum].fadeinid = (UINT8)i; } else if (fastcmp(word, "FADEOUTID")) { - DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].fadenum), UNDO_NONE); cutscenes[num]->scene[scenenum].fadeoutid = (UINT8)i; } else if (fastcmp(word, "FADECOLOR")) { - DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].fadenum), UNDO_NONE); cutscenes[num]->scene[scenenum].fadecolor = (UINT8)i; } else @@ -1556,9 +1520,6 @@ static void readcutscene(MYFILE *f, INT32 num) char *word2; char *tmp; INT32 value; -#ifdef DELFILE - const INT32 oldnumscenes = cutscenes[num]->numscenes; -#endif // Allocate memory for this cutscene if we don't yet have any if (!cutscenes[num]) @@ -1601,8 +1562,6 @@ static void readcutscene(MYFILE *f, INT32 num) if (1 <= value && value <= 128) { readcutscenescene(f, num, value - 1); - DEH_WriteUndoline(word, word2, UNDO_SPACE|UNDO_CUTLINE); - DEH_WriteUndoline("NUMSCENES", va("%d", oldnumscenes), UNDO_SPACE); } else deh_warning("Scene number %d out of range (1 - 128)", value); @@ -1616,6 +1575,528 @@ static void readcutscene(MYFILE *f, INT32 num) Z_Free(s); } +static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) +{ + char *s = Z_Calloc(MAXLINELEN, PU_STATIC, NULL); + char *word; + char *word2; + INT32 i; + UINT16 usi; + UINT8 picid; + + do + { + if (myfgets(s, MAXLINELEN, f)) + { + if (s[0] == '\n') + break; + + word = strtok(s, " "); + if (word) + strupr(word); + else + break; + + if (fastcmp(word, "PAGETEXT")) + { + char *pagetext = NULL; + char *buffer; + const int bufferlen = 4096; + + for (i = 0; i < MAXLINELEN; i++) + { + if (s[i] == '=') + { + pagetext = &s[i+2]; + break; + } + } + + if (!pagetext) + { + Z_Free(textprompts[num]->page[pagenum].text); + textprompts[num]->page[pagenum].text = NULL; + continue; + } + + for (i = 0; i < MAXLINELEN; i++) + { + if (s[i] == '\0') + { + s[i] = '\n'; + s[i+1] = '\0'; + break; + } + } + + buffer = Z_Malloc(4096, PU_STATIC, NULL); + strcpy(buffer, pagetext); + + // \todo trim trailing whitespace before the # + // and also support # at the end of a PAGETEXT with no line break + + strcat(buffer, + myhashfgets(pagetext, bufferlen + - strlen(buffer) - 1, f)); + + // A text prompt overwriting another one... + Z_Free(textprompts[num]->page[pagenum].text); + + textprompts[num]->page[pagenum].text = Z_StrDup(buffer); + + Z_Free(buffer); + + continue; + } + + word2 = strtok(NULL, " = "); + if (word2) + strupr(word2); + else + break; + + if (word2[strlen(word2)-1] == '\n') + word2[strlen(word2)-1] = '\0'; + i = atoi(word2); + usi = (UINT16)i; + + // copypasta from readcutscenescene + if (fastcmp(word, "NUMBEROFPICS")) + { + textprompts[num]->page[pagenum].numpics = (UINT8)i; + } + else if (fastcmp(word, "PICMODE")) + { + UINT8 picmode = 0; // PROMPT_PIC_PERSIST + if (usi == 1 || word2[0] == 'L') picmode = PROMPT_PIC_LOOP; + else if (usi == 2 || word2[0] == 'D' || word2[0] == 'H') picmode = PROMPT_PIC_DESTROY; + textprompts[num]->page[pagenum].picmode = picmode; + } + else if (fastcmp(word, "PICTOLOOP")) + textprompts[num]->page[pagenum].pictoloop = (UINT8)i; + else if (fastcmp(word, "PICTOSTART")) + textprompts[num]->page[pagenum].pictostart = (UINT8)i; + else if (fastcmp(word, "PICSMETAPAGE")) + { + if (usi && usi <= textprompts[num]->numpages) + { + UINT8 metapagenum = usi - 1; + + textprompts[num]->page[pagenum].numpics = textprompts[num]->page[metapagenum].numpics; + textprompts[num]->page[pagenum].picmode = textprompts[num]->page[metapagenum].picmode; + textprompts[num]->page[pagenum].pictoloop = textprompts[num]->page[metapagenum].pictoloop; + textprompts[num]->page[pagenum].pictostart = textprompts[num]->page[metapagenum].pictostart; + + for (picid = 0; picid < MAX_PROMPT_PICS; picid++) + { + strncpy(textprompts[num]->page[pagenum].picname[picid], textprompts[num]->page[metapagenum].picname[picid], 8); + textprompts[num]->page[pagenum].pichires[picid] = textprompts[num]->page[metapagenum].pichires[picid]; + textprompts[num]->page[pagenum].picduration[picid] = textprompts[num]->page[metapagenum].picduration[picid]; + textprompts[num]->page[pagenum].xcoord[picid] = textprompts[num]->page[metapagenum].xcoord[picid]; + textprompts[num]->page[pagenum].ycoord[picid] = textprompts[num]->page[metapagenum].ycoord[picid]; + } + } + } + else if (fastncmp(word, "PIC", 3)) + { + picid = (UINT8)atoi(word + 3); + if (picid > MAX_PROMPT_PICS || picid == 0) + { + deh_warning("textpromptscene %d: unknown word '%s'", num, word); + continue; + } + --picid; + + if (fastcmp(word+4, "NAME")) + { + strncpy(textprompts[num]->page[pagenum].picname[picid], word2, 8); + } + else if (fastcmp(word+4, "HIRES")) + { + textprompts[num]->page[pagenum].pichires[picid] = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y'); + } + else if (fastcmp(word+4, "DURATION")) + { + textprompts[num]->page[pagenum].picduration[picid] = usi; + } + else if (fastcmp(word+4, "XCOORD")) + { + textprompts[num]->page[pagenum].xcoord[picid] = usi; + } + else if (fastcmp(word+4, "YCOORD")) + { + textprompts[num]->page[pagenum].ycoord[picid] = usi; + } + else + deh_warning("textpromptscene %d: unknown word '%s'", num, word); + } + else if (fastcmp(word, "MUSIC")) + { + strncpy(textprompts[num]->page[pagenum].musswitch, word2, 7); + textprompts[num]->page[pagenum].musswitch[6] = 0; + } +#ifdef MUSICSLOT_COMPATIBILITY + else if (fastcmp(word, "MUSICSLOT")) + { + i = get_mus(word2, true); + if (i && i <= 1035) + snprintf(textprompts[num]->page[pagenum].musswitch, 7, "%sM", G_BuildMapName(i)); + else if (i && i <= 1050) + strncpy(textprompts[num]->page[pagenum].musswitch, compat_special_music_slots[i - 1036], 7); + else + textprompts[num]->page[pagenum].musswitch[0] = 0; // becomes empty string + textprompts[num]->page[pagenum].musswitch[6] = 0; + } +#endif + else if (fastcmp(word, "MUSICTRACK")) + { + textprompts[num]->page[pagenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK; + } + else if (fastcmp(word, "MUSICLOOP")) + { + textprompts[num]->page[pagenum].musicloop = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y'); + } + // end copypasta from readcutscenescene + else if (fastcmp(word, "NAME")) + { + INT32 j; + + // HACK: Add yellow control char now + // so the drawing function doesn't call it repeatedly + char name[34]; + name[0] = '\x82'; // color yellow + name[1] = 0; + strncat(name, word2, 33); + name[33] = 0; + + // Replace _ with ' ' + for (j = 0; j < 32 && name[j]; j++) + { + if (name[j] == '_') + name[j] = ' '; + } + + strncpy(textprompts[num]->page[pagenum].name, name, 32); + } + else if (fastcmp(word, "ICON")) + strncpy(textprompts[num]->page[pagenum].iconname, word2, 8); + else if (fastcmp(word, "ICONALIGN")) + textprompts[num]->page[pagenum].rightside = (i || word2[0] == 'R'); + else if (fastcmp(word, "ICONFLIP")) + textprompts[num]->page[pagenum].iconflip = (i || word2[0] == 'T' || word2[0] == 'Y'); + else if (fastcmp(word, "LINES")) + textprompts[num]->page[pagenum].lines = usi; + else if (fastcmp(word, "BACKCOLOR")) + { + INT32 backcolor; + if (i == 0 || fastcmp(word2, "WHITE")) backcolor = 0; + else if (i == 1 || fastcmp(word2, "GRAY") || fastcmp(word2, "GREY") || + fastcmp(word2, "BLACK")) backcolor = 1; + else if (i == 2 || fastcmp(word2, "SEPIA")) backcolor = 2; + else if (i == 3 || fastcmp(word2, "BROWN")) backcolor = 3; + else if (i == 4 || fastcmp(word2, "PINK")) backcolor = 4; + else if (i == 5 || fastcmp(word2, "RASPBERRY")) backcolor = 5; + else if (i == 6 || fastcmp(word2, "RED")) backcolor = 6; + else if (i == 7 || fastcmp(word2, "CREAMSICLE")) backcolor = 7; + else if (i == 8 || fastcmp(word2, "ORANGE")) backcolor = 8; + else if (i == 9 || fastcmp(word2, "GOLD")) backcolor = 9; + else if (i == 10 || fastcmp(word2, "YELLOW")) backcolor = 10; + else if (i == 11 || fastcmp(word2, "EMERALD")) backcolor = 11; + else if (i == 12 || fastcmp(word2, "GREEN")) backcolor = 12; + else if (i == 13 || fastcmp(word2, "CYAN") || fastcmp(word2, "AQUA")) backcolor = 13; + else if (i == 14 || fastcmp(word2, "STEEL")) backcolor = 14; + else if (i == 15 || fastcmp(word2, "PERIWINKLE")) backcolor = 15; + else if (i == 16 || fastcmp(word2, "BLUE")) backcolor = 16; + else if (i == 17 || fastcmp(word2, "PURPLE")) backcolor = 17; + else if (i == 18 || fastcmp(word2, "LAVENDER")) backcolor = 18; + else if (i < 0) backcolor = INT32_MAX; // CONS_BACKCOLOR user-configured + else backcolor = 1; // default gray + textprompts[num]->page[pagenum].backcolor = backcolor; + } + else if (fastcmp(word, "ALIGN")) + { + UINT8 align = 0; // left + if (usi == 1 || word2[0] == 'R') align = 1; + else if (usi == 2 || word2[0] == 'C' || word2[0] == 'M') align = 2; + textprompts[num]->page[pagenum].align = align; + } + else if (fastcmp(word, "VERTICALALIGN")) + { + UINT8 align = 0; // top + if (usi == 1 || word2[0] == 'B') align = 1; + else if (usi == 2 || word2[0] == 'C' || word2[0] == 'M') align = 2; + textprompts[num]->page[pagenum].verticalalign = align; + } + else if (fastcmp(word, "TEXTSPEED")) + textprompts[num]->page[pagenum].textspeed = get_number(word2); + else if (fastcmp(word, "TEXTSFX")) + textprompts[num]->page[pagenum].textsfx = get_number(word2); + else if (fastcmp(word, "HIDEHUD")) + { + UINT8 hidehud = 0; + if ((word2[0] == 'F' && (word2[1] == 'A' || !word2[1])) || word2[0] == 'N') hidehud = 0; // false + else if (usi == 1 || word2[0] == 'T' || word2[0] == 'Y') hidehud = 1; // true (hide appropriate HUD elements) + else if (usi == 2 || word2[0] == 'A' || (word2[0] == 'F' && word2[1] == 'O')) hidehud = 2; // force (hide all HUD elements) + textprompts[num]->page[pagenum].hidehud = hidehud; + } + else if (fastcmp(word, "METAPAGE")) + { + if (usi && usi <= textprompts[num]->numpages) + { + UINT8 metapagenum = usi - 1; + + strncpy(textprompts[num]->page[pagenum].name, textprompts[num]->page[metapagenum].name, 32); + strncpy(textprompts[num]->page[pagenum].iconname, textprompts[num]->page[metapagenum].iconname, 8); + textprompts[num]->page[pagenum].rightside = textprompts[num]->page[metapagenum].rightside; + textprompts[num]->page[pagenum].iconflip = textprompts[num]->page[metapagenum].iconflip; + textprompts[num]->page[pagenum].lines = textprompts[num]->page[metapagenum].lines; + textprompts[num]->page[pagenum].backcolor = textprompts[num]->page[metapagenum].backcolor; + textprompts[num]->page[pagenum].align = textprompts[num]->page[metapagenum].align; + textprompts[num]->page[pagenum].verticalalign = textprompts[num]->page[metapagenum].verticalalign; + textprompts[num]->page[pagenum].textspeed = textprompts[num]->page[metapagenum].textspeed; + textprompts[num]->page[pagenum].textsfx = textprompts[num]->page[metapagenum].textsfx; + textprompts[num]->page[pagenum].hidehud = textprompts[num]->page[metapagenum].hidehud; + + // music: don't copy, else each page change may reset the music + } + } + else if (fastcmp(word, "TAG")) + strncpy(textprompts[num]->page[pagenum].tag, word2, 33); + else if (fastcmp(word, "NEXTPROMPT")) + textprompts[num]->page[pagenum].nextprompt = usi; + else if (fastcmp(word, "NEXTPAGE")) + textprompts[num]->page[pagenum].nextpage = usi; + else if (fastcmp(word, "NEXTTAG")) + strncpy(textprompts[num]->page[pagenum].nexttag, word2, 33); + else if (fastcmp(word, "TIMETONEXT")) + textprompts[num]->page[pagenum].timetonext = get_number(word2); + else + deh_warning("PromptPage %d: unknown word '%s'", num, word); + } + } while (!myfeof(f)); // finish when the line is empty + + Z_Free(s); +} + +static void readtextprompt(MYFILE *f, INT32 num) +{ + char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); + char *word; + char *word2; + char *tmp; + INT32 value; + + // Allocate memory for this prompt if we don't yet have any + if (!textprompts[num]) + textprompts[num] = Z_Calloc(sizeof (textprompt_t), PU_STATIC, NULL); + + do + { + if (myfgets(s, MAXLINELEN, f)) + { + if (s[0] == '\n') + break; + + tmp = strchr(s, '#'); + if (tmp) + *tmp = '\0'; + if (s == tmp) + continue; // Skip comment lines, but don't break. + + word = strtok(s, " "); + if (word) + strupr(word); + else + break; + + word2 = strtok(NULL, " "); + if (word2) + value = atoi(word2); + else + { + deh_warning("No value for token %s", word); + continue; + } + + if (fastcmp(word, "NUMPAGES")) + { + textprompts[num]->numpages = min(max(value, 0), MAX_PAGES); + } + else if (fastcmp(word, "PAGE")) + { + if (1 <= value && value <= MAX_PAGES) + { + textprompts[num]->page[value - 1].backcolor = 1; // default to gray + textprompts[num]->page[value - 1].hidehud = 1; // hide appropriate HUD elements + readtextpromptpage(f, num, value - 1); + } + else + deh_warning("Page number %d out of range (1 - %d)", value, MAX_PAGES); + + } + else + deh_warning("Prompt %d: unknown word '%s', Page <num> expected.", num, word); + } + } while (!myfeof(f)); // finish when the line is empty + + Z_Free(s); +} + +static void readmenu(MYFILE *f, INT32 num) +{ + char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); + char *word = s; + char *word2; + char *tmp; + INT32 value; + + do + { + if (myfgets(s, MAXLINELEN, f)) + { + if (s[0] == '\n') + break; + + // First remove trailing newline, if there is one + tmp = strchr(s, '\n'); + if (tmp) + *tmp = '\0'; + + tmp = strchr(s, '#'); + if (tmp) + *tmp = '\0'; + if (s == tmp) + continue; // Skip comment lines, but don't break. + + // Get the part before the " = " + tmp = strchr(s, '='); + if (tmp) + *(tmp-1) = '\0'; + else + break; + strupr(word); + + // Now get the part after + word2 = (tmp += 2); + strupr(word2); + + value = atoi(word2); // used for numerical settings + + if (fastcmp(word, "BACKGROUNDNAME")) + { + strncpy(menupres[num].bgname, word2, 8); + titlechanged = true; + } + else if (fastcmp(word, "HIDEBACKGROUND")) + { + menupres[num].bghide = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y'); + titlechanged = true; + } + else if (fastcmp(word, "BACKGROUNDCOLOR")) + { + menupres[num].bgcolor = get_number(word2); + titlechanged = true; + } + else if (fastcmp(word, "HIDETITLEPICS") || fastcmp(word, "HIDEPICS")) + { + // true by default, except MM_MAIN + menupres[num].hidetitlepics = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y'); + titlechanged = true; + } + else if (fastcmp(word, "TITLESCROLLSPEED") || fastcmp(word, "TITLESCROLLXSPEED") + || fastcmp(word, "SCROLLSPEED") || fastcmp(word, "SCROLLXSPEED")) + { + menupres[num].titlescrollxspeed = get_number(word2); + titlechanged = true; + } + else if (fastcmp(word, "TITLESCROLLYSPEED") || fastcmp(word, "SCROLLYSPEED")) + { + menupres[num].titlescrollyspeed = get_number(word2); + titlechanged = true; + } + else if (fastcmp(word, "MUSIC")) + { + strncpy(menupres[num].musname, word2, 7); + menupres[num].musname[6] = 0; + titlechanged = true; + } +#ifdef MUSICSLOT_COMPATIBILITY + else if (fastcmp(word, "MUSICSLOT")) + { + value = get_mus(word2, true); + if (value && value <= 1035) + snprintf(menupres[num].musname, 7, "%sM", G_BuildMapName(value)); + else if (value && value <= 1050) + strncpy(menupres[num].musname, compat_special_music_slots[value - 1036], 7); + else + menupres[num].musname[0] = 0; // becomes empty string + menupres[num].musname[6] = 0; + titlechanged = true; + } +#endif + else if (fastcmp(word, "MUSICTRACK")) + { + menupres[num].mustrack = ((UINT16)value - 1); + titlechanged = true; + } + else if (fastcmp(word, "MUSICLOOP")) + { + // true by default except MM_MAIN + menupres[num].muslooping = (value || word2[0] == 'T' || word2[0] == 'Y'); + titlechanged = true; + } + else if (fastcmp(word, "NOMUSIC")) + { + menupres[num].musstop = (value || word2[0] == 'T' || word2[0] == 'Y'); + titlechanged = true; + } + else if (fastcmp(word, "IGNOREMUSIC")) + { + menupres[num].musignore = (value || word2[0] == 'T' || word2[0] == 'Y'); + titlechanged = true; + } + else if (fastcmp(word, "FADESTRENGTH")) + { + // one-based, <= 0 means use default value. 1-32 + menupres[num].fadestrength = get_number(word2)-1; + titlechanged = true; + } + else if (fastcmp(word, "NOENTERBUBBLE")) + { + menupres[num].enterbubble = !(value || word2[0] == 'T' || word2[0] == 'Y'); + titlechanged = true; + } + else if (fastcmp(word, "NOEXITBUBBLE")) + { + menupres[num].exitbubble = !(value || word2[0] == 'T' || word2[0] == 'Y'); + titlechanged = true; + } + else if (fastcmp(word, "ENTERTAG")) + { + menupres[num].entertag = get_number(word2); + titlechanged = true; + } + else if (fastcmp(word, "EXITTAG")) + { + menupres[num].exittag = get_number(word2); + titlechanged = true; + } + else if (fastcmp(word, "ENTERWIPE")) + { + menupres[num].enterwipe = get_number(word2); + titlechanged = true; + } + else if (fastcmp(word, "EXITWIPE")) + { + menupres[num].exitwipe = get_number(word2); + titlechanged = true; + } + } + } while (!myfeof(f)); // finish when the line is empty + + Z_Free(s); +} + static void readhuditem(MYFILE *f, INT32 num) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); @@ -1658,14 +2139,16 @@ static void readhuditem(MYFILE *f, INT32 num) if (fastcmp(word, "X")) { - DEH_WriteUndoline(word, va("%d", hudinfo[num].x), UNDO_NONE); hudinfo[num].x = i; } else if (fastcmp(word, "Y")) { - DEH_WriteUndoline(word, va("%d", hudinfo[num].y), UNDO_NONE); hudinfo[num].y = i; } + else if (fastcmp(word, "F")) + { + hudinfo[num].f = i; + } else deh_warning("Level header %d: unknown word '%s'", num, word); } @@ -1694,192 +2177,247 @@ typedef struct */ static actionpointer_t actionpointers[] = { - {{A_Explode}, "A_EXPLODE"}, - {{A_Pain}, "A_PAIN"}, - {{A_Fall}, "A_FALL"}, - {{A_MonitorPop}, "A_MONITORPOP"}, - {{A_Look}, "A_LOOK"}, - {{A_Chase}, "A_CHASE"}, - {{A_FaceStabChase}, "A_FACESTABCHASE"}, - {{A_FaceTarget}, "A_FACETARGET"}, - {{A_FaceTracer}, "A_FACETRACER"}, - {{A_Scream}, "A_SCREAM"}, - {{A_BossDeath}, "A_BOSSDEATH"}, - {{A_CustomPower}, "A_CUSTOMPOWER"}, - {{A_GiveWeapon}, "A_GIVEWEAPON"}, - {{A_RingShield}, "A_RINGSHIELD"}, - {{A_RingBox}, "A_RINGBOX"}, - {{A_Invincibility}, "A_INVINCIBILITY"}, - {{A_SuperSneakers}, "A_SUPERSNEAKERS"}, - {{A_BunnyHop}, "A_BUNNYHOP"}, - {{A_BubbleSpawn}, "A_BUBBLESPAWN"}, - {{A_FanBubbleSpawn}, "A_FANBUBBLESPAWN"}, - {{A_BubbleRise}, "A_BUBBLERISE"}, - {{A_BubbleCheck}, "A_BUBBLECHECK"}, - {{A_AwardScore}, "A_AWARDSCORE"}, - {{A_ExtraLife}, "A_EXTRALIFE"}, - {{A_BombShield}, "A_BOMBSHIELD"}, - {{A_JumpShield}, "A_JUMPSHIELD"}, - {{A_WaterShield}, "A_WATERSHIELD"}, - {{A_ForceShield}, "A_FORCESHIELD"}, - {{A_PityShield}, "A_PITYSHIELD"}, - {{A_GravityBox}, "A_GRAVITYBOX"}, - {{A_ScoreRise}, "A_SCORERISE"}, - {{A_ParticleSpawn}, "A_PARTICLESPAWN"}, - {{A_AttractChase}, "A_ATTRACTCHASE"}, - {{A_DropMine}, "A_DROPMINE"}, - {{A_FishJump}, "A_FISHJUMP"}, - {{A_ThrownRing}, "A_THROWNRING"}, - {{A_SetSolidSteam}, "A_SETSOLIDSTEAM"}, - {{A_UnsetSolidSteam}, "A_UNSETSOLIDSTEAM"}, - {{A_SignPlayer}, "A_SIGNPLAYER"}, - {{A_OverlayThink}, "A_OVERLAYTHINK"}, - {{A_JetChase}, "A_JETCHASE"}, - {{A_JetbThink}, "A_JETBTHINK"}, - {{A_JetgThink}, "A_JETGTHINK"}, - {{A_JetgShoot}, "A_JETGSHOOT"}, - {{A_ShootBullet}, "A_SHOOTBULLET"}, - {{A_MinusDigging}, "A_MINUSDIGGING"}, - {{A_MinusPopup}, "A_MINUSPOPUP"}, - {{A_MinusCheck}, "A_MINUSCHECK"}, - {{A_ChickenCheck}, "A_CHICKENCHECK"}, - {{A_MouseThink}, "A_MOUSETHINK"}, - {{A_DetonChase}, "A_DETONCHASE"}, - {{A_CapeChase}, "A_CAPECHASE"}, - {{A_RotateSpikeBall}, "A_ROTATESPIKEBALL"}, - {{A_SlingAppear}, "A_SLINGAPPEAR"}, - {{A_MaceRotate}, "A_MACEROTATE"}, - {{A_UnidusBall}, "A_UNIDUSBALL"}, - {{A_RockSpawn}, "A_ROCKSPAWN"}, - {{A_SetFuse}, "A_SETFUSE"}, - {{A_CrawlaCommanderThink}, "A_CRAWLACOMMANDERTHINK"}, - {{A_SmokeTrailer}, "A_SMOKETRAILER"}, - {{A_RingExplode}, "A_RINGEXPLODE"}, - {{A_OldRingExplode}, "A_OLDRINGEXPLODE"}, - {{A_MixUp}, "A_MIXUP"}, - {{A_RecyclePowers}, "A_RECYCLEPOWERS"}, - {{A_Boss1Chase}, "A_BOSS1CHASE"}, - {{A_FocusTarget}, "A_FOCUSTARGET"}, - {{A_Boss2Chase}, "A_BOSS2CHASE"}, - {{A_Boss2Pogo}, "A_BOSS2POGO"}, - {{A_BossZoom}, "A_BOSSZOOM"}, - {{A_BossScream}, "A_BOSSSCREAM"}, - {{A_Boss2TakeDamage}, "A_BOSS2TAKEDAMAGE"}, - {{A_Boss7Chase}, "A_BOSS7CHASE"}, - {{A_GoopSplat}, "A_GOOPSPLAT"}, - {{A_Boss2PogoSFX}, "A_BOSS2POGOSFX"}, - {{A_Boss2PogoTarget}, "A_BOSS2POGOTARGET"}, - {{A_BossJetFume}, "A_BOSSJETFUME"}, - {{A_EggmanBox}, "A_EGGMANBOX"}, - {{A_TurretFire}, "A_TURRETFIRE"}, - {{A_SuperTurretFire}, "A_SUPERTURRETFIRE"}, - {{A_TurretStop}, "A_TURRETSTOP"}, - {{A_JetJawRoam}, "A_JETJAWROAM"}, - {{A_JetJawChomp}, "A_JETJAWCHOMP"}, - {{A_PointyThink}, "A_POINTYTHINK"}, - {{A_CheckBuddy}, "A_CHECKBUDDY"}, - {{A_HoodThink}, "A_HOODTHINK"}, - {{A_ArrowCheck}, "A_ARROWCHECK"}, - {{A_SnailerThink}, "A_SNAILERTHINK"}, - {{A_SharpChase}, "A_SHARPCHASE"}, - {{A_SharpSpin}, "A_SHARPSPIN"}, - {{A_VultureVtol}, "A_VULTUREVTOL"}, - {{A_VultureCheck}, "A_VULTURECHECK"}, - {{A_SkimChase}, "A_SKIMCHASE"}, - {{A_1upThinker}, "A_1UPTHINKER"}, - {{A_SkullAttack}, "A_SKULLATTACK"}, - {{A_LobShot}, "A_LOBSHOT"}, - {{A_FireShot}, "A_FIRESHOT"}, - {{A_SuperFireShot}, "A_SUPERFIRESHOT"}, - {{A_BossFireShot}, "A_BOSSFIRESHOT"}, - {{A_Boss7FireMissiles}, "A_BOSS7FIREMISSILES"}, - {{A_Boss1Laser}, "A_BOSS1LASER"}, - {{A_Boss4Reverse}, "A_BOSS4REVERSE"}, - {{A_Boss4SpeedUp}, "A_BOSS4SPEEDUP"}, - {{A_Boss4Raise}, "A_BOSS4RAISE"}, - {{A_SparkFollow}, "A_SPARKFOLLOW"}, - {{A_BuzzFly}, "A_BUZZFLY"}, - {{A_GuardChase}, "A_GUARDCHASE"}, - {{A_EggShield}, "A_EGGSHIELD"}, - {{A_SetReactionTime}, "A_SETREACTIONTIME"}, - {{A_Boss1Spikeballs}, "A_BOSS1SPIKEBALLS"}, - {{A_Boss3TakeDamage}, "A_BOSS3TAKEDAMAGE"}, - {{A_Boss3Path}, "A_BOSS3PATH"}, - {{A_LinedefExecute}, "A_LINEDEFEXECUTE"}, - {{A_PlaySeeSound}, "A_PLAYSEESOUND"}, - {{A_PlayAttackSound}, "A_PLAYATTACKSOUND"}, - {{A_PlayActiveSound}, "A_PLAYACTIVESOUND"}, - {{A_SpawnObjectAbsolute}, "A_SPAWNOBJECTABSOLUTE"}, - {{A_SpawnObjectRelative}, "A_SPAWNOBJECTRELATIVE"}, - {{A_ChangeAngleRelative}, "A_CHANGEANGLERELATIVE"}, - {{A_ChangeAngleAbsolute}, "A_CHANGEANGLEABSOLUTE"}, - {{A_PlaySound}, "A_PLAYSOUND"}, - {{A_FindTarget}, "A_FINDTARGET"}, - {{A_FindTracer}, "A_FINDTRACER"}, - {{A_SetTics}, "A_SETTICS"}, - {{A_SetRandomTics}, "A_SETRANDOMTICS"}, - {{A_ChangeColorRelative}, "A_CHANGECOLORRELATIVE"}, - {{A_ChangeColorAbsolute}, "A_CHANGECOLORABSOLUTE"}, - {{A_MoveRelative}, "A_MOVERELATIVE"}, - {{A_MoveAbsolute}, "A_MOVEABSOLUTE"}, - {{A_Thrust}, "A_THRUST"}, - {{A_ZThrust}, "A_ZTHRUST"}, - {{A_SetTargetsTarget}, "A_SETTARGETSTARGET"}, - {{A_SetObjectFlags}, "A_SETOBJECTFLAGS"}, - {{A_SetObjectFlags2}, "A_SETOBJECTFLAGS2"}, - {{A_RandomState}, "A_RANDOMSTATE"}, - {{A_RandomStateRange}, "A_RANDOMSTATERANGE"}, - {{A_DualAction}, "A_DUALACTION"}, - {{A_RemoteAction}, "A_REMOTEACTION"}, - {{A_ToggleFlameJet}, "A_TOGGLEFLAMEJET"}, - {{A_OrbitNights}, "A_ORBITNIGHTS"}, - {{A_GhostMe}, "A_GHOSTME"}, - {{A_SetObjectState}, "A_SETOBJECTSTATE"}, - {{A_SetObjectTypeState}, "A_SETOBJECTTYPESTATE"}, - {{A_KnockBack}, "A_KNOCKBACK"}, - {{A_PushAway}, "A_PUSHAWAY"}, - {{A_RingDrain}, "A_RINGDRAIN"}, - {{A_SplitShot}, "A_SPLITSHOT"}, - {{A_MissileSplit}, "A_MISSILESPLIT"}, - {{A_MultiShot}, "A_MULTISHOT"}, - {{A_InstaLoop}, "A_INSTALOOP"}, - {{A_Custom3DRotate}, "A_CUSTOM3DROTATE"}, - {{A_SearchForPlayers}, "A_SEARCHFORPLAYERS"}, - {{A_CheckRandom}, "A_CHECKRANDOM"}, - {{A_CheckTargetRings}, "A_CHECKTARGETRINGS"}, - {{A_CheckRings}, "A_CHECKRINGS"}, - {{A_CheckTotalRings}, "A_CHECKTOTALRINGS"}, - {{A_CheckHealth}, "A_CHECKHEALTH"}, - {{A_CheckRange}, "A_CHECKRANGE"}, - {{A_CheckHeight}, "A_CHECKHEIGHT"}, - {{A_CheckTrueRange}, "A_CHECKTRUERANGE"}, - {{A_CheckThingCount}, "A_CHECKTHINGCOUNT"}, - {{A_CheckAmbush}, "A_CHECKAMBUSH"}, - {{A_CheckCustomValue}, "A_CHECKCUSTOMVALUE"}, - {{A_CheckCusValMemo}, "A_CHECKCUSVALMEMO"}, - {{A_SetCustomValue}, "A_SETCUSTOMVALUE"}, - {{A_UseCusValMemo}, "A_USECUSVALMEMO"}, - {{A_RelayCustomValue}, "A_RELAYCUSTOMVALUE"}, - {{A_CusValAction}, "A_CUSVALACTION"}, - {{A_ForceStop}, "A_FORCESTOP"}, - {{A_ForceWin}, "A_FORCEWIN"}, - {{A_SpikeRetract}, "A_SPIKERETRACT"}, - {{A_InfoState}, "A_INFOSTATE"}, - {{A_Repeat}, "A_REPEAT"}, - {{A_SetScale}, "A_SETSCALE"}, - {{A_RemoteDamage}, "A_REMOTEDAMAGE"}, - {{A_HomingChase}, "A_HOMINGCHASE"}, - {{A_TrapShot}, "A_TRAPSHOT"}, - {{A_VileTarget}, "A_VILETARGET"}, - {{A_VileAttack}, "A_VILEATTACK"}, - {{A_VileFire}, "A_VILEFIRE"}, - {{A_BrakChase}, "A_BRAKCHASE"}, - {{A_BrakFireShot}, "A_BRAKFIRESHOT"}, - {{A_BrakLobShot}, "A_BRAKLOBSHOT"}, - {{A_NapalmScatter}, "A_NAPALMSCATTER"}, - {{A_SpawnFreshCopy}, "A_SPAWNFRESHCOPY"}, - - {{NULL}, "NONE"}, + {{A_Explode}, "A_EXPLODE"}, + {{A_Pain}, "A_PAIN"}, + {{A_Fall}, "A_FALL"}, + {{A_MonitorPop}, "A_MONITORPOP"}, + {{A_GoldMonitorPop}, "A_GOLDMONITORPOP"}, + {{A_GoldMonitorRestore}, "A_GOLDMONITORRESTORE"}, + {{A_GoldMonitorSparkle}, "A_GOLDMONITORSPARKLE"}, + {{A_Look}, "A_LOOK"}, + {{A_Chase}, "A_CHASE"}, + {{A_FaceStabChase}, "A_FACESTABCHASE"}, + {{A_FaceStabRev}, "A_FACESTABREV"}, + {{A_FaceStabHurl}, "A_FACESTABHURL"}, + {{A_FaceStabMiss}, "A_FACESTABMISS"}, + {{A_StatueBurst}, "A_STATUEBURST"}, + {{A_FaceTarget}, "A_FACETARGET"}, + {{A_FaceTracer}, "A_FACETRACER"}, + {{A_Scream}, "A_SCREAM"}, + {{A_BossDeath}, "A_BOSSDEATH"}, + {{A_CustomPower}, "A_CUSTOMPOWER"}, + {{A_GiveWeapon}, "A_GIVEWEAPON"}, + {{A_RingBox}, "A_RINGBOX"}, + {{A_Invincibility}, "A_INVINCIBILITY"}, + {{A_SuperSneakers}, "A_SUPERSNEAKERS"}, + {{A_BunnyHop}, "A_BUNNYHOP"}, + {{A_BubbleSpawn}, "A_BUBBLESPAWN"}, + {{A_FanBubbleSpawn}, "A_FANBUBBLESPAWN"}, + {{A_BubbleRise}, "A_BUBBLERISE"}, + {{A_BubbleCheck}, "A_BUBBLECHECK"}, + {{A_AwardScore}, "A_AWARDSCORE"}, + {{A_ExtraLife}, "A_EXTRALIFE"}, + {{A_GiveShield}, "A_GIVESHIELD"}, + {{A_GravityBox}, "A_GRAVITYBOX"}, + {{A_ScoreRise}, "A_SCORERISE"}, + {{A_AttractChase}, "A_ATTRACTCHASE"}, + {{A_DropMine}, "A_DROPMINE"}, + {{A_FishJump}, "A_FISHJUMP"}, + {{A_ThrownRing}, "A_THROWNRING"}, + {{A_SetSolidSteam}, "A_SETSOLIDSTEAM"}, + {{A_UnsetSolidSteam}, "A_UNSETSOLIDSTEAM"}, + {{A_SignPlayer}, "A_SIGNPLAYER"}, + {{A_OverlayThink}, "A_OVERLAYTHINK"}, + {{A_JetChase}, "A_JETCHASE"}, + {{A_JetbThink}, "A_JETBTHINK"}, + {{A_JetgThink}, "A_JETGTHINK"}, + {{A_JetgShoot}, "A_JETGSHOOT"}, + {{A_ShootBullet}, "A_SHOOTBULLET"}, + {{A_MinusDigging}, "A_MINUSDIGGING"}, + {{A_MinusPopup}, "A_MINUSPOPUP"}, + {{A_MinusCheck}, "A_MINUSCHECK"}, + {{A_ChickenCheck}, "A_CHICKENCHECK"}, + {{A_MouseThink}, "A_MOUSETHINK"}, + {{A_DetonChase}, "A_DETONCHASE"}, + {{A_CapeChase}, "A_CAPECHASE"}, + {{A_RotateSpikeBall}, "A_ROTATESPIKEBALL"}, + {{A_SlingAppear}, "A_SLINGAPPEAR"}, + {{A_UnidusBall}, "A_UNIDUSBALL"}, + {{A_RockSpawn}, "A_ROCKSPAWN"}, + {{A_SetFuse}, "A_SETFUSE"}, + {{A_CrawlaCommanderThink}, "A_CRAWLACOMMANDERTHINK"}, + {{A_SmokeTrailer}, "A_SMOKETRAILER"}, + {{A_RingExplode}, "A_RINGEXPLODE"}, + {{A_OldRingExplode}, "A_OLDRINGEXPLODE"}, + {{A_MixUp}, "A_MIXUP"}, + {{A_RecyclePowers}, "A_RECYCLEPOWERS"}, + {{A_Boss1Chase}, "A_BOSS1CHASE"}, + {{A_FocusTarget}, "A_FOCUSTARGET"}, + {{A_Boss2Chase}, "A_BOSS2CHASE"}, + {{A_Boss2Pogo}, "A_BOSS2POGO"}, + {{A_BossZoom}, "A_BOSSZOOM"}, + {{A_BossScream}, "A_BOSSSCREAM"}, + {{A_Boss2TakeDamage}, "A_BOSS2TAKEDAMAGE"}, + {{A_Boss7Chase}, "A_BOSS7CHASE"}, + {{A_GoopSplat}, "A_GOOPSPLAT"}, + {{A_Boss2PogoSFX}, "A_BOSS2POGOSFX"}, + {{A_Boss2PogoTarget}, "A_BOSS2POGOTARGET"}, + {{A_BossJetFume}, "A_BOSSJETFUME"}, + {{A_EggmanBox}, "A_EGGMANBOX"}, + {{A_TurretFire}, "A_TURRETFIRE"}, + {{A_SuperTurretFire}, "A_SUPERTURRETFIRE"}, + {{A_TurretStop}, "A_TURRETSTOP"}, + {{A_JetJawRoam}, "A_JETJAWROAM"}, + {{A_JetJawChomp}, "A_JETJAWCHOMP"}, + {{A_PointyThink}, "A_POINTYTHINK"}, + {{A_CheckBuddy}, "A_CHECKBUDDY"}, + {{A_HoodFire}, "A_HOODFIRE"}, + {{A_HoodThink}, "A_HOODTHINK"}, + {{A_HoodFall}, "A_HOODFALL"}, + {{A_ArrowBonks}, "A_ARROWBONKS"}, + {{A_SnailerThink}, "A_SNAILERTHINK"}, + {{A_SharpChase}, "A_SHARPCHASE"}, + {{A_SharpSpin}, "A_SHARPSPIN"}, + {{A_SharpDecel}, "A_SHARPDECEL"}, + {{A_CrushstaceanWalk}, "A_CRUSHSTACEANWALK"}, + {{A_CrushstaceanPunch}, "A_CRUSHSTACEANPUNCH"}, + {{A_CrushclawAim}, "A_CRUSHCLAWAIM"}, + {{A_CrushclawLaunch}, "A_CRUSHCLAWLAUNCH"}, + {{A_VultureVtol}, "A_VULTUREVTOL"}, + {{A_VultureCheck}, "A_VULTURECHECK"}, + {{A_VultureHover}, "A_VULTUREHOVER"}, + {{A_VultureBlast}, "A_VULTUREBLAST"}, + {{A_VultureFly}, "A_VULTUREFLY"}, + {{A_SkimChase}, "A_SKIMCHASE"}, + {{A_1upThinker}, "A_1UPTHINKER"}, + {{A_SkullAttack}, "A_SKULLATTACK"}, + {{A_LobShot}, "A_LOBSHOT"}, + {{A_FireShot}, "A_FIRESHOT"}, + {{A_SuperFireShot}, "A_SUPERFIRESHOT"}, + {{A_BossFireShot}, "A_BOSSFIRESHOT"}, + {{A_Boss7FireMissiles}, "A_BOSS7FIREMISSILES"}, + {{A_Boss1Laser}, "A_BOSS1LASER"}, + {{A_Boss4Reverse}, "A_BOSS4REVERSE"}, + {{A_Boss4SpeedUp}, "A_BOSS4SPEEDUP"}, + {{A_Boss4Raise}, "A_BOSS4RAISE"}, + {{A_SparkFollow}, "A_SPARKFOLLOW"}, + {{A_BuzzFly}, "A_BUZZFLY"}, + {{A_GuardChase}, "A_GUARDCHASE"}, + {{A_EggShield}, "A_EGGSHIELD"}, + {{A_SetReactionTime}, "A_SETREACTIONTIME"}, + {{A_Boss1Spikeballs}, "A_BOSS1SPIKEBALLS"}, + {{A_Boss3TakeDamage}, "A_BOSS3TAKEDAMAGE"}, + {{A_Boss3Path}, "A_BOSS3PATH"}, + {{A_LinedefExecute}, "A_LINEDEFEXECUTE"}, + {{A_PlaySeeSound}, "A_PLAYSEESOUND"}, + {{A_PlayAttackSound}, "A_PLAYATTACKSOUND"}, + {{A_PlayActiveSound}, "A_PLAYACTIVESOUND"}, + {{A_SpawnObjectAbsolute}, "A_SPAWNOBJECTABSOLUTE"}, + {{A_SpawnObjectRelative}, "A_SPAWNOBJECTRELATIVE"}, + {{A_ChangeAngleRelative}, "A_CHANGEANGLERELATIVE"}, + {{A_ChangeAngleAbsolute}, "A_CHANGEANGLEABSOLUTE"}, + {{A_PlaySound}, "A_PLAYSOUND"}, + {{A_FindTarget}, "A_FINDTARGET"}, + {{A_FindTracer}, "A_FINDTRACER"}, + {{A_SetTics}, "A_SETTICS"}, + {{A_SetRandomTics}, "A_SETRANDOMTICS"}, + {{A_ChangeColorRelative}, "A_CHANGECOLORRELATIVE"}, + {{A_ChangeColorAbsolute}, "A_CHANGECOLORABSOLUTE"}, + {{A_MoveRelative}, "A_MOVERELATIVE"}, + {{A_MoveAbsolute}, "A_MOVEABSOLUTE"}, + {{A_Thrust}, "A_THRUST"}, + {{A_ZThrust}, "A_ZTHRUST"}, + {{A_SetTargetsTarget}, "A_SETTARGETSTARGET"}, + {{A_SetObjectFlags}, "A_SETOBJECTFLAGS"}, + {{A_SetObjectFlags2}, "A_SETOBJECTFLAGS2"}, + {{A_RandomState}, "A_RANDOMSTATE"}, + {{A_RandomStateRange}, "A_RANDOMSTATERANGE"}, + {{A_DualAction}, "A_DUALACTION"}, + {{A_RemoteAction}, "A_REMOTEACTION"}, + {{A_ToggleFlameJet}, "A_TOGGLEFLAMEJET"}, + {{A_OrbitNights}, "A_ORBITNIGHTS"}, + {{A_GhostMe}, "A_GHOSTME"}, + {{A_SetObjectState}, "A_SETOBJECTSTATE"}, + {{A_SetObjectTypeState}, "A_SETOBJECTTYPESTATE"}, + {{A_KnockBack}, "A_KNOCKBACK"}, + {{A_PushAway}, "A_PUSHAWAY"}, + {{A_RingDrain}, "A_RINGDRAIN"}, + {{A_SplitShot}, "A_SPLITSHOT"}, + {{A_MissileSplit}, "A_MISSILESPLIT"}, + {{A_MultiShot}, "A_MULTISHOT"}, + {{A_InstaLoop}, "A_INSTALOOP"}, + {{A_Custom3DRotate}, "A_CUSTOM3DROTATE"}, + {{A_SearchForPlayers}, "A_SEARCHFORPLAYERS"}, + {{A_CheckRandom}, "A_CHECKRANDOM"}, + {{A_CheckTargetRings}, "A_CHECKTARGETRINGS"}, + {{A_CheckRings}, "A_CHECKRINGS"}, + {{A_CheckTotalRings}, "A_CHECKTOTALRINGS"}, + {{A_CheckHealth}, "A_CHECKHEALTH"}, + {{A_CheckRange}, "A_CHECKRANGE"}, + {{A_CheckHeight}, "A_CHECKHEIGHT"}, + {{A_CheckTrueRange}, "A_CHECKTRUERANGE"}, + {{A_CheckThingCount}, "A_CHECKTHINGCOUNT"}, + {{A_CheckAmbush}, "A_CHECKAMBUSH"}, + {{A_CheckCustomValue}, "A_CHECKCUSTOMVALUE"}, + {{A_CheckCusValMemo}, "A_CHECKCUSVALMEMO"}, + {{A_SetCustomValue}, "A_SETCUSTOMVALUE"}, + {{A_UseCusValMemo}, "A_USECUSVALMEMO"}, + {{A_RelayCustomValue}, "A_RELAYCUSTOMVALUE"}, + {{A_CusValAction}, "A_CUSVALACTION"}, + {{A_ForceStop}, "A_FORCESTOP"}, + {{A_ForceWin}, "A_FORCEWIN"}, + {{A_SpikeRetract}, "A_SPIKERETRACT"}, + {{A_InfoState}, "A_INFOSTATE"}, + {{A_Repeat}, "A_REPEAT"}, + {{A_SetScale}, "A_SETSCALE"}, + {{A_RemoteDamage}, "A_REMOTEDAMAGE"}, + {{A_HomingChase}, "A_HOMINGCHASE"}, + {{A_TrapShot}, "A_TRAPSHOT"}, + {{A_VileTarget}, "A_VILETARGET"}, + {{A_VileAttack}, "A_VILEATTACK"}, + {{A_VileFire}, "A_VILEFIRE"}, + {{A_BrakChase}, "A_BRAKCHASE"}, + {{A_BrakFireShot}, "A_BRAKFIRESHOT"}, + {{A_BrakLobShot}, "A_BRAKLOBSHOT"}, + {{A_NapalmScatter}, "A_NAPALMSCATTER"}, + {{A_SpawnFreshCopy}, "A_SPAWNFRESHCOPY"}, + {{A_FlickySpawn}, "A_FLICKYSPAWN"}, + {{A_FlickyAim}, "A_FLICKYAIM"}, + {{A_FlickyFly}, "A_FLICKYFLY"}, + {{A_FlickySoar}, "A_FLICKYSOAR"}, + {{A_FlickyCoast}, "A_FLICKYCOAST"}, + {{A_FlickyHop}, "A_FLICKYHOP"}, + {{A_FlickyFlounder}, "A_FLICKYFLOUNDER"}, + {{A_FlickyCheck}, "A_FLICKYCHECK"}, + {{A_FlickyHeightCheck}, "A_FLICKYHEIGHTCHECK"}, + {{A_FlickyFlutter}, "A_FLICKYFLUTTER"}, + {{A_FlameParticle}, "A_FLAMEPARTICLE"}, + {{A_FadeOverlay}, "A_FADEOVERLAY"}, + {{A_Boss5Jump}, "A_BOSS5JUMP"}, + {{A_LightBeamReset}, "A_LIGHTBEAMRESET"}, + {{A_MineExplode}, "A_MINEEXPLODE"}, + {{A_MineRange}, "A_MINERANGE"}, + {{A_ConnectToGround}, "A_CONNECTTOGROUND"}, + {{A_SpawnParticleRelative}, "A_SPAWNPARTICLERELATIVE"}, + {{A_MultiShotDist}, "A_MULTISHOTDIST"}, + {{A_WhoCaresIfYourSonIsABee},"A_WHOCARESIFYOURSONISABEE"}, + {{A_ParentTriesToSleep}, "A_PARENTTRIESTOSLEEP"}, + {{A_CryingToMomma}, "A_CRYINGTOMOMMA"}, + {{A_CheckFlags2}, "A_CHECKFLAGS2"}, + {{A_Boss5FindWaypoint}, "A_BOSS5FINDWAYPOINT"}, + {{A_DoNPCSkid}, "A_DONPCSKID"}, + {{A_DoNPCPain}, "A_DONPCPAIN"}, + {{A_PrepareRepeat}, "A_PREPAREREPEAT"}, + {{A_Boss5ExtraRepeat}, "A_BOSS5EXTRAREPEAT"}, + {{A_Boss5Calm}, "A_BOSS5CALM"}, + {{A_Boss5CheckOnGround}, "A_BOSS5CHECKONGROUND"}, + {{A_Boss5CheckFalling}, "A_BOSS5CHECKFALLING"}, + {{A_Boss5PinchShot}, "A_BOSS5PINCHSHOT"}, + {{A_Boss5MakeItRain}, "A_BOSS5MAKEITRAIN"}, + {{A_LookForBetter}, "A_LOOKFORBETTER"}, + {{A_Boss5BombExplode}, "A_BOSS5BOMBEXPLODE"}, + {{A_DustDevilThink}, "A_DUSTDEVILTHINK"}, + {{A_TNTExplode}, "A_TNTEXPLODE"}, + {{A_DebrisRandom}, "A_DEBRISRANDOM"}, + {{A_TrainCameo}, "A_TRAINCAMEO"}, + {{A_TrainCameo2}, "A_TRAINCAMEO2"}, + {{A_CanarivoreGas}, "A_CANARIVOREGAS"}, + {{A_KillSegments}, "A_KILLSEGMENTS"}, + {{A_SnapperSpawn}, "A_SNAPPERSPAWN"}, + {{A_SnapperThinker}, "A_SNAPPERTHINKER"}, + {{A_SaloonDoorSpawn}, "A_SALOONDOORSPAWN"}, + {{A_MinecartSparkThink}, "A_MINECARTSPARKTHINK"}, + {{NULL}, "NONE"}, // This NULL entry must be the last in the list {{NULL}, NULL}, @@ -1921,39 +2459,33 @@ static void readframe(MYFILE *f, INT32 num) if (fastcmp(word1, "SPRITENUMBER") || fastcmp(word1, "SPRITENAME")) { - DEH_WriteUndoline(word1, va("%u", states[num].sprite), UNDO_NONE); states[num].sprite = get_sprite(word2); } else if (fastcmp(word1, "SPRITESUBNUMBER") || fastcmp(word1, "SPRITEFRAME")) { - DEH_WriteUndoline(word1, va("%d", states[num].frame), UNDO_NONE); states[num].frame = (INT32)get_number(word2); // So the FF_ flags get calculated } else if (fastcmp(word1, "DURATION")) { - DEH_WriteUndoline(word1, va("%u", states[num].tics), UNDO_NONE); states[num].tics = (INT32)get_number(word2); // So TICRATE can be used } else if (fastcmp(word1, "NEXT")) { - DEH_WriteUndoline(word1, va("%d", states[num].nextstate), UNDO_NONE); states[num].nextstate = get_state(word2); } else if (fastcmp(word1, "VAR1")) { - DEH_WriteUndoline(word1, va("%d", states[num].var1), UNDO_NONE); states[num].var1 = (INT32)get_number(word2); } else if (fastcmp(word1, "VAR2")) { - DEH_WriteUndoline(word1, va("%d", states[num].var2), UNDO_NONE); states[num].var2 = (INT32)get_number(word2); } else if (fastcmp(word1, "ACTION")) { size_t z; boolean found = false; - XBOXSTATIC char actiontocompare[32]; + char actiontocompare[32]; memset(actiontocompare, 0x00, sizeof(actiontocompare)); strlcpy(actiontocompare, word2, sizeof (actiontocompare)); @@ -1971,10 +2503,7 @@ static void readframe(MYFILE *f, INT32 num) for (z = 0; actionpointers[z].name; z++) { if (actionpointers[z].action.acv == states[num].action.acv) - { - DEH_WriteUndoline(word1, actionpointers[z].name, UNDO_NONE); break; - } } z = 0; @@ -2006,10 +2535,11 @@ static void readframe(MYFILE *f, INT32 num) Z_Free(s); } -static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[]) +static void readsound(MYFILE *f, INT32 num) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); char *word; + char *word2; char *tmp; INT32 value; @@ -2023,8 +2553,8 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[]) tmp = strchr(s, '#'); if (tmp) *tmp = '\0'; - - value = searchvalue(s); + if (s == tmp) + continue; // Skip comment lines, but don't break. word = strtok(s, " "); if (word) @@ -2032,43 +2562,38 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[]) else break; -/* if (fastcmp(word, "OFFSET")) + word2 = strtok(NULL, " "); + if (word2) + value = atoi(word2); + else { - value -= 150360; - if (value <= 64) - value /= 8; - else if (value <= 260) - value = (value+4)/8; - else - value = (value+8)/8; - if (value >= -1 && value < sfx_freeslot0 - 1) - S_sfx[num].name = savesfxnames[value+1]; - else - deh_warning("Sound %d: offset out of bounds", num); + deh_warning("No value for token %s", word); + continue; } - else */if (fastcmp(word, "SINGULAR")) + + if (fastcmp(word, "SINGULAR")) { - DEH_WriteUndoline(word, va("%d", S_sfx[num].singularity), UNDO_NONE); S_sfx[num].singularity = value; } else if (fastcmp(word, "PRIORITY")) { - DEH_WriteUndoline(word, va("%d", S_sfx[num].priority), UNDO_NONE); S_sfx[num].priority = value; } else if (fastcmp(word, "FLAGS")) { - DEH_WriteUndoline(word, va("%d", S_sfx[num].pitch), UNDO_NONE); S_sfx[num].pitch = value; } + else if (fastcmp(word, "CAPTION") || fastcmp(word, "DESCRIPTION")) + { + deh_strlcpy(S_sfx[num].caption, word2, + sizeof(S_sfx[num].caption), va("Sound effect %d: caption", num)); + } else deh_warning("Sound %d : unknown word '%s'",num,word); } } while (!myfeof(f)); Z_Free(s); - - (void)savesfxnames; } /** Checks if a game data file name for a mod is good. @@ -2099,11 +2624,7 @@ static boolean GoodDataFileName(const char *s) p = s + strlen(s) - strlen(tail); if (p <= s) return false; // too short if (!fasticmp(p, tail)) return false; // doesn't end in .dat -#ifdef DELFILE - if (fasticmp(s, "gamedata.dat") && !disableundo) return false; -#else if (fasticmp(s, "gamedata.dat")) return false; -#endif return true; } @@ -2116,17 +2637,6 @@ static void reademblemdata(MYFILE *f, INT32 num) char *tmp; INT32 value; - // Reset all data initially - DEH_WriteUndoline("TYPE", va("%d", emblemlocations[num-1].type), UNDO_NONE); - DEH_WriteUndoline("X", va("%d", emblemlocations[num-1].x), UNDO_NONE); - DEH_WriteUndoline("Y", va("%d", emblemlocations[num-1].y), UNDO_NONE); - DEH_WriteUndoline("Z", va("%d", emblemlocations[num-1].z), UNDO_NONE); - DEH_WriteUndoline("MAPNUM", va("%d", emblemlocations[num-1].level), UNDO_NONE); - DEH_WriteUndoline("VAR", va("%d", emblemlocations[num-1].var), UNDO_NONE); - DEH_WriteUndoline("SPRITE", va("%d", emblemlocations[num-1].sprite), UNDO_NONE); - DEH_WriteUndoline("COLOR", va("%d", emblemlocations[num-1].color), UNDO_NONE); - DEH_WriteUndoline("HINT", extraemblems[num-1].hint, UNDO_NONE); - memset(&emblemlocations[num-1], 0, sizeof(emblem_t)); do @@ -2181,6 +2691,8 @@ static void reademblemdata(MYFILE *f, INT32 num) emblemlocations[num-1].type = ET_TIME; else if (fastcmp(word2, "RINGS")) emblemlocations[num-1].type = ET_RINGS; + else if (fastcmp(word2, "MAP")) + emblemlocations[num-1].type = ET_MAP; else if (fastcmp(word2, "NGRADE")) emblemlocations[num-1].type = ET_NGRADE; else if (fastcmp(word2, "NTIME")) @@ -2188,12 +2700,8 @@ static void reademblemdata(MYFILE *f, INT32 num) else emblemlocations[num-1].type = (UINT8)value; } - else if (fastcmp(word, "X")) - emblemlocations[num-1].x = (INT16)value; - else if (fastcmp(word, "Y")) - emblemlocations[num-1].y = (INT16)value; - else if (fastcmp(word, "Z")) - emblemlocations[num-1].z = (INT16)value; + else if (fastcmp(word, "TAG")) + emblemlocations[num-1].tag = (INT16)value; else if (fastcmp(word, "MAPNUM")) { // Support using the actual map name, @@ -2263,13 +2771,6 @@ static void readextraemblemdata(MYFILE *f, INT32 num) char *tmp; INT32 value; - // Reset all data initially - DEH_WriteUndoline("NAME", extraemblems[num-1].name, UNDO_NONE); - DEH_WriteUndoline("OBJECTIVE", extraemblems[num-1].description, UNDO_NONE); - DEH_WriteUndoline("CONDITIONSET", va("%d", extraemblems[num-1].conditionset), UNDO_NONE); - DEH_WriteUndoline("SPRITE", va("%d", extraemblems[num-1].sprite), UNDO_NONE); - DEH_WriteUndoline("COLOR", va("%d", extraemblems[num-1].color), UNDO_NONE); - memset(&extraemblems[num-1], 0, sizeof(extraemblem_t)); do @@ -2347,17 +2848,8 @@ static void readunlockable(MYFILE *f, INT32 num) char *tmp; INT32 i; - // Same deal with unlockables, clear all first - DEH_WriteUndoline("NAME", unlockables[num].name, UNDO_NONE); - DEH_WriteUndoline("OBJECTIVE", unlockables[num].objective, UNDO_NONE); - DEH_WriteUndoline("HEIGHT", va("%d", unlockables[num].height), UNDO_NONE); - DEH_WriteUndoline("CONDITIONSET", va("%d", unlockables[num].conditionset), UNDO_NONE); - DEH_WriteUndoline("TYPE", va("%d", unlockables[num].type), UNDO_NONE); - DEH_WriteUndoline("NOCECHO", va("%d", unlockables[num].nocecho), UNDO_NONE); - DEH_WriteUndoline("NOCHECKLIST", va("%d", unlockables[num].nochecklist), UNDO_NONE); - DEH_WriteUndoline("VAR", va("%d", unlockables[num].variable), UNDO_NONE); - memset(&unlockables[num], 0, sizeof(unlockable_t)); + unlockables[num].objective[0] = '/'; do { @@ -2705,190 +3197,6 @@ static void readconditionset(MYFILE *f, UINT8 setnum) Z_Free(s); } -static void readtexture(MYFILE *f, const char *name) -{ - char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); - char *word; - char *word2; - char *tmp; - INT32 i, j, value; - UINT16 width = 0, height = 0; - INT16 patchcount = 0; - texture_t *texture; - - do - { - if (myfgets(s, MAXLINELEN, f)) - { - if (s[0] == '\n') - break; - - tmp = strchr(s, '#'); - if (tmp) - *tmp = '\0'; - - value = searchvalue(s); - word = strtok(s, " "); - if (word) - strupr(word); - else - break; - - word2 = strtok(NULL, " "); - if (word2) - strupr(word2); - else - break; - - // Width of the texture. - if (fastcmp(word, "WIDTH")) - { - DEH_WriteUndoline(word, va("%d", width), UNDO_NONE); - width = SHORT((UINT16)value); - } - // Height of the texture. - else if (fastcmp(word, "HEIGHT")) - { - DEH_WriteUndoline(word, va("%d", height), UNDO_NONE); - height = SHORT((UINT16)value); - } - // Number of patches the texture has. - else if (fastcmp(word, "NUMPATCHES")) - { - DEH_WriteUndoline(word, va("%d", patchcount), UNDO_NONE); - patchcount = SHORT((UINT16)value); - } - else - deh_warning("readtexture: unknown word '%s'", word); - } - } while (!myfeof(f)); - - // Error checking. - if (!width) - I_Error("Texture %s has no width!\n", name); - - if (!height) - I_Error("Texture %s has no height!\n", name); - - if (!patchcount) - I_Error("Texture %s has no patches!\n", name); - - // Allocate memory for the texture, and fill in information. - texture = Z_Calloc(sizeof(texture_t) + (sizeof(texpatch_t) * SHORT(patchcount)), PU_STATIC, NULL); - M_Memcpy(texture->name, name, sizeof(texture->name)); - texture->width = width; - texture->height = height; - texture->patchcount = patchcount; - texture->holes = false; - // Fill out the texture patches, to allow them to be detected - // accurately by readpatch. - for (i = 0; i < patchcount; i++) - { - texture->patches[i].originx = 0; - texture->patches[i].originy = 0; - texture->patches[i].wad = UINT16_MAX; - texture->patches[i].lump = UINT16_MAX; - } - - // Jump to the next empty texture entry. - i = 0; - while (textures[i]) - i++; - - // Fill the global texture buffer entries. - j = 1; - while (j << 1 <= texture->width) - j <<= 1; - - textures[i] = texture; - texturewidthmask[i] = j - 1; - textureheight[i] = texture->height << FRACBITS; - - // Clean up. - Z_Free(s); -} - -static void readpatch(MYFILE *f, const char *name, UINT16 wad) -{ - char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); - char *word; - char *word2; - char *tmp; - INT32 i = 0, j = 0, value; - texpatch_t patch = {0, 0, UINT16_MAX, UINT16_MAX}; - - // Jump to the texture this patch belongs to, which, - // coincidentally, is always the last one on the buffer cache. - while (textures[i+1]) - i++; - - // Jump to the next empty patch entry. - while (memcmp(&(textures[i]->patches[j]), &patch, sizeof(patch))) - j++; - - patch.wad = wad; - // Set the texture number, but only if the lump exists. - if ((patch.lump = W_CheckNumForNamePwad(name, wad, 0)) == INT16_MAX) - I_Error("readpatch: Missing patch in texture %s", textures[i]->name); - - // note: undoing this patch will be done by other means - do - { - if (myfgets(s, MAXLINELEN, f)) - { - if (s[0] == '\n') - break; - - tmp = strchr(s, '#'); - if (tmp) - *tmp = '\0'; - - value = searchvalue(s); - word = strtok(s, " "); - if (word) - strupr(word); - else - break; - - word2 = strtok(NULL, " "); - if (word2) - strupr(word2); - else - break; - - // X position of the patch in the texture. - if (fastcmp(word, "X")) - { - //DEH_WriteUndoline(word, va("%d", patch->originx), UNDO_NONE); - patch.originx = (INT16)value; - } - // Y position of the patch in the texture. - else if (fastcmp(word, "Y")) - { - //DEH_WriteUndoline(word, va("%d", patch->originy), UNDO_NONE); - patch.originy = (INT16)value; - } - else - deh_warning("readpatch: unknown word '%s'", word); - } - } while (!myfeof(f)); - - // Error checking. - /* // Irrelevant. Origins cannot be unsigned. - if (patch.originx == UINT16_MAX) - I_Error("Patch %s on texture %s has no X position!\n", name, textures[i]->name); - - if (patch.originy == UINT16_MAX) - I_Error("Patch %s on texture %s has no Y position!\n", name, textures[i]->name); -*/ - - // Set the patch as that patch number. - textures[i]->patches[j] = patch; - - // Clean up. - Z_Free(s); -} - static void readmaincfg(MYFILE *f) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); @@ -2943,7 +3251,6 @@ static void readmaincfg(MYFILE *f) else value = get_number(word2); - DEH_WriteUndoline(word, va("%d", spstage_start), UNDO_NONE); spstage_start = (INT16)value; } else if (fastcmp(word, "SSTAGE_START")) @@ -2957,97 +3264,119 @@ static void readmaincfg(MYFILE *f) else value = get_number(word2); - DEH_WriteUndoline(word, va("%d", sstage_start), UNDO_NONE); sstage_start = (INT16)value; - sstage_end = (INT16)(sstage_start+6); // 7 special stages total + sstage_end = (INT16)(sstage_start+7); // 7 special stages total plus one weirdo } - else if (fastcmp(word, "USENIGHTSSS")) + else if (fastcmp(word, "SMPSTAGE_START")) { - DEH_WriteUndoline(word, va("%d", useNightsSS), UNDO_NONE); - useNightsSS = (value || word2[0] == 'T' || word2[0] == 'Y'); + // Support using the actual map name, + // i.e., Level AB, Level FZ, etc. + + // Convert to map number + if (word2[0] >= 'A' && word2[0] <= 'Z') + value = M_MapNumber(word2[0], word2[1]); + else + value = get_number(word2); + + smpstage_start = (INT16)value; + smpstage_end = (INT16)(smpstage_start+6); // 7 special stages total } else if (fastcmp(word, "REDTEAM")) { - DEH_WriteUndoline(word, va("%d", skincolor_redteam), UNDO_NONE); skincolor_redteam = (UINT8)get_number(word2); } else if (fastcmp(word, "BLUETEAM")) { - DEH_WriteUndoline(word, va("%d", skincolor_blueteam), UNDO_NONE); skincolor_blueteam = (UINT8)get_number(word2); } else if (fastcmp(word, "REDRING")) { - DEH_WriteUndoline(word, va("%d", skincolor_redring), UNDO_NONE); skincolor_redring = (UINT8)get_number(word2); } else if (fastcmp(word, "BLUERING")) { - DEH_WriteUndoline(word, va("%d", skincolor_bluering), UNDO_NONE); skincolor_bluering = (UINT8)get_number(word2); } else if (fastcmp(word, "INVULNTICS")) { - DEH_WriteUndoline(word, va("%u", invulntics), UNDO_NONE); invulntics = (UINT16)get_number(word2); } else if (fastcmp(word, "SNEAKERTICS")) { - DEH_WriteUndoline(word, va("%u", sneakertics), UNDO_NONE); sneakertics = (UINT16)get_number(word2); } else if (fastcmp(word, "FLASHINGTICS")) { - DEH_WriteUndoline(word, va("%u", flashingtics), UNDO_NONE); flashingtics = (UINT16)get_number(word2); } else if (fastcmp(word, "TAILSFLYTICS")) { - DEH_WriteUndoline(word, va("%u", tailsflytics), UNDO_NONE); tailsflytics = (UINT16)get_number(word2); } else if (fastcmp(word, "UNDERWATERTICS")) { - DEH_WriteUndoline(word, va("%u", underwatertics), UNDO_NONE); underwatertics = (UINT16)get_number(word2); } else if (fastcmp(word, "SPACETIMETICS")) { - DEH_WriteUndoline(word, va("%u", spacetimetics), UNDO_NONE); spacetimetics = (UINT16)get_number(word2); } else if (fastcmp(word, "EXTRALIFETICS")) { - DEH_WriteUndoline(word, va("%u", extralifetics), UNDO_NONE); extralifetics = (UINT16)get_number(word2); } + else if (fastcmp(word, "NIGHTSLINKTICS")) + { + nightslinktics = (UINT16)get_number(word2); + } else if (fastcmp(word, "GAMEOVERTICS")) { - DEH_WriteUndoline(word, va("%u", gameovertics), UNDO_NONE); gameovertics = get_number(word2); } - else if (fastcmp(word, "INTROTOPLAY")) { - DEH_WriteUndoline(word, va("%d", introtoplay), UNDO_NONE); introtoplay = (UINT8)get_number(word2); // range check, you morons. if (introtoplay > 128) introtoplay = 128; + introchanged = true; } else if (fastcmp(word, "LOOPTITLE")) { - DEH_WriteUndoline(word, va("%d", looptitle), UNDO_NONE); looptitle = (value || word2[0] == 'T' || word2[0] == 'Y'); + titlechanged = true; + } + else if (fastcmp(word, "TITLEMAP")) + { + // Support using the actual map name, + // i.e., Level AB, Level FZ, etc. + + // Convert to map number + if (word2[0] >= 'A' && word2[0] <= 'Z') + value = M_MapNumber(word2[0], word2[1]); + else + value = get_number(word2); + + titlemap = (INT16)value; + titlechanged = true; + } + else if (fastcmp(word, "HIDETITLEPICS")) + { + hidetitlepics = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y'); + titlechanged = true; + } + else if (fastcmp(word, "TITLESCROLLSPEED") || fastcmp(word, "TITLESCROLLXSPEED")) + { + titlescrollxspeed = get_number(word2); + titlechanged = true; } - else if (fastcmp(word, "TITLESCROLLSPEED")) + else if (fastcmp(word, "TITLESCROLLYSPEED")) { - DEH_WriteUndoline(word, va("%d", titlescrollspeed), UNDO_NONE); - titlescrollspeed = get_number(word2); + titlescrollyspeed = get_number(word2); + titlechanged = true; } else if (fastcmp(word, "CREDITSCUTSCENE")) { - DEH_WriteUndoline(word, va("%d", creditscutscene), UNDO_NONE); creditscutscene = (UINT8)get_number(word2); // range check, you morons. if (creditscutscene > 128) @@ -3055,32 +3384,29 @@ static void readmaincfg(MYFILE *f) } else if (fastcmp(word, "DISABLESPEEDADJUST")) { - DEH_WriteUndoline(word, va("%d", disableSpeedAdjust), UNDO_NONE); disableSpeedAdjust = (value || word2[0] == 'T' || word2[0] == 'Y'); } else if (fastcmp(word, "NUMDEMOS")) { - DEH_WriteUndoline(word, va("%d", numDemos), UNDO_NONE); numDemos = (UINT8)get_number(word2); + titlechanged = true; } else if (fastcmp(word, "DEMODELAYTIME")) { - DEH_WriteUndoline(word, va("%d", demoDelayTime), UNDO_NONE); demoDelayTime = get_number(word2); + titlechanged = true; } else if (fastcmp(word, "DEMOIDLETIME")) { - DEH_WriteUndoline(word, va("%d", demoIdleTime), UNDO_NONE); demoIdleTime = get_number(word2); + titlechanged = true; } else if (fastcmp(word, "USE1UPSOUND")) { - DEH_WriteUndoline(word, va("%u", use1upSound), UNDO_NONE); use1upSound = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y'); } else if (fastcmp(word, "MAXXTRALIFE")) { - DEH_WriteUndoline(word, va("%u", maxXtraLife), UNDO_NONE); maxXtraLife = (UINT8)get_number(word2); } @@ -3094,7 +3420,6 @@ static void readmaincfg(MYFILE *f) I_Error("Maincfg: bad data file name '%s'\n", word2); G_SaveGameData(); - DEH_WriteUndoline(word, gamedatafilename, UNDO_NONE); strlcpy(gamedatafilename, word2, sizeof (gamedatafilename)); strlwr(gamedatafilename); savemoddata = true; @@ -3110,16 +3435,49 @@ static void readmaincfg(MYFILE *f) strcatbf(savegamename, srb2home, PATHSEP); gamedataadded = true; + titlechanged = true; } else if (fastcmp(word, "RESETDATA")) { - DEH_WriteUndoline(word, "0", UNDO_TODO); /// \todo P_ResetData(value); + titlechanged = true; } else if (fastcmp(word, "CUSTOMVERSION")) { - DEH_WriteUndoline(word, customversionstring, UNDO_NONE); strlcpy(customversionstring, word2, sizeof (customversionstring)); + //titlechanged = true; + } + else if (fastcmp(word, "BOOTMAP")) + { + // Support using the actual map name, + // i.e., Level AB, Level FZ, etc. + + // Convert to map number + if (word2[0] >= 'A' && word2[0] <= 'Z') + value = M_MapNumber(word2[0], word2[1]); + else + value = get_number(word2); + + bootmap = (INT16)value; + //titlechanged = true; + } + else if (fastcmp(word, "STARTCHAR")) + { + startchar = (INT16)value; + char_on = -1; + } + else if (fastcmp(word, "TUTORIALMAP")) + { + // Support using the actual map name, + // i.e., Level AB, Level FZ, etc. + + // Convert to map number + if (word2[0] >= 'A' && word2[0] <= 'Z') + value = M_MapNumber(word2[0], word2[1]); + else + value = get_number(word2); + + tutorialmap = (INT16)value; } else deh_warning("Maincfg: unknown word '%s'", word); @@ -3307,38 +3665,25 @@ static void ignorelines(MYFILE *f) Z_Free(s); } -static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) +static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); char *word; char *word2; INT32 i; - // do a copy of this for cross references probleme - //XBOXSTATIC actionf_t saveactions[NUMSTATES]; - //XBOXSTATIC const char *savesprnames[NUMSPRITES]; - XBOXSTATIC const char *savesfxnames[NUMSFX]; if (!deh_loaded) initfreeslots(); deh_num_warning = 0; - // save values for cross reference - /* - for (i = 0; i < NUMSTATES; i++) - saveactions[i] = states[i].action; - for (i = 0; i < NUMSPRITES; i++) - savesprnames[i] = sprnames[i]; - */ - for (i = 0; i < NUMSFX; i++) - savesfxnames[i] = S_sfx[i].name; - gamedataadded = false; + gamedataadded = titlechanged = introchanged = false; // it doesn't test the version of SRB2 and version of dehacked file dbg_line = -1; // start at -1 so the first line is 0. while (!myfeof(f)) { - XBOXSTATIC char origpos[128]; + char origpos[128]; INT32 size = 0; char *traverse; @@ -3372,25 +3717,24 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) else if (fastcmp(word, "MAINCFG")) { readmaincfg(f); - DEH_WriteUndoline(word, "", UNDO_HEADER); continue; } else if (fastcmp(word, "WIPES")) { readwipes(f); - DEH_WriteUndoline(word, "", UNDO_HEADER); continue; } word2 = strtok(NULL, " "); + if (word2) { + strupr(word2); + if (word2[strlen(word2) - 1] == '\n') + word2[strlen(word2) - 1] = '\0'; + i = atoi(word2); + } + else + i = 0; if (fastcmp(word, "CHARACTER")) { - if (word2) { - strupr(word2); - if (word2[strlen(word2)-1] == '\n') - word2[strlen(word2)-1] = '\0'; - i = atoi(word2); - } else - i = 0; if (i >= 0 && i < 32) readPlayer(f, i); else @@ -3398,47 +3742,89 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) deh_warning("Character %d out of range (0 - 31)", i); ignorelines(f); } - DEH_WriteUndoline(word, word2, UNDO_HEADER); continue; } - if (word2) + else if (fastcmp(word, "EMBLEM")) { - strupr(word2); - if (word2[strlen(word2)-1] == '\n') - word2[strlen(word2)-1] = '\0'; - i = atoi(word2); - if (fastcmp(word, "TEXTURE")) + if (!mainfile && !gamedataadded) + { + deh_warning("You must define a custom gamedata to use \"%s\"", word); + ignorelines(f); + } + else + { + if (!word2) + i = numemblems + 1; + + if (i > 0 && i <= MAXEMBLEMS) + { + if (numemblems < i) + numemblems = i; + reademblemdata(f, i); + } + else + { + deh_warning("Emblem number %d out of range (1 - %d)", i, MAXEMBLEMS); + ignorelines(f); + } + } + continue; + } + else if (fastcmp(word, "EXTRAEMBLEM")) + { + if (!mainfile && !gamedataadded) { - // Read texture from spec file. - readtexture(f, word2); - DEH_WriteUndoline(word, word2, UNDO_HEADER); + deh_warning("You must define a custom gamedata to use \"%s\"", word); + ignorelines(f); } - else if (fastcmp(word, "PATCH")) + else { - // Read patch from spec file. - readpatch(f, word2, wad); - DEH_WriteUndoline(word, word2, UNDO_HEADER); + if (!word2) + i = numextraemblems + 1; + + if (i > 0 && i <= MAXEXTRAEMBLEMS) + { + if (numextraemblems < i) + numextraemblems = i; + readextraemblemdata(f, i); + } + else + { + deh_warning("Extra emblem number %d out of range (1 - %d)", i, MAXEXTRAEMBLEMS); + ignorelines(f); + } } - else if (fastcmp(word, "THING") || fastcmp(word, "MOBJ") || fastcmp(word, "OBJECT")) + continue; + } + if (word2) + { + if (fastcmp(word, "THING") || fastcmp(word, "MOBJ") || fastcmp(word, "OBJECT")) { if (i == 0 && word2[0] != '0') // If word2 isn't a number i = get_mobjtype(word2); // find a thing by name - if (i < NUMMOBJTYPES && i >= 0) + if (i < NUMMOBJTYPES && i > 0) readthing(f, i); else { - deh_warning("Thing %d out of range (0 - %d)", i, NUMMOBJTYPES-1); + deh_warning("Thing %d out of range (1 - %d)", i, NUMMOBJTYPES-1); ignorelines(f); } - DEH_WriteUndoline(word, word2, UNDO_HEADER); } -/* else if (fastcmp(word, "ANIMTEX")) + else if (fastcmp(word, "SPRITE2")) { - readAnimTex(f, i); - }*/ + if (i == 0 && word2[0] != '0') // If word2 isn't a number + i = get_sprite2(word2); // find a sprite by name + if (i < (INT32)free_spr2 && i >= (INT32)SPR2_FIRSTFREESLOT) + readsprite2(f, i); + else + { + deh_warning("Sprite2 number %d out of range (%d - %d)", i, SPR2_FIRSTFREESLOT, free_spr2-1); + ignorelines(f); + } + } +#ifdef HWRENDER else if (fastcmp(word, "LIGHT")) { -#ifdef HWRENDER // TODO: Read lights by name if (i > 0 && i < NUMLIGHTS) readlight(f, i); @@ -3447,24 +3833,20 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) deh_warning("Light number %d out of range (1 - %d)", i, NUMLIGHTS-1); ignorelines(f); } - DEH_WriteUndoline(word, word2, UNDO_HEADER); -#endif } else if (fastcmp(word, "SPRITE")) { -#ifdef HWRENDER if (i == 0 && word2[0] != '0') // If word2 isn't a number i = get_sprite(word2); // find a sprite by name - if (i < NUMSPRITES && i >= 0) + if (i < NUMSPRITES && i > 0) readspritelight(f, i); else { deh_warning("Sprite number %d out of range (0 - %d)", i, NUMSPRITES-1); ignorelines(f); } - DEH_WriteUndoline(word, word2, UNDO_HEADER); -#endif } +#endif else if (fastcmp(word, "LEVEL")) { // Support using the actual map name, @@ -3481,7 +3863,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) deh_warning("Level number %d out of range (1 - %d)", i, NUMMAPS); ignorelines(f); } - DEH_WriteUndoline(word, word2, UNDO_HEADER); } else if (fastcmp(word, "CUTSCENE")) { @@ -3492,76 +3873,41 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) deh_warning("Cutscene number %d out of range (1 - 128)", i); ignorelines(f); } - DEH_WriteUndoline(word, word2, UNDO_HEADER); } - else if (fastcmp(word, "FRAME") || fastcmp(word, "STATE")) + else if (fastcmp(word, "PROMPT")) { - if (i == 0 && word2[0] != '0') // If word2 isn't a number - i = get_state(word2); // find a state by name - if (i < NUMSTATES && i >= 0) - readframe(f, i); + if (i > 0 && i < MAX_PROMPTS) + readtextprompt(f, i - 1); else { - deh_warning("Frame %d out of range (0 - %d)", i, NUMSTATES-1); + deh_warning("Prompt number %d out of range (1 - %d)", i, MAX_PROMPTS); ignorelines(f); } - DEH_WriteUndoline(word, word2, UNDO_HEADER); } - // <Callum> Added translations to this just in case its re-enabled -/* else if (fastcmp(word, "POINTER")) + else if (fastcmp(word, "FRAME") || fastcmp(word, "STATE")) { - word = strtok(NULL, " "); // get frame - word = strtok(NULL, ")"); - if (word) + if (i == 0 && word2[0] != '0') // If word2 isn't a number + i = get_state(word2); // find a state by name + if (i < NUMSTATES && i >= 0) + readframe(f, i); + else { - i = atoi(word); - if (i < NUMSTATES && i >= 0) - { - if (myfgets(s, MAXLINELEN, f)) - states[i].action = saveactions[searchvalue(s)]; - } - else - { - deh_warning("Pointer: Frame %d doesn't exist", i); - ignorelines(f); - } + deh_warning("Frame %d out of range (0 - %d)", i, NUMSTATES-1); + ignorelines(f); } - else - deh_warning("pointer (Frame %d) : missing ')'", i); - }*/ + } else if (fastcmp(word, "SOUND")) { if (i == 0 && word2[0] != '0') // If word2 isn't a number i = get_sfx(word2); // find a sound by name - if (i < NUMSFX && i >= 0) - readsound(f, i, savesfxnames); + if (i < NUMSFX && i > 0) + readsound(f, i); else { - deh_warning("Sound %d out of range (0 - %d)", i, NUMSFX-1); + deh_warning("Sound %d out of range (1 - %d)", i, NUMSFX-1); ignorelines(f); } - DEH_WriteUndoline(word, word2, UNDO_HEADER); } -/* else if (fastcmp(word, "SPRITE")) - { - if (i < NUMSPRITES && i >= 0) - { - if (myfgets(s, MAXLINELEN, f)) - { - INT32 k; - k = (searchvalue(s) - 151328)/8; - if (k >= 0 && k < NUMSPRITES) - sprnames[i] = savesprnames[k]; - else - { - deh_warning("Sprite %d: offset out of bounds", i); - ignorelines(f); - } - } - } - else - deh_warning("Sprite %d doesn't exist",i); - }*/ else if (fastcmp(word, "HUDITEM")) { if (i == 0 && word2[0] != '0') // If word2 isn't a number @@ -3573,51 +3919,23 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) deh_warning("HUD item number %d out of range (0 - %d)", i, NUMHUDITEMS-1); ignorelines(f); } - DEH_WriteUndoline(word, word2, UNDO_HEADER); - } - else if (fastcmp(word, "EMBLEM")) - { - if (!gamedataadded) - { - deh_warning("You must define a custom gamedata to use \"%s\"", word); - ignorelines(f); - } - else if (i > 0 && i <= MAXEMBLEMS) - { - if (numemblems < i) - numemblems = i; - reademblemdata(f, i); - } - else - { - deh_warning("Emblem number %d out of range (1 - %d)", i, MAXEMBLEMS); - ignorelines(f); - } - DEH_WriteUndoline(word, word2, UNDO_HEADER); } - else if (fastcmp(word, "EXTRAEMBLEM")) + else if (fastcmp(word, "MENU")) { - if (!gamedataadded) - { - deh_warning("You must define a custom gamedata to use \"%s\"", word); - ignorelines(f); - } - else if (i > 0 && i <= MAXEXTRAEMBLEMS) - { - if (numextraemblems < i) - numextraemblems = i; - readextraemblemdata(f, i); - } + if (i == 0 && word2[0] != '0') // If word2 isn't a number + i = get_menutype(word2); // find a huditem by name + if (i >= 1 && i < NUMMENUTYPES) + readmenu(f, i); else { - deh_warning("Extra emblem number %d out of range (1 - %d)", i, MAXEXTRAEMBLEMS); + // zero-based, but let's start at 1 + deh_warning("Menu number %d out of range (1 - %d)", i, NUMMENUTYPES-1); ignorelines(f); } - DEH_WriteUndoline(word, word2, UNDO_HEADER); } else if (fastcmp(word, "UNLOCKABLE")) { - if (!gamedataadded) + if (!mainfile && !gamedataadded) { deh_warning("You must define a custom gamedata to use \"%s\"", word); ignorelines(f); @@ -3629,11 +3947,10 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) deh_warning("Unlockable number %d out of range (1 - %d)", i, MAXUNLOCKABLES); ignorelines(f); } - DEH_WriteUndoline(word, word2, UNDO_HEADER); } else if (fastcmp(word, "CONDITIONSET")) { - if (!gamedataadded) + if (!mainfile && !gamedataadded) { deh_warning("You must define a custom gamedata to use \"%s\"", word); ignorelines(f); @@ -3645,25 +3962,26 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) deh_warning("Condition set number %d out of range (1 - %d)", i, MAXCONDITIONSETS); ignorelines(f); } - // no undo support for this insanity yet - //DEH_WriteUndoline(word, word2, UNDO_HEADER); } - else if (fastcmp(word, "SRB2")) + // Last I heard this crashes the game if you try to use it + // so this is disabled for now + // -- Monster Iestyn +/* else if (fastcmp(word, "SRB2")) { INT32 ver = searchvalue(strtok(NULL, "\n")); if (ver != PATCHVERSION) deh_warning("Patch is for SRB2 version %d,\nonly version %d is supported", ver, PATCHVERSION); - //DEH_WriteUndoline(word, va("%d", ver), UNDO_NONE); } // Clear all data in certain locations (mostly for unlocks) // Unless you REALLY want to piss people off, // define a custom gamedata /before/ doing this!! // (then again, modifiedgame will prevent game data saving anyway) +*/ else if (fastcmp(word, "CLEAR")) { boolean clearall = (fastcmp(word2, "ALL")); - if (!gamedataadded) + if (!mainfile && !gamedataadded) { deh_warning("You must define a custom gamedata to use \"%s\"", word); continue; @@ -3703,6 +4021,20 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) if (gamedataadded) G_LoadGameData(); + if (gamestate == GS_TITLESCREEN) + { + if (introchanged) + { + menuactive = false; + COM_BufAddText("playintro"); + } + else if (titlechanged) + { + menuactive = false; + COM_BufAddText("exitgame"); // Command_ExitGame_f() but delayed + } + } + dbg_line = -1; if (deh_num_warning) { @@ -3720,88 +4052,23 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) // read dehacked lump in a wad (there is special trick for for deh // file that are converted to wad in w_wad.c) -void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump) +void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump, boolean mainfile) { MYFILE f; -#ifdef DELFILE - unsocwad = wad; -#endif f.wad = wad; f.size = W_LumpLengthPwad(wad, lump); f.data = Z_Malloc(f.size + 1, PU_STATIC, NULL); W_ReadLumpPwad(wad, lump, f.data); f.curpos = f.data; f.data[f.size] = 0; - DEH_LoadDehackedFile(&f, wad); - DEH_WriteUndoline(va("# uload for wad: %u, lump: %u", wad, lump), NULL, UNDO_DONE); + DEH_LoadDehackedFile(&f, mainfile); Z_Free(f.data); } void DEH_LoadDehackedLump(lumpnum_t lumpnum) { - DEH_LoadDehackedLumpPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum)); -} - -#ifdef DELFILE -#define DUMPUNDONE - -// read (un)dehacked lump in wad's memory -void DEH_UnloadDehackedWad(UINT16 wad) -{ - undehacked_t *tmp, *curundo = unsocdata[wad]; - MYFILE f; - size_t len = 0; - char *data; -#ifdef DUMPUNDONE - FILE *UNDO = fopen("undo.soc", "wt"); -#endif - CONS_Printf(M_GetText("Unloading WAD SOC edits\n")); - while (curundo) - { - data = curundo->undata; - curundo = curundo->next; - if (data) - len += strlen(data); - len += 1; -#ifdef DUMPUNDONE - if (UNDO) - { - if (data) - fprintf(UNDO, "%s\n", data); - else - fprintf(UNDO, "\n"); - } -#endif - } -#ifndef DUMPUNDONE - if (UNDO) fclose(UNDO); -#endif - if (!len) return; - f.size = len; - data = f.data = Z_Malloc(f.size + 1, PU_STATIC, NULL); - curundo = unsocdata[wad]; - unsocdata[wad] = NULL; - while (curundo) - { - tmp = curundo; - curundo = curundo->next; - if (tmp->undata) - data += sprintf(data, "%s\n", tmp->undata); - else - data += sprintf(data, "\n"); - if (tmp->undata) free(tmp->undata); - free(tmp); - } - f.wad = wad; - f.curpos = f.data; - f.data[f.size] = 0; - disableundo = true; - DEH_LoadDehackedFile(&f); - disableundo = false; - Z_Free(f.data); + DEH_LoadDehackedLumpPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum), false); } -#endif //DELFILE - //////////////////////////////////////////////////////////////////////////////// // CRAZY LIST OF STATE NAMES AND ALL FROM HERE DOWN @@ -3830,61 +4097,65 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Thok "S_THOK", + // Player "S_PLAY_STND", - "S_PLAY_TAP1", - "S_PLAY_TAP2", - "S_PLAY_RUN1", - "S_PLAY_RUN2", - "S_PLAY_RUN3", - "S_PLAY_RUN4", - "S_PLAY_RUN5", - "S_PLAY_RUN6", - "S_PLAY_RUN7", - "S_PLAY_RUN8", - "S_PLAY_SPD1", - "S_PLAY_SPD2", - "S_PLAY_SPD3", - "S_PLAY_SPD4", - "S_PLAY_ATK1", - "S_PLAY_ATK2", - "S_PLAY_ATK3", - "S_PLAY_ATK4", - "S_PLAY_SPRING", - "S_PLAY_FALL1", - "S_PLAY_FALL2", - "S_PLAY_ABL1", - "S_PLAY_ABL2", - "S_PLAY_SPC1", - "S_PLAY_SPC2", - "S_PLAY_SPC3", - "S_PLAY_SPC4", - "S_PLAY_CLIMB1", - "S_PLAY_CLIMB2", - "S_PLAY_CLIMB3", - "S_PLAY_CLIMB4", - "S_PLAY_CLIMB5", - "S_PLAY_GASP", + "S_PLAY_WAIT", + "S_PLAY_WALK", + "S_PLAY_SKID", + "S_PLAY_RUN", + "S_PLAY_DASH", "S_PLAY_PAIN", - "S_PLAY_DIE", - "S_PLAY_TEETER1", - "S_PLAY_TEETER2", - "S_PLAY_CARRY", - "S_PLAY_SUPERSTAND", - "S_PLAY_SUPERWALK1", - "S_PLAY_SUPERWALK2", - "S_PLAY_SUPERFLY1", - "S_PLAY_SUPERFLY2", - "S_PLAY_SUPERTEETER", - "S_PLAY_SUPERHIT", - "S_PLAY_SUPERTRANS1", - "S_PLAY_SUPERTRANS2", - "S_PLAY_SUPERTRANS3", - "S_PLAY_SUPERTRANS4", - "S_PLAY_SUPERTRANS5", - "S_PLAY_SUPERTRANS6", - "S_PLAY_SUPERTRANS7", - "S_PLAY_SUPERTRANS8", - "S_PLAY_SUPERTRANS9", // This has special significance in the code. If you add more frames, search for it and make the appropriate changes. + "S_PLAY_STUN", + "S_PLAY_DEAD", + "S_PLAY_DRWN", + "S_PLAY_ROLL", + "S_PLAY_GASP", + "S_PLAY_JUMP", + "S_PLAY_SPRING", + "S_PLAY_FALL", + "S_PLAY_EDGE", + "S_PLAY_RIDE", + + // CA2_SPINDASH + "S_PLAY_SPINDASH", + + // CA_FLY/SWIM + "S_PLAY_FLY", + "S_PLAY_SWIM", + "S_PLAY_FLY_TIRED", + + // CA_GLIDEANDCLIMB + "S_PLAY_GLIDE", + "S_PLAY_CLING", + "S_PLAY_CLIMB", + + // CA_FLOAT/CA_SLOWFALL + "S_PLAY_FLOAT", + "S_PLAY_FLOAT_RUN", + + // CA_BOUNCE + "S_PLAY_BOUNCE", + "S_PLAY_BOUNCE_LANDING", + + // CA2_GUNSLINGER + "S_PLAY_FIRE", + "S_PLAY_FIRE_FINISH", + + // CA_TWINSPIN + "S_PLAY_TWINSPIN", + + // CA2_MELEE + "S_PLAY_MELEE", + "S_PLAY_MELEE_FINISH", + "S_PLAY_MELEE_LANDING", + + // SF_SUPER + "S_PLAY_SUPER_TRANS1", + "S_PLAY_SUPER_TRANS2", + "S_PLAY_SUPER_TRANS3", + "S_PLAY_SUPER_TRANS4", + "S_PLAY_SUPER_TRANS5", + "S_PLAY_SUPER_TRANS6", // This has special significance in the code. If you add more frames, search for it and make the appropriate changes. // technically the player goes here but it's an infinite tic state "S_OBJPLACE_DUMMY", @@ -3899,6 +4170,61 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Level end sign (uses player sprite) "S_PLAY_SIGN", + // NiGHTS character (uses player sprite) + "S_PLAY_NIGHTS_TRANS1", + "S_PLAY_NIGHTS_TRANS2", + "S_PLAY_NIGHTS_TRANS3", + "S_PLAY_NIGHTS_TRANS4", + "S_PLAY_NIGHTS_TRANS5", + "S_PLAY_NIGHTS_TRANS6", + + "S_PLAY_NIGHTS_STAND", + "S_PLAY_NIGHTS_FLOAT", + "S_PLAY_NIGHTS_STUN", + "S_PLAY_NIGHTS_PULL", + "S_PLAY_NIGHTS_ATTACK", + + "S_PLAY_NIGHTS_FLY0", + "S_PLAY_NIGHTS_DRILL0", + "S_PLAY_NIGHTS_FLY1", + "S_PLAY_NIGHTS_DRILL1", + "S_PLAY_NIGHTS_FLY2", + "S_PLAY_NIGHTS_DRILL2", + "S_PLAY_NIGHTS_FLY3", + "S_PLAY_NIGHTS_DRILL3", + "S_PLAY_NIGHTS_FLY4", + "S_PLAY_NIGHTS_DRILL4", + "S_PLAY_NIGHTS_FLY5", + "S_PLAY_NIGHTS_DRILL5", + "S_PLAY_NIGHTS_FLY6", + "S_PLAY_NIGHTS_DRILL6", + "S_PLAY_NIGHTS_FLY7", + "S_PLAY_NIGHTS_DRILL7", + "S_PLAY_NIGHTS_FLY8", + "S_PLAY_NIGHTS_DRILL8", + "S_PLAY_NIGHTS_FLY9", + "S_PLAY_NIGHTS_DRILL9", + "S_PLAY_NIGHTS_FLYA", + "S_PLAY_NIGHTS_DRILLA", + "S_PLAY_NIGHTS_FLYB", + "S_PLAY_NIGHTS_DRILLB", + "S_PLAY_NIGHTS_FLYC", + "S_PLAY_NIGHTS_DRILLC", + + // c: + "S_TAILSOVERLAY_STAND", + "S_TAILSOVERLAY_0DEGREES", + "S_TAILSOVERLAY_PLUS30DEGREES", + "S_TAILSOVERLAY_PLUS60DEGREES", + "S_TAILSOVERLAY_MINUS30DEGREES", + "S_TAILSOVERLAY_MINUS60DEGREES", + "S_TAILSOVERLAY_RUN", + "S_TAILSOVERLAY_FLY", + "S_TAILSOVERLAY_TIRE", + "S_TAILSOVERLAY_PAIN", + "S_TAILSOVERLAY_GASP", + "S_TAILSOVERLAY_EDGE", + // Blue Crawla "S_POSS_STND", "S_POSS_RUN1", @@ -3935,10 +4261,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_RBUZZFLY1", "S_RBUZZFLY2", - // AquaBuzz - "S_BBUZZFLY1", - "S_BBUZZFLY2", - // Jetty-Syn Bomber "S_JETBLOOK1", "S_JETBLOOK2", @@ -3975,7 +4297,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_DETON13", "S_DETON14", "S_DETON15", - "S_DETON16", // Skim Mine Dropper "S_SKIM1", @@ -4017,14 +4338,40 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_TURRETPOPDOWN7", "S_TURRETPOPDOWN8", - // Sharp - "S_SHARP_ROAM1", - "S_SHARP_ROAM2", - "S_SHARP_AIM1", - "S_SHARP_AIM2", - "S_SHARP_AIM3", - "S_SHARP_AIM4", - "S_SHARP_SPIN", + // Spincushion + "S_SPINCUSHION_LOOK", + "S_SPINCUSHION_CHASE1", + "S_SPINCUSHION_CHASE2", + "S_SPINCUSHION_CHASE3", + "S_SPINCUSHION_CHASE4", + "S_SPINCUSHION_AIM1", + "S_SPINCUSHION_AIM2", + "S_SPINCUSHION_AIM3", + "S_SPINCUSHION_AIM4", + "S_SPINCUSHION_AIM5", + "S_SPINCUSHION_SPIN1", + "S_SPINCUSHION_SPIN2", + "S_SPINCUSHION_SPIN3", + "S_SPINCUSHION_SPIN4", + "S_SPINCUSHION_STOP1", + "S_SPINCUSHION_STOP2", + "S_SPINCUSHION_STOP3", + "S_SPINCUSHION_STOP4", + + // Crushstacean + "S_CRUSHSTACEAN_ROAM1", + "S_CRUSHSTACEAN_ROAM2", + "S_CRUSHSTACEAN_ROAM3", + "S_CRUSHSTACEAN_ROAM4", + "S_CRUSHSTACEAN_ROAMPAUSE", + "S_CRUSHSTACEAN_PUNCH1", + "S_CRUSHSTACEAN_PUNCH2", + "S_CRUSHCLAW_AIM", + "S_CRUSHCLAW_OUT", + "S_CRUSHCLAW_STAY", + "S_CRUSHCLAW_IN", + "S_CRUSHCLAW_WAIT", + "S_CRUSHCHAIN", // Jet Jaw "S_JETJAW_ROAM1", @@ -4057,15 +4404,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Vulture "S_VULTURE_STND", - "S_VULTURE_VTOL1", - "S_VULTURE_VTOL2", - "S_VULTURE_VTOL3", - "S_VULTURE_VTOL4", + "S_VULTURE_DRIFT", "S_VULTURE_ZOOM1", "S_VULTURE_ZOOM2", - "S_VULTURE_ZOOM3", - "S_VULTURE_ZOOM4", - "S_VULTURE_ZOOM5", + "S_VULTURE_STUNNED", // Pointy "S_POINTY1", @@ -4073,11 +4415,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Robo-Hood "S_ROBOHOOD_LOOK", - "S_ROBOHOOD_STND", - "S_ROBOHOOD_SHOOT", - "S_ROBOHOOD_JUMP", + "S_ROBOHOOD_STAND", + "S_ROBOHOOD_FIRE1", + "S_ROBOHOOD_FIRE2", + "S_ROBOHOOD_JUMP1", "S_ROBOHOOD_JUMP2", - "S_ROBOHOOD_FALL", + "S_ROBOHOOD_JUMP3", // CastleBot FaceStabber "S_FACESTABBER_STND1", @@ -4090,6 +4433,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FACESTABBER_CHARGE2", "S_FACESTABBER_CHARGE3", "S_FACESTABBER_CHARGE4", + "S_FACESTABBER_PAIN", + "S_FACESTABBER_DIE1", + "S_FACESTABBER_DIE2", + "S_FACESTABBER_DIE3", + "S_FACESTABBERSPEAR", // Egg Guard "S_EGGGUARD_STND", @@ -4107,17 +4455,34 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Egg Shield for Egg Guard "S_EGGSHIELD", + "S_EGGSHIELDBREAK", // Green Snapper + "S_SNAPPER_SPAWN", + "S_SNAPPER_SPAWN2", "S_GSNAPPER_STND", "S_GSNAPPER1", "S_GSNAPPER2", "S_GSNAPPER3", "S_GSNAPPER4", + "S_SNAPPER_XPLD", + "S_SNAPPER_LEG", + "S_SNAPPER_LEGRAISE", + "S_SNAPPER_HEAD", // Minus + "S_MINUS_INIT", "S_MINUS_STND", - "S_MINUS_DIGGING", + "S_MINUS_DIGGING1", + "S_MINUS_DIGGING2", + "S_MINUS_DIGGING3", + "S_MINUS_DIGGING4", + "S_MINUS_BURST0", + "S_MINUS_BURST1", + "S_MINUS_BURST2", + "S_MINUS_BURST3", + "S_MINUS_BURST4", + "S_MINUS_BURST5", "S_MINUS_POPUP", "S_MINUS_UPWARD1", "S_MINUS_UPWARD2", @@ -4136,6 +4501,15 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_MINUS_DOWNWARD7", "S_MINUS_DOWNWARD8", + // Minus dirt + "S_MINUSDIRT1", + "S_MINUSDIRT2", + "S_MINUSDIRT3", + "S_MINUSDIRT4", + "S_MINUSDIRT5", + "S_MINUSDIRT6", + "S_MINUSDIRT7", + // Spring Shell "S_SSHELL_STND", "S_SSHELL_RUN1", @@ -4163,14 +4537,30 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_UNIDUS_RUN", "S_UNIDUS_BALL", + // Canarivore + "S_CANARIVORE_LOOK", + "S_CANARIVORE_AWAKEN1", + "S_CANARIVORE_AWAKEN2", + "S_CANARIVORE_AWAKEN3", + "S_CANARIVORE_GAS1", + "S_CANARIVORE_GAS2", + "S_CANARIVORE_GAS3", + "S_CANARIVORE_GAS4", + "S_CANARIVORE_GAS5", + "S_CANARIVORE_GASREPEAT", + "S_CANARIVORE_CLOSE1", + "S_CANARIVORE_CLOSE2", + "S_CANARIVOREGAS_1", + "S_CANARIVOREGAS_2", + "S_CANARIVOREGAS_3", + "S_CANARIVOREGAS_4", + "S_CANARIVOREGAS_5", + "S_CANARIVOREGAS_6", + "S_CANARIVOREGAS_7", + "S_CANARIVOREGAS_8", + // Boss Explosion - "S_BPLD1", - "S_BPLD2", - "S_BPLD3", - "S_BPLD4", - "S_BPLD5", - "S_BPLD6", - "S_BPLD7", + "S_BOSSEXPLODE", // S3&K Boss Explosion "S_SONIC3KBOSSEXPLOSION1", @@ -4272,6 +4662,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_GOOP1", "S_GOOP2", "S_GOOP3", + "S_GOOPTRAIL", // Boss 3 "S_EGGMOBILE3_STND", @@ -4390,6 +4781,96 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_JETFLAME1", "S_JETFLAME2", + // Boss 5 + "S_FANG_IDLE1", + "S_FANG_IDLE2", + "S_FANG_IDLE3", + "S_FANG_IDLE4", + "S_FANG_IDLE5", + "S_FANG_IDLE6", + "S_FANG_IDLE7", + "S_FANG_IDLE8", + "S_FANG_PAIN1", + "S_FANG_PAIN2", + "S_FANG_PATHINGSTART1", + "S_FANG_PATHINGSTART2", + "S_FANG_PATHING", + "S_FANG_BOUNCE1", + "S_FANG_BOUNCE2", + "S_FANG_BOUNCE3", + "S_FANG_BOUNCE4", + "S_FANG_FALL1", + "S_FANG_FALL2", + "S_FANG_CHECKPATH1", + "S_FANG_CHECKPATH2", + "S_FANG_PATHINGCONT1", + "S_FANG_PATHINGCONT2", + "S_FANG_PATHINGCONT3", + "S_FANG_SKID1", + "S_FANG_SKID2", + "S_FANG_SKID3", + "S_FANG_CHOOSEATTACK", + "S_FANG_FIRESTART1", + "S_FANG_FIRESTART2", + "S_FANG_FIRE1", + "S_FANG_FIRE2", + "S_FANG_FIRE3", + "S_FANG_FIRE4", + "S_FANG_FIREREPEAT", + "S_FANG_LOBSHOT1", + "S_FANG_LOBSHOT2", + "S_FANG_WAIT1", + "S_FANG_WAIT2", + "S_FANG_WALLHIT", + "S_FANG_PINCHPATHINGSTART1", + "S_FANG_PINCHPATHINGSTART2", + "S_FANG_PINCHPATHING", + "S_FANG_PINCHBOUNCE1", + "S_FANG_PINCHBOUNCE2", + "S_FANG_PINCHBOUNCE3", + "S_FANG_PINCHBOUNCE4", + "S_FANG_PINCHFALL1", + "S_FANG_PINCHFALL2", + "S_FANG_PINCHSKID1", + "S_FANG_PINCHSKID2", + "S_FANG_PINCHLOBSHOT1", + "S_FANG_PINCHLOBSHOT2", + "S_FANG_PINCHLOBSHOT3", + "S_FANG_PINCHLOBSHOT4", + "S_FANG_DIE1", + "S_FANG_DIE2", + "S_FANG_DIE3", + "S_FANG_DIE4", + "S_FANG_DIE5", + "S_FANG_DIE6", + "S_FANG_DIE7", + "S_FANG_DIE8", + "S_FANG_FLEEPATHING1", + "S_FANG_FLEEPATHING2", + "S_FANG_FLEEBOUNCE1", + "S_FANG_FLEEBOUNCE2", + "S_FANG_KO", + + "S_FBOMB1", + "S_FBOMB2", + "S_FBOMB_EXPL1", + "S_FBOMB_EXPL2", + "S_FBOMB_EXPL3", + "S_FBOMB_EXPL4", + "S_FBOMB_EXPL5", + "S_FBOMB_EXPL6", + "S_TNTDUST_1", + "S_TNTDUST_2", + "S_TNTDUST_3", + "S_TNTDUST_4", + "S_TNTDUST_5", + "S_TNTDUST_6", + "S_TNTDUST_7", + "S_TNTDUST_8", + "S_FSGNA", + "S_FSGNB", + "S_FSGNC", + // Black Eggman (Boss 7) "S_BLACKEGG_STND", "S_BLACKEGG_STND2", @@ -4626,7 +5107,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // S_PLAY_TAP1 "S_METALSONIC_WAIT1", "S_METALSONIC_WAIT2", - // S_PLAY_RUN1 + // S_PLAY_WALK "S_METALSONIC_WALK1", "S_METALSONIC_WALK2", "S_METALSONIC_WALK3", @@ -4644,11 +5125,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_METALSONIC_FLOAT", "S_METALSONIC_VECTOR", "S_METALSONIC_STUN", - "S_METALSONIC_BLOCK", "S_METALSONIC_RAISE", "S_METALSONIC_GATHER", "S_METALSONIC_DASH", "S_METALSONIC_BOUNCE", + "S_METALSONIC_BADBOUNCE", "S_METALSONIC_SHOOT", "S_METALSONIC_PAIN", "S_METALSONIC_DEATH", @@ -4674,27 +5155,33 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_RING", // Blue Sphere for special stages - "S_BLUEBALL", - "S_BLUEBALLSPARK", + "S_BLUESPHERE", + "S_BLUESPHEREBONUS", + "S_BLUESPHERESPARK", + + // Bomb Sphere + "S_BOMBSPHERE1", + "S_BOMBSPHERE2", + "S_BOMBSPHERE3", + "S_BOMBSPHERE4", + + // NiGHTS Chip + "S_NIGHTSCHIP", + "S_NIGHTSCHIPBONUS", + + // NiGHTS Star + "S_NIGHTSSTAR", + "S_NIGHTSSTARXMAS", // Gravity Wells for special stages "S_GRAVWELLGREEN", - "S_GRAVWELLGREEN2", - "S_GRAVWELLGREEN3", - "S_GRAVWELLRED", - "S_GRAVWELLRED2", - "S_GRAVWELLRED3", // Individual Team Rings "S_TEAMRING", - // Special Stage Token - "S_EMMY", - // Special Stage Token "S_TOKEN", - "S_MOVINGTOKEN", // CTF Flags "S_REDFLAG", @@ -4737,18 +5224,16 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_CEMG6", "S_CEMG7", - // Emeralds (for hunt) - "S_EMER1", - - "S_FAN", - "S_FAN2", - "S_FAN3", - "S_FAN4", - "S_FAN5", + // Emerald hunt shards + "S_SHRD1", + "S_SHRD2", + "S_SHRD3", // Bubble Source "S_BUBBLES1", "S_BUBBLES2", + "S_BUBBLES3", + "S_BUBBLES4", // Level End Sign "S_SIGN1", @@ -4805,16 +5290,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SIGN52", // Eggman "S_SIGN53", - // Steam Riser - "S_STEAM1", - "S_STEAM2", - "S_STEAM3", - "S_STEAM4", - "S_STEAM5", - "S_STEAM6", - "S_STEAM7", - "S_STEAM8", - // Spike Ball "S_SPIKEBALL1", "S_SPIKEBALL2", @@ -4825,7 +5300,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SPIKEBALL7", "S_SPIKEBALL8", - // Fire Shield's Spawn + // Elemental Shield's Spawn "S_SPINFIRE1", "S_SPINFIRE2", "S_SPINFIRE3", @@ -4843,190 +5318,169 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SPIKED1", "S_SPIKED2", + // Wall spikes + "S_WALLSPIKE1", + "S_WALLSPIKE2", + "S_WALLSPIKE3", + "S_WALLSPIKE4", + "S_WALLSPIKE5", + "S_WALLSPIKE6", + "S_WALLSPIKEBASE", + "S_WALLSPIKED1", + "S_WALLSPIKED2", + // Starpost "S_STARPOST_IDLE", "S_STARPOST_FLASH", + "S_STARPOST_STARTSPIN", "S_STARPOST_SPIN", + "S_STARPOST_ENDSPIN", // Big floating mine - "S_BIGMINE1", - "S_BIGMINE2", - "S_BIGMINE3", - "S_BIGMINE4", - "S_BIGMINE5", - "S_BIGMINE6", - "S_BIGMINE7", - "S_BIGMINE8", + "S_BIGMINE_IDLE", + "S_BIGMINE_ALERT1", + "S_BIGMINE_ALERT2", + "S_BIGMINE_ALERT3", + "S_BIGMINE_SET1", + "S_BIGMINE_SET2", + "S_BIGMINE_SET3", + "S_BIGMINE_BLAST1", + "S_BIGMINE_BLAST2", + "S_BIGMINE_BLAST3", + "S_BIGMINE_BLAST4", + "S_BIGMINE_BLAST5", // Cannon Launcher "S_CANNONLAUNCHER1", "S_CANNONLAUNCHER2", "S_CANNONLAUNCHER3", - // Super Ring Box - "S_SUPERRINGBOX", - "S_SUPERRINGBOX1", - "S_SUPERRINGBOX2", - "S_SUPERRINGBOX3", - "S_SUPERRINGBOX4", - "S_SUPERRINGBOX5", - "S_SUPERRINGBOX6", - - // Red Team Ring Box - "S_REDRINGBOX", - "S_REDRINGBOX1", - - // Blue Team Ring Box - "S_BLUERINGBOX", - "S_BLUERINGBOX1", - - // Super Sneakers Box - "S_SHTV", - "S_SHTV1", - "S_SHTV2", - "S_SHTV3", - "S_SHTV4", - "S_SHTV5", - "S_SHTV6", - - // Invincibility Box - "S_PINV", - "S_PINV1", - "S_PINV2", - "S_PINV3", - "S_PINV4", - "S_PINV5", - "S_PINV6", - - // 1-Up Box - "S_PRUP", - "S_PRUP1", - "S_PRUP2", - "S_PRUP3", - "S_PRUP4", - "S_PRUP5", - "S_PRUP6", - - // Ring Shield Box - "S_YLTV", - "S_YLTV1", - "S_YLTV2", - "S_YLTV3", - "S_YLTV4", - "S_YLTV5", - "S_YLTV6", - - // Force Shield Box - "S_BLTV1", - "S_BLTV2", - "S_BLTV3", - "S_BLTV4", - "S_BLTV5", - "S_BLTV6", - "S_BLTV7", - - // Bomb Shield Box - "S_BKTV1", - "S_BKTV2", - "S_BKTV3", - "S_BKTV4", - "S_BKTV5", - "S_BKTV6", - "S_BKTV7", - - // Jump Shield Box - "S_WHTV1", - "S_WHTV2", - "S_WHTV3", - "S_WHTV4", - "S_WHTV5", - "S_WHTV6", - "S_WHTV7", - - // Water Shield Box - "S_GRTV", - "S_GRTV1", - "S_GRTV2", - "S_GRTV3", - "S_GRTV4", - "S_GRTV5", - "S_GRTV6", - - // Pity Shield Box - "S_PITV1", - "S_PITV2", - "S_PITV3", - "S_PITV4", - "S_PITV5", - "S_PITV6", - "S_PITV7", - - // Eggman Box - "S_EGGTV1", - "S_EGGTV2", - "S_EGGTV3", - "S_EGGTV4", - "S_EGGTV5", - "S_EGGTV6", - "S_EGGTV7", - - // Teleport Box - "S_MIXUPBOX1", - "S_MIXUPBOX2", - "S_MIXUPBOX3", - "S_MIXUPBOX4", - "S_MIXUPBOX5", - "S_MIXUPBOX6", - "S_MIXUPBOX7", - - // Recycler Box - "S_RECYCLETV1", - "S_RECYCLETV2", - "S_RECYCLETV3", - "S_RECYCLETV4", - "S_RECYCLETV5", - "S_RECYCLETV6", - "S_RECYCLETV7", - - // Question Box - "S_RANDOMBOX1", - "S_RANDOMBOX2", - "S_RANDOMBOX3", - - // Gravity Boots Box - "S_GBTV1", - "S_GBTV2", - "S_GBTV3", - "S_GBTV4", - "S_GBTV5", - "S_GBTV6", - "S_GBTV7", - - // Score boxes - "S_SCORETVA1", - "S_SCORETVA2", - "S_SCORETVA3", - "S_SCORETVA4", - "S_SCORETVA5", - "S_SCORETVA6", - "S_SCORETVA7", - "S_SCORETVB1", - "S_SCORETVB2", - "S_SCORETVB3", - "S_SCORETVB4", - "S_SCORETVB5", - "S_SCORETVB6", - "S_SCORETVB7", - - // Monitor Explosion - "S_MONITOREXPLOSION1", - "S_MONITOREXPLOSION2", - - "S_REDMONITOREXPLOSION1", - "S_REDMONITOREXPLOSION2", - - "S_BLUEMONITOREXPLOSION1", - "S_BLUEMONITOREXPLOSION2", + // Monitor Miscellany + "S_BOXSPARKLE1", + "S_BOXSPARKLE2", + "S_BOXSPARKLE3", + "S_BOXSPARKLE4", + + "S_BOX_FLICKER", + "S_BOX_POP1", + "S_BOX_POP2", + + "S_GOLDBOX_FLICKER", + "S_GOLDBOX_OFF1", + "S_GOLDBOX_OFF2", + "S_GOLDBOX_OFF3", + "S_GOLDBOX_OFF4", + "S_GOLDBOX_OFF5", + "S_GOLDBOX_OFF6", + "S_GOLDBOX_OFF7", + + // Monitor States (one per box) + "S_MYSTERY_BOX", + "S_RING_BOX", + "S_PITY_BOX", + "S_ATTRACT_BOX", + "S_FORCE_BOX", + "S_ARMAGEDDON_BOX", + "S_WHIRLWIND_BOX", + "S_ELEMENTAL_BOX", + "S_SNEAKERS_BOX", + "S_INVULN_BOX", + "S_1UP_BOX", + "S_EGGMAN_BOX", + "S_MIXUP_BOX", + "S_GRAVITY_BOX", + "S_RECYCLER_BOX", + "S_SCORE1K_BOX", + "S_SCORE10K_BOX", + "S_FLAMEAURA_BOX", + "S_BUBBLEWRAP_BOX", + "S_THUNDERCOIN_BOX", + + // Gold Repeat Monitor States (one per box) + "S_PITY_GOLDBOX", + "S_ATTRACT_GOLDBOX", + "S_FORCE_GOLDBOX", + "S_ARMAGEDDON_GOLDBOX", + "S_WHIRLWIND_GOLDBOX", + "S_ELEMENTAL_GOLDBOX", + "S_SNEAKERS_GOLDBOX", + "S_INVULN_GOLDBOX", + "S_EGGMAN_GOLDBOX", + "S_GRAVITY_GOLDBOX", + "S_FLAMEAURA_GOLDBOX", + "S_BUBBLEWRAP_GOLDBOX", + "S_THUNDERCOIN_GOLDBOX", + + // Team Ring Boxes (these are special) + "S_RING_REDBOX1", + "S_RING_REDBOX2", + "S_REDBOX_POP1", + "S_REDBOX_POP2", + + "S_RING_BLUEBOX1", + "S_RING_BLUEBOX2", + "S_BLUEBOX_POP1", + "S_BLUEBOX_POP2", + + // Box Icons -- 2 states each, animation and action + "S_RING_ICON1", + "S_RING_ICON2", + + "S_PITY_ICON1", + "S_PITY_ICON2", + + "S_ATTRACT_ICON1", + "S_ATTRACT_ICON2", + + "S_FORCE_ICON1", + "S_FORCE_ICON2", + + "S_ARMAGEDDON_ICON1", + "S_ARMAGEDDON_ICON2", + + "S_WHIRLWIND_ICON1", + "S_WHIRLWIND_ICON2", + + "S_ELEMENTAL_ICON1", + "S_ELEMENTAL_ICON2", + + "S_SNEAKERS_ICON1", + "S_SNEAKERS_ICON2", + + "S_INVULN_ICON1", + "S_INVULN_ICON2", + + "S_1UP_ICON1", + "S_1UP_ICON2", + + "S_EGGMAN_ICON1", + "S_EGGMAN_ICON2", + + "S_MIXUP_ICON1", + "S_MIXUP_ICON2", + + "S_GRAVITY_ICON1", + "S_GRAVITY_ICON2", + + "S_RECYCLER_ICON1", + "S_RECYCLER_ICON2", + + "S_SCORE1K_ICON1", + "S_SCORE1K_ICON2", + + "S_SCORE10K_ICON1", + "S_SCORE10K_ICON2", + + "S_FLAMEAURA_ICON1", + "S_FLAMEAURA_ICON2", + + "S_BUBBLEWRAP_ICON1", + "S_BUBBLEWRAP_ICON2", + + "S_THUNDERCOIN_ICON1", + "S_THUNDERCOIN_ICON2", + + // --- "S_ROCKET", @@ -5057,39 +5511,60 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Arrow "S_ARROW", - "S_ARROWUP", - "S_ARROWDOWN", + "S_ARROWBONK", // Trapgoyle Demon fire - "S_DEMONFIRE1", - "S_DEMONFIRE2", - "S_DEMONFIRE3", - "S_DEMONFIRE4", - "S_DEMONFIRE5", - "S_DEMONFIRE6", + "S_DEMONFIRE", + // GFZ flowers "S_GFZFLOWERA", - "S_GFZFLOWERA2", - - "S_GFZFLOWERB1", - "S_GFZFLOWERB2", - - "S_GFZFLOWERC1", + "S_GFZFLOWERB", + "S_GFZFLOWERC", + "S_BLUEBERRYBUSH", "S_BERRYBUSH", "S_BUSH", - // THZ Plant - "S_THZPLANT1", - "S_THZPLANT2", - "S_THZPLANT3", - "S_THZPLANT4", + // Trees (both GFZ and misc) + "S_GFZTREE", + "S_GFZBERRYTREE", + "S_GFZCHERRYTREE", + "S_CHECKERTREE", + "S_CHECKERSUNSETTREE", + "S_FHZTREE", // Frozen Hillside + "S_FHZPINKTREE", + "S_POLYGONTREE", + "S_BUSHTREE", + "S_BUSHREDTREE", + "S_SPRINGTREE", + + // THZ flowers + "S_THZFLOWERA", // THZ1 Steam flower + "S_THZFLOWERB", // THZ1 Spin flower (red) + "S_THZFLOWERC", // THZ1 Spin flower (yellow) + + // THZ Steam Whistle tree/bush + "S_THZTREE", + "S_THZTREEBRANCH1", + "S_THZTREEBRANCH2", + "S_THZTREEBRANCH3", + "S_THZTREEBRANCH4", + "S_THZTREEBRANCH5", + "S_THZTREEBRANCH6", + "S_THZTREEBRANCH7", + "S_THZTREEBRANCH8", + "S_THZTREEBRANCH9", + "S_THZTREEBRANCH10", + "S_THZTREEBRANCH11", + "S_THZTREEBRANCH12", + "S_THZTREEBRANCH13", // THZ Alarm "S_ALARM1", // Deep Sea Gargoyle "S_GARGOYLE", + "S_BIGGARGOYLE", // DSZ Seaweed "S_SEAWEED1", @@ -5120,14 +5595,34 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Blue Crystal "S_BLUECRYSTAL1", + // Kelp, + "S_KELP", + + // DSZ Stalagmites + "S_DSZSTALAGMITE", + "S_DSZ2STALAGMITE", + + // DSZ Light beam + "S_LIGHTBEAM1", + "S_LIGHTBEAM2", + "S_LIGHTBEAM3", + "S_LIGHTBEAM4", + "S_LIGHTBEAM5", + "S_LIGHTBEAM6", + "S_LIGHTBEAM7", + "S_LIGHTBEAM8", + "S_LIGHTBEAM9", + "S_LIGHTBEAM10", + "S_LIGHTBEAM11", + "S_LIGHTBEAM12", + // CEZ Chain "S_CEZCHAIN", // Flame - "S_FLAME1", - "S_FLAME2", - "S_FLAME3", - "S_FLAME4", + "S_FLAME", + "S_FLAMEPARTICLE", + "S_FLAMEREST", // Eggman Statue "S_EGGSTATUE1", @@ -5136,19 +5631,82 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SLING1", "S_SLING2", - // CEZ Small Mace Chain + // CEZ maces and chains "S_SMALLMACECHAIN", - - // CEZ Big Mace Chain "S_BIGMACECHAIN", - - // CEZ Small Mace "S_SMALLMACE", - - // CEZ Big Mace "S_BIGMACE", - - "S_CEZFLOWER1", + "S_SMALLGRABCHAIN", + "S_BIGGRABCHAIN", + + // Yellow spring on a ball + "S_YELLOWSPRINGBALL", + "S_YELLOWSPRINGBALL2", + "S_YELLOWSPRINGBALL3", + "S_YELLOWSPRINGBALL4", + "S_YELLOWSPRINGBALL5", + + // Red spring on a ball + "S_REDSPRINGBALL", + "S_REDSPRINGBALL2", + "S_REDSPRINGBALL3", + "S_REDSPRINGBALL4", + "S_REDSPRINGBALL5", + + // Small Firebar + "S_SMALLFIREBAR1", + "S_SMALLFIREBAR2", + "S_SMALLFIREBAR3", + "S_SMALLFIREBAR4", + "S_SMALLFIREBAR5", + "S_SMALLFIREBAR6", + "S_SMALLFIREBAR7", + "S_SMALLFIREBAR8", + "S_SMALLFIREBAR9", + "S_SMALLFIREBAR10", + "S_SMALLFIREBAR11", + "S_SMALLFIREBAR12", + "S_SMALLFIREBAR13", + "S_SMALLFIREBAR14", + "S_SMALLFIREBAR15", + "S_SMALLFIREBAR16", + + // Big Firebar + "S_BIGFIREBAR1", + "S_BIGFIREBAR2", + "S_BIGFIREBAR3", + "S_BIGFIREBAR4", + "S_BIGFIREBAR5", + "S_BIGFIREBAR6", + "S_BIGFIREBAR7", + "S_BIGFIREBAR8", + "S_BIGFIREBAR9", + "S_BIGFIREBAR10", + "S_BIGFIREBAR11", + "S_BIGFIREBAR12", + "S_BIGFIREBAR13", + "S_BIGFIREBAR14", + "S_BIGFIREBAR15", + "S_BIGFIREBAR16", + + "S_CEZFLOWER", + "S_CEZPOLE", + "S_CEZBANNER", + "S_PINETREE", + "S_CEZBUSH1", + "S_CEZBUSH2", + "S_CANDLE", + "S_CANDLEPRICKET", + "S_FLAMEHOLDER", + "S_FIRETORCH", + "S_WAVINGFLAG", + "S_WAVINGFLAGSEG", + "S_CRAWLASTATUE", + "S_FACESTABBERSTATUE", + "S_SUSPICIOUSFACESTABBERSTATUE_WAIT", + "S_SUSPICIOUSFACESTABBERSTATUE_BURST1", + "S_SUSPICIOUSFACESTABBERSTATUE_BURST2", + "S_BRAMBLES", // Big Tumbleweed "S_BIGTUMBLEWEED", @@ -5177,6 +5735,95 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_CACTI2", "S_CACTI3", "S_CACTI4", + "S_CACTI5", + "S_CACTI6", + "S_CACTI7", + "S_CACTI8", + "S_CACTI9", + + // Warning signs sprites + "S_ARIDSIGN_CAUTION", + "S_ARIDSIGN_CACTI", + "S_ARIDSIGN_SHARPTURN", + + // Oil lamp + "S_OILLAMP", + "S_OILLAMPFLARE", + + // TNT barrel + "S_TNTBARREL_STND1", + "S_TNTBARREL_EXPL1", + "S_TNTBARREL_EXPL2", + "S_TNTBARREL_EXPL3", + "S_TNTBARREL_EXPL4", + "S_TNTBARREL_EXPL5", + "S_TNTBARREL_EXPL6", + "S_TNTBARREL_FLYING", + + // TNT proximity shell + "S_PROXIMITY_TNT", + "S_PROXIMITY_TNT_TRIGGER1", + "S_PROXIMITY_TNT_TRIGGER2", + "S_PROXIMITY_TNT_TRIGGER3", + "S_PROXIMITY_TNT_TRIGGER4", + "S_PROXIMITY_TNT_TRIGGER5", + "S_PROXIMITY_TNT_TRIGGER6", + "S_PROXIMITY_TNT_TRIGGER7", + "S_PROXIMITY_TNT_TRIGGER8", + "S_PROXIMITY_TNT_TRIGGER9", + "S_PROXIMITY_TNT_TRIGGER10", + "S_PROXIMITY_TNT_TRIGGER11", + "S_PROXIMITY_TNT_TRIGGER12", + "S_PROXIMITY_TNT_TRIGGER13", + "S_PROXIMITY_TNT_TRIGGER14", + "S_PROXIMITY_TNT_TRIGGER15", + "S_PROXIMITY_TNT_TRIGGER16", + "S_PROXIMITY_TNT_TRIGGER17", + "S_PROXIMITY_TNT_TRIGGER18", + "S_PROXIMITY_TNT_TRIGGER19", + "S_PROXIMITY_TNT_TRIGGER20", + "S_PROXIMITY_TNT_TRIGGER21", + "S_PROXIMITY_TNT_TRIGGER22", + "S_PROXIMITY_TNT_TRIGGER23", + + // Dust devil + "S_DUSTDEVIL", + "S_DUSTLAYER1", + "S_DUSTLAYER2", + "S_DUSTLAYER3", + "S_DUSTLAYER4", + "S_DUSTLAYER5", + "S_ARIDDUST1", + "S_ARIDDUST2", + "S_ARIDDUST3", + + // Minecart + "S_MINECART_IDLE", + "S_MINECART_DTH1", + "S_MINECARTEND", + "S_MINECARTSEG_FRONT", + "S_MINECARTSEG_BACK", + "S_MINECARTSEG_LEFT", + "S_MINECARTSEG_RIGHT", + "S_MINECARTSIDEMARK1", + "S_MINECARTSIDEMARK2", + "S_MINECARTSPARK", + + // Saloon door + "S_SALOONDOOR", + "S_SALOONDOORTHINKER", + + // Train cameo + "S_TRAINCAMEOSPAWNER_1", + "S_TRAINCAMEOSPAWNER_2", + "S_TRAINCAMEOSPAWNER_3", + "S_TRAINCAMEOSPAWNER_4", + "S_TRAINCAMEOSPAWNER_5", + "S_TRAINPUFFMAKER", + + // Train + "S_TRAINDUST", + "S_TRAINSTEAM", // Flame jet "S_FLAMEJETSTND", @@ -5189,36 +5836,13 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Spinning flame jets "S_FJSPINAXISA1", // Counter-clockwise "S_FJSPINAXISA2", - "S_FJSPINAXISA3", - "S_FJSPINAXISA4", - "S_FJSPINAXISA5", - "S_FJSPINAXISA6", - "S_FJSPINAXISA7", - "S_FJSPINAXISA8", - "S_FJSPINAXISA9", - "S_FJSPINHELPERA1", - "S_FJSPINHELPERA2", - "S_FJSPINHELPERA3", "S_FJSPINAXISB1", // Clockwise "S_FJSPINAXISB2", - "S_FJSPINAXISB3", - "S_FJSPINAXISB4", - "S_FJSPINAXISB5", - "S_FJSPINAXISB6", - "S_FJSPINAXISB7", - "S_FJSPINAXISB8", - "S_FJSPINAXISB9", - "S_FJSPINHELPERB1", - "S_FJSPINHELPERB2", - "S_FJSPINHELPERB3", // Blade's flame "S_FLAMEJETFLAMEB1", "S_FLAMEJETFLAMEB2", "S_FLAMEJETFLAMEB3", - "S_FLAMEJETFLAMEB4", - "S_FLAMEJETFLAMEB5", - "S_FLAMEJETFLAMEB6", // Trapgoyles "S_TRAPGOYLE", @@ -5266,7 +5890,63 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Xmas-specific stuff "S_XMASPOLE", "S_CANDYCANE", - "S_SNOWMAN", + "S_SNOWMAN", // normal + "S_SNOWMANHAT", // with hat + scarf + "S_LAMPPOST1", // normal + "S_LAMPPOST2", // with snow + "S_HANGSTAR", + // Xmas GFZ bushes + "S_XMASBLUEBERRYBUSH", + "S_XMASBERRYBUSH", + "S_XMASBUSH", + // FHZ + "S_FHZICE1", + "S_FHZICE2", + + // Halloween Scenery + // Pumpkins + "S_JACKO1", + "S_JACKO1OVERLAY_1", + "S_JACKO1OVERLAY_2", + "S_JACKO1OVERLAY_3", + "S_JACKO1OVERLAY_4", + "S_JACKO2", + "S_JACKO2OVERLAY_1", + "S_JACKO2OVERLAY_2", + "S_JACKO2OVERLAY_3", + "S_JACKO2OVERLAY_4", + "S_JACKO3", + "S_JACKO3OVERLAY_1", + "S_JACKO3OVERLAY_2", + "S_JACKO3OVERLAY_3", + "S_JACKO3OVERLAY_4", + // Dr Seuss Trees + "S_HHZTREE_TOP", + "S_HHZTREE_TRUNK", + "S_HHZTREE_LEAF", + // Mushroom + "S_HHZSHROOM_1", + "S_HHZSHROOM_2", + "S_HHZSHROOM_3", + "S_HHZSHROOM_4", + "S_HHZSHROOM_5", + "S_HHZSHROOM_6", + "S_HHZSHROOM_7", + "S_HHZSHROOM_8", + "S_HHZSHROOM_9", + "S_HHZSHROOM_10", + "S_HHZSHROOM_11", + "S_HHZSHROOM_12", + "S_HHZSHROOM_13", + "S_HHZSHROOM_14", + "S_HHZSHROOM_15", + "S_HHZSHROOM_16", + // Misc + "S_HHZGRASS", + "S_HHZTENT1", + "S_HHZTENT2", + "S_HHZSTALAGMITE_TALL", + "S_HHZSTALAGMITE_SHORT", // Botanic Serenity's loads of scenery states "S_BSZTALLFLOWER_RED", @@ -5313,8 +5993,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_BSZVINE_ORANGE", "S_BSZSHRUB", "S_BSZCLOVER", - "S_BSZFISH", - "S_BSZSUNFLOWER", + "S_BIG_PALMTREE_TRUNK", + "S_BIG_PALMTREE_TOP", + "S_PALMTREE_TRUNK", + "S_PALMTREE_TOP", "S_DBALL1", "S_DBALL2", @@ -5358,6 +6040,22 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ARMF14", "S_ARMF15", "S_ARMF16", + "S_ARMF17", + "S_ARMF18", + "S_ARMF19", + "S_ARMF20", + "S_ARMF21", + "S_ARMF22", + "S_ARMF23", + "S_ARMF24", + "S_ARMF25", + "S_ARMF26", + "S_ARMF27", + "S_ARMF28", + "S_ARMF29", + "S_ARMF30", + "S_ARMF31", + "S_ARMF32", "S_ARMB1", "S_ARMB2", @@ -5375,6 +6073,22 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ARMB14", "S_ARMB15", "S_ARMB16", + "S_ARMB17", + "S_ARMB18", + "S_ARMB19", + "S_ARMB20", + "S_ARMB21", + "S_ARMB22", + "S_ARMB23", + "S_ARMB24", + "S_ARMB25", + "S_ARMB26", + "S_ARMB27", + "S_ARMB28", + "S_ARMB29", + "S_ARMB30", + "S_ARMB31", + "S_ARMB32", "S_WIND1", "S_WIND2", @@ -5397,6 +6111,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_MAGN10", "S_MAGN11", "S_MAGN12", + "S_MAGN13", "S_FORC1", "S_FORC2", @@ -5420,6 +6135,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FORC19", "S_FORC20", + "S_FORC21", + "S_ELEM1", "S_ELEM2", "S_ELEM3", @@ -5433,6 +6150,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ELEM11", "S_ELEM12", + "S_ELEM13", + "S_ELEM14", + "S_ELEMF1", "S_ELEMF2", "S_ELEMF3", @@ -5441,6 +6161,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ELEMF6", "S_ELEMF7", "S_ELEMF8", + "S_ELEMF9", + "S_ELEMF10", "S_PITY1", "S_PITY2", @@ -5448,10 +6170,84 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_PITY4", "S_PITY5", "S_PITY6", - "S_PITY7", - "S_PITY8", - "S_PITY9", - "S_PITY10", + + "S_FIRS1", + "S_FIRS2", + "S_FIRS3", + "S_FIRS4", + "S_FIRS5", + "S_FIRS6", + "S_FIRS7", + "S_FIRS8", + "S_FIRS9", + + "S_FIRS10", + "S_FIRS11", + + "S_FIRSB1", + "S_FIRSB2", + "S_FIRSB3", + "S_FIRSB4", + "S_FIRSB5", + "S_FIRSB6", + "S_FIRSB7", + "S_FIRSB8", + "S_FIRSB9", + + "S_FIRSB10", + + "S_BUBS1", + "S_BUBS2", + "S_BUBS3", + "S_BUBS4", + "S_BUBS5", + "S_BUBS6", + "S_BUBS7", + "S_BUBS8", + "S_BUBS9", + + "S_BUBS10", + "S_BUBS11", + + "S_BUBSB1", + "S_BUBSB2", + "S_BUBSB3", + "S_BUBSB4", + + "S_BUBSB5", + "S_BUBSB6", + + "S_ZAPS1", + "S_ZAPS2", + "S_ZAPS3", + "S_ZAPS4", + "S_ZAPS5", + "S_ZAPS6", + "S_ZAPS7", + "S_ZAPS8", + "S_ZAPS9", + "S_ZAPS10", + "S_ZAPS11", + "S_ZAPS12", + "S_ZAPS13", // blank frame + "S_ZAPS14", + "S_ZAPS15", + "S_ZAPS16", + + "S_ZAPSB1", // blank frame + "S_ZAPSB2", + "S_ZAPSB3", + "S_ZAPSB4", + "S_ZAPSB5", + "S_ZAPSB6", + "S_ZAPSB7", + "S_ZAPSB8", + "S_ZAPSB9", + "S_ZAPSB10", + "S_ZAPSB11", // blank frame + + // Thunder spark + "S_THUNDERCOIN_SPARK", // Invincibility Sparkles "S_IVSP", @@ -5463,57 +6259,228 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SSPK4", "S_SSPK5", - // Freed Birdie - "S_BIRD1", - "S_BIRD2", - "S_BIRD3", - - // Freed Bunny - "S_BUNNY1", - "S_BUNNY2", - "S_BUNNY3", - "S_BUNNY4", - "S_BUNNY5", - "S_BUNNY6", - "S_BUNNY7", - "S_BUNNY8", - "S_BUNNY9", - "S_BUNNY10", - - // Freed Mouse - "S_MOUSE1", - "S_MOUSE2", - - // Freed Chicken - "S_CHICKEN1", - "S_CHICKENHOP", - "S_CHICKENFLY1", - "S_CHICKENFLY2", - - // Freed Cow - "S_COW1", - "S_COW2", - "S_COW3", - "S_COW4", - - // Red Birdie in Bubble - "S_RBIRD1", - "S_RBIRD2", - "S_RBIRD3", + // Flicky-sized bubble + "S_FLICKY_BUBBLE", + + // Bluebird + "S_FLICKY_01_OUT", + "S_FLICKY_01_FLAP1", + "S_FLICKY_01_FLAP2", + "S_FLICKY_01_FLAP3", + "S_FLICKY_01_STAND", + "S_FLICKY_01_CENTER", + + // Rabbit + "S_FLICKY_02_OUT", + "S_FLICKY_02_AIM", + "S_FLICKY_02_HOP", + "S_FLICKY_02_UP", + "S_FLICKY_02_DOWN", + "S_FLICKY_02_STAND", + "S_FLICKY_02_CENTER", + + // Chicken + "S_FLICKY_03_OUT", + "S_FLICKY_03_AIM", + "S_FLICKY_03_HOP", + "S_FLICKY_03_UP", + "S_FLICKY_03_FLAP1", + "S_FLICKY_03_FLAP2", + "S_FLICKY_03_STAND", + "S_FLICKY_03_CENTER", + + // Seal + "S_FLICKY_04_OUT", + "S_FLICKY_04_AIM", + "S_FLICKY_04_HOP", + "S_FLICKY_04_UP", + "S_FLICKY_04_DOWN", + "S_FLICKY_04_SWIM1", + "S_FLICKY_04_SWIM2", + "S_FLICKY_04_SWIM3", + "S_FLICKY_04_SWIM4", + "S_FLICKY_04_STAND", + "S_FLICKY_04_CENTER", + + // Pig + "S_FLICKY_05_OUT", + "S_FLICKY_05_AIM", + "S_FLICKY_05_HOP", + "S_FLICKY_05_UP", + "S_FLICKY_05_DOWN", + "S_FLICKY_05_STAND", + "S_FLICKY_05_CENTER", + + // Chipmunk + "S_FLICKY_06_OUT", + "S_FLICKY_06_AIM", + "S_FLICKY_06_HOP", + "S_FLICKY_06_UP", + "S_FLICKY_06_DOWN", + "S_FLICKY_06_STAND", + "S_FLICKY_06_CENTER", + + // Penguin + "S_FLICKY_07_OUT", + "S_FLICKY_07_AIML", + "S_FLICKY_07_HOPL", + "S_FLICKY_07_UPL", + "S_FLICKY_07_DOWNL", + "S_FLICKY_07_AIMR", + "S_FLICKY_07_HOPR", + "S_FLICKY_07_UPR", + "S_FLICKY_07_DOWNR", + "S_FLICKY_07_SWIM1", + "S_FLICKY_07_SWIM2", + "S_FLICKY_07_SWIM3", + "S_FLICKY_07_STAND", + "S_FLICKY_07_CENTER", + + // Fish + "S_FLICKY_08_OUT", + "S_FLICKY_08_AIM", + "S_FLICKY_08_HOP", + "S_FLICKY_08_FLAP1", + "S_FLICKY_08_FLAP2", + "S_FLICKY_08_FLAP3", + "S_FLICKY_08_FLAP4", + "S_FLICKY_08_SWIM1", + "S_FLICKY_08_SWIM2", + "S_FLICKY_08_SWIM3", + "S_FLICKY_08_SWIM4", + "S_FLICKY_08_STAND", + "S_FLICKY_08_CENTER", + + // Ram + "S_FLICKY_09_OUT", + "S_FLICKY_09_AIM", + "S_FLICKY_09_HOP", + "S_FLICKY_09_UP", + "S_FLICKY_09_DOWN", + "S_FLICKY_09_STAND", + "S_FLICKY_09_CENTER", + + // Puffin + "S_FLICKY_10_OUT", + "S_FLICKY_10_FLAP1", + "S_FLICKY_10_FLAP2", + "S_FLICKY_10_STAND", + "S_FLICKY_10_CENTER", + + // Cow + "S_FLICKY_11_OUT", + "S_FLICKY_11_AIM", + "S_FLICKY_11_RUN1", + "S_FLICKY_11_RUN2", + "S_FLICKY_11_RUN3", + "S_FLICKY_11_STAND", + "S_FLICKY_11_CENTER", + + // Rat + "S_FLICKY_12_OUT", + "S_FLICKY_12_AIM", + "S_FLICKY_12_RUN1", + "S_FLICKY_12_RUN2", + "S_FLICKY_12_RUN3", + "S_FLICKY_12_STAND", + "S_FLICKY_12_CENTER", + + // Bear + "S_FLICKY_13_OUT", + "S_FLICKY_13_AIM", + "S_FLICKY_13_HOP", + "S_FLICKY_13_UP", + "S_FLICKY_13_DOWN", + "S_FLICKY_13_STAND", + "S_FLICKY_13_CENTER", + + // Dove + "S_FLICKY_14_OUT", + "S_FLICKY_14_FLAP1", + "S_FLICKY_14_FLAP2", + "S_FLICKY_14_FLAP3", + "S_FLICKY_14_STAND", + "S_FLICKY_14_CENTER", + + // Cat + "S_FLICKY_15_OUT", + "S_FLICKY_15_AIM", + "S_FLICKY_15_HOP", + "S_FLICKY_15_UP", + "S_FLICKY_15_DOWN", + "S_FLICKY_15_STAND", + "S_FLICKY_15_CENTER", + + // Canary + "S_FLICKY_16_OUT", + "S_FLICKY_16_FLAP1", + "S_FLICKY_16_FLAP2", + "S_FLICKY_16_FLAP3", + "S_FLICKY_16_STAND", + "S_FLICKY_16_CENTER", + + // Spider + "S_SECRETFLICKY_01_OUT", + "S_SECRETFLICKY_01_AIM", + "S_SECRETFLICKY_01_HOP", + "S_SECRETFLICKY_01_UP", + "S_SECRETFLICKY_01_DOWN", + "S_SECRETFLICKY_01_STAND", + "S_SECRETFLICKY_01_CENTER", + + // Bat + "S_SECRETFLICKY_02_OUT", + "S_SECRETFLICKY_02_FLAP1", + "S_SECRETFLICKY_02_FLAP2", + "S_SECRETFLICKY_02_FLAP3", + "S_SECRETFLICKY_02_STAND", + "S_SECRETFLICKY_02_CENTER", + + // Fan + "S_FAN", + "S_FAN2", + "S_FAN3", + "S_FAN4", + "S_FAN5", + + // Steam Riser + "S_STEAM1", + "S_STEAM2", + "S_STEAM3", + "S_STEAM4", + "S_STEAM5", + "S_STEAM6", + "S_STEAM7", + "S_STEAM8", + + // Bumpers + "S_BUMPER", + "S_BUMPERHIT", + + // Balloons + "S_BALLOON", + "S_BALLOONPOP1", + "S_BALLOONPOP2", + "S_BALLOONPOP3", + "S_BALLOONPOP4", + "S_BALLOONPOP5", + "S_BALLOONPOP6", + // Yellow Spring "S_YELLOWSPRING", "S_YELLOWSPRING2", "S_YELLOWSPRING3", "S_YELLOWSPRING4", "S_YELLOWSPRING5", + // Red Spring "S_REDSPRING", "S_REDSPRING2", "S_REDSPRING3", "S_REDSPRING4", "S_REDSPRING5", - // Blue Springs + // Blue Spring "S_BLUESPRING", "S_BLUESPRING2", "S_BLUESPRING3", @@ -5540,6 +6507,46 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_RDIAG7", "S_RDIAG8", + // Blue Diagonal Spring + "S_BDIAG1", + "S_BDIAG2", + "S_BDIAG3", + "S_BDIAG4", + "S_BDIAG5", + "S_BDIAG6", + "S_BDIAG7", + "S_BDIAG8", + + // Yellow Side Spring + "S_YHORIZ1", + "S_YHORIZ2", + "S_YHORIZ3", + "S_YHORIZ4", + "S_YHORIZ5", + "S_YHORIZ6", + "S_YHORIZ7", + "S_YHORIZ8", + + // Red Side Spring + "S_RHORIZ1", + "S_RHORIZ2", + "S_RHORIZ3", + "S_RHORIZ4", + "S_RHORIZ5", + "S_RHORIZ6", + "S_RHORIZ7", + "S_RHORIZ8", + + // Blue Side Spring + "S_BHORIZ1", + "S_BHORIZ2", + "S_BHORIZ3", + "S_BHORIZ4", + "S_BHORIZ5", + "S_BHORIZ6", + "S_BHORIZ7", + "S_BHORIZ8", + // Rain "S_RAIN1", "S_RAINRETURN", @@ -5574,14 +6581,29 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Bubbles "S_SMALLBUBBLE", - "S_SMALLBUBBLE1", "S_MEDIUMBUBBLE", - "S_MEDIUMBUBBLE1", - "S_LARGEBUBBLE", + "S_LARGEBUBBLE1", + "S_LARGEBUBBLE2", "S_EXTRALARGEBUBBLE", // breathable "S_POP1", // Extra Large bubble goes POP! + "S_WATERZAP", + + // Spindash dust + "S_SPINDUST1", + "S_SPINDUST2", + "S_SPINDUST3", + "S_SPINDUST4", + "S_SPINDUST_BUBBLE1", + "S_SPINDUST_BUBBLE2", + "S_SPINDUST_BUBBLE3", + "S_SPINDUST_BUBBLE4", + "S_SPINDUST_FIRE1", + "S_SPINDUST_FIRE2", + "S_SPINDUST_FIRE3", + "S_SPINDUST_FIRE4", + "S_FOG1", "S_FOG2", "S_FOG3", @@ -5600,7 +6622,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SEED", "S_PARTICLE", - "S_PARTICLEGEN", // Score Logos "S_SCRA", // 100 @@ -5614,6 +6635,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SCRI", // 4000 (mario) "S_SCRJ", // 8000 (mario) "S_SCRK", // 1UP (mario) + "S_SCRL", // 10 // Drowning Timer Numbers "S_ZERO1", @@ -5623,14 +6645,23 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FOUR1", "S_FIVE1", + "S_ZERO2", + "S_ONE2", + "S_TWO2", + "S_THREE2", + "S_FOUR2", + "S_FIVE2", + + "S_LOCKON1", + "S_LOCKON2", + // Tag Sign - "S_TTAG1", + "S_TTAG", // Got Flag Sign - "S_GOTFLAG1", - "S_GOTFLAG2", - "S_GOTFLAG3", - "S_GOTFLAG4", + "S_GOTFLAG", + + "S_CORK", // Red Ring "S_RRNG1", @@ -5805,20 +6836,19 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FIREBALLEXP2", "S_FIREBALLEXP3", "S_SHELL", - "S_SHELL1", - "S_SHELL2", - "S_SHELL3", - "S_SHELL4", - "S_PUMA1", - "S_PUMA2", - "S_PUMA3", - "S_PUMA4", - "S_PUMA5", - "S_PUMA6", - "S_HAMMER1", - "S_HAMMER2", - "S_HAMMER3", - "S_HAMMER4", + "S_PUMA_START1", + "S_PUMA_START2", + "S_PUMA_UP1", + "S_PUMA_UP2", + "S_PUMA_UP3", + "S_PUMA_DOWN1", + "S_PUMA_DOWN2", + "S_PUMA_DOWN3", + "S_PUMATRAIL1", + "S_PUMATRAIL2", + "S_PUMATRAIL3", + "S_PUMATRAIL4", + "S_HAMMER", "S_KOOPA1", "S_KOOPA2", "S_KOOPAFLAME1", @@ -5832,8 +6862,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_TOAD", // Nights-specific stuff - "S_NIGHTSDRONE1", - "S_NIGHTSDRONE2", + "S_NIGHTSDRONE_MAN1", + "S_NIGHTSDRONE_MAN2", "S_NIGHTSDRONE_SPARKLING1", "S_NIGHTSDRONE_SPARKLING2", "S_NIGHTSDRONE_SPARKLING3", @@ -5850,97 +6880,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_NIGHTSDRONE_SPARKLING14", "S_NIGHTSDRONE_SPARKLING15", "S_NIGHTSDRONE_SPARKLING16", - "S_NIGHTSGOAL1", - "S_NIGHTSGOAL2", - "S_NIGHTSGOAL3", - "S_NIGHTSGOAL4", - - "S_NIGHTSFLY1A", - "S_NIGHTSFLY1B", - "S_NIGHTSDRILL1A", - "S_NIGHTSDRILL1B", - "S_NIGHTSDRILL1C", - "S_NIGHTSDRILL1D", - "S_NIGHTSFLY2A", - "S_NIGHTSFLY2B", - "S_NIGHTSDRILL2A", - "S_NIGHTSDRILL2B", - "S_NIGHTSDRILL2C", - "S_NIGHTSDRILL2D", - "S_NIGHTSFLY3A", - "S_NIGHTSFLY3B", - "S_NIGHTSDRILL3A", - "S_NIGHTSDRILL3B", - "S_NIGHTSDRILL3C", - "S_NIGHTSDRILL3D", - "S_NIGHTSFLY4A", - "S_NIGHTSFLY4B", - "S_NIGHTSDRILL4A", - "S_NIGHTSDRILL4B", - "S_NIGHTSDRILL4C", - "S_NIGHTSDRILL4D", - "S_NIGHTSFLY5A", - "S_NIGHTSFLY5B", - "S_NIGHTSDRILL5A", - "S_NIGHTSDRILL5B", - "S_NIGHTSDRILL5C", - "S_NIGHTSDRILL5D", - "S_NIGHTSFLY6A", - "S_NIGHTSFLY6B", - "S_NIGHTSDRILL6A", - "S_NIGHTSDRILL6B", - "S_NIGHTSDRILL6C", - "S_NIGHTSDRILL6D", - "S_NIGHTSFLY7A", - "S_NIGHTSFLY7B", - "S_NIGHTSDRILL7A", - "S_NIGHTSDRILL7B", - "S_NIGHTSDRILL7C", - "S_NIGHTSDRILL7D", - "S_NIGHTSFLY8A", - "S_NIGHTSFLY8B", - "S_NIGHTSDRILL8A", - "S_NIGHTSDRILL8B", - "S_NIGHTSDRILL8C", - "S_NIGHTSDRILL8D", - "S_NIGHTSFLY9A", - "S_NIGHTSFLY9B", - "S_NIGHTSDRILL9A", - "S_NIGHTSDRILL9B", - "S_NIGHTSDRILL9C", - "S_NIGHTSDRILL9D", - "S_NIGHTSHURT1", - "S_NIGHTSHURT2", - "S_NIGHTSHURT3", - "S_NIGHTSHURT4", - "S_NIGHTSHURT5", - "S_NIGHTSHURT6", - "S_NIGHTSHURT7", - "S_NIGHTSHURT8", - "S_NIGHTSHURT9", - "S_NIGHTSHURT10", - "S_NIGHTSHURT11", - "S_NIGHTSHURT12", - "S_NIGHTSHURT13", - "S_NIGHTSHURT14", - "S_NIGHTSHURT15", - "S_NIGHTSHURT16", - "S_NIGHTSHURT17", - "S_NIGHTSHURT18", - "S_NIGHTSHURT19", - "S_NIGHTSHURT20", - "S_NIGHTSHURT21", - "S_NIGHTSHURT22", - "S_NIGHTSHURT23", - "S_NIGHTSHURT24", - "S_NIGHTSHURT25", - "S_NIGHTSHURT26", - "S_NIGHTSHURT27", - "S_NIGHTSHURT28", - "S_NIGHTSHURT29", - "S_NIGHTSHURT30", - "S_NIGHTSHURT31", - "S_NIGHTSHURT32", + "S_NIGHTSDRONE_GOAL1", + "S_NIGHTSDRONE_GOAL2", + "S_NIGHTSDRONE_GOAL3", + "S_NIGHTSDRONE_GOAL4", "S_NIGHTSPARKLE1", "S_NIGHTSPARKLE2", @@ -5991,20 +6934,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_NIGHTSCORE90_2", "S_NIGHTSCORE100_2", - "S_NIGHTSWING", - "S_NIGHTSWING_XMAS", - // NiGHTS Paraloop Powerups - "S_NIGHTSPOWERUP1", - "S_NIGHTSPOWERUP2", - "S_NIGHTSPOWERUP3", - "S_NIGHTSPOWERUP4", - "S_NIGHTSPOWERUP5", - "S_NIGHTSPOWERUP6", - "S_NIGHTSPOWERUP7", - "S_NIGHTSPOWERUP8", - "S_NIGHTSPOWERUP9", - "S_NIGHTSPOWERUP10", + "S_NIGHTSSUPERLOOP", + "S_NIGHTSDRILLREFILL", + "S_NIGHTSHELPER", + "S_NIGHTSEXTRATIME", + "S_NIGHTSLINKFREEZE", "S_EGGCAPSULE", // Orbiting Chaos Emeralds @@ -6016,14 +6951,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ORBITEM6", "S_ORBITEM7", "S_ORBITEM8", - "S_ORBITEM9", - "S_ORBITEM10", - "S_ORBITEM11", - "S_ORBITEM12", - "S_ORBITEM13", - "S_ORBITEM14", - "S_ORBITEM15", - "S_ORBITEM16", + "S_ORBIDYA1", + "S_ORBIDYA2", + "S_ORBIDYA3", + "S_ORBIDYA4", + "S_ORBIDYA5", // "Flicky" helper "S_NIGHTOPIANHELPER1", @@ -6034,20 +6966,146 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_NIGHTOPIANHELPER6", "S_NIGHTOPIANHELPER7", "S_NIGHTOPIANHELPER8", + "S_NIGHTOPIANHELPER9", + + // Nightopian + "S_PIAN0", + "S_PIAN1", + "S_PIAN2", + "S_PIAN3", + "S_PIAN4", + "S_PIAN5", + "S_PIAN6", + "S_PIANSING", + + // Shleep + "S_SHLEEP1", + "S_SHLEEP2", + "S_SHLEEP3", + "S_SHLEEP4", + "S_SHLEEPBOUNCE1", + "S_SHLEEPBOUNCE2", + "S_SHLEEPBOUNCE3", + + // Secret badniks and hazards, shhhh + "S_PENGUINATOR_LOOK", + "S_PENGUINATOR_WADDLE1", + "S_PENGUINATOR_WADDLE2", + "S_PENGUINATOR_WADDLE3", + "S_PENGUINATOR_WADDLE4", + "S_PENGUINATOR_SLIDE1", + "S_PENGUINATOR_SLIDE2", + "S_PENGUINATOR_SLIDE3", + "S_PENGUINATOR_SLIDE4", + "S_PENGUINATOR_SLIDE5", + + "S_POPHAT_LOOK", + "S_POPHAT_SHOOT1", + "S_POPHAT_SHOOT2", + "S_POPHAT_SHOOT3", + + "S_HIVEELEMENTAL_LOOK", + "S_HIVEELEMENTAL_PREPARE1", + "S_HIVEELEMENTAL_PREPARE2", + "S_HIVEELEMENTAL_SHOOT1", + "S_HIVEELEMENTAL_SHOOT2", + "S_HIVEELEMENTAL_DORMANT", + "S_HIVEELEMENTAL_PAIN", + "S_HIVEELEMENTAL_DIE1", + "S_HIVEELEMENTAL_DIE2", + "S_HIVEELEMENTAL_DIE3", + + "S_BUMBLEBORE_SPAWN", + "S_BUMBLEBORE_LOOK1", + "S_BUMBLEBORE_LOOK2", + "S_BUMBLEBORE_FLY1", + "S_BUMBLEBORE_FLY2", + "S_BUMBLEBORE_RAISE", + "S_BUMBLEBORE_FALL1", + "S_BUMBLEBORE_FALL2", + "S_BUMBLEBORE_STUCK1", + "S_BUMBLEBORE_STUCK2", + "S_BUMBLEBORE_DIE", + + "S_BBUZZFLY1", + "S_BBUZZFLY2", + + "S_SMASHSPIKE_FLOAT", + "S_SMASHSPIKE_EASE1", + "S_SMASHSPIKE_EASE2", + "S_SMASHSPIKE_FALL", + "S_SMASHSPIKE_STOMP1", + "S_SMASHSPIKE_STOMP2", + "S_SMASHSPIKE_RISE1", + "S_SMASHSPIKE_RISE2", + + "S_CACO_LOOK", + "S_CACO_WAKE1", + "S_CACO_WAKE2", + "S_CACO_WAKE3", + "S_CACO_WAKE4", + "S_CACO_ROAR", + "S_CACO_CHASE", + "S_CACO_CHASE_REPEAT", + "S_CACO_RANDOM", + "S_CACO_PREPARE_SOUND", + "S_CACO_PREPARE1", + "S_CACO_PREPARE2", + "S_CACO_PREPARE3", + "S_CACO_SHOOT_SOUND", + "S_CACO_SHOOT1", + "S_CACO_SHOOT2", + "S_CACO_CLOSE", + "S_CACO_DIE_FLAGS", + "S_CACO_DIE_GIB1", + "S_CACO_DIE_GIB2", + "S_CACO_DIE_SCREAM", + "S_CACO_DIE_SHATTER", + "S_CACO_DIE_FALL", + "S_CACOSHARD_RANDOMIZE", + "S_CACOSHARD1_1", + "S_CACOSHARD1_2", + "S_CACOSHARD2_1", + "S_CACOSHARD2_2", + "S_CACOFIRE1", + "S_CACOFIRE2", + "S_CACOFIRE3", + "S_CACOFIRE_EXPLODE1", + "S_CACOFIRE_EXPLODE2", + "S_CACOFIRE_EXPLODE3", + "S_CACOFIRE_EXPLODE4", + + "S_SPINBOBERT_MOVE_FLIPUP", + "S_SPINBOBERT_MOVE_UP", + "S_SPINBOBERT_MOVE_FLIPDOWN", + "S_SPINBOBERT_MOVE_DOWN", + "S_SPINBOBERT_FIRE_MOVE", + "S_SPINBOBERT_FIRE_GHOST", + "S_SPINBOBERT_FIRE_TRAIL1", + "S_SPINBOBERT_FIRE_TRAIL2", + "S_SPINBOBERT_FIRE_TRAIL3", + + "S_HANGSTER_LOOK", + "S_HANGSTER_SWOOP1", + "S_HANGSTER_SWOOP2", + "S_HANGSTER_ARC1", + "S_HANGSTER_ARC2", + "S_HANGSTER_ARC3", + "S_HANGSTER_FLY1", + "S_HANGSTER_FLY2", + "S_HANGSTER_FLY3", + "S_HANGSTER_FLY4", + "S_HANGSTER_FLYREPEAT", + "S_HANGSTER_ARCUP1", + "S_HANGSTER_ARCUP2", + "S_HANGSTER_ARCUP3", + "S_HANGSTER_RETURN1", + "S_HANGSTER_RETURN2", + "S_HANGSTER_RETURN3", "S_CRUMBLE1", "S_CRUMBLE2", - "S_SUPERTRANS1", - "S_SUPERTRANS2", - "S_SUPERTRANS3", - "S_SUPERTRANS4", - "S_SUPERTRANS5", - "S_SUPERTRANS6", - "S_SUPERTRANS7", - "S_SUPERTRANS8", - "S_SUPERTRANS9", - // Spark "S_SPRK1", "S_SPRK2", @@ -6067,10 +7125,14 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SPRK16", // Robot Explosion + "S_XPLD_FLICKY", "S_XPLD1", "S_XPLD2", "S_XPLD3", "S_XPLD4", + "S_XPLD5", + "S_XPLD6", + "S_XPLD_EGGTRAP", // Underwater Explosion "S_WPLD1", @@ -6080,6 +7142,13 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_WPLD5", "S_WPLD6", + "S_DUST1", + "S_DUST2", + "S_DUST3", + "S_DUST4", + + "S_WOODDEBRIS", + "S_ROCKSPAWN", "S_ROCKCRUMBLEA", @@ -6099,70 +7168,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ROCKCRUMBLEO", "S_ROCKCRUMBLEP", - "S_SRB1_CRAWLA1", - "S_SRB1_CRAWLA2", - "S_SRB1_CRAWLA3", - "S_SRB1_CRAWLA4", - - "S_SRB1_BAT1", - "S_SRB1_BAT2", - "S_SRB1_BAT3", - "S_SRB1_BAT4", - - "S_SRB1_ROBOFISH1", - "S_SRB1_ROBOFISH2", - "S_SRB1_ROBOFISH3", - - "S_SRB1_VOLCANOGUY1", - "S_SRB1_VOLCANOGUY2", - - "S_SRB1_HOPPY1", - "S_SRB1_HOPPY2", - - "S_SRB1_HOPPYWATER1", - "S_SRB1_HOPPYWATER2", - - "S_SRB1_HOPPYSKYLAB1", - - "S_SRB1_MMZFLYING1", - "S_SRB1_MMZFLYING2", - "S_SRB1_MMZFLYING3", - "S_SRB1_MMZFLYING4", - "S_SRB1_MMZFLYING5", - - "S_SRB1_UFO1", - "S_SRB1_UFO2", - - "S_SRB1_GRAYBOT1", - "S_SRB1_GRAYBOT2", - "S_SRB1_GRAYBOT3", - "S_SRB1_GRAYBOT4", - "S_SRB1_GRAYBOT5", - "S_SRB1_GRAYBOT6", - - "S_SRB1_ROBOTOPOLIS1", - "S_SRB1_ROBOTOPOLIS2", - - "S_SRB1_RBZBUZZ1", - "S_SRB1_RBZBUZZ2", - - "S_SRB1_RBZSPIKES1", - "S_SRB1_RBZSPIKES2", - - "S_SRB1_METALSONIC1", - "S_SRB1_METALSONIC2", - "S_SRB1_METALSONIC3", - - "S_SRB1_GOLDBOT1", - "S_SRB1_GOLDBOT2", - "S_SRB1_GOLDBOT3", - "S_SRB1_GOLDBOT4", - "S_SRB1_GOLDBOT5", - "S_SRB1_GOLDBOT6", - - "S_SRB1_GENREX1", - "S_SRB1_GENREX2", - #ifdef SEENAMES "S_NAMECHECK", #endif @@ -6177,37 +7182,46 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_THOK", // Thok! mobj "MT_PLAYER", + "MT_TAILSOVERLAY", // c: // Enemies - "MT_BLUECRAWLA", - "MT_REDCRAWLA", - "MT_GFZFISH", // Greenflower Fish - "MT_GOLDBUZZ", - "MT_REDBUZZ", - "MT_AQUABUZZ", + "MT_BLUECRAWLA", // Crawla (Blue) + "MT_REDCRAWLA", // Crawla (Red) + "MT_GFZFISH", // SDURF + "MT_GOLDBUZZ", // Buzz (Gold) + "MT_REDBUZZ", // Buzz (Red) "MT_JETTBOMBER", // Jetty-Syn Bomber "MT_JETTGUNNER", // Jetty-Syn Gunner "MT_CRAWLACOMMANDER", // Crawla Commander "MT_DETON", // Deton "MT_SKIM", // Skim mine dropper - "MT_TURRET", - "MT_POPUPTURRET", - "MT_SHARP", // Sharp + "MT_TURRET", // Industrial Turret + "MT_POPUPTURRET", // Pop-Up Turret + "MT_SPINCUSHION", // Spincushion + "MT_CRUSHSTACEAN", // Crushstacean + "MT_CRUSHCLAW", // Big meaty claw + "MT_CRUSHCHAIN", // Chain "MT_JETJAW", // Jet Jaw "MT_SNAILER", // Snailer - "MT_VULTURE", // Vulture + "MT_VULTURE", // BASH "MT_POINTY", // Pointy "MT_POINTYBALL", // Pointy Ball "MT_ROBOHOOD", // Robo-Hood - "MT_FACESTABBER", // CastleBot FaceStabber + "MT_FACESTABBER", // Castlebot Facestabber + "MT_FACESTABBERSPEAR", // Castlebot Facestabber spear aura "MT_EGGGUARD", // Egg Guard - "MT_EGGSHIELD", // Egg Shield for Egg Guard + "MT_EGGSHIELD", // Egg Guard's shield "MT_GSNAPPER", // Green Snapper + "MT_SNAPPER_LEG", // Green Snapper leg + "MT_SNAPPER_HEAD", // Green Snapper head "MT_MINUS", // Minus - "MT_SPRINGSHELL", // Spring Shell (no drop) + "MT_MINUSDIRT", // Minus dirt + "MT_SPRINGSHELL", // Spring Shell "MT_YELLOWSHELL", // Spring Shell (yellow) "MT_UNIDUS", // Unidus "MT_UNIBALL", // Unidus Ball + "MT_CANARIVORE", // Canarivore + "MT_CANARIVORE_GAS", // Canarivore gas // Generic Boss Items "MT_BOSSEXPLODE", @@ -6231,6 +7245,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_BOSSTANK2", "MT_BOSSSPIGOT", "MT_GOOP", + "MT_GOOPTRAIL", // Boss 3 "MT_EGGMOBILE3", @@ -6242,6 +7257,14 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_EGGMOBILE4_MACE", "MT_JETFLAME", + // Boss 5 + "MT_FANG", + "MT_FBOMB", + "MT_TNTDUST", // also used by barrel + "MT_FSGNA", + "MT_FSGNB", + "MT_FANGWAYPOINT", + // Black Eggman (Boss 7) "MT_BLACKEGGMAN", "MT_BLACKEGGMAN_HELPER", @@ -6270,11 +7293,12 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s // Collectible Items "MT_RING", "MT_FLINGRING", // Lost ring - "MT_BLUEBALL", // Blue sphere replacement for special stages + "MT_BLUESPHERE", // Blue sphere for special stages + "MT_FLINGBLUESPHERE", // Lost blue sphere + "MT_BOMBSPHERE", "MT_REDTEAMRING", //Rings collectable by red team. "MT_BLUETEAMRING", //Rings collectable by blue team. - "MT_EMMY", // emerald token for special stage - "MT_TOKEN", // Special Stage Token (uncollectible part) + "MT_TOKEN", // Special Stage Token "MT_REDFLAG", // Red CTF Flag "MT_BLUEFLAG", // Blue CTF Flag "MT_EMBLEM", @@ -6291,66 +7315,97 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s // Springs and others "MT_FAN", - "MT_STEAM", // Steam riser - "MT_BLUESPRING", + "MT_STEAM", + "MT_BUMPER", + "MT_BALLOON", + "MT_YELLOWSPRING", "MT_REDSPRING", - "MT_YELLOWDIAG", // Yellow Diagonal Spring - "MT_REDDIAG", // Red Diagonal Spring + "MT_BLUESPRING", + "MT_YELLOWDIAG", + "MT_REDDIAG", + "MT_BLUEDIAG", + "MT_YELLOWHORIZ", + "MT_REDHORIZ", + "MT_BLUEHORIZ", // Interactive Objects "MT_BUBBLES", // Bubble source "MT_SIGN", // Level end sign "MT_SPIKEBALL", // Spike Ball - "MT_SPECIALSPIKEBALL", "MT_SPINFIRE", "MT_SPIKE", + "MT_WALLSPIKE", + "MT_WALLSPIKEBASE", "MT_STARPOST", "MT_BIGMINE", - "MT_BIGAIRMINE", + "MT_BLASTEXECUTOR", "MT_CANNONLAUNCHER", - // Monitor Boxes - "MT_SUPERRINGBOX", - "MT_REDRINGBOX", - "MT_BLUERINGBOX", - "MT_SNEAKERTV", - "MT_INV", - "MT_PRUP", // 1up Box - "MT_YELLOWTV", // Attract shield TV - "MT_BLUETV", // Force shield TV - "MT_BLACKTV", // Bomb shield TV - "MT_WHITETV", // Jump shield TV - "MT_GREENTV", // Elemental shield TV - "MT_PITYTV", // Pity shield TV - "MT_EGGMANBOX", - "MT_MIXUPBOX", - "MT_RECYCLETV", - "MT_RECYCLEICO", - "MT_QUESTIONBOX", - "MT_GRAVITYBOX", - "MT_SCORETVSMALL", - "MT_SCORETVLARGE", - // Monitor miscellany - "MT_MONITOREXPLOSION", - "MT_REDMONITOREXPLOSION", - "MT_BLUEMONITOREXPLOSION", - "MT_RINGICO", - "MT_SHOESICO", - "MT_INVCICO", - "MT_1UPICO", - "MT_YSHIELDICO", - "MT_BSHIELDICO", - "MT_KSHIELDICO", - "MT_WSHIELDICO", - "MT_GSHIELDICO", - "MT_PITYSHIELDICO", - "MT_EGGMANICO", - "MT_MIXUPICO", - "MT_GRAVITYICO", - "MT_SCOREICOSMALL", - "MT_SCOREICOLARGE", + "MT_BOXSPARKLE", + + // Monitor boxes -- regular + "MT_RING_BOX", + "MT_PITY_BOX", + "MT_ATTRACT_BOX", + "MT_FORCE_BOX", + "MT_ARMAGEDDON_BOX", + "MT_WHIRLWIND_BOX", + "MT_ELEMENTAL_BOX", + "MT_SNEAKERS_BOX", + "MT_INVULN_BOX", + "MT_1UP_BOX", + "MT_EGGMAN_BOX", + "MT_MIXUP_BOX", + "MT_MYSTERY_BOX", + "MT_GRAVITY_BOX", + "MT_RECYCLER_BOX", + "MT_SCORE1K_BOX", + "MT_SCORE10K_BOX", + "MT_FLAMEAURA_BOX", + "MT_BUBBLEWRAP_BOX", + "MT_THUNDERCOIN_BOX", + + // Monitor boxes -- repeating (big) boxes + "MT_PITY_GOLDBOX", + "MT_ATTRACT_GOLDBOX", + "MT_FORCE_GOLDBOX", + "MT_ARMAGEDDON_GOLDBOX", + "MT_WHIRLWIND_GOLDBOX", + "MT_ELEMENTAL_GOLDBOX", + "MT_SNEAKERS_GOLDBOX", + "MT_INVULN_GOLDBOX", + "MT_EGGMAN_GOLDBOX", + "MT_GRAVITY_GOLDBOX", + "MT_FLAMEAURA_GOLDBOX", + "MT_BUBBLEWRAP_GOLDBOX", + "MT_THUNDERCOIN_GOLDBOX", + + // Monitor boxes -- special + "MT_RING_REDBOX", + "MT_RING_BLUEBOX", + + // Monitor icons + "MT_RING_ICON", + "MT_PITY_ICON", + "MT_ATTRACT_ICON", + "MT_FORCE_ICON", + "MT_ARMAGEDDON_ICON", + "MT_WHIRLWIND_ICON", + "MT_ELEMENTAL_ICON", + "MT_SNEAKERS_ICON", + "MT_INVULN_ICON", + "MT_1UP_ICON", + "MT_EGGMAN_ICON", + "MT_MIXUP_ICON", + "MT_GRAVITY_ICON", + "MT_RECYCLER_ICON", + "MT_SCORE1K_ICON", + "MT_SCORE10K_ICON", + "MT_FLAMEAURA_ICON", + "MT_BUBBLEWRAP_ICON", + "MT_THUNDERCOIN_ICON", // Projectiles "MT_ROCKET", @@ -6370,15 +7425,35 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_GFZFLOWER1", "MT_GFZFLOWER2", "MT_GFZFLOWER3", + + "MT_BLUEBERRYBUSH", "MT_BERRYBUSH", "MT_BUSH", + // Trees (both GFZ and misc) + "MT_GFZTREE", + "MT_GFZBERRYTREE", + "MT_GFZCHERRYTREE", + "MT_CHECKERTREE", + "MT_CHECKERSUNSETTREE", + "MT_FHZTREE", // Frozen Hillside + "MT_FHZPINKTREE", + "MT_POLYGONTREE", + "MT_BUSHTREE", + "MT_BUSHREDTREE", + "MT_SPRINGTREE", + // Techno Hill Scenery - "MT_THZPLANT", // THZ Plant + "MT_THZFLOWER1", + "MT_THZFLOWER2", + "MT_THZFLOWER3", + "MT_THZTREE", // Steam whistle tree/bush + "MT_THZTREEBRANCH", // branch of said tree "MT_ALARM", // Deep Sea Scenery "MT_GARGOYLE", // Deep Sea Gargoyle + "MT_BIGGARGOYLE", // Deep Sea Gargoyle (Big) "MT_SEAWEED", // DSZ Seaweed "MT_WATERDRIP", // Dripping Water source "MT_WATERDROP", // Water drop from dripping water @@ -6386,21 +7461,49 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_CORAL2", // Coral 2 "MT_CORAL3", // Coral 3 "MT_BLUECRYSTAL", // Blue Crystal + "MT_KELP", // Kelp + "MT_DSZSTALAGMITE", // Deep Sea 1 Stalagmite + "MT_DSZ2STALAGMITE", // Deep Sea 2 Stalagmite + "MT_LIGHTBEAM", // DSZ Light beam // Castle Eggman Scenery "MT_CHAIN", // CEZ Chain "MT_FLAME", // Flame (has corona) + "MT_FLAMEPARTICLE", "MT_EGGSTATUE", // Eggman Statue "MT_MACEPOINT", // Mace rotation point - "MT_SWINGMACEPOINT", // Mace swinging point - "MT_HANGMACEPOINT", // Hangable mace chain - "MT_SPINMACEPOINT", // Spin/Controllable mace chain + "MT_CHAINMACEPOINT", // Combination of chains and maces point + "MT_SPRINGBALLPOINT", // Spring ball point + "MT_CHAINPOINT", // Mace chain "MT_HIDDEN_SLING", // Spin mace chain (activatable) + "MT_FIREBARPOINT", // Firebar + "MT_CUSTOMMACEPOINT", // Custom mace "MT_SMALLMACECHAIN", // Small Mace Chain "MT_BIGMACECHAIN", // Big Mace Chain "MT_SMALLMACE", // Small Mace "MT_BIGMACE", // Big Mace - "MT_CEZFLOWER", + "MT_SMALLGRABCHAIN", // Small Grab Chain + "MT_BIGGRABCHAIN", // Big Grab Chain + "MT_YELLOWSPRINGBALL", // Yellow spring on a ball + "MT_REDSPRINGBALL", // Red spring on a ball + "MT_SMALLFIREBAR", // Small Firebar + "MT_BIGFIREBAR", // Big Firebar + "MT_CEZFLOWER", // Flower + "MT_CEZPOLE", // Pole + "MT_CEZBANNER", // Banner + "MT_PINETREE", // Pine Tree + "MT_CEZBUSH1", // Bush 1 + "MT_CEZBUSH2", // Bush 2 + "MT_CANDLE", // Candle + "MT_CANDLEPRICKET", // Candle pricket + "MT_FLAMEHOLDER", // Flame holder + "MT_FIRETORCH", // Fire torch + "MT_WAVINGFLAG", // Waving flag + "MT_WAVINGFLAGSEG", // Waving flag segment + "MT_CRAWLASTATUE", // Crawla statue + "MT_FACESTABBERSTATUE", // Facestabber statue + "MT_SUSPICIOUSFACESTABBERSTATUE", // :eggthinking: + "MT_BRAMBLES", // Brambles // Arid Canyon Scenery "MT_BIGTUMBLEWEED", @@ -6409,6 +7512,34 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_CACTI2", "MT_CACTI3", "MT_CACTI4", + "MT_CACTI5", + "MT_CACTI6", + "MT_CACTI7", + "MT_CACTI8", + "MT_CACTI9", + "MT_ARIDSIGN_CAUTION", + "MT_ARIDSIGN_CACTI", + "MT_ARIDSIGN_SHARPTURN", + "MT_OILLAMP", + "MT_TNTBARREL", + "MT_PROXIMITYTNT", + "MT_DUSTDEVIL", + "MT_DUSTLAYER", + "MT_ARIDDUST", + "MT_MINECART", + "MT_MINECARTSEG", + "MT_MINECARTSPAWNER", + "MT_MINECARTEND", + "MT_MINECARTENDSOLID", + "MT_MINECARTSIDEMARK", + "MT_MINECARTSPARK", + "MT_SALOONDOOR", + "MT_SALOONDOORTHINKER", + "MT_TRAINCAMEOSPAWNER", + "MT_TRAINSEG", + "MT_TRAINDUSTSPAWNER", + "MT_TRAINSTEAMSPAWNER", + "MT_MINECARTSWITCHPOINT", // Red Volcano Scenery "MT_FLAMEJET", @@ -6416,9 +7547,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_FLAMEJETFLAME", "MT_FJSPINAXISA", // Counter-clockwise - "MT_FJSPINHELPERA", "MT_FJSPINAXISB", // Clockwise - "MT_FJSPINHELPERB", "MT_FLAMEJETFLAMEB", // Blade's flame @@ -6448,7 +7577,34 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s // Christmas Scenery "MT_XMASPOLE", "MT_CANDYCANE", - "MT_SNOWMAN", + "MT_SNOWMAN", // normal + "MT_SNOWMANHAT", // with hat + scarf + "MT_LAMPPOST1", // normal + "MT_LAMPPOST2", // with snow + "MT_HANGSTAR", + // Xmas GFZ bushes + "MT_XMASBLUEBERRYBUSH", + "MT_XMASBERRYBUSH", + "MT_XMASBUSH", + // FHZ + "MT_FHZICE1", + "MT_FHZICE2", + + // Halloween Scenery + // Pumpkins + "MT_JACKO1", + "MT_JACKO2", + "MT_JACKO3", + // Dr Seuss Trees + "MT_HHZTREE_TOP", + "MT_HHZTREE_PART", + // Misc + "MT_HHZSHROOM", + "MT_HHZGRASS", + "MT_HHZTENTACLE1", + "MT_HHZTENTACLE2", + "MT_HHZSTALAGMITE_TALL", + "MT_HHZSTALAGMITE_SHORT", // Botanic Serenity "MT_BSZTALLFLOWER_RED", @@ -6495,30 +7651,67 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_BSZVINE_ORANGE", "MT_BSZSHRUB", "MT_BSZCLOVER", - "MT_BSZFISH", - "MT_BSZSUNFLOWER", + "MT_BIG_PALMTREE_TRUNK", + "MT_BIG_PALMTREE_TOP", + "MT_PALMTREE_TRUNK", + "MT_PALMTREE_TOP", // Misc scenery "MT_DBALL", "MT_EGGSTATUE2", // Powerup Indicators - "MT_GREENORB", // Elemental shield mobj - "MT_YELLOWORB", // Attract shield mobj - "MT_BLUEORB", // Force shield mobj - "MT_BLACKORB", // Armageddon shield mobj - "MT_WHITEORB", // Whirlwind shield mobj - "MT_PITYORB", // Pity shield mobj - "MT_IVSP", // invincibility sparkles + "MT_ELEMENTAL_ORB", // Elemental shield mobj + "MT_ATTRACT_ORB", // Attract shield mobj + "MT_FORCE_ORB", // Force shield mobj + "MT_ARMAGEDDON_ORB", // Armageddon shield mobj + "MT_WHIRLWIND_ORB", // Whirlwind shield mobj + "MT_PITY_ORB", // Pity shield mobj + "MT_FLAMEAURA_ORB", // Flame shield mobj + "MT_BUBBLEWRAP_ORB", // Bubble shield mobj + "MT_THUNDERCOIN_ORB", // Thunder shield mobj + "MT_THUNDERCOIN_SPARK", // Thunder spark + "MT_IVSP", // Invincibility sparkles "MT_SUPERSPARK", // Super Sonic Spark - // Freed Animals - "MT_BIRD", // Birdie freed! - "MT_BUNNY", // Bunny freed! - "MT_MOUSE", // Mouse - "MT_CHICKEN", // Chicken - "MT_COW", // Cow - "MT_REDBIRD", // Red Birdie in Bubble + // Flickies + "MT_FLICKY_01", // Bluebird + "MT_FLICKY_01_CENTER", + "MT_FLICKY_02", // Rabbit + "MT_FLICKY_02_CENTER", + "MT_FLICKY_03", // Chicken + "MT_FLICKY_03_CENTER", + "MT_FLICKY_04", // Seal + "MT_FLICKY_04_CENTER", + "MT_FLICKY_05", // Pig + "MT_FLICKY_05_CENTER", + "MT_FLICKY_06", // Chipmunk + "MT_FLICKY_06_CENTER", + "MT_FLICKY_07", // Penguin + "MT_FLICKY_07_CENTER", + "MT_FLICKY_08", // Fish + "MT_FLICKY_08_CENTER", + "MT_FLICKY_09", // Ram + "MT_FLICKY_09_CENTER", + "MT_FLICKY_10", // Puffin + "MT_FLICKY_10_CENTER", + "MT_FLICKY_11", // Cow + "MT_FLICKY_11_CENTER", + "MT_FLICKY_12", // Rat + "MT_FLICKY_12_CENTER", + "MT_FLICKY_13", // Bear + "MT_FLICKY_13_CENTER", + "MT_FLICKY_14", // Dove + "MT_FLICKY_14_CENTER", + "MT_FLICKY_15", // Cat + "MT_FLICKY_15_CENTER", + "MT_FLICKY_16", // Canary + "MT_FLICKY_16_CENTER", + "MT_SECRETFLICKY_01", // Spider + "MT_SECRETFLICKY_01_CENTER", + "MT_SECRETFLICKY_02", // Bat + "MT_SECRETFLICKY_02_CENTER", + "MT_SEED", // Environmental Effects "MT_RAIN", // Rain @@ -6528,8 +7721,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_SMALLBUBBLE", // small bubble "MT_MEDIUMBUBBLE", // medium bubble "MT_EXTRALARGEBUBBLE", // extra large bubble + "MT_WATERZAP", + "MT_SPINDUST", // Spindash dust "MT_TFOG", - "MT_SEED", "MT_PARTICLE", "MT_PARTICLEGEN", // For fans, etc. @@ -6537,9 +7731,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_SCORE", // score logo "MT_DROWNNUMBERS", // Drowning Timer "MT_GOTEMERALD", // Chaos Emerald (intangible) + "MT_LOCKON", // Target "MT_TAG", // Tag Sign "MT_GOTFLAG", // Got Flag sign - "MT_GOTFLAG2", // Got Flag sign // Ambient Sounds "MT_AWATERA", // Ambient Water Sound 1 @@ -6552,6 +7746,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_AWATERH", // Ambient Water Sound 8 "MT_RANDOMAMBIENT", "MT_RANDOMAMBIENT2", + "MT_MACHINEAMBIENCE", + + "MT_CORK", // Ring Weapons "MT_REDRING", @@ -6586,6 +7783,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_FIREBALL", "MT_SHELL", "MT_PUMA", + "MT_PUMATRAIL", "MT_HAMMER", "MT_KOOPA", "MT_KOOPAFLAME", @@ -6599,8 +7797,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_AXISTRANSFER", "MT_AXISTRANSFERLINE", "MT_NIGHTSDRONE", - "MT_NIGHTSGOAL", - "MT_NIGHTSCHAR", + "MT_NIGHTSDRONE_MAN", + "MT_NIGHTSDRONE_SPARKLING", + "MT_NIGHTSDRONE_GOAL", "MT_NIGHTSPARKLE", "MT_NIGHTSLOOPHELPER", "MT_NIGHTSBUMPER", // NiGHTS Bumper @@ -6608,14 +7807,38 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_HOOPCOLLIDE", // Collision detection for NiGHTS hoops "MT_HOOPCENTER", // Center of a hoop "MT_NIGHTSCORE", - "MT_NIGHTSWING", + "MT_NIGHTSCHIP", // NiGHTS Chip + "MT_FLINGNIGHTSCHIP", // Lost NiGHTS Chip + "MT_NIGHTSSTAR", // NiGHTS Star "MT_NIGHTSSUPERLOOP", "MT_NIGHTSDRILLREFILL", "MT_NIGHTSHELPER", "MT_NIGHTSEXTRATIME", "MT_NIGHTSLINKFREEZE", "MT_EGGCAPSULE", + "MT_IDEYAANCHOR", "MT_NIGHTOPIANHELPER", // the actual helper object that orbits you + "MT_PIAN", // decorative singing friend + "MT_SHLEEP", // almost-decorative sleeping enemy + + // Secret badniks and hazards, shhhh + "MT_PENGUINATOR", + "MT_POPHAT", + "MT_POPSHOT", + + "MT_HIVEELEMENTAL", + "MT_BUMBLEBORE", + + "MT_BUBBLEBUZZ", + + "MT_SMASHINGSPIKEBALL", + "MT_CACOLANTERN", + "MT_CACOSHARD", + "MT_CACOFIRE", + "MT_SPINBOBERT", + "MT_SPINBOBERT_FIRE1", + "MT_SPINBOBERT_FIRE2", + "MT_HANGSTER", // Utility Objects "MT_TELEPORTMAN", @@ -6626,6 +7849,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_PULL", "MT_GHOST", "MT_OVERLAY", + "MT_ANGLEMAN", "MT_POLYANCHOR", "MT_POLYSPAWN", "MT_POLYSPAWNCRUSH", @@ -6637,6 +7861,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_SPARK", //spark "MT_EXPLODE", // Robot Explosion "MT_UWEXPLODE", // Underwater Explosion + "MT_DUST", + "MT_WOODDEBRIS", "MT_ROCKSPAWNER", "MT_FALLINGROCK", "MT_ROCKCRUMBLE1", @@ -6656,22 +7882,6 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_ROCKCRUMBLE15", "MT_ROCKCRUMBLE16", - "MT_SRB1_CRAWLA", - "MT_SRB1_BAT", - "MT_SRB1_ROBOFISH", - "MT_SRB1_VOLCANOGUY", - "MT_SRB1_HOPPY", - "MT_SRB1_HOPPYWATER", - "MT_SRB1_HOPPYSKYLAB", - "MT_SRB1_MMZFLYING", - "MT_SRB1_UFO", - "MT_SRB1_GRAYBOT", - "MT_SRB1_ROBOTOPOLIS", - "MT_SRB1_RBZBUZZ", - "MT_SRB1_RBZSPIKES", - "MT_SRB1_METALSONIC", - "MT_SRB1_GOLDBOT", - "MT_SRB1_GENREX", #ifdef SEENAMES "MT_NAMECHECK", #endif @@ -6683,7 +7893,7 @@ static const char *const MOBJFLAG_LIST[] = { "SHOOTABLE", "NOSECTOR", "NOBLOCKMAP", - "AMBUSH", + "PAPERCOLLISION", "PUSHABLE", "BOSS", "SPAWNCEILING", @@ -6713,34 +7923,36 @@ static const char *const MOBJFLAG_LIST[] = { // \tMF2_(\S+).*// (.+) --> \t"\1", // \2 static const char *const MOBJFLAG2_LIST[] = { - "AXIS", // It's a NiGHTS axis! (For faster checking) - "TWOD", // Moves like it's in a 2D level - "DONTRESPAWN", // Don't respawn this object! - "DONTDRAW", // Don't generate a vissprite - "AUTOMATIC", // Thrown ring has automatic properties - "RAILRING", // Thrown ring has rail properties - "BOUNCERING", // Thrown ring has bounce properties - "EXPLOSION", // Thrown ring has explosive properties - "SCATTER", // Thrown ring has scatter properties - "BEYONDTHEGRAVE",// Source of this missile has died and has since respawned. - "PUSHED", // Mobj was already pushed this tic - "SLIDEPUSH", // MF_PUSHABLE that pushes continuously. - "CLASSICPUSH", // Drops straight down when object has negative Z. - "STANDONME", // While not pushable, stand on me anyway. - "INFLOAT", // Floating to a height for a move, don't auto float to target's height. - "DEBRIS", // Splash ring from explosion ring - "NIGHTSPULL", // Attracted from a paraloop - "JUSTATTACKED", // can be pushed by other moving mobjs - "FIRING", // turret fire - "SUPERFIRE", // Firing something with Super Sonic-stopping properties. Or, if mobj has MF_MISSILE, this is the actual fire from it. - "SHADOW", // Fuzzy draw, makes targeting harder. - "STRONGBOX", // Flag used for "strong" random monitors. - "OBJECTFLIP", // Flag for objects that always have flipped gravity. - "SKULLFLY", // Special handling: skull in flight. - "FRET", // Flashing from a previous hit - "BOSSNOTRAP", // No Egg Trap after boss - "BOSSFLEE", // Boss is fleeing! - "BOSSDEAD", // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.) + "AXIS", // It's a NiGHTS axis! (For faster checking) + "TWOD", // Moves like it's in a 2D level + "DONTRESPAWN", // Don't respawn this object! + "DONTDRAW", // Don't generate a vissprite + "AUTOMATIC", // Thrown ring has automatic properties + "RAILRING", // Thrown ring has rail properties + "BOUNCERING", // Thrown ring has bounce properties + "EXPLOSION", // Thrown ring has explosive properties + "SCATTER", // Thrown ring has scatter properties + "BEYONDTHEGRAVE", // Source of this missile has died and has since respawned. + "SLIDEPUSH", // MF_PUSHABLE that pushes continuously. + "CLASSICPUSH", // Drops straight down when object has negative momz. + "INVERTAIMABLE", // Flips whether it's targetable by A_LookForEnemies (enemies no, decoys yes) + "INFLOAT", // Floating to a height for a move, don't auto float to target's height. + "DEBRIS", // Splash ring from explosion ring + "NIGHTSPULL", // Attracted from a paraloop + "JUSTATTACKED", // can be pushed by other moving mobjs + "FIRING", // turret fire + "SUPERFIRE", // Firing something with Super Sonic-stopping properties. Or, if mobj has MF_MISSILE, this is the actual fire from it. + "SHADOW", // Fuzzy draw, makes targeting harder. + "STRONGBOX", // Flag used for "strong" random monitors. + "OBJECTFLIP", // Flag for objects that always have flipped gravity. + "SKULLFLY", // Special handling: skull in flight. + "FRET", // Flashing from a previous hit + "BOSSNOTRAP", // No Egg Trap after boss + "BOSSFLEE", // Boss is fleeing! + "BOSSDEAD", // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.) + "AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH + "LINKDRAW", // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position) + "SHIELD", // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use) NULL }; @@ -6752,7 +7964,7 @@ static const char *const MOBJEFLAG_LIST[] = { "JUSTSTEPPEDDOWN", // used for ramp sectors "VERTICALFLIP", // Vertically flip sprite/allow upside-down physics "GOOWATER", // Goo water - "\x01", // free: 1<<7 (name un-matchable) + "PUSHED", // Mobj was already pushed this tic "SPRUNG", // Mobj was already sprung this tic "APPLYPMOMZ", // Platform movement NULL @@ -6768,8 +7980,12 @@ static const char *const MAPTHINGFLAG_LIST[4] = { #endif static const char *const PLAYERFLAG_LIST[] = { - // Flip camera angle with gravity flip prefrence. - "FLIPCAM", + + // Cvars + "FLIPCAM", // Flip camera angle with gravity flip prefrence. + "ANALOGMODE", // Analog mode? + "DIRECTIONCHAR", // Directional character sprites? + "AUTOBRAKE", // Autobrake? // Cheats "GODMODE", @@ -6787,53 +8003,36 @@ static const char *const PLAYERFLAG_LIST[] = { "JUMPSTASIS", // and that includes jumping. // (we don't include FULLSTASIS here I guess because it's just those two together...?) - // Did you get a time-over? - "TIMEOVER", - - // Ready for Super? - "SUPERREADY", + // Applying autobrake? + "APPLYAUTOBRAKE", // Character action status + "STARTJUMP", "JUMPED", + "NOJUMPDAMAGE", + "SPINNING", "STARTDASH", - "THOKKED", - // Are you gliding? + "THOKKED", + "SHIELDABILITY", "GLIDING", - - // Tails pickup! - "CARRIED", + "BOUNCING", // Sliding (usually in water) like Labyrinth/Oil Ocean "SLIDING", - // Hanging on a rope - "ROPEHANG", - - // Hanging on an item of some kind - zipline, chain, etc. (->tracer) - "ITEMHANG", - - // On the mace chain spinning around (->tracer) - "MACESPIN", - - /*** NIGHTS STUFF ***/ - // Is the player in NiGHTS mode? - "NIGHTSMODE", + // NiGHTS stuff "TRANSFERTOCLOSEST", - - // Spill rings after falling - "NIGHTSFALL", "DRILLING", - "SKIDDOWN", - /*** TAG STUFF ***/ - "TAGGED", // Player has been tagged and awaits the next round in hide and seek. + // Gametype-specific stuff + "GAMETYPEOVER", // Race time over, or H&S out-of-game "TAGIT", // The player is it! For Tag Mode /*** misc ***/ "FORCESTRAFE", // Translate turn inputs into strafe inputs - "ANALOGMODE", // Analog mode? + "CANCARRY", // Can carry? NULL // stop loop here. }; @@ -6863,50 +8062,130 @@ static const char *const ML_LIST[16] = { // This DOES differ from r_draw's Color_Names, unfortunately. // Also includes Super colors static const char *COLOR_ENUMS[] = { - "NONE", // SKINCOLOR_NONE - "WHITE", // SKINCOLOR_WHITE - "SILVER", // SKINCOLOR_SILVER - "GREY", // SKINCOLOR_GREY - "BLACK", // SKINCOLOR_BLACK - "CYAN", // SKINCOLOR_CYAN - "TEAL", // SKINCOLOR_TEAL - "STEELBLUE", // SKINCOLOR_STEELBLUE - "BLUE", // SKINCOLOR_BLUE - "PEACH", // SKINCOLOR_PEACH - "TAN", // SKINCOLOR_TAN - "PINK", // SKINCOLOR_PINK - "LAVENDER", // SKINCOLOR_LAVENDER - "PURPLE", // SKINCOLOR_PURPLE - "ORANGE", // SKINCOLOR_ORANGE - "ROSEWOOD", // SKINCOLOR_ROSEWOOD - "BEIGE", // SKINCOLOR_BEIGE - "BROWN", // SKINCOLOR_BROWN - "RED", // SKINCOLOR_RED - "DARKRED", // SKINCOLOR_DARKRED - "NEONGREEN", // SKINCOLOR_NEONGREEN - "GREEN", // SKINCOLOR_GREEN - "ZIM", // SKINCOLOR_ZIM - "OLIVE", // SKINCOLOR_OLIVE - "YELLOW", // SKINCOLOR_YELLOW - "GOLD", // SKINCOLOR_GOLD + "NONE", // SKINCOLOR_NONE, + + // Greyscale ranges + "WHITE", // SKINCOLOR_WHITE, + "BONE", // SKINCOLOR_BONE, + "CLOUDY", // SKINCOLOR_CLOUDY, + "GREY", // SKINCOLOR_GREY, + "SILVER", // SKINCOLOR_SILVER, + "CARBON", // SKINCOLOR_CARBON, + "JET", // SKINCOLOR_JET, + "BLACK", // SKINCOLOR_BLACK, + + // Desaturated + "AETHER", // SKINCOLOR_AETHER, + "SLATE", // SKINCOLOR_SLATE, + "PINK", // SKINCOLOR_PINK, + "YOGURT", // SKINCOLOR_YOGURT, + "BROWN", // SKINCOLOR_BROWN, + "TAN", // SKINCOLOR_TAN, + "BEIGE", // SKINCOLOR_BEIGE, + "MOSS", // SKINCOLOR_MOSS, + "AZURE", // SKINCOLOR_AZURE, + "LAVENDER", // SKINCOLOR_LAVENDER, + + // Viv's vivid colours (toast 21/07/17) + "RUBY", // SKINCOLOR_RUBY, + "SALMON", // SKINCOLOR_SALMON, + "RED", // SKINCOLOR_RED, + "CRIMSON", // SKINCOLOR_CRIMSON, + "FLAME", // SKINCOLOR_FLAME, + "PEACHY", // SKINCOLOR_PEACHY, + "QUAIL", // SKINCOLOR_QUAIL, + "SUNSET", // SKINCOLOR_SUNSET, + "APRICOT", // SKINCOLOR_APRICOT, + "ORANGE", // SKINCOLOR_ORANGE, + "RUST", // SKINCOLOR_RUST, + "GOLD", // SKINCOLOR_GOLD, + "SANDY", // SKINCOLOR_SANDY, + "YELLOW", // SKINCOLOR_YELLOW, + "OLIVE", // SKINCOLOR_OLIVE, + "LIME", // SKINCOLOR_LIME, + "PERIDOT", // SKINCOLOR_PERIDOT, + "GREEN", // SKINCOLOR_GREEN, + "FOREST", // SKINCOLOR_FOREST, + "EMERALD", // SKINCOLOR_EMERALD, + "MINT", // SKINCOLOR_MINT, + "SEAFOAM", // SKINCOLOR_SEAFOAM, + "AQUA", // SKINCOLOR_AQUA, + "TEAL", // SKINCOLOR_TEAL, + "WAVE", // SKINCOLOR_WAVE, + "CYAN", // SKINCOLOR_CYAN, + "SKY", // SKINCOLOR_SKY, + "CERULEAN", // SKINCOLOR_CERULEAN, + "ICY", // SKINCOLOR_ICY, + "SAPPHIRE", // SKINCOLOR_SAPPHIRE, + "CORNFLOWER", // SKINCOLOR_CORNFLOWER, + "BLUE", // SKINCOLOR_BLUE, + "COBALT", // SKINCOLOR_COBALT, + "VAPOR", // SKINCOLOR_VAPOR, + "DUSK", // SKINCOLOR_DUSK, + "PASTEL", // SKINCOLOR_PASTEL, + "PURPLE", // SKINCOLOR_PURPLE, + "BUBBLEGUM", // SKINCOLOR_BUBBLEGUM, + "MAGENTA", // SKINCOLOR_MAGENTA, + "NEON", // SKINCOLOR_NEON, + "VIOLET", // SKINCOLOR_VIOLET, + "LILAC", // SKINCOLOR_LILAC, + "PLUM", // SKINCOLOR_PLUM, + "ROSY", // SKINCOLOR_ROSY, + // Super special awesome Super flashing colors! - "SUPER1", // SKINCOLOR_SUPER1 - "SUPER2", // SKINCOLOR_SUPER2, - "SUPER3", // SKINCOLOR_SUPER3, - "SUPER4", // SKINCOLOR_SUPER4, - "SUPER5", // SKINCOLOR_SUPER5, - // Super Tails - "TSUPER1", // SKINCOLOR_TSUPER1, - "TSUPER2", // SKINCOLOR_TSUPER2, - "TSUPER3", // SKINCOLOR_TSUPER3, - "TSUPER4", // SKINCOLOR_TSUPER4, - "TSUPER5", // SKINCOLOR_TSUPER5, - // Super Knuckles - "KSUPER1", // SKINCOLOR_KSUPER1, - "KSUPER2", // SKINCOLOR_KSUPER2, - "KSUPER3", // SKINCOLOR_KSUPER3, - "KSUPER4", // SKINCOLOR_KSUPER4, - "KSUPER5" // SKINCOLOR_KSUPER5, + "SUPERSILVER1", // SKINCOLOR_SUPERSILVER1 + "SUPERSILVER2", // SKINCOLOR_SUPERSILVER2, + "SUPERSILVER3", // SKINCOLOR_SUPERSILVER3, + "SUPERSILVER4", // SKINCOLOR_SUPERSILVER4, + "SUPERSILVER5", // SKINCOLOR_SUPERSILVER5, + + "SUPERRED1", // SKINCOLOR_SUPERRED1 + "SUPERRED2", // SKINCOLOR_SUPERRED2, + "SUPERRED3", // SKINCOLOR_SUPERRED3, + "SUPERRED4", // SKINCOLOR_SUPERRED4, + "SUPERRED5", // SKINCOLOR_SUPERRED5, + + "SUPERORANGE1", // SKINCOLOR_SUPERORANGE1 + "SUPERORANGE2", // SKINCOLOR_SUPERORANGE2, + "SUPERORANGE3", // SKINCOLOR_SUPERORANGE3, + "SUPERORANGE4", // SKINCOLOR_SUPERORANGE4, + "SUPERORANGE5", // SKINCOLOR_SUPERORANGE5, + + "SUPERGOLD1", // SKINCOLOR_SUPERGOLD1 + "SUPERGOLD2", // SKINCOLOR_SUPERGOLD2, + "SUPERGOLD3", // SKINCOLOR_SUPERGOLD3, + "SUPERGOLD4", // SKINCOLOR_SUPERGOLD4, + "SUPERGOLD5", // SKINCOLOR_SUPERGOLD5, + + "SUPERPERIDOT1", // SKINCOLOR_SUPERPERIDOT1 + "SUPERPERIDOT2", // SKINCOLOR_SUPERPERIDOT2, + "SUPERPERIDOT3", // SKINCOLOR_SUPERPERIDOT3, + "SUPERPERIDOT4", // SKINCOLOR_SUPERPERIDOT4, + "SUPERPERIDOT5", // SKINCOLOR_SUPERPERIDOT5, + + "SUPERSKY1", // SKINCOLOR_SUPERSKY1 + "SUPERSKY2", // SKINCOLOR_SUPERSKY2, + "SUPERSKY3", // SKINCOLOR_SUPERSKY3, + "SUPERSKY4", // SKINCOLOR_SUPERSKY4, + "SUPERSKY5", // SKINCOLOR_SUPERSKY5, + + "SUPERPURPLE1", // SKINCOLOR_SUPERPURPLE1, + "SUPERPURPLE2", // SKINCOLOR_SUPERPURPLE2, + "SUPERPURPLE3", // SKINCOLOR_SUPERPURPLE3, + "SUPERPURPLE4", // SKINCOLOR_SUPERPURPLE4, + "SUPERPURPLE5", // SKINCOLOR_SUPERPURPLE5, + + "SUPERRUST1", // SKINCOLOR_SUPERRUST1 + "SUPERRUST2", // SKINCOLOR_SUPERRUST2, + "SUPERRUST3", // SKINCOLOR_SUPERRUST3, + "SUPERRUST4", // SKINCOLOR_SUPERRUST4, + "SUPERRUST5", // SKINCOLOR_SUPERRUST5, + + "SUPERTAN1", // SKINCOLOR_SUPERTAN1 + "SUPERTAN2", // SKINCOLOR_SUPERTAN2, + "SUPERTAN3", // SKINCOLOR_SUPERTAN3, + "SUPERTAN4", // SKINCOLOR_SUPERTAN4, + "SUPERTAN5" // SKINCOLOR_SUPERTAN5, }; static const char *const POWERS_LIST[] = { @@ -6914,10 +8193,12 @@ static const char *const POWERS_LIST[] = { "SNEAKERS", "FLASHING", "SHIELD", + "CARRY", "TAILSFLY", // tails flying "UNDERWATER", // underwater timer "SPACETIME", // In space, no one can hear you spin! "EXTRALIFE", // Extra Life timer + "PUSHING", "SUPER", // Are you super? "GRAVITYBOOTS", // gravity boots @@ -6940,37 +8221,26 @@ static const char *const POWERS_LIST[] = { "NIGHTS_LINKFREEZE", //for linedef exec 427 - "NOCONTROL", - "INGOOP" // In goop + "NOCONTROL" }; static const char *const HUDITEMS_LIST[] = { - "LIVESNAME", - "LIVESPIC", - "LIVESNUM", - "LIVESX", + "LIVES", "RINGS", - "RINGSSPLIT", "RINGSNUM", - "RINGSNUMSPLIT", "SCORE", "SCORENUM", "TIME", - "TIMESPLIT", "MINUTES", - "MINUTESSPLIT", "TIMECOLON", - "TIMECOLONSPLIT", "SECONDS", - "SECONDSSPLIT", "TIMETICCOLON", "TICS", "SS_TOTALRINGS", - "SS_TOTALRINGS_SPLIT", "GETRINGS", "GETRINGSNUM", @@ -6978,10 +8248,100 @@ static const char *const HUDITEMS_LIST[] = { "TIMELEFTNUM", "TIMEUP", "HUNTPICS", - "GRAVBOOTSICO", + "POWERUPS", "LAP" }; +static const char *const MENUTYPES_LIST[] = { + "NONE", + + "MAIN", + + // Single Player + "SP_MAIN", + + "SP_LOAD", + "SP_PLAYER", + + "SP_LEVELSELECT", + "SP_LEVELSTATS", + + "SP_TIMEATTACK", + "SP_TIMEATTACK_LEVELSELECT", + "SP_GUESTREPLAY", + "SP_REPLAY", + "SP_GHOST", + + "SP_NIGHTSATTACK", + "SP_NIGHTS_LEVELSELECT", + "SP_NIGHTS_GUESTREPLAY", + "SP_NIGHTS_REPLAY", + "SP_NIGHTS_GHOST", + + // Multiplayer + "MP_MAIN", + "MP_SPLITSCREEN", // SplitServer + "MP_SERVER", + "MP_CONNECT", + "MP_ROOM", + "MP_PLAYERSETUP", // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET + + // Options + "OP_MAIN", + + "OP_P1CONTROLS", + "OP_CHANGECONTROLS", // OP_ChangeControlsDef shared with P2 + "OP_P1MOUSE", + "OP_P1JOYSTICK", + "OP_JOYSTICKSET", // OP_JoystickSetDef shared with P2 + + "OP_P2CONTROLS", + "OP_P2MOUSE", + "OP_P2JOYSTICK", + + "OP_VIDEO", + "OP_VIDEOMODE", + "OP_COLOR", + "OP_OPENGL", + "OP_OPENGL_LIGHTING", + "OP_OPENGL_FOG", + "OP_OPENGL_COLOR", + + "OP_SOUND", + + "OP_SERVER", + "OP_MONITORTOGGLE", + + "OP_DATA", + "OP_ADDONS", + "OP_SCREENSHOTS", + "OP_ERASEDATA", + + // Secrets + "SR_MAIN", + "SR_PANDORA", + "SR_LEVELSELECT", + "SR_UNLOCKCHECKLIST", + "SR_EMBLEMHINT", + + // Addons (Part of MISC, but let's make it our own) + "AD_MAIN", + + // MISC + // "MESSAGE", + // "SPAUSE", + + // "MPAUSE", + // "SCRAMBLETEAM", + // "CHANGETEAM", + // "CHANGELEVEL", + + // "MAPAUSE", + // "HELP", + + "SPECIAL" +}; + struct { const char *n; // has to be able to hold both fixed_t and angle_t, so drastic measure!! @@ -7022,6 +8382,8 @@ struct { {"CODEBASE",CODEBASE}, // or what release of SRB2 this is. {"VERSION",VERSION}, // Grab the game's version! {"SUBVERSION",SUBVERSION}, // more precise version number + {"NEWTICRATE",NEWTICRATE}, // TICRATE*NEWTICRATERATIO + {"NEWTICRATERATIO",NEWTICRATERATIO}, // Special linedef executor tag numbers! {"LE_PINCHPHASE",LE_PINCHPHASE}, // A boss entered pinch phase (and, in most cases, is preparing their pinch phase attack!) @@ -7029,13 +8391,28 @@ struct { {"LE_BOSSDEAD",LE_BOSSDEAD}, // A boss in the map died (Chaos mode boss tally) {"LE_BOSS4DROP",LE_BOSS4DROP}, // CEZ boss dropped its cage {"LE_BRAKVILEATACK",LE_BRAKVILEATACK}, // Brak's doing his LOS attack, oh noes + {"LE_TURRET",LE_TURRET}, // THZ turret + {"LE_BRAKPLATFORM",LE_BRAKPLATFORM}, // v2.0 Black Eggman destroys platform + {"LE_CAPSULE2",LE_CAPSULE2}, // Egg Capsule + {"LE_CAPSULE1",LE_CAPSULE1}, // Egg Capsule + {"LE_CAPSULE0",LE_CAPSULE0}, // Egg Capsule + {"LE_KOOPA",LE_KOOPA}, // Distant cousin to Gay Bowser + {"LE_AXE",LE_AXE}, // MKB Axe object + {"LE_PARAMWIDTH",LE_PARAMWIDTH}, // If an object that calls LinedefExecute has a nonzero parameter value, this times the parameter will be subtracted. (Mostly for the purpose of coexisting bosses...) /// \todo Get all this stuff into its own sections, maybe. Maybe. // Frame settings {"FF_FRAMEMASK",FF_FRAMEMASK}, + {"FF_SPR2SUPER",FF_SPR2SUPER}, + {"FF_SPR2ENDSTATE",FF_SPR2ENDSTATE}, + {"FF_SPR2MIDSTART",FF_SPR2MIDSTART}, {"FF_ANIMATE",FF_ANIMATE}, + {"FF_RANDOMANIM",FF_RANDOMANIM}, + {"FF_GLOBALANIM",FF_GLOBALANIM}, {"FF_FULLBRIGHT",FF_FULLBRIGHT}, + {"FF_VERTICALFLIP",FF_VERTICALFLIP}, + {"FF_PAPERSPRITE",FF_PAPERSPRITE}, {"FF_TRANSMASK",FF_TRANSMASK}, {"FF_TRANSSHIFT",FF_TRANSSHIFT}, // new preshifted translucency (used in source) @@ -7092,17 +8469,15 @@ struct { {"LF_NOSSMUSIC",LF_NOSSMUSIC}, {"LF_NORELOAD",LF_NORELOAD}, {"LF_NOZONE",LF_NOZONE}, + {"LF_SAVEGAME",LF_SAVEGAME}, + {"LF_MIXNIGHTSCOUNTDOWN",LF_MIXNIGHTSCOUNTDOWN}, // And map flags {"LF2_HIDEINMENU",LF2_HIDEINMENU}, {"LF2_HIDEINSTATS",LF2_HIDEINSTATS}, {"LF2_RECORDATTACK",LF2_RECORDATTACK}, {"LF2_NIGHTSATTACK",LF2_NIGHTSATTACK}, {"LF2_NOVISITNEEDED",LF2_NOVISITNEEDED}, - - // Save override - {"SAVE_NEVER",SAVE_NEVER}, - {"SAVE_DEFAULT",SAVE_DEFAULT}, - {"SAVE_ALWAYS",SAVE_ALWAYS}, + {"LF2_WIDEICON",LF2_WIDEICON}, // NiGHTS grades {"GRADE_F",GRADE_F}, @@ -7136,23 +8511,43 @@ struct { {"PRECIP_STORM_NOSTRIKES",PRECIP_STORM_NOSTRIKES}, // Shields - // These ones use the lower 8 bits {"SH_NONE",SH_NONE}, - {"SH_JUMP",SH_JUMP}, + // Shield flags + {"SH_PROTECTFIRE",SH_PROTECTFIRE}, + {"SH_PROTECTWATER",SH_PROTECTWATER}, + {"SH_PROTECTELECTRIC",SH_PROTECTELECTRIC}, + {"SH_PROTECTSPIKE",SH_PROTECTSPIKE}, + // Indivisible shields + {"SH_PITY",SH_PITY}, + {"SH_WHIRLWIND",SH_WHIRLWIND}, + {"SH_ARMAGEDDON",SH_ARMAGEDDON}, + // normal shields that use flags {"SH_ATTRACT",SH_ATTRACT}, {"SH_ELEMENTAL",SH_ELEMENTAL}, - {"SH_BOMB",SH_BOMB}, + // Sonic 3 shields + {"SH_FLAMEAURA",SH_FLAMEAURA}, {"SH_BUBBLEWRAP",SH_BUBBLEWRAP}, {"SH_THUNDERCOIN",SH_THUNDERCOIN}, - {"SH_FLAMEAURA",SH_FLAMEAURA}, - {"SH_PITY",SH_PITY}, - // These ones are special and use the upper bits - {"SH_FIREFLOWER",SH_FIREFLOWER}, // Lower bits are a normal shield stacked on top of the fire flower - {"SH_FORCE",SH_FORCE}, // Lower bits are how many hits left, 0 is the last hit - // Stack masks + // The force shield uses the lower 8 bits to count how many extra hits are left. + {"SH_FORCE",SH_FORCE}, + {"SH_FORCEHP",SH_FORCEHP}, // to be used as a bitmask only + // Mostly for use with Mario mode. + {"SH_FIREFLOWER", SH_FIREFLOWER}, {"SH_STACK",SH_STACK}, {"SH_NOSTACK",SH_NOSTACK}, + // Carrying + {"CR_NONE",CR_NONE}, + {"CR_GENERIC",CR_GENERIC}, + {"CR_PLAYER",CR_PLAYER}, + {"CR_NIGHTSMODE",CR_NIGHTSMODE}, + {"CR_NIGHTSFALL",CR_NIGHTSFALL}, + {"CR_BRAKGOOP",CR_BRAKGOOP}, + {"CR_ZOOMTUBE",CR_ZOOMTUBE}, + {"CR_ROPEHANG",CR_ROPEHANG}, + {"CR_MACESPIN",CR_MACESPIN}, + {"CR_MINECART",CR_MINECART}, + // Ring weapons (ringweapons_t) // Useful for A_GiveWeapon {"RW_AUTO",RW_AUTO}, @@ -7164,12 +8559,20 @@ struct { // Character flags (skinflags_t) {"SF_SUPER",SF_SUPER}, - {"SF_SUPERANIMS",SF_SUPERANIMS}, - {"SF_SUPERSPIN",SF_SUPERSPIN}, + {"SF_NOSUPERSPIN",SF_NOSUPERSPIN}, + {"SF_NOSPINDASHDUST",SF_NOSPINDASHDUST}, {"SF_HIRES",SF_HIRES}, {"SF_NOSKID",SF_NOSKID}, {"SF_NOSPEEDADJUST",SF_NOSPEEDADJUST}, {"SF_RUNONWATER",SF_RUNONWATER}, + {"SF_NOJUMPSPIN",SF_NOJUMPSPIN}, + {"SF_NOJUMPDAMAGE",SF_NOJUMPDAMAGE}, + {"SF_STOMPDAMAGE",SF_STOMPDAMAGE}, + {"SF_MARIODAMAGE",SF_MARIODAMAGE}, + {"SF_MACHINE",SF_MACHINE}, + {"SF_DASHMODE",SF_DASHMODE}, + {"SF_FASTEDGE",SF_FASTEDGE}, + {"SF_MULTIABILITY",SF_MULTIABILITY}, // Character abilities! // Primary @@ -7187,10 +8590,13 @@ struct { {"CA_JUMPBOOST",CA_JUMPBOOST}, {"CA_AIRDRILL",CA_AIRDRILL}, {"CA_JUMPTHOK",CA_JUMPTHOK}, + {"CA_BOUNCE",CA_BOUNCE}, + {"CA_TWINSPIN",CA_TWINSPIN}, // Secondary {"CA2_NONE",CA2_NONE}, // now slot 0! {"CA2_SPINDASH",CA2_SPINDASH}, - {"CA2_MULTIABILITY",CA2_MULTIABILITY}, + {"CA2_GUNSLINGER",CA2_GUNSLINGER}, + {"CA2_MELEE",CA2_MELEE}, // Sound flags {"SF_TOTALLYSINGLE",SF_TOTALLYSINGLE}, @@ -7201,6 +8607,15 @@ struct { {"SF_NOINTERRUPT",SF_NOINTERRUPT}, {"SF_X2AWAYSOUND",SF_X2AWAYSOUND}, + // Global emblem var flags + {"GE_NIGHTSPULL",GE_NIGHTSPULL}, + {"GE_NIGHTSITEM",GE_NIGHTSITEM}, + + // Map emblem var flags + {"ME_ALLEMERALDS",ME_ALLEMERALDS}, + {"ME_ULTIMATE",ME_ULTIMATE}, + {"ME_PERFECT",ME_PERFECT}, + #ifdef HAVE_BLUA // p_local.h constants {"FLOATSPEED",FLOATSPEED}, @@ -7215,6 +8630,23 @@ struct { {"PAL_MIXUP",PAL_MIXUP}, {"PAL_RECYCLE",PAL_RECYCLE}, {"PAL_NUKE",PAL_NUKE}, + // for P_DamageMobj + //// Damage types + {"DMG_WATER",DMG_WATER}, + {"DMG_FIRE",DMG_FIRE}, + {"DMG_ELECTRIC",DMG_ELECTRIC}, + {"DMG_SPIKE",DMG_SPIKE}, + {"DMG_NUKE",DMG_NUKE}, + //// Death types + {"DMG_INSTAKILL",DMG_INSTAKILL}, + {"DMG_DROWNED",DMG_DROWNED}, + {"DMG_SPACEDROWN",DMG_SPACEDROWN}, + {"DMG_DEATHPIT",DMG_DEATHPIT}, + {"DMG_CRUSHED",DMG_CRUSHED}, + {"DMG_SPECTATOR",DMG_SPECTATOR}, + //// Masks + {"DMG_CANHURTSELF",DMG_CANHURTSELF}, + {"DMG_DEATHMASK",DMG_DEATHMASK}, // Gametypes, for use with global var "gametype" {"GT_COOP",GT_COOP}, @@ -7234,11 +8666,18 @@ struct { // Player animation (panim_t) {"PA_ETC",PA_ETC}, {"PA_IDLE",PA_IDLE}, + {"PA_EDGE",PA_EDGE}, {"PA_WALK",PA_WALK}, {"PA_RUN",PA_RUN}, + {"PA_DASH",PA_DASH}, + {"PA_PAIN",PA_PAIN}, {"PA_ROLL",PA_ROLL}, + {"PA_JUMP",PA_JUMP}, + {"PA_SPRING",PA_SPRING}, {"PA_FALL",PA_FALL}, {"PA_ABILITY",PA_ABILITY}, + {"PA_ABILITY2",PA_ABILITY2}, + {"PA_RIDE",PA_RIDE}, // Current weapon {"WEP_AUTO",WEP_AUTO}, @@ -7249,6 +8688,9 @@ struct { {"WEP_RAIL",WEP_RAIL}, {"NUM_WEAPONS",NUM_WEAPONS}, + // Value for infinite lives + {"INFLIVES", INFLIVES}, + // Got Flags, for player->gotflag! // Used to be MF_ for some stupid reason, now they're GF_ to stop them looking like mobjflags {"GF_REDFLAG",GF_REDFLAG}, @@ -7316,6 +8758,10 @@ struct { {"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel {"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop. +#ifdef HAVE_LUA_SEGS + // Node flags + {"NF_SUBSECTOR",NF_SUBSECTOR}, // Indicate a leaf. +#endif #ifdef ESLOPE // Slope flags {"SL_NOPHYSICS",SL_NOPHYSICS}, // Don't do momentum adjustment with this slope @@ -7405,13 +8851,23 @@ struct { {"V_6WIDTHSPACE",V_6WIDTHSPACE}, {"V_OLDSPACING",V_OLDSPACING}, {"V_MONOSPACE",V_MONOSPACE}, - {"V_PURPLEMAP",V_PURPLEMAP}, + + {"V_MAGENTAMAP",V_MAGENTAMAP}, {"V_YELLOWMAP",V_YELLOWMAP}, {"V_GREENMAP",V_GREENMAP}, {"V_BLUEMAP",V_BLUEMAP}, {"V_REDMAP",V_REDMAP}, {"V_GRAYMAP",V_GRAYMAP}, {"V_ORANGEMAP",V_ORANGEMAP}, + {"V_SKYMAP",V_SKYMAP}, + {"V_PURPLEMAP",V_PURPLEMAP}, + {"V_AQUAMAP",V_AQUAMAP}, + {"V_PERIDOTMAP",V_PERIDOTMAP}, + {"V_AZUREMAP",V_AZUREMAP}, + {"V_BROWNMAP",V_BROWNMAP}, + {"V_ROSYMAP",V_ROSYMAP}, + {"V_INVERTMAP",V_INVERTMAP}, + {"V_TRANSLUCENT",V_TRANSLUCENT}, {"V_10TRANS",V_10TRANS}, {"V_20TRANS",V_20TRANS}, @@ -7437,7 +8893,7 @@ struct { {"V_WRAPX",V_WRAPX}, {"V_WRAPY",V_WRAPY}, {"V_NOSCALESTART",V_NOSCALESTART}, - {"V_SPLITSCREEN",V_SPLITSCREEN}, + {"V_PERPLAYER",V_PERPLAYER}, {"V_PARAMMASK",V_PARAMMASK}, {"V_SCALEPATCHMASK",V_SCALEPATCHMASK}, @@ -7477,7 +8933,7 @@ static mobjtype_t get_mobjtype(const char *word) if (fastcmp(word, MOBJTYPE_LIST[i]+3)) return i; deh_warning("Couldn't find mobjtype named 'MT_%s'",word); - return MT_BLUECRAWLA; + return MT_NULL; } static statenum_t get_state(const char *word) @@ -7514,6 +8970,20 @@ static spritenum_t get_sprite(const char *word) return SPR_NULL; } +static playersprite_t get_sprite2(const char *word) +{ // Returns the value of SPR2_ enumerations + playersprite_t i; + if (*word >= '0' && *word <= '9') + return atoi(word); + if (fastncmp("SPR2_",word,5)) + word += 5; // take off the SPR2_ + for (i = 0; i < NUMPLAYERSPRITES; i++) + if (!spr2names[i][4] && memcmp(word,spr2names[i],4)==0) + return i; + deh_warning("Couldn't find sprite named 'SPR2_%s'",word); + return SPR2_STND; +} + static sfxenum_t get_sfx(const char *word) { // Returns the value of SFX_ enumerations sfxenum_t i; @@ -7581,7 +9051,21 @@ static hudnum_t get_huditem(const char *word) if (fastcmp(word, HUDITEMS_LIST[i])) return i; deh_warning("Couldn't find huditem named 'HUD_%s'",word); - return HUD_LIVESNAME; + return HUD_LIVES; +} + +static menutype_t get_menutype(const char *word) +{ // Returns the value of MN_ enumerations + menutype_t i; + if (*word >= '0' && *word <= '9') + return atoi(word); + if (fastncmp("MN_",word,3)) + word += 3; // take off the MN_ + for (i = 0; i < NUMMENUTYPES; i++) + if (fastcmp(word, MENUTYPES_LIST[i])) + return i; + deh_warning("Couldn't find menutype named 'MN_%s'",word); + return MN_NONE; } #ifndef HAVE_BLUA @@ -7780,6 +9264,11 @@ static fixed_t find_const(const char **rword) free(word); return r; } + else if (fastncmp("MN_",word,4)) { + r = get_menutype(word); + free(word); + return r; + } else if (fastncmp("HUD_",word,4)) { r = get_huditem(word); free(word); @@ -7864,11 +9353,14 @@ void DEH_Check(void) static inline int lib_freeslot(lua_State *L) { int n = lua_gettop(L); - int r = 0; // args returned + int r = 0; // args returned char *s, *type,*word; - while (n-- > 0) - { + if (!lua_lumploading) + return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); + + while (n-- > 0) + { s = Z_StrDup(luaL_checkstring(L,1)); type = strtok(s, "_"); if (type) @@ -7894,7 +9386,7 @@ static inline int lib_freeslot(lua_State *L) lua_pushinteger(L, sfx); r++; } else - return r; + CONS_Alert(CONS_WARNING, "Ran out of free SFX slots!\n"); } else if (fastcmp(type, "SPR")) { @@ -7921,7 +9413,7 @@ static inline int lib_freeslot(lua_State *L) break; } if (j > SPR_LASTFREESLOT) - return r; + CONS_Alert(CONS_WARNING, "Ran out of free sprite slots!\n"); } else if (fastcmp(type, "S")) { @@ -7936,7 +9428,7 @@ static inline int lib_freeslot(lua_State *L) break; } if (i == NUMSTATEFREESLOTS) - return r; + CONS_Alert(CONS_WARNING, "Ran out of free State slots!\n"); } else if (fastcmp(type, "MT")) { @@ -7951,7 +9443,26 @@ static inline int lib_freeslot(lua_State *L) break; } if (i == NUMMOBJFREESLOTS) - return r; + CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n"); + } + else if (fastcmp(type, "SPR2")) + { + // Search if we already have an SPR2 by that name... + playersprite_t i; + for (i = SPR2_FIRSTFREESLOT; i < free_spr2; i++) + if (memcmp(spr2names[i],word,4) == 0) + break; + // We don't, so allocate a new one. + if (i >= free_spr2) { + if (free_spr2 < NUMPLAYERSPRITES) + { + CONS_Printf("Sprite SPR2_%s allocated.\n",word); + strncpy(spr2names[free_spr2],word,4); + spr2names[free_spr2++][4] = 0; + } else + CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n"); + } + r++; } Z_Free(s); lua_remove(L, 1); @@ -7961,14 +9472,14 @@ static inline int lib_freeslot(lua_State *L) } // Wrapper for ALL A_Action functions. -// Upvalue: actionf_t to represent // Arguments: mobj_t actor, int var1, int var2 -static inline int lib_action(lua_State *L) +static int action_call(lua_State *L) { - actionf_t *action = lua_touserdata(L,lua_upvalueindex(1)); - mobj_t *actor = *((mobj_t **)luaL_checkudata(L,1,META_MOBJ)); - var1 = (INT32)luaL_optinteger(L,2,0); - var2 = (INT32)luaL_optinteger(L,3,0); + //actionf_t *action = lua_touserdata(L,lua_upvalueindex(1)); + actionf_t *action = *((actionf_t **)luaL_checkudata(L, 1, META_ACTION)); + mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + var1 = (INT32)luaL_optinteger(L, 3, 0); + var2 = (INT32)luaL_optinteger(L, 4, 0); if (!actor) return LUA_ErrInvalid(L, "mobj_t"); action->acp1(actor); @@ -8116,6 +9627,27 @@ static inline int lib_getenum(lua_State *L) if (mathlib) return luaL_error(L, "sprite '%s' could not be found.\n", word); return 0; } + else if (fastncmp("SPR2_",word,5)) { + p = word+5; + for (i = 0; i < (fixed_t)free_spr2; i++) + if (!spr2names[i][4]) + { + // special 3-char cases, e.g. SPR2_RUN + // the spr2names entry will have "_" on the end, as in "RUN_" + if (spr2names[i][3] == '_' && !p[3]) { + if (fastncmp(p,spr2names[i],3)) { + lua_pushinteger(L, i); + return 1; + } + } + else if (fastncmp(p,spr2names[i],4)) { + lua_pushinteger(L, i); + return 1; + } + } + if (mathlib) return luaL_error(L, "player sprite '%s' could not be found.\n", word); + return 0; + } else if (!mathlib && fastncmp("sfx_",word,4)) { p = word+4; for (i = 0; i < NUMSFX; i++) @@ -8205,6 +9737,16 @@ static inline int lib_getenum(lua_State *L) if (mathlib) return luaL_error(L, "skincolor '%s' could not be found.\n", word); return 0; } + else if (fastncmp("MN_",word,3)) { + p = word+3; + for (i = 0; i < NUMMENUTYPES; i++) + if (fastcmp(p, MENUTYPES_LIST[i])) { + lua_pushinteger(L, i); + return 1; + } + if (mathlib) return luaL_error(L, "menutype '%s' could not be found.\n", word); + return 0; + } else if (!mathlib && fastncmp("A_",word,2)) { char *caps; // Try to get a Lua action first. @@ -8224,9 +9766,8 @@ static inline int lib_getenum(lua_State *L) // Retrieving them from this metatable allows them to be case-insensitive! for (i = 0; actionpointers[i].name; i++) if (fasticmp(word, actionpointers[i].name)) { - // push lib_action as a C closure with the actionf_t* as an upvalue. - lua_pushlightuserdata(L, &actionpointers[i].action); - lua_pushcclosure(L, lib_action, 1); + // We push the actionf_t* itself as userdata! + LUA_PushUserdata(L, &actionpointers[i].action, META_ACTION); return 1; } return 0; @@ -8240,8 +9781,7 @@ static inline int lib_getenum(lua_State *L) } for (i = 0; actionpointers[i].name; i++) if (fasticmp(superactions[superstack-1], actionpointers[i].name)) { - lua_pushlightuserdata(L, &actionpointers[i].action); - lua_pushcclosure(L, lib_action, 1); + LUA_PushUserdata(L, &actionpointers[i].action, META_ACTION); return 1; } return 0; @@ -8303,6 +9843,12 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"paused")) { lua_pushboolean(L, paused); return 1; + } else if (fastcmp(word,"titlemap")) { + lua_pushinteger(L, titlemap); + return 1; + } else if (fastcmp(word,"titlemapinaction")) { + lua_pushboolean(L, (titlemapinaction != TITLEMAP_OFF)); + return 1; } else if (fastcmp(word,"gametype")) { lua_pushinteger(L, gametype); return 1; @@ -8371,9 +9917,66 @@ int LUA_EnumLib(lua_State *L) return 0; } +// getActionName(action) -> return action's string name +static int lib_getActionName(lua_State *L) +{ + if (lua_isuserdata(L, 1)) // arg 1 is built-in action, expect action userdata + { + actionf_t *action = *((actionf_t **)luaL_checkudata(L, 1, META_ACTION)); + const char *name = NULL; + if (!action) + return luaL_error(L, "not a valid action?"); + name = LUA_GetActionName(action); + if (!name) // that can't be right? + return luaL_error(L, "no name string could be found for this action"); + lua_pushstring(L, name); + return 1; + } + else if (lua_isfunction(L, 1)) // arg 1 is a function (either C or Lua) + { + lua_settop(L, 1); // set top of stack to 1 (removing any extra args, which there shouldn't be) + // get the name for this action, if possible. + lua_getfield(L, LUA_REGISTRYINDEX, LREG_ACTIONS); + lua_pushnil(L); + // Lua stack at this point: + // 1 ... -2 -1 + // arg ... LREG_ACTIONS nil + while (lua_next(L, -2)) + { + // Lua stack at this point: + // 1 ... -3 -2 -1 + // arg ... LREG_ACTIONS "A_ACTION" function + if (lua_rawequal(L, -1, 1)) // is this the same as the arg? + { + // make sure the key (i.e. "A_ACTION") is a string first + // (note: we don't use lua_isstring because it also returns true for numbers) + if (lua_type(L, -2) == LUA_TSTRING) + { + lua_pushvalue(L, -2); // push "A_ACTION" string to top of stack + return 1; + } + lua_pop(L, 2); // pop the name and function + break; // probably should have succeeded but we didn't, so end the loop + } + lua_pop(L, 1); + } + lua_pop(L, 1); // pop LREG_ACTIONS + return 0; // return nothing (don't error) + } + + return luaL_typerror(L, 1, "action userdata or Lua function"); +} + int LUA_SOCLib(lua_State *L) { lua_register(L,"freeslot",lib_freeslot); + lua_register(L,"getActionName",lib_getActionName); + + luaL_newmetatable(L, META_ACTION); + lua_pushcfunction(L, action_call); + lua_setfield(L, -2, "__call"); + lua_pop(L, 1); + return 0; } diff --git a/src/dehacked.h b/src/dehacked.h index 411cb6c1b5ec6c3309f57f2d679db1811bc57982..31f7f220dceb37654af225bf8113928922ac78f7 100644 --- a/src/dehacked.h +++ b/src/dehacked.h @@ -27,15 +27,8 @@ typedef enum UNDO_DONE = 0, } undotype_f; -#ifdef DELFILE -void DEH_WriteUndoline(const char *value, const char *data, undotype_f flags); -void DEH_UnloadDehackedWad(UINT16 wad); -#else // null the undo lines -#define DEH_WriteUndoline(a,b,c) -#endif - void DEH_LoadDehackedLump(lumpnum_t lumpnum); -void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump); +void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump, boolean mainfile); void DEH_Check(void); diff --git a/src/djgppdos/i_video.c b/src/djgppdos/i_video.c index 612c722151967a614d33a3b476da42652e46491f..6a7641174491d47793895c24677c6221c1f9e73b 100644 --- a/src/djgppdos/i_video.c +++ b/src/djgppdos/i_video.c @@ -90,6 +90,10 @@ static unsigned long nombre = NEWTICRATE*10; static void I_BlitScreenVesa1(void); //see later void I_FinishUpdate (void) { + // draw captions if enabled + if (cv_closedcaptioning.value) + SCR_ClosedCaptions(); + // draw FPS if enabled if (cv_ticrate.value) SCR_DisplayTicRate(); diff --git a/src/doomdata.h b/src/doomdata.h index ff025e99c0b9d1f8943ab3f2ab9911b396d9b2d4..2b9472569c598cbb345de0176351eacab42dc8d1 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -46,6 +46,9 @@ enum ML_BLOCKMAP, // LUT, motion clipping, walls/grid element }; +// Extra flag for objects. +#define MTF_EXTRA 1 + // Reverse gravity flag for objects. #define MTF_OBJECTFLIP 2 @@ -207,8 +210,9 @@ typedef struct #define ZSHIFT 4 -extern const char *Color_Names[MAXSKINCOLORS]; -extern const UINT8 Color_Opposite[MAXSKINCOLORS*2]; +extern const UINT8 Color_Index[MAXTRANSLATIONS-1][16]; +extern const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS]; +extern const UINT8 Color_Opposite[(MAXSKINCOLORS - 1)*2]; #define NUMMAPS 1035 diff --git a/src/doomdef.h b/src/doomdef.h index 6b6afbf1bb6058160280460d3f20507807eaf038..475328918ab57a54c013e9f7c6ea965583450e61 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -28,13 +28,11 @@ // Use Mixer interface? #ifdef HAVE_MIXER - //#if !defined(DC) && !defined(_WIN32_WCE) && !defined(_XBOX) && !defined(GP2X) #define SOUND SOUND_MIXER #define NOHS // No HW3SOUND #ifdef HW3SOUND #undef HW3SOUND #endif - //#endif #endif // Use generic SDL interface. @@ -70,7 +68,7 @@ #endif #endif -#if defined (_WIN32) || defined (_WIN32_WCE) +#ifdef _WIN32 #define ASMCALL __cdecl #else #define ASMCALL @@ -87,13 +85,6 @@ // warning C4152: nonstandard extension, function/data pointer conversion in expression // warning C4213: nonstandard extension used : cast on l-value -#if defined (_WIN32_WCE) && defined (DEBUG) && defined (ARM) -#if defined (ARMV4) || defined (ARMV4I) -//#pragma warning(disable : 1166) -// warning LNK1166: cannot adjust code at offset= -#endif -#endif - #include "doomtype.h" @@ -110,13 +101,11 @@ #include <locale.h> #endif -#if !defined (_WIN32_WCE) #include <sys/types.h> #include <sys/stat.h> -#endif #include <ctype.h> -#if ((defined (_WIN32) && !defined (_WIN32_WCE)) || defined (__DJGPP__)) && !defined (_XBOX) +#if defined (_WIN32) || defined (__DJGPP__) #include <io.h> #endif @@ -140,7 +129,7 @@ extern FILE *logstream; #endif -//#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3 +#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3 #ifdef DEVELOP #define VERSION 0 // Game version #define SUBVERSION 0 // more precise version number @@ -149,10 +138,10 @@ extern FILE *logstream; // most interface strings are ignored in development mode. // we use comprevision and compbranch instead. #else -#define VERSION 201 // Game version -#define SUBVERSION 24 // more precise version number -#define VERSIONSTRING "v2.1.24" -#define VERSIONSTRINGW L"v2.1.24" +#define VERSION 202 // Game version +#define SUBVERSION 0 // more precise version number +#define VERSIONSTRING "v2.2" +#define VERSIONSTRINGW L"v2.2" // Hey! If you change this, add 1 to the MODVERSION below! // Otherwise we can't force updates! #endif @@ -206,7 +195,7 @@ extern FILE *logstream; // and should not be changed unless you have merged changes between versions of SRB2 // (such as 2.0.4 to 2.0.5, etc) into your working copy. // Will always resemble the versionstring, 205 = 2.0.5, 210 = 2.1, etc. -#define CODEBASE 210 +#define CODEBASE 220 // The Modification ID; must be obtained from Rob ( https://mb.srb2.org/private.php?do=newpm&u=546 ). // DO NOT try to set this otherwise, or your modification will be unplayable through the Master Server. @@ -217,7 +206,7 @@ extern FILE *logstream; // 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.1.0 is not version "1". -#define MODVERSION 29 +#define MODVERSION 28 // To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically. // Increment MINOREXECVERSION whenever a config change is needed that does not correspond @@ -239,64 +228,143 @@ extern FILE *logstream; // NOTE: it needs more than this to increase the number of players... #define MAXPLAYERS 32 -#define MAXSKINS MAXPLAYERS +#define MAXSKINS 32 #define PLAYERSMASK (MAXPLAYERS-1) #define MAXPLAYERNAME 21 typedef enum { SKINCOLOR_NONE = 0, + + // Greyscale ranges SKINCOLOR_WHITE, - SKINCOLOR_SILVER, + SKINCOLOR_BONE, + SKINCOLOR_CLOUDY, SKINCOLOR_GREY, + SKINCOLOR_SILVER, + SKINCOLOR_CARBON, + SKINCOLOR_JET, SKINCOLOR_BLACK, - SKINCOLOR_CYAN, - SKINCOLOR_TEAL, - SKINCOLOR_STEELBLUE, - SKINCOLOR_BLUE, - SKINCOLOR_PEACH, - SKINCOLOR_TAN, + + // Desaturated + SKINCOLOR_AETHER, + SKINCOLOR_SLATE, SKINCOLOR_PINK, - SKINCOLOR_LAVENDER, - SKINCOLOR_PURPLE, - SKINCOLOR_ORANGE, - SKINCOLOR_ROSEWOOD, - SKINCOLOR_BEIGE, + SKINCOLOR_YOGURT, SKINCOLOR_BROWN, + SKINCOLOR_TAN, + SKINCOLOR_BEIGE, + SKINCOLOR_MOSS, + SKINCOLOR_AZURE, + SKINCOLOR_LAVENDER, + + // Viv's vivid colours (toast 21/07/17) + SKINCOLOR_RUBY, + SKINCOLOR_SALMON, SKINCOLOR_RED, - SKINCOLOR_DARKRED, - SKINCOLOR_NEONGREEN, - SKINCOLOR_GREEN, - SKINCOLOR_ZIM, - SKINCOLOR_OLIVE, - SKINCOLOR_YELLOW, + SKINCOLOR_CRIMSON, + SKINCOLOR_FLAME, + SKINCOLOR_PEACHY, + SKINCOLOR_QUAIL, + SKINCOLOR_SUNSET, + SKINCOLOR_APRICOT, + SKINCOLOR_ORANGE, + SKINCOLOR_RUST, SKINCOLOR_GOLD, + SKINCOLOR_SANDY, + SKINCOLOR_YELLOW, + SKINCOLOR_OLIVE, + SKINCOLOR_LIME, + SKINCOLOR_PERIDOT, + SKINCOLOR_GREEN, + SKINCOLOR_FOREST, + SKINCOLOR_EMERALD, + SKINCOLOR_MINT, + SKINCOLOR_SEAFOAM, + SKINCOLOR_AQUA, + SKINCOLOR_TEAL, + SKINCOLOR_WAVE, + SKINCOLOR_CYAN, + SKINCOLOR_SKY, + SKINCOLOR_CERULEAN, + SKINCOLOR_ICY, + SKINCOLOR_SAPPHIRE, // sweet mother, i cannot weave – slender aphrodite has overcome me with longing for a girl + SKINCOLOR_CORNFLOWER, + SKINCOLOR_BLUE, + SKINCOLOR_COBALT, + SKINCOLOR_VAPOR, + SKINCOLOR_DUSK, + SKINCOLOR_PASTEL, + SKINCOLOR_PURPLE, + SKINCOLOR_BUBBLEGUM, + SKINCOLOR_MAGENTA, + SKINCOLOR_NEON, + SKINCOLOR_VIOLET, + SKINCOLOR_LILAC, + SKINCOLOR_PLUM, + SKINCOLOR_ROSY, + + // SKINCOLOR_? - one left before we bump up against 0x39, which isn't a HARD limit anymore but would be excessive - // Careful! MAXSKINCOLORS cannot be greater than 0x20! MAXSKINCOLORS, // Super special awesome Super flashing colors! - SKINCOLOR_SUPER1 = MAXSKINCOLORS, - SKINCOLOR_SUPER2, - SKINCOLOR_SUPER3, - SKINCOLOR_SUPER4, - SKINCOLOR_SUPER5, - - // Super Tails - SKINCOLOR_TSUPER1, - SKINCOLOR_TSUPER2, - SKINCOLOR_TSUPER3, - SKINCOLOR_TSUPER4, - SKINCOLOR_TSUPER5, - - // Super Knuckles - SKINCOLOR_KSUPER1, - SKINCOLOR_KSUPER2, - SKINCOLOR_KSUPER3, - SKINCOLOR_KSUPER4, - SKINCOLOR_KSUPER5, - - MAXTRANSLATIONS + SKINCOLOR_SUPERSILVER1 = MAXSKINCOLORS, + SKINCOLOR_SUPERSILVER2, + SKINCOLOR_SUPERSILVER3, + SKINCOLOR_SUPERSILVER4, + SKINCOLOR_SUPERSILVER5, + + SKINCOLOR_SUPERRED1, + SKINCOLOR_SUPERRED2, + SKINCOLOR_SUPERRED3, + SKINCOLOR_SUPERRED4, + SKINCOLOR_SUPERRED5, + + SKINCOLOR_SUPERORANGE1, + SKINCOLOR_SUPERORANGE2, + SKINCOLOR_SUPERORANGE3, + SKINCOLOR_SUPERORANGE4, + SKINCOLOR_SUPERORANGE5, + + SKINCOLOR_SUPERGOLD1, + SKINCOLOR_SUPERGOLD2, + SKINCOLOR_SUPERGOLD3, + SKINCOLOR_SUPERGOLD4, + SKINCOLOR_SUPERGOLD5, + + SKINCOLOR_SUPERPERIDOT1, + SKINCOLOR_SUPERPERIDOT2, + SKINCOLOR_SUPERPERIDOT3, + SKINCOLOR_SUPERPERIDOT4, + SKINCOLOR_SUPERPERIDOT5, + + SKINCOLOR_SUPERSKY1, + SKINCOLOR_SUPERSKY2, + SKINCOLOR_SUPERSKY3, + SKINCOLOR_SUPERSKY4, + SKINCOLOR_SUPERSKY5, + + SKINCOLOR_SUPERPURPLE1, + SKINCOLOR_SUPERPURPLE2, + SKINCOLOR_SUPERPURPLE3, + SKINCOLOR_SUPERPURPLE4, + SKINCOLOR_SUPERPURPLE5, + + SKINCOLOR_SUPERRUST1, + SKINCOLOR_SUPERRUST2, + SKINCOLOR_SUPERRUST3, + SKINCOLOR_SUPERRUST4, + SKINCOLOR_SUPERRUST5, + + SKINCOLOR_SUPERTAN1, + SKINCOLOR_SUPERTAN2, + SKINCOLOR_SUPERTAN3, + SKINCOLOR_SUPERTAN4, + SKINCOLOR_SUPERTAN5, + + MAXTRANSLATIONS, + NUMSUPERCOLORS = ((MAXTRANSLATIONS - MAXSKINCOLORS)/5) } skincolors_t; // State updates, number of tics / second. @@ -313,21 +381,27 @@ typedef enum // Special linedef executor tag numbers! enum { - LE_PINCHPHASE = -2, // A boss entered pinch phase (and, in most cases, is preparing their pinch phase attack!) - LE_ALLBOSSESDEAD = -3, // All bosses in the map are dead (Egg capsule raise) - LE_BOSSDEAD = -4, // A boss in the map died (Chaos mode boss tally) - LE_BOSS4DROP = -5, // CEZ boss dropped its cage - LE_BRAKVILEATACK = -6 // Brak's doing his LOS attack, oh noes + LE_PINCHPHASE = -2, // A boss entered pinch phase (and, in most cases, is preparing their pinch phase attack!) + LE_ALLBOSSESDEAD = -3, // All bosses in the map are dead (Egg capsule raise) + LE_BOSSDEAD = -4, // A boss in the map died (Chaos mode boss tally) + LE_BOSS4DROP = -5, // CEZ boss dropped its cage + LE_BRAKVILEATACK = -6, // Brak's doing his LOS attack, oh noes + LE_TURRET = 32000, // THZ turret + LE_BRAKPLATFORM = 4200, // v2.0 Black Eggman destroys platform + LE_CAPSULE2 = 682, // Egg Capsule + LE_CAPSULE1 = 681, // Egg Capsule + LE_CAPSULE0 = 680, // Egg Capsule + LE_KOOPA = 650, // Distant cousin to Gay Bowser + LE_AXE = 649, // MKB Axe object + LE_PARAMWIDTH = -100 // If an object that calls LinedefExecute has a nonzero parameter value, this times the parameter will be subtracted. (Mostly for the purpose of coexisting bosses...) }; // Name of local directory for config files and savegames -#if !defined(_arch_dreamcast) && !defined(_WIN32_WCE) && !defined(GP2X) && !defined(_WII) && !defined(_PS3) #if (((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON)) && !defined (__CYGWIN__)) && !defined (__APPLE__) #define DEFAULTDIR ".srb2" #else #define DEFAULTDIR "srb2" #endif -#endif #include "g_state.h" @@ -385,6 +459,7 @@ void M_StartupLocale(void); extern void *(*M_Memcpy)(void* dest, const void* src, size_t n) FUNCNONNULL; char *va(const char *format, ...) FUNCPRINTF; char *M_GetToken(const char *inputString); +void M_UnGetToken(void); char *sizeu1(size_t num); char *sizeu2(size_t num); char *sizeu3(size_t num); @@ -398,7 +473,7 @@ extern INT32 cv_debug; #define DBG_BASIC 0x0001 #define DBG_DETAILED 0x0002 -#define DBG_RANDOMIZER 0x0004 +#define DBG_PLAYER 0x0004 #define DBG_RENDER 0x0008 #define DBG_NIGHTSBASIC 0x0010 #define DBG_NIGHTS 0x0020 @@ -408,6 +483,7 @@ extern INT32 cv_debug; #define DBG_MEMORY 0x0200 #define DBG_SETUP 0x0400 #define DBG_LUA 0x0800 +#define DBG_RANDOMIZER 0x1000 // ======================= // Misc stuff for later... @@ -470,10 +546,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; #define ESLOPE_TYPESHIM #endif -/// Delete file while the game is running. -/// \note EXTREMELY buggy, tends to crash game. -//#define DELFILE - /// Allows the use of devmode in multiplayer. AKA "fishcake" //#define NETGAME_DEVMODE @@ -501,19 +573,15 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Most modifications should probably enable this. //#define SAVEGAME_OTHERVERSIONS -#if !defined (_NDS) && !defined (_PSP) /// Shuffle's incomplete OpenGL sorting code. #define SHUFFLE // This has nothing to do with sorting, why was it disabled? -#endif -#if !defined (_NDS) && !defined (_PSP) /// Allow the use of the SOC RESETINFO command. /// \note Builds that are tight on memory should disable this. /// This stops the game from storing backups of the states, sprites, and mobjinfo tables. /// Though this info is compressed under normal circumstances, it's still a lot of extra /// memory that never gets touched. #define ALLOW_RESETDATA -#endif #ifndef NONET /// Display a connection screen on join attempts. @@ -527,9 +595,19 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// \note You should leave this enabled unless you're working with a future SRB2 version. #define MUSICSLOT_COMPATIBILITY +/// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls. +//#define PAPER_COLLISIONCORRECTION + +/// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up +/// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down) +/// on the bright side it fixes some weird issues with translucent walls +/// \note SRB2CB port. +/// SRB2CB itself ported this from PrBoom+ +#define NEWCLIP + /// Handle touching sector specials in P_PlayerAfterThink instead of P_PlayerThink. /// \note Required for proper collision with moving sloped surfaces that have sector specials on them. -//#define SECTORSPECIALSAFTERTHINK +#define SECTORSPECIALSAFTERTHINK /// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up /// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down) diff --git a/src/doomstat.h b/src/doomstat.h index 7f8b5fd6e0e81c030ad2f7ec150e3ccc30aa008f..87b98ab40c979e8e819f13e94129f86bdb02d3d9 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -43,9 +43,14 @@ extern INT16 maptol; extern UINT8 globalweather; extern INT32 curWeather; extern INT32 cursaveslot; -extern INT16 lastmapsaved; +//extern INT16 lastmapsaved; +extern INT16 lastmaploaded; extern boolean gamecomplete; +#define maxgameovers 13 +extern UINT8 numgameovers; +extern SINT8 startinglivesbalance[maxgameovers+1]; + #define PRECIP_NONE 0 #define PRECIP_STORM 1 #define PRECIP_SNOW 2 @@ -120,11 +125,21 @@ extern INT32 secondarydisplayplayer; // for splitscreen // Maps of special importance extern INT16 spstage_start; -extern INT16 sstage_start; -extern INT16 sstage_end; +extern INT16 sstage_start, sstage_end, smpstage_start, smpstage_end; + +extern INT16 titlemap; +extern boolean hidetitlepics; +extern INT16 bootmap; //bootmap for loading a map on startup + +extern INT16 tutorialmap; // map to load for tutorial +extern boolean tutorialmode; // are we in a tutorial right now? +extern INT32 tutorialgcs; // which control scheme is loaded? +extern INT32 tutorialusemouse; // store cv_usemouse user value +extern INT32 tutorialfreelook; // store cv_alwaysfreelook user value +extern INT32 tutorialmousemove; // store cv_mousemove user value +extern INT32 tutorialanalog; // store cv_analog user value extern boolean looptitle; -extern boolean useNightsSS; // CTF colors. extern UINT8 skincolor_redteam, skincolor_blueteam, skincolor_redring, skincolor_bluering; @@ -163,11 +178,65 @@ typedef struct extern cutscene_t *cutscenes[128]; +// Reserve prompt space for tutorials +#define TUTORIAL_PROMPT 201 // one-based +#define TUTORIAL_AREAS 6 +#define TUTORIAL_AREA_PROMPTS 5 +#define MAX_PROMPTS (TUTORIAL_PROMPT+TUTORIAL_AREAS*TUTORIAL_AREA_PROMPTS*3) // 3 control modes +#define MAX_PAGES 128 + +#define PROMPT_PIC_PERSIST 0 +#define PROMPT_PIC_LOOP 1 +#define PROMPT_PIC_DESTROY 2 +#define MAX_PROMPT_PICS 8 +typedef struct +{ + UINT8 numpics; + UINT8 picmode; // sequence mode after displaying last pic, 0 = persist, 1 = loop, 2 = destroy + UINT8 pictoloop; // if picmode == loop, which pic to loop to? + UINT8 pictostart; // initial pic number to show + char picname[MAX_PROMPT_PICS][8]; + UINT8 pichires[MAX_PROMPT_PICS]; + UINT16 xcoord[MAX_PROMPT_PICS]; // gfx + UINT16 ycoord[MAX_PROMPT_PICS]; // gfx + UINT16 picduration[MAX_PROMPT_PICS]; + + char musswitch[7]; + UINT16 musswitchflags; + UINT8 musicloop; + + char tag[33]; // page tag + char name[34]; // narrator name, extra char for color + char iconname[8]; // narrator icon lump + boolean rightside; // narrator side, false = left, true = right + boolean iconflip; // narrator flip icon horizontally + UINT8 hidehud; // hide hud, 0 = show all, 1 = hide depending on prompt position (top/bottom), 2 = hide all + UINT8 lines; // # of lines to show. If name is specified, name takes one of the lines. If 0, defaults to 4. + INT32 backcolor; // see CON_SetupBackColormap: 0-11, INT32_MAX for user-defined (CONS_BACKCOLOR) + UINT8 align; // text alignment, 0 = left, 1 = right, 2 = center + UINT8 verticalalign; // vertical text alignment, 0 = top, 1 = bottom, 2 = middle + UINT8 textspeed; // text speed, delay in tics between characters. + sfxenum_t textsfx; // sfx_ id for printing text + UINT8 nextprompt; // next prompt to jump to, one-based. 0 = current prompt + UINT8 nextpage; // next page to jump to, one-based. 0 = next page within prompt->numpages + char nexttag[33]; // next tag to jump to. If set, this overrides nextprompt and nextpage. + INT32 timetonext; // time in tics to jump to next page automatically. 0 = don't jump automatically + char *text; +} textpage_t; + +typedef struct +{ + textpage_t page[MAX_PAGES]; + INT32 numpages; // Number of pages in this prompt +} textprompt_t; + +extern textprompt_t *textprompts[MAX_PROMPTS]; + // For the Custom Exit linedef. extern INT16 nextmapoverride; extern boolean skipstats; -extern UINT32 totalrings; // Total # of rings in a level +extern UINT32 ssspheres; // Total # of spheres in a level // Fun extra stuff extern INT16 lastmap; // Last level you were at (returning from special stages). @@ -239,11 +308,18 @@ typedef struct SINT8 unlockrequired; ///< Is an unlockable required to play this level? -1 if no. UINT8 levelselect; ///< Is this map available in the level select? If so, which map list is it available in? SINT8 bonustype; ///< What type of bonus does this level have? (-1 for null.) - SINT8 saveoverride; ///< Set how the game is allowed to save (1 for always, -1 for never, 0 is 2.1 default) + SINT8 maxbonuslives; ///< How many bonus lives to award at Intermission? (-1 for unlimited.) - UINT8 levelflags; ///< LF_flags: merged eight booleans into one UINT8 for space, see below + UINT8 levelflags; ///< LF_flags: merged booleans into one UINT8 for space, see below UINT8 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus + char selectheading[22]; ///< Level select heading. Allows for controllable grouping. + UINT16 startrings; ///< Number of rings players start with. + + // Freed animals stuff. + UINT8 numFlickies; ///< Internal. For freed flicky support. + mobjtype_t *flickies; ///< List of freeable flickies in this level. Allocated dynamically for space reasons. Be careful. + // NiGHTS stuff. UINT8 numGradedMares; ///< Internal. For grade support. nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful. @@ -264,17 +340,15 @@ typedef struct #define LF_NOSSMUSIC 4 ///< Disable Super Sonic music #define LF_NORELOAD 8 ///< Don't reload level on death #define LF_NOZONE 16 ///< Don't include "ZONE" on level title +#define LF_SAVEGAME 32 ///< Save the game upon loading this level +#define LF_MIXNIGHTSCOUNTDOWN 64 ///< Play sfx_timeup instead of music change for NiGHTS countdown #define LF2_HIDEINMENU 1 ///< Hide in the multiplayer menu #define LF2_HIDEINSTATS 2 ///< Hide in the statistics screen #define LF2_RECORDATTACK 4 ///< Show this map in Time Attack #define LF2_NIGHTSATTACK 8 ///< Show this map in NiGHTS mode menu #define LF2_NOVISITNEEDED 16 ///< Available in time attack/nights mode without visiting the level - -// Save override -#define SAVE_NEVER -1 -#define SAVE_DEFAULT 0 -#define SAVE_ALWAYS 1 +#define LF2_WIDEICON 32 ///< If you're in a circumstance where it fits, use a wide map icon extern mapheader_t* mapheaderinfo[NUMMAPS]; @@ -319,7 +393,7 @@ enum GameType NUMGAMETYPES }; -// If you alter this list, update dehacked.c, and Gametype_Names in g_game.c +// If you alter this list, update dehacked.c, MISC_ChangeGameTypeMenu in m_menu.c, and Gametype_Names in g_game.c // String names for gametypes extern const char *Gametype_Names[NUMGAMETYPES]; @@ -380,6 +454,7 @@ extern recorddata_t *mainrecords[NUMMAPS]; #define MV_ULTIMATE 8 #define MV_PERFECT 16 #define MV_MAX 31 // used in gamedata check +#define MV_MP 128 extern UINT8 mapvisited[NUMMAPS]; // Temporary holding place for nights data for the current map @@ -387,6 +462,7 @@ nightsdata_t ntemprecords; extern UINT32 token; ///< Number of tokens collected in a level extern UINT32 tokenlist; ///< List of tokens collected +extern boolean gottoken; ///< Did you get a token? Used for end of act extern INT32 tokenbits; ///< Used for setting token bits extern INT32 sstimer; ///< Time allotted in the special stage extern UINT32 bluescore; ///< Blue Team Scores @@ -408,6 +484,7 @@ extern UINT16 tailsflytics; extern UINT16 underwatertics; extern UINT16 spacetimetics; extern UINT16 extralifetics; +extern UINT16 nightslinktics; extern UINT8 introtoplay; extern UINT8 creditscutscene; @@ -480,6 +557,8 @@ extern boolean precache; // wipegamestate can be set to -1 // to force a wipe on the next draw extern gamestate_t wipegamestate; +extern INT16 wipetypepre; +extern INT16 wipetypepost; // debug flag to cancel adaptiveness extern boolean singletics; @@ -491,6 +570,8 @@ extern boolean singletics; #include "d_clisrv.h" extern consvar_t cv_timetic; // display high resolution timer +extern consvar_t cv_powerupdisplay; // display powerups +extern consvar_t cv_showinputjoy; // display joystick in time attack extern consvar_t cv_forceskin; // force clients to use the server's skin extern consvar_t cv_downloading; // allow clients to downloading WADs. extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS]; diff --git a/src/doomtype.h b/src/doomtype.h index dd4268cdfc4c891cd1ddc8b3e0ed50cb154cb9a4..5f60e21b51cc6aec62c1a3427a897c47d649816d 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -17,18 +17,20 @@ #ifndef __DOOMTYPE__ #define __DOOMTYPE__ -#if (defined (_WIN32) && !defined (_XBOX)) || (defined (_WIN32_WCE) && !defined (__GNUC__)) +#ifdef _WIN32 //#define WIN32_LEAN_AND_MEAN #define RPC_NO_WINDOWS_H #include <windows.h> #endif -#ifdef _NDS -#include <nds.h> -#endif - /* 7.18.1.1 Exact-width integer types */ #ifdef _MSC_VER +// libopenmpt.h will include stdint.h later; +// include it now so that INT8_MAX etc. don't get redefined +#ifdef HAVE_OPENMPT +#include <stdint.h> +#endif + #define UINT8 unsigned __int8 #define SINT8 signed __int8 @@ -52,19 +54,6 @@ typedef long ssize_t; #define PDWORD_PTR PDWORD #endif #endif -#elif defined (_arch_dreamcast) // KOS Dreamcast -#include <arch/types.h> - -#define UINT8 unsigned char -#define SINT8 signed char - -#define UINT16 uint16 -#define INT16 int16 - -#define INT32 int -#define UINT32 unsigned int -#define INT64 int64 -#define UINT64 uint64 #elif defined (__DJGPP__) #define UINT8 unsigned char #define SINT8 signed char @@ -100,15 +89,13 @@ typedef long ssize_t; /* Strings and some misc platform specific stuff */ -#if defined (_MSC_VER) || defined (__OS2__) - // Microsoft VisualC++ #ifdef _MSC_VER + // Microsoft VisualC++ #if (_MSC_VER <= 1800) // MSVC 2013 and back #define snprintf _snprintf #if (_MSC_VER <= 1200) // MSVC 6.0 and back #define vsnprintf _vsnprintf #endif -#endif #endif #define strncasecmp strnicmp #define strcasecmp stricmp @@ -121,23 +108,12 @@ typedef long ssize_t; #define strncasecmp strnicmp #define strcasecmp strcmpi #endif -#ifdef _PSP - #include <malloc.h> -#elif (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) +#if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) #undef stricmp #define stricmp(x,y) strcasecmp(x,y) #undef strnicmp #define strnicmp(x,y,n) strncasecmp(x,y,n) #endif -#ifdef _WIN32_WCE -#ifndef __GNUC__ - #define stricmp(x,y) _stricmp(x,y) - #define strnicmp _strnicmp -#endif - #define strdup _strdup - #define strupr _strupr - #define strlwr _strlwr -#endif #if defined (macintosh) //|| defined (__APPLE__) //skip all boolean/Boolean crap #define true 1 @@ -157,7 +133,7 @@ typedef long ssize_t; #endif #endif //macintosh -#if defined (PC_DOS) || defined (_WIN32) || defined (_WII) || defined (_PSP) || defined (_arch_dreamcast) || defined (__HAIKU__) || defined(_NDS) || defined(_PS3) +#if defined (PC_DOS) || defined (_WIN32) || defined (__HAIKU__) #define HAVE_DOSSTR_FUNCS #endif @@ -191,21 +167,17 @@ size_t strlcpy(char *dst, const char *src, size_t siz); //faB: clean that up !! #if defined( _MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013 and forward #include "stdbool.h" - #elif (defined (_WIN32) || (defined (_WIN32_WCE) && !defined (__GNUC__))) && !defined (_XBOX) + #elif defined (_WIN32) #define false FALSE // use windows types #define true TRUE #define boolean BOOL - #elif defined(_NDS) - #define boolean bool - #elif defined(_PS3) // defined(__GNUC__)? - #include <stdbool.h> //_bool_true_false_are_defined? - #define boolean bool #else typedef enum {false, true} boolean; #endif #endif // __BYTEBOOL__ /* 7.18.2.1 Limits of exact-width integer types */ + #ifndef INT8_MIN #define INT8_MIN (-128) #endif @@ -298,12 +270,6 @@ size_t strlcpy(char *dst, const char *src, size_t siz); #endif #define ATTRUNUSED __attribute__((unused)) - - // Xbox-only macros - #ifdef _XBOX - #define FILESTAMP I_OutputMsg("%s:%d\n",__FILE__,__LINE__); - #define XBOXSTATIC static - #endif #elif defined (_MSC_VER) #define ATTRNORETURN __declspec(noreturn) #define ATTRINLINE __forceinline @@ -357,12 +323,6 @@ size_t strlcpy(char *dst, const char *src, size_t siz); #ifndef ATTRNOINLINE #define ATTRNOINLINE #endif -#ifndef XBOXSTATIC -#define XBOXSTATIC -#endif -#ifndef FILESTAMP -#define FILESTAMP -#endif /* Miscellaneous types that don't fit anywhere else (Can this be changed?) */ diff --git a/src/f_finale.c b/src/f_finale.c index 63221fc23bc6237d0ab71522aef575297736264f..a0fa3658a3c9d9d926cd7b6cd22ba7903c883c74 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -29,18 +29,30 @@ #include "g_input.h" #include "console.h" #include "m_random.h" +#include "m_misc.h" // moviemode functionality #include "y_inter.h" #include "m_cond.h" +#include "p_local.h" +#include "p_setup.h" +#include "st_stuff.h" // hud hiding +#include "fastcmp.h" + +#ifdef HAVE_BLUA +#include "lua_hud.h" +#endif // Stage of animation: // 0 = text, 1 = art screen static INT32 finalecount; -INT32 titlescrollspeed = 80; +INT32 titlescrollxspeed = 80; +INT32 titlescrollyspeed = 0; +UINT8 titlemapinaction = TITLEMAP_OFF; static INT32 timetonext; // Delay between screen changes static INT32 continuetime; // Short delay when continuing static tic_t animtimer; // Used for some animation timings +static INT16 skullAnimCounter; // Prompts: Chevron animation static INT32 roidtics; // Asteroid spinning static INT32 deplete; @@ -49,6 +61,20 @@ static tic_t stoptimer; static boolean keypressed = false; // (no longer) De-Demo'd Title Screen +static tic_t xscrolltimer; +static tic_t yscrolltimer; +static INT32 menuanimtimer; // Title screen: background animation timing +mobj_t *titlemapcameraref = NULL; + +// menu presentation state +char curbgname[8]; +SINT8 curfadevalue; +boolean curhidepics; +INT32 curbgcolor; +INT32 curbgxspeed; +INT32 curbgyspeed; +boolean curbghide; + static UINT8 curDemo = 0; static UINT32 demoDelayLeft; static UINT32 demoIdleLeft; @@ -69,7 +95,17 @@ static patch_t *ttspop5; static patch_t *ttspop6; static patch_t *ttspop7; -static void F_SkyScroll(INT32 scrollspeed); +// +// PROMPT STATE +// +static boolean promptactive = false; +static mobj_t *promptmo; +static INT16 promptpostexectag; +static boolean promptblockcontrols; +static char *promptpagetext = NULL; +static INT32 callpromptnum = INT32_MAX; +static INT32 callpagenum = INT32_MAX; +static INT32 callplayer = INT32_MAX; // // CUTSCENE TEXT WRITING @@ -159,99 +195,6 @@ static void F_NewCutscene(const char *basetext) cutscene_textcount = TICRATE/2; } -// -// F_DrawPatchCol -// -static void F_DrawPatchCol(INT32 x, patch_t *patch, INT32 col) -{ - const column_t *column; - const UINT8 *source; - UINT8 *desttop, *dest = NULL; - const UINT8 *deststop, *destbottom; - size_t count; - - desttop = screens[0] + x*vid.dupx; - deststop = screens[0] + vid.rowbytes * vid.height; - destbottom = desttop + vid.height*vid.width; - - do { - INT32 topdelta, prevdelta = -1; - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[col])); - - // step through the posts in a column - while (column->topdelta != 0xff) - { - topdelta = column->topdelta; - if (topdelta <= prevdelta) - topdelta += prevdelta; - prevdelta = topdelta; - source = (const UINT8 *)column + 3; - dest = desttop + topdelta*vid.width; - count = column->length; - - while (count--) - { - INT32 dupycount = vid.dupy; - - while (dupycount-- && dest < destbottom) - { - INT32 dupxcount = vid.dupx; - while (dupxcount-- && dest <= deststop) - *dest++ = *source; - - dest += (vid.width - vid.dupx); - } - source++; - } - column = (const column_t *)((const UINT8 *)column + column->length + 4); - } - - desttop += SHORT(patch->height)*vid.dupy*vid.width; - } while(dest < destbottom); -} - -// -// F_SkyScroll -// -static void F_SkyScroll(INT32 scrollspeed) -{ - INT32 scrolled, x, mx, fakedwidth; - patch_t *pat; - - pat = W_CachePatchName("TITLESKY", PU_CACHE); - - animtimer = ((finalecount*scrollspeed)/16) % SHORT(pat->width); - - fakedwidth = vid.width / vid.dupx; - - if (rendermode == render_soft) - { // if only hardware rendering could be this elegant and complete - scrolled = (SHORT(pat->width) - animtimer) - 1; - for (x = 0, mx = scrolled; x < fakedwidth; x++, mx = (mx+1)%SHORT(pat->width)) - F_DrawPatchCol(x, pat, mx); - } -#ifdef HWRENDER - else if (rendermode != render_none) - { // if only software rendering could be this simple and retarded - INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); - INT32 y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz; - scrolled = animtimer * dupz; - for (x = 0; x < vid.width; x += pw) - { - for (y = 0; y < vid.height; y += ph) - { - if (scrolled > 0) - V_DrawScaledPatch(scrolled - pw, y, V_NOSCALESTART, pat); - - V_DrawScaledPatch(x + scrolled, y, V_NOSCALESTART, pat); - } - } - } -#endif - - W_UnlockCachedPatch(pat); -} - // ============= // INTRO SCENE // ============= @@ -286,6 +229,8 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset void F_StartIntro(void) { + S_StopMusic(); + if (introtoplay) { if (!cutscenes[introtoplay - 1]) @@ -305,7 +250,7 @@ void F_StartIntro(void) introtext[2] = M_GetText( "As it was about to drain the rings\n" "away from the planet, Sonic burst into\n" - "the Satellite and for what he thought\n" + "the control room and for what he thought\n" "would be the last time,\xB4 defeated\n" "Dr. Eggman.\n#"); @@ -315,11 +260,11 @@ void F_StartIntro(void) "return,\xB8 bringing an all new threat.\n#"); introtext[4] = M_GetText( - "\xA8""About once every year, a strange asteroid\n" + "\xA8""About every five years, a strange asteroid\n" "hovers around the planet.\xBF It suddenly\n" "appears from nowhere, circles around, and\n" "\xB6- just as mysteriously as it arrives -\xB6\n" - "vanishes after about two months.\xBF\n" + "vanishes after only one week.\xBF\n" "No one knows why it appears, or how.\n#"); introtext[5] = M_GetText( @@ -331,11 +276,11 @@ void F_StartIntro(void) "the screen, and just shrugged it off.\n#"); introtext[6] = M_GetText( - "It was only later\n" + "It was hours later\n" "that he had an\n" "idea. \xBF\xA7\"The Black\n" - "Rock usually has a\n" - "lot of energy\n" + "Rock has a large\n" + "amount of energy\n" "within it\xAC...\xA7\xBF\n" "If I can somehow\n" "harness this,\xB8 I\n" @@ -353,37 +298,37 @@ void F_StartIntro(void) "a reunion party...\n#"); introtext[8] = M_GetText( - "\xA5\"We're\xB6 ready\xB6 to\xB4 fire\xB6 in\xB6 15\xB6 seconds!\"\xA8\xB8\n" - "The robot said, his voice crackling a\n" - "little down the com-link. \xBF\xA7\"Good!\"\xA8\xB8\n" - "Eggman sat back in his Egg-Mobile and\n" + "\xA5\"PRE-""\xB6""PARING-""\xB6""TO-""\xB4""FIRE-\xB6IN-""\xB6""15-""\xB6""SECONDS!\"\xA8\xB8\n" + "his targeting system crackled\n" + "robotically down the com-link. \xBF\xA7\"Good!\"\xA8\xB8\n" + "Eggman sat back in his eggmobile and\n" "began to count down as he saw the\n" - "GreenFlower city on the main monitor.\n#"); + "Greenflower mountain on the monitor.\n#"); introtext[9] = M_GetText( "\xA5\"10...\xD2""9...\xD2""8...\"\xA8\xD2\n" "Meanwhile, Sonic was tearing across the\n" "zones. Everything became a blur as he\n" - "ran around loops, skimmed over water,\n" + "ran up slopes, skimmed over water,\n" "and catapulted himself off rocks with\n" "his phenomenal speed.\n#"); introtext[10] = M_GetText( "\xA5\"6...\xD2""5...\xD2""4...\"\xA8\xD2\n" "Sonic knew he was getting closer to the\n" - "City, and pushed himself harder.\xB4 Finally,\n" - "the city appeared in the horizon.\xD2\xD2\n" + "zone, and pushed himself harder.\xB4 Finally,\n" + "the mountain appeared on the horizon.\xD2\xD2\n" "\xA5\"3...\xD2""2...\xD2""1...\xD2""Zero.\"\n#"); introtext[11] = M_GetText( - "GreenFlower City was gone.\xC4\n" + "Greenflower Mountain was no more.\xC4\n" "Sonic arrived just in time to see what\n" "little of the 'ruins' were left.\n" - "Everyone and everything in the city\n" + "The natural beauty of the zone\n" "had been obliterated.\n#"); introtext[12] = M_GetText( - "\xA7\"You're not quite as dead as we thought,\n" + "\xA7\"You're not quite as gone as we thought,\n" "huh?\xBF Are you going to tell us your plan as\n" "usual or will I \xA8\xB4'have to work it out'\xA7 or\n" "something?\"\xD2\xD2\n" @@ -397,8 +342,8 @@ void F_StartIntro(void) "leaving Sonic\n" "and Tails behind.\xB6\n" "Tails looked at\n" - "the ruins of the\n" - "Greenflower City\n" + "the once-perfect\n" + "mountainside\n" "with a grim face\n" "and sighed.\xC6\n" "\xA7\"Now\xB6 what do we\n" @@ -447,7 +392,7 @@ void F_StartIntro(void) F_NewCutscene(introtext[0]); intro_scenenum = 0; - finalecount = animtimer = stoptimer = 0; + finalecount = animtimer = skullAnimCounter = stoptimer = 0; roidtics = BASEVIDWIDTH - 64; timetonext = introscenetime[intro_scenenum]; } @@ -565,7 +510,7 @@ static void F_IntroDrawScene(void) if (finalecount < 4) S_StopMusic(); if (finalecount == 4) - S_ChangeMusicInternal("stjr", false); + S_ChangeMusicInternal("_stjr", false); x = (BASEVIDWIDTH<<FRACBITS)/2 - FixedMul(334<<FRACBITS, aspect)/2; y = (BASEVIDHEIGHT<<FRACBITS)/2 - FixedMul(358<<FRACBITS, aspect)/2; V_DrawSciencePatch(x, y, 0, (patch = W_CachePatchName("WAHH1", PU_CACHE)), aspect); @@ -679,7 +624,7 @@ static void F_IntroDrawScene(void) } else { - F_SkyScroll(80*4); + F_SkyScroll(80*4, 0, "TITLESKY"); if (timetonext == 6) { stoptimer = finalecount; @@ -777,7 +722,7 @@ void F_IntroDrawer(void) F_RunWipe(99,true); } - S_ChangeMusicInternal("read_m", false); + S_ChangeMusicInternal("_intro", false); } else if (intro_scenenum == 3) roidtics = BASEVIDWIDTH - 64; @@ -804,18 +749,27 @@ void F_IntroDrawer(void) // Stay on black for a bit. =) { - tic_t quittime; - quittime = I_GetTime() + NEWTICRATE*2; // Shortened the quit time, used to be 2 seconds - while (quittime > I_GetTime()) + tic_t nowtime, quittime, lasttime; + nowtime = lasttime = I_GetTime(); + quittime = nowtime + NEWTICRATE*2; // Shortened the quit time, used to be 2 seconds + while (quittime > nowtime) { + while (!((nowtime = I_GetTime()) - lasttime)) + I_Sleep(); + lasttime = nowtime; + I_OsPolling(); I_UpdateNoBlit(); M_Drawer(); // menu is drawn even on top of wipes I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001 + + if (moviemode) // make sure we save frames for the white hold too + M_SaveFrame(); } } D_StartTitle(); + wipegamestate = GS_INTRO; return; } F_NewCutscene(introtext[++intro_scenenum]); @@ -1017,6 +971,7 @@ static const char *credits[] = { "Jim \"MotorRoach\" DeMello", "Desmond \"Blade\" DesJardins", "Sherman \"CoatRack\" DesJardins", + "Vivian \"toaster\" Grannell", "Andrew \"Senku Niola\" Moran", "David \"Instant Sonic\" Spencer Jr.", "\"SSNTails\"", @@ -1051,6 +1006,7 @@ static const char *credits[] = { "Sherman \"CoatRack\" DesJardins", "Ben \"Mystic\" Geyer", "Nathan \"Jazz\" Giroux", + "Vivian \"toaster\" Grannell", "Dan \"Blitzzo\" Hagerstrand", "Kepa \"Nev3r\" Iceta", "Thomas \"Shadow Hog\" Igoe", @@ -1133,7 +1089,7 @@ void F_StartCredits(void) M_ClearMenus(true); // Save the second we enter the credits - if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot >= 0) + if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0) G_SaveGame((UINT32)cursaveslot); if (creditscutscene) @@ -1147,7 +1103,7 @@ void F_StartCredits(void) CON_ToggleOff(); S_StopMusic(); - S_ChangeMusicInternal("credit", false); + S_ChangeMusicInternal("_creds", false); finalecount = 0; animtimer = 0; @@ -1166,7 +1122,7 @@ void F_CreditDrawer(void) V_DrawSciencePatch(credits_pics[i].x<<FRACBITS, (credits_pics[i].y<<FRACBITS) - 4*(animtimer<<FRACBITS)/5, 0, W_CachePatchName(credits_pics[i].patch, PU_CACHE), FRACUNIT>>1); // Dim the background - V_DrawFadeScreen(); + V_DrawFadeScreen(0xFF00, 16); // Draw credits text on top for (i = 0; credits[i]; i++) @@ -1291,7 +1247,7 @@ static boolean drawemblem = false, drawchaosemblem = false; void F_StartGameEvaluation(void) { // Credits option in secrets menu - if (cursaveslot == -2) + if (cursaveslot == -1) { F_StartGameEnd(); return; @@ -1305,7 +1261,7 @@ void F_StartGameEvaluation(void) // Save the second we enter the evaluation // We need to do this again! Remember, it's possible a mod designed skipped // the credits sequence! - if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot >= 0) + if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0) G_SaveGame((UINT32)cursaveslot); gameaction = ga_nothing; @@ -1364,7 +1320,7 @@ void F_GameEvaluationDrawer(void) ++timesBeatenUltimate; if (M_UpdateUnlockablesAndExtraEmblems()) - S_StartSound(NULL, sfx_ncitem); + S_StartSound(NULL, sfx_s3k68); G_SaveGameData(); } @@ -1451,20 +1407,172 @@ void F_GameEndTicker(void) // ============== // TITLE SCREEN // ============== + +void F_InitMenuPresValues(void) +{ + menuanimtimer = 0; + prevMenuId = 0; + activeMenuId = MainDef.menuid; + + // Set defaults for presentation values + strncpy(curbgname, "TITLESKY", 8); + curfadevalue = 16; + curhidepics = hidetitlepics; + curbgcolor = -1; + curbgxspeed = titlescrollxspeed; + curbgyspeed = titlescrollyspeed; + curbghide = true; + + // Find current presentation values + M_SetMenuCurBackground((gamestate == GS_TIMEATTACK) ? "SRB2BACK" : "TITLESKY"); + M_SetMenuCurFadeValue(16); + M_SetMenuCurHideTitlePics(); +} + +// +// F_SkyScroll +// +void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname) +{ + INT32 xscrolled, x, xneg = (scrollxspeed > 0) - (scrollxspeed < 0), tilex; + INT32 yscrolled, y, yneg = (scrollyspeed > 0) - (scrollyspeed < 0), tiley; + boolean xispos = (scrollxspeed >= 0), yispos = (scrollyspeed >= 0); + INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); + INT16 patwidth, patheight; + INT32 pw, ph; // scaled by dupz + patch_t *pat; + INT32 i, j; + + if (rendermode == render_none) + return; + + if (!patchname || !patchname[0]) + { + V_DrawFill(0, 0, vid.width, vid.height, 31); + return; + } + + if (!scrollxspeed && !scrollyspeed) + { + V_DrawPatchFill(W_CachePatchName(patchname, PU_CACHE)); + return; + } + + pat = W_CachePatchName(patchname, PU_CACHE); + + patwidth = SHORT(pat->width); + patheight = SHORT(pat->height); + pw = patwidth * dupz; + ph = patheight * dupz; + + tilex = max(FixedCeil(FixedDiv(vid.width, pw)) >> FRACBITS, 1)+2; // one tile on both sides of center + tiley = max(FixedCeil(FixedDiv(vid.height, ph)) >> FRACBITS, 1)+2; + + xscrolltimer = ((menuanimtimer*scrollxspeed)/16 + patwidth*xneg) % (patwidth); + yscrolltimer = ((menuanimtimer*scrollyspeed)/16 + patheight*yneg) % (patheight); + + // coordinate offsets + xscrolled = xscrolltimer * dupz; + yscrolled = yscrolltimer * dupz; + + for (x = (xispos) ? -pw*(tilex-1)+pw : 0, i = 0; + i < tilex; + x += pw, i++) + { + for (y = (yispos) ? -ph*(tiley-1)+ph : 0, j = 0; + j < tiley; + y += ph, j++) + { + V_DrawScaledPatch( + (xispos) ? xscrolled - x : x + xscrolled, + (yispos) ? yscrolled - y : y + yscrolled, + V_NOSCALESTART, pat); + } + } + + W_UnlockCachedPatch(pat); +} + void F_StartTitleScreen(void) { + if (menupres[MN_MAIN].musname[0]) + S_ChangeMusic(menupres[MN_MAIN].musname, menupres[MN_MAIN].mustrack, menupres[MN_MAIN].muslooping); + else + S_ChangeMusicInternal("_title", looptitle); + if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS) + { finalecount = 0; + wipetypepost = menupres[MN_MAIN].enterwipe; + } else wipegamestate = GS_TITLESCREEN; + + if (titlemap) + { + mapthing_t *startpos; + + gamestate_t prevwipegamestate = wipegamestate; + titlemapinaction = TITLEMAP_LOADING; + titlemapcameraref = NULL; + gamemap = titlemap; + + if (!mapheaderinfo[gamemap-1]) + P_AllocMapHeader(gamemap-1); + + maptol = mapheaderinfo[gamemap-1]->typeoflevel; + globalweather = mapheaderinfo[gamemap-1]->weather; + + G_DoLoadLevel(true); + if (!titlemap) + return; + + players[displayplayer].playerstate = PST_DEAD; // Don't spawn the player in dummy (I'm still a filthy cheater) + + // Set Default Position + if (playerstarts[0]) + startpos = playerstarts[0]; + else if (deathmatchstarts[0]) + startpos = deathmatchstarts[0]; + else + startpos = NULL; + + if (startpos) + { + camera.x = startpos->x << FRACBITS; + camera.y = startpos->y << FRACBITS; + camera.subsector = R_PointInSubsector(camera.x, camera.y); + camera.z = camera.subsector->sector->floorheight + ((startpos->options >> ZSHIFT) << FRACBITS); + camera.angle = (startpos->angle % 360)*ANG1; + camera.aiming = 0; + } + else + { + camera.x = camera.y = camera.z = camera.angle = camera.aiming = 0; + camera.subsector = NULL; // toast is filthy too + } + + camera.chase = true; + camera.height = 0; + + // Run enter linedef exec for MN_MAIN, since this is where we start + if (menupres[MN_MAIN].entertag) + P_LinedefExecute(menupres[MN_MAIN].entertag, players[displayplayer].mo, NULL); + + wipegamestate = prevwipegamestate; + } + else + { + titlemapinaction = TITLEMAP_OFF; + gamemap = 1; // g_game.c + CON_ClearHUD(); + } + G_SetGamestate(GS_TITLESCREEN); - CON_ClearHUD(); // IWAD dependent stuff. - S_ChangeMusicInternal("titles", looptitle); - - animtimer = 0; + animtimer = skullAnimCounter = 0; demoDelayLeft = demoDelayTime; demoIdleLeft = demoIdleTime; @@ -1489,16 +1597,30 @@ void F_StartTitleScreen(void) // (no longer) De-Demo'd Title Screen void F_TitleScreenDrawer(void) { + boolean hidepics; + if (modeattacking) return; // We likely came here from retrying. Don't do a damn thing. // Draw that sky! - F_SkyScroll(titlescrollspeed); + if (curbgcolor >= 0) + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); + else if (!curbghide || !titlemapinaction || gamestate == GS_WAITINGPLAYERS) + F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); - // Don't draw outside of the title screewn, or if the patch isn't there. + // Don't draw outside of the title screen, or if the patch isn't there. if (!ttwing || (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS)) return; + // rei|miru: use title pics? + hidepics = curhidepics; + if (hidepics) +#ifdef HAVE_BLUA + goto luahook; +#else + return; +#endif + V_DrawScaledPatch(30, 14, 0, ttwing); if (finalecount < 57) @@ -1535,6 +1657,19 @@ void F_TitleScreenDrawer(void) } V_DrawScaledPatch(48, 142, 0,ttbanner); + +#ifdef HAVE_BLUA +luahook: + LUAh_TitleHUD(); +#endif +} + +// separate animation timer for backgrounds, since we also count +// during GS_TIMEATTACK +void F_MenuPresTicker(boolean run) +{ + if (run) + menuanimtimer++; } // (no longer) De-Demo'd Title Screen @@ -1547,6 +1682,52 @@ void F_TitleScreenTicker(boolean run) if (gameaction != ga_nothing || gamestate != GS_TITLESCREEN) return; + // Execute the titlemap camera settings + if (titlemapinaction) + { + thinker_t *th; + mobj_t *mo2; + mobj_t *cameraref = NULL; + + // If there's a Line 422 Switch Cut-Away view, don't force us. + if (!titlemapcameraref || titlemapcameraref->type != MT_ALTVIEWMAN) + { + for (th = thinkercap.next; th != &thinkercap; th = th->next) + { + if (th->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker + continue; + + mo2 = (mobj_t *)th; + + if (!mo2) + continue; + + if (mo2->type != MT_ALTVIEWMAN) + continue; + + cameraref = titlemapcameraref = mo2; + break; + } + } + else + cameraref = titlemapcameraref; + + if (cameraref) + { + camera.x = cameraref->x; + camera.y = cameraref->y; + camera.z = cameraref->z; + camera.angle = cameraref->angle; + camera.aiming = cameraref->cusval; + camera.subsector = cameraref->subsector; + } + else + { + // Default behavior: Do a lil' camera spin if a title map is loaded; + camera.angle += titlescrollxspeed*ANG1/64; + } + } + // no demos to play? or, are they disabled? if (!cv_rollingdemos.value || !numDemos) return; @@ -1626,7 +1807,7 @@ void F_StartContinue(void) // In case menus are still up?!! M_ClearMenus(true); - S_ChangeMusicInternal("contsc", false); + S_ChangeMusicInternal("_conti", false); S_StopSounds(); timetonext = TICRATE*11; @@ -1718,7 +1899,7 @@ boolean F_ContinueResponder(event_t *event) // CUSTOM CUTSCENES // ================== static INT32 scenenum, cutnum; -static INT32 picxpos, picypos, picnum, pictime; +static INT32 picxpos, picypos, picnum, pictime, picmode, numpics, pictoloop; static INT32 textxpos, textypos; static boolean dofadenow = false, cutsceneover = false; static boolean runningprecutscene = false, precutresetplayer = false; @@ -1787,6 +1968,9 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset G_SetGamestate(GS_CUTSCENE); + if (wipegamestate == GS_CUTSCENE) + wipegamestate = -1; + gameaction = ga_nothing; paused = false; CON_ToggleOff(); @@ -1925,3 +2109,617 @@ boolean F_CutsceneResponder(event_t *event) return false; } + +// ================== +// TEXT PROMPTS +// ================== + +static void F_GetPageTextGeometry(UINT8 *pagelines, boolean *rightside, INT32 *boxh, INT32 *texth, INT32 *texty, INT32 *namey, INT32 *chevrony, INT32 *textx, INT32 *textr) +{ + // reuse: + // cutnum -> promptnum + // scenenum -> pagenum + lumpnum_t iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname); + + *pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4; + *rightside = (iconlump != LUMPERROR && textprompts[cutnum]->page[scenenum].rightside); + + // Vertical calculations + *boxh = *pagelines*2; + *texth = textprompts[cutnum]->page[scenenum].name[0] ? (*pagelines-1)*2 : *pagelines*2; // name takes up first line if it exists + *texty = BASEVIDHEIGHT - ((*texth * 4) + (*texth/2)*4); + *namey = BASEVIDHEIGHT - ((*boxh * 4) + (*boxh/2)*4); + *chevrony = BASEVIDHEIGHT - (((1*2) * 4) + ((1*2)/2)*4); // force on last line + + // Horizontal calculations + // Shift text to the right if we have a character icon on the left side + // Add 4 margin against icon + *textx = (iconlump != LUMPERROR && !*rightside) ? ((*boxh * 4) + (*boxh/2)*4) + 4 : 4; + *textr = *rightside ? BASEVIDWIDTH - (((*boxh * 4) + (*boxh/2)*4) + 4) : BASEVIDWIDTH-4; +} + +static fixed_t F_GetPromptHideHudBound(void) +{ + UINT8 pagelines; + boolean rightside; + INT32 boxh, texth, texty, namey, chevrony; + INT32 textx, textr; + + if (cutnum == INT32_MAX || scenenum == INT32_MAX || !textprompts[cutnum] || scenenum >= textprompts[cutnum]->numpages || + !textprompts[cutnum]->page[scenenum].hidehud || + (splitscreen && textprompts[cutnum]->page[scenenum].hidehud != 2)) // don't hide on splitscreen, unless hide all is forced + return 0; + else if (textprompts[cutnum]->page[scenenum].hidehud == 2) // hide all + return BASEVIDHEIGHT; + + F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr); + + // calc boxheight (see V_DrawPromptBack) + boxh *= vid.dupy; + boxh = (boxh * 4) + (boxh/2)*5; // 4 lines of space plus gaps between and some leeway + + // return a coordinate to check + // if negative: don't show hud elements below this coordinate (visually) + // if positive: don't show hud elements above this coordinate (visually) + return 0 - boxh; // \todo: if prompt at top of screen (someday), make this return positive +} + +boolean F_GetPromptHideHudAll(void) +{ + if (cutnum == INT32_MAX || scenenum == INT32_MAX || !textprompts[cutnum] || scenenum >= textprompts[cutnum]->numpages || + !textprompts[cutnum]->page[scenenum].hidehud || + (splitscreen && textprompts[cutnum]->page[scenenum].hidehud != 2)) // don't hide on splitscreen, unless hide all is forced + return false; + else if (textprompts[cutnum]->page[scenenum].hidehud == 2) // hide all + return true; + else + return false; +} + +boolean F_GetPromptHideHud(fixed_t y) +{ + INT32 ybound; + boolean fromtop; + fixed_t ytest; + + if (!promptactive) + return false; + + ybound = F_GetPromptHideHudBound(); + fromtop = (ybound >= 0); + ytest = (fromtop ? ybound : BASEVIDHEIGHT + ybound); + + return (fromtop ? y < ytest : y >= ytest); // true means hide +} + +static void F_PreparePageText(char *pagetext) +{ + UINT8 pagelines; + boolean rightside; + INT32 boxh, texth, texty, namey, chevrony; + INT32 textx, textr; + + F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr); + + if (promptpagetext) + Z_Free(promptpagetext); + promptpagetext = (pagetext && pagetext[0]) ? V_WordWrap(textx, textr, 0, pagetext) : Z_StrDup(""); + + F_NewCutscene(promptpagetext); + cutscene_textspeed = textprompts[cutnum]->page[scenenum].textspeed ? textprompts[cutnum]->page[scenenum].textspeed : TICRATE/5; + cutscene_textcount = 0; // no delay in beginning + cutscene_boostspeed = 0; // don't print 8 characters to start + + // \todo update control hot strings on re-config + // and somehow don't reset cutscene text counters +} + +static void F_AdvanceToNextPage(void) +{ + INT32 nextprompt = textprompts[cutnum]->page[scenenum].nextprompt ? textprompts[cutnum]->page[scenenum].nextprompt - 1 : INT32_MAX, + nextpage = textprompts[cutnum]->page[scenenum].nextpage ? textprompts[cutnum]->page[scenenum].nextpage - 1 : INT32_MAX, + oldcutnum = cutnum; + + if (textprompts[cutnum]->page[scenenum].nexttag[0]) + F_GetPromptPageByNamedTag(textprompts[cutnum]->page[scenenum].nexttag, &nextprompt, &nextpage); + + // determine next prompt + if (nextprompt != INT32_MAX) + { + if (nextprompt <= MAX_PROMPTS && textprompts[nextprompt]) + cutnum = nextprompt; + else + cutnum = INT32_MAX; + } + + // determine next page + if (nextpage != INT32_MAX) + { + if (cutnum != INT32_MAX) + { + scenenum = nextpage; + if (scenenum >= MAX_PAGES || scenenum > textprompts[cutnum]->numpages-1) + scenenum = INT32_MAX; + } + } + else + { + if (cutnum != oldcutnum) + scenenum = 0; + else if (scenenum + 1 < MAX_PAGES && scenenum < textprompts[cutnum]->numpages-1) + scenenum++; + else + scenenum = INT32_MAX; + } + + // close the prompt if either num is invalid + if (cutnum == INT32_MAX || scenenum == INT32_MAX) + F_EndTextPrompt(false, false); + else + { + // on page mode, number of tics before allowing boost + // on timer mode, number of tics until page advances + timetonext = textprompts[cutnum]->page[scenenum].timetonext ? textprompts[cutnum]->page[scenenum].timetonext : TICRATE/10; + F_PreparePageText(textprompts[cutnum]->page[scenenum].text); + + // gfx + picnum = textprompts[cutnum]->page[scenenum].pictostart; + numpics = textprompts[cutnum]->page[scenenum].numpics; + picmode = textprompts[cutnum]->page[scenenum].picmode; + pictoloop = textprompts[cutnum]->page[scenenum].pictoloop > 0 ? textprompts[cutnum]->page[scenenum].pictoloop - 1 : 0; + picxpos = textprompts[cutnum]->page[scenenum].xcoord[picnum]; + picypos = textprompts[cutnum]->page[scenenum].ycoord[picnum]; + animtimer = pictime = textprompts[cutnum]->page[scenenum].picduration[picnum]; + + // music change + if (textprompts[cutnum]->page[scenenum].musswitch[0]) + S_ChangeMusic(textprompts[cutnum]->page[scenenum].musswitch, + textprompts[cutnum]->page[scenenum].musswitchflags, + textprompts[cutnum]->page[scenenum].musicloop); + } +} + +void F_EndTextPrompt(boolean forceexec, boolean noexec) +{ + boolean promptwasactive = promptactive; + promptactive = false; + callpromptnum = callpagenum = callplayer = INT32_MAX; + + if (promptwasactive) + { + if (promptmo && promptmo->player && promptblockcontrols) + promptmo->reactiontime = TICRATE/4; // prevent jumping right away // \todo account freeze realtime for this) + // \todo reset frozen realtime? + } + + // \todo net safety, maybe loop all player thinkers? + if ((promptwasactive || forceexec) && !noexec && promptpostexectag) + { + if (tmthing) // edge case where starting an invalid prompt immediately on level load will make P_MapStart fail + P_LinedefExecute(promptpostexectag, promptmo, NULL); + else + { + P_MapStart(); + P_LinedefExecute(promptpostexectag, promptmo, NULL); + P_MapEnd(); + } + } +} + +void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postexectag, boolean blockcontrols, boolean freezerealtime) +{ + INT32 i; + + // if splitscreen and we already have a prompt active, ignore. + // \todo Proper per-player splitscreen support (individual prompts) + if (promptactive && splitscreen && promptnum == callpromptnum && pagenum == callpagenum) + return; + + // \todo proper netgame support + if (netgame) + { + F_EndTextPrompt(true, false); // run the post-effects immediately + return; + } + + // We share vars, so no starting text prompts over cutscenes or title screens! + keypressed = false; + finalecount = 0; + timetonext = 0; + animtimer = 0; + stoptimer = 0; + skullAnimCounter = 0; + + // Set up state + promptmo = mo; + promptpostexectag = postexectag; + promptblockcontrols = blockcontrols; + (void)freezerealtime; // \todo freeze player->realtime, maybe this needs to cycle through player thinkers + + // Initialize current prompt and scene + callpromptnum = promptnum; + callpagenum = pagenum; + cutnum = (promptnum < MAX_PROMPTS && textprompts[promptnum]) ? promptnum : INT32_MAX; + scenenum = (cutnum != INT32_MAX && pagenum < MAX_PAGES && pagenum <= textprompts[cutnum]->numpages-1) ? pagenum : INT32_MAX; + promptactive = (cutnum != INT32_MAX && scenenum != INT32_MAX); + + if (promptactive) + { + // on page mode, number of tics before allowing boost + // on timer mode, number of tics until page advances + timetonext = textprompts[cutnum]->page[scenenum].timetonext ? textprompts[cutnum]->page[scenenum].timetonext : TICRATE/10; + F_PreparePageText(textprompts[cutnum]->page[scenenum].text); + + // gfx + picnum = textprompts[cutnum]->page[scenenum].pictostart; + numpics = textprompts[cutnum]->page[scenenum].numpics; + picmode = textprompts[cutnum]->page[scenenum].picmode; + pictoloop = textprompts[cutnum]->page[scenenum].pictoloop > 0 ? textprompts[cutnum]->page[scenenum].pictoloop - 1 : 0; + picxpos = textprompts[cutnum]->page[scenenum].xcoord[picnum]; + picypos = textprompts[cutnum]->page[scenenum].ycoord[picnum]; + animtimer = pictime = textprompts[cutnum]->page[scenenum].picduration[picnum]; + + // music change + if (textprompts[cutnum]->page[scenenum].musswitch[0]) + S_ChangeMusic(textprompts[cutnum]->page[scenenum].musswitch, + textprompts[cutnum]->page[scenenum].musswitchflags, + textprompts[cutnum]->page[scenenum].musicloop); + + // get the calling player + if (promptblockcontrols && mo && mo->player) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (players[i].mo == mo) + { + callplayer = i; + break; + } + } + } + } + else + F_EndTextPrompt(true, false); // run the post-effects immediately +} + +static boolean F_GetTextPromptTutorialTag(char *tag, INT32 length) +{ + INT32 gcs = gcs_custom; + boolean suffixed = true; + + if (!tag || !tag[0] || !tutorialmode) + return false; + + if (!strncmp(tag, "TAM", 3)) // Movement + gcs = G_GetControlScheme(gamecontrol, gcl_movement, num_gcl_movement); + else if (!strncmp(tag, "TAC", 3)) // Camera + { + // Check for gcl_movement so we can differentiate between FPS and Platform schemes. + gcs = G_GetControlScheme(gamecontrol, gcl_movement, num_gcl_movement); + if (gcs == gcs_custom) // try again, maybe we'll get a match + gcs = G_GetControlScheme(gamecontrol, gcl_camera, num_gcl_camera); + if (gcs == gcs_fps && !cv_usemouse.value) + gcs = gcs_platform; // Platform (arrow) scheme is stand-in for no mouse + } + else if (!strncmp(tag, "TAD", 3)) // Movement and Camera + gcs = G_GetControlScheme(gamecontrol, gcl_movement_camera, num_gcl_movement_camera); + else if (!strncmp(tag, "TAJ", 3)) // Jump + gcs = G_GetControlScheme(gamecontrol, gcl_jump, num_gcl_jump); + else if (!strncmp(tag, "TAS", 3)) // Spin + gcs = G_GetControlScheme(gamecontrol, gcl_use, num_gcl_use); + else if (!strncmp(tag, "TAA", 3)) // Char ability + gcs = G_GetControlScheme(gamecontrol, gcl_jump, num_gcl_jump); + else if (!strncmp(tag, "TAW", 3)) // Shield ability + gcs = G_GetControlScheme(gamecontrol, gcl_jump_use, num_gcl_jump_use); + else + gcs = G_GetControlScheme(gamecontrol, gcl_tutorial_used, num_gcl_tutorial_used); + + switch (gcs) + { + case gcs_fps: + // strncat(tag, "FPS", length); + suffixed = false; + break; + + case gcs_platform: + strncat(tag, "PLATFORM", length); + break; + + default: + strncat(tag, "CUSTOM", length); + break; + } + + return suffixed; +} + +void F_GetPromptPageByNamedTag(const char *tag, INT32 *promptnum, INT32 *pagenum) +{ + INT32 nosuffixpromptnum = INT32_MAX, nosuffixpagenum = INT32_MAX; + INT32 tutorialpromptnum = (tutorialmode) ? TUTORIAL_PROMPT-1 : 0; + boolean suffixed = false, found = false; + char suffixedtag[33]; + + *promptnum = *pagenum = INT32_MAX; + + if (!tag || !tag[0]) + return; + + strncpy(suffixedtag, tag, 33); + suffixedtag[32] = 0; + + if (tutorialmode) + suffixed = F_GetTextPromptTutorialTag(suffixedtag, 33); + + for (*promptnum = 0 + tutorialpromptnum; *promptnum < MAX_PROMPTS; (*promptnum)++) + { + if (!textprompts[*promptnum]) + continue; + + for (*pagenum = 0; *pagenum < textprompts[*promptnum]->numpages && *pagenum < MAX_PAGES; (*pagenum)++) + { + if (suffixed && fastcmp(suffixedtag, textprompts[*promptnum]->page[*pagenum].tag)) + { + // this goes first because fastcmp ends early if first string is shorter + found = true; + break; + } + else if (nosuffixpromptnum == INT32_MAX && nosuffixpagenum == INT32_MAX && fastcmp(tag, textprompts[*promptnum]->page[*pagenum].tag)) + { + if (suffixed) + { + nosuffixpromptnum = *promptnum; + nosuffixpagenum = *pagenum; + // continue searching for the suffixed tag + } + else + { + found = true; + break; + } + } + } + + if (found) + break; + } + + if (suffixed && !found && nosuffixpromptnum != INT32_MAX && nosuffixpagenum != INT32_MAX) + { + found = true; + *promptnum = nosuffixpromptnum; + *pagenum = nosuffixpagenum; + } + + if (!found) + CONS_Debug(DBG_GAMELOGIC, "Text prompt: Can't find a page with named tag %s or suffixed tag %s\n", tag, suffixedtag); +} + +void F_TextPromptDrawer(void) +{ + // reuse: + // cutnum -> promptnum + // scenenum -> pagenum + lumpnum_t iconlump; + UINT8 pagelines; + boolean rightside; + INT32 boxh, texth, texty, namey, chevrony; + INT32 textx, textr; + + // Data + patch_t *patch; + + if (!promptactive) + return; + + iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname); + F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr); + + // Draw gfx first + if (picnum >= 0 && picnum < numpics && textprompts[cutnum]->page[scenenum].picname[picnum][0] != '\0') + { + if (textprompts[cutnum]->page[scenenum].pichires[picnum]) + V_DrawSmallScaledPatch(picxpos, picypos, 0, + W_CachePatchName(textprompts[cutnum]->page[scenenum].picname[picnum], PU_CACHE)); + else + V_DrawScaledPatch(picxpos,picypos, 0, + W_CachePatchName(textprompts[cutnum]->page[scenenum].picname[picnum], PU_CACHE)); + } + + // Draw background + V_DrawPromptBack(boxh, textprompts[cutnum]->page[scenenum].backcolor); + + // Draw narrator icon + if (iconlump != LUMPERROR) + { + INT32 iconx, icony, scale, scaledsize; + patch = W_CachePatchName(textprompts[cutnum]->page[scenenum].iconname, PU_CACHE); + + // scale and center + if (patch->width > patch->height) + { + scale = FixedDiv(((boxh * 4) + (boxh/2)*4) - 4, patch->width); + scaledsize = FixedMul(patch->height, scale); + iconx = (rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4) << FRACBITS; + icony = ((namey-4) << FRACBITS) + FixedDiv(BASEVIDHEIGHT - namey + 4 - scaledsize, 2); // account for 4 margin + } + else if (patch->height > patch->width) + { + scale = FixedDiv(((boxh * 4) + (boxh/2)*4) - 4, patch->height); + scaledsize = FixedMul(patch->width, scale); + iconx = (rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4) << FRACBITS; + icony = namey << FRACBITS; + iconx += FixedDiv(FixedMul(patch->height, scale) - scaledsize, 2); + } + else + { + scale = FixedDiv(((boxh * 4) + (boxh/2)*4) - 4, patch->width); + iconx = (rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4) << FRACBITS; + icony = namey << FRACBITS; + } + + if (textprompts[cutnum]->page[scenenum].iconflip) + iconx += FixedMul(patch->width, scale) << FRACBITS; + + V_DrawFixedPatch(iconx, icony, scale, (V_SNAPTOBOTTOM|(textprompts[cutnum]->page[scenenum].iconflip ? V_FLIP : 0)), patch, NULL); + W_UnlockCachedPatch(patch); + } + + // Draw text + V_DrawString(textx, texty, (V_SNAPTOBOTTOM|V_ALLOWLOWERCASE), cutscene_disptext); + + // Draw name + // Don't use V_YELLOWMAP here so that the name color can be changed with control codes + if (textprompts[cutnum]->page[scenenum].name[0]) + V_DrawString(textx, namey, (V_SNAPTOBOTTOM|V_ALLOWLOWERCASE), textprompts[cutnum]->page[scenenum].name); + + // Draw chevron + if (promptblockcontrols && !timetonext) + V_DrawString(textr-8, chevrony + (skullAnimCounter/5), (V_SNAPTOBOTTOM|V_YELLOWMAP), "\x1B"); // down arrow +} + +void F_TextPromptTicker(void) +{ + INT32 i; + + if (!promptactive || paused || P_AutoPause()) + return; + + // advance animation + finalecount++; + cutscene_boostspeed = 0; + + // for the chevron + if (--skullAnimCounter <= 0) + skullAnimCounter = 8; + + // button handling + if (textprompts[cutnum]->page[scenenum].timetonext) + { + if (promptblockcontrols) // same procedure as below, just without the button handling + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (netgame && i != serverplayer && !IsPlayerAdmin(i)) + continue; + else if (splitscreen) { + // Both players' controls are locked, + // But only consoleplayer can advance the prompt. + // \todo Proper per-player splitscreen support (individual prompts) + if (i == consoleplayer || i == secondarydisplayplayer) + players[i].powers[pw_nocontrol] = 1; + } + else if (i == consoleplayer) + players[i].powers[pw_nocontrol] = 1; + + if (!splitscreen) + break; + } + } + + if (timetonext >= 1) + timetonext--; + + if (!timetonext) + F_AdvanceToNextPage(); + + F_WriteText(); + } + else + { + if (promptblockcontrols) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (netgame && i != serverplayer && !IsPlayerAdmin(i)) + continue; + else if (splitscreen) { + // Both players' controls are locked, + // But only the triggering player can advance the prompt. + if (i == consoleplayer || i == secondarydisplayplayer) + { + players[i].powers[pw_nocontrol] = 1; + + if (callplayer == consoleplayer || callplayer == secondarydisplayplayer) + { + if (i != callplayer) + continue; + } + else if (i != consoleplayer) + continue; + } + else + continue; + } + else if (i == consoleplayer) + players[i].powers[pw_nocontrol] = 1; + else + continue; + + if ((players[i].cmd.buttons & BT_USE) || (players[i].cmd.buttons & BT_JUMP)) + { + if (timetonext > 1) + timetonext--; + else if (cutscene_baseptr) // don't set boost if we just reset the string + cutscene_boostspeed = 1; // only after a slight delay + + if (keypressed) + { + if (!splitscreen) + break; + else + continue; + } + + if (!timetonext) // is 0 when finished generating text + { + F_AdvanceToNextPage(); + if (promptactive) + S_StartSound(NULL, sfx_menu1); + } + keypressed = true; // prevent repeat events + } + else if (!(players[i].cmd.buttons & BT_USE) && !(players[i].cmd.buttons & BT_JUMP)) + keypressed = false; + + if (!splitscreen) + break; + } + } + + // generate letter-by-letter text + if (scenenum >= MAX_PAGES || + !textprompts[cutnum]->page[scenenum].text || + !textprompts[cutnum]->page[scenenum].text[0] || + !F_WriteText()) + timetonext = !promptblockcontrols; // never show the chevron if we can't toggle pages + } + + // gfx + if (picnum >= 0 && picnum < numpics) + { + if (animtimer <= 0) + { + boolean persistanimtimer = false; + + if (picnum < numpics-1 && textprompts[cutnum]->page[scenenum].picname[picnum+1][0] != '\0') + picnum++; + else if (picmode == PROMPT_PIC_LOOP) + picnum = pictoloop; + else if (picmode == PROMPT_PIC_DESTROY) + picnum = -1; + else // if (picmode == PROMPT_PIC_PERSIST) + persistanimtimer = true; + + if (!persistanimtimer && picnum >= 0) + { + picxpos = textprompts[cutnum]->page[scenenum].xcoord[picnum]; + picypos = textprompts[cutnum]->page[scenenum].ycoord[picnum]; + pictime = textprompts[cutnum]->page[scenenum].picduration[picnum]; + animtimer = pictime; + } + } + else + animtimer--; + } +} diff --git a/src/f_finale.h b/src/f_finale.h index efab71698f5f97d87324c269d0779420c63ec2a6..c0c6360c316186698c1c78b200d56b3399f121f8 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -17,6 +17,7 @@ #include "doomtype.h" #include "d_event.h" +#include "p_mobj.h" // // FINALE @@ -33,11 +34,13 @@ void F_IntroTicker(void); void F_TitleScreenTicker(boolean run); void F_CutsceneTicker(void); void F_TitleDemoTicker(void); +void F_TextPromptTicker(void); // Called by main loop. void F_GameEndDrawer(void); void F_IntroDrawer(void); void F_TitleScreenDrawer(void); +void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname); void F_GameEvaluationDrawer(void); void F_StartGameEvaluation(void); @@ -50,6 +53,13 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset void F_CutsceneDrawer(void); void F_EndCutScene(void); +void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postexectag, boolean blockcontrols, boolean freezerealtime); +void F_GetPromptPageByNamedTag(const char *tag, INT32 *promptnum, INT32 *pagenum); +void F_TextPromptDrawer(void); +void F_EndTextPrompt(boolean forceexec, boolean noexec); +boolean F_GetPromptHideHudAll(void); +boolean F_GetPromptHideHud(fixed_t y); + void F_StartGameEnd(void); void F_StartIntro(void); void F_StartTitleScreen(void); @@ -60,17 +70,48 @@ void F_StartContinue(void); void F_ContinueTicker(void); void F_ContinueDrawer(void); -extern INT32 titlescrollspeed; +extern INT32 titlescrollxspeed; +extern INT32 titlescrollyspeed; + +typedef enum +{ + TITLEMAP_OFF = 0, + TITLEMAP_LOADING, + TITLEMAP_RUNNING +} titlemap_enum; + +// Current menu parameters + +extern UINT8 titlemapinaction; +extern mobj_t *titlemapcameraref; +extern char curbgname[8]; +extern SINT8 curfadevalue; +extern boolean curhidepics; +extern INT32 curbgcolor; +extern INT32 curbgxspeed; +extern INT32 curbgyspeed; +extern boolean curbghide; + +#define TITLEBACKGROUNDACTIVE (curfadevalue >= 0 || curbgname[0]) + +void F_InitMenuPresValues(void); +void F_MenuPresTicker(boolean run); // // WIPE // +// HACK for menu fading while titlemapinaction; skips the level check +#define FORCEWIPE -3 +#define FORCEWIPEOFF -2 + extern boolean WipeInAction; extern INT32 lastwipetic; void F_WipeStartScreen(void); void F_WipeEndScreen(void); void F_RunWipe(UINT8 wipetype, boolean drawMenu); +tic_t F_GetWipeLength(UINT8 wipetype); +boolean F_WipeExists(UINT8 wipetype); enum { diff --git a/src/f_wipe.c b/src/f_wipe.c index 95dd5bbdef8c386727f0df4f6e641b6885129774..26c65ad91c9fb1d7c87410a59fdeebcceee96e39 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -86,7 +86,7 @@ INT32 lastwipetic = 0; static UINT8 *wipe_scr_start; //screen 3 static UINT8 *wipe_scr_end; //screen 4 static UINT8 *wipe_scr; //screen 0 (main drawing) -static fixed_t paldiv; +static fixed_t paldiv = 0; /** Create fademask_t from lump * @@ -145,7 +145,7 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) { while (lsize--) { // Determine pixel to use from fademask - pcolor = &pLocalPalette[*lump++]; + pcolor = &pMasterPalette[*lump++]; *mask++ = FixedDiv((pcolor->s.red+1)<<FRACBITS, paldiv)>>FRACBITS; } @@ -337,7 +337,8 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu) UINT8 wipeframe = 0; fademask_t *fmask; - paldiv = FixedDiv(257<<FRACBITS, 11<<FRACBITS); + if (!paldiv) + paldiv = FixedDiv(257<<FRACBITS, 11<<FRACBITS); // Init the wipe WipeInAction = true; @@ -377,3 +378,48 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu) WipeInAction = false; #endif } + +/** Returns tic length of wipe + * One lump equals one tic + */ +tic_t F_GetWipeLength(UINT8 wipetype) +{ +#ifdef NOWIPE + return 0; +#else + static char lumpname[10] = "FADEmmss"; + lumpnum_t lumpnum; + UINT8 wipeframe; + + if (wipetype > 99) + return 0; + + for (wipeframe = 0; wipeframe < 100; wipeframe++) + { + sprintf(&lumpname[4], "%.2hu%.2hu", (UINT16)wipetype, (UINT16)wipeframe); + + lumpnum = W_CheckNumForName(lumpname); + if (lumpnum == LUMPERROR) + return --wipeframe; + } + return --wipeframe; +#endif +} + +boolean F_WipeExists(UINT8 wipetype) +{ +#ifdef NOWIPE + return false; +#else + static char lumpname[10] = "FADEmm00"; + lumpnum_t lumpnum; + + if (wipetype > 99) + return false; + + sprintf(&lumpname[4], "%.2hu00", (UINT16)wipetype); + + lumpnum = W_CheckNumForName(lumpname); + return !(lumpnum == LUMPERROR); +#endif +} diff --git a/src/filesrch.c b/src/filesrch.c index 0276e1c90c92b00488814768f5503db9fee038f6..8f157bdd522c86af9cb16c647de8f802cb7f42d6 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -16,16 +16,12 @@ #ifdef __GNUC__ #include <dirent.h> #endif -#if defined (_WIN32) && !defined (_XBOX) +#ifdef _WIN32 //#define WIN32_LEAN_AND_MEAN #define RPC_NO_WINDOWS_H #include <windows.h> #endif -#ifdef _WIN32_WCE -#include "sdl12/SRB2CE/cehelp.h" -#else #include <sys/stat.h> -#endif #include <string.h> #include "filesrch.h" @@ -34,7 +30,7 @@ #include "z_zone.h" #include "m_menu.h" // Addons_option_Onchange -#if (defined (_WIN32) && !defined (_WIN32_WCE)) && defined (_MSC_VER) && !defined (_XBOX) +#if defined (_WIN32) && defined (_MSC_VER) #include <errno.h> #include <io.h> @@ -344,107 +340,6 @@ char *refreshdirname = NULL; size_t packetsizetally = 0; size_t mainwadstally = 0; -#if defined (_XBOX) && defined (_MSC_VER) -filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, - boolean completepath, int maxsearchdepth) -{ -//NONE? - startpath = filename = NULL; - wantedmd5sum = NULL; - maxsearchdepth = 0; - completepath = false; - return FS_NOTFOUND; -} - -void closefilemenu(boolean validsize) -{ - (void)validsize; - return; -} - -void searchfilemenu(char *tempname) -{ - (void)tempname; - return; -} - -boolean preparefilemenu(boolean samedepth) -{ - (void)samedepth; - return false; -} - -#elif defined (_WIN32_WCE) -filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, - boolean completepath, int maxsearchdepth) -{ -#ifdef __GNUC__ -//NONE? - startpath = filename = NULL; - wantedmd5sum = NULL; - maxsearchdepth = 0; - completepath = false; -#else - WIN32_FIND_DATA dta; - HANDLE searchhandle = INVALID_HANDLE_VALUE; - const wchar_t wm[4] = L"*.*"; - - //if (startpath) SetCurrentDirectory(startpath); - if (FIL_ReadFileOK(filename)) - { - // checkfilemd5 returns an FS_* value, either FS_FOUND or FS_MD5SUMBAD - return checkfilemd5(filename, wantedmd5sum); - } - ZeroMemory(&dta,sizeof (dta)); - if (maxsearchdepth) - searchhandle = FindFirstFile(wm,&dta); - if (searchhandle != INVALID_HANDLE_VALUE) - { - do - { - if ((dta.cFileName[0]!='.') && (dta.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { - //if (SetCurrentDirectory(dta.cFileName)) - { // can fail if we haven't the right - filestatus_t found; - found = filesearch(filename,NULL,wantedmd5sum,completepath,maxsearchdepth-1); - //SetCurrentDirectory(".."); - if (found == FS_FOUND || found == FS_MD5SUMBAD) - { - if (completepath) - strcatbf(filename,(char *)dta.cFileName,"\\"); - FindClose(searchhandle); - return found; - } - } - } - } while (FindNextFile(searchhandle,&dta)==0); - FindClose(searchhandle); - } -#endif - return FS_NOTFOUND; -} - -void closefilemenu(boolean validsize) -{ - (void)validsize; - return; -} - -void searchfilemenu(char *tempname) -{ - (void)tempname; - return; -} - -boolean preparefilemenu(boolean samedepth) -{ - (void)samedepth; - return false; -} - -#else - filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, boolean completepath, int maxsearchdepth) { filestatus_t retval = FS_NOTFOUND; @@ -473,9 +368,9 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want return FS_NOTFOUND; } - if (searchpath[searchpathindex[depthleft]-2] != '/') + if (searchpath[searchpathindex[depthleft]-2] != PATHSEP[0]) { - searchpath[searchpathindex[depthleft]-1] = '/'; + searchpath[searchpathindex[depthleft]-1] = PATHSEP[0]; searchpath[searchpathindex[depthleft]] = 0; } else @@ -517,7 +412,7 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want depthleft++; } - searchpath[searchpathindex[depthleft]-1]='/'; + searchpath[searchpathindex[depthleft]-1]=PATHSEP[0]; searchpath[searchpathindex[depthleft]]=0; } else if (!strcasecmp(searchname, dent->d_name)) @@ -906,5 +801,3 @@ boolean preparefilemenu(boolean samedepth) return true; } - -#endif diff --git a/src/g_game.c b/src/g_game.c index b28ab775296d16870eda6f93696c5cf441b8c389..85d21e8e1f053fc675362fc87ce06ae7d859077b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -78,10 +78,14 @@ INT16 gamemap = 1; INT16 maptol; UINT8 globalweather = 0; INT32 curWeather = PRECIP_NONE; -INT32 cursaveslot = -1; // Auto-save 1p savegame slot -INT16 lastmapsaved = 0; // Last map we auto-saved at +INT32 cursaveslot = 0; // Auto-save 1p savegame slot +//INT16 lastmapsaved = 0; // Last map we auto-saved at +INT16 lastmaploaded = 0; // Last map the game loaded boolean gamecomplete = false; +UINT8 numgameovers = 0; // for startinglives balance +SINT8 startinglivesbalance[maxgameovers+1] = {3, 5, 7, 9, 12, 15, 20, 25, 30, 40, 50, 75, 99, 0x7F}; + UINT16 mainwads = 0; boolean modifiedgame; // Set if homebrew PWAD stuff has been added. boolean savemoddata = false; @@ -90,6 +94,7 @@ UINT8 modeattacking = ATTACKING_NONE; boolean disableSpeedAdjust = false; boolean imcontinuing = false; boolean runemeraldmanager = false; +UINT16 emeraldspawndelay = 60*TICRATE; // menu demo things UINT8 numDemos = 3; @@ -113,27 +118,38 @@ INT32 secondarydisplayplayer; // for splitscreen tic_t gametic; tic_t levelstarttic; // gametic at level start -UINT32 totalrings; // for intermission +UINT32 ssspheres; // old special stage INT16 lastmap; // last level you were at (returning from special stages) tic_t timeinmap; // Ticker for time spent in level (used for levelcard display) INT16 spstage_start; -INT16 sstage_start; -INT16 sstage_end; +INT16 sstage_start, sstage_end, smpstage_start, smpstage_end; + +INT16 titlemap = 0; +boolean hidetitlepics = false; +INT16 bootmap; //bootmap for loading a map on startup + +INT16 tutorialmap = 0; // map to load for tutorial +boolean tutorialmode = false; // are we in a tutorial right now? +INT32 tutorialgcs = gcs_custom; // which control scheme is loaded? +INT32 tutorialusemouse = 0; // store cv_usemouse user value +INT32 tutorialfreelook = 0; // store cv_alwaysfreelook user value +INT32 tutorialmousemove = 0; // store cv_mousemove user value +INT32 tutorialanalog = 0; // store cv_analog user value boolean looptitle = false; -boolean useNightsSS = false; UINT8 skincolor_redteam = SKINCOLOR_RED; UINT8 skincolor_blueteam = SKINCOLOR_BLUE; -UINT8 skincolor_redring = SKINCOLOR_RED; -UINT8 skincolor_bluering = SKINCOLOR_STEELBLUE; +UINT8 skincolor_redring = SKINCOLOR_SALMON; +UINT8 skincolor_bluering = SKINCOLOR_CORNFLOWER; tic_t countdowntimer = 0; boolean countdowntimeup = false; boolean exitfadestarted = false; cutscene_t *cutscenes[128]; +textprompt_t *textprompts[MAX_PROMPTS]; INT16 nextmapoverride; boolean skipstats; @@ -158,6 +174,7 @@ UINT8 stagefailed; // Used for GEMS BONUS? Also to see if you beat the stage. UINT16 emeralds; UINT32 token; // Number of tokens collected in a level UINT32 tokenlist; // List of tokens collected +boolean gottoken; // Did you get a token? Used for end of act INT32 tokenbits; // Used for setting token bits // Old Special Stage @@ -196,6 +213,7 @@ UINT16 tailsflytics = 8*TICRATE; UINT16 underwatertics = 30*TICRATE; UINT16 spacetimetics = 11*TICRATE + (TICRATE/2); UINT16 extralifetics = 4*TICRATE; +UINT16 nightslinktics = 2*TICRATE; INT32 gameovertics = 15*TICRATE; @@ -241,7 +259,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 -static boolean demosynced = true; // console warning message +boolean demosynced = true; // console warning message boolean metalrecording; // recording as metal sonic mobj_t *metalplayback; @@ -286,48 +304,16 @@ static void UserAnalog_OnChange(void); static void UserAnalog2_OnChange(void); static void Analog_OnChange(void); static void Analog2_OnChange(void); +static void DirectionChar_OnChange(void); +static void DirectionChar2_OnChange(void); +static void AutoBrake_OnChange(void); +static void AutoBrake2_OnChange(void); void SendWeaponPref(void); void SendWeaponPref2(void); static CV_PossibleValue_t crosshair_cons_t[] = {{0, "Off"}, {1, "Cross"}, {2, "Angle"}, {3, "Point"}, {0, NULL}}; static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"}, -#ifdef _WII -{1, "LStick.X"}, {2, "LStick.Y"}, {-1, "LStick.X-"}, {-2, "LStick.Y-"}, -#if JOYAXISSET > 1 -{3, "RStick.X"}, {4, "RStick.Y"}, {-3, "RStick.X-"}, {-4, "RStick.Y-"}, -#endif -#if JOYAXISSET > 2 -{5, "RTrigger"}, {6, "LTrigger"}, {-5, "RTrigger-"}, {-6, "LTrigger-"}, -#endif -#if JOYAXISSET > 3 -{7, "Pitch"}, {8, "Roll"}, {-7, "Pitch-"}, {-8, "Roll-"}, -#endif -#if JOYAXISSET > 4 -{7, "Yaw"}, {8, "Dummy"}, {-7, "Yaw-"}, {-8, "Dummy-"}, -#endif -#if JOYAXISSET > 4 -{9, "LAnalog"}, {10, "RAnalog"}, {-9, "LAnalog-"}, {-10, "RAnalog-"}, -#endif -#elif defined (WMINPUT) -{1, "LStick.X"}, {2, "LStick.Y"}, {-1, "LStick.X-"}, {-2, "LStick.Y-"}, -#if JOYAXISSET > 1 -{3, "RStick.X"}, {4, "RStick.Y"}, {-3, "RStick.X-"}, {-4, "RStick.Y-"}, -#endif -#if JOYAXISSET > 2 -{5, "NStick.X"}, {6, "NStick.Y"}, {-5, "NStick.X-"}, {-6, "NStick.Y-"}, -#endif -#if JOYAXISSET > 3 -{7, "LAnalog"}, {8, "RAnalog"}, {-7, "LAnalog-"}, {-8, "RAnalog-"}, -#endif -#else {1, "X-Axis"}, {2, "Y-Axis"}, {-1, "X-Axis-"}, {-2, "Y-Axis-"}, -#ifdef _arch_dreamcast -{3, "R-Trig"}, {4, "L-Trig"}, {-3, "R-Trig-"}, {-4, "L-Trig-"}, -{5, "Alt X-Axis"}, {6, "Alt Y-Axis"}, {-5, "Alt X-Axis-"}, {-6, "Alt Y-Axis-"}, -{7, "Triggers"}, {-7,"Triggers-"}, -#elif defined (_XBOX) -{3, "Alt X-Axis"}, {4, "Alt Y-Axis"}, {-3, "Alt X-Axis-"}, {-4, "Alt Y-Axis-"}, -#else #if JOYAXISSET > 1 {3, "Z-Axis"}, {4, "X-Rudder"}, {-3, "Z-Axis-"}, {-4, "X-Rudder-"}, #endif @@ -336,19 +322,11 @@ static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"}, #endif #if JOYAXISSET > 3 {7, "U-Axis"}, {8, "V-Axis"}, {-7, "U-Axis-"}, {-8, "V-Axis-"}, -#endif -#endif #endif {0, NULL}}; -#ifdef _WII -#if JOYAXISSET > 5 -"More Axis Sets" -#endif -#else #if JOYAXISSET > 4 "More Axis Sets" #endif -#endif // don't mind me putting these here, I was lazy to figure out where else I could put those without blowing up the compiler. @@ -384,22 +362,27 @@ consvar_t cv_consolechat = {"chatmode", "Window", CV_SAVE, consolechat_cons_t, N consvar_t cv_crosshair = {"crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_crosshair2 = {"crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_invertmouse = {"invertmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_invertmouse2 = {"invertmouse2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_alwaysfreelook = {"alwaysmlook", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_invertmouse2 = {"invertmouse2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_alwaysfreelook2 = {"alwaysmlook2", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_chasefreelook = {"chasemlook", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_chasefreelook2 = {"chasemlook2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_mousemove = {"mousemove", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_mousemove2 = {"mousemove2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_analog = {"analog", "Off", CV_CALL, CV_OnOff, Analog_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_analog2 = {"analog2", "Off", CV_CALL, CV_OnOff, Analog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; -#ifdef DC -consvar_t cv_useranalog = {"useranalog", "On", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_useranalog2 = {"useranalog2", "On", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; -#else -consvar_t cv_useranalog = {"useranalog", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_useranalog2 = {"useranalog2", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; -#endif + +// previously "analog", "analog2", "useranalog", and "useranalog2", invalidating 2.1-era copies of config.cfg +// changed because it'd be nice to see people try out our actually good controls with gamepads now autobrake exists +consvar_t cv_analog = {"sessionanalog", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, Analog_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_analog2 = {"sessionanalog2", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, Analog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_useranalog = {"configanalog", "Off", CV_SAVE|CV_CALL|CV_NOSHOWHELP, CV_OnOff, UserAnalog_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_useranalog2 = {"configanalog2", "Off", CV_SAVE|CV_CALL|CV_NOSHOWHELP, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +// deez New User eXperiences +static CV_PossibleValue_t directionchar_cons_t[] = {{0, "Camera"}, {1, "Movement"}, {0, NULL}}; +consvar_t cv_directionchar = {"directionchar", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_directionchar2 = {"directionchar2", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_autobrake = {"autobrake", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_autobrake2 = {"autobrake2", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake2_OnChange, 0, NULL, NULL, 0, 0, NULL}; typedef enum { @@ -415,76 +398,23 @@ typedef enum AXISFIRENORMAL, } axis_input_e; -#if defined (_WII) || defined (WMINPUT) -consvar_t cv_turnaxis = {"joyaxis_turn", "LStick.X", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_moveaxis = {"joyaxis_move", "LStick.Y", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_sideaxis = {"joyaxis_side", "RStick.X", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_lookaxis = {"joyaxis_look", "RStick.Y", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_jumpaxis = {"joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_spinaxis = {"joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_fireaxis = {"joyaxis_fire", "LAnalog", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_firenaxis = {"joyaxis_firenormal", "RAnalog", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#else consvar_t cv_turnaxis = {"joyaxis_turn", "X-Rudder", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#ifdef PSP -consvar_t cv_moveaxis = {"joyaxis_move", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#else consvar_t cv_moveaxis = {"joyaxis_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif -#ifdef _arch_dreamcast -consvar_t cv_sideaxis = {"joyaxis_side", "Triggers", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#elif defined (_XBOX) -consvar_t cv_sideaxis = {"joyaxis_side", "Alt X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_lookaxis = {"joyaxis_look", "Alt Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#elif defined (PSP) -consvar_t cv_sideaxis = {"joyaxis_side", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#else consvar_t cv_sideaxis = {"joyaxis_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif -#ifndef _XBOX -#ifdef PSP -consvar_t cv_lookaxis = {"joyaxis_look", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#else consvar_t cv_lookaxis = {"joyaxis_look", "Y-Rudder-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif -#endif consvar_t cv_jumpaxis = {"joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_spinaxis = {"joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis = {"joyaxis_fire", "Z-Axis-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_firenaxis = {"joyaxis_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif -#if defined (_WII) || defined (WMINPUT) -consvar_t cv_turnaxis2 = {"joyaxis2_turn", "LStick.X", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_moveaxis2 = {"joyaxis2_move", "LStick.Y", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_sideaxis2 = {"joyaxis2_side", "RStick.X", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_lookaxis2 = {"joyaxis2_look", "RStick.Y", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_jumpaxis2 = {"joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_spinaxis2 = {"joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_fireaxis2 = {"joyaxis2_fire", "LAnalog", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_firenaxis2 = {"joyaxis2_firenormal", "RAnalog", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#else consvar_t cv_turnaxis2 = {"joyaxis2_turn", "X-Rudder", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_moveaxis2 = {"joyaxis2_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#ifdef _arch_dreamcast -consvar_t cv_sideaxis2 = {"joyaxis2_side", "Triggers", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#elif defined (_XBOX) -consvar_t cv_sideaxis2 = {"joyaxis2_side", "Alt X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_lookaxis2 = {"joyaxis2_look", "Alt Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#elif defined (_PSP) -consvar_t cv_sideaxis2 = {"joyaxis2_side", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#else consvar_t cv_sideaxis2 = {"joyaxis2_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif -#ifndef _XBOX consvar_t cv_lookaxis2 = {"joyaxis2_look", "Y-Rudder-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif consvar_t cv_jumpaxis2 = {"joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_spinaxis2 = {"joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis2 = {"joyaxis2_fire", "Z-Axis-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_firenaxis2 = {"joyaxis2_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif - #if MAXPLAYERS > 32 #error "please update player_name table using the new value for MAXPLAYERS" @@ -742,8 +672,7 @@ void G_SetNightsRecords(void) free(gpath); // If the mare count changed, this will update the score display - CV_AddValue(&cv_nextmap, 1); - CV_AddValue(&cv_nextmap, -1); + Nextmap_OnChange(); } // for consistency among messages: this modifies the game and removes savemoddata. @@ -869,14 +798,6 @@ static INT32 JoyAxis(axis_input_e axissel) axisval = -axisval; flp = true; } -#ifdef _arch_dreamcast - if (axisval == 7) // special case - { - retaxis = joyxmove[1] - joyymove[1]; - goto skipDC; - } - else -#endif if (axisval > JOYAXISSET*2 || axisval == 0) //not there in array or None return 0; @@ -892,10 +813,6 @@ static INT32 JoyAxis(axis_input_e axissel) retaxis = joyymove[axisval]; } -#ifdef _arch_dreamcast - skipDC: -#endif - if (retaxis < (-JOYAXISRANGE)) retaxis = -JOYAXISRANGE; if (retaxis > (+JOYAXISRANGE)) @@ -953,14 +870,7 @@ static INT32 Joy2Axis(axis_input_e axissel) axisval = -axisval; flp = true; } -#ifdef _arch_dreamcast - if (axisval == 7) // special case - { - retaxis = joy2xmove[1] - joy2ymove[1]; - goto skipDC; - } - else -#endif + if (axisval > JOYAXISSET*2 || axisval == 0) //not there in array or None return 0; @@ -976,10 +886,6 @@ static INT32 Joy2Axis(axis_input_e axissel) retaxis = joy2ymove[axisval]; } -#ifdef _arch_dreamcast - skipDC: -#endif - if (retaxis < (-JOYAXISRANGE)) retaxis = -JOYAXISRANGE; if (retaxis > (+JOYAXISRANGE)) @@ -1016,7 +922,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) INT32 tspeed, forward, side, axis, altaxis, i; const INT32 speed = 1; // these ones used for multiple conditions - boolean turnleft, turnright, mouseaiming, analogjoystickmove, gamepadjoystickmove, thisjoyaiming; + boolean turnleft, turnright, strafelkey, straferkey, movefkey, movebkey, mouseaiming, analogjoystickmove, gamepadjoystickmove, thisjoyaiming; player_t *player = &players[consoleplayer]; camera_t *thiscam = &camera; @@ -1029,7 +935,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) // why build a ticcmd if we're paused? // Or, for that matter, if we're being reborn. - if (paused || P_AutoPause() || (gamestate == GS_LEVEL && player->playerstate == PST_REBORN)) + // ...OR if we're blindfolded. No looking into the floor. + if (paused || P_AutoPause() || (gamestate == GS_LEVEL && (player->playerstate == PST_REBORN || ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + && (leveltime < hidetime * TICRATE) && (player->pflags & PF_TAGIT))))) { cmd->angleturn = (INT16)(localangle >> 16); cmd->aiming = G_ClipAimingPitch(&localaiming); @@ -1038,6 +946,12 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) turnright = PLAYER1INPUTDOWN(gc_turnright); turnleft = PLAYER1INPUTDOWN(gc_turnleft); + + straferkey = PLAYER1INPUTDOWN(gc_straferight); + strafelkey = PLAYER1INPUTDOWN(gc_strafeleft); + movefkey = PLAYER1INPUTDOWN(gc_forward); + movebkey = PLAYER1INPUTDOWN(gc_backward); + mouseaiming = (PLAYER1INPUTDOWN(gc_mouseaiming)) ^ (cv_chasecam.value ? cv_chasefreelook.value : cv_alwaysfreelook.value); analogjoystickmove = cv_usejoystick.value && !Joystick.bGamepadStyle; @@ -1078,14 +992,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) if (turnleft) cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]); } - if (cv_analog.value || twodlevel + if (twodlevel || (player->mo && (player->mo->flags2 & MF2_TWOD)) || (!demoplayback && (player->climbing - || (player->pflags & PF_NIGHTSMODE) - || (player->pflags & PF_SLIDING) - || (player->pflags & PF_FORCESTRAFE)))) // Analog + || (player->powers[pw_carry] == CR_NIGHTSMODE) + || (player->pflags & (PF_SLIDING|PF_FORCESTRAFE))))) // Analog forcestrafe = true; - if (forcestrafe) // Analog + if (forcestrafe) { if (turnright) side += sidemove[speed]; @@ -1098,6 +1011,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) side += ((axis * sidemove[1]) >> 10); } } + else if (cv_analog.value) // Analog + { + if (turnright) + cmd->buttons |= BT_CAMRIGHT; + if (turnleft) + cmd->buttons |= BT_CAMLEFT; + } else { if (turnright) @@ -1129,12 +1049,12 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) // forward with key or button axis = JoyAxis(AXISMOVE); altaxis = JoyAxis(AXISLOOK); - if (PLAYER1INPUTDOWN(gc_forward) || (gamepadjoystickmove && axis < 0) - || ((player->pflags & PF_NIGHTSMODE) + if (movefkey || (gamepadjoystickmove && axis < 0) + || ((player->powers[pw_carry] == CR_NIGHTSMODE) && (PLAYER1INPUTDOWN(gc_lookup) || (gamepadjoystickmove && altaxis < 0)))) forward = forwardmove[speed]; - if (PLAYER1INPUTDOWN(gc_backward) || (gamepadjoystickmove && axis > 0) - || ((player->pflags & PF_NIGHTSMODE) + if (movebkey || (gamepadjoystickmove && axis > 0) + || ((player->powers[pw_carry] == CR_NIGHTSMODE) && (PLAYER1INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && altaxis > 0)))) forward -= forwardmove[speed]; @@ -1143,9 +1063,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) // some people strafe left & right with mouse buttons // those people are weird - if (PLAYER1INPUTDOWN(gc_straferight)) + if (straferkey) side += sidemove[speed]; - if (PLAYER1INPUTDOWN(gc_strafeleft)) + if (strafelkey) side -= sidemove[speed]; if (PLAYER1INPUTDOWN(gc_weaponnext)) @@ -1191,15 +1111,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) if (PLAYER1INPUTDOWN(gc_use) || (cv_usejoystick.value && axis > 0)) cmd->buttons |= BT_USE; - // Camera Controls - if (cv_debug || cv_analog.value || demoplayback || objectplacing || player->pflags & PF_NIGHTSMODE) - { - if (PLAYER1INPUTDOWN(gc_camleft)) - cmd->buttons |= BT_CAMLEFT; - if (PLAYER1INPUTDOWN(gc_camright)) - cmd->buttons |= BT_CAMRIGHT; - } - if (PLAYER1INPUTDOWN(gc_camreset)) { if (camera.chase && !resetdown) @@ -1239,7 +1150,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) if (!keyboard_look && cv_lookaxis.value == 0 && !joyaiming && !mouseaiming) localaiming = 0; - if (!(player->pflags & PF_NIGHTSMODE)) + if (!(player->powers[pw_carry] == CR_NIGHTSMODE)) { if (PLAYER1INPUTDOWN(gc_lookup) || (gamepadjoystickmove && axis < 0)) { @@ -1265,10 +1176,19 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) if (!mouseaiming && cv_mousemove.value) forward += mousey; - if (cv_analog.value || - (!demoplayback && (player->climbing + if ((!demoplayback && (player->climbing || (player->pflags & PF_SLIDING)))) // Analog for mouse side += mousex*2; + else if (cv_analog.value) + { + if (mousex) + { + if (mousex > 0) + cmd->buttons |= BT_CAMRIGHT; + else + cmd->buttons |= BT_CAMLEFT; + } + } else cmd->angleturn = (INT16)(cmd->angleturn - (mousex*8)); @@ -1285,7 +1205,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) // No additional acceleration when moving forward/backward and strafing simultaneously. // do this AFTER we cap to MAXPLMOVE so people can't find ways to cheese around this. - if (!forcestrafe && forward && side) + // 9-18-2017: ALSO, only do this when using keys to move. Gamepad analog sticks get severely gimped by this + if (!forcestrafe && (((movefkey || movebkey) && side) || ((strafelkey || straferkey) && forward))) { forward = FixedMul(forward, 3*FRACUNIT/4); side = FixedMul(side, 3*FRACUNIT/4); @@ -1303,9 +1224,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) cmd->sidemove = (SINT8)(cmd->sidemove + side); if (cv_analog.value) { - cmd->angleturn = (INT16)(thiscam->angle >> 16); if (player->awayviewtics) cmd->angleturn = (INT16)(player->awayviewmobj->angle >> 16); + else + cmd->angleturn = (INT16)(thiscam->angle >> 16); } else { @@ -1326,7 +1248,7 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) INT32 tspeed, forward, side, axis, altaxis, i; const INT32 speed = 1; // these ones used for multiple conditions - boolean turnleft, turnright, mouseaiming, analogjoystickmove, gamepadjoystickmove, thisjoyaiming; + boolean turnleft, turnright, strafelkey, straferkey, movefkey, movebkey, mouseaiming, analogjoystickmove, gamepadjoystickmove, thisjoyaiming; player_t *player = &players[secondarydisplayplayer]; camera_t *thiscam = (player->bot == 2 ? &camera : &camera2); @@ -1348,6 +1270,12 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) turnright = PLAYER2INPUTDOWN(gc_turnright); turnleft = PLAYER2INPUTDOWN(gc_turnleft); + + straferkey = PLAYER2INPUTDOWN(gc_straferight); + strafelkey = PLAYER2INPUTDOWN(gc_strafeleft); + movefkey = PLAYER2INPUTDOWN(gc_forward); + movebkey = PLAYER2INPUTDOWN(gc_backward); + mouseaiming = (PLAYER2INPUTDOWN(gc_mouseaiming)) ^ (cv_chasecam2.value ? cv_chasefreelook2.value : cv_alwaysfreelook2.value); analogjoystickmove = cv_usejoystick2.value && !Joystick2.bGamepadStyle; @@ -1388,12 +1316,11 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) if (turnleft) cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]); } - if (cv_analog2.value || twodlevel + if (twodlevel || (player->mo && (player->mo->flags2 & MF2_TWOD)) || player->climbing - || (player->pflags & PF_NIGHTSMODE) - || (player->pflags & PF_SLIDING) - || (player->pflags & PF_FORCESTRAFE)) // Analog + || (player->powers[pw_carry] == CR_NIGHTSMODE) + || (player->pflags & (PF_SLIDING|PF_FORCESTRAFE))) // Analog forcestrafe = true; if (forcestrafe) // Analog { @@ -1408,6 +1335,13 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) side += ((axis * sidemove[1]) >> 10); } } + else if (cv_analog2.value) // Analog + { + if (turnright) + cmd->buttons |= BT_CAMRIGHT; + if (turnleft) + cmd->buttons |= BT_CAMLEFT; + } else { if (turnright) @@ -1439,12 +1373,12 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) // forward with key or button axis = Joy2Axis(AXISMOVE); altaxis = Joy2Axis(AXISLOOK); - if (PLAYER2INPUTDOWN(gc_forward) || (gamepadjoystickmove && axis < 0) - || ((player->pflags & PF_NIGHTSMODE) + if (movefkey || (gamepadjoystickmove && axis < 0) + || ((player->powers[pw_carry] == CR_NIGHTSMODE) && (PLAYER2INPUTDOWN(gc_lookup) || (gamepadjoystickmove && altaxis < 0)))) forward = forwardmove[speed]; - if (PLAYER2INPUTDOWN(gc_backward) || (gamepadjoystickmove && axis > 0) - || ((player->pflags & PF_NIGHTSMODE) + if (movebkey || (gamepadjoystickmove && axis > 0) + || ((player->powers[pw_carry] == CR_NIGHTSMODE) && (PLAYER2INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && altaxis > 0)))) forward -= forwardmove[speed]; @@ -1453,9 +1387,9 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) // some people strafe left & right with mouse buttons // those people are (still) weird - if (PLAYER2INPUTDOWN(gc_straferight)) + if (straferkey) side += sidemove[speed]; - if (PLAYER2INPUTDOWN(gc_strafeleft)) + if (strafelkey) side -= sidemove[speed]; if (PLAYER2INPUTDOWN(gc_weaponnext)) @@ -1498,15 +1432,6 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) if (PLAYER2INPUTDOWN(gc_use) || (cv_usejoystick2.value && axis > 0)) cmd->buttons |= BT_USE; - // Camera Controls - if (cv_debug || cv_analog2.value || player->pflags & PF_NIGHTSMODE) - { - if (PLAYER2INPUTDOWN(gc_camleft)) - cmd->buttons |= BT_CAMLEFT; - if (PLAYER2INPUTDOWN(gc_camright)) - cmd->buttons |= BT_CAMRIGHT; - } - if (PLAYER2INPUTDOWN(gc_camreset)) { if (camera2.chase && !resetdown) @@ -1546,7 +1471,7 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) if (!keyboard_look && cv_lookaxis2.value == 0 && !joyaiming && !mouseaiming) localaiming2 = 0; - if (!(player->pflags & PF_NIGHTSMODE)) + if (!(player->powers[pw_carry] == CR_NIGHTSMODE)) { if (PLAYER2INPUTDOWN(gc_lookup) || (gamepadjoystickmove && axis < 0)) { @@ -1572,9 +1497,19 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) if (!mouseaiming && cv_mousemove2.value) forward += mouse2y; - if (cv_analog2.value || player->climbing + if (player->climbing || (player->pflags & PF_SLIDING)) // Analog for mouse side += mouse2x*2; + else if (cv_analog2.value) + { + if (mouse2x) + { + if (mouse2x > 0) + cmd->buttons |= BT_CAMRIGHT; + else + cmd->buttons |= BT_CAMLEFT; + } + } else cmd->angleturn = (INT16)(cmd->angleturn - (mouse2x*8)); @@ -1591,7 +1526,8 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) // No additional acceleration when moving forward/backward and strafing simultaneously. // do this AFTER we cap to MAXPLMOVE so people can't find ways to cheese around this. - if (!forcestrafe && forward && side) + // 9-18-2017: ALSO, only do this when using keys to move. Gamepad analog sticks get severely gimped by this + if (!forcestrafe && (((movefkey || movebkey) && side) || ((strafelkey || straferkey) && forward))) { forward = FixedMul(forward, 3*FRACUNIT/4); side = FixedMul(side, 3*FRACUNIT/4); @@ -1622,9 +1558,10 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) } if (cv_analog2.value) { - cmd->angleturn = (INT16)(thiscam->angle >> 16); if (player->awayviewtics) cmd->angleturn = (INT16)(player->awayviewmobj->angle >> 16); + else + cmd->angleturn = (INT16)(thiscam->angle >> 16); } else { @@ -1684,6 +1621,26 @@ static void Analog2_OnChange(void) SendWeaponPref2(); } +static void DirectionChar_OnChange(void) +{ + SendWeaponPref(); +} + +static void DirectionChar2_OnChange(void) +{ + SendWeaponPref2(); +} + +static void AutoBrake_OnChange(void) +{ + SendWeaponPref(); +} + +static void AutoBrake2_OnChange(void) +{ + SendWeaponPref2(); +} + // // G_DoLoadLevel // @@ -1693,6 +1650,7 @@ void G_DoLoadLevel(boolean resetplayer) // Make sure objectplace is OFF when you first start the level! OP_ResetObjectplace(); + demosynced = true; levelstarttic = gametic; // for time calculation @@ -1702,6 +1660,21 @@ void G_DoLoadLevel(boolean resetplayer) if (gamestate == GS_INTERMISSION) Y_EndIntermission(); + // cleanup + if (titlemapinaction == TITLEMAP_LOADING) + { + if (W_CheckNumForName(G_BuildMapName(gamemap)) == LUMPERROR) + { + titlemap = 0; // let's not infinite recursion ok + Command_ExitGame_f(); + return; + } + + titlemapinaction = TITLEMAP_RUNNING; + } + else + titlemapinaction = TITLEMAP_OFF; + G_SetGamestate(GS_LEVEL); for (i = 0; i < MAXPLAYERS; i++) @@ -1711,7 +1684,7 @@ void G_DoLoadLevel(boolean resetplayer) } // Setup the level. - if (!P_SetupLevel(false)) + if (!P_SetupLevel(false)) // this never returns false? { // fail so reset game stuff Command_ExitGame_f(); @@ -1749,7 +1722,8 @@ void G_DoLoadLevel(boolean resetplayer) CON_ClearHUD(); } -static INT32 pausedelay = 0; +INT32 pausedelay = 0; +boolean pausebreakkey = false; static INT32 camtoggledelay, camtoggledelay2 = 0; // @@ -1868,7 +1842,6 @@ boolean G_Responder(event_t *ev) return true; } } - else if (gamestate == GS_CREDITS) { if (HU_Responder(ev)) @@ -1882,17 +1855,15 @@ boolean G_Responder(event_t *ev) return true; } } - else if (gamestate == GS_CONTINUING) { if (F_ContinueResponder(ev)) return true; } // Demo End - else if (gamestate == GS_GAMEEND || gamestate == GS_EVALUATION || gamestate == GS_CREDITS) + else if (gamestate == GS_GAMEEND) return true; - - else if (gamestate == GS_INTERMISSION) + else if (gamestate == GS_INTERMISSION || gamestate == GS_EVALUATION) if (HU_Responder(ev)) return true; // chat ate the event @@ -1906,17 +1877,32 @@ boolean G_Responder(event_t *ev) || ev->data1 == gamecontrol[gc_pause][1] || ev->data1 == KEY_PAUSE) { - if (!pausedelay) + if (modeattacking && !demoplayback && (gamestate == GS_LEVEL)) { - // don't let busy scripts prevent pausing - pausedelay = NEWTICRATE/7; + pausebreakkey = (ev->data1 == KEY_PAUSE); + if (menuactive || pausedelay < 0 || leveltime < 2) + return true; - // command will handle all the checks for us - COM_ImmedExecute("pause"); - return true; + if (pausedelay < 1+(NEWTICRATE/2)) + pausedelay = 1+(NEWTICRATE/2); + else if (++pausedelay > 1+(NEWTICRATE/2)+(NEWTICRATE/3)) + { + G_SetRetryFlag(); + return true; + } + pausedelay++; // counteract subsequent subtraction this frame } else - pausedelay = NEWTICRATE/7; + { + INT32 oldpausedelay = pausedelay; + pausedelay = (NEWTICRATE/7); + if (!oldpausedelay) + { + // command will handle all the checks for us + COM_ImmedExecute("pause"); + return true; + } + } } if (ev->data1 == gamecontrol[gc_camtoggle][0] || ev->data1 == gamecontrol[gc_camtoggle][1]) @@ -1976,11 +1962,19 @@ void G_Ticker(boolean run) { G_ClearRetryFlag(); - // Costs a life to retry ... unless the player in question is dead already. - if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE) - players[consoleplayer].lives -= 1; + if (modeattacking) + { + pausedelay = INT32_MIN; + M_ModeAttackRetry(0); + } + else + { + // Costs a life to retry ... unless the player in question is dead already. + if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != INFLIVES) + players[consoleplayer].lives -= 1; - G_DoReborn(consoleplayer); + G_DoReborn(consoleplayer); + } } for (i = 0; i < MAXPLAYERS; i++) @@ -2018,6 +2012,7 @@ void G_Ticker(boolean run) F_TitleDemoTicker(); P_Ticker(run); // tic the game ST_Ticker(); + F_TextPromptTicker(); AM_Ticker(); HU_Ticker(); break; @@ -2029,6 +2024,7 @@ void G_Ticker(boolean run) break; case GS_TIMEATTACK: + F_MenuPresTicker(run); break; case GS_INTRO: @@ -2050,6 +2046,7 @@ void G_Ticker(boolean run) case GS_EVALUATION: if (run) F_GameEvaluationTicker(); + HU_Ticker(); break; case GS_CONTINUING: @@ -2064,7 +2061,10 @@ void G_Ticker(boolean run) break; case GS_TITLESCREEN: + if (titlemapinaction) P_Ticker(run); // then intentionally fall through + /* FALLTHRU */ case GS_WAITINGPLAYERS: + F_MenuPresTicker(run); F_TitleScreenTicker(run); break; @@ -2075,8 +2075,13 @@ void G_Ticker(boolean run) if (run) { - if (pausedelay) - pausedelay--; + if (pausedelay && pausedelay != INT32_MIN) + { + if (pausedelay > 0) + pausedelay--; + else + pausedelay++; + } if (camtoggledelay) camtoggledelay--; @@ -2127,6 +2132,8 @@ void G_PlayerReborn(INT32 player) INT32 score; INT32 lives; INT32 continues; + fixed_t camerascale; + fixed_t shieldscale; UINT8 charability; UINT8 charability2; fixed_t normalspeed; @@ -2139,6 +2146,7 @@ void G_PlayerReborn(INT32 player) UINT32 thokitem; UINT32 spinitem; UINT32 revitem; + UINT32 followitem; fixed_t actionspd; fixed_t mindash; fixed_t maxdash; @@ -2150,6 +2158,8 @@ void G_PlayerReborn(INT32 player) INT32 starpostnum; INT32 starpostangle; fixed_t jumpfactor; + fixed_t height; + fixed_t spinheight; INT32 exiting; INT16 numboxes; INT16 totalring; @@ -2157,8 +2167,10 @@ void G_PlayerReborn(INT32 player) UINT8 mare; UINT8 skincolor; INT32 skin; + UINT32 availabilities; tic_t jointime; boolean spectator; + boolean outofcoop; INT16 bot; SINT8 pity; @@ -2169,7 +2181,8 @@ void G_PlayerReborn(INT32 player) exiting = players[player].exiting; jointime = players[player].jointime; spectator = players[player].spectator; - pflags = (players[player].pflags & (PF_TIMEOVER|PF_FLIPCAM|PF_TAGIT|PF_TAGGED|PF_ANALOGMODE)); + outofcoop = players[player].outofcoop; + pflags = (players[player].pflags & (PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE|PF_TAGIT|PF_GAMETYPEOVER)); // As long as we're not in multiplayer, carry over cheatcodes from map to map if (!(netgame || multiplayer)) @@ -2181,6 +2194,9 @@ void G_PlayerReborn(INT32 player) skincolor = players[player].skincolor; skin = players[player].skin; + availabilities = players[player].availabilities; + camerascale = players[player].camerascale; + shieldscale = players[player].shieldscale; charability = players[player].charability; charability2 = players[player].charability2; normalspeed = players[player].normalspeed; @@ -2197,9 +2213,12 @@ void G_PlayerReborn(INT32 player) starpostnum = players[player].starpostnum; starpostangle = players[player].starpostangle; jumpfactor = players[player].jumpfactor; + height = players[player].height; + spinheight = players[player].spinheight; thokitem = players[player].thokitem; spinitem = players[player].spinitem; revitem = players[player].revitem; + followitem = players[player].followitem; actionspd = players[player].actionspd; mindash = players[player].mindash; maxdash = players[player].maxdash; @@ -2218,10 +2237,14 @@ void G_PlayerReborn(INT32 player) p->ctfteam = ctfteam; p->jointime = jointime; p->spectator = spectator; + p->outofcoop = outofcoop; // save player config truth reborn p->skincolor = skincolor; p->skin = skin; + p->availabilities = availabilities; + p->camerascale = camerascale; + p->shieldscale = shieldscale; p->charability = charability; p->charability2 = charability2; p->normalspeed = normalspeed; @@ -2233,6 +2256,7 @@ void G_PlayerReborn(INT32 player) p->thokitem = thokitem; p->spinitem = spinitem; p->revitem = revitem; + p->followitem = followitem; p->actionspd = actionspd; p->mindash = mindash; p->maxdash = maxdash; @@ -2244,6 +2268,8 @@ void G_PlayerReborn(INT32 player) p->starpostnum = starpostnum; p->starpostangle = starpostangle; p->jumpfactor = jumpfactor; + p->height = height; + p->spinheight = spinheight; p->exiting = exiting; p->numboxes = numboxes; @@ -2261,11 +2287,11 @@ void G_PlayerReborn(INT32 player) p->pflags |= PF_JUMPDOWN; p->playerstate = PST_LIVE; - p->health = 1; // 0 rings + p->rings = p->spheres = 0; // 0 rings p->panim = PA_IDLE; // standing animation - if ((netgame || multiplayer) && !p->spectator) - p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent + //if ((netgame || multiplayer) && !p->spectator) -- moved into P_SpawnPlayer to account for forced changes there + //p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent if (p-players == consoleplayer) { @@ -2297,6 +2323,8 @@ void G_PlayerReborn(INT32 player) if (p->mare == 255) p->mare = 0; + p->marelap = p->marebonuslap = 0; + // Check to make sure their color didn't change somehow... if (G_GametypeHasTeams()) { @@ -2370,6 +2398,8 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost) P_SpawnPlayer(playernum); + players[playernum].rings = mapheaderinfo[gamemap-1]->startrings; + if (starpost) //Don't even bother with looking for a place to spawn. { P_MovePlayerToStarpost(playernum); @@ -2559,7 +2589,8 @@ void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo) void G_DoReborn(INT32 playernum) { player_t *player = &players[playernum]; - boolean starpost = false; + boolean resetlevel = false; + INT32 i; if (modeattacking) { @@ -2585,35 +2616,98 @@ void G_DoReborn(INT32 playernum) B_RespawnBot(playernum); if (oldmo) G_ChangePlayerReferences(oldmo, players[playernum].mo); + + return; + } + + if (countdowntimeup || (!(netgame || multiplayer) && gametype == GT_COOP)) + resetlevel = true; + else if (gametype == GT_COOP && (netgame || multiplayer)) + { + boolean notgameover = true; + + if (cv_cooplives.value != 0 && player->lives <= 0) // consider game over first + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + if (players[i].exiting || players[i].lives > 0) + break; + } + + if (i == MAXPLAYERS) + { + notgameover = false; + if (!countdown2) + { + // They're dead, Jim. + //nextmapoverride = spstage_start; + nextmapoverride = gamemap; + countdown2 = TICRATE; + skipstats = true; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i]) + players[i].score = 0; + } + + //emeralds = 0; + tokenbits = 0; + tokenlist = 0; + token = 0; + } + } + } + + if (notgameover && cv_coopstarposts.value == 2) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].playerstate != PST_DEAD && !players[i].spectator && players[i].mo && players[i].mo->health) + break; + } + if (i == MAXPLAYERS) + resetlevel = true; + } } - else if (countdowntimeup || (!multiplayer && gametype == GT_COOP)) + + if (resetlevel) { // reload the level from scratch if (countdowntimeup) { - player->starpostangle = 0; - player->starposttime = 0; - player->starpostx = 0; - player->starposty = 0; - player->starpostz = 0; - player->starpostnum = 0; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + players[i].starpostangle = 0; + players[i].starposttime = 0; + players[i].starpostx = 0; + players[i].starposty = 0; + players[i].starpostz = 0; + players[i].starpostnum = 0; + } } if (!countdowntimeup && (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD)) { - INT32 i; - - player->playerstate = PST_REBORN; - P_LoadThingsOnly(); - P_ClearStarPost(player->starpostnum); + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + players[i].playerstate = PST_REBORN; + P_ClearStarPost(players[i].starpostnum); + } // Do a wipe wipegamestate = -1; - if (player->starposttime) - starpost = true; - if (camera.chase) P_ResetCamera(&players[displayplayer], &camera); if (camera2.chase && splitscreen) @@ -2621,7 +2715,7 @@ void G_DoReborn(INT32 playernum) // clear cmd building stuff memset(gamekeydown, 0, sizeof (gamekeydown)); - for (i = 0;i < JOYAXISSET; i++) + for (i = 0; i < JOYAXISSET; i++) { joyxmove[i] = joyymove[i] = 0; joy2xmove[i] = joy2ymove[i] = 0; @@ -2633,12 +2727,24 @@ void G_DoReborn(INT32 playernum) CON_ClearHUD(); // Starpost support - G_SpawnPlayer(playernum, starpost); + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + G_SpawnPlayer(i, (players[i].starposttime)); + } - if (botingame) - { // Bots respawn next to their master. - players[secondarydisplayplayer].playerstate = PST_REBORN; - G_SpawnPlayer(secondarydisplayplayer, false); + // restore time in netgame (see also p_setup.c) + if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2) + { + // is this a hack? maybe + tic_t maxstarposttime = 0; + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && players[i].starposttime > maxstarposttime) + maxstarposttime = players[i].starposttime; + } + leveltime = maxstarposttime; } } else @@ -2647,6 +2753,7 @@ void G_DoReborn(INT32 playernum) LUAh_MapChange(gamemap); #endif G_DoLoadLevel(true); + return; } } else @@ -2654,8 +2761,11 @@ void G_DoReborn(INT32 playernum) // respawn at the start mobj_t *oldmo = NULL; - if (player->starposttime) - starpost = true; + // Not resetting map, so return to level music + if (!countdown2 + && player->lives <= 0 + && cv_cooplives.value == 1) // not allowed for life steal because no way to come back from zero group lives without addons, which should call this anyways + P_RestoreMultiMusic(player); // first dissasociate the corpse if (player->mo) @@ -2665,7 +2775,7 @@ void G_DoReborn(INT32 playernum) P_RemoveMobj(player->mo); } - G_SpawnPlayer(playernum, starpost); + G_SpawnPlayer(playernum, (player->starposttime)); if (oldmo) G_ChangePlayerReferences(oldmo, players[playernum].mo); } @@ -2673,10 +2783,49 @@ void G_DoReborn(INT32 playernum) void G_AddPlayer(INT32 playernum) { + INT32 countplayers = 0, notexiting = 0; + player_t *p = &players[playernum]; + // Go through the current players and make sure you have the latest starpost set + if (G_PlatformGametype() && (netgame || multiplayer)) + { + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].bot) // ignore dumb, stupid tails + continue; + + countplayers++; + + if (!players->exiting) + notexiting++; + + if (!(cv_coopstarposts.value && (gametype == GT_COOP) && (p->starpostnum < players[i].starpostnum))) + continue; + + p->starposttime = players[i].starposttime; + p->starpostx = players[i].starpostx; + p->starposty = players[i].starposty; + p->starpostz = players[i].starpostz; + p->starpostangle = players[i].starpostangle; + p->starpostnum = players[i].starpostnum; + } + } + p->jointime = 0; p->playerstate = PST_REBORN; + + p->height = mobjinfo[MT_PLAYER].height; + + if (G_GametypeUsesLives() || ((netgame || multiplayer) && gametype == GT_COOP)) + p->lives = cv_startinglives.value; + + if (countplayers && !notexiting) + P_DoPlayerExit(p); } void G_ExitLevel(void) @@ -2717,7 +2866,7 @@ const char *Gametype_Names[NUMGAMETYPES] = "Team Match", // GT_TEAMMATCH "Tag", // GT_TAG - "Hide and Seek", // GT_HIDEANDSEEK + "Hide & Seek", // GT_HIDEANDSEEK "CTF" // GT_CTF }; @@ -2746,7 +2895,11 @@ INT32 G_GetGametypeByName(const char *gametypestr) // boolean G_IsSpecialStage(INT32 mapnum) { - if (gametype == GT_COOP && modeattacking != ATTACKING_RECORD && mapnum >= sstage_start && mapnum <= sstage_end) + if (gametype != GT_COOP || modeattacking == ATTACKING_RECORD) + return false; + if (mapnum >= sstage_start && mapnum <= sstage_end) + return true; + if (mapnum >= smpstage_start && mapnum <= smpstage_end) return true; return false; @@ -2882,10 +3035,12 @@ static INT16 RandMap(INT16 tolflags, INT16 pprevmap) static void G_DoCompleted(void) { INT32 i; - boolean gottoken = false; tokenlist = 0; // Reset the list + if (modeattacking && pausedelay) + pausedelay = 0; + gameaction = ga_nothing; if (metalplayback) @@ -2968,26 +3123,18 @@ static void G_DoCompleted(void) if (nextmap >= 1100-1 && nextmap <= 1102-1 && (gametype == GT_RACE || gametype == GT_COMPETITION)) nextmap = (INT16)(spstage_start-1); - if (gametype == GT_COOP && token) + if ((gottoken = (gametype == GT_COOP && token))) { token--; - gottoken = true; - - if (!(emeralds & EMERALD1)) - nextmap = (INT16)(sstage_start - 1); // Special Stage 1 - else if (!(emeralds & EMERALD2)) - nextmap = (INT16)(sstage_start); // Special Stage 2 - else if (!(emeralds & EMERALD3)) - nextmap = (INT16)(sstage_start + 1); // Special Stage 3 - else if (!(emeralds & EMERALD4)) - nextmap = (INT16)(sstage_start + 2); // Special Stage 4 - else if (!(emeralds & EMERALD5)) - nextmap = (INT16)(sstage_start + 3); // Special Stage 5 - else if (!(emeralds & EMERALD6)) - nextmap = (INT16)(sstage_start + 4); // Special Stage 6 - else if (!(emeralds & EMERALD7)) - nextmap = (INT16)(sstage_start + 5); // Special Stage 7 - else + + for (i = 0; i < 7; i++) + if (!(emeralds & (1<<i))) + { + nextmap = ((netgame || multiplayer) ? smpstage_start : sstage_start) + i - 1; // to special stage! + break; + } + + if (i == 7) gottoken = false; } @@ -3108,8 +3255,11 @@ static void G_DoContinued(void) tokenlist = 0; token = 0; + if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) && (!modifiedgame || savemoddata) && cursaveslot > 0) + G_SaveGameOver((UINT32)cursaveslot, true); + // Reset # of lives - pl->lives = (ultimatemode) ? 1 : 3; + pl->lives = (ultimatemode) ? 1 : startinglivesbalance[numgameovers]; D_MapChange(gamemap, gametype, ultimatemode, false, 0, false, false); @@ -3156,9 +3306,9 @@ void G_LoadGameSettings(void) { // defaults spstage_start = 1; - sstage_start = 50; - sstage_end = 57; // 8 special stages in vanilla SRB2 - useNightsSS = false; //true; + sstage_start = smpstage_start = 50; + sstage_end = smpstage_end = 56; // 7 special stages in vanilla SRB2 + sstage_end++; // plus one weirdo // initialize free sfx slots for skin sounds S_InitRuntimeSounds(); @@ -3363,7 +3513,7 @@ void G_SaveGameData(void) // TODO put another cipher on these things? meh, I don't care... for (i = 0; i < NUMMAPS; i++) - WRITEUINT8(save_p, mapvisited[i]); + WRITEUINT8(save_p, (mapvisited[i] & MV_MAX)); // To save space, use one bit per collected/achieved/unlocked flag for (i = 0; i < MAXEMBLEMS;) @@ -3448,59 +3598,6 @@ void G_SaveGameData(void) #define VERSIONSIZE 16 -#ifdef SAVEGAMES_OTHERVERSIONS -static INT16 startonmapnum = 0; - -// -// User wants to load a savegame from a different version? -// -static void M_ForceLoadGameResponse(INT32 ch) -{ - if (ch != 'y' && ch != KEY_ENTER) - { - //refused - Z_Free(savebuffer); - save_p = savebuffer = NULL; - startonmapnum = 0; - M_SetupNextMenu(&SP_LoadDef); - return; - } - - // pick up where we left off. - save_p += VERSIONSIZE; - if (!P_LoadGame(startonmapnum)) - { - M_ClearMenus(true); // so ESC backs out to title - M_StartMessage(M_GetText("Savegame file corrupted\n\nPress ESC\n"), NULL, MM_NOTHING); - Command_ExitGame_f(); - Z_Free(savebuffer); - save_p = savebuffer = NULL; - startonmapnum = 0; - - // no cheating! - memset(&savedata, 0, sizeof(savedata)); - return; - } - - // done - Z_Free(savebuffer); - save_p = savebuffer = NULL; - startonmapnum = 0; - - //set cursaveslot to -1 so nothing gets saved. - cursaveslot = -1; - - displayplayer = consoleplayer; - multiplayer = splitscreen = false; - - if (setsizeneeded) - R_ExecuteSetViewSize(); - - M_ClearMenus(true); - CON_ToggleOff(); -} -#endif - // // G_InitFromSavegame // Can be called by the startup code or the menu task. @@ -3593,13 +3690,13 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride) // G_SaveGame // Saves your game. // -void G_SaveGame(UINT32 savegameslot) +void G_SaveGame(UINT32 slot) { boolean saved; char savename[256] = ""; const char *backup; - sprintf(savename, savegamename, savegameslot); + sprintf(savename, savegamename, slot); backup = va("%s",savename); // save during evaluation or credits? game's over, folks! @@ -3635,9 +3732,91 @@ void G_SaveGame(UINT32 savegameslot) if (cv_debug && saved) CONS_Printf(M_GetText("Game saved.\n")); else if (!saved) - CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, savegameslot, savegamename); + CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, savegamename); } +#define BADSAVE goto cleanup; +#define CHECKPOS if (save_p >= end_p) BADSAVE +void G_SaveGameOver(UINT32 slot, boolean modifylives) +{ + boolean saved = false; + size_t length; + char vcheck[VERSIONSIZE]; + char savename[255]; + const char *backup; + + sprintf(savename, savegamename, slot); + backup = va("%s",savename); + + length = FIL_ReadFile(savename, &savebuffer); + if (!length) + { + CONS_Printf(M_GetText("Couldn't read file %s\n"), savename); + return; + } + + { + char temp[sizeof(timeattackfolder)]; + UINT8 *end_p = savebuffer + length; + UINT8 *lives_p; + SINT8 pllives; + + save_p = savebuffer; + // Version check + memset(vcheck, 0, sizeof (vcheck)); + sprintf(vcheck, "version %d", VERSION); + if (strcmp((const char *)save_p, (const char *)vcheck)) BADSAVE + save_p += VERSIONSIZE; + + // P_UnArchiveMisc() + (void)READINT16(save_p); + CHECKPOS + (void)READUINT16(save_p); // emeralds + CHECKPOS + READSTRINGN(save_p, temp, sizeof(temp)); // mod it belongs to + if (strcmp(temp, timeattackfolder)) BADSAVE + + // P_UnArchivePlayer() + CHECKPOS + (void)READUINT16(save_p); + CHECKPOS + + WRITEUINT8(save_p, numgameovers); + CHECKPOS + + lives_p = save_p; + pllives = READSINT8(save_p); // lives + CHECKPOS + if (modifylives && pllives < startinglivesbalance[numgameovers]) + { + pllives = startinglivesbalance[numgameovers]; + WRITESINT8(lives_p, pllives); + } + + (void)READINT32(save_p); // Score + CHECKPOS + (void)READINT32(save_p); // continues + + // File end marker check + CHECKPOS + if (READUINT8(save_p) != 0x1d) BADSAVE; + + // done + saved = FIL_WriteFile(backup, savebuffer, length); + } + +cleanup: + if (cv_debug && saved) + CONS_Printf(M_GetText("Game saved.\n")); + else if (!saved) + CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, savegamename); + Z_Free(savebuffer); + save_p = savebuffer = NULL; + +} +#undef CHECKPOS +#undef BADSAVE + // // G_DeferedInitNew // Can be called by the startup code or the menu task, @@ -3645,7 +3824,7 @@ void G_SaveGame(UINT32 savegameslot) // void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, boolean SSSG, boolean FLS) { - UINT8 color = 0; + UINT8 color = skins[pickedchar].prefcolor; paused = false; if (demoplayback) @@ -3657,10 +3836,8 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, b if (savedata.lives > 0) { - color = savedata.skincolor; - botskin = savedata.botskin; - botcolor = savedata.botcolor; - botingame = (botskin != 0); + if ((botingame = ((botskin = savedata.botskin) != 0))) + botcolor = skins[botskin-1].prefcolor; } else if (splitscreen != SSSG) { @@ -3668,8 +3845,7 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, b SplitScreen_OnChange(); } - if (!color) - color = skins[pickedchar].prefcolor; + color = skins[pickedchar].prefcolor; SetPlayerSkinByNum(consoleplayer, pickedchar); CV_StealthSet(&cv_skin, skins[pickedchar].name); CV_StealthSetValue(&cv_playercolor, color); @@ -3682,7 +3858,7 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, b // This is the map command interpretation something like Command_Map_f // // called at: map cmd execution, doloadgame, doplaydemo -void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean skipprecutscene) +void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean skipprecutscene, boolean FLS) { INT32 i; @@ -3701,7 +3877,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean if (resetplayer) { // Clear a bunch of variables - tokenlist = token = sstimer = redscore = bluescore = lastmap = 0; + numgameovers = tokenlist = token = sstimer = redscore = bluescore = lastmap = 0; countdown = countdown2 = exitfadestarted = 0; for (i = 0; i < MAXPLAYERS; i++) @@ -3712,27 +3888,26 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean if (netgame || multiplayer) { - players[i].lives = cv_startinglives.value; - players[i].continues = 0; - } - else if (pultmode) - { - players[i].lives = 1; + if (!FLS || (players[i].lives < 1)) + players[i].lives = cv_startinglives.value; players[i].continues = 0; } else { - players[i].lives = 3; - players[i].continues = 1; + players[i].lives = (pultmode) ? 1 : startinglivesbalance[0]; + players[i].continues = (pultmode) ? 0 : 1; } + if (!((netgame || multiplayer) && (FLS))) + players[i].score = 0; + // The latter two should clear by themselves, but just in case - players[i].pflags &= ~(PF_TAGIT|PF_TAGGED|PF_FULLSTASIS); + players[i].pflags &= ~(PF_TAGIT|PF_GAMETYPEOVER|PF_FULLSTASIS); // Clear cheatcodes too, just in case. players[i].pflags &= ~(PF_GODMODE|PF_NOCLIP|PF_INVIS); - players[i].score = players[i].xtralife = 0; + players[i].xtralife = 0; } // Reset unlockable triggers @@ -3794,6 +3969,9 @@ char *G_BuildMapTitle(INT32 mapnum) { char *title = NULL; + if (!mapheaderinfo[mapnum-1]) + P_AllocMapHeader(mapnum-1); + if (strcmp(mapheaderinfo[mapnum-1]->lvlttl, "")) { size_t len = 1; @@ -3823,7 +4001,7 @@ char *G_BuildMapTitle(INT32 mapnum) // DEMO RECORDING // -#define DEMOVERSION 0x0009 +#define DEMOVERSION 0x000a #define DEMOHEADER "\xF0" "SRB2Replay" "\x0F" #define DF_GHOST 0x01 // This demo contains ghost data too! @@ -3848,9 +4026,10 @@ static ticcmd_t oldcmd; #define GZT_MOMZ 0x04 #define GZT_ANGLE 0x08 // Not used for Metal Sonic -#define GZT_SPRITE 0x10 // Animation frame -#define GZT_EXTRA 0x20 -#define GZT_NIGHTS 0x40 // NiGHTS Mode stuff! +#define GZT_FRAME 0x10 // Animation frame +#define GZT_SPR2 0x20 // Player animations +#define GZT_EXTRA 0x40 +#define GZT_FOLLOW 0x80 // Followmobj // GZT_EXTRA flags #define EZT_THOK 0x01 // Spawned a thok object @@ -3862,6 +4041,7 @@ static ticcmd_t oldcmd; #define EZT_SCALE 0x10 // Changed size #define EZT_HIT 0x20 // Damaged a mobj #define EZT_SPRITE 0x40 // Changed sprite set completely out of PLAY (NiGHTS, SOCs, whatever) +// spare EZT slot 0x80 static mobj_t oldmetal, oldghost; @@ -4054,21 +4234,12 @@ void G_WriteGhostTic(mobj_t *ghost) char ziptic = 0; UINT8 *ziptic_p; UINT32 i; - UINT8 sprite; - UINT8 frame; if (!demo_p) return; if (!(demoflags & DF_GHOST)) return; // No ghost data to write. - if (ghost->player && ghost->player->pflags & PF_NIGHTSMODE && ghost->tracer) - { - // We're talking about the NiGHTS thing, not the normal platforming thing! - ziptic |= GZT_NIGHTS; - ghost = ghost->tracer; - } - ziptic_p = demo_p++; // the ziptic, written at the end of this function #define MAXMOM (0xFFFF<<8) @@ -4122,27 +4293,33 @@ void G_WriteGhostTic(mobj_t *ghost) // Only store the 8 most relevant bits of angle // because exact values aren't too easy to discern to begin with when only 8 angles have different sprites // and it does not affect this mode of movement at all anyway. - if (ghost->angle>>24 != oldghost.angle) + if (ghost->player && ghost->player->drawangle>>24 != oldghost.angle) { - oldghost.angle = ghost->angle>>24; + oldghost.angle = ghost->player->drawangle>>24; ziptic |= GZT_ANGLE; WRITEUINT8(demo_p,oldghost.angle); } // Store the sprite frame. - frame = ghost->frame & 0xFF; - if (frame != oldghost.frame) + if ((ghost->frame & FF_FRAMEMASK) != oldghost.frame) { - oldghost.frame = frame; - ziptic |= GZT_SPRITE; + oldghost.frame = (ghost->frame & FF_FRAMEMASK); + ziptic |= GZT_FRAME; WRITEUINT8(demo_p,oldghost.frame); } + if (ghost->sprite == SPR_PLAY + && ghost->sprite2 != oldghost.sprite2) + { + oldghost.sprite2 = ghost->sprite2; + ziptic |= GZT_SPR2; + WRITEUINT8(demo_p,oldghost.sprite2); + } + // Check for sprite set changes - sprite = ghost->sprite; - if (sprite != oldghost.sprite) + if (ghost->sprite != oldghost.sprite) { - oldghost.sprite = sprite; + oldghost.sprite = ghost->sprite; ghostext.flags |= EZT_SPRITE; } @@ -4172,7 +4349,7 @@ void G_WriteGhostTic(mobj_t *ghost) for (i = 0; i < ghostext.hits; i++) { mobj_t *mo = ghostext.hitlist[i]; - WRITEUINT32(demo_p,UINT32_MAX); // reserved for some method of determining exactly which mobj this is. (mobjnum doesn't work here.) + //WRITEUINT32(demo_p,UINT32_MAX); // reserved for some method of determining exactly which mobj this is. (mobjnum doesn't work here.) WRITEUINT32(demo_p,mo->type); WRITEUINT16(demo_p,(UINT16)mo->health); WRITEFIXED(demo_p,mo->x); @@ -4185,15 +4362,32 @@ void G_WriteGhostTic(mobj_t *ghost) ghostext.hitlist = NULL; } if (ghostext.flags & EZT_SPRITE) - WRITEUINT8(demo_p,sprite); + WRITEUINT8(demo_p,oldghost.sprite); ghostext.flags = 0; } + if (ghost->player && ghost->player->followmobj) + { + INT16 temp; + + ziptic |= GZT_FOLLOW; + + temp = (INT16)((ghost->player->followmobj->x-ghost->x)>>8); + WRITEINT16(demo_p,temp); + temp = (INT16)((ghost->player->followmobj->y-ghost->y)>>8); + WRITEINT16(demo_p,temp); + temp = (INT16)((ghost->player->followmobj->z-ghost->z)>>8); + WRITEINT16(demo_p,temp); + WRITEUINT8(demo_p,ghost->player->followmobj->sprite); + WRITEUINT8(demo_p,ghost->player->followmobj->sprite2); + WRITEUINT8(demo_p,(ghost->player->followmobj->frame & FF_FRAMEMASK)); + } + *ziptic_p = ziptic; // attention here for the ticcmd size! // latest demos with mouse aiming byte in ticcmd - if (demo_p >= demoend - (13 + 9)) + if (demo_p >= demoend - (13 + 9 + 9)) { G_CheckDemoStatus(); // no more space return; @@ -4207,7 +4401,6 @@ void G_ConsGhostTic(void) UINT8 ziptic; UINT16 px,py,pz,gx,gy,gz; mobj_t *testmo; - boolean nightsfail = false; if (!demo_p || !demo_start) return; @@ -4239,23 +4432,19 @@ void G_ConsGhostTic(void) } if (ziptic & GZT_ANGLE) demo_p++; - if (ziptic & GZT_SPRITE) + if (ziptic & GZT_FRAME) + demo_p++; + if (ziptic & GZT_SPR2) demo_p++; - if(ziptic & GZT_NIGHTS) { - if (!testmo->player || !(testmo->player->pflags & PF_NIGHTSMODE) || !testmo->tracer) - nightsfail = true; - else - testmo = testmo->tracer; - } if (ziptic & GZT_EXTRA) { // But wait, there's more! - ziptic = READUINT8(demo_p); - if (ziptic & EZT_COLOR) + UINT8 xziptic = READUINT8(demo_p); + if (xziptic & EZT_COLOR) demo_p++; - if (ziptic & EZT_SCALE) + if (xziptic & EZT_SCALE) demo_p += sizeof(fixed_t); - if (ziptic & EZT_HIT) + if (xziptic & EZT_HIT) { // Resync mob damage. UINT16 i, count = READUINT16(demo_p); thinker_t *th; @@ -4269,7 +4458,7 @@ void G_ConsGhostTic(void) for (i = 0; i < count; i++) { - demo_p += 4; // reserved. + //demo_p += 4; // reserved. type = READUINT32(demo_p); health = READUINT16(demo_p); x = READFIXED(demo_p); @@ -4292,14 +4481,24 @@ void G_ConsGhostTic(void) if (demosynced) CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); demosynced = false; - P_DamageMobj(mobj, players[0].mo, players[0].mo, 1); + P_DamageMobj(mobj, players[0].mo, players[0].mo, 1, 0); } } } - if (ziptic & EZT_SPRITE) + if (xziptic & EZT_SPRITE) demo_p++; } + if (ziptic & GZT_FOLLOW) + { // Even more... + demo_p += sizeof(INT16); + demo_p += sizeof(INT16); + demo_p += sizeof(INT16); + demo_p++; + demo_p++; + demo_p++; + } + // Re-synchronise px = testmo->x>>FRACBITS; py = testmo->y>>FRACBITS; @@ -4308,7 +4507,7 @@ void G_ConsGhostTic(void) gy = oldghost.y>>FRACBITS; gz = oldghost.z>>FRACBITS; - if (nightsfail || px != gx || py != gy || pz != gz) + if (px != gx || py != gy || pz != gz) { if (demosynced) CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); @@ -4336,6 +4535,7 @@ void G_GhostTicker(void) { // Skip normal demo data. UINT8 ziptic = READUINT8(g->p); + UINT8 xziptic = 0; if (ziptic & ZT_FWD) g->p++; if (ziptic & ZT_SIDE) @@ -4369,9 +4569,11 @@ void G_GhostTicker(void) g->oldmo.z += g->oldmo.momz; } if (ziptic & GZT_ANGLE) - g->oldmo.angle = READUINT8(g->p)<<24; - if (ziptic & GZT_SPRITE) + g->mo->angle = READUINT8(g->p)<<24; + if (ziptic & GZT_FRAME) g->oldmo.frame = READUINT8(g->p); + if (ziptic & GZT_SPR2) + g->oldmo.sprite2 = READUINT8(g->p); // Update ghost P_UnsetThingPosition(g->mo); @@ -4379,13 +4581,13 @@ void G_GhostTicker(void) g->mo->y = g->oldmo.y; g->mo->z = g->oldmo.z; P_SetThingPosition(g->mo); - g->mo->angle = g->oldmo.angle; g->mo->frame = g->oldmo.frame | tr_trans30<<FF_TRANSSHIFT; + g->mo->sprite2 = g->oldmo.sprite2; if (ziptic & GZT_EXTRA) { // But wait, there's more! - ziptic = READUINT8(g->p); - if (ziptic & EZT_COLOR) + xziptic = READUINT8(g->p); + if (xziptic & EZT_COLOR) { g->color = READUINT8(g->p); switch(g->color) @@ -4403,22 +4605,22 @@ void G_GhostTicker(void) break; } } - if (ziptic & EZT_FLIP) + if (xziptic & EZT_FLIP) g->mo->eflags ^= MFE_VERTICALFLIP; - if (ziptic & EZT_SCALE) + if (xziptic & EZT_SCALE) { g->mo->destscale = READFIXED(g->p); if (g->mo->destscale != g->mo->scale) P_SetScale(g->mo, g->mo->destscale); } - if (ziptic & EZT_THOKMASK) + if (xziptic & EZT_THOKMASK) { // Let's only spawn ONE of these per frame, thanks. mobj_t *mobj; INT32 type = -1; if (g->mo->skin) { skin_t *skin = (skin_t *)g->mo->skin; - switch (ziptic & EZT_THOKMASK) + switch (xziptic & EZT_THOKMASK) { case EZT_THOK: type = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem; @@ -4459,7 +4661,7 @@ void G_GhostTicker(void) mobj->fuse = 8; P_SetTarget(&mobj->target, g->mo); } - if (ziptic & EZT_HIT) + if (xziptic & EZT_HIT) { // Spawn hit poofs for killing things! UINT16 i, count = READUINT16(g->p), health; UINT32 type; @@ -4468,7 +4670,7 @@ void G_GhostTicker(void) mobj_t *poof; for (i = 0; i < count; i++) { - g->p += 4; // reserved + //g->p += 4; // reserved type = READUINT32(g->p); health = READUINT16(g->p); x = READFIXED(g->p); @@ -4486,24 +4688,78 @@ void G_GhostTicker(void) P_SetMobjStateNF(poof, S_XPLD1); } } - if (ziptic & EZT_SPRITE) + if (xziptic & EZT_SPRITE) g->mo->sprite = READUINT8(g->p); } // Tick ghost colors (Super and Mario Invincibility flashing) switch(g->color) { - case GHC_SUPER: // Super Sonic (P_DoSuperStuff) - g->mo->color = SKINCOLOR_SUPER1; + case GHC_SUPER: // Super (P_DoSuperStuff) + if (g->mo->skin) + { + skin_t *skin = (skin_t *)g->mo->skin; + g->mo->color = skin->supercolor; + } + else + g->mo->color = SKINCOLOR_SUPERGOLD1; g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); break; case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) - g->mo->color = (UINT8)(leveltime % MAXSKINCOLORS); + g->mo->color = (UINT8)(SKINCOLOR_RUBY + (leveltime % (MAXSKINCOLORS - SKINCOLOR_RUBY))); // Passes through all saturated colours break; default: break; } +#define follow g->mo->tracer + if (ziptic & GZT_FOLLOW) + { // Even more... + if (!follow) + { + mobj_t *newmo = P_SpawnMobj(g->mo->x, g->mo->y, g->mo->z, MT_GHOST); + P_SetTarget(&g->mo->tracer, newmo); + P_SetTarget(&newmo->tracer, g->mo); + newmo->skin = g->mo->skin; + newmo->tics = -1; + newmo->flags2 |= MF2_LINKDRAW; + + follow->eflags = (follow->eflags & ~MFE_VERTICALFLIP)|(g->mo->eflags & MFE_VERTICALFLIP); + follow->destscale = g->mo->destscale; + if (follow->destscale != follow->scale) + P_SetScale(follow, follow->destscale); + } + else + { + if (xziptic & EZT_FLIP) + g->mo->eflags ^= MFE_VERTICALFLIP; + if (xziptic & EZT_SCALE) + { + follow->destscale = g->mo->destscale; + if (follow->destscale != follow->scale) + P_SetScale(follow, follow->destscale); + } + } + + P_UnsetThingPosition(follow); + follow->x = g->mo->x + (READINT16(g->p)<<8); + follow->y = g->mo->y + (READINT16(g->p)<<8); + follow->z = g->mo->z + (READINT16(g->p)<<8); + P_SetThingPosition(follow); + follow->sprite = READUINT8(g->p); + follow->sprite2 = READUINT8(g->p); + follow->frame = (READUINT8(g->p)) | tr_trans30<<FF_TRANSSHIFT; + + follow->angle = g->mo->angle; + follow->color = g->mo->color; + } + else if (follow) + { + P_RemoveMobj(follow); + P_SetTarget(&follow, NULL); + } +#undef follow + // Demo ends after ghost data. if (*g->p == DEMOMARKER) { @@ -4551,9 +4807,11 @@ void G_ReadMetalTic(mobj_t *metal) oldmetal.z += oldmetal.momz; } if (ziptic & GZT_ANGLE) - oldmetal.angle = READUINT8(metal_p)<<24; - if (ziptic & GZT_SPRITE) + metal->angle = READUINT8(metal_p)<<24; + if (ziptic & GZT_FRAME) metal_p++; // Currently unused. (Metal Sonic figures out what he's doing his own damn self.) + if (ziptic & GZT_SPR2) + metal_p++; // Set movement, position, and angle // oldmetal contains where you're supposed to be. @@ -4565,7 +4823,6 @@ void G_ReadMetalTic(mobj_t *metal) metal->y = oldmetal.y; metal->z = oldmetal.z; P_SetThingPosition(metal); - metal->angle = oldmetal.angle; if (ziptic & GZT_EXTRA) { // But wait, there's more! @@ -4680,11 +4937,11 @@ void G_WriteMetalTic(mobj_t *metal) // Only store the 8 most relevant bits of angle // because exact values aren't too easy to discern to begin with when only 8 angles have different sprites // and it does not affect movement at all anyway. - if (metal->angle>>24 != oldmetal.angle) + if (metal->player && metal->player->drawangle>>24 != oldmetal.angle) { - oldmetal.angle = metal->angle>>24; - WRITEUINT8(demo_p,oldmetal.angle); + oldmetal.angle = metal->player->drawangle>>24; ziptic |= GZT_ANGLE; + WRITEUINT8(demo_p,oldmetal.angle); } // Metal Sonic does not need our state changes. @@ -4843,12 +5100,37 @@ void G_BeginRecording(void) WRITEUINT8(demo_p,player->thrustfactor); WRITEUINT8(demo_p,player->accelstart); WRITEUINT8(demo_p,player->acceleration); + WRITEUINT8(demo_p,player->height>>FRACBITS); + WRITEUINT8(demo_p,player->spinheight>>FRACBITS); + WRITEUINT8(demo_p,player->camerascale>>FRACBITS); + WRITEUINT8(demo_p,player->shieldscale>>FRACBITS); // Trying to convert it back to % causes demo desync due to precision loss. // Don't do it. WRITEFIXED(demo_p, player->jumpfactor); - // Save netvar data (SONICCD, etc) + // And mobjtype_t is best with UINT32 too... + WRITEUINT32(demo_p, player->followitem); + + // Save pflag data + { + UINT8 buf = 0; + if (player->pflags & PF_FLIPCAM) + buf |= 0x01; + if (player->pflags & PF_ANALOGMODE) + buf |= 0x02; + if (player->pflags & PF_DIRECTIONCHAR) + buf |= 0x04; + if (player->pflags & PF_AUTOBRAKE) + buf |= 0x08; + if (cv_usejoystick.value) + buf |= 0x10; + CV_SetValue(&cv_showinputjoy, !!(cv_usejoystick.value)); + + WRITEUINT8(demo_p,buf); + } + + // Save netvar data CV_SaveNetVars(&demo_p); memset(&oldcmd,0,sizeof(oldcmd)); @@ -4862,7 +5144,7 @@ void G_BeginRecording(void) oldghost.x = player->mo->x; oldghost.y = player->mo->y; oldghost.z = player->mo->z; - oldghost.angle = player->mo->angle; + oldghost.angle = player->mo->angle>>24; // preticker started us gravity flipped if (player->mo->eflags & MFE_VERTICALFLIP) @@ -4895,7 +5177,7 @@ void G_BeginMetal(void) oldmetal.x = mo->x; oldmetal.y = mo->y; oldmetal.z = mo->z; - oldmetal.angle = mo->angle; + oldmetal.angle = mo->angle>>24; } void G_SetDemoTime(UINT32 ptime, UINT32 pscore, UINT16 prings) @@ -4995,8 +5277,6 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) switch(oldversion) // demoversion { case DEMOVERSION: // latest always supported - // compatibility available? - case 0x0008: break; // too old, cannot support. default: @@ -5072,8 +5352,9 @@ void G_DoPlayDemo(char *defdemoname) lumpnum_t l; char skin[17],color[17],*n,*pdemoname; UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration; - UINT32 randseed; - fixed_t actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor; + pflags_t pflags; + UINT32 randseed, followitem; + fixed_t camerascale,shieldscale,actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor,height,spinheight; char msg[1024]; skin[16] = '\0'; @@ -5135,8 +5416,6 @@ void G_DoPlayDemo(char *defdemoname) switch(demoversion) { case DEMOVERSION: // latest always supported - // compatibility available? - case 0x0008: break; // too old, cannot support. default: @@ -5162,10 +5441,7 @@ void G_DoPlayDemo(char *defdemoname) return; } demo_p += 4; // "PLAY" - if (demoversion <= 0x0008) - gamemap = READUINT8(demo_p); - else - gamemap = READINT16(demo_p); + gamemap = READINT16(demo_p); demo_p += 16; // mapmd5 demoflags = READUINT8(demo_p); @@ -5219,7 +5495,27 @@ void G_DoPlayDemo(char *defdemoname) thrustfactor = READUINT8(demo_p); accelstart = READUINT8(demo_p); acceleration = READUINT8(demo_p); + height = (fixed_t)READUINT8(demo_p)<<FRACBITS; + spinheight = (fixed_t)READUINT8(demo_p)<<FRACBITS; + camerascale = (fixed_t)READUINT8(demo_p)<<FRACBITS; + shieldscale = (fixed_t)READUINT8(demo_p)<<FRACBITS; jumpfactor = READFIXED(demo_p); + followitem = READUINT32(demo_p); + + // pflag data + { + UINT8 buf = READUINT8(demo_p); + pflags = 0; + if (buf & 0x01) + pflags |= PF_FLIPCAM; + if (buf & 0x02) + pflags |= PF_ANALOGMODE; + if (buf & 0x04) + pflags |= PF_DIRECTIONCHAR; + if (buf & 0x08) + pflags |= PF_AUTOBRAKE; + CV_SetValue(&cv_showinputjoy, !!(buf & 0x10)); + } // net var data CV_LoadNetVars(&demo_p); @@ -5245,12 +5541,12 @@ void G_DoPlayDemo(char *defdemoname) if (VERSION != version || SUBVERSION != subversion) CONS_Alert(CONS_WARNING, M_GetText("Demo version does not match game version. Desyncs may occur.\n")); - // console warning messages - demosynced = true; - // didn't start recording right away. demo_start = false; + // Set skin + SetPlayerSkin(0, skin); + #ifdef HAVE_BLUA LUAh_MapChange(gamemap); #endif @@ -5258,10 +5554,7 @@ void G_DoPlayDemo(char *defdemoname) memset(playeringame,0,sizeof(playeringame)); playeringame[0] = true; P_SetRandSeed(randseed); - G_InitNew(false, G_BuildMapName(gamemap), true, true); - - // Set skin - SetPlayerSkin(0, skin); + G_InitNew(false, G_BuildMapName(gamemap), true, true, false); // Set color for (i = 0; i < MAXSKINCOLORS; i++) @@ -5282,6 +5575,8 @@ void G_DoPlayDemo(char *defdemoname) // Set saved attribute values // No cheat checking here, because even if they ARE wrong... // it would only break the replay if we clipped them. + players[0].camerascale = camerascale; + players[0].shieldscale = shieldscale; players[0].charability = charability; players[0].charability2 = charability2; players[0].actionspd = actionspd; @@ -5292,7 +5587,11 @@ void G_DoPlayDemo(char *defdemoname) players[0].thrustfactor = thrustfactor; players[0].accelstart = accelstart; players[0].acceleration = acceleration; + players[0].height = height; + players[0].spinheight = spinheight; players[0].jumpfactor = jumpfactor; + players[0].followitem = followitem; + players[0].pflags = pflags; demo_start = true; } @@ -5356,8 +5655,6 @@ void G_AddGhost(char *defdemoname) switch(ghostversion) { case DEMOVERSION: // latest always supported - // compatibility available? - case 0x0008: break; // too old, cannot support. default: @@ -5434,7 +5731,14 @@ void G_AddGhost(char *defdemoname) p++; // thrustfactor p++; // accelstart p++; // acceleration + p++; // height + p++; // spinheight + p++; // camerascale + p++; // shieldscale p += 4; // jumpfactor + p += 4; // followitem + + p++; // pflag data // net var data count = READUINT16(p); @@ -5488,10 +5792,6 @@ void G_AddGhost(char *defdemoname) } gh->mo->z = z; } - gh->mo->state = states+S_PLAY_STND; - gh->mo->sprite = gh->mo->state->sprite; - gh->mo->frame = (gh->mo->state->frame & FF_FRAMEMASK) | tr_trans20<<FF_TRANSSHIFT; - gh->mo->tics = -1; gh->oldmo.x = gh->mo->x; gh->oldmo.y = gh->mo->y; @@ -5517,6 +5817,12 @@ void G_AddGhost(char *defdemoname) } gh->oldmo.color = gh->mo->color; + gh->mo->state = states+S_PLAY_STND; + gh->mo->sprite = gh->mo->state->sprite; + gh->mo->sprite2 = (gh->mo->state->frame & FF_FRAMEMASK); + gh->mo->frame = tr_trans20<<FF_TRANSSHIFT; + gh->mo->tics = -1; + CONS_Printf(M_GetText("Added ghost %s from %s\n"), name, pdemoname); Z_Free(pdemoname); } @@ -5563,8 +5869,10 @@ void G_DoPlayMetal(void) continue; mo = (mobj_t *)th; - if (mo->type == MT_METALSONIC_RACE) - break; + if (mo->type != MT_METALSONIC_RACE) + continue; + + break; } if (!mo) { @@ -5581,8 +5889,6 @@ void G_DoPlayMetal(void) switch(metalversion) { case DEMOVERSION: // latest always supported - // compatibility available? - case 0x0008: break; // too old, cannot support. default: @@ -5603,7 +5909,6 @@ void G_DoPlayMetal(void) oldmetal.x = mo->x; oldmetal.y = mo->y; oldmetal.z = mo->z; - oldmetal.angle = mo->angle; metalplayback = mo; } diff --git a/src/g_game.h b/src/g_game.h index 9e360f8823024501ba09458bcaf4add43ff40672..56682084eec874a50c910adec56d601bcdd18d3f 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -42,6 +42,7 @@ extern tic_t demostarttime; // Quit after playing a demo from cmdline. extern boolean singledemo; extern boolean demo_start; +extern boolean demosynced; extern mobj_t *metalplayback; @@ -53,14 +54,19 @@ extern INT16 prevmap, nextmap; extern INT32 gameovertics; extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard display) extern INT16 rw_maximums[NUM_WEAPONS]; +extern INT32 pausedelay; +extern boolean pausebreakkey; // 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; extern consvar_t cv_crosshair, cv_crosshair2; extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove; extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2; extern consvar_t cv_useranalog, cv_useranalog2; extern consvar_t cv_analog, cv_analog2; +extern consvar_t cv_directionchar, cv_directionchar2; +extern consvar_t cv_autobrake, cv_autobrake2; extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis; extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2; extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; @@ -94,7 +100,7 @@ void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo); void G_DoReborn(INT32 playernum); void G_PlayerReborn(INT32 player); void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, - boolean skipprecutscene); + boolean skipprecutscene, boolean FLS); char *G_BuildMapTitle(INT32 mapnum); // XMOD spawning @@ -118,6 +124,8 @@ void G_SaveGameData(void); void G_SaveGame(UINT32 slot); +void G_SaveGameOver(UINT32 slot, boolean modifylives); + // Only called by startup code. void G_RecordDemo(const char *name); void G_RecordMetal(void); diff --git a/src/g_input.c b/src/g_input.c index 79623555909687fc6bf49ec637f59886e49bf3d4..45c517e1a634740caf8a25accf5facc93df35227 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -45,6 +45,48 @@ UINT8 gamekeydown[NUMINPUTS]; // two key codes (or virtual key) per game control INT32 gamecontrol[num_gamecontrols][2]; INT32 gamecontrolbis[num_gamecontrols][2]; // secondary splitscreen player +INT32 gamecontroldefault[num_gamecontrolschemes][num_gamecontrols][2]; // default control storage, use 0 (gcs_custom) for memory retention +INT32 gamecontrolbisdefault[num_gamecontrolschemes][num_gamecontrols][2]; + +// lists of GC codes for selective operation +const INT32 gcl_tutorial_check[num_gcl_tutorial_check] = { + gc_forward, gc_backward, gc_strafeleft, gc_straferight, + gc_turnleft, gc_turnright +}; + +const INT32 gcl_tutorial_used[num_gcl_tutorial_used] = { + gc_forward, gc_backward, gc_strafeleft, gc_straferight, + gc_turnleft, gc_turnright, + gc_jump, gc_use +}; + +const INT32 gcl_tutorial_full[num_gcl_tutorial_full] = { + gc_forward, gc_backward, gc_strafeleft, gc_straferight, + gc_lookup, gc_lookdown, gc_turnleft, gc_turnright, gc_centerview, + gc_jump, gc_use, + gc_fire, gc_firenormal +}; + +const INT32 gcl_movement[num_gcl_movement] = { + gc_forward, gc_backward, gc_strafeleft, gc_straferight +}; + +const INT32 gcl_camera[num_gcl_camera] = { + gc_turnleft, gc_turnright +}; + +const INT32 gcl_movement_camera[num_gcl_movement_camera] = { + gc_forward, gc_backward, gc_strafeleft, gc_straferight, + gc_turnleft, gc_turnright +}; + +const INT32 gcl_jump[num_gcl_jump] = { gc_jump }; + +const INT32 gcl_use[num_gcl_use] = { gc_use }; + +const INT32 gcl_jump_use[num_gcl_jump_use] = { + gc_jump, gc_use +}; typedef struct { @@ -208,11 +250,9 @@ static keyname_t keynames[] = {KEY_SCROLLLOCK, "SCROLLLOCK"}, // bill gates keys -#ifndef _arch_dreamcast {KEY_LEFTWIN, "LEFTWIN"}, {KEY_RIGHTWIN, "RIGHTWIN"}, {KEY_MENU, "MENU"}, -#endif {KEY_LSHIFT, "LSHIFT"}, {KEY_RSHIFT, "RSHIFT"}, @@ -274,140 +314,24 @@ static keyname_t keynames[] = {KEY_MOUSE1+0,"MOUSE1"}, {KEY_MOUSE1+1,"MOUSE2"}, {KEY_MOUSE1+2,"MOUSE3"}, -#if !defined (_arch_dreamcast) && !defined (_XBOX) && !defined (_PSP) && !defined (_WII) {KEY_MOUSE1+3,"MOUSE4"}, {KEY_MOUSE1+4,"MOUSE5"}, {KEY_MOUSE1+5,"MOUSE6"}, {KEY_MOUSE1+6,"MOUSE7"}, {KEY_MOUSE1+7,"MOUSE8"}, -#endif {KEY_2MOUSE1+0,"SEC_MOUSE2"}, // BP: sorry my mouse handler swap button 1 and 2 {KEY_2MOUSE1+1,"SEC_MOUSE1"}, {KEY_2MOUSE1+2,"SEC_MOUSE3"}, -#if !defined (_arch_dreamcast) && !defined (_XBOX) && !defined (_PSP) && !defined (_WII) {KEY_2MOUSE1+3,"SEC_MOUSE4"}, {KEY_2MOUSE1+4,"SEC_MOUSE5"}, {KEY_2MOUSE1+5,"SEC_MOUSE6"}, {KEY_2MOUSE1+6,"SEC_MOUSE7"}, {KEY_2MOUSE1+7,"SEC_MOUSE8"}, -#endif {KEY_MOUSEWHEELUP, "Wheel 1 UP"}, {KEY_MOUSEWHEELDOWN, "Wheel 1 Down"}, {KEY_2MOUSEWHEELUP, "Wheel 2 UP"}, {KEY_2MOUSEWHEELDOWN, "Wheel 2 Down"}, -#ifdef DC - {KEY_JOY1+0, "JOYC"}, - {KEY_JOY1+1, "JOYB"}, - {KEY_JOY1+2, "JOYA"}, - {KEY_JOY1+3, "JOYS"}, - {KEY_JOY1+4, "JOYZ"}, - {KEY_JOY1+5, "JOYY"}, - {KEY_JOY1+6, "JOYX"}, - {KEY_JOY1+7, "JOYD"}, -#elif defined (_XBOX) - {KEY_JOY1+0, "JOYA"}, - {KEY_JOY1+1, "JOYB"}, - {KEY_JOY1+2, "JOYX"}, - {KEY_JOY1+3, "JOYY"}, - {KEY_JOY1+4, "JOYG"}, - {KEY_JOY1+5, "JOYW"}, - {KEY_JOY1+6, "JOYL"}, - {KEY_JOY1+7, "JOYR"}, - {KEY_JOY1+8, "JOYS"}, - {KEY_JOY1+9, "JOYN"}, - {KEY_JOY1+10,"JOYW"}, - {KEY_JOY1+11,"JOYE"}, -#define NOMOREJOYBTN_1S -#elif defined (_PSP) - {KEY_JOY1+0, "TRIANGLE"}, - {KEY_JOY1+1, "CIRCLE" }, - {KEY_JOY1+2, "CROSS" }, - {KEY_JOY1+3, "SQUARE" }, - {KEY_JOY1+4, "LTRIGGER"}, - {KEY_JOY1+5, "RTRIGGER"}, - {KEY_JOY1+6, "SELECT" }, - {KEY_JOY1+7, "START" }, - {KEY_JOY1+8, "HOME" }, - {KEY_JOY1+9, "HOLD" }, -#define NOMOREJOYBTN_1S -#elif defined (GP2X) - {KEY_JOY1+0, "JOYA"}, - {KEY_JOY1+1, "JOYY"}, - {KEY_JOY1+2, "JOYB"}, - {KEY_JOY1+3, "JOYX"}, - {KEY_JOY1+4, "JOYL"}, - {KEY_JOY1+5, "JOYR"}, - {KEY_JOY1+6, "JOYVOLUP"}, - {KEY_JOY1+7, "JOYVOLDOWN"}, - {KEY_JOY1+8, "JOYSELECT"}, -#elif defined (_NDS) - {KEY_JOY1+0, "JOYA"}, - {KEY_JOY1+1, "JOYB"}, - {KEY_JOY1+2, "JOYX"}, - {KEY_JOY1+3, "JOYY"}, - {KEY_JOY1+4, "JOYL"}, - {KEY_JOY1+5, "JOYR"}, - {KEY_JOY1+6, "JOYSTART"}, - {KEY_JOY1+7, "JOYSELECT"}, -#define NOMOREJOYBTN_1S -#elif defined (WMINPUT) - {KEY_JOY1+0, "JOYB"}, - {KEY_JOY1+1, "JOYA"}, - {KEY_JOY1+2, "JOYUP"}, - {KEY_JOY1+3, "JOYDOWN"}, - {KEY_JOY1+4, "JOYLEFT"}, - {KEY_JOY1+5, "JOYRIGHT"}, - {KEY_JOY1+6, "JOYAA"}, - {KEY_JOY1+7, "JOYBB"}, - {KEY_JOY1+8, "JOYCC"}, - {KEY_JOY1+9, "JOYXX"}, - {KEY_JOY1+10, "JOYYY"}, - {KEY_JOY1+11, "JOYZZ"}, - {KEY_JOY1+12, "JOYL"}, - {KEY_JOY1+13, "JOYR"}, - {KEY_JOY1+14, "JOYZL"}, - {KEY_JOY1+15, "JOYZR"}, - {KEY_JOY1+16, "JOYSELECT"}, - {KEY_JOY1+17, "JOYSTART"}, - {KEY_JOY1+18, "JOYHOME"}, - {KEY_JOY1+19, "JOYMINUS"}, - {KEY_JOY1+20, "JOYPLUS"}, - {KEY_JOY1+21, "JOY_1"}, - {KEY_JOY1+22, "JOY_2"}, - {KEY_JOY1+23, "JOY24"}, - {KEY_JOY1+24, "JOY25"}, - {KEY_JOY1+25, "JOY26"}, - {KEY_JOY1+26, "JOY27"}, - {KEY_JOY1+27, "JOY28"}, - {KEY_JOY1+28, "JOY29"}, - {KEY_JOY1+29, "JOY30"}, - {KEY_JOY1+30, "JOY31"}, - {KEY_JOY1+31, "JOY32"}, -#define NOMOREJOYBTN_1S -#elif defined (_WII) - {KEY_JOY1+0, "JOYA"}, - {KEY_JOY1+1, "JOYB"}, - {KEY_JOY1+2, "JOY1"}, - {KEY_JOY1+3, "JOY2"}, - {KEY_JOY1+4, "JOYMINUS"}, - {KEY_JOY1+5, "JOYPLUS"}, - {KEY_JOY1+6, "JOYHOME"}, - {KEY_JOY1+7, "JOYZ"}, - {KEY_JOY1+8, "JOYC"}, - {KEY_JOY1+9, "JOYA_CC"}, - {KEY_JOY1+10, "JOYB_CC"}, - {KEY_JOY1+11, "JOYX"}, - {KEY_JOY1+12, "JOYY"}, - {KEY_JOY1+13, "JOYL"}, - {KEY_JOY1+14, "JOYR"}, - {KEY_JOY1+15, "JOYZL"}, - {KEY_JOY1+16, "JOYZR"}, - {KEY_JOY1+17, "JOYMINUS_CC"}, - {KEY_JOY1+18, "JOYHPLUS_CC"}, - {KEY_JOY1+19, "JOYMHOME_CC"}, -#define NOMOREJOYBTN_1S -#else {KEY_JOY1+0, "JOY1"}, {KEY_JOY1+1, "JOY2"}, {KEY_JOY1+2, "JOY3"}, @@ -417,8 +341,7 @@ static keyname_t keynames[] = {KEY_JOY1+6, "JOY7"}, {KEY_JOY1+7, "JOY8"}, {KEY_JOY1+8, "JOY9"}, -#endif -#if !defined (_arch_dreamcast) && !defined (NOMOREJOYBTN_1S) +#if !defined (NOMOREJOYBTN_1S) // we use up to 32 buttons in DirectInput {KEY_JOY1+9, "JOY10"}, {KEY_JOY1+10, "JOY11"}, @@ -449,12 +372,10 @@ static keyname_t keynames[] = {KEY_HAT1+1, "HATDOWN"}, {KEY_HAT1+2, "HATLEFT"}, {KEY_HAT1+3, "HATRIGHT"}, -#if !defined (_XBOX) && !defined (_PSP) && !defined (_WII) {KEY_HAT1+4, "HATUP2"}, {KEY_HAT1+5, "HATDOWN2"}, {KEY_HAT1+6, "HATLEFT2"}, {KEY_HAT1+7, "HATRIGHT2"}, -#ifndef _arch_dreamcast {KEY_HAT1+8, "HATUP3"}, {KEY_HAT1+9, "HATDOWN3"}, {KEY_HAT1+10, "HATLEFT3"}, @@ -463,142 +384,24 @@ static keyname_t keynames[] = {KEY_HAT1+13, "HATDOWN4"}, {KEY_HAT1+14, "HATLEFT4"}, {KEY_HAT1+15, "HATRIGHT4"}, -#endif -#endif {KEY_DBLMOUSE1+0, "DBLMOUSE1"}, {KEY_DBLMOUSE1+1, "DBLMOUSE2"}, {KEY_DBLMOUSE1+2, "DBLMOUSE3"}, -#if !defined (_arch_dreamcast) && !defined (_XBOX) && !defined (_PSP) && !defined (_WII) {KEY_DBLMOUSE1+3, "DBLMOUSE4"}, {KEY_DBLMOUSE1+4, "DBLMOUSE5"}, {KEY_DBLMOUSE1+5, "DBLMOUSE6"}, {KEY_DBLMOUSE1+6, "DBLMOUSE7"}, {KEY_DBLMOUSE1+7, "DBLMOUSE8"}, -#endif {KEY_DBL2MOUSE1+0, "DBLSEC_MOUSE2"}, // BP: sorry my mouse handler swap button 1 and 2 {KEY_DBL2MOUSE1+1, "DBLSEC_MOUSE1"}, {KEY_DBL2MOUSE1+2, "DBLSEC_MOUSE3"}, -#if !defined (_arch_dreamcast) && !defined (_XBOX) && !defined (_PSP) && !defined (_WII) {KEY_DBL2MOUSE1+3, "DBLSEC_MOUSE4"}, {KEY_DBL2MOUSE1+4, "DBLSEC_MOUSE5"}, {KEY_DBL2MOUSE1+5, "DBLSEC_MOUSE6"}, {KEY_DBL2MOUSE1+6, "DBLSEC_MOUSE7"}, {KEY_DBL2MOUSE1+7, "DBLSEC_MOUSE8"}, -#endif -#ifdef DC - {KEY_DBLJOY1+0, "DBLJOYC"}, - {KEY_DBLJOY1+1, "DBLJOYB"}, - {KEY_DBLJOY1+2, "DBLJOYA"}, - {KEY_DBLJOY1+3, "DBLJOYS"}, - {KEY_DBLJOY1+4, "DBLJOYZ"}, - {KEY_DBLJOY1+5, "DBLJOYY"}, - {KEY_DBLJOY1+6, "DBLJOYX"}, - {KEY_DBLJOY1+7, "DBLJOYD"}, -#elif defined (_XBOX) - {KEY_DBLJOY1+0, "DBLJOYA"}, - {KEY_DBLJOY1+1, "DBLJOYB"}, - {KEY_DBLJOY1+2, "DBLJOYX"}, - {KEY_DBLJOY1+3, "DBLJOYY"}, - {KEY_DBLJOY1+4, "DBLJOYG"}, - {KEY_DBLJOY1+5, "DBLJOYW"}, - {KEY_DBLJOY1+6, "DBLJOYL"}, - {KEY_DBLJOY1+7, "DBLJOYR"}, - {KEY_DBLJOY1+8, "DBLJOYS"}, - {KEY_DBLJOY1+9, "DBLJOYN"}, - {KEY_DBLJOY1+10,"DBLJOYW"}, - {KEY_DBLJOY1+11,"DBLJOYE"}, -#define NOMOREJOYBTN_1DBL -#elif defined (_PSP) - {KEY_DBLJOY1+0, "DBLTRIANGLE"}, - {KEY_DBLJOY1+1, "DBLCIRCLE" }, - {KEY_DBLJOY1+2, "DBLCROSS" }, - {KEY_DBLJOY1+3, "DBLSQUARE" }, - {KEY_DBLJOY1+4, "DBLLTRIGGER"}, - {KEY_DBLJOY1+5, "DBLRTRIGGER"}, - {KEY_DBLJOY1+6, "DBLSELECT" }, - {KEY_DBLJOY1+7, "DBLSTART" }, - {KEY_DBLJOY1+8, "DBLHOME" }, - {KEY_DBLJOY1+9, "DBLHOLD" }, -#elif defined (GP2X) - {KEY_DBLJOY1+0, "DBLJOYA"}, - {KEY_DBLJOY1+1, "DBLJOYY"}, - {KEY_DBLJOY1+2, "DBLJOYB"}, - {KEY_DBLJOY1+3, "DBLJOYX"}, - {KEY_DBLJOY1+4, "DBLJOYL"}, - {KEY_DBLJOY1+5, "DBLJOYR"}, - {KEY_DBLJOY1+6, "DBLJOYVOLUP"}, - {KEY_DBLJOY1+7, "DBLJOYVOLDOWN"}, - {KEY_DBLJOY1+8, "DBLJOYSELECT"}, -#define NOMOREJOYBTN_1DBL -#elif defined (_NDS) - {KEY_DBLJOY1+0, "DBLJOYA"}, - {KEY_DBLJOY1+1, "DBLJOYB"}, - {KEY_DBLJOY1+2, "DBLJOYX"}, - {KEY_DBLJOY1+3, "DBLJOYY"}, - {KEY_DBLJOY1+4, "DBLJOYL"}, - {KEY_DBLJOY1+5, "DBLJOYR"}, - {KEY_DBLJOY1+6, "DBLJOYSTART"}, - {KEY_DBLJOY1+7, "DBLJOYSELECT"}, -#define NOMOREJOYBTN_1DBL -#elif defined (WMINPUT) - {KEY_DBLJOY1+0, "DBLJOYB"}, - {KEY_DBLJOY1+1, "DBLJOYA"}, - {KEY_DBLJOY1+2, "DBLJOYUP"}, - {KEY_DBLJOY1+3, "DBLJOYDOWN"}, - {KEY_DBLJOY1+4, "DBLJOYLEFT"}, - {KEY_DBLJOY1+5, "DBLJOYRIGHT"}, - {KEY_DBLJOY1+6, "DBLJOYAA"}, - {KEY_DBLJOY1+7, "DBLJOYBB"}, - {KEY_DBLJOY1+8, "DBLJOYCC"}, - {KEY_DBLJOY1+9, "DBLJOYXX"}, - {KEY_DBLJOY1+10, "DBLJOYYY"}, - {KEY_DBLJOY1+11, "DBLJOYZZ"}, - {KEY_DBLJOY1+12, "DBLJOYL"}, - {KEY_DBLJOY1+13, "DBLJOYR"}, - {KEY_DBLJOY1+14, "DBLJOYZL"}, - {KEY_DBLJOY1+15, "DBLJOYZR"}, - {KEY_DBLJOY1+16, "DBLJOYSELECT"}, - {KEY_DBLJOY1+17, "DBLJOYSTART"}, - {KEY_DBLJOY1+18, "DBLJOYHOME"}, - {KEY_DBLJOY1+19, "DBLJOYMINUS"}, - {KEY_DBLJOY1+20, "DBLJOYPLUS"}, - {KEY_DBLJOY1+21, "DBLJOY_1"}, - {KEY_DBLJOY1+22, "DBLJOY_2"}, - {KEY_DBLJOY1+23, "DBLJOY24"}, - {KEY_DBLJOY1+24, "DBLJOY25"}, - {KEY_DBLJOY1+25, "DBLJOY26"}, - {KEY_DBLJOY1+26, "DBLJOY27"}, - {KEY_DBLJOY1+27, "DBLJOY28"}, - {KEY_DBLJOY1+28, "DBLJOY29"}, - {KEY_DBLJOY1+29, "DBLJOY30"}, - {KEY_DBLJOY1+30, "DBLJOY31"}, - {KEY_DBLJOY1+31, "DBLJOY32"}, -#define NOMOREJOYBTN_1DBL -#elif defined (_WII) - {KEY_DBLJOY1+0, "DBLJOYA"}, - {KEY_DBLJOY1+1, "DBLJOYB"}, - {KEY_DBLJOY1+2, "DBLJOY1"}, - {KEY_DBLJOY1+3, "DBLJOY2"}, - {KEY_DBLJOY1+4, "DBLJOYMINUS"}, - {KEY_DBLJOY1+5, "DBLJOYPLUS"}, - {KEY_DBLJOY1+6, "DBLJOYHOME"}, - {KEY_DBLJOY1+7, "DBLJOYZ"}, - {KEY_DBLJOY1+8, "DBLJOYC"}, - {KEY_DBLJOY1+9, "DBLJOYA_CC"}, - {KEY_DBLJOY1+10, "DBLJOYB_CC"}, - {KEY_DBLJOY1+11, "DBLJOYX"}, - {KEY_DBLJOY1+12, "DBLJOYY"}, - {KEY_DBLJOY1+13, "DBLJOYL"}, - {KEY_DBLJOY1+14, "DBLJOYR"}, - {KEY_DBLJOY1+15, "DBLJOYZL"}, - {KEY_DBLJOY1+16, "DBLJOYZR"}, - {KEY_DBLJOY1+17, "DBLJOYMINUS_CC"}, - {KEY_DBLJOY1+18, "DBLJOYHPLUS_CC"}, - {KEY_DBLJOY1+19, "DBLJOYMHOME_CC"}, -#define NOMOREJOYBTN_1DBL -#else {KEY_DBLJOY1+0, "DBLJOY1"}, {KEY_DBLJOY1+1, "DBLJOY2"}, {KEY_DBLJOY1+2, "DBLJOY3"}, @@ -607,8 +410,7 @@ static keyname_t keynames[] = {KEY_DBLJOY1+5, "DBLJOY6"}, {KEY_DBLJOY1+6, "DBLJOY7"}, {KEY_DBLJOY1+7, "DBLJOY8"}, -#endif -#if !defined (_arch_dreamcast) && !defined (NOMOREJOYBTN_1DBL) +#if !defined (NOMOREJOYBTN_1DBL) {KEY_DBLJOY1+8, "DBLJOY9"}, {KEY_DBLJOY1+9, "DBLJOY10"}, {KEY_DBLJOY1+10, "DBLJOY11"}, @@ -638,12 +440,10 @@ static keyname_t keynames[] = {KEY_DBLHAT1+1, "DBLHATDOWN"}, {KEY_DBLHAT1+2, "DBLHATLEFT"}, {KEY_DBLHAT1+3, "DBLHATRIGHT"}, -#if !defined (_XBOX) && !defined (_PSP) && !defined (_WII) {KEY_DBLHAT1+4, "DBLHATUP2"}, {KEY_DBLHAT1+5, "DBLHATDOWN2"}, {KEY_DBLHAT1+6, "DBLHATLEFT2"}, {KEY_DBLHAT1+7, "DBLHATRIGHT2"}, -#ifndef _arch_dreamcast {KEY_DBLHAT1+8, "DBLHATUP3"}, {KEY_DBLHAT1+9, "DBLHATDOWN3"}, {KEY_DBLHAT1+10, "DBLHATLEFT3"}, @@ -652,101 +452,7 @@ static keyname_t keynames[] = {KEY_DBLHAT1+13, "DBLHATDOWN4"}, {KEY_DBLHAT1+14, "DBLHATLEFT4"}, {KEY_DBLHAT1+15, "DBLHATRIGHT4"}, -#endif -#endif -#ifdef DC - {KEY_2JOY1+0, "SEC_JOYC"}, - {KEY_2JOY1+1, "SEC_JOYB"}, - {KEY_2JOY1+2, "SEC_JOYA"}, - {KEY_2JOY1+3, "SEC_JOYS"}, - {KEY_2JOY1+4, "SEC_JOYZ"}, - {KEY_2JOY1+5, "SEC_JOYY"}, - {KEY_2JOY1+6, "SEC_JOYX"}, - {KEY_2JOY1+7, "SEC_JOYD"}, -#elif defined (_XBOX) - {KEY_2JOY1+0, "SEC_JOYA"}, - {KEY_2JOY1+1, "SEC_JOYB"}, - {KEY_2JOY1+2, "SEC_JOYX"}, - {KEY_2JOY1+3, "SEC_JOYY"}, - {KEY_2JOY1+4, "SEC_JOYG"}, - {KEY_2JOY1+5, "SEC_JOYW"}, - {KEY_2JOY1+6, "SEC_JOYL"}, - {KEY_2JOY1+7, "SEC_JOYR"}, - {KEY_2JOY1+8, "SEC_JOYS"}, - {KEY_2JOY1+9, "SEC_JOYN"}, - {KEY_2JOY1+10,"SEC_JOYW"}, - {KEY_2JOY1+11,"SEC_JOYE"}, -#define NOMOREJOYBTN_2S -#elif defined (_PSP) - {KEY_2JOY1+0, "SEC_TRIANGLE"}, - {KEY_2JOY1+1, "SEC_CIRCLE" }, - {KEY_2JOY1+2, "SEC_CROSS" }, - {KEY_2JOY1+3, "SEC_SQUARE" }, - {KEY_2JOY1+4, "SEC_LTRIGGER"}, - {KEY_2JOY1+5, "SEC_RTRIGGER"}, - {KEY_2JOY1+6, "SEC_SELECT" }, - {KEY_2JOY1+7, "SEC_START" }, - {KEY_2JOY1+8, "SEC_HOME" }, - {KEY_2JOY1+9, "SEC_HOLD" }, -#define NOMOREJOYBTN_2S -#elif defined (WMINPUT) - {KEY_2JOY1+0, "SEC_JOYB"}, - {KEY_2JOY1+1, "SEC_JOYA"}, - {KEY_2JOY1+2, "SEC_JOYUP"}, - {KEY_2JOY1+3, "SEC_JOYDOWN"}, - {KEY_2JOY1+4, "SEC_JOYLEFT"}, - {KEY_2JOY1+5, "SEC_JOYRIGHT"}, - {KEY_2JOY1+6, "SEC_JOYAA"}, - {KEY_2JOY1+7, "SEC_JOYBB"}, - {KEY_2JOY1+8, "SEC_JOYCC"}, - {KEY_2JOY1+9, "SEC_JOYXX"}, - {KEY_2JOY1+10, "SEC_JOYYY"}, - {KEY_2JOY1+11, "SEC_JOYZZ"}, - {KEY_2JOY1+12, "SEC_JOYL"}, - {KEY_2JOY1+13, "SEC_JOYR"}, - {KEY_2JOY1+14, "SEC_JOYZL"}, - {KEY_2JOY1+15, "SEC_JOYZR"}, - {KEY_2JOY1+16, "SEC_JOYSELECT"}, - {KEY_2JOY1+17, "SEC_JOYSTART"}, - {KEY_2JOY1+18, "SEC_JOYHOME"}, - {KEY_2JOY1+19, "SEC_JOYMINUS"}, - {KEY_2JOY1+20, "SEC_JOYPLUS"}, - {KEY_2JOY1+21, "SEC_JOY_1"}, - {KEY_2JOY1+22, "SEC_JOY_2"}, - {KEY_2JOY1+23, "SEC_JOY24"}, - {KEY_2JOY1+24, "SEC_JOY25"}, - {KEY_2JOY1+25, "SEC_JOY26"}, - {KEY_2JOY1+26, "SEC_JOY27"}, - {KEY_2JOY1+27, "SEC_JOY28"}, - {KEY_2JOY1+28, "SEC_JOY29"}, - {KEY_2JOY1+29, "SEC_JOY30"}, - {KEY_2JOY1+30, "SEC_JOY31"}, - {KEY_2JOY1+31, "SEC_JOY32"}, -#define NOMOREJOYBTN_2S -#elif defined (_WII) - {KEY_2JOY1+0, "SEC_JOYA"}, - {KEY_2JOY1+1, "SEC_JOYB"}, - {KEY_2JOY1+2, "SEC_JOY1"}, - {KEY_2JOY1+3, "SEC_JOY2"}, - {KEY_2JOY1+4, "SEC_JOYMINUS"}, - {KEY_2JOY1+5, "SEC_JOYPLUS"}, - {KEY_2JOY1+6, "SEC_JOYHOME"}, - {KEY_2JOY1+7, "SEC_JOYZ"}, - {KEY_2JOY1+8, "SEC_JOYC"}, - {KEY_2JOY1+9, "SEC_JOYA_CC"}, - {KEY_2JOY1+10, "SEC_JOYB_CC"}, - {KEY_2JOY1+11, "SEC_JOYX"}, - {KEY_2JOY1+12, "SEC_JOYY"}, - {KEY_2JOY1+13, "SEC_JOYL"}, - {KEY_2JOY1+14, "SEC_JOYR"}, - {KEY_2JOY1+15, "SEC_JOYZL"}, - {KEY_2JOY1+16, "SEC_JOYZR"}, - {KEY_2JOY1+17, "SEC_JOYMINUS_CC"}, - {KEY_2JOY1+18, "SEC_JOYHPLUS_CC"}, - {KEY_2JOY1+19, "SEC_JOYMHOME_CC"}, -#define NOMOREJOYBTN_2S -#else {KEY_2JOY1+0, "SEC_JOY1"}, {KEY_2JOY1+1, "SEC_JOY2"}, {KEY_2JOY1+2, "SEC_JOY3"}, @@ -755,8 +461,7 @@ static keyname_t keynames[] = {KEY_2JOY1+5, "SEC_JOY6"}, {KEY_2JOY1+6, "SEC_JOY7"}, {KEY_2JOY1+7, "SEC_JOY8"}, -#endif -#if !defined (_arch_dreamcast) && !defined (NOMOREJOYBTN_2S) +#if !defined (NOMOREJOYBTN_2S) // we use up to 32 buttons in DirectInput {KEY_2JOY1+8, "SEC_JOY9"}, {KEY_2JOY1+9, "SEC_JOY10"}, @@ -788,12 +493,10 @@ static keyname_t keynames[] = {KEY_2HAT1+1, "SEC_HATDOWN"}, {KEY_2HAT1+2, "SEC_HATLEFT"}, {KEY_2HAT1+3, "SEC_HATRIGHT"}, -#if !defined (_XBOX) && !defined (_PSP) && !defined (_WII) {KEY_2HAT1+4, "SEC_HATUP2"}, {KEY_2HAT1+5, "SEC_HATDOWN2"}, {KEY_2HAT1+6, "SEC_HATLEFT2"}, {KEY_2HAT1+7, "SEC_HATRIGHT2"}, -#ifndef _arch_dreamcast {KEY_2HAT1+8, "SEC_HATUP3"}, {KEY_2HAT1+9, "SEC_HATDOWN3"}, {KEY_2HAT1+10, "SEC_HATLEFT3"}, @@ -802,101 +505,7 @@ static keyname_t keynames[] = {KEY_2HAT1+13, "SEC_HATDOWN4"}, {KEY_2HAT1+14, "SEC_HATLEFT4"}, {KEY_2HAT1+15, "SEC_HATRIGHT4"}, -#endif -#endif -#ifdef DC - {KEY_DBL2JOY1+0, "DBLSEC_JOYC"}, - {KEY_DBL2JOY1+1, "DBLSEC_JOYB"}, - {KEY_DBL2JOY1+2, "DBLSEC_JOYA"}, - {KEY_DBL2JOY1+3, "DBLSEC_JOYS"}, - {KEY_DBL2JOY1+4, "DBLSEC_JOYZ"}, - {KEY_DBL2JOY1+5, "DBLSEC_JOYY"}, - {KEY_DBL2JOY1+6, "DBLSEC_JOYX"}, - {KEY_DBL2JOY1+7, "DBLSEC_JOYD"}, -#elif defined (_XBOX) - {KEY_DBL2JOY1+0, "DBLSEC_JOYA"}, - {KEY_DBL2JOY1+1, "DBLSEC_JOYB"}, - {KEY_DBL2JOY1+2, "DBLSEC_JOYX"}, - {KEY_DBL2JOY1+3, "DBLSEC_JOYY"}, - {KEY_DBL2JOY1+4, "DBLSEC_JOYG"}, - {KEY_DBL2JOY1+5, "DBLSEC_JOYW"}, - {KEY_DBL2JOY1+6, "DBLSEC_JOYL"}, - {KEY_DBL2JOY1+7, "DBLSEC_JOYR"}, - {KEY_DBL2JOY1+8, "DBLSEC_JOYS"}, - {KEY_DBL2JOY1+9, "DBLSEC_JOYN"}, - {KEY_DBL2JOY1+10,"DBLSEC_JOYW"}, - {KEY_DBL2JOY1+11,"DBLSEC_JOYE"}, -#define NOMOREJOYBTN_2DBL -#elif defined (_PSP) - {KEY_DBL2JOY1+0, "DBLSEC_TRIANGLE"}, - {KEY_DBL2JOY1+1, "DBLSEC_CIRCLE" }, - {KEY_DBL2JOY1+2, "DBLSEC_CROSS" }, - {KEY_DBL2JOY1+3, "DBLSEC_SQUARE" }, - {KEY_DBL2JOY1+4, "DBLSEC_LTRIGGER"}, - {KEY_DBL2JOY1+5, "DBLSEC_RTRIGGER"}, - {KEY_DBL2JOY1+6, "DBLSEC_SELECT" }, - {KEY_DBL2JOY1+7, "DBLSEC_START" }, - {KEY_DBL2JOY1+8, "DBLSEC_HOME" }, - {KEY_DBL2JOY1+9, "DBLSEC_HOLD" }, -#define NOMOREJOYBTN_2DBL -#elif defined (WMINPUT) - {KEY_DBL2JOY1+0, "DBLSEC_JOYB"}, - {KEY_DBL2JOY1+1, "DBLSEC_JOYA"}, - {KEY_DBL2JOY1+2, "DBLSEC_JOYUP"}, - {KEY_DBL2JOY1+3, "DBLSEC_JOYDOWN"}, - {KEY_DBL2JOY1+4, "DBLSEC_JOYLEFT"}, - {KEY_DBL2JOY1+5, "DBLSEC_JOYRIGHT"}, - {KEY_DBL2JOY1+6, "DBLSEC_JOYAA"}, - {KEY_DBL2JOY1+7, "DBLSEC_JOYBB"}, - {KEY_DBL2JOY1+8, "DBLSEC_JOYCC"}, - {KEY_DBL2JOY1+9, "DBLSEC_JOYXX"}, - {KEY_DBL2JOY1+10, "DBLSEC_JOYYY"}, - {KEY_DBL2JOY1+11, "DBLSEC_JOYZZ"}, - {KEY_DBL2JOY1+12, "DBLSEC_JOYL"}, - {KEY_DBL2JOY1+13, "DBLSEC_JOYR"}, - {KEY_DBL2JOY1+14, "DBLSEC_JOYZL"}, - {KEY_DBL2JOY1+15, "DBLSEC_JOYZR"}, - {KEY_DBL2JOY1+16, "DBLSEC_JOYSELECT"}, - {KEY_DBL2JOY1+17, "DBLSEC_JOYSTART"}, - {KEY_DBL2JOY1+18, "DBLSEC_JOYHOME"}, - {KEY_DBL2JOY1+19, "DBLSEC_JOYMINUS"}, - {KEY_DBL2JOY1+20, "DBLSEC_JOYPLUS"}, - {KEY_DBL2JOY1+21, "DBLSEC_JOY_1"}, - {KEY_DBL2JOY1+22, "DBLSEC_JOY_2"}, - {KEY_DBL2JOY1+23, "DBLSEC_JOY24"}, - {KEY_DBL2JOY1+24, "DBLSEC_JOY25"}, - {KEY_DBL2JOY1+25, "DBLSEC_JOY26"}, - {KEY_DBL2JOY1+26, "DBLSEC_JOY27"}, - {KEY_DBL2JOY1+27, "DBLSEC_JOY28"}, - {KEY_DBL2JOY1+28, "DBLSEC_JOY29"}, - {KEY_DBL2JOY1+29, "DBLSEC_JOY30"}, - {KEY_DBL2JOY1+30, "DBLSEC_JOY31"}, - {KEY_DBL2JOY1+31, "DBLSEC_JOY32"}, -#define NOMOREJOYBTN_2SDBL -#elif defined (_WII) - {KEY_DBL2JOY1+0, "DBLSEC_JOYA"}, - {KEY_DBL2JOY1+1, "DBLSEC_JOYB"}, - {KEY_DBL2JOY1+2, "DBLSEC_JOY1"}, - {KEY_DBL2JOY1+3, "DBLSEC_JOY2"}, - {KEY_DBL2JOY1+4, "DBLSEC_JOYMINUS"}, - {KEY_DBL2JOY1+5, "DBLSEC_JOYPLUS"}, - {KEY_DBL2JOY1+6, "DBLSEC_JOYHOME"}, - {KEY_DBL2JOY1+7, "DBLSEC_JOYZ"}, - {KEY_DBL2JOY1+8, "DBLSEC_JOYC"}, - {KEY_DBL2JOY1+9, "DBLSEC_JOYA_CC"}, - {KEY_DBL2JOY1+10, "DBLSEC_JOYB_CC"}, - {KEY_DBL2JOY1+11, "DBLSEC_JOYX"}, - {KEY_DBL2JOY1+12, "DBLSEC_JOYY"}, - {KEY_DBL2JOY1+13, "DBLSEC_JOYL"}, - {KEY_DBL2JOY1+14, "DBLSEC_JOYR"}, - {KEY_DBL2JOY1+15, "DBLSEC_JOYZL"}, - {KEY_DBL2JOY1+16, "DBLSEC_JOYZR"}, - {KEY_DBL2JOY1+17, "DBLSEC_JOYMINUS_CC"}, - {KEY_DBL2JOY1+18, "DBLSEC_JOYHPLUS_CC"}, - {KEY_DBL2JOY1+19, "DBLSEC_JOYMHOME_CC"}, -#define NOMOREJOYBTN_2DBL -#else {KEY_DBL2JOY1+0, "DBLSEC_JOY1"}, {KEY_DBL2JOY1+1, "DBLSEC_JOY2"}, {KEY_DBL2JOY1+2, "DBLSEC_JOY3"}, @@ -905,8 +514,7 @@ static keyname_t keynames[] = {KEY_DBL2JOY1+5, "DBLSEC_JOY6"}, {KEY_DBL2JOY1+6, "DBLSEC_JOY7"}, {KEY_DBL2JOY1+7, "DBLSEC_JOY8"}, -#endif -#if !defined (_arch_dreamcast) && !defined (NOMOREJOYBTN_2DBL) +#if !defined (NOMOREJOYBTN_2DBL) {KEY_DBL2JOY1+8, "DBLSEC_JOY9"}, {KEY_DBL2JOY1+9, "DBLSEC_JOY10"}, {KEY_DBL2JOY1+10, "DBLSEC_JOY11"}, @@ -936,12 +544,10 @@ static keyname_t keynames[] = {KEY_DBL2HAT1+1, "DBLSEC_HATDOWN"}, {KEY_DBL2HAT1+2, "DBLSEC_HATLEFT"}, {KEY_DBL2HAT1+3, "DBLSEC_HATRIGHT"}, -#if !defined (_XBOX) && !defined (_PSP) && !defined (_WII) {KEY_DBL2HAT1+4, "DBLSEC_HATUP2"}, {KEY_DBL2HAT1+5, "DBLSEC_HATDOWN2"}, {KEY_DBL2HAT1+6, "DBLSEC_HATLEFT2"}, {KEY_DBL2HAT1+7, "DBLSEC_HATRIGHT2"}, -#ifndef _arch_dreamcast {KEY_DBL2HAT1+8, "DBLSEC_HATUP3"}, {KEY_DBL2HAT1+9, "DBLSEC_HATDOWN3"}, {KEY_DBL2HAT1+10, "DBLSEC_HATLEFT3"}, @@ -950,8 +556,6 @@ static keyname_t keynames[] = {KEY_DBL2HAT1+13, "DBLSEC_HATDOWN4"}, {KEY_DBL2HAT1+14, "DBLSEC_HATLEFT4"}, {KEY_DBL2HAT1+15, "DBLSEC_HATRIGHT4"}, -#endif -#endif }; @@ -981,8 +585,6 @@ static const char *gamecontrolname[num_gamecontrols] = "tossflag", "use", "camtoggle", - "camleft", - "camright", "camreset", "lookup", "lookdown", @@ -1069,260 +671,150 @@ INT32 G_KeyStringtoNum(const char *keystr) return 0; } -#ifdef DC -void G_Controldefault(void) +void G_DefineDefaultControls(void) { - gamecontrol[gc_forward ][0] = KEY_HAT1+0; //Up - gamecontrol[gc_forward ][1] = KEY_UPARROW; - gamecontrol[gc_backward ][0] = KEY_HAT1+1; //Down - gamecontrol[gc_backward ][1] = KEY_DOWNARROW; - //gamecontrol[gc_straferight][0] = '['; - //gamecontrol[gc_strafeleft ][0] = ']'; - gamecontrol[gc_turnleft ][0] = KEY_HAT1+2; //Left - gamecontrol[gc_turnleft ][1] = KEY_LEFTARROW; - gamecontrol[gc_turnright ][0] = KEY_HAT1+3; //Right - gamecontrol[gc_turnright ][1] = KEY_RIGHTARROW; - gamecontrol[gc_weaponnext ][0] = ']'; - gamecontrol[gc_weaponprev ][0] = '['; - gamecontrol[gc_fire ][0] = KEY_JOY1+6; //X - gamecontrol[gc_fire ][1] = KEY_RCTRL; - gamecontrol[gc_firenormal ][0] = KEY_JOY1+5; //Y - gamecontrol[gc_firenormal ][1] = ';'; - gamecontrol[gc_tossflag ][0] = '\''; - gamecontrol[gc_use ][0] = KEY_JOY1+1; //B - gamecontrol[gc_use ][1] = '.'; - gamecontrol[gc_camtoggle ][1] = ','; - gamecontrol[gc_camleft ][0] = 'o'; - gamecontrol[gc_camright ][0] = 'p'; - gamecontrol[gc_camreset ][0] = 'c'; - gamecontrol[gc_lookup ][0] = KEY_PGUP; - gamecontrol[gc_lookdown ][0] = KEY_PGDN; - gamecontrol[gc_centerview ][0] = KEY_END; - gamecontrol[gc_mouseaiming][0] = 's'; - gamecontrol[gc_talkkey ][0] = 't'; - gamecontrol[gc_teamkey ][0] = 'y'; - gamecontrol[gc_scores ][0] = KEY_TAB; - gamecontrol[gc_jump ][0] = KEY_JOY1+2; //A - gamecontrol[gc_jump ][1] = '/'; - gamecontrol[gc_console ][0] = KEY_CONSOLE; - gamecontrol[gc_console ][1] = KEY_F5; - //gamecontrolbis - gamecontrolbis[gc_forward ][0] = KEY_2HAT1+0; - gamecontrolbis[gc_forward ][1] = 'w'; - gamecontrolbis[gc_backward ][0] = KEY_2HAT1+1; - gamecontrolbis[gc_backward ][1] = 's'; - gamecontrolbis[gc_turnleft ][0] = KEY_2HAT1+2; - gamecontrolbis[gc_turnleft ][1] = 'a'; - gamecontrolbis[gc_turnright ][0] = KEY_2HAT1+3; - gamecontrolbis[gc_turnright ][1] = 'd'; - gamecontrolbis[gc_weaponnext][0] = 't'; - gamecontrolbis[gc_weaponprev][0] = 'r'; - gamecontrolbis[gc_fire ][0] = KEY_2JOY1+6; //X - gamecontrolbis[gc_firenormal][0] = KEY_2JOY1+5; //Y - gamecontrolbis[gc_use ][0] = KEY_2JOY1+1; //B - gamecontrolbis[gc_jump ][0] = KEY_2JOY1+2; //A - //gamecontrolbis[gc_straferight][0] = 'x'; - //gamecontrolbis[gc_strafeleft ][0] = 'z'; -} -#elif defined (_PSP) -void G_Controldefault(void) -{ - gamecontrol[gc_forward ][0] = KEY_HAT1+0; // Up - gamecontrol[gc_backward ][0] = KEY_HAT1+1; // Down - gamecontrol[gc_turnleft ][0] = KEY_HAT1+2; // Left - gamecontrol[gc_turnright ][0] = KEY_HAT1+3; // Right - gamecontrol[gc_strafeleft ][0] = KEY_JOY1+4; // L - gamecontrol[gc_straferight][0] = KEY_JOY1+5; // R - gamecontrol[gc_tossflag ][0] = KEY_JOY1+0; // Triangle - gamecontrol[gc_use ][0] = KEY_JOY1+1; // Circle - gamecontrol[gc_camtoggle ][0] = KEY_JOY1+6; // Select - gamecontrol[gc_camreset ][0] = KEY_JOY1+3; // Square - gamecontrol[gc_centerview ][0] = KEY_JOY1+9; // Hold - gamecontrol[gc_pause ][0] = KEY_JOY1+8; // Start - gamecontrol[gc_jump ][0] = KEY_JOY1+2; // Cross -} -#elif defined (GP2X) -void G_Controldefault(void) -{ - gamecontrol[gc_fire ][0] = KEY_JOY1+0; //A - gamecontrol[gc_forward ][0] = KEY_JOY1+1; //Y - gamecontrol[gc_jump ][0] = KEY_JOY1+2; //B - gamecontrol[gc_use ][0] = KEY_JOY1+3; //X - gamecontrol[gc_strafeleft ][0] = KEY_JOY1+4; //L - gamecontrol[gc_straferight][0] = KEY_JOY1+5; //R - gamecontrol[gc_lookup ][0] = KEY_JOY1+6; //U - gamecontrol[gc_lookdown ][0] = KEY_JOY1+7; //D - gamecontrol[gc_pause ][0] = KEY_JOY1+8; //S + INT32 i; + + // FPS game controls (WASD) + gamecontroldefault[gcs_fps][gc_forward ][0] = 'w'; + gamecontroldefault[gcs_fps][gc_backward ][0] = 's'; + gamecontroldefault[gcs_fps][gc_strafeleft ][0] = 'a'; + gamecontroldefault[gcs_fps][gc_straferight][0] = 'd'; + gamecontroldefault[gcs_fps][gc_lookup ][0] = KEY_UPARROW; + gamecontroldefault[gcs_fps][gc_lookdown ][0] = KEY_DOWNARROW; + gamecontroldefault[gcs_fps][gc_turnleft ][0] = KEY_LEFTARROW; + gamecontroldefault[gcs_fps][gc_turnright ][0] = KEY_RIGHTARROW; + gamecontroldefault[gcs_fps][gc_centerview ][0] = KEY_END; + gamecontroldefault[gcs_fps][gc_jump ][0] = KEY_SPACE; + gamecontroldefault[gcs_fps][gc_use ][0] = KEY_LSHIFT; + gamecontroldefault[gcs_fps][gc_fire ][0] = KEY_RCTRL; + gamecontroldefault[gcs_fps][gc_fire ][1] = KEY_MOUSE1+0; + gamecontroldefault[gcs_fps][gc_firenormal ][0] = 'c'; + + // Platform game controls (arrow keys) + gamecontroldefault[gcs_platform][gc_forward ][0] = KEY_UPARROW; + gamecontroldefault[gcs_platform][gc_backward ][0] = KEY_DOWNARROW; + gamecontroldefault[gcs_platform][gc_strafeleft ][0] = 'a'; + gamecontroldefault[gcs_platform][gc_straferight][0] = 'd'; + gamecontroldefault[gcs_platform][gc_lookup ][0] = KEY_PGUP; + gamecontroldefault[gcs_platform][gc_lookdown ][0] = KEY_PGDN; + gamecontroldefault[gcs_platform][gc_turnleft ][0] = KEY_LEFTARROW; + gamecontroldefault[gcs_platform][gc_turnright ][0] = KEY_RIGHTARROW; + gamecontroldefault[gcs_platform][gc_centerview ][0] = KEY_END; + gamecontroldefault[gcs_platform][gc_jump ][0] = KEY_SPACE; + gamecontroldefault[gcs_platform][gc_use ][0] = KEY_LSHIFT; + gamecontroldefault[gcs_platform][gc_fire ][0] = 's'; + gamecontroldefault[gcs_platform][gc_fire ][1] = KEY_MOUSE1+0; + gamecontroldefault[gcs_platform][gc_firenormal ][0] = 'w'; + + for (i = 1; i < num_gamecontrolschemes; i++) // skip gcs_custom (0) + { + gamecontroldefault[i][gc_weaponnext ][0] = 'e'; + gamecontroldefault[i][gc_weaponprev ][0] = 'q'; + gamecontroldefault[i][gc_wepslot1 ][0] = '1'; + gamecontroldefault[i][gc_wepslot2 ][0] = '2'; + gamecontroldefault[i][gc_wepslot3 ][0] = '3'; + gamecontroldefault[i][gc_wepslot4 ][0] = '4'; + gamecontroldefault[i][gc_wepslot5 ][0] = '5'; + gamecontroldefault[i][gc_wepslot6 ][0] = '6'; + gamecontroldefault[i][gc_wepslot7 ][0] = '7'; + gamecontroldefault[i][gc_wepslot8 ][0] = '8'; + gamecontroldefault[i][gc_wepslot9 ][0] = '9'; + gamecontroldefault[i][gc_wepslot10 ][0] = '0'; + gamecontroldefault[i][gc_tossflag ][0] = '\''; + gamecontroldefault[i][gc_camtoggle ][0] = 'v'; + gamecontroldefault[i][gc_camreset ][0] = 'r'; + gamecontroldefault[i][gc_talkkey ][0] = 't'; + gamecontroldefault[i][gc_teamkey ][0] = 'y'; + gamecontroldefault[i][gc_scores ][0] = KEY_TAB; + gamecontroldefault[i][gc_console ][0] = KEY_CONSOLE; + gamecontroldefault[i][gc_pause ][0] = 'p'; + gamecontroldefault[i][gc_screenshot ][0] = KEY_F8; + gamecontroldefault[i][gc_recordgif ][0] = KEY_F9; + gamecontroldefault[i][gc_viewpoint ][0] = KEY_F12; + + // Gamepad controls -- same for both schemes + gamecontroldefault[i][gc_weaponnext ][1] = KEY_JOY1+1; // B + gamecontroldefault[i][gc_weaponprev ][1] = KEY_JOY1+2; // X + gamecontroldefault[i][gc_tossflag ][1] = KEY_JOY1+0; // A + gamecontroldefault[i][gc_use ][1] = KEY_JOY1+4; // LB + gamecontroldefault[i][gc_camtoggle ][1] = KEY_HAT1+0; // D-Pad Up + gamecontroldefault[i][gc_camreset ][1] = KEY_JOY1+3; // Y + gamecontroldefault[i][gc_centerview ][1] = KEY_JOY1+9; // Right Stick + gamecontroldefault[i][gc_talkkey ][1] = KEY_HAT1+2; // D-Pad Left + gamecontroldefault[i][gc_scores ][1] = KEY_HAT1+3; // D-Pad Right + gamecontroldefault[i][gc_jump ][1] = KEY_JOY1+5; // RB + gamecontroldefault[i][gc_pause ][1] = KEY_JOY1+6; // Back + gamecontroldefault[i][gc_screenshot ][1] = KEY_HAT1+1; // D-Pad Down + gamecontroldefault[i][gc_systemmenu ][0] = KEY_JOY1+7; // Start + + // Second player controls only have joypad defaults + gamecontrolbisdefault[i][gc_weaponnext][0] = KEY_2JOY1+1; // B + gamecontrolbisdefault[i][gc_weaponprev][0] = KEY_2JOY1+2; // X + gamecontrolbisdefault[i][gc_tossflag ][0] = KEY_2JOY1+0; // A + gamecontrolbisdefault[i][gc_use ][0] = KEY_2JOY1+4; // LB + gamecontrolbisdefault[i][gc_camreset ][0] = KEY_2JOY1+3; // Y + gamecontrolbisdefault[i][gc_centerview][0] = KEY_2JOY1+9; // Right Stick + gamecontrolbisdefault[i][gc_jump ][0] = KEY_2JOY1+5; // RB + //gamecontrolbisdefault[i][gc_pause ][0] = KEY_2JOY1+6; // Back + //gamecontrolbisdefault[i][gc_systemmenu][0] = KEY_2JOY1+7; // Start + gamecontrolbisdefault[i][gc_camtoggle ][0] = KEY_2HAT1+0; // D-Pad Up + gamecontrolbisdefault[i][gc_screenshot][0] = KEY_2HAT1+1; // D-Pad Down + //gamecontrolbisdefault[i][gc_talkkey ][0] = KEY_2HAT1+2; // D-Pad Left + //gamecontrolbisdefault[i][gc_scores ][0] = KEY_2HAT1+3; // D-Pad Right + } } -#elif defined (_NDS) -void G_Controldefault(void) + +INT32 G_GetControlScheme(INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen) { - gamecontrol[gc_fire ][0] = KEY_JOY1+2; //X - gamecontrol[gc_forward ][0] = KEY_UPARROW; - gamecontrol[gc_backward ][0] = KEY_DOWNARROW; - gamecontrol[gc_jump ][0] = KEY_JOY1+0; //A - gamecontrol[gc_use ][0] = KEY_JOY1+3; //Y - gamecontrol[gc_strafeleft ][0] = KEY_JOY1+4; //L - gamecontrol[gc_straferight][0] = KEY_JOY1+5; //R - gamecontrol[gc_turnleft ][0] = KEY_LEFTARROW; - gamecontrol[gc_turnright ][0] = KEY_RIGHTARROW; - gamecontrol[gc_pause ][0] = KEY_JOY1+6; //Start - gamecontrol[gc_weaponnext ][0] = KEY_JOY1+7; //Select + INT32 i, j, gc; + boolean skipscheme; + + for (i = 1; i < num_gamecontrolschemes; i++) // skip gcs_custom (0) + { + skipscheme = false; + for (j = 0; j < (gclist && gclen ? gclen : num_gamecontrols); j++) + { + gc = (gclist && gclen) ? gclist[j] : j; + if (((fromcontrols[gc][0] && gamecontroldefault[i][gc][0]) ? fromcontrols[gc][0] != gamecontroldefault[i][gc][0] : true) && + ((fromcontrols[gc][0] && gamecontroldefault[i][gc][1]) ? fromcontrols[gc][0] != gamecontroldefault[i][gc][1] : true) && + ((fromcontrols[gc][1] && gamecontroldefault[i][gc][0]) ? fromcontrols[gc][1] != gamecontroldefault[i][gc][0] : true) && + ((fromcontrols[gc][1] && gamecontroldefault[i][gc][1]) ? fromcontrols[gc][1] != gamecontroldefault[i][gc][1] : true)) + { + skipscheme = true; + break; + } + } + if (!skipscheme) + return i; + } + + return gcs_custom; } -#else -void G_Controldefault(void) + +void G_CopyControls(INT32 (*setupcontrols)[2], INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen) { - gamecontrol[gc_forward ][0] = 'w'; - gamecontrol[gc_backward ][0] = 's'; - gamecontrol[gc_strafeleft ][0] = 'a'; - gamecontrol[gc_straferight][0] = 'd'; - gamecontrol[gc_turnleft ][0] = KEY_LEFTARROW; - gamecontrol[gc_turnright ][0] = KEY_RIGHTARROW; - gamecontrol[gc_weaponnext ][0] = 'e'; - gamecontrol[gc_weaponnext ][1] = KEY_JOY1+1; // B - gamecontrol[gc_weaponprev ][0] = 'q'; - gamecontrol[gc_weaponprev ][1] = KEY_JOY1+2; // X - gamecontrol[gc_wepslot1 ][0] = '1'; - gamecontrol[gc_wepslot2 ][0] = '2'; - gamecontrol[gc_wepslot3 ][0] = '3'; - gamecontrol[gc_wepslot4 ][0] = '4'; - gamecontrol[gc_wepslot5 ][0] = '5'; - gamecontrol[gc_wepslot6 ][0] = '6'; - gamecontrol[gc_wepslot7 ][0] = '7'; - gamecontrol[gc_wepslot8 ][0] = '8'; - gamecontrol[gc_wepslot9 ][0] = '9'; - gamecontrol[gc_wepslot10 ][0] = '0'; - gamecontrol[gc_fire ][0] = KEY_RCTRL; - gamecontrol[gc_fire ][1] = KEY_MOUSE1+0; - gamecontrol[gc_firenormal ][0] = 'c'; - gamecontrol[gc_tossflag ][0] = '\''; - gamecontrol[gc_tossflag ][1] = KEY_JOY1+0; // A - gamecontrol[gc_use ][0] = KEY_LSHIFT; - gamecontrol[gc_use ][1] = KEY_JOY1+4; // LB - gamecontrol[gc_camtoggle ][0] = 'v'; - gamecontrol[gc_camtoggle ][1] = KEY_HAT1+0; // D-Pad Up - gamecontrol[gc_camleft ][0] = '['; - gamecontrol[gc_camright ][0] = ']'; - gamecontrol[gc_camreset ][0] = 'r'; - gamecontrol[gc_camreset ][1] = KEY_JOY1+3; // Y - gamecontrol[gc_lookup ][0] = KEY_UPARROW; - gamecontrol[gc_lookdown ][0] = KEY_DOWNARROW; - gamecontrol[gc_centerview ][0] = KEY_END; - gamecontrol[gc_centerview ][1] = KEY_JOY1+9; // Right Stick - gamecontrol[gc_talkkey ][0] = 't'; - gamecontrol[gc_talkkey ][1] = KEY_HAT1+2; // D-Pad Left - gamecontrol[gc_teamkey ][0] = 'y'; - gamecontrol[gc_scores ][0] = KEY_TAB; - gamecontrol[gc_scores ][1] = KEY_HAT1+3; // D-Pad Right - gamecontrol[gc_jump ][0] = KEY_SPACE; - gamecontrol[gc_jump ][1] = KEY_JOY1+5; // RB - gamecontrol[gc_console ][0] = KEY_CONSOLE; - gamecontrol[gc_pause ][0] = 'p'; - gamecontrol[gc_pause ][1] = KEY_JOY1+6; // Back - gamecontrol[gc_screenshot ][0] = KEY_F8; - gamecontrol[gc_screenshot ][1] = KEY_HAT1+1; // D-Pad Down - gamecontrol[gc_recordgif ][0] = KEY_F9; - gamecontrol[gc_viewpoint ][0] = KEY_F12; - gamecontrol[gc_systemmenu ][0] = KEY_JOY1+7; // Start - gamecontrolbis[gc_weaponnext][0] = KEY_2JOY1+1; // B - gamecontrolbis[gc_weaponprev][0] = KEY_2JOY1+2; // X - gamecontrolbis[gc_tossflag ][0] = KEY_2JOY1+0; // A - gamecontrolbis[gc_use ][0] = KEY_2JOY1+4; // LB - gamecontrolbis[gc_camreset ][0] = KEY_2JOY1+3; // Y - gamecontrolbis[gc_centerview][0] = KEY_2JOY1+9; // Right Stick - gamecontrolbis[gc_jump ][0] = KEY_2JOY1+5; // RB - //gamecontrolbis[gc_pause ][0] = KEY_2JOY1+6; // Back - //gamecontrolbis[gc_systemmenu][0] = KEY_2JOY1+7; // Start - gamecontrolbis[gc_camtoggle ][0] = KEY_2HAT1+0; // D-Pad Up - gamecontrolbis[gc_screenshot][0] = KEY_2HAT1+1; // D-Pad Down - //gamecontrolbis[gc_talkkey ][0] = KEY_2HAT1+2; // D-Pad Left - //gamecontrolbis[gc_scores ][0] = KEY_2HAT1+3; // D-Pad Right -#ifdef WMINPUT - gamecontrol[gc_forward ][0] = KEY_JOY1+02; //UP - gamecontrol[gc_backward ][0] = KEY_JOY1+03; //DOWN - gamecontrol[gc_turnleft ][0] = KEY_JOY1+04; //LEFT - gamecontrol[gc_turnright ][0] = KEY_JOY1+05; //RIGHT - gamecontrol[gc_weaponnext ][0] = KEY_JOY1+10; //y - gamecontrol[gc_weaponprev ][0] = KEY_JOY1+9; //x - gamecontrol[gc_fire ][0] = KEY_JOY1+12; //L - gamecontrol[gc_firenormal ][0] = KEY_JOY1+13; //R - gamecontrol[gc_use ][0] = KEY_JOY1+00; //B - gamecontrol[gc_use ][1] = KEY_JOY1+07; //b - gamecontrol[gc_jump ][0] = KEY_JOY1+01; //A - gamecontrol[gc_jump ][1] = KEY_JOY1+06; //a - gamecontrol[gc_pause ][0] = KEY_JOY1+18; //Home - gamecontrolbis[gc_forward ][0] = KEY_2JOY1+02; //UP - gamecontrolbis[gc_backward ][0] = KEY_2JOY1+03; //DOWN - gamecontrolbis[gc_turnleft ][0] = KEY_2JOY1+04; //LEFT - gamecontrolbis[gc_turnright ][0] = KEY_2JOY1+05; //RIGHT - gamecontrolbis[gc_weaponnext ][0] = KEY_2JOY1+10; //y - gamecontrolbis[gc_weaponprev ][0] = KEY_2JOY1+9; //x - gamecontrolbis[gc_fire ][0] = KEY_2JOY1+12; //L - gamecontrolbis[gc_firenormal ][0] = KEY_2JOY1+13; //R - gamecontrolbis[gc_use ][0] = KEY_2JOY1+00; //B - gamecontrolbis[gc_use ][1] = KEY_2JOY1+07; //b - gamecontrolbis[gc_jump ][0] = KEY_2JOY1+01; //A - gamecontrolbis[gc_jump ][1] = KEY_2JOY1+06; //a - gamecontrolbis[gc_pause ][0] = KEY_2JOY1+18; //Home -#endif -#ifdef _WII - gamecontrol[gc_forward ][1] = KEY_HAT1+00; //UP - gamecontrol[gc_backward ][1] = KEY_HAT1+01; //DOWN - gamecontrol[gc_straferight][1] = KEY_JOY1+16; //ZR - gamecontrol[gc_strafeleft ][1] = KEY_JOY1+15; //ZL - gamecontrol[gc_turnleft ][1] = KEY_HAT1+02; //LEFT - gamecontrol[gc_turnright ][1] = KEY_HAT1+03; //RIGHT - gamecontrol[gc_weaponnext ][1] = KEY_JOY1+11; //x - gamecontrol[gc_fire ][0] = KEY_JOY1+12; //y - gamecontrol[gc_fire ][1] = KEY_JOY1+01; //B - gamecontrol[gc_firenormal ][0] = KEY_JOY1+13; //L - gamecontrol[gc_firenormal ][1] = KEY_JOY1+00; //A - gamecontrol[gc_tossflag ][1] = KEY_JOY1+17; //Plus CC - gamecontrol[gc_use ][0] = KEY_JOY1+9; //a - gamecontrol[gc_use ][1] = KEY_JOY1+02; //1 - gamecontrol[gc_centerview ][1] = KEY_JOY1+14; //R - gamecontrol[gc_scores ][0] = KEY_JOY1+04; //Minus - gamecontrol[gc_scores ][1] = KEY_JOY1+18; //Minus - gamecontrol[gc_jump ][0] = KEY_JOY1+10; //b - gamecontrol[gc_jump ][1] = KEY_JOY1+3; //2 - gamecontrol[gc_pause ][0] = KEY_JOY1+06; //Home - gamecontrol[gc_pause ][1] = KEY_JOY1+19; //Home - gamecontrolbis[gc_forward ][1] = KEY_2HAT1+00; //UP - gamecontrolbis[gc_backward ][1] = KEY_2HAT1+01; //DOWN - gamecontrolbis[gc_straferight][1] = KEY_2JOY1+16; //ZR - gamecontrolbis[gc_strafeleft ][1] = KEY_2JOY1+15; //ZL - gamecontrolbis[gc_turnleft ][1] = KEY_2HAT1+02; //LEFT - gamecontrolbis[gc_turnright ][1] = KEY_2HAT1+03; //RIGHT - gamecontrolbis[gc_weaponnext ][1] = KEY_2JOY1+11; //x - gamecontrolbis[gc_fire ][0] = KEY_2JOY1+12; //y - gamecontrolbis[gc_fire ][1] = KEY_2JOY1+01; //B - gamecontrolbis[gc_firenormal ][0] = KEY_2JOY1+13; //L - gamecontrolbis[gc_firenormal ][1] = KEY_2JOY1+00; //A - gamecontrolbis[gc_tossflag ][1] = KEY_2JOY1+17; //Plus CC - gamecontrolbis[gc_use ][0] = KEY_2JOY1+9; //a - gamecontrolbis[gc_use ][1] = KEY_2JOY1+02; //1 - gamecontrolbis[gc_centerview ][1] = KEY_2JOY1+14; //R - gamecontrolbis[gc_scores ][0] = KEY_2JOY1+04; //Minus - gamecontrolbis[gc_scores ][1] = KEY_2JOY1+18; //Minus - gamecontrolbis[gc_jump ][0] = KEY_2JOY1+10; //b - gamecontrolbis[gc_jump ][1] = KEY_2JOY1+3; //2 - gamecontrolbis[gc_pause ][0] = KEY_2JOY1+06; //Home - gamecontrolbis[gc_pause ][1] = KEY_2JOY1+19; //Home -#endif + INT32 i, gc; + + for (i = 0; i < (gclist && gclen ? gclen : num_gamecontrols); i++) + { + gc = (gclist && gclen) ? gclist[i] : i; + setupcontrols[gc][0] = fromcontrols[gc][0]; + setupcontrols[gc][1] = fromcontrols[gc][1]; + } } -#endif -void G_SaveKeySetting(FILE *f) +void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis)[2]) { INT32 i; for (i = 1; i < num_gamecontrols; i++) { fprintf(f, "setcontrol \"%s\" \"%s\"", gamecontrolname[i], - G_KeynumToString(gamecontrol[i][0])); + G_KeynumToString(fromcontrols[i][0])); - if (gamecontrol[i][1]) - fprintf(f, " \"%s\"\n", G_KeynumToString(gamecontrol[i][1])); + if (fromcontrols[i][1]) + fprintf(f, " \"%s\"\n", G_KeynumToString(fromcontrols[i][1])); else fprintf(f, "\n"); } @@ -1330,10 +822,10 @@ void G_SaveKeySetting(FILE *f) for (i = 1; i < num_gamecontrols; i++) { fprintf(f, "setcontrol2 \"%s\" \"%s\"", gamecontrolname[i], - G_KeynumToString(gamecontrolbis[i][0])); + G_KeynumToString(fromcontrolsbis[i][0])); - if (gamecontrolbis[i][1]) - fprintf(f, " \"%s\"\n", G_KeynumToString(gamecontrolbis[i][1])); + if (fromcontrolsbis[i][1]) + fprintf(f, " \"%s\"\n", G_KeynumToString(fromcontrolsbis[i][1])); else fprintf(f, "\n"); } @@ -1390,7 +882,6 @@ static INT32 G_FilterKeyByVersion(INT32 numctrl, INT32 keyidx, INT32 player, INT else if (keyidx == 1 && *keynum2 == KEY_PAUSE) return -1; // skip setting control -#if !defined (DC) && !defined (_PSP) && !defined (GP2X) && !defined (_NDS) && !defined(WMINPUT) && !defined(_WII) if (GETMAJOREXECVERSION(cv_execversion.value) < 27 && ( // v2.1.22 numctrl == gc_weaponnext || numctrl == gc_weaponprev || numctrl == gc_tossflag || numctrl == gc_use || numctrl == gc_camreset || numctrl == gc_jump || @@ -1483,7 +974,6 @@ static INT32 G_FilterKeyByVersion(INT32 numctrl, INT32 keyidx, INT32 player, INT else return 0; } -#endif // All's good, so pass the keynum as-is if (keyidx == 1) diff --git a/src/g_input.h b/src/g_input.h index 8f4e9cb097d7c3f46c8f1ba76daf6008fcda2ec0..d3c6937817b91c050fd3f83d3539147b37362962 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -22,33 +22,10 @@ // keys (mousebuttons and joybuttons becomes keys) #define NUMKEYS 256 - -#ifdef _arch_dreamcast -#define MOUSEBUTTONS 5 -#define JOYBUTTONS 8 // 8 buttons -#define JOYHATS 2 // 2 hats -#define JOYAXISSET 3 // 3 Sets of 2 axises -#elif defined (_XBOX) -#define MOUSEBUTTONS 5 -#define JOYBUTTONS 12 // 12 buttons -#define JOYHATS 1 // 1 hat -#define JOYAXISSET 2 // 2 Sets of 2 axises -#elif defined (_PSP) -#define MOUSEBUTTONS 3 -#define JOYBUTTONS 14 // 10 buttons -#define JOYHATS 1 // 1 hat -#define JOYAXISSET 1 // 1 Set of 2 axises -#elif defined (_WII) -#define MOUSEBUTTONS 3 -#define JOYBUTTONS 20 // 20 buttons -#define JOYHATS 1 // 1 hat -#define JOYAXISSET 5 // 5 Sets of 2 axises -#else #define MOUSEBUTTONS 8 #define JOYBUTTONS 32 // 32 buttons #define JOYHATS 4 // 4 hats #define JOYAXISSET 4 // 4 Sets of 2 axises -#endif // // mouse and joystick buttons are handled as 'virtual' keys @@ -105,8 +82,6 @@ typedef enum gc_tossflag, gc_use, gc_camtoggle, - gc_camleft, - gc_camright, gc_camreset, gc_lookup, gc_lookdown, @@ -128,6 +103,14 @@ typedef enum num_gamecontrols } gamecontrols_e; +typedef enum +{ + gcs_custom, + gcs_fps, + gcs_platform, + num_gamecontrolschemes +} gamecontrolschemes_e; + // mouse values are used once extern consvar_t cv_mousesens, cv_mouseysens; extern consvar_t cv_mousesens2, cv_mouseysens2; @@ -145,9 +128,31 @@ extern UINT8 gamekeydown[NUMINPUTS]; // two key codes (or virtual key) per game control extern INT32 gamecontrol[num_gamecontrols][2]; extern INT32 gamecontrolbis[num_gamecontrols][2]; // secondary splitscreen player +extern INT32 gamecontroldefault[num_gamecontrolschemes][num_gamecontrols][2]; // default control storage, use 0 (gcs_custom) for memory retention +extern INT32 gamecontrolbisdefault[num_gamecontrolschemes][num_gamecontrols][2]; #define PLAYER1INPUTDOWN(gc) (gamekeydown[gamecontrol[gc][0]] || gamekeydown[gamecontrol[gc][1]]) #define PLAYER2INPUTDOWN(gc) (gamekeydown[gamecontrolbis[gc][0]] || gamekeydown[gamecontrolbis[gc][1]]) +#define num_gcl_tutorial_check 6 +#define num_gcl_tutorial_used 8 +#define num_gcl_tutorial_full 13 +#define num_gcl_movement 4 +#define num_gcl_camera 2 +#define num_gcl_movement_camera 6 +#define num_gcl_jump 1 +#define num_gcl_use 1 +#define num_gcl_jump_use 2 + +extern const INT32 gcl_tutorial_check[num_gcl_tutorial_check]; +extern const INT32 gcl_tutorial_used[num_gcl_tutorial_used]; +extern const INT32 gcl_tutorial_full[num_gcl_tutorial_full]; +extern const INT32 gcl_movement[num_gcl_movement]; +extern const INT32 gcl_camera[num_gcl_camera]; +extern const INT32 gcl_movement_camera[num_gcl_movement_camera]; +extern const INT32 gcl_jump[num_gcl_jump]; +extern const INT32 gcl_use[num_gcl_use]; +extern const INT32 gcl_jump_use[num_gcl_jump_use]; + // peace to my little coder fingers! // check a gamecontrol being active or not @@ -163,8 +168,10 @@ void G_ClearControlKeys(INT32 (*setupcontrols)[2], INT32 control); void G_ClearAllControlKeys(void); void Command_Setcontrol_f(void); void Command_Setcontrol2_f(void); -void G_Controldefault(void); -void G_SaveKeySetting(FILE *f); +void G_DefineDefaultControls(void); +INT32 G_GetControlScheme(INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen); +void G_CopyControls(INT32 (*setupcontrols)[2], INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen); +void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis)[2]); INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify); #endif diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c index 21fd85a33ce753b248774a66ba06acc4b224ba40..48393249214ff7dc7dd13051d88f5b50c2478a44 100644 --- a/src/hardware/hw_bsp.c +++ b/src/hardware/hw_bsp.c @@ -29,6 +29,7 @@ #include "../m_argv.h" #include "../i_video.h" #include "../w_wad.h" +#include "../p_setup.h" // levelfadecol // -------------------------------------------------------------------------- // This is global data for planes rendering diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index d49531bdf3cfa53dcdf5c1eac8d3df8bd7db50a9..01782164d05b5d2b11429bcc1b01abf3add85675 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -41,50 +41,340 @@ static INT32 blocksize, blockwidth, blockheight; INT32 patchformat = GR_TEXFMT_AP_88; // use alpha for holes INT32 textureformat = GR_TEXFMT_P_8; // use chromakey for hole -// sprite, use alpha and chroma key for hole -static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, - INT32 pblockwidth, INT32 pblockheight, INT32 blockmodulo, - INT32 ptexturewidth, INT32 ptextureheight, - INT32 originx, INT32 originy, // where to draw patch in surface block - const patch_t *realpatch, INT32 bpp) +static const INT32 format2bpp[16] = { - INT32 x, x1, x2; - INT32 col, ncols; - fixed_t xfrac, xfracstep; - fixed_t yfrac, yfracstep, position, count; - fixed_t scale_y; + 0, //0 + 0, //1 + 1, //2 GR_TEXFMT_ALPHA_8 + 1, //3 GR_TEXFMT_INTENSITY_8 + 1, //4 GR_TEXFMT_ALPHA_INTENSITY_44 + 1, //5 GR_TEXFMT_P_8 + 4, //6 GR_RGBA + 0, //7 + 0, //8 + 0, //9 + 2, //10 GR_TEXFMT_RGB_565 + 2, //11 GR_TEXFMT_ARGB_1555 + 2, //12 GR_TEXFMT_ARGB_4444 + 2, //13 GR_TEXFMT_ALPHA_INTENSITY_88 + 2, //14 GR_TEXFMT_AP_88 +}; + + +// This code was originally placed directly in HWR_DrawPatchInCache. +// It is now split from it for my sanity! (and the sanity of others) +// -- Monster Iestyn (13/02/19) +static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipmap_t *mipmap, + INT32 pblockheight, INT32 blockmodulo, + fixed_t yfracstep, fixed_t scale_y, + texpatch_t *originPatch, INT32 patchheight, + INT32 bpp) +{ + fixed_t yfrac, position, count; + UINT8 *dest; + const UINT8 *source; + INT32 topdelta, prevdelta = -1; + INT32 originy = 0; + + // for writing a pixel to dest RGBA_t colortemp; + UINT8 alpha; + UINT8 texel; + UINT16 texelu16; + + (void)patchheight; // This parameter is unused + + if (originPatch) // originPatch can be NULL here, unlike in the software version + originy = originPatch->originy; + + while (patchcol->topdelta != 0xff) + { + topdelta = patchcol->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + source = (const UINT8 *)patchcol + 3; + count = ((patchcol->length * scale_y) + (FRACUNIT/2)) >> FRACBITS; + position = originy + topdelta; + + yfrac = 0; + //yfracstep = (patchcol->length << FRACBITS) / count; + if (position < 0) + { + yfrac = -position<<FRACBITS; + count += (((position * scale_y) + (FRACUNIT/2)) >> FRACBITS); + position = 0; + } + + position = ((position * scale_y) + (FRACUNIT/2)) >> FRACBITS; + + if (position < 0) + position = 0; + + if (position + count >= pblockheight) + count = pblockheight - position; + + dest = block + (position*blockmodulo); + while (count > 0) + { + count--; + + texel = source[yfrac>>FRACBITS]; + + if (firetranslucent && (transtables[(texel<<8)+0x40000]!=texel)) + alpha = 0x80; + else + alpha = 0xff; + + //Hurdler: not perfect, but better than holes + if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX && (mipmap->flags & TF_CHROMAKEYED)) + texel = HWR_CHROMAKEY_EQUIVALENTCOLORINDEX; + //Hurdler: 25/04/2000: now support colormap in hardware mode + else if (mipmap->colormap) + texel = mipmap->colormap[texel]; + + // hope compiler will get this switch out of the loops (dreams...) + // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?) + // Alam: SRB2 uses Mingw, HUGS + switch (bpp) + { + case 2 : texelu16 = (UINT16)((alpha<<8) | texel); + memcpy(dest, &texelu16, sizeof(UINT16)); + break; + case 3 : colortemp = V_GetColor(texel); + memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); + break; + case 4 : colortemp = V_GetColor(texel); + colortemp.s.alpha = alpha; + memcpy(dest, &colortemp, sizeof(RGBA_t)); + break; + // default is 1 + default: *dest = texel; + break; + } + + dest += blockmodulo; + yfrac += yfracstep; + } + patchcol = (const column_t *)((const UINT8 *)patchcol + patchcol->length + 4); + } +} + +static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, GLMipmap_t *mipmap, + INT32 pblockheight, INT32 blockmodulo, + fixed_t yfracstep, fixed_t scale_y, + texpatch_t *originPatch, INT32 patchheight, + INT32 bpp) +{ + fixed_t yfrac, position, count; UINT8 *dest; const UINT8 *source; - const column_t *patchcol; + INT32 topdelta, prevdelta = -1; + INT32 originy = 0; + + // for writing a pixel to dest + RGBA_t colortemp; UINT8 alpha; - UINT8 *block = mipmap->grInfo.data; UINT8 texel; UINT16 texelu16; - x1 = originx; - x2 = x1 + SHORT(realpatch->width); + if (originPatch) // originPatch can be NULL here, unlike in the software version + originy = originPatch->originy; + + while (patchcol->topdelta != 0xff) + { + topdelta = patchcol->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + topdelta = patchheight-patchcol->length-topdelta; + source = (const UINT8 *)patchcol + 3; + count = ((patchcol->length * scale_y) + (FRACUNIT/2)) >> FRACBITS; + position = originy + topdelta; + + yfrac = (patchcol->length-1) << FRACBITS; + + if (position < 0) + { + yfrac += position<<FRACBITS; + count += (((position * scale_y) + (FRACUNIT/2)) >> FRACBITS); + position = 0; + } + + position = ((position * scale_y) + (FRACUNIT/2)) >> FRACBITS; + + if (position < 0) + position = 0; + + if (position + count >= pblockheight) + count = pblockheight - position; + + dest = block + (position*blockmodulo); + while (count > 0) + { + count--; + + texel = source[yfrac>>FRACBITS]; + + if (firetranslucent && (transtables[(texel<<8)+0x40000]!=texel)) + alpha = 0x80; + else + alpha = 0xff; + + //Hurdler: not perfect, but better than holes + if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX && (mipmap->flags & TF_CHROMAKEYED)) + texel = HWR_CHROMAKEY_EQUIVALENTCOLORINDEX; + //Hurdler: 25/04/2000: now support colormap in hardware mode + else if (mipmap->colormap) + texel = mipmap->colormap[texel]; + + // hope compiler will get this switch out of the loops (dreams...) + // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?) + // Alam: SRB2 uses Mingw, HUGS + switch (bpp) + { + case 2 : texelu16 = (UINT16)((alpha<<8) | texel); + memcpy(dest, &texelu16, sizeof(UINT16)); + break; + case 3 : colortemp = V_GetColor(texel); + memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); + break; + case 4 : colortemp = V_GetColor(texel); + colortemp.s.alpha = alpha; + memcpy(dest, &colortemp, sizeof(RGBA_t)); + break; + // default is 1 + default: *dest = texel; + break; + } + + dest += blockmodulo; + yfrac -= yfracstep; + } + patchcol = (const column_t *)((const UINT8 *)patchcol + patchcol->length + 4); + } +} + + +// Simplified patch caching function +// for use by sprites and other patches that are not part of a wall texture +// no alpha or flipping should be present since we do not want non-texture graphics to have them +// no offsets are used either +// -- Monster Iestyn (13/02/19) +static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, + INT32 pblockwidth, INT32 pblockheight, + INT32 pwidth, INT32 pheight, + const patch_t *realpatch) +{ + INT32 ncols; + fixed_t xfrac, xfracstep; + fixed_t yfracstep, scale_y; + const column_t *patchcol; + UINT8 *block = mipmap->grInfo.data; + INT32 bpp; + INT32 blockmodulo; + + if (pwidth <= 0 || pheight <= 0) + return; + + ncols = (pwidth * pblockwidth) / pwidth; + + // source advance + xfrac = 0; + xfracstep = (pwidth << FRACBITS) / pblockwidth; + yfracstep = (pheight << FRACBITS) / pblockheight; + scale_y = (pblockheight << FRACBITS) / pheight; + + bpp = format2bpp[mipmap->grInfo.format]; + + if (bpp < 1 || bpp > 4) + I_Error("HWR_DrawPatchInCache: no drawer defined for this bpp (%d)\n",bpp); + + // NOTE: should this actually be pblockwidth*bpp? + blockmodulo = blockwidth*bpp; + + // Draw each column to the block cache + for (; ncols--; block += bpp, xfrac += xfracstep) + { + patchcol = (const column_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[xfrac>>FRACBITS])); + + HWR_DrawColumnInCache(patchcol, block, mipmap, + pblockheight, blockmodulo, + yfracstep, scale_y, + NULL, pheight, // not that pheight is going to get used anyway... + bpp); + } +} + +// This function we use for caching patches that belong to textures +static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, + INT32 pblockwidth, INT32 pblockheight, + texture_t *texture, texpatch_t *patch, + const patch_t *realpatch) +{ + INT32 x, x1, x2; + INT32 col, ncols; + fixed_t xfrac, xfracstep; + fixed_t yfracstep, scale_y; + const column_t *patchcol; + UINT8 *block = mipmap->grInfo.data; + INT32 bpp; + INT32 blockmodulo; + INT32 width, height; + // Column drawing function pointer. + static void (*ColumnDrawerPointer)(const column_t *patchcol, UINT8 *block, GLMipmap_t *mipmap, + INT32 pblockheight, INT32 blockmodulo, + fixed_t yfracstep, fixed_t scale_y, + texpatch_t *originPatch, INT32 patchheight, + INT32 bpp); + + if (texture->width <= 0 || texture->height <= 0) + return; + + /*if ((patch->style == AST_TRANSLUCENT) && (patch->alpha <= (10*255/11))) // Alpha style set to translucent? Is the alpha small enough for translucency? + { + if (patch->alpha < 255/11) // Is the patch way too translucent? Don't render then. + continue; + ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawTransFlippedColumnInCache : HWR_DrawTransColumnInCache; + } + else*/ + { + ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawFlippedColumnInCache : HWR_DrawColumnInCache; + } + + x1 = patch->originx; + width = SHORT(realpatch->width); + height = SHORT(realpatch->height); + x2 = x1 + width; + + if (x1 > texture->width || x2 < 0) + return; // patch not located within texture's x bounds, ignore + + if (patch->originy > texture->height || (patch->originy + height) < 0) + return; // patch not located within texture's y bounds, ignore + + // patch is actually inside the texture! + // now check if texture is partly off-screen and adjust accordingly + // left edge if (x1 < 0) x = 0; else x = x1; - if (x2 > ptexturewidth) - x2 = ptexturewidth; + // right edge + if (x2 > texture->width) + x2 = texture->width; - if (!ptexturewidth) - return; - col = x * pblockwidth / ptexturewidth; - ncols = ((x2 - x) * pblockwidth) / ptexturewidth; + col = x * pblockwidth / texture->width; + ncols = ((x2 - x) * pblockwidth) / texture->width; /* - CONS_Debug(DBG_RENDER, "patch %dx%d texture %dx%d block %dx%d\n", SHORT(realpatch->width), - SHORT(realpatch->height), - ptexturewidth, - textureheight, - pblockwidth,pblockheight); + CONS_Debug(DBG_RENDER, "patch %dx%d texture %dx%d block %dx%d\n", + width, height, + texture->width, texture->height, + pblockwidth, pblockheight); CONS_Debug(DBG_RENDER, " col %d ncols %d x %d\n", col, ncols, x); */ @@ -93,90 +383,31 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, if (x1 < 0) xfrac = -x1<<FRACBITS; - xfracstep = (ptexturewidth << FRACBITS) / pblockwidth; - yfracstep = (ptextureheight<< FRACBITS) / pblockheight; + xfracstep = (texture->width << FRACBITS) / pblockwidth; + yfracstep = (texture->height<< FRACBITS) / pblockheight; + scale_y = (pblockheight << FRACBITS) / texture->height; + + bpp = format2bpp[mipmap->grInfo.format]; + if (bpp < 1 || bpp > 4) I_Error("HWR_DrawPatchInCache: no drawer defined for this bpp (%d)\n",bpp); + // NOTE: should this actually be pblockwidth*bpp? + blockmodulo = blockwidth*bpp; + + // Draw each column to the block cache for (block += col*bpp; ncols--; block += bpp, xfrac += xfracstep) { - INT32 topdelta, prevdelta = -1; - patchcol = (const column_t *)((const UINT8 *)realpatch - + LONG(realpatch->columnofs[xfrac>>FRACBITS])); - - scale_y = (pblockheight << FRACBITS) / ptextureheight; - - while (patchcol->topdelta != 0xff) - { - topdelta = patchcol->topdelta; - if (topdelta <= prevdelta) - topdelta += prevdelta; - prevdelta = topdelta; - source = (const UINT8 *)patchcol + 3; - count = ((patchcol->length * scale_y) + (FRACUNIT/2)) >> FRACBITS; - position = originy + topdelta; - - yfrac = 0; - //yfracstep = (patchcol->length << FRACBITS) / count; - if (position < 0) - { - yfrac = -position<<FRACBITS; - count += (((position * scale_y) + (FRACUNIT/2)) >> FRACBITS); - position = 0; - } - - position = ((position * scale_y) + (FRACUNIT/2)) >> FRACBITS; - - if (position < 0) - position = 0; - - if (position + count >= pblockheight) - count = pblockheight - position; + if (patch->flip & 1) + patchcol = (const column_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[(width-1)-(xfrac>>FRACBITS)])); + else + patchcol = (const column_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[xfrac>>FRACBITS])); - dest = block + (position*blockmodulo); - while (count > 0) - { - count--; - - texel = source[yfrac>>FRACBITS]; - - if (firetranslucent && (transtables[(texel<<8)+0x40000]!=texel)) - alpha = 0x80; - else - alpha = 0xff; - - //Hurdler: not perfect, but better than holes - if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX && (mipmap->flags & TF_CHROMAKEYED)) - texel = HWR_CHROMAKEY_EQUIVALENTCOLORINDEX; - //Hurdler: 25/04/2000: now support colormap in hardware mode - else if (mipmap->colormap) - texel = mipmap->colormap[texel]; - - // hope compiler will get this switch out of the loops (dreams...) - // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?) - // Alam: SRB2 uses Mingw, HUGS - switch (bpp) - { - case 2 : texelu16 = (UINT16)((alpha<<8) | texel); - memcpy(dest, &texelu16, sizeof(UINT16)); - break; - case 3 : colortemp = V_GetColor(texel); - memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); - break; - case 4 : colortemp = V_GetColor(texel); - colortemp.s.alpha = alpha; - memcpy(dest, &colortemp, sizeof(RGBA_t)); - break; - // default is 1 - default: *dest = texel; - break; - } - - dest += blockmodulo; - yfrac += yfracstep; - } - patchcol = (const column_t *)((const UINT8 *)patchcol + patchcol->length + 4); - } + ColumnDrawerPointer(patchcol, block, mipmap, + pblockheight, blockmodulo, + yfracstep, scale_y, + patch, height, + bpp); } } @@ -300,26 +531,6 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, //CONS_Debug(DBG_RENDER, "Width is %d, Height is %d\n", blockwidth, blockheight); } - -static const INT32 format2bpp[16] = -{ - 0, //0 - 0, //1 - 1, //2 GR_TEXFMT_ALPHA_8 - 1, //3 GR_TEXFMT_INTENSITY_8 - 1, //4 GR_TEXFMT_ALPHA_INTENSITY_44 - 1, //5 GR_TEXFMT_P_8 - 4, //6 GR_RGBA - 0, //7 - 0, //8 - 0, //9 - 2, //10 GR_TEXFMT_RGB_565 - 2, //11 GR_TEXFMT_ARGB_1555 - 2, //12 GR_TEXFMT_ARGB_4444 - 2, //13 GR_TEXFMT_ALPHA_INTENSITY_88 - 2, //14 GR_TEXFMT_AP_88 -}; - static UINT8 *MakeBlock(GLMipmap_t *grMipmap) { UINT8 *block; @@ -403,13 +614,10 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) { realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); - HWR_DrawPatchInCache(&grtex->mipmap, + HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, - blockwidth*format2bpp[grtex->mipmap.grInfo.format], - texture->width, texture->height, - patch->originx, patch->originy, - realpatch, - format2bpp[grtex->mipmap.grInfo.format]); + texture, patch, + realpatch); Z_Unlock(realpatch); } //Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :( @@ -484,11 +692,8 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm HWR_DrawPatchInCache(grMipmap, newwidth, newheight, - blockwidth*format2bpp[grMipmap->grInfo.format], grPatch->width, grPatch->height, - 0, 0, - patch, - format2bpp[grMipmap->grInfo.format]); + patch); } grPatch->max_s = (float)newwidth / (float)blockwidth; @@ -532,8 +737,8 @@ void HWR_FreeTextureCache(void) // free all hardware-converted graphics cached in the heap // our gool is only the textures since user of the texture is the texture cache - Z_FreeTags(PU_HWRCACHE, PU_HWRCACHE); - Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRCACHE_UNLOCKED); + Z_FreeTag(PU_HWRCACHE); + Z_FreeTag(PU_HWRCACHE_UNLOCKED); // Alam: free the Z_Blocks before freeing it's users @@ -580,8 +785,8 @@ void HWR_SetPalette(RGBA_t *palette) // now flush data texture cache so 32 bit texture are recomputed if (patchformat == GR_RGBA || textureformat == GR_RGBA) { - Z_FreeTags(PU_HWRCACHE, PU_HWRCACHE); - Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRCACHE_UNLOCKED); + Z_FreeTag(PU_HWRCACHE); + Z_FreeTag(PU_HWRCACHE_UNLOCKED); } } diff --git a/src/hardware/hw_data.h b/src/hardware/hw_data.h index 4bbc578ed9da7530e67b4234c96e68802325402f..44929dd67ba00267173afde6f4fa55a50440c107 100644 --- a/src/hardware/hw_data.h +++ b/src/hardware/hw_data.h @@ -20,7 +20,7 @@ #ifndef _HWR_DATA_ #define _HWR_DATA_ -#if defined (_WIN32) && !defined (__CYGWIN__) && !defined (_XBOX) +#if defined (_WIN32) && !defined (__CYGWIN__) //#define WIN32_LEAN_AND_MEAN #define RPC_NO_WINDOWS_H #include <windows.h> diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index df0f39ece226fde29021020e0f07988bf192eda3..83d601b8745e979003ea7ac8832dafdb7527fae9 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -41,14 +41,8 @@ typedef unsigned char FBOOLEAN; // ========================================================================== // byte value for paletted graphics, which represent the transparent color -#ifdef _NDS -// NDS is hardwired to use zero as transparent color -#define HWR_PATCHES_CHROMAKEY_COLORINDEX 0 -#define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 1 -#else -#define HWR_PATCHES_CHROMAKEY_COLORINDEX 247 -#define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 220 -#endif +#define HWR_PATCHES_CHROMAKEY_COLORINDEX 255 +#define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 130 // the chroma key color shows on border sprites, set it to black #define HWR_PATCHES_CHROMAKEY_COLORVALUE (0x00000000) //RGBA format as in grSstWinOpen() diff --git a/src/hardware/hw_dll.h b/src/hardware/hw_dll.h index 6b9f4d538860d29a61967ccd7e2c538d65fecdaa..452e9037c2dab8f14bf1798113a22b87f3f95049 100644 --- a/src/hardware/hw_dll.h +++ b/src/hardware/hw_dll.h @@ -40,14 +40,14 @@ #define EXPORT #endif #endif - #if defined (_WIN32) && !defined (_XBOX) + #ifdef _WIN32 #define HWRAPI(fn) WINAPI fn #else #define HWRAPI(fn) fn #endif #else // _CREATE_DLL_ #define EXPORT typedef - #if defined (_WIN32) && !defined (_XBOX) + #ifdef _WIN32 #define HWRAPI(fn) (WINAPI *fn) #else #define HWRAPI(fn) (*fn) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index cd2c95237aa17ef7f891643f6a4b8261d5a248f8..dd9fa8423b21897fc8894d37bfd4e59486be171f 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -33,6 +33,8 @@ #include "../z_zone.h" #include "../v_video.h" #include "../st_stuff.h" +#include "../p_local.h" // stplyr +#include "../g_game.h" // players #include <fcntl.h> #include "../i_video.h" // for rendermode != render_glide @@ -147,7 +149,9 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, // | /| // |/ | // 0--1 - float dupx, dupy, fscale, fwidth, fheight; + float dupx, dupy, fscalew, fscaleh, fwidth, fheight; + + UINT8 perplayershuffle = 0; if (alphalevel >= 10 && alphalevel < 13) return; @@ -177,7 +181,7 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, } dupx = dupy = (dupx < dupy ? dupx : dupy); - fscale = FIXED_TO_FLOAT(pscale); + fscalew = fscaleh = FIXED_TO_FLOAT(pscale); // See my comments in v_video.c's V_DrawFixedPatch // -- Monster Iestyn 29/10/18 @@ -186,13 +190,13 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, // left offset if (option & V_FLIP) - offsetx = (float)(SHORT(gpatch->width) - SHORT(gpatch->leftoffset)) * fscale; + offsetx = (float)(SHORT(gpatch->width) - SHORT(gpatch->leftoffset)) * fscalew; else - offsetx = (float)SHORT(gpatch->leftoffset) * fscale; + offsetx = (float)SHORT(gpatch->leftoffset) * fscalew; // top offset // TODO: make some kind of vertical version of V_FLIP, maybe by deprecating V_OFFSET in future?!? - offsety = (float)SHORT(gpatch->topoffset) * fscale; + offsety = (float)SHORT(gpatch->topoffset) * fscaleh; if ((option & (V_NOSCALESTART|V_OFFSET)) == (V_NOSCALESTART|V_OFFSET)) // Multiply by dupx/dupy for crosshairs { @@ -204,8 +208,73 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, cy -= offsety; } - if (option & V_SPLITSCREEN) + if (splitscreen && (option & V_PERPLAYER)) + { + float adjusty = ((option & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f; + fscaleh /= 2; cy /= 2; +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + float adjustx = ((option & V_NOSCALESTART) ? vid.width : BASEVIDWIDTH)/2.0f; + fscalew /= 2; + cx /= 2; + if (stplyr == &players[displayplayer]) + { + if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(option & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; + option &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + } + else if (stplyr == &players[secondarydisplayplayer]) + { + if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(option & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; + cx += adjustx; + option &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; + } + else if (stplyr == &players[thirddisplayplayer]) + { + if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(option & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; + cy += adjusty; + option &= ~V_SNAPTOTOP|V_SNAPTORIGHT; + } + else if (stplyr == &players[fourthdisplayplayer]) + { + if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(option & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; + cx += adjustx; + cy += adjusty; + option &= ~V_SNAPTOTOP|V_SNAPTOLEFT; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[displayplayer]) + { + if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle = 1; + option &= ~V_SNAPTOBOTTOM; + } + else //if (stplyr == &players[secondarydisplayplayer]) + { + if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle = 2; + cy += adjusty; + option &= ~V_SNAPTOTOP; + } + } + } if (!(option & V_NOSCALESTART)) { @@ -233,23 +302,29 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)); else if (!(option & V_SNAPTOLEFT)) cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2; + if (perplayershuffle & 4) + cx -= ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/4; + else if (perplayershuffle & 8) + cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/4; } if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f) { - if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM)) - cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy)); - else if (option & V_SNAPTOBOTTOM) + if (option & V_SNAPTOBOTTOM) cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)); else if (!(option & V_SNAPTOTOP)) cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2; + if (perplayershuffle & 1) + cy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/4; + else if (perplayershuffle & 2) + cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/4; } } } - if (pscale != FRACUNIT) + if (pscale != FRACUNIT || (splitscreen && option & V_PERPLAYER)) { - fwidth = (float)SHORT(gpatch->width) * fscale * dupx; - fheight = (float)SHORT(gpatch->height) * fscale * dupy; + fwidth = (float)SHORT(gpatch->width) * fscalew * dupx; + fheight = (float)SHORT(gpatch->height) * fscaleh * dupy; } else { @@ -352,6 +427,8 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal dupx = dupy = (dupx < dupy ? dupx : dupy); fscale = FIXED_TO_FLOAT(pscale); + // fuck it, no GL support for croppedpatch v_perplayer right now. it's not like it's accessible to Lua or anything, and we only use it for menus... + cy -= (float)SHORT(gpatch->topoffset) * fscale; cx -= (float)SHORT(gpatch->leftoffset) * fscale; @@ -384,9 +461,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal } if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f) { - if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM)) - cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy)); - else if (option & V_SNAPTOBOTTOM) + if (option & V_SNAPTOBOTTOM) cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)); else if (!(option & V_SNAPTOTOP)) cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2; @@ -397,12 +472,6 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal fwidth = w; fheight = h; - if (fwidth > w - sx) - fwidth = w - sx; - - if (fheight > h - sy) - fheight = h - sy; - if (fwidth > SHORT(gpatch->width)) fwidth = SHORT(gpatch->width); @@ -437,10 +506,17 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].sow = v[3].sow = ((sx)/(float)SHORT(gpatch->width) )*gpatch->max_s; - v[2].sow = v[1].sow = ((w )/(float)SHORT(gpatch->width) )*gpatch->max_s; - v[0].tow = v[1].tow = ((sy)/(float)SHORT(gpatch->height))*gpatch->max_t; - v[2].tow = v[3].tow = ((h )/(float)SHORT(gpatch->height))*gpatch->max_t; + v[0].sow = v[3].sow = ((sx )/(float)SHORT(gpatch->width) )*gpatch->max_s; + if (sx + w > SHORT(gpatch->width)) + v[2].sow = v[1].sow = gpatch->max_s; + else + v[2].sow = v[1].sow = ((sx+w)/(float)SHORT(gpatch->width) )*gpatch->max_s; + + v[0].tow = v[1].tow = ((sy )/(float)SHORT(gpatch->height))*gpatch->max_t; + if (sy + h > SHORT(gpatch->height)) + v[2].tow = v[3].tow = gpatch->max_t; + else + v[2].tow = v[3].tow = ((sy+h)/(float)SHORT(gpatch->height))*gpatch->max_t; flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest; @@ -584,18 +660,14 @@ void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum // | /| // |/ | // 0--1 -void HWR_FadeScreenMenuBack(UINT32 color, INT32 height) +void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength) { FOutVector v[4]; FSurfaceInfo Surf; - // setup some neat-o translucency effect - if (!height) //cool hack 0 height is full height - height = vid.height; - v[0].x = v[3].x = -1.0f; v[2].x = v[1].x = 1.0f; - v[0].y = v[1].y = 1.0f-((height<<1)/(float)vid.height); + v[0].y = v[1].y = -1.0f; v[2].y = v[3].y = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; @@ -604,8 +676,16 @@ void HWR_FadeScreenMenuBack(UINT32 color, INT32 height) v[0].tow = v[1].tow = 1.0f; v[2].tow = v[3].tow = 0.0f; - Surf.FlatColor.rgba = UINT2RGBA(color); - Surf.FlatColor.s.alpha = (UINT8)((0xff/2) * ((float)height / vid.height)); //calum: varies console alpha + if (color & 0xFF00) // Do COLORMAP fade. + { + Surf.FlatColor.rgba = UINT2RGBA(0x01010160); + Surf.FlatColor.s.alpha = (strength*8); + } + else // Do TRANSMAP** fade. + { + Surf.FlatColor.rgba = pLocalPalette[color].rgba; + Surf.FlatColor.s.alpha = (UINT8)(strength*25.5f); + } HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } @@ -636,6 +716,32 @@ void HWR_DrawConsoleBack(UINT32 color, INT32 height) HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } +// Very similar to HWR_DrawConsoleBack, except we draw from the middle(-ish) of the screen to the bottom. +void HWR_DrawTutorialBack(UINT32 color, INT32 boxheight) +{ + FOutVector v[4]; + FSurfaceInfo Surf; + INT32 height = (boxheight * 4) + (boxheight/2)*5; // 4 lines of space plus gaps between and some leeway + + // setup some neat-o translucency effect + + v[0].x = v[3].x = -1.0f; + v[2].x = v[1].x = 1.0f; + v[0].y = v[1].y = -1.0f; + v[2].y = v[3].y = -1.0f+((height<<1)/(float)vid.height); + v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; + + v[0].sow = v[3].sow = 0.0f; + v[2].sow = v[1].sow = 1.0f; + v[0].tow = v[1].tow = 1.0f; + v[2].tow = v[3].tow = 0.0f; + + Surf.FlatColor.rgba = UINT2RGBA(color); + Surf.FlatColor.s.alpha = (color == 0 ? 0xC0 : 0x80); // make black darker, like software + + HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); +} + // ========================================================================== // R_DRAW.C STUFF @@ -904,6 +1010,8 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) FSurfaceInfo Surf; float fx, fy, fw, fh; + UINT8 perplayershuffle = 0; + if (w < 0 || h < 0) return; // consistency w/ software @@ -912,6 +1020,74 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) // |/ | // 0--1 + if (splitscreen && (color & V_PERPLAYER)) + { + fixed_t adjusty = ((color & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f; + h >>= 1; + y >>= 1; +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + fixed_t adjustx = ((color & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f; + w >>= 1; + x >>= 1; + if (stplyr == &players[displayplayer]) + { + if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; + color &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + } + else if (stplyr == &players[secondarydisplayplayer]) + { + if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; + x += adjustx; + color &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; + } + else if (stplyr == &players[thirddisplayplayer]) + { + if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; + y += adjusty; + color &= ~V_SNAPTOTOP|V_SNAPTORIGHT; + } + else //if (stplyr == &players[fourthdisplayplayer]) + { + if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; + x += adjustx; + y += adjusty; + color &= ~V_SNAPTOTOP|V_SNAPTOLEFT; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[displayplayer]) + { + if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + color &= ~V_SNAPTOBOTTOM; + } + else //if (stplyr == &players[secondarydisplayplayer]) + { + if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + y += adjusty; + color &= ~V_SNAPTOTOP; + } + } + } + fx = (float)x; fy = (float)y; fw = (float)w; @@ -944,6 +1120,10 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)); else if (!(color & V_SNAPTOLEFT)) fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2; + if (perplayershuffle & 4) + fx -= ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4; + else if (perplayershuffle & 8) + fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4; } if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f) { @@ -952,6 +1132,10 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)); else if (!(color & V_SNAPTOTOP)) fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2; + if (perplayershuffle & 1) + fy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4; + else if (perplayershuffle & 2) + fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4; } } diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index bdf21946468b687344318c1ae84185c6f2df7d18..9656e54e9b1d44df9bc921cbb544a03e8101a26d 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -71,7 +71,6 @@ typedef struct gr_vissprite_s struct gr_vissprite_s *prev; struct gr_vissprite_s *next; float x1, x2; - float z1, z2; float tz, ty; lumpnum_t patchlumpnum; boolean flip; @@ -82,6 +81,7 @@ typedef struct gr_vissprite_s //Hurdler: 25/04/2000: now support colormap in hardware mode UINT8 *colormap; INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing + float z1, z2; } gr_vissprite_t; // -------- diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index a93e96dc3d3e27ea2497b0230c90812ad363744f..8baa547af31bf94bfa0f252e89d0909609b71c19 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -62,7 +62,7 @@ static dynlights_t *dynlights = &view_dynlights[0]; light_t lspr[NUMLIGHTS] = { // type offset x, y coronas color, c_size,light color,l_radius, sqr radius computed at init - // UNDEFINED: 0 + // NOLIGHT: 0 { UNDEFINED_SPR, 0.0f, 0.0f, 0x00000000, 24.0f, 0x00000000, 0.0f, 0.0f}, // weapons // RINGSPARK_L @@ -151,10 +151,9 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_POSS &lspr[NOLIGHT], // SPR_SPOS &lspr[NOLIGHT], // SPR_FISH - &lspr[NOLIGHT], // SPR_BUZZ Graue 03-10-2004 - &lspr[NOLIGHT], // SPR_RBUZ Graue 03-10-2004 + &lspr[NOLIGHT], // SPR_BUZZ + &lspr[NOLIGHT], // SPR_RBUZ &lspr[NOLIGHT], // SPR_JETB - &lspr[NOLIGHT], // SPR_JETW &lspr[NOLIGHT], // SPR_JETG &lspr[NOLIGHT], // SPR_CCOM &lspr[NOLIGHT], // SPR_DETN @@ -162,19 +161,25 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_TRET &lspr[NOLIGHT], // SPR_TURR &lspr[NOLIGHT], // SPR_SHRP + &lspr[NOLIGHT], // SPR_CRAB &lspr[NOLIGHT], // SPR_JJAW &lspr[NOLIGHT], // SPR_SNLR &lspr[NOLIGHT], // SPR_VLTR &lspr[NOLIGHT], // SPR_PNTY &lspr[NOLIGHT], // SPR_ARCH &lspr[NOLIGHT], // SPR_CBFS + &lspr[JETLIGHT_L], // SPR_STAB &lspr[NOLIGHT], // SPR_SPSH &lspr[NOLIGHT], // SPR_ESHI &lspr[NOLIGHT], // SPR_GSNP + &lspr[NOLIGHT], // SPR_GSNL + &lspr[NOLIGHT], // SPR_GSNH &lspr[NOLIGHT], // SPR_MNUS + &lspr[NOLIGHT], // SPR_MNUD &lspr[NOLIGHT], // SPR_SSHL &lspr[NOLIGHT], // SPR_UNID - &lspr[NOLIGHT], // SPR_BBUZ + &lspr[NOLIGHT], // SPR_CANA + &lspr[NOLIGHT], // SPR_CANG // Generic Boos Items &lspr[JETLIGHT_L], // SPR_JETF // Boss jet fumes @@ -199,7 +204,11 @@ light_t *t_lspr[NUMSPRITES] = &lspr[REDBALL_L], // SPR_EFIR // Boss 5 (Arid Canyon) - &lspr[NOLIGHT], // SPR_EGGQ + &lspr[NOLIGHT], //SPR_FANG // replaces EGGQ + &lspr[NOLIGHT], //SPR_FBOM + &lspr[NOLIGHT], //SPR_FSGN + &lspr[REDBALL_L], //SPR_BARX // bomb explosion (also used by barrel) + &lspr[NOLIGHT], //SPR_BARD // bomb dust (also used by barrel) // Boss 6 (Red Volcano) &lspr[NOLIGHT], // SPR_EEGR @@ -226,48 +235,55 @@ light_t *t_lspr[NUMSPRITES] = // Collectible Items &lspr[NOLIGHT], // SPR_RING &lspr[NOLIGHT], // SPR_TRNG - &lspr[NOLIGHT], // SPR_EMMY - &lspr[BLUEBALL_L], // SPR_TOKE - &lspr[REDBALL_L], // SPR_RFLG - &lspr[BLUEBALL_L], // SPR_BFLG - &lspr[NOLIGHT], // SPR_NWNG + &lspr[NOLIGHT], // SPR_TOKE + &lspr[REDBALL_L], // SPR_RFLG + &lspr[BLUEBALL_L], // SPR_BFLG + &lspr[NOLIGHT], // SPR_SPHR + &lspr[NOLIGHT], // SPR_NCHP + &lspr[NOLIGHT], // SPR_NSTR &lspr[NOLIGHT], // SPR_EMBM &lspr[NOLIGHT], // SPR_CEMG - &lspr[NOLIGHT], // SPR_EMER + &lspr[NOLIGHT], // SPR_SHRD // Interactive Objects - &lspr[NOLIGHT], // SPR_FANS - &lspr[NOLIGHT], // SPR_BUBL + &lspr[NOLIGHT], // SPR_BBLS &lspr[NOLIGHT], // SPR_SIGN - &lspr[NOLIGHT], // SPR_STEM &lspr[NOLIGHT], // SPR_SPIK &lspr[NOLIGHT], // SPR_SFLM &lspr[NOLIGHT], // SPR_USPK + &lspr[NOLIGHT], // SPR_WSPK + &lspr[NOLIGHT], // SPR_WSPB &lspr[NOLIGHT], // SPR_STPT &lspr[NOLIGHT], // SPR_BMNE // Monitor Boxes - &lspr[NOLIGHT], // SPR_SRBX - &lspr[NOLIGHT], // SPR_RRBX - &lspr[NOLIGHT], // SPR_BRBX - &lspr[NOLIGHT], // SPR_SHTV - &lspr[NOLIGHT], // SPR_PINV - &lspr[NOLIGHT], // SPR_YLTV - &lspr[NOLIGHT], // SPR_BLTV - &lspr[NOLIGHT], // SPR_BKTV - &lspr[NOLIGHT], // SPR_WHTV - &lspr[NOLIGHT], // SPR_GRTV - &lspr[NOLIGHT], // SPR_ELTV - &lspr[NOLIGHT], // SPR_EGGB - &lspr[NOLIGHT], // SPR_MIXU - &lspr[NOLIGHT], // SPR_RECY - &lspr[NOLIGHT], // SPR_QUES - &lspr[NOLIGHT], // SPR_GBTV - &lspr[NOLIGHT], // SPR_PRUP - &lspr[NOLIGHT], // SPR_PTTV - - // Monitor Miscellany - &lspr[NOLIGHT], // SPR_MTEX + &lspr[NOLIGHT], // SPR_MSTV + &lspr[NOLIGHT], // SPR_XLTV + + &lspr[NOLIGHT], // SPR_TRRI + &lspr[NOLIGHT], // SPR_TBRI + + &lspr[NOLIGHT], // SPR_TVRI + &lspr[NOLIGHT], // SPR_TVPI + &lspr[NOLIGHT], // SPR_TVAT + &lspr[NOLIGHT], // SPR_TVFO + &lspr[NOLIGHT], // SPR_TVAR + &lspr[NOLIGHT], // SPR_TVWW + &lspr[NOLIGHT], // SPR_TVEL + &lspr[NOLIGHT], // SPR_TVSS + &lspr[NOLIGHT], // SPR_TVIV + &lspr[NOLIGHT], // SPR_TV1U + &lspr[NOLIGHT], // SPR_TV1P + &lspr[NOLIGHT], // SPR_TVEG + &lspr[NOLIGHT], // SPR_TVMX + &lspr[NOLIGHT], // SPR_TVMY + &lspr[NOLIGHT], // SPR_TVGV + &lspr[NOLIGHT], // SPR_TVRC + &lspr[NOLIGHT], // SPR_TV1K + &lspr[NOLIGHT], // SPR_TVTK + &lspr[NOLIGHT], // SPR_TVFL + &lspr[NOLIGHT], // SPR_TVBB + &lspr[NOLIGHT], // SPR_TVZP // Projectiles &lspr[NOLIGHT], // SPR_MISL @@ -287,10 +303,19 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_FWR4 &lspr[NOLIGHT], // SPR_BUS1 &lspr[NOLIGHT], // SPR_BUS2 + &lspr[NOLIGHT], // SPR_BUS3 + // Trees (both GFZ and misc) + &lspr[NOLIGHT], // SPR_TRE1 + &lspr[NOLIGHT], // SPR_TRE2 + &lspr[NOLIGHT], // SPR_TRE3 + &lspr[NOLIGHT], // SPR_TRE4 + &lspr[NOLIGHT], // SPR_TRE5 + &lspr[NOLIGHT], // SPR_TRE6 // Techno Hill Scenery &lspr[NOLIGHT], // SPR_THZP - &lspr[REDBALL_L], // SPR_ALRM + &lspr[NOLIGHT], // SPR_FWR5 + &lspr[REDBALL_L], // SPR_ALRM // Deep Sea Scenery &lspr[NOLIGHT], // SPR_GARG @@ -309,11 +334,40 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_BMCH &lspr[NOLIGHT], // SPR_SMCE &lspr[NOLIGHT], // SPR_BMCE + &lspr[NOLIGHT], // SPR_YSPB + &lspr[NOLIGHT], // SPR_RSPB + &lspr[REDBALL_L], // SPR_SFBR + &lspr[REDBALL_L], // SPR_BFBR + &lspr[NOLIGHT], // SPR_BANR + &lspr[NOLIGHT], // SPR_PINE + &lspr[NOLIGHT], // SPR_CEZB + &lspr[REDBALL_L], // SPR_CNDL + &lspr[NOLIGHT], // SPR_FLMH + &lspr[REDBALL_L], // SPR_CTRC + &lspr[NOLIGHT], // SPR_CFLG + &lspr[NOLIGHT], // SPR_CSTA + &lspr[NOLIGHT], // SPR_CBBS // Arid Canyon Scenery &lspr[NOLIGHT], // SPR_BTBL &lspr[NOLIGHT], // SPR_STBL &lspr[NOLIGHT], // SPR_CACT + &lspr[NOLIGHT], // SPR_WWSG + &lspr[NOLIGHT], // SPR_WWS2 + &lspr[NOLIGHT], // SPR_WWS3 + &lspr[NOLIGHT], // SPR_OILL + &lspr[NOLIGHT], // SPR_OILF + &lspr[NOLIGHT], // SPR_BARR + &lspr[NOLIGHT], // SPR_REMT + &lspr[NOLIGHT], // SPR_TAZD + &lspr[NOLIGHT], // SPR_ADST + &lspr[NOLIGHT], // SPR_MCRT + &lspr[NOLIGHT], // SPR_MCSP + &lspr[NOLIGHT], // SPR_NON2 + &lspr[NOLIGHT], // SPR_SALD + &lspr[NOLIGHT], // SPR_TRAE + &lspr[NOLIGHT], // SPR_TRAI + &lspr[NOLIGHT], // SPR_STEA // Red Volcano Scenery &lspr[REDBALL_L], // SPR_FLME @@ -327,24 +381,35 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_XMS1 &lspr[NOLIGHT], // SPR_XMS2 &lspr[NOLIGHT], // SPR_XMS3 + &lspr[NOLIGHT], // SPR_XMS4 + &lspr[NOLIGHT], // SPR_XMS5 + &lspr[NOLIGHT], // SPR_FHZI + + // Halloween Scenery + &lspr[RINGLIGHT_L], // SPR_PUMK + &lspr[NOLIGHT], // SPR_HHPL + &lspr[NOLIGHT], // SPR_SHRM + &lspr[NOLIGHT], // SPR_HHZM // Botanic Serenity Scenery &lspr[NOLIGHT], // SPR_BSZ1 &lspr[NOLIGHT], // SPR_BSZ2 &lspr[NOLIGHT], // SPR_BSZ3 - &lspr[NOLIGHT], // SPR_BSZ4 + //&lspr[NOLIGHT], -- SPR_BSZ4 + &lspr[NOLIGHT], // SPR_BST1 + &lspr[NOLIGHT], // SPR_BST2 + &lspr[NOLIGHT], // SPR_BST3 + &lspr[NOLIGHT], // SPR_BST4 + &lspr[NOLIGHT], // SPR_BST5 + &lspr[NOLIGHT], // SPR_BST6 &lspr[NOLIGHT], // SPR_BSZ5 &lspr[NOLIGHT], // SPR_BSZ6 &lspr[NOLIGHT], // SPR_BSZ7 &lspr[NOLIGHT], // SPR_BSZ8 - // Stalagmites + // Misc Scenery &lspr[NOLIGHT], // SPR_STLG - - // Disco Ball &lspr[NOLIGHT], // SPR_DBAL - - // ATZ Red Crystal &lspr[NOLIGHT], // SPR_RCRY // Powerup Indicators @@ -356,47 +421,73 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_ELEM &lspr[NOLIGHT], // SPR_FORC &lspr[NOLIGHT], // SPR_PITY - &lspr[INVINCIBLE_L], // SPR_IVSP - &lspr[SUPERSPARK_L], // SPR_SSPK + &lspr[NOLIGHT], // SPR_FIRS + &lspr[NOLIGHT], // SPR_BUBS + &lspr[NOLIGHT], // SPR_ZAPS + &lspr[INVINCIBLE_L], // SPR_IVSP + &lspr[SUPERSPARK_L], // SPR_SSPK &lspr[NOLIGHT], // SPR_GOAL - // Freed Animals - &lspr[NOLIGHT], // SPR_BIRD - &lspr[NOLIGHT], // SPR_BUNY - &lspr[NOLIGHT], // SPR_MOUS - &lspr[NOLIGHT], // SPR_CHIC - &lspr[NOLIGHT], // SPR_COWZ - &lspr[NOLIGHT], // SPR_RBRD + // Flickies + &lspr[NOLIGHT], // SPR_FBUB + &lspr[NOLIGHT], // SPR_FL01 + &lspr[NOLIGHT], // SPR_FL02 + &lspr[NOLIGHT], // SPR_FL03 + &lspr[NOLIGHT], // SPR_FL04 + &lspr[NOLIGHT], // SPR_FL05 + &lspr[NOLIGHT], // SPR_FL06 + &lspr[NOLIGHT], // SPR_FL07 + &lspr[NOLIGHT], // SPR_FL08 + &lspr[NOLIGHT], // SPR_FL09 + &lspr[NOLIGHT], // SPR_FL10 + &lspr[NOLIGHT], // SPR_FL11 + &lspr[NOLIGHT], // SPR_FL12 + &lspr[NOLIGHT], // SPR_FL13 + &lspr[NOLIGHT], // SPR_FL14 + &lspr[NOLIGHT], // SPR_FL15 + &lspr[NOLIGHT], // SPR_FL16 + &lspr[NOLIGHT], // SPR_FS01 + &lspr[NOLIGHT], // SPR_FS02 // Springs + &lspr[NOLIGHT], // SPR_FANS + &lspr[NOLIGHT], // SPR_STEM + &lspr[NOLIGHT], // SPR_BUMP + &lspr[NOLIGHT], // SPR_BLON &lspr[NOLIGHT], // SPR_SPRY &lspr[NOLIGHT], // SPR_SPRR - &lspr[NOLIGHT], // SPR_SPRB Graue + &lspr[NOLIGHT], // SPR_SPRB &lspr[NOLIGHT], // SPR_YSPR &lspr[NOLIGHT], // SPR_RSPR + &lspr[NOLIGHT], // SPR_BSPR + &lspr[NOLIGHT], // SPR_SSWY + &lspr[NOLIGHT], // SPR_SSWR + &lspr[NOLIGHT], // SPR_SSWB - // Environmentals Effects + // Environmental Effects &lspr[NOLIGHT], // SPR_RAIN &lspr[NOLIGHT], // SPR_SNO1 &lspr[NOLIGHT], // SPR_SPLH &lspr[NOLIGHT], // SPR_SPLA &lspr[NOLIGHT], // SPR_SMOK - &lspr[NOLIGHT], // SPR_BUBP - &lspr[NOLIGHT], // SPR_BUBO - &lspr[NOLIGHT], // SPR_BUBN - &lspr[NOLIGHT], // SPR_BUBM - &lspr[NOLIGHT], // SPR_POPP + &lspr[NOLIGHT], // SPR_BUBL + &lspr[RINGLIGHT_L], // SPR_WZAP + &lspr[NOLIGHT], // SPR_DUST + &lspr[NOLIGHT], // SPR_FPRT &lspr[SUPERSPARK_L], // SPR_TFOG - &lspr[NIGHTSLIGHT_L], // SPR_SEED // Sonic CD flower seed + &lspr[NIGHTSLIGHT_L], // SPR_SEED &lspr[NOLIGHT], // SPR_PRTL // Game Indicators &lspr[NOLIGHT], // SPR_SCOR &lspr[NOLIGHT], // SPR_DRWN + &lspr[NOLIGHT], // SPR_LCKN &lspr[NOLIGHT], // SPR_TTAG &lspr[NOLIGHT], // SPR_GFLG + &lspr[NOLIGHT], // SPR_CORK + // Ring Weapons &lspr[RINGLIGHT_L], // SPR_RRNG &lspr[RINGLIGHT_L], // SPR_RNGB @@ -424,29 +515,43 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_GOOM &lspr[NOLIGHT], // SPR_BGOM &lspr[REDBALL_L], // SPR_FFWR - &lspr[SMALLREDBALL_L], // SPR_FBLL + &lspr[SMALLREDBALL_L], // SPR_FBLL &lspr[NOLIGHT], // SPR_SHLL - &lspr[REDBALL_L], // SPR_PUMA + &lspr[REDBALL_L], // SPR_PUMA &lspr[NOLIGHT], // SPR_HAMM &lspr[NOLIGHT], // SPR_KOOP - &lspr[REDBALL_L], // SPR_BFLM + &lspr[REDBALL_L], // SPR_BFLM &lspr[NOLIGHT], // SPR_MAXE &lspr[NOLIGHT], // SPR_MUS1 &lspr[NOLIGHT], // SPR_MUS2 &lspr[NOLIGHT], // SPR_TOAD // NiGHTS Stuff - &lspr[SUPERSONIC_L], // SPR_NDRN // NiGHTS drone - &lspr[SUPERSONIC_L], // SPR_SUPE // NiGHTS character flying - &lspr[SUPERSONIC_L], // SPR_SUPZ // NiGHTS hurt - &lspr[SUPERSONIC_L], // SPR_NDRL // NiGHTS character drilling + &lspr[SUPERSONIC_L], // SPR_NDRN // NiGHTS drone &lspr[NOLIGHT], // SPR_NSPK &lspr[NOLIGHT], // SPR_NBMP &lspr[NOLIGHT], // SPR_HOOP &lspr[NOLIGHT], // SPR_HSCR &lspr[NOLIGHT], // SPR_NPRU &lspr[NOLIGHT], // SPR_CAPS - &lspr[SUPERSONIC_L], // SPR_SUPT + &lspr[INVINCIBLE_L], // SPR_IDYA + &lspr[NOLIGHT], // SPR_NTPN + &lspr[NOLIGHT], // SPR_SHLP + + // Secret badniks and hazards, shhhh + &lspr[NOLIGHT], // SPR_PENG + &lspr[NOLIGHT], // SPR_POPH, + &lspr[NOLIGHT], // SPR_HIVE + &lspr[NOLIGHT], // SPR_BUMB, + &lspr[NOLIGHT], // SPR_BBUZ + &lspr[NOLIGHT], // SPR_FMCE, + &lspr[NOLIGHT], // SPR_HMCE, + &lspr[NOLIGHT], // SPR_CACO, + &lspr[BLUEBALL_L], // SPR_BAL2, + &lspr[NOLIGHT], // SPR_SBOB, + &lspr[BLUEBALL_L], // SPR_SBFL, + &lspr[BLUEBALL_L], // SPR_SBSK, + &lspr[NOLIGHT], // SPR_BATT, // Debris &lspr[RINGSPARK_L], // SPR_SPRK @@ -454,6 +559,8 @@ light_t *t_lspr[NUMSPRITES] = &lspr[SUPERSPARK_L], // SPR_BOM2 &lspr[SUPERSPARK_L], // SPR_BOM3 &lspr[NOLIGHT], // SPR_BOM4 + &lspr[REDBALL_L], // SPR_BMNB + &lspr[NOLIGHT], // SPR_WDDB // Crumbly rocks &lspr[NOLIGHT], // SPR_ROIA @@ -473,30 +580,10 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_ROIO &lspr[NOLIGHT], // SPR_ROIP - // Blue Spheres - &lspr[NOLIGHT], // SPR_BBAL - // Gravity Well Objects &lspr[NOLIGHT], // SPR_GWLG &lspr[NOLIGHT], // SPR_GWLR - // SRB1 Sprites - &lspr[NOLIGHT], // SPR_SRBA - &lspr[NOLIGHT], // SPR_SRBB - &lspr[NOLIGHT], // SPR_SRBC - &lspr[NOLIGHT], // SPR_SRBD - &lspr[NOLIGHT], // SPR_SRBE - &lspr[NOLIGHT], // SPR_SRBF - &lspr[NOLIGHT], // SPR_SRBG - &lspr[NOLIGHT], // SPR_SRBH - &lspr[NOLIGHT], // SPR_SRBI - &lspr[NOLIGHT], // SPR_SRBJ - &lspr[NOLIGHT], // SPR_SRBK - &lspr[NOLIGHT], // SPR_SRBL - &lspr[NOLIGHT], // SPR_SRBM - &lspr[NOLIGHT], // SPR_SRBN - &lspr[NOLIGHT], // SPR_SRBO - // Free slots &lspr[NOLIGHT], &lspr[NOLIGHT], diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 1f3b56e22de925960bbf3a90b2f63ed0ac62a077..d8af96c6f7245bfb20d45efef0e6f1f77aef74c7 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -641,13 +641,13 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is { scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize; scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize; - angle = FOFsector->floorpic_angle>>ANGLETOFINESHIFT; + angle = FOFsector->floorpic_angle; } else // it's a ceiling { scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatsize; scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatsize; - angle = FOFsector->ceilingpic_angle>>ANGLETOFINESHIFT; + angle = FOFsector->ceilingpic_angle; } } else if (gr_frontsector) @@ -656,25 +656,19 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is { scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize; scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize; - angle = gr_frontsector->floorpic_angle>>ANGLETOFINESHIFT; + angle = gr_frontsector->floorpic_angle; } else // it's a ceiling { scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatsize; scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatsize; - angle = gr_frontsector->ceilingpic_angle>>ANGLETOFINESHIFT; + angle = gr_frontsector->ceilingpic_angle; } } if (angle) // Only needs to be done if there's an altered angle { - - // This needs to be done so that it scrolls in a different direction after rotation like software - tempxsow = FLOAT_TO_FIXED(scrollx); - tempytow = FLOAT_TO_FIXED(scrolly); - scrollx = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); - scrolly = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle)))); - + angle = InvAngle(angle)>>ANGLETOFINESHIFT; // This needs to be done so everything aligns after rotation // It would be done so that rotation is done, THEN the translation, but I couldn't get it to rotate AND scroll like software does tempxsow = FLOAT_TO_FIXED(flatxref); @@ -687,7 +681,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is { // Hurdler: add scrolling texture on floor/ceiling v3d->sow = (float)((pv->x / fflatsize) - flatxref + scrollx); - v3d->tow = (float)(flatyref - (pv->y / fflatsize) + scrolly); + v3d->tow = (float)(-(pv->y / fflatsize) + flatyref + scrolly); //v3d->sow = (float)(pv->x / fflatsize); //v3d->tow = (float)(pv->y / fflatsize); @@ -698,7 +692,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is tempxsow = FLOAT_TO_FIXED(v3d->sow); tempytow = FLOAT_TO_FIXED(v3d->tow); v3d->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); - v3d->tow = (FIXED_TO_FLOAT(-FixedMul(tempxsow, FINESINE(angle)) - FixedMul(tempytow, FINECOSINE(angle)))); + v3d->tow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle)))); } //v3d->sow = (float)(v3d->sow - flatxref + scrollx); @@ -1132,7 +1126,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, else { lightnum = *list[i].lightlevel; - colormap = list[i].extra_colormap; + colormap = *list[i].extra_colormap; } } @@ -1314,9 +1308,9 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap); } -// HWR_DrawSkyWalls +// HWR_DrawSkyWall // Draw walls into the depth buffer so that anything behind is culled properly -static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t bottom, fixed_t top) +static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf) { HWD.pfnSetTexture(NULL); // no texture @@ -1324,9 +1318,7 @@ static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t b wallVerts[0].t = wallVerts[1].t = 0; wallVerts[0].s = wallVerts[3].s = 0; wallVerts[2].s = wallVerts[1].s = 0; - // set top/bottom coords - wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(top); // No real way to find the correct height of this - wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(bottom); // worldlow/bottom because it needs to cover up the lower thok barrier wall + // this no longer sets top/bottom coords, this should be done before caling the function HWR_ProjectWall(wallVerts, Surf, PF_Invisible|PF_Clip|PF_NoTexture, 255, NULL); // PF_Invisible so it's not drawn into the colour buffer // PF_NoTexture for no texture @@ -1447,8 +1439,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (gr_backsector) { - INT32 gr_toptexture, gr_bottomtexture; + INT32 gr_toptexture = 0, gr_bottomtexture = 0; // two sided line + boolean bothceilingssky = false; // turned on if both back and front ceilings are sky + boolean bothfloorssky = false; // likewise, but for floors #ifdef ESLOPE SLOPEPARAMS(gr_backsector->c_slope, worldhigh, worldhighslope, gr_backsector->ceilingheight) @@ -1461,17 +1455,23 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) // hack to allow height changes in outdoor areas // This is what gets rid of the upper textures if there should be sky - if (gr_frontsector->ceilingpic == skyflatnum && - gr_backsector->ceilingpic == skyflatnum) + if (gr_frontsector->ceilingpic == skyflatnum + && gr_backsector->ceilingpic == skyflatnum) { - worldtop = worldhigh; -#ifdef ESLOPE - worldtopslope = worldhighslope; -#endif + bothceilingssky = true; + } + + // likewise, but for floors and upper textures + if (gr_frontsector->floorpic == skyflatnum + && gr_backsector->floorpic == skyflatnum) + { + bothfloorssky = true; } - gr_toptexture = R_GetTextureNum(gr_sidedef->toptexture); - gr_bottomtexture = R_GetTextureNum(gr_sidedef->bottomtexture); + if (!bothceilingssky) + gr_toptexture = R_GetTextureNum(gr_sidedef->toptexture); + if (!bothfloorssky) + gr_bottomtexture = R_GetTextureNum(gr_sidedef->bottomtexture); // check TOP TEXTURE if (( @@ -1912,84 +1912,42 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) }*/ } - // Isn't this just the most lovely mess +#if 1 + // Sky culling + // No longer so much a mess as before! if (!gr_curline->polyseg) // Don't do it for polyobjects { - if (gr_frontsector->ceilingpic == skyflatnum || gr_backsector->ceilingpic == skyflatnum) + if (gr_frontsector->ceilingpic == skyflatnum) { - fixed_t depthwallheight; - - if (!gr_sidedef->toptexture || (gr_frontsector->ceilingpic == skyflatnum && gr_backsector->ceilingpic == skyflatnum)) // when both sectors are sky, the top texture isn't drawn - depthwallheight = gr_frontsector->ceilingheight < gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight; - else - depthwallheight = gr_frontsector->ceilingheight > gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight; - - if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier - { - if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier - { - if (!gr_sidedef->bottomtexture) // Only extend further down if there's no texture - HWR_DrawSkyWall(wallVerts, &Surf, worldbottom < worldlow ? worldbottom : worldlow, INT32_MAX); - else - HWR_DrawSkyWall(wallVerts, &Surf, worldbottom > worldlow ? worldbottom : worldlow, INT32_MAX); - } - // behind sector is not a thok barrier - else if (gr_backsector->ceilingheight <= gr_frontsector->ceilingheight) // behind sector ceiling is lower or equal to current sector - HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX); - // gr_front/backsector heights need to be used here because of the worldtop being set to worldhigh earlier on - } - else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not + if (gr_backsector->ceilingpic != skyflatnum) // don't cull if back sector is also sky { - if (gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier ceiling height is equal to or greater than current sector ceiling height - || gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier ceiling height is equal to or less than current sector floor height - || gr_backsector->ceilingpic != skyflatnum) // thok barrier is not a sky - HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX); - } - else // neither sectors are thok barriers - { - if ((gr_backsector->ceilingheight < gr_frontsector->ceilingheight && !gr_sidedef->toptexture) // no top texture and sector behind is lower - || gr_backsector->ceilingpic != skyflatnum) // behind sector is not a sky - HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX); + wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(INT32_MAX); // draw to top of map space +#ifdef ESLOPE + wallVerts[0].y = FIXED_TO_FLOAT(worldtop); + wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope); +#else + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop); +#endif + HWR_DrawSkyWall(wallVerts, &Surf); } } - // And now for sky floors! - if (gr_frontsector->floorpic == skyflatnum || gr_backsector->floorpic == skyflatnum) - { - fixed_t depthwallheight; - if (!gr_sidedef->bottomtexture) - depthwallheight = worldbottom > worldlow ? worldbottom : worldlow; - else - depthwallheight = worldbottom < worldlow ? worldbottom : worldlow; - - if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier - { - if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier - { - if (!gr_sidedef->toptexture) // Only extend up if there's no texture - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop > worldhigh ? worldtop : worldhigh); - else - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop < worldhigh ? worldtop : worldhigh); - } - // behind sector is not a thok barrier - else if (gr_backsector->floorheight >= gr_frontsector->floorheight) // behind sector floor is greater or equal to current sector - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight); - } - else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not - { - if (gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier floor height is equal to or less than current sector floor height - || gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier floor height is equal to or greater than current sector ceiling height - || gr_backsector->floorpic != skyflatnum) // thok barrier is not a sky - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight); - } - else // neither sectors are thok barriers + if (gr_frontsector->floorpic == skyflatnum) + { + if (gr_backsector->floorpic != skyflatnum) // don't cull if back sector is also sky { - if ((gr_backsector->floorheight > gr_frontsector->floorheight && !gr_sidedef->bottomtexture) // no bottom texture and sector behind is higher - || gr_backsector->floorpic != skyflatnum) // behind sector is not a sky - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight); +#ifdef ESLOPE + wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); + wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope); +#else + wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); +#endif + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); // draw to bottom of map space + HWR_DrawSkyWall(wallVerts, &Surf); } } } +#endif } else { @@ -2060,9 +2018,27 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (!gr_curline->polyseg) { if (gr_frontsector->ceilingpic == skyflatnum) // It's a single-sided line with sky for its sector - HWR_DrawSkyWall(wallVerts, &Surf, worldtop, INT32_MAX); + { + wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(INT32_MAX); // draw to top of map space +#ifdef ESLOPE + wallVerts[0].y = FIXED_TO_FLOAT(worldtop); + wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope); +#else + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop); +#endif + HWR_DrawSkyWall(wallVerts, &Surf); + } if (gr_frontsector->floorpic == skyflatnum) - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldbottom); + { +#ifdef ESLOPE + wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); + wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope); +#else + wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); +#endif + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); // draw to bottom of map space + HWR_DrawSkyWall(wallVerts, &Surf); + } } } @@ -2384,6 +2360,12 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks { fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends + boolean bothceilingssky = false, bothfloorssky = false; + + if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) + bothceilingssky = true; + if (abacksector->floorpic == skyflatnum && afrontsector->floorpic == skyflatnum) + bothfloorssky = true; // GZDoom method of sloped line clipping @@ -2416,62 +2398,45 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks backf1 = backf2 = abacksector->floorheight; backc1 = backc2 = abacksector->ceilingheight; } - - // now check for closed sectors! - if (backc1 <= frontf1 && backc2 <= frontf2) - { - checkforemptylines = false; - if (!seg->sidedef->toptexture) - return false; - - if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) - return false; - - return true; - } - - if (backf1 >= frontc1 && backf2 >= frontc2) - { - checkforemptylines = false; - if (!seg->sidedef->bottomtexture) - return false; - - // properly render skies (consider door "open" if both floors are sky): - if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) - return false; - - return true; - } - - if (backc1 <= backf1 && backc2 <= backf2) + // properly render skies (consider door "open" if both ceilings are sky) + // same for floors + if (!bothceilingssky && !bothfloorssky) { - checkforemptylines = false; - // preserve a kind of transparent door/lift special effect: - if (backc1 < frontc1 || backc2 < frontc2) + // now check for closed sectors! + if ((backc1 <= frontf1 && backc2 <= frontf2) + || (backf1 >= frontc1 && backf2 >= frontc2)) { - if (!seg->sidedef->toptexture) - return false; + checkforemptylines = false; + return true; } - if (backf1 > frontf1 || backf2 > frontf2) + + if (backc1 <= backf1 && backc2 <= backf2) { - if (!seg->sidedef->bottomtexture) - return false; + // preserve a kind of transparent door/lift special effect: + if (((backc1 >= frontc1 && backc2 >= frontc2) || seg->sidedef->toptexture) + && ((backf1 <= frontf1 && backf2 <= frontf2) || seg->sidedef->bottomtexture)) + { + checkforemptylines = false; + return true; + } } - if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) - return false; + } - if (abacksector->floorpic == skyflatnum && afrontsector->floorpic == skyflatnum) + if (!bothceilingssky) { + if (backc1 != frontc1 || backc2 != frontc2) + { + checkforemptylines = false; return false; - - return true; + } } - if (backc1 != frontc1 || backc2 != frontc2 - || backf1 != frontf1 || backf2 != frontf2) + if (!bothfloorssky) { + if (backf1 != frontf1 || backf2 != frontf2) { checkforemptylines = false; return false; } + } return false; } @@ -2774,6 +2739,7 @@ static void HWR_AddLine(seg_t * line) #ifndef NEWCLIP INT32 x1, x2; angle_t span, tspan; + boolean bothceilingssky = false, bothfloorssky = false; #endif // SoM: Backsector needs to be run through R_FakeFlat @@ -2899,7 +2865,30 @@ static void HWR_AddLine(seg_t * line) } else { + boolean bothceilingssky = false, bothfloorssky = false; + gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true); + + if (gr_backsector->ceilingpic == skyflatnum && gr_frontsector->ceilingpic == skyflatnum) + bothceilingssky = true; + if (gr_backsector->floorpic == skyflatnum && gr_frontsector->floorpic == skyflatnum) + bothfloorssky = true; + + if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then + { + if ( +#ifdef POLYOBJECTS + !line->polyseg && +#endif + !line->sidedef->midtexture + && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) + || (gr_frontsector->tag == gr_backsector->tag))) + return; // line is empty, don't even bother + // treat like wide open window instead + HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D + return; + } + if (CheckClip(line, gr_frontsector, gr_backsector)) { gld_clipper_SafeAddClipRange(angle2, angle1); @@ -2922,6 +2911,25 @@ static void HWR_AddLine(seg_t * line) gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true); + if (gr_backsector->ceilingpic == skyflatnum && gr_frontsector->ceilingpic == skyflatnum) + bothceilingssky = true; + if (gr_backsector->floorpic == skyflatnum && gr_frontsector->floorpic == skyflatnum) + bothfloorssky = true; + + if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then + { + if ( +#ifdef POLYOBJECTS + !line->polyseg && +#endif + !line->sidedef->midtexture + && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) + || (gr_frontsector->tag == gr_backsector->tag))) + return; // line is empty, don't even bother + + goto clippass; // treat like wide open window instead + } + #ifdef ESLOPE if (gr_frontsector->f_slope || gr_frontsector->c_slope || gr_backsector->f_slope || gr_backsector->c_slope) { @@ -2940,47 +2948,58 @@ static void HWR_AddLine(seg_t * line) SLOPEPARAMS( gr_backsector->f_slope, backf1, backf2, gr_backsector->floorheight) SLOPEPARAMS( gr_backsector->c_slope, backc1, backc2, gr_backsector->ceilingheight) #undef SLOPEPARAMS - - // Closed door. - if ((backc1 <= frontf1 && backc2 <= frontf2) - || (backf1 >= frontc1 && backf2 >= frontc2)) + // if both ceilings are skies, consider it always "open" + // same for floors + if (!bothceilingssky && !bothfloorssky) { - goto clipsolid; - } + // Closed door. + if ((backc1 <= frontf1 && backc2 <= frontf2) + || (backf1 >= frontc1 && backf2 >= frontc2)) + { + goto clipsolid; + } - // Check for automap fix. - if (backc1 <= backf1 && backc2 <= backf2 - && ((backc1 >= frontc1 && backc2 >= frontc2) || gr_curline->sidedef->toptexture) - && ((backf1 <= frontf1 && backf2 >= frontf2) || gr_curline->sidedef->bottomtexture) - && (gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum)) - goto clipsolid; + // Check for automap fix. + if (backc1 <= backf1 && backc2 <= backf2 + && ((backc1 >= frontc1 && backc2 >= frontc2) || gr_curline->sidedef->toptexture) + && ((backf1 <= frontf1 && backf2 >= frontf2) || gr_curline->sidedef->bottomtexture)) + goto clipsolid; + } // Window. - if (backc1 != frontc1 || backc2 != frontc2 - || backf1 != frontf1 || backf2 != frontf2) - { - goto clippass; - } + if (!bothceilingssky) // ceilings are always the "same" when sky + if (backc1 != frontc1 || backc2 != frontc2) + goto clippass; + if (!bothfloorssky) // floors are always the "same" when sky + if (backf1 != frontf1 || backf2 != frontf2) + goto clippass; } else #endif { - // Closed door. - if (gr_backsector->ceilingheight <= gr_frontsector->floorheight || - gr_backsector->floorheight >= gr_frontsector->ceilingheight) - goto clipsolid; - - // Check for automap fix. - if (gr_backsector->ceilingheight <= gr_backsector->floorheight - && ((gr_backsector->ceilingheight >= gr_frontsector->ceilingheight) || gr_curline->sidedef->toptexture) - && ((gr_backsector->floorheight <= gr_backsector->floorheight) || gr_curline->sidedef->bottomtexture) - && (gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum)) - goto clipsolid; + // if both ceilings are skies, consider it always "open" + // same for floors + if (!bothceilingssky && !bothfloorssky) + { + // Closed door. + if (gr_backsector->ceilingheight <= gr_frontsector->floorheight || + gr_backsector->floorheight >= gr_frontsector->ceilingheight) + goto clipsolid; + + // Check for automap fix. + if (gr_backsector->ceilingheight <= gr_backsector->floorheight + && ((gr_backsector->ceilingheight >= gr_frontsector->ceilingheight) || gr_curline->sidedef->toptexture) + && ((gr_backsector->floorheight <= gr_backsector->floorheight) || gr_curline->sidedef->bottomtexture)) + goto clipsolid; + } // Window. - if (gr_backsector->ceilingheight != gr_frontsector->ceilingheight || - gr_backsector->floorheight != gr_frontsector->floorheight) - goto clippass; + if (!bothceilingssky) // ceilings are always the "same" when sky + if (gr_backsector->ceilingheight != gr_frontsector->ceilingheight) + goto clippass; + if (!bothfloorssky) // floors are always the "same" when sky + if (gr_backsector->floorheight != gr_frontsector->floorheight) + goto clippass; } // Reject empty lines used for triggers and special events. @@ -3497,12 +3516,12 @@ static void HWR_Subsector(size_t num) light = R_GetPlaneLight(gr_frontsector, locFloorHeight, false); if (gr_frontsector->floorlightsec == -1) floorlightlevel = *gr_frontsector->lightlist[light].lightlevel; - floorcolormap = gr_frontsector->lightlist[light].extra_colormap; + floorcolormap = *gr_frontsector->lightlist[light].extra_colormap; light = R_GetPlaneLight(gr_frontsector, locCeilingHeight, false); if (gr_frontsector->ceilinglightsec == -1) ceilinglightlevel = *gr_frontsector->lightlist[light].lightlevel; - ceilingcolormap = gr_frontsector->lightlist[light].extra_colormap; + ceilingcolormap = *gr_frontsector->lightlist[light].extra_colormap; } sub->sector->extra_colormap = gr_frontsector->extra_colormap; @@ -3626,7 +3645,7 @@ static void HWR_Subsector(size_t num) *rover->bottomheight, *gr_frontsector->lightlist[light].lightlevel, rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent, - false, gr_frontsector->lightlist[light].extra_colormap); + false, *gr_frontsector->lightlist[light].extra_colormap); #endif } else @@ -3634,7 +3653,7 @@ static void HWR_Subsector(size_t num) HWR_GetFlat(levelflats[*rover->bottompic].lumpnum); light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum, - rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap); + rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap); } } @@ -3689,7 +3708,7 @@ static void HWR_Subsector(size_t num) *rover->topheight, *gr_frontsector->lightlist[light].lightlevel, rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent, - false, gr_frontsector->lightlist[light].extra_colormap); + false, *gr_frontsector->lightlist[light].extra_colormap); #endif } @@ -3698,7 +3717,7 @@ static void HWR_Subsector(size_t num) HWR_GetFlat(levelflats[*rover->toppic].lumpnum); light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum, - rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap); + rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap); } } } @@ -4209,8 +4228,8 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t if (!(spr->mobj->frame & FF_FULLBRIGHT)) lightlevel = *sector->lightlist[light].lightlevel; - if (sector->lightlist[light].extra_colormap) - colormap = sector->lightlist[light].extra_colormap; + if (*sector->lightlist[light].extra_colormap) + colormap = *sector->lightlist[light].extra_colormap; } else { @@ -4249,7 +4268,9 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t // This is expecting a pointer to an array containing 4 wallVerts for a sprite static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts) { - if (cv_grspritebillboarding.value && spr && spr->mobj && wallVerts) + if (cv_grspritebillboarding.value + && spr && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE) + && wallVerts) { float basey = FIXED_TO_FLOAT(spr->mobj->z); float lowy = wallVerts[0].y; @@ -4428,7 +4449,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) // Start with the lightlevel and colormap from the top of the sprite lightlevel = *list[sector->numlights - 1].lightlevel; - colormap = list[sector->numlights - 1].extra_colormap; + colormap = *list[sector->numlights - 1].extra_colormap; i = 0; temp = FLOAT_TO_FIXED(realtop); @@ -4444,7 +4465,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) { if (!(spr->mobj->frame & FF_FULLBRIGHT)) lightlevel = *list[i-1].lightlevel; - colormap = list[i-1].extra_colormap; + colormap = *list[i-1].extra_colormap; break; } } @@ -4452,7 +4473,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) i = R_GetPlaneLight(sector, temp, false); if (!(spr->mobj->frame & FF_FULLBRIGHT)) lightlevel = *list[i].lightlevel; - colormap = list[i].extra_colormap; + colormap = *list[i].extra_colormap; #endif for (i = 0; i < sector->numlights; i++) @@ -4468,7 +4489,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) { if (!(spr->mobj->frame & FF_FULLBRIGHT)) lightlevel = *list[i].lightlevel; - colormap = list[i].extra_colormap; + colormap = *list[i].extra_colormap; } #ifdef ESLOPE @@ -4530,7 +4551,8 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) wallVerts[1].y = endbot; // The x and y only need to be adjusted in the case that it's not a papersprite - if (cv_grspritebillboarding.value && spr->mobj) + if (cv_grspritebillboarding.value + && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE)) { // Get the x and z of the vertices so billboarding draws correctly realheight = realbot - realtop; @@ -4559,7 +4581,8 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) wallVerts[0].y = wallVerts[1].y = bot; // The x and y only need to be adjusted in the case that it's not a papersprite - if (cv_grspritebillboarding.value && spr->mobj) + if (cv_grspritebillboarding.value + && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE)) { // Get the x and z of the vertices so billboarding draws correctly realheight = realbot - realtop; @@ -4641,6 +4664,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) GLPatch_t *gpatch; // sprite patch converted to hardware FSurfaceInfo Surf; const boolean hires = (spr->mobj && spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES); + //const boolean papersprite = (spr->mobj && (spr->mobj->frame & FF_PAPERSPRITE)); if (spr->mobj) this_scale = FIXED_TO_FLOAT(spr->mobj->scale); if (hires) @@ -4856,8 +4880,8 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) if (!(spr->mobj->frame & FF_FULLBRIGHT)) lightlevel = *sector->lightlist[light].lightlevel; - if (sector->lightlist[light].extra_colormap) - colormap = sector->lightlist[light].extra_colormap; + if (*sector->lightlist[light].extra_colormap) + colormap = *sector->lightlist[light].extra_colormap; } else { @@ -5052,8 +5076,6 @@ static polyplaneinfo_t *polyplaneinfo = NULL; #ifndef SORTING size_t numfloors = 0; #else -//static floorinfo_t *floorinfo = NULL; -//static size_t numfloors = 0; //Hurdler: 3D water sutffs typedef struct gr_drawnode_s { @@ -5409,7 +5431,7 @@ static void HWR_AddSprites(sector_t *sec) } #ifdef HWPRECIP - // Someone seriously wants infinite draw distance for precipitation? + // no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off if ((limit_dist = (fixed_t)cv_drawdist_precip.value << FRACBITS)) { for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext) @@ -5425,13 +5447,6 @@ static void HWR_AddSprites(sector_t *sec) HWR_ProjectPrecipitationSprite(precipthing); } } - else - { - // Draw everything in sector, no checks - for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext) - if (!(precipthing->precipflags & PCF_INVISIBLE)) - HWR_ProjectPrecipitationSprite(precipthing); - } #endif } @@ -5446,7 +5461,6 @@ static void HWR_ProjectSprite(mobj_t *thing) float tr_x, tr_y; float tz; float x1, x2; - float z1, z2; float rightsin, rightcos; float this_scale; float gz, gzt; @@ -5455,8 +5469,13 @@ static void HWR_ProjectSprite(mobj_t *thing) size_t lumpoff; unsigned rot; UINT8 flip; + boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP)); + angle_t ang; INT32 heightsec, phs; + const boolean papersprite = (thing->frame & FF_PAPERSPRITE); + angle_t mobjangle = (thing->player ? thing->player->drawangle : thing->angle); + float z1, z2; if (!thing) return; @@ -5471,7 +5490,7 @@ static void HWR_ProjectSprite(mobj_t *thing) tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin); // thing is behind view plane? - if (tz < ZCLIP_PLANE && (!cv_grmdls.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear + if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmdls.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear return; // The above can stay as it works for cutting sprites that are too close @@ -5488,7 +5507,7 @@ static void HWR_ProjectSprite(mobj_t *thing) //Fab : 02-08-98: 'skin' override spritedef currently used for skin if (thing->skin && thing->sprite == SPR_PLAY) - sprdef = &((skin_t *)thing->skin)->spritedef; + sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2]; else sprdef = &sprites[thing->sprite]; @@ -5511,28 +5530,60 @@ static void HWR_ProjectSprite(mobj_t *thing) I_Error("sprframes NULL for sprite %d\n", thing->sprite); #endif - if (sprframe->rotate) - { - // choose a different rotation based on player view - ang = R_PointToAngle(thing->x, thing->y); // uses viewx,viewy - rot = (ang-thing->angle+ANGLE_202h)>>29; - //Fab: lumpid is the index for spritewidth,spriteoffset... tables - lumpoff = sprframe->lumpid[rot]; - flip = sprframe->flip & (1<<rot); - } - else + ang = R_PointToAngle (thing->x, thing->y) - mobjangle; + + if (sprframe->rotate == SRF_SINGLE) { // use single rotation for all views rot = 0; //Fab: for vis->patch below lumpoff = sprframe->lumpid[0]; //Fab: see note above flip = sprframe->flip; // Will only be 0x00 or 0xFF + + if (papersprite && ang < ANGLE_180) + { + if (flip) + flip = 0; + else + flip = 255; + } + } + else + { + // choose a different rotation based on player view + if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right + rot = 6; // F7 slot + else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left + rot = 2; // F3 slot + else // Normal behaviour + rot = (ang+ANGLE_202h)>>29; + + //Fab: lumpid is the index for spritewidth,spriteoffset... tables + lumpoff = sprframe->lumpid[rot]; + flip = sprframe->flip & (1<<rot); + + if (papersprite && ang < ANGLE_180) + { + if (flip) + flip = 0; + else + flip = 1<<rot; + } } if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)thing->skin)->highresscale); - rightsin = FIXED_TO_FLOAT(FINESINE((viewangle + ANGLE_90)>>ANGLETOFINESHIFT)); - rightcos = FIXED_TO_FLOAT(FINECOSINE((viewangle + ANGLE_90)>>ANGLETOFINESHIFT)); + if (papersprite) + { + rightsin = FIXED_TO_FLOAT(FINESINE((mobjangle)>>ANGLETOFINESHIFT)); + rightcos = FIXED_TO_FLOAT(FINECOSINE((mobjangle)>>ANGLETOFINESHIFT)); + } + else + { + rightsin = FIXED_TO_FLOAT(FINESINE((viewangle + ANGLE_90)>>ANGLETOFINESHIFT)); + rightcos = FIXED_TO_FLOAT(FINECOSINE((viewangle + ANGLE_90)>>ANGLETOFINESHIFT)); + } + if (flip) { x1 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale); @@ -5544,12 +5595,24 @@ static void HWR_ProjectSprite(mobj_t *thing) x2 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale); } + // test if too close +/* + if (papersprite) + { + z1 = tz - x1 * angle_scalez; + z2 = tz + x2 * angle_scalez; + + if (max(z1, z2) < ZCLIP_PLANE) + return; + } +*/ + z1 = tr_y + x1 * rightsin; z2 = tr_y - x2 * rightsin; x1 = tr_x + x1 * rightcos; x2 = tr_x - x2 * rightcos; - if (thing->eflags & MFE_VERTICALFLIP) + if (vflip) { gz = FIXED_TO_FLOAT(thing->z+thing->height) - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].topoffset) * this_scale; gzt = gz + FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height) * this_scale; @@ -5588,13 +5651,13 @@ static void HWR_ProjectSprite(mobj_t *thing) vis = HWR_NewVisSprite(); vis->x1 = x1; vis->x2 = x2; - vis->z1 = z1; - vis->z2 = z2; vis->tz = tz; // Keep tz for the simple sprite sorting that happens vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST vis->patchlumpnum = sprframe->lumppat[rot]; vis->flip = flip; vis->mobj = thing; + vis->z1 = z1; + vis->z2 = z2; //Hurdler: 25/04/2000: now support colormap in hardware mode if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash" @@ -5626,10 +5689,7 @@ static void HWR_ProjectSprite(mobj_t *thing) //CONS_Debug(DBG_RENDER, "------------------\nH: sprite : %d\nH: frame : %x\nH: type : %d\nH: sname : %s\n\n", // thing->sprite, thing->frame, thing->type, sprnames[thing->sprite]); - if (thing->eflags & MFE_VERTICALFLIP) - vis->vflip = true; - else - vis->vflip = false; + vis->vflip = vflip; vis->precip = false; } @@ -5707,16 +5767,6 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) x1 = tr_x + x1 * rightcos; x2 = tr_x - x2 * rightcos; - // okay, we can't return now... this is a hack, but weather isn't networked, so it should be ok - if (!(thing->precipflags & PCF_THUNK)) - { - if (thing->precipflags & PCF_RAIN) - P_RainThinker(thing); - else - P_SnowThinker(thing); - thing->precipflags |= PCF_THUNK; - } - // // store information in a vissprite // @@ -5737,6 +5787,16 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) vis->ty = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset); vis->precip = true; + + // okay... this is a hack, but weather isn't networked, so it should be ok + if (!(thing->precipflags & PCF_THUNK)) + { + if (thing->precipflags & PCF_RAIN) + P_RainThinker(thing); + else + P_SnowThinker(thing); + thing->precipflags |= PCF_THUNK; + } } #endif @@ -5751,7 +5811,7 @@ static void HWR_DrawSkyBackground(void) float aspectratio; float angleturn; - HWR_GetTexture(skytexture); + HWR_GetTexture(texturetranslation[skytexture]); aspectratio = (float)vid.width/(float)vid.height; //Hurdler: the sky is the only texture who need 4.0f instead of 1.0 @@ -5777,14 +5837,16 @@ static void HWR_DrawSkyBackground(void) // The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture angle = (dup_viewangle + gr_xtoviewangle[0]); - dimensionmultiply = ((float)textures[skytexture]->width/256.0f); - v[0].sow = v[3].sow = ((float) angle / ((ANGLE_90-1)*dimensionmultiply)); - v[2].sow = v[1].sow = (-1.0f/dimensionmultiply)+((float) angle / ((ANGLE_90-1)*dimensionmultiply)); + dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f); + + v[0].sow = v[3].sow = (-1.0f * angle) / ((ANGLE_90-1)*dimensionmultiply); // left + v[2].sow = v[1].sow = v[0].sow + (1.0f/dimensionmultiply); // right (or left + 1.0f) + // use +angle and -1.0f above instead if you wanted old backwards behavior // Y angle = aimingangle; - dimensionmultiply = ((float)textures[skytexture]->height/(128.0f*aspectratio)); + dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->height/(128.0f*aspectratio)); if (splitscreen) { @@ -5797,13 +5859,13 @@ static void HWR_DrawSkyBackground(void) if (atransform.flip) { // During vertical flip the sky should be flipped and it's y movement should also be flipped obviously - v[3].tow = v[2].tow = -(0.5f-(0.5f/dimensionmultiply)); - v[0].tow = v[1].tow = (-1.0f/dimensionmultiply)-(0.5f-(0.5f/dimensionmultiply)); + v[3].tow = v[2].tow = -(0.5f-(0.5f/dimensionmultiply)); // top + v[0].tow = v[1].tow = v[3].tow - (1.0f/dimensionmultiply); // bottom (or top - 1.0f) } else { - v[3].tow = v[2].tow = (-1.0f/dimensionmultiply)-(0.5f-(0.5f/dimensionmultiply)); - v[0].tow = v[1].tow = -(0.5f-(0.5f/dimensionmultiply)); + v[0].tow = v[1].tow = -(0.5f-(0.5f/dimensionmultiply)); // bottom + v[3].tow = v[2].tow = v[0].tow - (1.0f/dimensionmultiply); // top (or bottom - 1.0f) } angleturn = (((float)ANGLE_45-1.0f)*aspectratio)*dimensionmultiply; @@ -6125,7 +6187,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) } // note: sets viewangle, viewx, viewy, viewz - R_SetupFrame(player, false); // This can stay false because it is only used to set viewsky in r_main.c, which isn't used here + R_SetupFrame(player); framecount++; // timedemo // copy view cam position for local use @@ -6437,12 +6499,7 @@ void HWR_Startup(void) } if (rendermode == render_opengl) - textureformat = patchformat = -#ifdef _NDS - GR_TEXFMT_P_8; -#else - GR_RGBA; -#endif + textureformat = patchformat = GR_RGBA; startupdone = true; } diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 98229c75228cdfb44fde0046d07460c2b6e58997..cd4e13ef5adf29772fe79351f10e191a4fdd954f 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -32,8 +32,9 @@ void HWR_Startup(void); void HWR_Shutdown(void); void HWR_drawAMline(const fline_t *fl, INT32 color); -void HWR_FadeScreenMenuBack(UINT32 color, INT32 height); +void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength); void HWR_DrawConsoleBack(UINT32 color, INT32 height); +void HWR_DrawTutorialBack(UINT32 color, INT32 boxheight); void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player); void HWR_RenderPlayerView(INT32 viewnumber, player_t *player); void HWR_DrawViewBorder(INT32 clearlines); @@ -43,8 +44,7 @@ void HWR_SetViewSize(void); void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option); void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale, INT32 option, const UINT8 *colormap); void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h); -void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, INT32 option, fixed_t scale, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h); -void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap); +void HWR_MakePatch(const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap); void HWR_CreatePlanePolygons(INT32 bspnum); void HWR_CreateStaticLightmaps(INT32 bspnum); void HWR_PrepLevelCache(size_t pnumtextures); @@ -104,13 +104,4 @@ extern float gr_viewwindowx, gr_basewindowcentery; extern fixed_t *hwbbox; extern FTransform atransform; -typedef struct -{ - wallVert3D floorVerts[4]; - FSurfaceInfo Surf; - INT32 texnum; - INT32 blend; - INT32 drawcount; -} floorinfo_t; - #endif diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 4bb86cdf117e55e436856ed7f98b41ace21184a5..f0783bfe4e7573670ce54700f0a597a22b3247fe 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -28,12 +28,12 @@ #include "../doomdef.h" #include "../doomstat.h" +#include "../fastcmp.h" #ifdef HWRENDER #include "hw_drv.h" #include "hw_light.h" #include "hw_md2.h" -#include "../d_main.h" #include "../r_bsp.h" #include "../r_main.h" #include "../m_misc.h" @@ -647,135 +647,10 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, image = gpatch->mipmap.grInfo.data; blendimage = blendgpatch->mipmap.grInfo.data; - switch (color) - { - case SKINCOLOR_WHITE: - blendcolor = V_GetColor(3); - break; - case SKINCOLOR_SILVER: - blendcolor = V_GetColor(10); - break; - case SKINCOLOR_GREY: - blendcolor = V_GetColor(15); - break; - case SKINCOLOR_BLACK: - blendcolor = V_GetColor(27); - break; - case SKINCOLOR_CYAN: - blendcolor = V_GetColor(215); - break; - case SKINCOLOR_TEAL: - blendcolor = V_GetColor(221); - break; - case SKINCOLOR_STEELBLUE: - blendcolor = V_GetColor(203); - break; - case SKINCOLOR_BLUE: - blendcolor = V_GetColor(232); - break; - case SKINCOLOR_PEACH: - blendcolor = V_GetColor(71); - break; - case SKINCOLOR_TAN: - blendcolor = V_GetColor(79); - break; - case SKINCOLOR_PINK: - blendcolor = V_GetColor(147); - break; - case SKINCOLOR_LAVENDER: - blendcolor = V_GetColor(251); - break; - case SKINCOLOR_PURPLE: - blendcolor = V_GetColor(195); - break; - case SKINCOLOR_ORANGE: - blendcolor = V_GetColor(87); - break; - case SKINCOLOR_ROSEWOOD: - blendcolor = V_GetColor(94); - break; - case SKINCOLOR_BEIGE: - blendcolor = V_GetColor(40); - break; - case SKINCOLOR_BROWN: - blendcolor = V_GetColor(57); - break; - case SKINCOLOR_RED: - blendcolor = V_GetColor(130); - break; - case SKINCOLOR_DARKRED: - blendcolor = V_GetColor(139); - break; - case SKINCOLOR_NEONGREEN: - blendcolor = V_GetColor(184); - break; - case SKINCOLOR_GREEN: - blendcolor = V_GetColor(166); - break; - case SKINCOLOR_ZIM: - blendcolor = V_GetColor(180); - break; - case SKINCOLOR_OLIVE: - blendcolor = V_GetColor(108); - break; - case SKINCOLOR_YELLOW: - blendcolor = V_GetColor(104); - break; - case SKINCOLOR_GOLD: - blendcolor = V_GetColor(115); - break; - - case SKINCOLOR_SUPER1: - blendcolor = V_GetColor(97); - break; - case SKINCOLOR_SUPER2: - blendcolor = V_GetColor(100); - break; - case SKINCOLOR_SUPER3: - blendcolor = V_GetColor(103); - break; - case SKINCOLOR_SUPER4: - blendcolor = V_GetColor(113); - break; - case SKINCOLOR_SUPER5: - blendcolor = V_GetColor(116); - break; - - case SKINCOLOR_TSUPER1: - blendcolor = V_GetColor(81); - break; - case SKINCOLOR_TSUPER2: - blendcolor = V_GetColor(82); - break; - case SKINCOLOR_TSUPER3: - blendcolor = V_GetColor(84); - break; - case SKINCOLOR_TSUPER4: - blendcolor = V_GetColor(85); - break; - case SKINCOLOR_TSUPER5: - blendcolor = V_GetColor(87); - break; - - case SKINCOLOR_KSUPER1: - blendcolor = V_GetColor(122); - break; - case SKINCOLOR_KSUPER2: - blendcolor = V_GetColor(123); - break; - case SKINCOLOR_KSUPER3: - blendcolor = V_GetColor(124); - break; - case SKINCOLOR_KSUPER4: - blendcolor = V_GetColor(125); - break; - case SKINCOLOR_KSUPER5: - blendcolor = V_GetColor(126); - break; - default: - blendcolor = V_GetColor(247); - break; - } + if (color == SKINCOLOR_NONE || color >= MAXTRANSLATIONS) + blendcolor = V_GetColor(0xff); + else + blendcolor = V_GetColor(Color_Index[color-1][4]); while (size--) { @@ -882,6 +757,51 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, con res? run? */ + +static UINT8 P_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t *player) +{ + UINT8 super = 0, i = 0; + + if (!md2 || !skin) + return 0; + + while (!(md2->model->spr2frames[spr2*2 + 1]) + && spr2 != SPR2_STND + && ++i != 32) // recursion limiter + { + if (spr2 & FF_SPR2SUPER) + { + super = FF_SPR2SUPER; + spr2 &= ~FF_SPR2SUPER; + continue; + } + + switch(spr2) + { + + // Normal special cases. + case SPR2_JUMP: + spr2 = ((player + ? player->charflags + : skin->flags) + & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL; + break; + case SPR2_TIRE: + spr2 = (player && player->charability == CA_SWIM) ? SPR2_SWIM : SPR2_FLY; + break; + + // Use the handy list, that's what it's there for! + default: + spr2 = spr2defaults[spr2]; + break; + } + + spr2 |= super; + } + + return spr2; +} + #define NORMALFOG 0x00000000 #define FADEFOG 0x19000000 void HWR_DrawMD2(gr_vissprite_t *spr) @@ -917,8 +837,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr) if (!(spr->mobj->frame & FF_FULLBRIGHT)) lightlevel = *sector->lightlist[light].lightlevel; - if (sector->lightlist[light].extra_colormap) - colormap = sector->lightlist[light].extra_colormap; + if (*sector->lightlist[light].extra_colormap) + colormap = *sector->lightlist[light].extra_colormap; } else { @@ -940,8 +860,13 @@ void HWR_DrawMD2(gr_vissprite_t *spr) GLPatch_t *gpatch; INT32 durs = spr->mobj->state->tics; INT32 tics = spr->mobj->tics; +<<<<<<< HEAD //mdlframe_t *next = NULL; const UINT8 flip = (UINT8)((spr->mobj->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP); +======= + md2_frame_t *curr, *next = NULL; + const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !(spr->mobj->frame & FF_VERTICALFLIP)); +>>>>>>> origin/master spritedef_t *sprdef; spriteframe_t *sprframe; float finalscale; @@ -1030,44 +955,104 @@ void HWR_DrawMD2(gr_vissprite_t *spr) tics = spr->mobj->anim_duration; } +<<<<<<< HEAD //FIXME: this is not yet correct frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames; #ifdef USE_MODEL_NEXTFRAME if (cv_grmdls.value == 1 && tics <= durs) +======= +#define INTERPOLERATION_LIMIT TICRATE/4 + + if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && md2->model->spr2frames) +>>>>>>> origin/master { - // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation - if (spr->mobj->frame & FF_ANIMATE) + UINT8 spr2 = P_GetModelSprite2(md2, spr->mobj->skin, spr->mobj->sprite2, spr->mobj->player); + UINT8 mod = md2->model->spr2frames[spr2*2 + 1] ? md2->model->spr2frames[spr2*2 + 1] : md2->model->header.numFrames; + if (mod > ((skin_t *)spr->mobj->skin)->sprites[spr2].numframes) + mod = ((skin_t *)spr->mobj->skin)->sprites[spr2].numframes; + //FIXME: this is not yet correct + frame = (spr->mobj->frame & FF_FRAMEMASK); + if (frame >= mod) + frame = 0; + buff = md2->model->glCommandBuffer; + curr = &md2->model->frames[md2->model->spr2frames[spr2*2] + frame]; + if (cv_grmd2.value == 1 && tics <= durs && tics <= INTERPOLERATION_LIMIT) { +<<<<<<< HEAD nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1; if (nextFrame >= spr->mobj->state->var1) nextFrame = (spr->mobj->state->frame & FF_FRAMEMASK); nextFrame %= md2->model->meshes[0].numFrames; //next = &md2->model->meshes[0].frames[nextFrame]; +======= + if (durs > INTERPOLERATION_LIMIT) + durs = INTERPOLERATION_LIMIT; + + if (spr->mobj->frame & FF_ANIMATE + || (spr->mobj->state->nextstate != S_NULL + && states[spr->mobj->state->nextstate].sprite == spr->mobj->sprite + && (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) == spr->mobj->sprite2)) + { + if (++frame >= mod) + frame = 0; + if (frame || !(spr->mobj->state->frame & FF_SPR2ENDSTATE)) + next = &md2->model->frames[md2->model->spr2frames[spr2*2] + frame]; + } +>>>>>>> origin/master } - else + } + else + { + //FIXME: this is not yet correct + frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames; + buff = md2->model->glCommandBuffer; + curr = &md2->model->frames[frame]; + if (cv_grmd2.value == 1 && tics <= durs && tics <= INTERPOLERATION_LIMIT) { - if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL - && !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_TAP1 || spr->mobj->state->nextstate == S_PLAY_TAP2) && spr->mobj->state == &states[S_PLAY_STND])) + if (durs > INTERPOLERATION_LIMIT) + durs = INTERPOLERATION_LIMIT; + + // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation + if (spr->mobj->frame & FF_ANIMATE) { +<<<<<<< HEAD nextFrame = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames; //next = &md2->model->meshes[0].frames[nextFrame]; +======= + UINT32 nextframe = (spr->mobj->frame & FF_FRAMEMASK) + 1; + if (nextframe >= (UINT32)spr->mobj->state->var1) + nextframe = (spr->mobj->state->frame & FF_FRAMEMASK); + nextframe %= md2->model->header.numFrames; + next = &md2->model->frames[nextframe]; +>>>>>>> origin/master + } + else + { + if (spr->mobj->state->nextstate != S_NULL + && states[spr->mobj->state->nextstate].sprite == spr->mobj->sprite) + { + const UINT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames; + next = &md2->model->frames[nextframe]; + } } } } #endif +#undef INTERPOLERATION_LIMIT + //Hurdler: it seems there is still a small problem with mobj angle p.x = FIXED_TO_FLOAT(spr->mobj->x); p.y = FIXED_TO_FLOAT(spr->mobj->y)+md2->offset; - if (spr->mobj->eflags & MFE_VERTICALFLIP) + if (flip) p.z = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height); else p.z = FIXED_TO_FLOAT(spr->mobj->z); if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) - sprdef = &((skin_t *)spr->mobj->skin)->spritedef; + sprdef = &((skin_t *)spr->mobj->skin)->sprites[spr->mobj->sprite2]; else sprdef = &sprites[spr->mobj->sprite]; @@ -1075,14 +1060,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) if (sprframe->rotate) { - fixed_t anglef = AngleFixed(spr->mobj->angle); - // \todo adapt for 2.2 directionchar? The below code is from Kart -#if 0 - if (spr->mobj->player) - anglef = AngleFixed(spr->mobj->player->frameangle); - else - anglef = AngleFixed(spr->mobj->angle); -#endif + const fixed_t anglef = AngleFixed((spr->mobj->player ? spr->mobj->player->drawangle : spr->mobj->angle)); p.angley = FIXED_TO_FLOAT(anglef); } else diff --git a/src/hardware/hws_data.h b/src/hardware/hws_data.h index 9e2d0547eb6b980ee6c69d23e08aebd1fcf4d69e..b890d976b0ec0831dbad6bab765f3befe9ba5dd9 100644 --- a/src/hardware/hws_data.h +++ b/src/hardware/hws_data.h @@ -114,7 +114,7 @@ typedef struct snddev_s size_t numsfxs; // Windows specific data -#if defined (_WIN32) && !defined (_XBOX) +#ifdef _WIN32 UINT32 cooplevel; HWND hWnd; #endif diff --git a/src/hardware/r_minigl/r_minigl.c b/src/hardware/r_minigl/r_minigl.c deleted file mode 100644 index b2482a5521e702b1f0d87812e0e577aaf081cc4b..0000000000000000000000000000000000000000 --- a/src/hardware/r_minigl/r_minigl.c +++ /dev/null @@ -1,33 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief MiniGL API for Doom Legacy - - -// tell r_opengl.cpp to compile for MiniGL Drivers -#define MINI_GL_COMPATIBILITY - -// tell r_opengl.cpp to compile for ATI Rage Pro OpenGL driver -//#define ATI_RAGE_PRO_COMPATIBILITY - -#define DRIVER_STRING "HWRAPI Init(): SRB2 MiniGL renderer" - -// Include this at end -#include "../r_opengl/r_opengl.c" -#include "../r_opengl/ogl_win.c" - -// That's all ;-) -// Just, be sure to do the right changes in r_opengl.cpp diff --git a/src/hardware/r_minigl/r_minigl.dev b/src/hardware/r_minigl/r_minigl.dev deleted file mode 100644 index edf725ac55d9d03823b4325a6f15b1f3b52ec873..0000000000000000000000000000000000000000 --- a/src/hardware/r_minigl/r_minigl.dev +++ /dev/null @@ -1,89 +0,0 @@ -[Project] -FileName=r_minigl.dev -Name=r_minigl -Ver=1 -IsCpp=1 -Type=3 -Compiler=-D_M_IX86=500_@@_-Wall_@@_-D_WINDOWS_@@_-DUSE_WGL_SWAP_@@_-Os_@@_-fomit-frame-pointer_@@_ -CppCompiler= -Includes= -Linker=--def ../r_mingw.def_@@_-lgdi32_@@_ -Libs= -UnitCount=4 -Folders= -ObjFiles= -PrivateResource= -ResourceIncludes= -MakeIncludes= -Icon= -ExeOutput=C:\srb2demo2 -ObjectOutput=..\..\..\objs\Mingw\r_minigl -OverrideOutput=1 -OverrideOutputName=r_minigl.dll -HostApplication= -CommandLine= -IncludeVersionInfo=0 -SupportXPThemes=0 -CompilerSet=0 -CompilerSettings=00000000000000000111d0 -UseCustomMakefile=0 -CustomMakefile= - -[Unit1] -FileName=..\r_opengl\ogl_win.c -Folder= -Compile=0 -CompileCpp=0 -Link=0 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd=$(CC) -c ogl_win.c -o ../../../objs/Mingw/r_minigl/ogl_win.o $(CFLAGS) - -[Unit2] -FileName=..\r_opengl\r_opengl.c -Folder= -Compile=0 -CompileCpp=0 -Link=0 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd=$(CC) -c r_opengl.c -o ../../../objs/Mingw/r_minigl/r_opengl.o $(CFLAGS) - -[Unit3] -FileName=..\r_opengl\r_opengl.h -Folder= -Compile=1 -CompileCpp=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[VersionInfo] -Major=0 -Minor=1 -Release=1 -Build=1 -LanguageID=1033 -CharsetID=1252 -CompanyName= -FileVersion=0.1 -FileDescription=Developed using the Dev-C++ IDE -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename=r_opengl.exe -ProductName=r_opengl -ProductVersion=0.1 -AutoIncBuildNr=0 - -[Unit4] -FileName=r_minigl.c -CompileCpp=0 -Folder=r_minigl -Compile=1 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd=$(CC) -c r_minigl.c -o ../../../objs/Mingw/r_minigl/r_minigl.o $(CFLAGS) - diff --git a/src/hardware/r_minigl/r_minigl.dsp b/src/hardware/r_minigl/r_minigl.dsp deleted file mode 100644 index 686ca35a3dd6eec4ab45596e50f8f5b3752f1ecc..0000000000000000000000000000000000000000 --- a/src/hardware/r_minigl/r_minigl.dsp +++ /dev/null @@ -1,103 +0,0 @@ -# Microsoft Developer Studio Project File - Name="r_minigl" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=r_minigl - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "r_minigl.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "r_minigl.mak" CFG="r_minigl - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "r_minigl - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "r_minigl - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "r_minigl - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "..\..\..\objs\Release" -# PROP BASE Intermediate_Dir "..\..\..\objs\Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "..\..\..\bin\VC\Release\r_minigl" -# PROP Intermediate_Dir "..\..\..\objs\VC\Release\r_minigl" -# PROP Ignore_Export_Lib 1 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "R_MINIGL_EXPORTS" /YX /FD /c -# ADD CPP /nologo /G5 /MT /W3 /GX /Zi /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /FR /FD /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x80c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 user32.lib gdi32.lib /nologo /dll /pdb:"..\..\..\bin\VC\Release\r_minigl.pdb" /machine:I386 /out:"..\..\..\bin\VC\Release\r_minigl.dll" -# SUBTRACT LINK32 /pdb:none /debug - -!ELSEIF "$(CFG)" == "r_minigl - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "..\..\..\objs\Debug" -# PROP BASE Intermediate_Dir "..\..\..\objs\Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "..\..\..\bin\VC\Debug\r_minigl" -# PROP Intermediate_Dir "..\..\..\objs\VC\Debug\r_minigl" -# PROP Ignore_Export_Lib 1 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "R_MINIGL_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /D "_MBCS" /D "_USRDLL" /D "R_MINIGL_EXPORTS" /FR /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x80c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 ouser32.lib gdi32.lib /nologo /dll /pdb:"..\..\..\bin\VC\Debug\r_minigl.pdb" /debug /machine:I386 /out:"..\..\..\bin\VC\Debug\r_minigl.dll" /pdbtype:sept -# SUBTRACT LINK32 /pdb:none - -!ENDIF - -# Begin Target - -# Name "r_minigl - Win32 Release" -# Name "r_minigl - Win32 Debug" -# Begin Source File - -SOURCE=.\r_minigl.c -# End Source File -# Begin Source File - -SOURCE=..\r_opengl\r_opengl.h -# End Source File -# End Target -# End Project diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 816c4758ce3e0aa08ef2303f11d0290232c472a6..415e6648f081238369fef42fd99b7f0988be9e3d 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -945,9 +945,7 @@ EXPORT void HWRAPI(Draw2DLine) (F2DCoord * v1, static void Clamp2D(GLenum pname) { pglTexParameteri(GL_TEXTURE_2D, pname, GL_CLAMP); // fallback clamp -#ifdef GL_CLAMP_TO_EDGE pglTexParameteri(GL_TEXTURE_2D, pname, GL_CLAMP_TO_EDGE); -#endif } @@ -1002,7 +1000,6 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) break; } } - if (Xor & PF_NoAlphaTest) { if (PolyFlags & PF_NoAlphaTest) @@ -1231,15 +1228,11 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) if (MipMap) { pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); -#ifdef GL_TEXTURE_MIN_LOD pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); -#endif -#ifdef GL_TEXTURE_MAX_LOD if (pTexInfo->flags & TF_TRANSPARENT) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff else pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4); -#endif //pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR); } else @@ -1251,15 +1244,11 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) if (MipMap) { pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); -#ifdef GL_TEXTURE_MIN_LOD pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); -#endif -#ifdef GL_TEXTURE_MAX_LOD if (pTexInfo->flags & TF_TRANSPARENT) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff else pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4); -#endif //pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR); } else @@ -1271,15 +1260,11 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) { pgluBuild2DMipmaps(GL_TEXTURE_2D, textureformatGL, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); // Control the mipmap level of detail -#ifdef GL_TEXTURE_MIN_LOD pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); // the lower the number, the higer the detail -#endif -#ifdef GL_TEXTURE_MAX_LOD if (pTexInfo->flags & TF_TRANSPARENT) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff else pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 5); -#endif } else pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index a9a2b7504c07287ab40efae2c01d4e23ae88fc5f..f86100e27148054a0fc4fa167f0e429fc220f7a8 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -69,6 +69,7 @@ patch_t *nightsnum[10]; // 0-9 // Level title and credits fonts patch_t *lt_font[LT_FONTSIZE]; patch_t *cred_font[CRED_FONTSIZE]; +patch_t *ttlnum[20]; // act numbers (0-19) static player_t *plr; boolean chat_on; // entering a chat message? @@ -84,15 +85,16 @@ patch_t *rmatcico; patch_t *bmatcico; patch_t *tagico; patch_t *tallminus; +patch_t *tallinfin; //------------------------------------------- // coop hud //------------------------------------------- -patch_t *emeraldpics[7]; -patch_t *tinyemeraldpics[7]; +patch_t *emeraldpics[3][8]; // 0 = normal, 1 = tiny, 2 = coinbox static patch_t *emblemicon; -static patch_t *tokenicon; +patch_t *tokenicon; +static patch_t *exiticon; //------------------------------------------- // misc vars @@ -199,21 +201,6 @@ void HU_LoadGraphics(void) tny_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); } - // cache the level title font for entire game execution - lt_font[0] = (patch_t *)W_CachePatchName("LTFNT039", PU_HUDGFX); /// \note fake start hack - - // Number support - lt_font[9] = (patch_t *)W_CachePatchName("LTFNT048", PU_HUDGFX); - lt_font[10] = (patch_t *)W_CachePatchName("LTFNT049", PU_HUDGFX); - lt_font[11] = (patch_t *)W_CachePatchName("LTFNT050", PU_HUDGFX); - lt_font[12] = (patch_t *)W_CachePatchName("LTFNT051", PU_HUDGFX); - lt_font[13] = (patch_t *)W_CachePatchName("LTFNT052", PU_HUDGFX); - lt_font[14] = (patch_t *)W_CachePatchName("LTFNT053", PU_HUDGFX); - lt_font[15] = (patch_t *)W_CachePatchName("LTFNT054", PU_HUDGFX); - lt_font[16] = (patch_t *)W_CachePatchName("LTFNT055", PU_HUDGFX); - lt_font[17] = (patch_t *)W_CachePatchName("LTFNT056", PU_HUDGFX); - lt_font[18] = (patch_t *)W_CachePatchName("LTFNT057", PU_HUDGFX); - j = LT_FONTSTART; for (i = 0; i < LT_FONTSIZE; i++) { @@ -250,6 +237,14 @@ void HU_LoadGraphics(void) // minus for negative tallnums tallminus = (patch_t *)W_CachePatchName("STTMINUS", PU_HUDGFX); + tallinfin = (patch_t *)W_CachePatchName("STTINFIN", PU_HUDGFX); + + // cache act numbers for level titles + for (i = 0; i < 20; i++) + { + sprintf(buffer, "TTL%.2d", i); + ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); + } // cache the crosshairs, don't bother to know which one is being used, // just cache all 3, they're so small anyway. @@ -261,21 +256,34 @@ void HU_LoadGraphics(void) emblemicon = W_CachePatchName("EMBLICON", PU_HUDGFX); tokenicon = W_CachePatchName("TOKNICON", PU_HUDGFX); - - emeraldpics[0] = W_CachePatchName("CHAOS1", PU_HUDGFX); - emeraldpics[1] = W_CachePatchName("CHAOS2", PU_HUDGFX); - emeraldpics[2] = W_CachePatchName("CHAOS3", PU_HUDGFX); - emeraldpics[3] = W_CachePatchName("CHAOS4", PU_HUDGFX); - emeraldpics[4] = W_CachePatchName("CHAOS5", PU_HUDGFX); - emeraldpics[5] = W_CachePatchName("CHAOS6", PU_HUDGFX); - emeraldpics[6] = W_CachePatchName("CHAOS7", PU_HUDGFX); - tinyemeraldpics[0] = W_CachePatchName("TEMER1", PU_HUDGFX); - tinyemeraldpics[1] = W_CachePatchName("TEMER2", PU_HUDGFX); - tinyemeraldpics[2] = W_CachePatchName("TEMER3", PU_HUDGFX); - tinyemeraldpics[3] = W_CachePatchName("TEMER4", PU_HUDGFX); - tinyemeraldpics[4] = W_CachePatchName("TEMER5", PU_HUDGFX); - tinyemeraldpics[5] = W_CachePatchName("TEMER6", PU_HUDGFX); - tinyemeraldpics[6] = W_CachePatchName("TEMER7", PU_HUDGFX); + exiticon = W_CachePatchName("EXITICON", PU_HUDGFX); + + emeraldpics[0][0] = W_CachePatchName("CHAOS1", PU_HUDGFX); + emeraldpics[0][1] = W_CachePatchName("CHAOS2", PU_HUDGFX); + emeraldpics[0][2] = W_CachePatchName("CHAOS3", PU_HUDGFX); + emeraldpics[0][3] = W_CachePatchName("CHAOS4", PU_HUDGFX); + emeraldpics[0][4] = W_CachePatchName("CHAOS5", PU_HUDGFX); + emeraldpics[0][5] = W_CachePatchName("CHAOS6", PU_HUDGFX); + emeraldpics[0][6] = W_CachePatchName("CHAOS7", PU_HUDGFX); + emeraldpics[0][7] = W_CachePatchName("CHAOS8", PU_HUDGFX); + + emeraldpics[1][0] = W_CachePatchName("TEMER1", PU_HUDGFX); + emeraldpics[1][1] = W_CachePatchName("TEMER2", PU_HUDGFX); + emeraldpics[1][2] = W_CachePatchName("TEMER3", PU_HUDGFX); + emeraldpics[1][3] = W_CachePatchName("TEMER4", PU_HUDGFX); + emeraldpics[1][4] = W_CachePatchName("TEMER5", PU_HUDGFX); + emeraldpics[1][5] = W_CachePatchName("TEMER6", PU_HUDGFX); + emeraldpics[1][6] = W_CachePatchName("TEMER7", PU_HUDGFX); + //emeraldpics[1][7] = W_CachePatchName("TEMER8", PU_HUDGFX); -- unused + + emeraldpics[2][0] = W_CachePatchName("EMBOX1", PU_HUDGFX); + emeraldpics[2][1] = W_CachePatchName("EMBOX2", PU_HUDGFX); + emeraldpics[2][2] = W_CachePatchName("EMBOX3", PU_HUDGFX); + emeraldpics[2][3] = W_CachePatchName("EMBOX4", PU_HUDGFX); + emeraldpics[2][4] = W_CachePatchName("EMBOX5", PU_HUDGFX); + emeraldpics[2][5] = W_CachePatchName("EMBOX6", PU_HUDGFX); + emeraldpics[2][6] = W_CachePatchName("EMBOX7", PU_HUDGFX); + //emeraldpics[2][7] = W_CachePatchName("EMBOX8", PU_HUDGFX); -- unused } // Initialise Heads up @@ -424,7 +432,7 @@ void HU_AddChatText(const char *text, boolean playsound) static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags) { - XBOXSTATIC char buf[254]; + char buf[254]; size_t numwords, ix; char *msg = &buf[2]; const size_t msgspace = sizeof buf - 2; @@ -622,7 +630,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) player_names[playernum]); if (server) { - XBOXSTATIC UINT8 buf[2]; + UINT8 buf[2]; buf[0] = (UINT8)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -642,7 +650,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) CONS_Alert(CONS_WARNING, M_GetText("Illegal say command received from %s containing invalid characters\n"), player_names[playernum]); if (server) { - XBOXSTATIC char buf[2]; + char buf[2]; buf[0] = (char)playernum; buf[1] = KICK_MSG_CON_FAIL; @@ -742,26 +750,103 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) cstart = "\x83"; - if (color <= SKINCOLOR_SILVER) - cstart = "\x80"; // White - else if (color <= SKINCOLOR_BLACK) - cstart = "\x86"; // Grey - else if (color <= SKINCOLOR_BLUE) - cstart = "\x84"; // Blue - else if (color <= SKINCOLOR_PEACH) - cstart = "\x87"; //... Orange??? - else if (color == SKINCOLOR_PINK) - cstart = "\x85"; // Red. - else if (color <= SKINCOLOR_PURPLE) - cstart = "\x81"; // Purple - else if (color <= SKINCOLOR_ROSEWOOD) - cstart = "\x87"; // Orange - else if (color <= SKINCOLOR_DARKRED) - cstart = "\x85"; // Red - else if (color <= SKINCOLOR_OLIVE) - cstart = "\x83"; // green - else if (color <= SKINCOLOR_GOLD) - cstart = "\x82"; // Yellow + // Follow palette order at r_draw.c Color_Names + switch (color) + { + default: + case SKINCOLOR_WHITE: + case SKINCOLOR_BONE: + case SKINCOLOR_CLOUDY: + case SKINCOLOR_GREY: + case SKINCOLOR_SILVER: + case SKINCOLOR_AETHER: + case SKINCOLOR_SLATE: + cstart = "\x80"; // white + break; + case SKINCOLOR_CARBON: + case SKINCOLOR_JET: + case SKINCOLOR_BLACK: + cstart = "\x86"; // V_GRAYMAP + break; + case SKINCOLOR_PINK: + case SKINCOLOR_RUBY: + case SKINCOLOR_SALMON: + case SKINCOLOR_RED: + case SKINCOLOR_CRIMSON: + case SKINCOLOR_FLAME: + cstart = "\x85"; // V_REDMAP + break; + case SKINCOLOR_YOGURT: + case SKINCOLOR_BROWN: + case SKINCOLOR_TAN: + case SKINCOLOR_BEIGE: + case SKINCOLOR_QUAIL: + cstart = "\x8d"; // V_BROWNMAP + break; + case SKINCOLOR_MOSS: + case SKINCOLOR_GREEN: + case SKINCOLOR_FOREST: + case SKINCOLOR_EMERALD: + case SKINCOLOR_MINT: + cstart = "\x83"; // V_GREENMAP + break; + case SKINCOLOR_AZURE: + cstart = "\x8c"; // V_AZUREMAP + break; + case SKINCOLOR_LAVENDER: + case SKINCOLOR_PASTEL: + case SKINCOLOR_PURPLE: + cstart = "\x89"; // V_PURPLEMAP + break; + case SKINCOLOR_PEACHY: + case SKINCOLOR_LILAC: + case SKINCOLOR_PLUM: + case SKINCOLOR_ROSY: + cstart = "\x8e"; // V_ROSYMAP + break; + case SKINCOLOR_SUNSET: + case SKINCOLOR_APRICOT: + case SKINCOLOR_ORANGE: + case SKINCOLOR_RUST: + cstart = "\x87"; // V_ORANGEMAP + break; + case SKINCOLOR_GOLD: + case SKINCOLOR_SANDY: + case SKINCOLOR_YELLOW: + case SKINCOLOR_OLIVE: + cstart = "\x82"; // V_YELLOWMAP + break; + case SKINCOLOR_LIME: + case SKINCOLOR_PERIDOT: + cstart = "\x8b"; // V_PERIDOTMAP + break; + case SKINCOLOR_SEAFOAM: + case SKINCOLOR_AQUA: + cstart = "\x8a"; // V_AQUAMAP + break; + case SKINCOLOR_TEAL: + case SKINCOLOR_WAVE: + case SKINCOLOR_CYAN: + case SKINCOLOR_SKY: + case SKINCOLOR_CERULEAN: + case SKINCOLOR_ICY: + case SKINCOLOR_SAPPHIRE: + case SKINCOLOR_VAPOR: + cstart = "\x88"; // V_SKYMAP + break; + case SKINCOLOR_CORNFLOWER: + case SKINCOLOR_BLUE: + case SKINCOLOR_COBALT: + case SKINCOLOR_DUSK: + cstart = "\x84"; // V_BLUEMAP + break; + case SKINCOLOR_BUBBLEGUM: + case SKINCOLOR_MAGENTA: + case SKINCOLOR_NEON: + case SKINCOLOR_VIOLET: + cstart = "\x81"; // V_MAGENTAMAP + break; + } } prefix = cstart; @@ -1304,7 +1389,7 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) // 30/7/18: chaty is now the distance at which the lowest point of the chat will be drawn if that makes any sense. -INT16 chatx = 13, chaty = 169; // let's use this as our coordinates, shh +INT16 chatx = 13, chaty = 169; // let's use this as our coordinates // chat stuff by VincyTM LOL XD! @@ -1383,7 +1468,6 @@ static void HU_drawMiniChat(void) if (splitscreen > 1) y += 16; }*/ - y -= (G_RingSlingerGametype() ? 16 : 0); dx = 0; dy = 0; @@ -1479,12 +1563,10 @@ static void HU_drawChatLog(INT32 offset) if (splitscreen) { y -= BASEVIDHEIGHT/2; - if (splitscreen > 1) - y += 16; + //if (splitscreen > 1) + //y += 16; } #endif - y -= (G_RingSlingerGametype() ? 16 : 0); - chat_topy = y + chat_scroll*charheight; chat_bottomy = chat_topy + boxh*charheight; @@ -1556,10 +1638,11 @@ static void HU_drawChatLog(INT32 offset) chat_scroll = chat_maxscroll; // draw arrows to indicate that we can (or not) scroll. + // account for Y = -1 offset in tinyfont if (chat_scroll > 0) - V_DrawThinString(chatx-8, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), V_SNAPTOBOTTOM | V_SNAPTOLEFT | V_YELLOWMAP, "\x1A"); // up arrow + V_DrawThinString(chatx-8, ((justscrolledup) ? (chat_topy-1) : (chat_topy)) - 1, V_SNAPTOBOTTOM | V_SNAPTOLEFT | V_YELLOWMAP, "\x1A"); // up arrow if (chat_scroll < chat_maxscroll) - V_DrawThinString(chatx-8, chat_bottomy-((justscrolleddown) ? 5 : 6), V_SNAPTOBOTTOM | V_SNAPTOLEFT | V_YELLOWMAP, "\x1B"); // down arrow + V_DrawThinString(chatx-8, chat_bottomy-((justscrolleddown) ? 5 : 6) - 1, V_SNAPTOBOTTOM | V_SNAPTOLEFT | V_YELLOWMAP, "\x1B"); // down arrow justscrolleddown = false; justscrolledup = false; @@ -1593,7 +1676,6 @@ static void HU_DrawChat(void) } } #endif - y -= (G_RingSlingerGametype() ? 16 : 0); if (teamtalk) { @@ -1686,7 +1768,6 @@ static void HU_DrawChat(void) p_dispy += 16; } #endif - p_dispy -= (G_RingSlingerGametype() ? 16 : 0); i = 0; for(i=0; (i<MAXPLAYERS); i++) @@ -1787,7 +1868,7 @@ static void HU_DrawChat_Old(void) else { //charwidth = SHORT(hu_font[talk[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value); + V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, true); } c += charwidth; } @@ -1815,7 +1896,7 @@ static void HU_DrawChat_Old(void) else { //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; - V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value); + V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, true); } c += charwidth; @@ -1825,6 +1906,9 @@ static void HU_DrawChat_Old(void) y += charheight; } } + + if (hu_tick < 4) + V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, true); } #endif @@ -1890,7 +1974,7 @@ static void HU_DrawCEcho(void) INT32 y = (BASEVIDHEIGHT/2)-4; INT32 pnumlines = 0; - UINT32 realflags = cechoflags; + UINT32 realflags = cechoflags|V_PERPLAYER; // requested as part of splitscreen's stuff INT32 realalpha = (INT32)((cechoflags & V_ALPHAMASK) >> V_ALPHASHIFT); char *line; @@ -1933,6 +2017,12 @@ static void HU_DrawCEcho(void) *line = '\0'; V_DrawCenteredString(BASEVIDWIDTH/2, y, realflags, echoptr); + if (splitscreen) + { + stplyr = ((stplyr == &players[displayplayer]) ? &players[secondarydisplayplayer] : &players[displayplayer]); + V_DrawCenteredString(BASEVIDWIDTH/2, y, realflags, echoptr); + stplyr = ((stplyr == &players[displayplayer]) ? &players[secondarydisplayplayer] : &players[displayplayer]); + } y += ((realflags & V_RETURN8) ? 8 : 12); echoptr = line; @@ -1966,25 +2056,29 @@ UINT16 hu_demorings; static void HU_DrawDemoInfo(void) { - V_DrawString(4, 188-24, V_YELLOWMAP, va(M_GetText("%s's replay"), player_names[0])); + INT32 h = 188; + if (modeattacking == ATTACKING_NIGHTS) + h -= 12; + + V_DrawString(4, h-24, V_YELLOWMAP|V_ALLOWLOWERCASE, va(M_GetText("%s's replay"), player_names[0])); if (modeattacking) { - V_DrawString(4, 188-16, V_YELLOWMAP|V_MONOSPACE, "SCORE:"); - V_DrawRightAlignedString(120, 188-16, V_MONOSPACE, va("%d", hu_demoscore)); + V_DrawString(4, h-16, V_YELLOWMAP|V_MONOSPACE, "SCORE:"); + V_DrawRightAlignedString(120, h-16, V_MONOSPACE, va("%d", hu_demoscore)); - V_DrawString(4, 188- 8, V_YELLOWMAP|V_MONOSPACE, "TIME:"); + V_DrawString(4, h-8, V_YELLOWMAP|V_MONOSPACE, "TIME:"); if (hu_demotime != UINT32_MAX) - V_DrawRightAlignedString(120, 188- 8, V_MONOSPACE, va("%i:%02i.%02i", + V_DrawRightAlignedString(120, h-8, V_MONOSPACE, va("%i:%02i.%02i", G_TicsToMinutes(hu_demotime,true), G_TicsToSeconds(hu_demotime), G_TicsToCentiseconds(hu_demotime))); else - V_DrawRightAlignedString(120, 188- 8, V_MONOSPACE, "--:--.--"); + V_DrawRightAlignedString(120, h-8, V_MONOSPACE, "--:--.--"); if (modeattacking == ATTACKING_RECORD) { - V_DrawString(4, 188 , V_YELLOWMAP|V_MONOSPACE, "RINGS:"); - V_DrawRightAlignedString(120, 188 , V_MONOSPACE, va("%d", hu_demorings)); + V_DrawString(4, h, V_YELLOWMAP|V_MONOSPACE, "RINGS:"); + V_DrawRightAlignedString(120, h, V_MONOSPACE, va("%d", hu_demorings)); } } } @@ -2091,6 +2185,31 @@ void HU_Drawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_YELLOWMAP | V_ALLOWLOWERCASE, resynch_text); } + + if (modeattacking && pausedelay > 0 && !pausebreakkey) + { + INT32 strength = ((pausedelay - 1 - NEWTICRATE/2)*10)/(NEWTICRATE/3); + INT32 y = hudinfo[HUD_LIVES].y - 13; + + if (players[consoleplayer].powers[pw_carry] == CR_NIGHTSMODE) + y -= 16; + else + { + if (players[consoleplayer].pflags & PF_AUTOBRAKE) + y -= 8; + if (players[consoleplayer].pflags & PF_ANALOGMODE) + y -= 8; + } + + V_DrawThinString(hudinfo[HUD_LIVES].x-2, y, + hudinfo[HUD_LIVES].f|((leveltime & 4) ? V_SKYMAP : V_BLUEMAP), + "HOLD TO RETRY..."); + + if (strength > 9) + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0); + else if (strength > 0) + V_DrawFadeScreen(0, strength); + } } //====================================================================== @@ -2167,13 +2286,16 @@ void HU_Erase(void) // IN-LEVEL MULTIPLAYER RANKINGS //====================================================================== +#define supercheckdef ((players[tab[i].num].powers[pw_super] && players[tab[i].num].mo && (players[tab[i].num].mo->state < &states[S_PLAY_SUPER_TRANS1] || players[tab[i].num].mo->state >= &states[S_PLAY_SUPER_TRANS6])) || (players[tab[i].num].powers[pw_carry] == CR_NIGHTSMODE && skins[players[tab[i].num].skin].flags & SF_SUPER)) +#define greycheckdef (players[tab[i].num].spectator || players[tab[i].num].playerstate == PST_DEAD || (G_IsSpecialStage(gamemap) && players[tab[i].num].exiting)) + // // HU_drawPing // void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext) { UINT8 numbars = 1; // how many ping bars do we draw? - UINT8 barcolor = 128; // color we use for the bars (green, yellow or red) + UINT8 barcolor = 35; // color we use for the bars (green, yellow or red) SINT8 i = 0; SINT8 yoffset = 6; INT32 dx = x+1 - (V_SmallStringWidth(va("%dms", ping), V_ALLOWLOWERCASE)/2); @@ -2181,12 +2303,12 @@ void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext) if (ping < 128) { numbars = 3; - barcolor = 184; + barcolor = 112; } else if (ping < 256) { numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it. - barcolor = 103; + barcolor = 73; } if (!notext || vid.width >= 640) // how sad, we're using a shit resolution. @@ -2209,6 +2331,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I { INT32 i; const UINT8 *colormap; + boolean greycheck, supercheck; //this function is designed for 9 or less score lines only I_Assert(scorelines <= 9); @@ -2217,9 +2340,12 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I for (i = 0; i < scorelines; i++) { - if (players[tab[i].num].spectator) + if (players[tab[i].num].spectator && gametype != GT_COOP) continue; //ignore them. + greycheck = greycheckdef; + supercheck = supercheckdef; + if (!splitscreen) // don't draw it on splitscreen, { if (!(tab[i].num == serverplayer)) @@ -2230,17 +2356,19 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | ((players[tab[i].num].health > 0) ? 0 : V_60TRANS) + | (greycheck ? V_60TRANS : 0) | V_ALLOWLOWERCASE, tab[i].name); // Draw emeralds - if (!players[tab[i].num].powers[pw_super] + if (players[tab[i].num].powers[pw_invulnerability] && (players[tab[i].num].powers[pw_invulnerability] == players[tab[i].num].powers[pw_sneakers]) && ((leveltime/7) & 1)) + HU_DrawEmeralds(x-12,y+2,255); + else if (!players[tab[i].num].powers[pw_super] || ((leveltime/7) & 1)) { HU_DrawEmeralds(x-12,y+2,tab[i].emeralds); } - if (players[tab[i].num].health <= 0) + if (greycheck) V_DrawSmallTranslucentPatch (x, y-4, V_80TRANS, livesback); else V_DrawSmallScaledPatch (x, y-4, 0, livesback); @@ -2248,11 +2376,11 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I if (tab[i].color == 0) { colormap = colormaps; - if (players[tab[i].num].powers[pw_super]) + if (supercheck) V_DrawSmallScaledPatch(x, y-4, 0, superprefix[players[tab[i].num].skin]); else { - if (players[tab[i].num].health <= 0) + if (greycheck) V_DrawSmallTranslucentPatch(x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin]); else V_DrawSmallScaledPatch(x, y-4, 0, faceprefix[players[tab[i].num].skin]); @@ -2260,31 +2388,34 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I } else { - if (players[tab[i].num].powers[pw_super]) + if (supercheck) { - colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); + colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo->color, GTC_CACHE); V_DrawSmallMappedPatch (x, y-4, 0, superprefix[players[tab[i].num].skin], colormap); } else { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); - if (players[tab[i].num].health <= 0) + if (greycheck) V_DrawSmallTranslucentMappedPatch (x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin], colormap); else V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); } } - if (G_GametypeUsesLives()) //show lives - V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%dx", players[tab[i].num].lives)); + if (G_GametypeUsesLives() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives + V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|(greycheck ? V_60TRANS : 0), va("%dx", players[tab[i].num].lives)); else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT) { - if (players[tab[i].num].health <= 0) + if (greycheck) V_DrawSmallTranslucentPatch(x-32, y-4, V_60TRANS, tagico); else V_DrawSmallScaledPatch(x-32, y-4, 0, tagico); } + if (players[tab[i].num].exiting) + V_DrawSmallScaledPatch(x - SHORT(exiticon->width)/2 - 1, y-3, 0, exiticon); + if (gametype == GT_RACE) { if (circuitmap) @@ -2292,13 +2423,13 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I if (players[tab[i].num].exiting) V_DrawRightAlignedString(x+240, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime))); else - V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count)); + V_DrawRightAlignedString(x+240, y, (greycheck ? V_60TRANS : 0), va("%u", tab[i].count)); } else - V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); + V_DrawRightAlignedString(x+240, y, (greycheck ? V_60TRANS : 0), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); } else - V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count)); + V_DrawRightAlignedString(x+240, y, (greycheck ? V_60TRANS : 0), va("%u", tab[i].count)); y += 16; } @@ -2311,25 +2442,25 @@ static void HU_Draw32Emeralds(INT32 x, INT32 y, INT32 pemeralds) { //Draw the emeralds, in the CORRECT order, using tiny emerald sprites. if (pemeralds & EMERALD1) - V_DrawSmallScaledPatch(x , y, 0, tinyemeraldpics[0]); + V_DrawSmallScaledPatch(x , y, 0, emeraldpics[1][0]); if (pemeralds & EMERALD2) - V_DrawSmallScaledPatch(x+4, y, 0, tinyemeraldpics[1]); + V_DrawSmallScaledPatch(x+4, y, 0, emeraldpics[1][1]); if (pemeralds & EMERALD3) - V_DrawSmallScaledPatch(x+8, y, 0, tinyemeraldpics[2]); + V_DrawSmallScaledPatch(x+8, y, 0, emeraldpics[1][2]); if (pemeralds & EMERALD4) - V_DrawSmallScaledPatch(x+12 , y, 0, tinyemeraldpics[3]); + V_DrawSmallScaledPatch(x+12 , y, 0, emeraldpics[1][3]); if (pemeralds & EMERALD5) - V_DrawSmallScaledPatch(x+16, y, 0, tinyemeraldpics[4]); + V_DrawSmallScaledPatch(x+16, y, 0, emeraldpics[1][4]); if (pemeralds & EMERALD6) - V_DrawSmallScaledPatch(x+20, y, 0, tinyemeraldpics[5]); + V_DrawSmallScaledPatch(x+20, y, 0, emeraldpics[1][5]); if (pemeralds & EMERALD7) - V_DrawSmallScaledPatch(x+24, y, 0, tinyemeraldpics[6]); + V_DrawSmallScaledPatch(x+24, y, 0, emeraldpics[1][6]); } // @@ -2341,6 +2472,7 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer) INT32 redplayers = 0, blueplayers = 0; const UINT8 *colormap; char name[MAXPLAYERNAME+1]; + boolean greycheck, supercheck; V_DrawFill(160, 26, 1, 154, 0); //Draw a vertical line to separate the two teams. V_DrawFill(1, 26, 318, 1, 0); //And a horizontal line to make a T. @@ -2351,6 +2483,9 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer) if (players[tab[i].num].spectator) continue; //ignore them. + greycheck = greycheckdef; + supercheck = supercheckdef; + if (tab[i].color == skincolor_redteam) //red { redplayers++; @@ -2366,10 +2501,13 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer) else //er? not on red or blue, so ignore them continue; + greycheck = greycheckdef; + supercheck = supercheckdef; + strlcpy(name, tab[i].name, 8); V_DrawString(x + 10, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT) + | (greycheck ? 0 : V_TRANSLUCENT) | V_ALLOWLOWERCASE, name); if (gametype == GT_CTF) @@ -2381,13 +2519,19 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer) } // Draw emeralds - if (!players[tab[i].num].powers[pw_super] + if (players[tab[i].num].powers[pw_invulnerability] && (players[tab[i].num].powers[pw_invulnerability] == players[tab[i].num].powers[pw_sneakers]) && ((leveltime/7) & 1)) + { + HU_Draw32Emeralds(x+60, y+2, 255); + //HU_DrawEmeralds(x-12,y+2,255); + } + else if (!players[tab[i].num].powers[pw_super] || ((leveltime/7) & 1)) { HU_Draw32Emeralds(x+60, y+2, tab[i].emeralds); + //HU_DrawEmeralds(x-12,y+2,tab[i].emeralds); } - if (players[tab[i].num].powers[pw_super]) + if (supercheck) { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT/4, 0, superprefix[players[tab[i].num].skin], colormap); @@ -2395,12 +2539,12 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer) else { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); - if (players[tab[i].num].health <= 0) + if (players[tab[i].num].spectator || players[tab[i].num].playerstate == PST_DEAD) V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT/4, V_HUDTRANSHALF, faceprefix[players[tab[i].num].skin], colormap); else V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT/4, 0, faceprefix[players[tab[i].num].skin], colormap); } - V_DrawRightAlignedThinString(x+128, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + V_DrawRightAlignedThinString(x+128, y, ((players[tab[i].num].spectator || players[tab[i].num].playerstate == PST_DEAD) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); if (!splitscreen) { if (!(tab[i].num == serverplayer)) @@ -2421,6 +2565,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) boolean smol = false; const UINT8 *colormap; char name[MAXPLAYERNAME+1]; + boolean greycheck, supercheck; // before we draw, we must count how many players are in each team. It makes an additional loop, but we need to know if we have to draw a big or a small ranking. for (i = 0; i < MAXPLAYERS; i++) @@ -2484,10 +2629,13 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) else //er? not on red or blue, so ignore them continue; + greycheck = greycheckdef; + supercheck = supercheckdef; + strlcpy(name, tab[i].name, 7); V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT) + | (greycheck ? V_TRANSLUCENT : 0) | V_ALLOWLOWERCASE, name); if (gametype == GT_CTF) @@ -2499,13 +2647,15 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) } // Draw emeralds - if (!players[tab[i].num].powers[pw_super] + if (players[tab[i].num].powers[pw_invulnerability] && (players[tab[i].num].powers[pw_invulnerability] == players[tab[i].num].powers[pw_sneakers]) && ((leveltime/7) & 1)) + HU_DrawEmeralds(x-12,y+2,255); + else if (!players[tab[i].num].powers[pw_super] || ((leveltime/7) & 1)) { HU_DrawEmeralds(x-12,y+2,tab[i].emeralds); } - if (players[tab[i].num].powers[pw_super]) + if (supercheck) { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); V_DrawSmallMappedPatch (x, y-4, 0, superprefix[players[tab[i].num].skin], colormap); @@ -2513,12 +2663,12 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) else { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); - if (players[tab[i].num].health <= 0) - V_DrawSmallTranslucentMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); + if (greycheck) + V_DrawSmallTranslucentMappedPatch (x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin], colormap); else V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); } - V_DrawRightAlignedThinString(x+100, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + V_DrawRightAlignedThinString(x+100, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count)); if (!splitscreen) { if (!(tab[i].num == serverplayer)) @@ -2537,6 +2687,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline INT32 i; const UINT8 *colormap; char name[MAXPLAYERNAME+1]; + boolean greycheck, supercheck; V_DrawFill(160, 26, 1, 154, 0); //Draw a vertical line to separate the two sides. V_DrawFill(1, 26, 318, 1, 0); //And a horizontal line to make a T. @@ -2544,9 +2695,12 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline for (i = 0; i < scorelines; i++) { - if (players[tab[i].num].spectator) + if (players[tab[i].num].spectator && gametype != GT_COOP) continue; //ignore them. + greycheck = greycheckdef; + supercheck = supercheckdef; + strlcpy(name, tab[i].name, 7); if (!(tab[i].num == serverplayer)) HU_drawPing(x+ 113, y+2, playerpingtable[tab[i].num], false); @@ -2555,16 +2709,21 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT) + | (greycheck ? V_TRANSLUCENT : 0) | V_ALLOWLOWERCASE, name); - if (G_GametypeUsesLives()) //show lives + if (G_GametypeUsesLives() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE, va("%dx", players[tab[i].num].lives)); else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT) V_DrawSmallScaledPatch(x-28, y-4, 0, tagico); + if (players[tab[i].num].exiting) + V_DrawSmallScaledPatch(x - SHORT(exiticon->width)/2 - 1, y-3, 0, exiticon); + // Draw emeralds - if (!players[tab[i].num].powers[pw_super] + if (players[tab[i].num].powers[pw_invulnerability] && (players[tab[i].num].powers[pw_invulnerability] == players[tab[i].num].powers[pw_sneakers]) && ((leveltime/7) & 1)) + HU_DrawEmeralds(x-12,y+2,255); + else if (!players[tab[i].num].powers[pw_super] || ((leveltime/7) & 1)) { HU_DrawEmeralds(x-12,y+2,tab[i].emeralds); @@ -2574,19 +2733,19 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline if (tab[i].color == 0) { colormap = colormaps; - if (players[tab[i].num].powers[pw_super]) + if (supercheck) V_DrawSmallScaledPatch (x, y-4, 0, superprefix[players[tab[i].num].skin]); else { - if (players[tab[i].num].health <= 0) - V_DrawSmallTranslucentPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin]); + if (greycheck) + V_DrawSmallTranslucentPatch (x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin]); else V_DrawSmallScaledPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin]); } } else { - if (players[tab[i].num].powers[pw_super]) + if (supercheck) { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); V_DrawSmallMappedPatch (x, y-4, 0, superprefix[players[tab[i].num].skin], colormap); @@ -2594,8 +2753,8 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline else { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); - if (players[tab[i].num].health <= 0) - V_DrawSmallTranslucentMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); + if (greycheck) + V_DrawSmallTranslucentMappedPatch (x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin], colormap); else V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); } @@ -2609,13 +2768,13 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline if (players[tab[i].num].exiting) V_DrawRightAlignedThinString(x+146, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime))); else - V_DrawRightAlignedThinString(x+146, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + V_DrawRightAlignedThinString(x+146, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count)); } else - V_DrawRightAlignedThinString(x+146, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); + V_DrawRightAlignedThinString(x+146, y, (greycheck ? V_TRANSLUCENT : 0), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); } else - V_DrawRightAlignedThinString(x+100, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + V_DrawRightAlignedThinString(x+100, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count)); y += 16; if (y > 160) @@ -2634,6 +2793,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor INT32 i; const UINT8 *colormap; char name[MAXPLAYERNAME+1]; + boolean greycheck, supercheck; V_DrawFill(160, 26, 1, 154, 0); //Draw a vertical line to separate the two sides. V_DrawFill(1, 26, 318, 1, 0); //And a horizontal line to make a T. @@ -2641,9 +2801,12 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor for (i = 0; i < scorelines; i++) { - if (players[tab[i].num].spectator) + if (players[tab[i].num].spectator && gametype != GT_COOP) continue; //ignore them. + greycheck = greycheckdef; + supercheck = supercheckdef; + strlcpy(name, tab[i].name, 7); if (!splitscreen) // don't draw it on splitscreen, { @@ -2655,7 +2818,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor V_DrawString(x + 10, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT) + | (greycheck ? 0 : V_TRANSLUCENT) | V_ALLOWLOWERCASE, name); if (G_GametypeUsesLives()) //show lives @@ -2664,7 +2827,12 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor V_DrawFixedPatch((x-10)*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, tagico, 0); // Draw emeralds - if (!players[tab[i].num].powers[pw_super] + if (players[tab[i].num].powers[pw_invulnerability] && (players[tab[i].num].powers[pw_invulnerability] == players[tab[i].num].powers[pw_sneakers]) && ((leveltime/7) & 1)) + { + HU_Draw32Emeralds(x+60, y+2, 255); + //HU_DrawEmeralds(x-12,y+2,255); + } + else if (!players[tab[i].num].powers[pw_super] || ((leveltime/7) & 1)) { HU_Draw32Emeralds(x+60, y+2, tab[i].emeralds); @@ -2679,7 +2847,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT/4, 0, superprefix[players[tab[i].num].skin], 0); else { - if (players[tab[i].num].health <= 0) + if (greycheck) V_DrawFixedPatch(x*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, V_HUDTRANSHALF, faceprefix[players[tab[i].num].skin], 0); else V_DrawFixedPatch(x*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, faceprefix[players[tab[i].num].skin], 0); @@ -2687,7 +2855,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor } else { - if (players[tab[i].num].powers[pw_super]) + if (supercheck) { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT/4, 0, superprefix[players[tab[i].num].skin], colormap); @@ -2695,7 +2863,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor else { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); - if (players[tab[i].num].health <= 0) + if (greycheck) V_DrawFixedPatch(x*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, V_HUDTRANSHALF, faceprefix[players[tab[i].num].skin], colormap); else V_DrawFixedPatch(x*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, faceprefix[players[tab[i].num].skin], colormap); @@ -2710,13 +2878,13 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor if (players[tab[i].num].exiting) V_DrawRightAlignedThinString(x+128, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime))); else - V_DrawRightAlignedThinString(x+128, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + V_DrawRightAlignedThinString(x+128, y, (greycheck ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); } else - V_DrawRightAlignedThinString(x+128, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); + V_DrawRightAlignedThinString(x+128, y, (greycheck ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); } else - V_DrawRightAlignedThinString(x+128, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + V_DrawRightAlignedThinString(x+128, y, (greycheck ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); y += 9; if (i == 16) @@ -2734,25 +2902,25 @@ void HU_DrawEmeralds(INT32 x, INT32 y, INT32 pemeralds) { //Draw the emeralds, in the CORRECT order, using tiny emerald sprites. if (pemeralds & EMERALD1) - V_DrawSmallScaledPatch(x , y-6, 0, tinyemeraldpics[0]); + V_DrawSmallScaledPatch(x , y-6, 0, emeraldpics[1][0]); if (pemeralds & EMERALD2) - V_DrawSmallScaledPatch(x+4, y-3, 0, tinyemeraldpics[1]); + V_DrawSmallScaledPatch(x+4, y-3, 0, emeraldpics[1][1]); if (pemeralds & EMERALD3) - V_DrawSmallScaledPatch(x+4, y+3, 0, tinyemeraldpics[2]); + V_DrawSmallScaledPatch(x+4, y+3, 0, emeraldpics[1][2]); if (pemeralds & EMERALD4) - V_DrawSmallScaledPatch(x , y+6, 0, tinyemeraldpics[3]); + V_DrawSmallScaledPatch(x , y+6, 0, emeraldpics[1][3]); if (pemeralds & EMERALD5) - V_DrawSmallScaledPatch(x-4, y+3, 0, tinyemeraldpics[4]); + V_DrawSmallScaledPatch(x-4, y+3, 0, emeraldpics[1][4]); if (pemeralds & EMERALD6) - V_DrawSmallScaledPatch(x-4, y-3, 0, tinyemeraldpics[5]); + V_DrawSmallScaledPatch(x-4, y-3, 0, emeraldpics[1][5]); if (pemeralds & EMERALD7) - V_DrawSmallScaledPatch(x, y, 0, tinyemeraldpics[6]); + V_DrawSmallScaledPatch(x, y, 0, emeraldpics[1][6]); } // @@ -2807,7 +2975,7 @@ static inline void HU_DrawSpectatorTicker(void) templength = length; } - V_DrawString(templength, height + 8, V_TRANSLUCENT, current); + V_DrawString(templength, height + 8, V_TRANSLUCENT|V_ALLOWLOWERCASE, current); } length += (signed)strlen(player_names[i]) * 8 + 16; @@ -2819,7 +2987,6 @@ static inline void HU_DrawSpectatorTicker(void) // static void HU_DrawRankings(void) { - patch_t *p; playersort_t tab[MAXPLAYERS]; INT32 i, j, scorelines; boolean completed[MAXPLAYERS]; @@ -2828,43 +2995,12 @@ static void HU_DrawRankings(void) // draw the current gametype in the lower right HU_drawGametype(); - if (G_GametypeHasTeams()) - { - if (gametype == GT_CTF) - p = bflagico; - else - p = bmatcico; - - V_DrawSmallScaledPatch(128 - SHORT(p->width)/4, 4, 0, p); - V_DrawCenteredString(128, 16, 0, va("%u", bluescore)); - - if (gametype == GT_CTF) - p = rflagico; - else - p = rmatcico; - - V_DrawSmallScaledPatch(192 - SHORT(p->width)/4, 4, 0, p); - V_DrawCenteredString(192, 16, 0, va("%u", redscore)); - } - if (gametype != GT_RACE && gametype != GT_COMPETITION && gametype != GT_COOP) { if (cv_timelimit.value && timelimitintics > 0) { - INT32 timeval = (timelimitintics+1-leveltime)/TICRATE; - - if (leveltime <= timelimitintics) - { - V_DrawCenteredString(64, 8, 0, "TIME LEFT"); - V_DrawCenteredString(64, 16, 0, va("%u", timeval)); - } - - // overtime - if ((leveltime > (timelimitintics + TICRATE/2)) && cv_overtime.value) - { - V_DrawCenteredString(64, 8, 0, "TIME LEFT"); - V_DrawCenteredString(64, 16, 0, "OVERTIME"); - } + V_DrawCenteredString(64, 8, 0, "TIME"); + V_DrawCenteredString(64, 16, 0, va("%i:%02i", G_TicsToMinutes(stplyr->realtime, true), G_TicsToSeconds(stplyr->realtime))); } if (cv_pointlimit.value > 0) @@ -2913,61 +3049,67 @@ static void HU_DrawRankings(void) for (j = 0; j < MAXPLAYERS; j++) { - if (!playeringame[j] || players[j].spectator) + if (!playeringame[j]) + continue; + + if (gametype != GT_COOP && players[j].spectator) continue; for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && !players[i].spectator) + if (!playeringame[i]) + continue; + + if (gametype != GT_COOP && players[i].spectator) + continue; + + if (gametype == GT_RACE) { - if (gametype == GT_RACE) - { - if (circuitmap) - { - if ((unsigned)players[i].laps+1 >= tab[scorelines].count && completed[i] == false) - { - tab[scorelines].count = players[i].laps+1; - tab[scorelines].num = i; - tab[scorelines].color = players[i].skincolor; - tab[scorelines].name = player_names[i]; - } - } - else - { - if (players[i].realtime <= tab[scorelines].count && completed[i] == false) - { - tab[scorelines].count = players[i].realtime; - tab[scorelines].num = i; - tab[scorelines].color = players[i].skincolor; - tab[scorelines].name = player_names[i]; - } - } - } - else if (gametype == GT_COMPETITION) + if (circuitmap) { - // todo put something more fitting for the gametype here, such as current - // number of categories led - if (players[i].score >= tab[scorelines].count && completed[i] == false) + if ((unsigned)players[i].laps+1 >= tab[scorelines].count && completed[i] == false) { - tab[scorelines].count = players[i].score; + tab[scorelines].count = players[i].laps+1; tab[scorelines].num = i; tab[scorelines].color = players[i].skincolor; tab[scorelines].name = player_names[i]; - tab[scorelines].emeralds = players[i].powers[pw_emeralds]; } } else { - if (players[i].score >= tab[scorelines].count && completed[i] == false) + if (players[i].realtime <= tab[scorelines].count && completed[i] == false) { - tab[scorelines].count = players[i].score; + tab[scorelines].count = players[i].realtime; tab[scorelines].num = i; tab[scorelines].color = players[i].skincolor; tab[scorelines].name = player_names[i]; - tab[scorelines].emeralds = players[i].powers[pw_emeralds]; } } } + else if (gametype == GT_COMPETITION) + { + // todo put something more fitting for the gametype here, such as current + // number of categories led + if (players[i].score >= tab[scorelines].count && completed[i] == false) + { + tab[scorelines].count = players[i].score; + tab[scorelines].num = i; + tab[scorelines].color = players[i].skincolor; + tab[scorelines].name = player_names[i]; + tab[scorelines].emeralds = players[i].powers[pw_emeralds]; + } + } + else + { + if (players[i].score >= tab[scorelines].count && completed[i] == false) + { + tab[scorelines].count = players[i].score; + tab[scorelines].num = i; + tab[scorelines].color = players[i].skincolor; + tab[scorelines].name = player_names[i]; + tab[scorelines].emeralds = players[i].powers[pw_emeralds]; + } + } } completed[tab[scorelines].num] = true; scorelines++; @@ -2978,7 +3120,7 @@ static void HU_DrawRankings(void) // shush, we'll do it anyway. if (G_GametypeHasTeams()) - HU_DrawTeamTabRankings(tab, whiteplayer); //separate function for Spazzo's silly request + HU_DrawTeamTabRankings(tab, whiteplayer); else if (scorelines <= 9 && !cv_compactscoreboard.value) HU_DrawTabRankings(40, 32, tab, scorelines, whiteplayer); else if (scorelines <= 20 && !cv_compactscoreboard.value) @@ -3018,25 +3160,35 @@ static void HU_DrawCoopOverlay(void) #endif if (emeralds & EMERALD1) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)-32, 0, emeraldpics[0]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)-32, 0, emeraldpics[0][0]); if (emeralds & EMERALD2) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8+24, (BASEVIDHEIGHT/3)-16, 0, emeraldpics[1]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8+24, (BASEVIDHEIGHT/3)-16, 0, emeraldpics[0][1]); if (emeralds & EMERALD3) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8+24, (BASEVIDHEIGHT/3)+16, 0, emeraldpics[2]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8+24, (BASEVIDHEIGHT/3)+16, 0, emeraldpics[0][2]); if (emeralds & EMERALD4) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)+32, 0, emeraldpics[3]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)+32, 0, emeraldpics[0][3]); if (emeralds & EMERALD5) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8-24, (BASEVIDHEIGHT/3)+16, 0, emeraldpics[4]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8-24, (BASEVIDHEIGHT/3)+16, 0, emeraldpics[0][4]); if (emeralds & EMERALD6) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8-24, (BASEVIDHEIGHT/3)-16, 0, emeraldpics[5]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8-24, (BASEVIDHEIGHT/3)-16, 0, emeraldpics[0][5]); if (emeralds & EMERALD7) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3) , 0, emeraldpics[6]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3) , 0, emeraldpics[0][6]); } static void HU_DrawNetplayCoopOverlay(void) { int i; + if (token +#ifdef HAVE_BLUA + && LUA_HudEnabled(hud_tokens) +#endif + ) + { + V_DrawString(168, 10, 0, va("- %d", token)); + V_DrawSmallScaledPatch(148, 6, 0, tokenicon); + } + #ifdef HAVE_BLUA if (!LUA_HudEnabled(hud_coopemeralds)) return; @@ -3045,7 +3197,7 @@ static void HU_DrawNetplayCoopOverlay(void) for (i = 0; i < 7; ++i) { if (emeralds & (1 << i)) - V_DrawScaledPatch(20 + (i * 20), 6, 0, emeraldpics[i]); + V_DrawScaledPatch(20 + (i * 10), 9, 0, emeraldpics[1][i]); } } diff --git a/src/hu_stuff.h b/src/hu_stuff.h index b1d3918281852caf2fdd58dce33721971c9d9c2c..ab77e67b6f9a36cd3f390344a0337f9a5e666c4c 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -77,14 +77,16 @@ extern patch_t *tallnum[10]; extern patch_t *nightsnum[10]; extern patch_t *lt_font[LT_FONTSIZE]; extern patch_t *cred_font[CRED_FONTSIZE]; -extern patch_t *emeraldpics[7]; -extern patch_t *tinyemeraldpics[7]; +extern patch_t *ttlnum[20]; +extern patch_t *emeraldpics[3][8]; extern patch_t *rflagico; extern patch_t *bflagico; extern patch_t *rmatcico; extern patch_t *bmatcico; extern patch_t *tagico; extern patch_t *tallminus; +extern patch_t *tallinfin; +extern patch_t *tokenicon; // set true whenever the tab rankings are being shown for any reason extern boolean hu_showscores; diff --git a/src/i_addrinfo.c b/src/i_addrinfo.c index 03edf732de7a5e91d0359e94fc7dbe4626e36a59..375fd4845c91108a7de1d9d0e023a7cfd7d93a1e 100644 --- a/src/i_addrinfo.c +++ b/src/i_addrinfo.c @@ -20,17 +20,11 @@ #else #include <winsock.h> #endif -#elif !defined (__DJGPP__) && !defined(_WII) +#elif !defined (__DJGPP__) #include <sys/socket.h> -#ifndef _NDS #include <arpa/inet.h> -#endif -#ifdef _PS3 -#include <net/netdb.h> -#elif ! defined (_arch_dreamcast) #include <netdb.h> #endif -#endif #include "i_addrinfo.h" @@ -262,9 +256,6 @@ int I_getaddrinfo(const char *node, const char *service, for (i = 0, j = 0; i < ailen; i++, j++) { ai = *res+i; -#ifdef _PS3 - addr[i].sin_len = famsize; -#endif addr[i].sin_port = htons((UINT16)sockport); if (nodename) { diff --git a/src/i_addrinfo.h b/src/i_addrinfo.h index 1b8ce915367b8e19b4c145168e1cb41efb0fe38f..7c3afc614f0c181d295ff0d26b96ed6be773a0c4 100644 --- a/src/i_addrinfo.h +++ b/src/i_addrinfo.h @@ -39,17 +39,7 @@ #define EAI_NONAME -2 #endif -#ifdef _PS3 // PSL1GHT v2 -struct my_addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - size_t ai_addrlen; - struct sockaddr *ai_addr; - struct my_addrinfo *ai_next; -}; -#elif defined (_WIN32) // already use the stub for Win32 +#ifdef _WIN32 // already use the stub for Win32 // w32api, ws2tcpip.h, r1.12 struct my_addrinfo { int ai_flags; diff --git a/src/i_sound.h b/src/i_sound.h index 9a5c2930afeb6a6af98fb22b8d5b0296c2446bc7..d427881d240c1e705aa649e6f12d17c625135710 100644 --- a/src/i_sound.h +++ b/src/i_sound.h @@ -30,7 +30,8 @@ typedef enum { MU_MP3_MAD_UNUSED, // use MU_MP3 instead MU_FLAC, MU_MODPLUG_UNUSED, // use MU_MOD instead - MU_GME + MU_GME, + MU_MOD_EX // libopenmpt } musictype_t; /** \brief Sound subsystem runing and waiting diff --git a/src/i_tcp.c b/src/i_tcp.c index 11a84cebad5def2d4ae852261540f759a3feffd5..f2b4336dc313faba1f0c3bebe84e31e89fb923ab 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -18,20 +18,12 @@ #ifdef __GNUC__ #include <unistd.h> #endif -#ifdef __OS2__ -#include <sys/types.h> -#include <sys/time.h> -#endif // __OS2__ - -#ifdef _PS3 -#define NO_IPV6 // PSL1GHT v2 do not have IPv6 support -#endif #ifndef NO_IPV6 #define HAVE_IPV6 #endif -#if defined (_WIN32) || defined (_WIN32_WCE) +#ifdef _WIN32 #define USE_WINSOCK #if defined (_WIN64) || defined (HAVE_IPV6) #define USE_WINSOCK2 @@ -40,12 +32,6 @@ #endif #endif //WIN32 OS -#ifdef _XBOX // XBox have on WinSock API? -#undef USE_WINSOCK -#undef USE_WINSOCK1 -#undef USE_WINSOCK2 -#endif - #ifdef USE_WINSOCK2 #include <ws2tcpip.h> #endif @@ -61,17 +47,12 @@ #else #ifdef USE_WINSOCK1 #include <winsock.h> -#elif !defined (SCOUW2) && !defined (SCOUW7) && !defined (__OS2__) -#ifdef HAVE_LWIP -#include <lwip/inet.h> -#elif !defined (USE_WINSOCK) +#elif !defined (SCOUW2) && !defined (SCOUW7) +#ifndef USE_WINSOCK #include <arpa/inet.h> #endif //normal BSD API -#ifdef HAVE_LWIP -#include <lwip/sockets.h> -#define ioctl lwip_ioctl -#elif !defined (USE_WINSOCK) //!HAVE_LWIP +#ifndef USE_WINSOCK #ifdef __APPLE_CC__ #ifndef _BSD_SOCKLEN_T_ #define _BSD_SOCKLEN_T_ @@ -81,14 +62,7 @@ #include <netinet/in.h> #endif //normal BSD API -#if defined(_arch_dreamcast) && !defined(HAVE_LWIP) -#include <kos/net.h> -#elif defined(HAVE_LWIP) -#include <lwip/lwip.h> -#elif defined (_PS3) -#include <net/select.h> -#include <net/net.h> -#elif !defined(USE_WINSOCK) //!HAVE_LWIP +#ifndef USE_WINSOCK #include <netdb.h> #include <sys/ioctl.h> #endif //normal BSD API @@ -96,10 +70,6 @@ #include <errno.h> #include <time.h> -#ifdef _arch_dreamcast -#include "sdl12/SRB2DC/dchelp.h" -#endif - #if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) #include <sys/time.h> #endif // UNIXCOMMON @@ -190,11 +160,6 @@ static UINT8 UPNP_support = TRUE; // winsock stuff (in winsock a socket is not a file) #define ioctl ioctlsocket #define close closesocket - - #ifdef _WIN32_WCE - #include "sdl12/SRB2CE/cehelp.h" - #endif - #endif #include "i_addrinfo.h" @@ -205,9 +170,7 @@ static UINT8 UPNP_support = TRUE; #define SELECTTEST #endif -#elif defined(HAVE_LWIP) -#define SELECTTEST -#elif !defined( _arch_dreamcast) +#else #define SELECTTEST #endif @@ -217,7 +180,7 @@ static UINT8 UPNP_support = TRUE; typedef SOCKET SOCKET_TYPE; #define ERRSOCKET (SOCKET_ERROR) #else -#if (defined (__unix__) && !defined (MSDOS)) || defined (__APPLE__) || defined (__HAIKU__) || defined(_PS3) +#if (defined (__unix__) && !defined (MSDOS)) || defined (__APPLE__) || defined (__HAIKU__) typedef int SOCKET_TYPE; #else typedef unsigned long SOCKET_TYPE; @@ -1177,12 +1140,6 @@ boolean I_InitTcpDriver(void) CONS_Debug(DBG_NETPLAY, "WinSock description: %s\n",WSAData.szDescription); CONS_Debug(DBG_NETPLAY, "WinSock System Status: %s\n",WSAData.szSystemStatus); #endif -#ifdef HAVE_LWIP - lwip_kos_init(); -#elif defined(_arch_dreamcast) - //return; - net_init(); -#endif #ifdef __DJGPP__ #ifdef WATTCP // Alam_GBC: survive bootp, dhcp, rarp and wattcp/pktdrv from failing to load survive_eth = 1; // would be needed to not exit if pkt_eth_init() fails @@ -1235,9 +1192,6 @@ boolean I_InitTcpDriver(void) CONS_Debug(DBG_NETPLAY, "No TCP/IP driver detected\n"); #endif // libsocket #endif // __DJGPP__ -#ifdef _PS3 - netInitialize(); -#endif #ifndef __DJGPP__ init_tcp_driver = true; #endif @@ -1285,11 +1239,6 @@ void I_ShutdownTcpDriver(void) WS_addrinfocleanup(); WSACleanup(); #endif -#ifdef HAVE_LWIP - lwip_kos_shutdown(); -#elif defined(_arch_dreamcast) - net_shutdown(); -#endif #ifdef __DJGPP__ #ifdef WATTCP // wattcp //_outch = NULL; @@ -1298,9 +1247,6 @@ void I_ShutdownTcpDriver(void) __lsck_uninit(); #endif // libsocket #endif // __DJGPP__ -#ifdef _PS3 - netDeinitialize(); -#endif CONS_Printf("shut down\n"); init_tcp_driver = false; #endif diff --git a/src/info.c b/src/info.c index 08470d4cd151c35a900941fb31d84d402a2ff958..074e31ba2eb044476607796a58ab05f0d6c90c1e 100644 --- a/src/info.c +++ b/src/info.c @@ -16,6 +16,7 @@ #include "doomstat.h" #include "sounds.h" #include "p_mobj.h" +#include "p_local.h" // DMG_ constants #include "m_misc.h" #include "z_zone.h" #include "d_player.h" @@ -25,43 +26,658 @@ #endif // Hey, moron! If you change this table, don't forget about the sprite enum in info.h and the sprite lights in hw_light.c! +// For the sake of constant merge conflicts, let's spread this out char sprnames[NUMSPRITES + 1][5] = { - "NULL","UNKN","THOK","PLAY","POSS","SPOS","FISH","BUZZ","RBUZ","JETB", - "JETW","JETG","CCOM","DETN","SKIM","TRET","TURR","SHRP","JJAW","SNLR", - "VLTR","PNTY","ARCH","CBFS","SPSH","ESHI","GSNP","MNUS","SSHL","UNID", - "BBUZ","JETF","EGGM","EGGN","TNKA","TNKB","SPNK","GOOP","EGGO","PRPL", - "FAKE","EGGP","EFIR","EGGQ","EGGR","BRAK","BGOO","BMSL","EGGT","RCKT", - "ELEC","TARG","NPLM","MNPL","METL","MSCF","MSCB","RING","TRNG","EMMY", - "TOKE","RFLG","BFLG","NWNG","EMBM","CEMG","EMER","FANS","BUBL","SIGN", - "STEM","SPIK","SFLM","USPK","STPT","BMNE","SRBX","RRBX","BRBX","SHTV", - "PINV","YLTV","BLTV","BKTV","WHTV","GRTV","ELTV","EGGB","MIXU","RECY", - "QUES","GBTV","PRUP","PTTV","MTEX","MISL","TORP","ENRG","MINE","JBUL", - "TRLS","CBLL","AROW","CFIR","FWR1","FWR2","FWR3","FWR4","BUS1","BUS2", - "THZP","ALRM","GARG","SEWE","DRIP","CRL1","CRL2","CRL3","BCRY","CHAN", - "FLAM","ESTA","SMCH","BMCH","SMCE","BMCE","BTBL","STBL","CACT","FLME", - "DFLM","XMS1","XMS2","XMS3","BSZ1","BSZ2","BSZ3","BSZ4","BSZ5","BSZ6", - "BSZ7","BSZ8","STLG","DBAL","RCRY","ARMA","ARMF","ARMB","WIND","MAGN", - "ELEM","FORC","PITY","IVSP","SSPK","GOAL","BIRD","BUNY","MOUS","CHIC", - "COWZ","RBRD","SPRY","SPRR","SPRB","YSPR","RSPR","RAIN","SNO1","SPLH", - "SPLA","SMOK","BUBP","BUBO","BUBN","BUBM","POPP","TFOG","SEED","PRTL", - "SCOR","DRWN","TTAG","GFLG","RRNG","RNGB","RNGR","RNGI","RNGA","RNGE", - "RNGS","RNGG","PIKB","PIKR","PIKA","PIKE","PIKS","PIKG","TAUT","TGRE", - "TSCR","COIN","CPRK","GOOM","BGOM","FFWR","FBLL","SHLL","PUMA","HAMM", - "KOOP","BFLM","MAXE","MUS1","MUS2","TOAD","NDRN","SUPE","SUPZ","NDRL", - "NSPK","NBMP","HOOP","NSCR","NPRU","CAPS","SUPT","SPRK","BOM1","BOM2", - "BOM3","BOM4","ROIA","ROIB","ROIC","ROID","ROIE","ROIF","ROIG","ROIH", - "ROII","ROIJ","ROIK","ROIL","ROIM","ROIN","ROIO","ROIP","BBAL","GWLG", - "GWLR","SRBA","SRBB","SRBC","SRBD","SRBE","SRBF","SRBG","SRBH","SRBI", - "SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO", + "NULL", // invisible object + "UNKN", + + "THOK", // Thok! mobj + "PLAY", + + // Enemies + "POSS", // Crawla (Blue) + "SPOS", // Crawla (Red) + "FISH", // SDURF + "BUZZ", // Buzz (Gold) + "RBUZ", // Buzz (Red) + "JETB", // Jetty-Syn Bomber + "JETG", // Jetty-Syn Gunner + "CCOM", // Crawla Commander + "DETN", // Deton + "SKIM", // Skim mine dropper + "TRET", // Industrial Turret + "TURR", // Pop-Up Turret + "SHRP", // Sharp + "CRAB", // Crushstacean + "JJAW", // Jet Jaw + "SNLR", // Snailer + "VLTR", // BASH + "PNTY", // Pointy + "ARCH", // Robo-Hood + "CBFS", // Castlebot Facestabber + "STAB", // Castlebot Facestabber spear aura + "SPSH", // Egg Guard + "ESHI", // Egg Guard's shield + "GSNP", // Green Snapper + "GSNL", // Green Snapper leg + "GSNH", // Green Snapper head + "MNUS", // Minus + "MNUD", // Minus dirt + "SSHL", // Spring Shell + "UNID", // Unidus + "CANA", // Canarivore + "CANG", // Canarivore gas + + // Generic Boss Items + "JETF", // Boss jet fumes + + // Boss 1 (Greenflower) + "EGGM", + + // Boss 2 (Techno Hill) + "EGGN", // Boss 2 + "TNKA", // Boss 2 Tank 1 + "TNKB", // Boss 2 Tank 2 + "SPNK", // Boss 2 Spigot + "GOOP", // Boss 2 Goop + + // Boss 3 (Deep Sea) + "EGGO", // Boss 3 + "PRPL", // Boss 3 Propeller + "FAKE", // Boss 3 Fakemobile + + // Boss 4 (Castle Eggman) + "EGGP", + "EFIR", // Boss 4 jet flame + + // Boss 5 (Arid Canyon) + "FANG", // replaces EGGQ + "FBOM", + "FSGN", + "BARX", // bomb explosion (also used by barrel) + "BARD", // bomb dust (also used by barrel) + + // Boss 6 (Red Volcano) + "EGGR", + + // Boss 7 (Dark City) + "BRAK", + "BGOO", // Goop + "BMSL", + + // Boss 8 (Egg Rock) + "EGGT", + + // Cy-Brak-Demon; uses "BRAK" as well, but has some extras + "RCKT", // Rockets! + "ELEC", // Electricity! + "TARG", // Targeting reticules! + "NPLM", // Big napalm bombs! + "MNPL", // Mini napalm bombs! + + // Metal Sonic + "METL", + "MSCF", + "MSCB", + + // Collectible Items + "RING", + "TRNG", // Team Rings + "TOKE", // Special Stage Token + "RFLG", // Red CTF Flag + "BFLG", // Blue CTF Flag + "SPHR", // Sphere + "NCHP", // NiGHTS chip + "NSTR", // NiGHTS star + "EMBM", // Emblem + "CEMG", // Chaos Emeralds + "SHRD", // Emerald hunt shards + + // Interactive Objects + "BBLS", // water bubble source + "SIGN", // Level end sign + "SPIK", // Spike Ball + "SFLM", // Spin fire + "USPK", // Floor spike + "WSPK", // Wall spike + "WSPB", // Wall spike base + "STPT", // Starpost + "BMNE", // Big floating mine + + // Monitor Boxes + "MSTV", // MiSc TV sprites + "XLTV", // eXtra Large TV sprites + + "TRRI", // Red team: 10 RIngs + "TBRI", // Blue team: 10 RIngs + + "TVRI", // 10 RIng + "TVPI", // PIty shield + "TVAT", // ATtraction shield + "TVFO", // FOrce shield + "TVAR", // ARmageddon shield + "TVWW", // WhirlWind shield + "TVEL", // ELemental shield + "TVSS", // Super Sneakers + "TVIV", // InVincibility + "TV1U", // 1Up + "TV1P", // 1uP (textless) + "TVEG", // EGgman + "TVMX", // MiXup + "TVMY", // MYstery + "TVGV", // GraVity boots + "TVRC", // ReCycler + "TV1K", // 1,000 points (1 K) + "TVTK", // 10,000 points (Ten K) + "TVFL", // FLame shield + "TVBB", // BuBble shield + "TVZP", // Thunder shield (ZaP) + + // Projectiles + "MISL", + "TORP", // Torpedo + "ENRG", // Energy ball + "MINE", // Skim mine + "JBUL", // Jetty-Syn Bullet + "TRLS", + "CBLL", // Cannonball + "AROW", // Arrow + "CFIR", // Colored fire of various sorts + + // Greenflower Scenery + "FWR1", + "FWR2", // GFZ Sunflower + "FWR3", // GFZ budding flower + "FWR4", + "BUS1", // GFZ Bush w/ berries + "BUS2", // GFZ Bush w/o berries + "BUS3", // GFZ Bush w/ BLUE berries + // Trees (both GFZ and misc) + "TRE1", // GFZ + "TRE2", // Checker + "TRE3", // Frozen Hillside + "TRE4", // Polygon + "TRE5", // Bush tree + "TRE6", // Spring tree + + // Techno Hill Scenery + "THZP", // THZ1 Steam Flower + "FWR5", // THZ1 Spin flower (red) + "FWR6", // THZ1 Spin flower (yellow) + "THZT", // Steam Whistle tree/bush + "ALRM", // THZ2 Alarm + + // Deep Sea Scenery + "GARG", // Deep Sea Gargoyle + "SEWE", // Deep Sea Seaweed + "DRIP", // Dripping water + "CRL1", // Coral 1 + "CRL2", // Coral 2 + "CRL3", // Coral 3 + "BCRY", // Blue Crystal + "KELP", // Kelp + "DSTG", // DSZ Stalagmites + "LIBE", // DSZ Light beam + + // Castle Eggman Scenery + "CHAN", // CEZ Chain + "FLAM", // Flame + "ESTA", // Eggman esta una estatua! + "SMCH", // Small Mace Chain + "BMCH", // Big Mace Chain + "SMCE", // Small Mace + "BMCE", // Big Mace + "YSPB", // Yellow spring on a ball + "RSPB", // Red spring on a ball + "SFBR", // Small Firebar + "BFBR", // Big Firebar + "BANR", // Banner + "PINE", // Pine Tree + "CEZB", // Bush + "CNDL", // Candle/pricket + "FLMH", // Flame holder + "CTRC", // Fire torch + "CFLG", // Waving flag/segment + "CSTA", // Crawla statue + "CBBS", // Facestabber statue + "CABR", // Brambles + + // Arid Canyon Scenery + "BTBL", // Big tumbleweed + "STBL", // Small tumbleweed + "CACT", // Cacti sprites + "WWSG", // Caution Sign + "WWS2", // Cacti Sign + "WWS3", // Sharp Turn Sign + "OILL", // Oil lamp + "OILF", // Oil lamp flare + "BARR", // TNT barrel + "REMT", // TNT proximity shell + "TAZD", // Dust devil + "ADST", // Arid dust + "MCRT", // Minecart + "MCSP", // Minecart spark + "NON2", // Saloon door thinker + "SALD", // Saloon door + "TRAE", // Train cameo locomotive + "TRAI", // Train cameo wagon + "STEA", // Train steam + + // Red Volcano Scenery + "FLME", // Flame jet + "DFLM", // Blade's flame + + // Dark City Scenery + + // Egg Rock Scenery + + // Christmas Scenery + "XMS1", // Christmas Pole + "XMS2", // Candy Cane + "XMS3", // Snowman + "XMS4", // Lamppost + "XMS5", // Hanging Star + "FHZI", // FHZ ice + + // Halloween Scenery + "PUMK", // Pumpkins + "HHPL", // Dr Seuss Trees + "SHRM", // Mushroom + "HHZM", // Misc + + // Botanic Serenity Scenery + "BSZ1", // Tall flowers + "BSZ2", // Medium flowers + "BSZ3", // Small flowers + //"BSZ4", -- Tulips + "BST1", // Red tulip + "BST2", // Purple tulip + "BST3", // Blue tulip + "BST4", // Cyan tulip + "BST5", // Yellow tulip + "BST6", // Orange tulip + "BSZ5", // Cluster of Tulips + "BSZ6", // Bush + "BSZ7", // Vine + "BSZ8", // Misc things + + // Misc Scenery + "STLG", // Stalagmites + "DBAL", // Disco + "RCRY", // ATZ Red Crystal (Target) + + // Powerup Indicators + "ARMA", // Armageddon Shield Orb + "ARMF", // Armageddon Shield Ring, Front + "ARMB", // Armageddon Shield Ring, Back + "WIND", // Whirlwind Shield Orb + "MAGN", // Attract Shield Orb + "ELEM", // Elemental Shield Orb and Fire + "FORC", // Force Shield Orb + "PITY", // Pity Shield Orb + "FIRS", // Flame Shield Orb + "BUBS", // Bubble Shield Orb + "ZAPS", // Thunder Shield Orb + "IVSP", // invincibility sparkles + "SSPK", // Super Sonic Spark + + "GOAL", // Special Stage goal (here because lol NiGHTS) + + // Flickies + "FBUB", // Flicky-sized bubble + "FL01", // Bluebird + "FL02", // Rabbit + "FL03", // Chicken + "FL04", // Seal + "FL05", // Pig + "FL06", // Chipmunk + "FL07", // Penguin + "FL08", // Fish + "FL09", // Ram + "FL10", // Puffin + "FL11", // Cow + "FL12", // Rat + "FL13", // Bear + "FL14", // Dove + "FL15", // Cat + "FL16", // Canary + "FS01", // Spider + "FS02", // Bat + + // Springs + "FANS", // Fan + "STEM", // Steam riser + "BUMP", // Bumpers + "BLON", // Balloons + "SPRY", // Yellow spring + "SPRR", // Red spring + "SPRB", // Blue spring + "YSPR", // Yellow Diagonal Spring + "RSPR", // Red Diagonal Spring + "BSPR", // Blue Diagonal Spring + "SSWY", // Yellow Side Spring + "SSWR", // Red Side Spring + "SSWB", // Blue Side Spring + + // Environmental Effects + "RAIN", // Rain + "SNO1", // Snowflake + "SPLH", // Water Splish + "SPLA", // Water Splash + "SMOK", + "BUBL", // Bubble + "WZAP", + "DUST", // Spindash dust + "FPRT", // Spindash dust (flame) + "TFOG", // Teleport Fog + "SEED", // Sonic CD flower seed + "PRTL", // Particle (for fans, etc.) + + // Game Indicators + "SCOR", // Score logo + "DRWN", // Drowning Timer + "LCKN", // Target + "TTAG", // Tag Sign + "GFLG", // Got Flag sign + + "CORK", + + // Ring Weapons + "RRNG", // Red Ring + "RNGB", // Bounce Ring + "RNGR", // Rail Ring + "RNGI", // Infinity Ring + "RNGA", // Automatic Ring + "RNGE", // Explosion Ring + "RNGS", // Scatter Ring + "RNGG", // Grenade Ring + + "PIKB", // Bounce Ring Pickup + "PIKR", // Rail Ring Pickup + "PIKA", // Automatic Ring Pickup + "PIKE", // Explosion Ring Pickup + "PIKS", // Scatter Ring Pickup + "PIKG", // Grenade Ring Pickup + + "TAUT", // Thrown Automatic Ring + "TGRE", // Thrown Grenade Ring + "TSCR", // Thrown Scatter Ring + + // Mario-specific stuff + "COIN", + "CPRK", + "GOOM", + "BGOM", + "FFWR", + "FBLL", + "SHLL", + "PUMA", + "HAMM", + "KOOP", + "BFLM", + "MAXE", + "MUS1", + "MUS2", + "TOAD", + + // NiGHTS Stuff + "NDRN", // NiGHTS drone + "NSPK", // NiGHTS sparkle + "NBMP", // NiGHTS Bumper + "HOOP", // NiGHTS hoop sprite + "NSCR", // NiGHTS score sprite + "NPRU", // Nights Powerups + "CAPS", // Capsule thingy for NiGHTS + "IDYA", // Ideya + "NTPN", // Nightopian + "SHLP", // Shleep + + // Secret badniks and hazards, shhhh + "PENG", + "POPH", + "HIVE", + "BUMB", + "BBUZ", + "FMCE", + "HMCE", + "CACO", + "BAL2", + "SBOB", + "SBFL", + "SBSK", + "HBAT", + + // Debris + "SPRK", // Sparkle + "BOM1", // Robot Explosion + "BOM2", // Boss Explosion 1 + "BOM3", // Boss Explosion 2 + "BOM4", // Underwater Explosion + "BMNB", // Mine Explosion + "WDDB", // Wood Debris + + // Crumbly rocks + "ROIA", + "ROIB", + "ROIC", + "ROID", + "ROIE", + "ROIF", + "ROIG", + "ROIH", + "ROII", + "ROIJ", + "ROIK", + "ROIL", + "ROIM", + "ROIN", + "ROIO", + "ROIP", + + // Gravity Well Objects + "GWLG", + "GWLR", +}; + +char spr2names[NUMPLAYERSPRITES][5] = +{ + "STND", + "WAIT", + "WALK", + "SKID", + "RUN_", + "DASH", + "PAIN", + "STUN", + "DEAD", + "DRWN", + "ROLL", + "GASP", + "JUMP", + "SPNG", + "FALL", + "EDGE", + "RIDE", + + "SPIN", + + "FLY_", + "SWIM", + "TIRE", + + "GLID", + "CLNG", + "CLMB", + + "FLT_", + "FRUN", + + "BNCE", + "BLND", + + "FIRE", + + "TWIN", + + "MLEE", + "MLEL", + + "TRNS", + + "NSTD", + "NFLT", + "NSTN", + "NPUL", + "NATK", + + "NGT0", + "NGT1", + "NGT2", + "NGT3", + "NGT4", + "NGT5", + "NGT6", + "NGT7", + "NGT8", + "NGT9", + "NGTA", + "NGTB", + "NGTC", + + "DRL0", + "DRL1", + "DRL2", + "DRL3", + "DRL4", + "DRL5", + "DRL6", + "DRL7", + "DRL8", + "DRL9", + "DRLA", + "DRLB", + "DRLC", + + "TAL0", + "TAL1", + "TAL2", + "TAL3", + "TAL4", + "TAL5", + "TAL6", + "TAL7", + "TAL8", + "TAL9", + "TALA", + "TALB", + + "SIGN", + "LIFE" +}; +playersprite_t free_spr2 = SPR2_FIRSTFREESLOT; + +playersprite_t spr2defaults[NUMPLAYERSPRITES] = { + 0, // SPR2_STND, + 0, // SPR2_WAIT, + 0, // SPR2_WALK, + SPR2_WALK, // SPR2_SKID, + SPR2_WALK, // SPR2_RUN , + SPR2_FRUN, // SPR2_DASH, + 0, // SPR2_PAIN, + SPR2_PAIN, // SPR2_STUN, + SPR2_PAIN, // SPR2_DEAD, + SPR2_DEAD, // SPR2_DRWN, + 0, // SPR2_ROLL, + SPR2_SPNG, // SPR2_GASP, + 0, // SPR2_JUMP, (conditional) + SPR2_FALL, // SPR2_SPNG, + SPR2_WALK, // SPR2_FALL, + 0, // SPR2_EDGE, + SPR2_FALL, // SPR2_RIDE, + + SPR2_ROLL, // SPR2_SPIN, + + SPR2_SPNG, // SPR2_FLY , + SPR2_FLY , // SPR2_SWIM, + 0, // SPR2_TIRE, (conditional) + + SPR2_FLY , // SPR2_GLID, + SPR2_CLMB, // SPR2_CLNG, + SPR2_ROLL, // SPR2_CLMB, + + SPR2_WALK, // SPR2_FLT , + SPR2_RUN , // SPR2_FRUN, + + SPR2_FALL, // SPR2_BNCE, + SPR2_ROLL, // SPR2_BLND, + + 0, // SPR2_FIRE, + + SPR2_ROLL, // SPR2_TWIN, + + SPR2_TWIN, // SPR2_MLEE, + 0, // SPR2_MLEL, + + 0, // SPR2_TRNS, + + FF_SPR2SUPER|SPR2_STND, // SPR2_NSTD, + FF_SPR2SUPER|SPR2_FLT , // SPR2_NFLT, + FF_SPR2SUPER|SPR2_STUN, // SPR2_NSTN, + SPR2_NSTN, // SPR2_NPUL, + FF_SPR2SUPER|SPR2_ROLL, // SPR2_NATK, + + 0, // SPR2_NGT0, (should never be referenced) + SPR2_NGT0, // SPR2_NGT1, + SPR2_NGT1, // SPR2_NGT2, + SPR2_NGT2, // SPR2_NGT3, + SPR2_NGT3, // SPR2_NGT4, + SPR2_NGT4, // SPR2_NGT5, + SPR2_NGT5, // SPR2_NGT6, + SPR2_NGT0, // SPR2_NGT7, + SPR2_NGT7, // SPR2_NGT8, + SPR2_NGT8, // SPR2_NGT9, + SPR2_NGT9, // SPR2_NGTA, + SPR2_NGTA, // SPR2_NGTB, + SPR2_NGTB, // SPR2_NGTC, + + SPR2_NGT0, // SPR2_DRL0, + SPR2_NGT1, // SPR2_DRL1, + SPR2_NGT2, // SPR2_DRL2, + SPR2_NGT3, // SPR2_DRL3, + SPR2_NGT4, // SPR2_DRL4, + SPR2_NGT5, // SPR2_DRL5, + SPR2_NGT6, // SPR2_DRL6, + SPR2_NGT7, // SPR2_DRL7, + SPR2_NGT8, // SPR2_DRL8, + SPR2_NGT9, // SPR2_DRL9, + SPR2_NGTA, // SPR2_DRLA, + SPR2_NGTB, // SPR2_DRLB, + SPR2_NGTC, // SPR2_DRLC, + + 0, // SPR2_TAL0, + SPR2_TAL0, // SPR2_TAL1, + SPR2_TAL1, // SPR2_TAL2, + SPR2_TAL2, // SPR2_TAL3, + SPR2_TAL1, // SPR2_TAL4, + SPR2_TAL4, // SPR2_TAL5, + SPR2_TAL0, // SPR2_TAL6, + SPR2_TAL3, // SPR2_TAL7, + SPR2_TAL7, // SPR2_TAL8, + SPR2_TAL0, // SPR2_TAL9, + SPR2_TAL9, // SPR2_TALA, + SPR2_TAL0, // SPR2_TALB, + + 0, // SPR2_SIGN, + 0, // SPR2_LIFE, }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) state_t states[NUMSTATES] = { // frame is masked through FF_FRAMEMASK - // FF_ANIMATE (0x4000) makes simple state animations (var1 #frames, var2 tic delay) - // FF_FULLBRIGHT (0x8000) activates the fullbright colormap + // FF_ANIMATE makes simple state animations (var1 #frames, var2 tic delay) + // FF_FULLBRIGHT activates the fullbright colormap // use FF_TRANS10 - FF_TRANS90 for easy translucency // (or tr_trans10<<FF_TRANSSHIFT if you want to make it hard on yourself) @@ -82,73 +698,133 @@ state_t states[NUMSTATES] = {SPR_THOK, FF_TRANS50, 8, {NULL}, 0, 0, S_NULL}, // S_THOK // Player - {SPR_PLAY, 0, 105, {NULL}, 0, 0, S_PLAY_TAP1}, // S_PLAY_STND - {SPR_PLAY, 1, 16, {NULL}, 0, 0, S_PLAY_TAP2}, // S_PLAY_TAP1 - {SPR_PLAY, 2, 16, {NULL}, 0, 0, S_PLAY_TAP1}, // S_PLAY_TAP2 - {SPR_PLAY, 3, 4, {NULL}, 0, 0, S_PLAY_RUN2}, // S_PLAY_RUN1 - {SPR_PLAY, 4, 4, {NULL}, 0, 0, S_PLAY_RUN3}, // S_PLAY_RUN2 - {SPR_PLAY, 5, 4, {NULL}, 0, 0, S_PLAY_RUN4}, // S_PLAY_RUN3 - {SPR_PLAY, 6, 4, {NULL}, 0, 0, S_PLAY_RUN5}, // S_PLAY_RUN4 - {SPR_PLAY, 7, 4, {NULL}, 0, 0, S_PLAY_RUN6}, // S_PLAY_RUN5 - {SPR_PLAY, 8, 4, {NULL}, 0, 0, S_PLAY_RUN7}, // S_PLAY_RUN6 - {SPR_PLAY, 9, 4, {NULL}, 0, 0, S_PLAY_RUN8}, // S_PLAY_RUN7 - {SPR_PLAY, 10, 4, {NULL}, 0, 0, S_PLAY_RUN1}, // S_PLAY_RUN8 - {SPR_PLAY, 16, 2, {NULL}, 0, 0, S_PLAY_SPD2}, // S_PLAY_SPD1 - {SPR_PLAY, 17, 2, {NULL}, 0, 0, S_PLAY_SPD3}, // S_PLAY_SPD2 - {SPR_PLAY, 18, 2, {NULL}, 0, 0, S_PLAY_SPD4}, // S_PLAY_SPD3 - {SPR_PLAY, 19, 2, {NULL}, 0, 0, S_PLAY_SPD1}, // S_PLAY_SPD4 - {SPR_PLAY, 11, 1, {NULL}, 0, 0, S_PLAY_ATK2}, // S_PLAY_ATK1 - {SPR_PLAY, 12, 1, {NULL}, 0, 0, S_PLAY_ATK3}, // S_PLAY_ATK2 - {SPR_PLAY, 13, 1, {NULL}, 0, 0, S_PLAY_ATK4}, // S_PLAY_ATK3 - {SPR_PLAY, 14, 1, {NULL}, 0, 0, S_PLAY_ATK1}, // S_PLAY_ATK4 - {SPR_PLAY, 15, -1, {NULL}, 0, 0, S_PLAY_FALL1}, // S_PLAY_SPRING - {SPR_PLAY, 31, 2, {NULL}, 0, 0, S_PLAY_FALL2}, // S_PLAY_FALL1 - {SPR_PLAY, 32, 2, {NULL}, 0, 0, S_PLAY_FALL1}, // S_PLAY_FALL2 - {SPR_PLAY, 20, 2, {NULL}, 0, 0, S_PLAY_ABL2}, // S_PLAY_ABL1 - {SPR_PLAY, 21, 2, {NULL}, 0, 0, S_PLAY_ABL1}, // S_PLAY_ABL2 - {SPR_PLAY, 22, 6, {NULL}, 0, 0, S_PLAY_SPC2}, // S_PLAY_SPC1 - {SPR_PLAY, 23, 6, {NULL}, 0, 0, S_PLAY_SPC3}, // S_PLAY_SPC2 - {SPR_PLAY, 24, 6, {NULL}, 0, 0, S_PLAY_SPC4}, // S_PLAY_SPC3 - {SPR_PLAY, 25, 6, {NULL}, 0, 0, S_PLAY_SPC1}, // S_PLAY_SPC4 - {SPR_PLAY, 22, -1, {NULL}, 0, 0, S_NULL}, // S_PLAY_CLIMB1 - {SPR_PLAY, 23, 5, {NULL}, 0, 0, S_PLAY_CLIMB3}, // S_PLAY_CLIMB2 - {SPR_PLAY, 24, 5, {NULL}, 0, 0, S_PLAY_CLIMB4}, // S_PLAY_CLIMB3 - {SPR_PLAY, 25, 5, {NULL}, 0, 0, S_PLAY_CLIMB5}, // S_PLAY_CLIMB4 - {SPR_PLAY, 24, 5, {NULL}, 0, 0, S_PLAY_CLIMB2}, // S_PLAY_CLIMB5 - {SPR_PLAY, 26, 14, {NULL}, 0, 0, S_PLAY_RUN1}, // S_PLAY_GASP - {SPR_PLAY, 27, 350, {NULL}, 0, 0, S_PLAY_FALL1}, // S_PLAY_PAIN - {SPR_PLAY, 28, -1, {A_Fall}, 0, 0, S_NULL}, // S_PLAY_DIE - {SPR_PLAY, 29, 12, {NULL}, 0, 0, S_PLAY_TEETER2}, // S_PLAY_TEETER1 - {SPR_PLAY, 30, 12, {NULL}, 0, 0, S_PLAY_TEETER1}, // S_PLAY_TEETER2 - {SPR_PLAY, 33, -1, {NULL}, 0, 0, S_NULL}, // S_PLAY_CARRY - {SPR_PLAY, 20, -1, {NULL}, 0, 0, S_PLAY_SUPERSTAND}, // S_PLAY_SUPERSTAND - {SPR_PLAY, 20, 7, {NULL}, 0, 0, S_PLAY_SUPERWALK2}, // S_PLAY_SUPERWALK1 - {SPR_PLAY, 21, 7, {NULL}, 0, 0, S_PLAY_SUPERWALK1}, // S_PLAY_SUPERWALK2 - {SPR_PLAY, 22, 7, {NULL}, 0, 0, S_PLAY_SUPERFLY2}, // S_PLAY_SUPERFLY1 - {SPR_PLAY, 23, 7, {NULL}, 0, 0, S_PLAY_SUPERFLY1}, // S_PLAY_SUPERFLY2 - {SPR_PLAY, 24, 12, {NULL}, 0, 0, S_PLAY_SUPERTEETER}, // S_PLAY_SUPERTEETER - {SPR_PLAY, 25, -1, {NULL}, 0, 0, S_PLAY_SUPERSTAND}, // S_PLAY_SUPERHIT - {SPR_PLAY, 36, 4, {NULL}, 0, 0, S_PLAY_SUPERTRANS2}, // S_PLAY_SUPERTRANS1 - {SPR_PLAY, 37, 4, {NULL}, 0, 0, S_PLAY_SUPERTRANS3}, // S_PLAY_SUPERTRANS2 - {SPR_PLAY, 32806, 4, {NULL}, 0, 0, S_PLAY_SUPERTRANS4}, // S_PLAY_SUPERTRANS3 - {SPR_PLAY, 39, 3, {NULL}, 0, 0, S_PLAY_SUPERTRANS5}, // S_PLAY_SUPERTRANS4 - {SPR_PLAY, 40, 3, {NULL}, 0, 0, S_PLAY_SUPERTRANS6}, // S_PLAY_SUPERTRANS5 - {SPR_PLAY, 41, 3, {NULL}, 0, 0, S_PLAY_SUPERTRANS7}, // S_PLAY_SUPERTRANS6 - {SPR_PLAY, 42, 3, {NULL}, 0, 0, S_PLAY_SUPERTRANS8}, // S_PLAY_SUPERTRANS7 - {SPR_PLAY, 43, 3, {NULL}, 0, 0, S_PLAY_SUPERTRANS9}, // S_PLAY_SUPERTRANS8 - {SPR_PLAY, 44, 16, {NULL}, 0, 0, S_PLAY_RUN1}, // S_PLAY_SUPERTRANS9 + {SPR_PLAY, SPR2_STND|FF_ANIMATE, 105, {NULL}, 0, 7, S_PLAY_WAIT}, // S_PLAY_STND + {SPR_PLAY, SPR2_WAIT|FF_ANIMATE, -1, {NULL}, 0, 16, S_NULL}, // S_PLAY_WAIT + {SPR_PLAY, SPR2_WALK, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK + {SPR_PLAY, SPR2_SKID, 1, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_SKID + {SPR_PLAY, SPR2_RUN , 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN + {SPR_PLAY, SPR2_DASH, 2, {NULL}, 0, 0, S_PLAY_DASH}, // S_PLAY_DASH + {SPR_PLAY, SPR2_PAIN|FF_ANIMATE, 350, {NULL}, 0, 4, S_PLAY_FALL}, // S_PLAY_PAIN + {SPR_PLAY, SPR2_STUN|FF_ANIMATE, 350, {NULL}, 0, 4, S_PLAY_FALL}, // S_PLAY_STUN + {SPR_PLAY, SPR2_DEAD|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_DEAD + {SPR_PLAY, SPR2_DRWN|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_DRWN + {SPR_PLAY, SPR2_ROLL, 1, {NULL}, 0, 0, S_PLAY_ROLL}, // S_PLAY_ROLL + {SPR_PLAY, SPR2_GASP|FF_ANIMATE, 14, {NULL}, 0, 4, S_PLAY_WALK}, // S_PLAY_GASP + {SPR_PLAY, SPR2_JUMP, 1, {NULL}, 0, 0, S_PLAY_JUMP}, // S_PLAY_JUMP + {SPR_PLAY, SPR2_SPNG, 2, {NULL}, 0, 0, S_PLAY_SPRING}, // S_PLAY_SPRING + {SPR_PLAY, SPR2_FALL, 2, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_FALL + {SPR_PLAY, SPR2_EDGE, 12, {NULL}, 0, 0, S_PLAY_EDGE}, // S_PLAY_EDGE + {SPR_PLAY, SPR2_RIDE, 4, {NULL}, 0, 0, S_PLAY_RIDE}, // S_PLAY_RIDE + + // CA2_SPINDASH + {SPR_PLAY, SPR2_SPIN, 2, {NULL}, 0, 0, S_PLAY_SPINDASH}, // S_PLAY_SPINDASH + + // CA_FLY/CA_SWIM + {SPR_PLAY, SPR2_FLY , 2, {NULL}, 0, 0, S_PLAY_FLY}, // S_PLAY_FLY + {SPR_PLAY, SPR2_SWIM, 2, {NULL}, 0, 0, S_PLAY_SWIM}, // S_PLAY_SWIM + {SPR_PLAY, SPR2_TIRE, 12, {NULL}, 0, 0, S_PLAY_FLY_TIRED}, // S_PLAY_FLY_TIRED + + // CA_GLIDEANDCLIMB + {SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE + {SPR_PLAY, SPR2_CLNG|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_CLING + {SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB + + // CA_FLOAT/CA_SLOWFALL + {SPR_PLAY, SPR2_FLT , 7, {NULL}, 0, 0, S_PLAY_FLOAT}, // S_PLAY_FLOAT + {SPR_PLAY, SPR2_FRUN, 7, {NULL}, 0, 0, S_PLAY_FLOAT_RUN}, // S_PLAY_FLOAT_RUN + + // CA_BOUNCE + {SPR_PLAY, SPR2_BNCE|FF_ANIMATE, -1, {NULL}, 0, 0, S_NULL}, // S_PLAY_BOUNCE + {SPR_PLAY, SPR2_BLND|FF_SPR2ENDSTATE, 2, {NULL}, S_PLAY_BOUNCE, 0, S_PLAY_BOUNCE_LANDING}, // S_PLAY_BOUNCE_LANDING + + // CA2_GUNSLINGER + {SPR_PLAY, SPR2_FIRE|FF_SPR2ENDSTATE, 2, {NULL}, S_PLAY_FIRE_FINISH, 0, S_PLAY_FIRE}, // S_PLAY_FIRE + {SPR_PLAY, SPR2_FIRE, 15, {NULL}, S_PLAY_STND, 0, S_PLAY_STND}, // S_PLAY_FIRE_FINISH + + // CA_TWINSPIN + {SPR_PLAY, SPR2_TWIN|FF_SPR2ENDSTATE, 1, {NULL}, S_PLAY_JUMP, 0, S_PLAY_TWINSPIN}, // S_PLAY_TWINSPIN + + // CA2_MELEE + {SPR_PLAY, SPR2_MLEE|FF_SPR2ENDSTATE, 1, {NULL}, S_PLAY_MELEE_FINISH, 0, S_PLAY_MELEE}, // S_PLAY_MELEE + {SPR_PLAY, SPR2_MLEE, 70, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_MELEE_FINISH + {SPR_PLAY, SPR2_MLEL, 35, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_MELEE_LANDING + + // SF_SUPER + {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_ANIMATE, 7, {NULL}, 0, 4, S_PLAY_SUPER_TRANS2}, // S_PLAY_SUPER_TRANS1 + {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS3}, // S_PLAY_SUPER_TRANS2 + {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_SUPER_TRANS4}, // S_PLAY_SUPER_TRANS3 + {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4 + {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5 + {SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 19, {A_FadeOverlay}, 0, 0, S_PLAY_FALL}, // S_PLAY_SUPER_TRANS6 {SPR_NULL, 0, -1, {NULL}, 0, 0, S_OBJPLACE_DUMMY}, //S_OBJPLACE_DUMMY - // 1-Up Box Sprites (uses player sprite) - {SPR_PLAY, 35, 2, {NULL}, 0, 16, S_PLAY_BOX2}, // S_PLAY_BOX1 - {SPR_NULL, 0, 1, {NULL}, 0, 0, S_PLAY_BOX1}, // S_PLAY_BOX2 - {SPR_PLAY, 35, 4, {NULL}, 0, 4, S_PLAY_ICON2}, // S_PLAY_ICON1 - {SPR_NULL, 0, 12, {NULL}, 0, 0, S_PLAY_ICON3}, // S_PLAY_ICON2 - {SPR_PLAY, 35, 18, {NULL}, 0, 4, S_NULL}, // S_PLAY_ICON3 + // 1-Up box sprites (uses player sprite) + {SPR_PLAY, SPR2_LIFE, 2, {NULL}, 0, 18, S_PLAY_BOX2}, // S_PLAY_BOX1 + {SPR_NULL, 0, 1, {NULL}, 0, 0, S_PLAY_BOX1}, // S_PLAY_BOX2 + {SPR_PLAY, SPR2_LIFE, 4, {NULL}, 0, 4, S_PLAY_ICON2}, // S_PLAY_ICON1 + {SPR_NULL, 0, 12, {NULL}, 0, 0, S_PLAY_ICON3}, // S_PLAY_ICON2 + {SPR_PLAY, SPR2_LIFE, 20, {NULL}, 0, 4, S_NULL}, // S_PLAY_ICON3 // Level end sign (uses player sprite) - {SPR_PLAY, 34, 1, {NULL}, 0, 24, S_PLAY_SIGN}, // S_PLAY_SIGN + {SPR_PLAY, SPR2_SIGN, 1, {NULL}, 0, 24, S_PLAY_SIGN}, // S_PLAY_SIGN + + // NiGHTS Player, transforming + {SPR_PLAY, SPR2_TRNS|FF_ANIMATE, 7, {NULL}, 0, 4, S_PLAY_NIGHTS_TRANS2}, // S_PLAY_NIGHTS_TRANS1 + {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS3}, // S_PLAY_NIGHTS_TRANS2 + {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS4}, // S_PLAY_NIGHTS_TRANS3 + {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS5}, // S_PLAY_NIGHTS_TRANS4 + {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS6}, // S_PLAY_NIGHTS_TRANS5 + {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 21, {A_FadeOverlay}, 2, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_TRANS5 + + // NiGHTS Player, stand, float, pain, pull and attack + {SPR_PLAY, SPR2_NSTD, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_STAND}, // S_PLAY_NIGHTS_STAND + {SPR_PLAY, SPR2_NFLT, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_FLOAT + {SPR_PLAY, SPR2_NSTN, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_STUN}, // S_PLAY_NIGHTS_STUN + {SPR_PLAY, SPR2_NPUL, 1, {NULL}, 0, 0, S_PLAY_NIGHTS_PULL}, // S_PLAY_NIGHTS_PULL + {SPR_PLAY, SPR2_NATK, 1, {NULL}, 0, 0, S_PLAY_NIGHTS_ATTACK}, // S_PLAY_NIGHTS_ATTACK + + // NiGHTS Player, flying and drilling + {SPR_PLAY, SPR2_NGT0, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY0}, // S_PLAY_NIGHTS_FLY0 + {SPR_PLAY, SPR2_DRL0, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL0}, // S_PLAY_NIGHTS_DRILL0 + {SPR_PLAY, SPR2_NGT1, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY1}, // S_PLAY_NIGHTS_FLY1 + {SPR_PLAY, SPR2_DRL1, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL1}, // S_PLAY_NIGHTS_DRILL1 + {SPR_PLAY, SPR2_NGT2, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY2}, // S_PLAY_NIGHTS_FLY2 + {SPR_PLAY, SPR2_DRL2, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL2}, // S_PLAY_NIGHTS_DRILL2 + {SPR_PLAY, SPR2_NGT3, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY3}, // S_PLAY_NIGHTS_FLY3 + {SPR_PLAY, SPR2_DRL3, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL3}, // S_PLAY_NIGHTS_DRILL3 + {SPR_PLAY, SPR2_NGT4, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY4}, // S_PLAY_NIGHTS_FLY4 + {SPR_PLAY, SPR2_DRL4, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL4}, // S_PLAY_NIGHTS_DRILL4 + {SPR_PLAY, SPR2_NGT5, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY5}, // S_PLAY_NIGHTS_FLY5 + {SPR_PLAY, SPR2_DRL5, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL5}, // S_PLAY_NIGHTS_DRILL5 + {SPR_PLAY, SPR2_NGT6, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY6}, // S_PLAY_NIGHTS_FLY6 + {SPR_PLAY, SPR2_DRL6, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL6}, // S_PLAY_NIGHTS_DRILL6 + {SPR_PLAY, SPR2_NGT7, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY7}, // S_PLAY_NIGHTS_FLY7 + {SPR_PLAY, SPR2_DRL7, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL7}, // S_PLAY_NIGHTS_DRILL7 + {SPR_PLAY, SPR2_NGT8, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY8}, // S_PLAY_NIGHTS_FLY8 + {SPR_PLAY, SPR2_DRL8, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL8}, // S_PLAY_NIGHTS_DRILL8 + {SPR_PLAY, SPR2_NGT9, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY9}, // S_PLAY_NIGHTS_FLY9 + {SPR_PLAY, SPR2_DRL9, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL9}, // S_PLAY_NIGHTS_DRILL9 + {SPR_PLAY, SPR2_NGTA, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYA}, // S_PLAY_NIGHTS_FLYA + {SPR_PLAY, SPR2_DRLA, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLA}, // S_PLAY_NIGHTS_DRILLA + {SPR_PLAY, SPR2_NGTB, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYB}, // S_PLAY_NIGHTS_FLYB + {SPR_PLAY, SPR2_DRLB, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLB}, // S_PLAY_NIGHTS_DRILLB + {SPR_PLAY, SPR2_NGTC, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYC}, // S_PLAY_NIGHTS_FLYC + {SPR_PLAY, SPR2_DRLC, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLC}, // S_PLAY_NIGHTS_DRILLC + + // c: + {SPR_PLAY, SPR2_TAL0|FF_SPR2MIDSTART, 5, {NULL}, 0, 0, S_TAILSOVERLAY_STAND}, // S_TAILSOVERLAY_STAND + {SPR_PLAY, SPR2_TAL1|FF_SPR2MIDSTART, 35, {NULL}, 0, 0, S_TAILSOVERLAY_0DEGREES}, // S_TAILSOVERLAY_0DEGREES + {SPR_PLAY, SPR2_TAL2|FF_SPR2MIDSTART, 35, {NULL}, 0, 0, S_TAILSOVERLAY_PLUS30DEGREES}, // S_TAILSOVERLAY_PLUS30DEGREES + {SPR_PLAY, SPR2_TAL3|FF_SPR2MIDSTART, 35, {NULL}, 0, 0, S_TAILSOVERLAY_PLUS60DEGREES}, // S_TAILSOVERLAY_PLUS60DEGREES + {SPR_PLAY, SPR2_TAL4|FF_SPR2MIDSTART, 35, {NULL}, 0, 0, S_TAILSOVERLAY_MINUS30DEGREES}, // S_TAILSOVERLAY_MINUS30DEGREES + {SPR_PLAY, SPR2_TAL5|FF_SPR2MIDSTART, 35, {NULL}, 0, 0, S_TAILSOVERLAY_MINUS60DEGREES}, // S_TAILSOVERLAY_MINUS60DEGREES + {SPR_PLAY, SPR2_TAL6|FF_SPR2MIDSTART, 35, {NULL}, 0, 0, S_TAILSOVERLAY_RUN}, // S_TAILSOVERLAY_RUN + {SPR_PLAY, SPR2_TAL7|FF_SPR2MIDSTART, 4, {NULL}, 0, 0, S_TAILSOVERLAY_FLY}, // S_TAILSOVERLAY_FLY + {SPR_PLAY, SPR2_TAL8|FF_SPR2MIDSTART, 4, {NULL}, 0, 0, S_TAILSOVERLAY_TIRE}, // S_TAILSOVERLAY_TIRE + {SPR_PLAY, SPR2_TAL9|FF_SPR2MIDSTART, 35, {NULL}, 0, 0, S_TAILSOVERLAY_PAIN}, // S_TAILSOVERLAY_PAIN + {SPR_PLAY, SPR2_TALA|FF_SPR2MIDSTART, 35, {NULL}, 0, 0, S_TAILSOVERLAY_GASP}, // S_TAILSOVERLAY_GASP + {SPR_PLAY, SPR2_TALB , 35, {NULL}, 0, 0, S_TAILSOVERLAY_EDGE}, // S_TAILSOVERLAY_EDGE // Blue Crawla {SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND}, // S_POSS_STND @@ -186,10 +862,6 @@ state_t states[NUMSTATES] = {SPR_RBUZ, 0, 2, {A_BuzzFly}, sfx_buzz4, 0, S_RBUZZFLY2}, // S_RBUZZFLY1 {SPR_RBUZ, 1, 2, {A_BuzzFly}, 0, 0, S_RBUZZFLY1}, // S_RBUZZFLY2 - // AquaBuzz - {SPR_BBUZ, 0, 2, {NULL}, 0, 0, S_BBUZZFLY2}, // S_BBUZZFLY1 - {SPR_BBUZ, 1, 2, {NULL}, 0, 0, S_BBUZZFLY1}, // S_BBUZZFLY2 - // Jetty-Syn Bomber {SPR_JETB, 0, 4, {A_Look}, 0, 0, S_JETBLOOK2}, // S_JETBLOOK1 {SPR_JETB, 1, 4, {A_Look}, 0, 0, S_JETBLOOK1}, // S_JETBLOOK2 @@ -226,7 +898,6 @@ state_t states[NUMSTATES] = {SPR_DETN, 3, 1, {A_DetonChase}, 0, 0, S_DETON14}, // S_DETON13 {SPR_DETN, 2, 1, {A_DetonChase}, 0, 0, S_DETON15}, // S_DETON14 {SPR_DETN, 1, 1, {A_DetonChase}, 0, 0, S_DETON2}, // S_DETON15 - {SPR_DETN, 0, -1, {NULL}, 0, 0, S_DETON16}, // S_DETON16 // Skim Mine Dropper {SPR_SKIM, 0, 1, {A_SkimChase}, 0, 0, S_SKIM2}, // S_SKIM1 @@ -245,7 +916,7 @@ state_t states[NUMSTATES] = {SPR_TRET, FF_FULLBRIGHT|2, 7, {A_Pain}, 0, 0, S_TURRETSHOCK7}, // S_TURRETSHOCK6 {SPR_TRET, FF_FULLBRIGHT|3, 7, {NULL}, 0, 0, S_TURRETSHOCK8}, // S_TURRETSHOCK7 {SPR_TRET, FF_FULLBRIGHT|4, 7, {NULL}, 0, 0, S_TURRETSHOCK9}, // S_TURRETSHOCK8 - {SPR_TRET, FF_FULLBRIGHT|4, 7, {A_LinedefExecute}, 32000, 0, S_XPLD1}, // S_TURRETSHOCK9 + {SPR_TRET, FF_FULLBRIGHT|4, 7, {A_LinedefExecute}, LE_TURRET, 0, S_XPLD1}, // S_TURRETSHOCK9 {SPR_TURR, 0, 1, {A_Look}, 1, 0, S_TURRETPOPDOWN8}, // S_TURRETLOOK {SPR_TURR, 0, 0, {A_FaceTarget}, 0, 0, S_TURRETPOPUP1}, // S_TURRETSEE @@ -267,14 +938,40 @@ state_t states[NUMSTATES] = {SPR_TURR, 1, 2, {NULL}, 0, 0, S_TURRETPOPDOWN8}, // S_TURRETPOPDOWN7 {SPR_TURR, 0, 69,{A_SetTics}, 0, 1, S_TURRETLOOK}, // S_TURRETPOPDOWN8 - // Sharp - {SPR_SHRP, 0, 1, {A_Look}, 0, 0, S_SHARP_ROAM1}, // S_SHARP_ROAM1, - {SPR_SHRP, 0, 1, {A_SharpChase}, 0, 0, S_SHARP_ROAM2}, // S_SHARP_ROAM2, - {SPR_SHRP, 1, 2, {A_FaceTarget}, 0, 0, S_SHARP_AIM2}, // S_SHARP_AIM1, - {SPR_SHRP, 2, 2, {A_FaceTarget}, 0, 0, S_SHARP_AIM3}, // S_SHARP_AIM2, - {SPR_SHRP, 3, 2, {A_FaceTarget}, 0, 0, S_SHARP_AIM4}, // S_SHARP_AIM3, - {SPR_SHRP, 4, 7, {A_FaceTarget}, 0, 0, S_SHARP_SPIN}, // S_SHARP_AIM4, - {SPR_SHRP, 4, 1, {A_SharpSpin}, 0, 0, S_SHARP_SPIN}, // S_SHARP_SPIN, + // Spincushion + {SPR_SHRP, 0, 2, {A_Look}, 0, 0, S_SPINCUSHION_LOOK}, // S_SPINCUSHION_LOOK + {SPR_SHRP, 1, 2, {A_SharpChase}, 0, 0, S_SPINCUSHION_CHASE2}, // S_SPINCUSHION_CHASE1 + {SPR_SHRP, 2, 2, {A_SharpChase}, 0, 0, S_SPINCUSHION_CHASE3}, // S_SPINCUSHION_CHASE2 + {SPR_SHRP, 3, 2, {A_SharpChase}, 0, 0, S_SPINCUSHION_CHASE4}, // S_SPINCUSHION_CHASE3 + {SPR_SHRP, 0, 2, {A_SharpChase}, 0, 0, S_SPINCUSHION_CHASE1}, // S_SPINCUSHION_CHASE4 + {SPR_SHRP, 0, 2, {NULL}, 0, 0, S_SPINCUSHION_AIM2}, // S_SPINCUSHION_AIM1 + {SPR_SHRP, 4, 2, {NULL}, 0, 0, S_SPINCUSHION_AIM3}, // S_SPINCUSHION_AIM2 + {SPR_SHRP, 5, 2, {A_SetObjectFlags}, MF_PAIN, 2, S_SPINCUSHION_AIM4}, // S_SPINCUSHION_AIM3 + {SPR_SHRP, 6, 16, {A_MultiShotDist}, (MT_DUST<<16)|6, -32, S_SPINCUSHION_AIM5}, // S_SPINCUSHION_AIM4 + {SPR_SHRP, 6, 0, {A_PlaySound}, sfx_shrpgo, 1, S_SPINCUSHION_SPIN1}, // S_SPINCUSHION_AIM5 + {SPR_SHRP, 6, 1, {A_SharpSpin}, 0, 0, S_SPINCUSHION_SPIN2}, // S_SPINCUSHION_SPIN1 + {SPR_SHRP, 8, 1, {A_SharpSpin}, 0, 0, S_SPINCUSHION_SPIN3}, // S_SPINCUSHION_SPIN2 + {SPR_SHRP, 7, 1, {A_SharpSpin}, 0, 0, S_SPINCUSHION_SPIN4}, // S_SPINCUSHION_SPIN3 + {SPR_SHRP, 8, 1, {A_SharpSpin}, MT_SPINDUST, 0, S_SPINCUSHION_SPIN1}, // S_SPINCUSHION_SPIN4 + {SPR_SHRP, 6, 1, {A_PlaySound}, sfx_s3k69, 1, S_SPINCUSHION_STOP2}, // S_SPINCUSHION_STOP1 + {SPR_SHRP, 6, 4, {A_SharpDecel}, 0, 0, S_SPINCUSHION_STOP2}, // S_SPINCUSHION_STOP2 + {SPR_SHRP, 5, 4, {A_FaceTarget}, 0, 0, S_SPINCUSHION_STOP4}, // S_SPINCUSHION_STOP3 + {SPR_SHRP, 4, 4, {A_SetObjectFlags}, MF_PAIN, 1, S_SPINCUSHION_LOOK}, // S_SPINCUSHION_STOP4 + + // Crushstacean + {SPR_CRAB, 0, 3, {A_CrushstaceanWalk}, 0, S_CRUSHSTACEAN_ROAMPAUSE, S_CRUSHSTACEAN_ROAM2}, // S_CRUSHSTACEAN_ROAM1 + {SPR_CRAB, 1, 3, {A_CrushstaceanWalk}, 0, S_CRUSHSTACEAN_ROAMPAUSE, S_CRUSHSTACEAN_ROAM3}, // S_CRUSHSTACEAN_ROAM2 + {SPR_CRAB, 0, 3, {A_CrushstaceanWalk}, 0, S_CRUSHSTACEAN_ROAMPAUSE, S_CRUSHSTACEAN_ROAM4}, // S_CRUSHSTACEAN_ROAM3 + {SPR_CRAB, 2, 3, {A_CrushstaceanWalk}, 0, S_CRUSHSTACEAN_ROAMPAUSE, S_CRUSHSTACEAN_ROAM1}, // S_CRUSHSTACEAN_ROAM4 + {SPR_CRAB, 0, 40, {NULL}, 0, 0, S_CRUSHSTACEAN_ROAM1}, // S_CRUSHSTACEAN_ROAMPAUSE + {SPR_CRAB, 0, 10, {NULL}, 0, 0, S_CRUSHSTACEAN_PUNCH2}, // S_CRUSHSTACEAN_PUNCH1 + {SPR_CRAB, 0, -1, {A_CrushstaceanPunch}, 0, 0, S_CRUSHSTACEAN_ROAMPAUSE}, // S_CRUSHSTACEAN_PUNCH2 + {SPR_CRAB, 3, 1, {A_CrushclawAim}, 40, 20, S_CRUSHCLAW_AIM}, // S_CRUSHCLAW_AIM + {SPR_CRAB, 3, 1, {A_CrushclawLaunch}, 0, S_CRUSHCLAW_STAY, S_CRUSHCLAW_OUT}, // S_CRUSHCLAW_OUT + {SPR_CRAB, 3, 10, {NULL}, 0, 0, S_CRUSHCLAW_IN}, // S_CRUSHCLAW_STAY + {SPR_CRAB, 3, 1, {A_CrushclawLaunch}, 1, S_CRUSHCLAW_WAIT, S_CRUSHCLAW_IN}, // S_CRUSHCLAW_IN + {SPR_CRAB, 3, 37, {NULL}, 0, 0, S_CRUSHCLAW_AIM}, // S_CRUSHCLAW_WAIT + {SPR_CRAB, 4, -1, {NULL}, 0, 0, S_NULL}, // S_CRUSHCHAIN // Jet Jaw {SPR_JJAW, 0, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM2}, // S_JETJAW_ROAM1 @@ -306,16 +1003,11 @@ state_t states[NUMSTATES] = {SPR_SNLR, 0, 1, {A_SnailerThink}, 0, 0, S_SNAILER1}, // S_SNAILER1 // Vulture - {SPR_VLTR, 4, 35, {A_Look}, 1, 0, S_VULTURE_STND}, // S_VULTURE_STND - {SPR_VLTR, 4, 1, {A_VultureVtol}, 0, 0, S_VULTURE_VTOL2}, // S_VULTURE_VTOL1 - {SPR_VLTR, 5, 1, {A_VultureVtol}, 0, 0, S_VULTURE_VTOL3}, // S_VULTURE_VTOL2 - {SPR_VLTR, 6, 1, {A_VultureVtol}, 0, 0, S_VULTURE_VTOL4}, // S_VULTURE_VTOL3 - {SPR_VLTR, 7, 1, {A_VultureVtol}, 0, 0, S_VULTURE_VTOL1}, // S_VULTURE_VTOL4 - {SPR_VLTR, 0, 1, {A_Thrust}, 30, 1, S_VULTURE_ZOOM2}, // S_VULTURE_ZOOM1 - {SPR_VLTR, 0, 1, {A_VultureCheck}, 0, 0, S_VULTURE_ZOOM3}, // S_VULTURE_ZOOM2 - {SPR_VLTR, 1, 1, {A_VultureCheck}, 0, 0, S_VULTURE_ZOOM4}, // S_VULTURE_ZOOM3 - {SPR_VLTR, 2, 1, {A_VultureCheck}, 0, 0, S_VULTURE_ZOOM5}, // S_VULTURE_ZOOM4 - {SPR_VLTR, 3, 1, {A_VultureCheck}, 0, 0, S_VULTURE_ZOOM2}, // S_VULTURE_ZOOM5 + {SPR_VLTR, 4, 35, {A_Look}, 1, 0, S_VULTURE_STND}, // S_VULTURE_STND + {SPR_VLTR, 4, 3, {A_VultureHover}, 0, 0, S_VULTURE_DRIFT}, // S_VULTURE_DRIFT + {SPR_VLTR, 0, 6, {A_VultureBlast}, 0, 0, S_VULTURE_ZOOM2}, // S_VULTURE_ZOOM1 + {SPR_VLTR, 0, 3, {A_VultureFly}, 0, 0, S_VULTURE_ZOOM2}, // S_VULTURE_ZOOM2 + {SPR_VLTR, 0, 3*TICRATE, {NULL}, 0, 0, S_VULTURE_DRIFT}, // S_VULTURE_STUNNED // Pointy {SPR_PNTY, 0, 1, {A_PointyThink}, 0, 0, S_POINTY1}, // S_POINTY1 @@ -324,24 +1016,31 @@ state_t states[NUMSTATES] = {SPR_PNTY, 1, 1, {A_CheckBuddy}, 0, 0, S_POINTYBALL1}, // S_POINTYBALL1 // Robo-Hood - {SPR_ARCH, 0, 14, {A_Look}, (512<<16), 0, S_ROBOHOOD_LOOK}, // S_ROBOHOOD_LOOK - {SPR_ARCH, 2, 1, {A_HoodThink}, 0, 0, S_ROBOHOOD_STND}, // S_ROBOHOOD_STND - {SPR_ARCH, 0, 35, {A_FireShot}, MT_ARROW, -24, S_ROBOHOOD_STND}, // S_ROBOHOOD_SHOOT - {SPR_ARCH, 1, 1, {A_BunnyHop}, 8, 5, S_ROBOHOOD_JUMP2}, // S_ROBOHOOD_JUMP - {SPR_ARCH, 1, 1, {A_HoodThink}, 0, 0, S_ROBOHOOD_JUMP2}, // S_ROBOHOOD_JUMP2 - {SPR_ARCH, 0, 1, {A_HoodThink}, 0, 0, S_ROBOHOOD_FALL}, // S_ROBOHOOD_FALL - - // CastleBot FaceStabber - {SPR_CBFS, 0, 1, {A_FaceStabChase}, 0, 0, S_FACESTABBER_STND2}, // S_FACESTABBER_STND1 - {SPR_CBFS, 1, 1, {A_FaceStabChase}, 0, 0, S_FACESTABBER_STND3}, // S_FACESTABBER_STND2 - {SPR_CBFS, 2, 1, {A_FaceStabChase}, 0, 0, S_FACESTABBER_STND4}, // S_FACESTABBER_STND3 - {SPR_CBFS, 3, 1, {A_FaceStabChase}, 0, 0, S_FACESTABBER_STND5}, // S_FACESTABBER_STND4 - {SPR_CBFS, 4, 1, {A_FaceStabChase}, 0, 0, S_FACESTABBER_STND6}, // S_FACESTABBER_STND5 - {SPR_CBFS, 5, 1, {A_FaceStabChase}, 0, 0, S_FACESTABBER_STND1}, // S_FACESTABBER_STND6 - {SPR_CBFS, 6, 14, {A_PlayActiveSound}, 0, 0, S_FACESTABBER_CHARGE2}, // S_FACESTABBER_CHARGE1 - {SPR_CBFS, 6, 0, {A_PlayAttackSound}, 0, 0, S_FACESTABBER_CHARGE3}, // S_FACESTABBER_CHARGE2 - {SPR_CBFS, 6, 0, {A_FaceTarget}, 0, 0, S_FACESTABBER_CHARGE4}, // S_FACESTABBER_CHARGE3 - {SPR_CBFS, 7, 35, {A_Thrust}, 20, 1, S_FACESTABBER_STND1}, // S_FACESTABBER_CHARGE4 + {SPR_ARCH, 0, 4, {A_Look}, 2048<<FRACBITS, 0, S_ROBOHOOD_LOOK}, // S_ROBOHOOD_LOOK + {SPR_ARCH, 0, 1, {A_HoodThink}, 0, 0, S_ROBOHOOD_STAND}, // S_ROBOHOOD_STAND + {SPR_ARCH, 2, TICRATE, {A_PlayActiveSound}, 0, 0, S_ROBOHOOD_FIRE2}, // S_ROBOHOOD_FIRE1 + {SPR_ARCH, 2, 20, {A_HoodFire}, MT_ARROW, 0, S_ROBOHOOD_STAND}, // S_ROBOHOOD_FIRE2 + {SPR_ARCH, 1, 1, {A_FaceTarget}, 0, 0, S_ROBOHOOD_JUMP2}, // S_ROBOHOOD_JUMP1 + {SPR_ARCH, 1, 1, {A_BunnyHop}, 4, -10, S_ROBOHOOD_JUMP3}, // S_ROBOHOOD_JUMP2 + {SPR_ARCH, 1, 1, {A_HoodFall}, 0, 0, S_ROBOHOOD_JUMP3}, // S_ROBOHOOD_JUMP3 + + // Castlebot Facestabber + {SPR_CBFS, 0, 1, {A_Chase}, 0, 0, S_FACESTABBER_STND2}, // S_FACESTABBER_STND1 + {SPR_CBFS, 1, 1, {A_Chase}, 0, 0, S_FACESTABBER_STND3}, // S_FACESTABBER_STND2 + {SPR_CBFS, 2, 1, {A_Chase}, 0, 0, S_FACESTABBER_STND4}, // S_FACESTABBER_STND3 + {SPR_CBFS, 3, 1, {A_Chase}, 0, 0, S_FACESTABBER_STND5}, // S_FACESTABBER_STND4 + {SPR_CBFS, 4, 1, {A_Chase}, 0, 0, S_FACESTABBER_STND6}, // S_FACESTABBER_STND5 + {SPR_CBFS, 5, 1, {A_Chase}, 0, 0, S_FACESTABBER_STND1}, // S_FACESTABBER_STND6 + {SPR_CBFS, 0, 1, {A_FaceStabRev}, 20, S_FACESTABBER_CHARGE2, S_FACESTABBER_CHARGE1}, // S_FACESTABBER_CHARGE1 + {SPR_CBFS, 0, 0, {A_FaceTarget}, 0, 0, S_FACESTABBER_CHARGE3}, // S_FACESTABBER_CHARGE2 + {SPR_CBFS, 7, 1, {A_FaceStabHurl}, 6, S_FACESTABBER_CHARGE4, S_FACESTABBER_CHARGE3}, // S_FACESTABBER_CHARGE3 + {SPR_CBFS, 7, 1, {A_FaceStabMiss}, 0, S_FACESTABBER_STND1, S_FACESTABBER_CHARGE4}, // S_FACESTABBER_CHARGE4 + {SPR_CBFS, 0, 35, {A_Pain}, 0, 0, S_FACESTABBER_STND1}, // S_FACESTABBER_PAIN + {SPR_CBFS, 0, 2, {A_BossScream}, 1, MT_SONIC3KBOSSEXPLODE, S_FACESTABBER_DIE2}, // S_FACESTABBER_DIE1 + {SPR_NULL, 0, 2, {A_BossScream}, 1, MT_SONIC3KBOSSEXPLODE, S_FACESTABBER_DIE3}, // S_FACESTABBER_DIE2 + {SPR_NULL, 0, 0, {A_Repeat}, 7, S_FACESTABBER_DIE1, S_XPLD_FLICKY}, // S_FACESTABBER_DIE3 + + {SPR_STAB, FF_PAPERSPRITE|FF_TRANS50|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_FACESTABBERSPEAR // Egg Guard {SPR_SPSH, 0, 1, {A_Look}, 0, 0, S_EGGGUARD_STND}, // S_EGGGUARD_STND @@ -357,19 +1056,35 @@ state_t states[NUMSTATES] = {SPR_SPSH, 10, 1, {A_GuardChase}, 0, 0, S_EGGGUARD_RUN4}, // S_EGGGUARD_RUN3 {SPR_SPSH, 11, 1, {A_GuardChase}, 0, 0, S_EGGGUARD_RUN1}, // S_EGGGUARD_RUN4 - // Egg Shield for Egg Guard - {SPR_ESHI, 0, 8, {A_EggShield}, 0, 0, S_EGGSHIELD}, // S_EGGSHIELD + {SPR_ESHI, 0, 8, {A_EggShield}, 0, 0, S_EGGSHIELD}, // S_EGGSHIELD + {SPR_ESHI, 0, TICRATE/2, {NULL}, 0, 0, S_NULL}, // S_EGGSHIELDBREAK // Green Snapper - {SPR_GSNP, 0, 1, {A_Look}, 0, 0, S_GSNAPPER_STND}, // S_GSNAPPER_STND - {SPR_GSNP, 0, 2, {A_Chase}, 0, 0, S_GSNAPPER2}, // S_GSNAPPER1 - {SPR_GSNP, 1, 2, {A_Chase}, 0, 0, S_GSNAPPER3}, // S_GSNAPPER2 - {SPR_GSNP, 2, 2, {A_Chase}, 0, 0, S_GSNAPPER4}, // S_GSNAPPER3 - {SPR_GSNP, 3, 2, {A_Chase}, 0, 0, S_GSNAPPER1}, // S_GSNAPPER4 + {SPR_GSNP, 0, TICRATE, {NULL}, 0, 0, S_SNAPPER_SPAWN2}, // S_SNAPPER_SPAWN + {SPR_GSNP, 0, 2, {A_SnapperSpawn}, MT_SNAPPER_LEG, MT_SNAPPER_HEAD, S_GSNAPPER_STND}, // S_SNAPPER_SPAWN2 + {SPR_GSNP, 0, 1, {A_SnapperThinker}, 0, 0, S_GSNAPPER_STND}, // S_GSNAPPER_STND + {SPR_GSNP, 0, 2, {A_Chase}, 0, 0, S_GSNAPPER2}, // S_GSNAPPER1 + {SPR_GSNP, 1, 2, {A_Chase}, 0, 0, S_GSNAPPER3}, // S_GSNAPPER2 + {SPR_GSNP, 2, 2, {A_Chase}, 0, 0, S_GSNAPPER4}, // S_GSNAPPER3 + {SPR_GSNP, 3, 2, {A_Chase}, 0, 0, S_GSNAPPER1}, // S_GSNAPPER4 + {SPR_GSNP, 0, 0, {A_KillSegments}, 0, 0, S_XPLD_FLICKY}, // S_SNAPPER_XPLD + {SPR_GSNL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SNAPPER_LEG + {SPR_GSNL, 1, -1, {NULL}, 0, 0, S_NULL}, // S_SNAPPER_LEGRAISE + {SPR_GSNH, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SNAPPER_HEAD // Minus - {SPR_NULL, 0, 1, {A_Look}, 0, 0, S_MINUS_STND}, // S_MINUS_STND - {SPR_MNUS, 16, 1, {A_MinusDigging}, 0, 0, S_MINUS_DIGGING}, // S_MINUS_DIGGING + {SPR_MNUD, 0, 1, {NULL}, 0, 0, S_MINUS_STND}, // S_MINUS_INIT (required for objectplace to work) + {SPR_NULL, 0, 10, {A_Look}, 0, 0, S_MINUS_STND}, // S_MINUS_STND + {SPR_NULL, 0, 1, {A_MinusDigging}, 1, 0, S_MINUS_DIGGING2}, // S_MINUS_DIGGING1 + {SPR_NULL, 0, 1, {A_MinusDigging}, 0, 0, S_MINUS_DIGGING3}, // S_MINUS_DIGGING2 + {SPR_NULL, 0, 1, {A_MinusDigging}, 0, 0, S_MINUS_DIGGING4}, // S_MINUS_DIGGING3 + {SPR_NULL, 0, 1, {A_MinusDigging}, 0, 0, S_MINUS_DIGGING1}, // S_MINUS_DIGGING4 + {SPR_NULL, 0, 25, {NULL}, 0, 0, S_MINUS_POPUP}, // S_MINUS_BURST0 + {SPR_MNUD, FF_ANIMATE, 5, {NULL}, 1, 2, S_MINUS_BURST2}, // S_MINUS_BURST1 + {SPR_MNUD, 1|FF_ANIMATE, 5, {NULL}, 1, 2, S_MINUS_BURST3}, // S_MINUS_BURST2 + {SPR_MNUD, 2|FF_ANIMATE, 5, {NULL}, 1, 2, S_MINUS_BURST4}, // S_MINUS_BURST3 + {SPR_MNUD, 3|FF_ANIMATE, 5, {NULL}, 1, 2, S_MINUS_BURST5}, // S_MINUS_BURST4 + {SPR_MNUD, 4|FF_ANIMATE, 5, {NULL}, 1, 2, S_MINUSDIRT2}, // S_MINUS_BURST5 {SPR_MNUS, 0, 1, {A_MinusPopup}, 0, 0, S_MINUS_UPWARD1}, // S_MINUS_POPUP {SPR_MNUS, 0, 1, {A_MinusCheck}, 0, 0, S_MINUS_UPWARD2}, // S_MINUS_UPWARD1 {SPR_MNUS, 1, 1, {A_MinusCheck}, 0, 0, S_MINUS_UPWARD3}, // S_MINUS_UPWARD2 @@ -388,6 +1103,14 @@ state_t states[NUMSTATES] = {SPR_MNUS, 14, 1, {A_MinusCheck}, 0, 0, S_MINUS_DOWNWARD8}, // S_MINUS_DOWNWARD7 {SPR_MNUS, 15, 1, {A_MinusCheck}, 0, 0, S_MINUS_DOWNWARD1}, // S_MINUS_DOWNWARD8 + {SPR_MNUD, FF_ANIMATE, 6, {NULL}, 1, 5, S_MINUSDIRT2}, // S_MINUSDIRT1 + {SPR_MNUD, 5, 8, {NULL}, 3, 5, S_MINUSDIRT3}, // S_MINUSDIRT2 + {SPR_MNUD, 4, 8, {NULL}, 3, 5, S_MINUSDIRT4}, // S_MINUSDIRT3 + {SPR_MNUD, 3, 8, {NULL}, 3, 5, S_MINUSDIRT5}, // S_MINUSDIRT4 + {SPR_MNUD, 2, 8, {NULL}, 3, 5, S_MINUSDIRT6}, // S_MINUSDIRT5 + {SPR_MNUD, 1, 8, {NULL}, 3, 5, S_MINUSDIRT7}, // S_MINUSDIRT6 + {SPR_MNUD, 0, 8, {NULL}, 3, 5, S_NULL}, // S_MINUSDIRT7 + // Spring Shell {SPR_SSHL, 0, 4, {A_Look}, 0, 0, S_SSHELL_STND}, // S_SSHELL_STND {SPR_SSHL, 0, 4, {A_Chase}, 0, 0, S_SSHELL_RUN2}, // S_SSHELL_RUN1 @@ -415,14 +1138,31 @@ state_t states[NUMSTATES] = {SPR_UNID, 0, 1, {A_Chase}, 0, 0, S_UNIDUS_RUN }, // S_UNIDUS_RUN {SPR_UNID, 1, 1, {A_UnidusBall}, 1, 0, S_UNIDUS_BALL}, // S_UNIDUS_BALL + // Canarivore + {SPR_CANA, 0, 5, {A_Look}, 1200*FRACUNIT+1, 1, S_CANARIVORE_LOOK}, // S_CANARIVORE_LOOK + {SPR_CANA, 0, 3, {A_PlaySound}, sfx_s3k76, 1, S_CANARIVORE_AWAKEN2}, // S_CANARIVORE_AWAKEN1 + {SPR_CANA, 1, 5, {NULL}, 0, 0, S_CANARIVORE_AWAKEN3}, // S_CANARIVORE_AWAKEN2 + {SPR_CANA, 2, 8, {NULL}, 0, 0, S_CANARIVORE_GAS1}, // S_CANARIVORE_AWAKEN3 + {SPR_CANA, 2, 15, {A_PlaySound}, sfx_s3k93, 1, S_CANARIVORE_GAS2}, // S_CANARIVORE_GAS1 + {SPR_CANA, 1, 4, {NULL}, 0, 0, S_CANARIVORE_GAS3}, // S_CANARIVORE_GAS2 + {SPR_CANA, 2, 0, {A_PlaySound}, sfx_s3k97, 1, S_CANARIVORE_GAS4}, // S_CANARIVORE_GAS3 + {SPR_CANA, 2, 5, {A_CanarivoreGas}, MT_CANARIVORE_GAS, 0, S_CANARIVORE_GAS5}, // S_CANARIVORE_GAS4 + {SPR_CANA, 1, 5, {NULL}, 0, 0, S_CANARIVORE_GASREPEAT}, // S_CANARIVORE_GAS5 + {SPR_CANA, 2, 0, {A_Repeat}, 6, S_CANARIVORE_GAS4, S_CANARIVORE_CLOSE1}, // S_CANARIVORE_GASREPEAT + {SPR_CANA, 1, 8, {NULL}, 0, 0, S_CANARIVORE_CLOSE2}, // S_CANARIVORE_CLOSE1 + {SPR_CANA, 0, 90, {NULL}, sfx_s3k5d, 1, S_CANARIVORE_LOOK}, // S_CANARIVORE_CLOSE2 + + {SPR_CANG, 0|FF_TRANS90, 2, {NULL}, 0, 0, S_CANARIVOREGAS_2}, // S_CANARIVOREGAS_1 + {SPR_CANG, 0|FF_TRANS30, 2*TICRATE, {A_SetRandomTics}, 2, TICRATE, S_CANARIVOREGAS_3}, // S_CANARIVOREGAS_2 + {SPR_CANG, 0|FF_TRANS40, 10, {NULL}, 0, 0, S_CANARIVOREGAS_4}, // S_CANARIVOREGAS_3 + {SPR_CANG, 0|FF_TRANS50, 10, {NULL}, 0, 0, S_CANARIVOREGAS_5}, // S_CANARIVOREGAS_4 + {SPR_CANG, 0|FF_TRANS60, 10, {NULL}, 0, 0, S_CANARIVOREGAS_6}, // S_CANARIVOREGAS_5 + {SPR_CANG, 0|FF_TRANS70, 10, {NULL}, 0, 0, S_CANARIVOREGAS_7}, // S_CANARIVOREGAS_6 + {SPR_CANG, 0|FF_TRANS80, 10, {NULL}, 0, 0, S_CANARIVOREGAS_8}, // S_CANARIVOREGAS_7 + {SPR_CANG, 0|FF_TRANS90, 10, {NULL}, 0, 0, S_NULL}, // S_CANARIVOREGAS_8 + // Boss Explosion - {SPR_BOM2, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_BPLD2}, // S_BPLD1 - {SPR_BOM2, FF_FULLBRIGHT|1, 5, {NULL}, 0, 0, S_BPLD3}, // S_BPLD2 - {SPR_BOM2, FF_FULLBRIGHT|2, 5, {NULL}, 0, 0, S_BPLD4}, // S_BPLD3 - {SPR_BOM2, FF_FULLBRIGHT|3, 5, {NULL}, 0, 0, S_BPLD5}, // S_BPLD4 - {SPR_BOM2, FF_FULLBRIGHT|4, 5, {NULL}, 0, 0, S_BPLD6}, // S_BPLD5 - {SPR_BOM2, FF_FULLBRIGHT|5, 5, {NULL}, 0, 0, S_BPLD7}, // S_BPLD6 - {SPR_BOM2, FF_FULLBRIGHT|6, 5, {NULL}, 0, 0, S_NULL}, // S_BPLD7 + {SPR_BOM2, FF_FULLBRIGHT|FF_ANIMATE, (5*7), {NULL}, 6, 5, S_NULL}, // S_BOSSEXPLODE // S3&K Boss Explosion {SPR_BOM3, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_SONIC3KBOSSEXPLOSION2}, // S_SONIC3KBOSSEXPLOSION1 @@ -459,13 +1199,13 @@ state_t states[NUMSTATES] = {SPR_EGGM, 20, 2, {NULL}, 0, 0, S_EGGMOBILE_STND}, // S_EGGMOBILE_RATK10 {SPR_EGGM, 3, 12, {NULL}, 0, 0, S_EGGMOBILE_PANIC2}, // S_EGGMOBILE_PANIC1 {SPR_EGGM, 4, 4, {A_Boss1Spikeballs}, 0, 4, S_EGGMOBILE_PANIC3}, // S_EGGMOBILE_PANIC2 - {SPR_EGGM, 3, 5, {NULL}, 0, 0, S_EGGMOBILE_PANIC4}, // S_EGGMOBILE_PANIC3 + {SPR_EGGM, 3, 8, {NULL}, 0, 0, S_EGGMOBILE_PANIC4}, // S_EGGMOBILE_PANIC3 {SPR_EGGM, 4, 4, {A_Boss1Spikeballs}, 1, 4, S_EGGMOBILE_PANIC5}, // S_EGGMOBILE_PANIC4 - {SPR_EGGM, 3, 5, {NULL}, 0, 0, S_EGGMOBILE_PANIC6}, // S_EGGMOBILE_PANIC5 + {SPR_EGGM, 3, 8, {NULL}, 0, 0, S_EGGMOBILE_PANIC6}, // S_EGGMOBILE_PANIC5 {SPR_EGGM, 4, 4, {A_Boss1Spikeballs}, 2, 4, S_EGGMOBILE_PANIC7}, // S_EGGMOBILE_PANIC6 - {SPR_EGGM, 3, 5, {NULL}, 0, 0, S_EGGMOBILE_PANIC8}, // S_EGGMOBILE_PANIC7 + {SPR_EGGM, 3, 8, {NULL}, 0, 0, S_EGGMOBILE_PANIC8}, // S_EGGMOBILE_PANIC7 {SPR_EGGM, 4, 4, {A_Boss1Spikeballs}, 3, 4, S_EGGMOBILE_PANIC9}, // S_EGGMOBILE_PANIC8 - {SPR_EGGM, 3, 5, {NULL}, 0, 0, S_EGGMOBILE_PANIC10},// S_EGGMOBILE_PANIC9 + {SPR_EGGM, 3, 8, {NULL}, 0, 0, S_EGGMOBILE_PANIC10},// S_EGGMOBILE_PANIC9 {SPR_EGGM, 0, 35, {A_SkullAttack}, 0, 0, S_EGGMOBILE_STND}, // S_EGGMOBILE_PANIC10 {SPR_EGGM, 21, 24, {A_Pain}, 0, 0, S_EGGMOBILE_PAIN2}, // S_EGGMOBILE_PAIN {SPR_EGGM, 21, 16, {A_SkullAttack}, 1, 1, S_EGGMOBILE_STND}, // S_EGGMOBILE_PAIN2 @@ -521,9 +1261,10 @@ state_t states[NUMSTATES] = {SPR_SPNK, 0, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSSPIGOT // Boss 2 Goop - {SPR_GOOP, 0, 2, {NULL}, 0, 0, S_GOOP2}, // S_GOOP1 - {SPR_GOOP, 1, 2, {NULL}, 0, 0, S_GOOP1}, // S_GOOP2 - {SPR_GOOP, 2,-1, {NULL}, 0, 0, S_NULL}, // S_GOOP3 + {SPR_GOOP, 0, 2, {A_SpawnObjectRelative}, 0, MT_GOOPTRAIL, S_GOOP2}, // S_GOOP1 + {SPR_GOOP, 1, 2, {A_SpawnObjectRelative}, 0, MT_GOOPTRAIL, S_GOOP1}, // S_GOOP2 + {SPR_GOOP, 2, -1, {NULL}, 0, 0, S_NULL}, // S_GOOP3 + {SPR_GOOP, FF_ANIMATE|3, 11, {NULL}, 2, 6, S_NULL}, // S_GOOPTRAIL // Boss 3 {SPR_EGGO, 0, 1, {NULL}, 0, 0, S_EGGMOBILE3_STND}, // S_EGGMOBILE3_STND @@ -642,6 +1383,115 @@ state_t states[NUMSTATES] = {SPR_EFIR, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_JETFLAME2}, // S_JETFLAME1 {SPR_EFIR, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_JETFLAME1}, // S_JETFLAME2 + // Boss 5 + {SPR_FANG, 2, 16, {A_Look}, 1, 0, S_FANG_IDLE2}, // S_FANG_IDLE1 + {SPR_FANG, 3, 16, {A_Look}, 1, 0, S_FANG_IDLE3}, // S_FANG_IDLE2 + {SPR_FANG, 3, 16, {A_Look}, 1, 0, S_FANG_IDLE4}, // S_FANG_IDLE3 + {SPR_FANG, 3, 16, {A_Look}, 1, 0, S_FANG_IDLE5}, // S_FANG_IDLE4 + {SPR_FANG, 2, 16, {A_Look}, 1, 0, S_FANG_IDLE6}, // S_FANG_IDLE5 + {SPR_FANG, 1, 16, {A_Look}, 1, 0, S_FANG_IDLE7}, // S_FANG_IDLE6 + {SPR_FANG, 1, 16, {A_Look}, 1, 0, S_FANG_IDLE8}, // S_FANG_IDLE7 + {SPR_FANG, 1, 16, {A_Look}, 1, 0, S_FANG_IDLE1}, // S_FANG_IDLE8 + + {SPR_FANG, 14, 0, {A_DoNPCPain}, FRACUNIT, 0, S_FANG_PAIN2}, // S_FANG_PAIN1 + {SPR_FANG, 14, 1, {A_Boss5CheckOnGround}, S_FANG_PATHINGSTART1, S_FANG_PINCHPATHINGSTART1, S_FANG_PAIN2}, // S_FANG_PAIN2 + + {SPR_FANG, 8, 0, {A_Boss5ExtraRepeat}, 5, 4, S_FANG_PATHINGSTART2}, // S_FANG_PATHINGSTART1 + {SPR_FANG, 8, 0, {A_PlayActiveSound}, 0, 0, S_FANG_PATHING}, // S_FANG_PATHINGSTART2 + {SPR_FANG, 8, 0, {A_Boss5FindWaypoint}, 0, 0, S_FANG_BOUNCE1}, // S_FANG_PATHING + + {SPR_FANG, 8, 2, {A_Thrust}, 0, 1, S_FANG_BOUNCE2}, // S_FANG_BOUNCE1 + {SPR_FANG, 9, 2, {NULL}, 0, 0, S_FANG_BOUNCE3}, // S_FANG_BOUNCE2 + {SPR_FANG, 10, 1, {A_Boss5Jump}, 0, 0, S_FANG_BOUNCE4}, // S_FANG_BOUNCE3 + {SPR_FANG, 10, 1, {A_Boss5CheckFalling}, S_FANG_CHECKPATH1, S_FANG_FALL1, S_FANG_BOUNCE4}, // S_FANG_BOUNCE4 + + {SPR_FANG, 12, 1, {A_Boss5CheckOnGround}, S_FANG_CHECKPATH1, 0, S_FANG_FALL2}, // S_FANG_FALL1 + {SPR_FANG, 13, 1, {A_Boss5CheckOnGround}, S_FANG_CHECKPATH1, 0, S_FANG_FALL1}, // S_FANG_FALL2 + + {SPR_FANG, 8, 0, {A_Boss5Calm}, 0, 0, S_FANG_CHECKPATH2}, // S_FANG_CHECKPATH1 + {SPR_FANG, 8, 0, {A_Repeat}, 0, S_FANG_PATHINGCONT1, S_FANG_SKID1}, // S_FANG_CHECKPATH2 + + {SPR_FANG, 9, 0, {A_Boss5PinchShot}, MT_FBOMB, -16, S_FANG_PATHINGCONT2}, // S_FANG_PATHINGCONT1 + {SPR_FANG, 9, 0, {A_PlayActiveSound}, 0, 0, S_FANG_PATHINGCONT3}, // S_FANG_PATHINGCONT2 + {SPR_FANG, 9, 2, {A_Thrust}, 0, 1, S_FANG_PATHING}, // S_FANG_PATHINGCONT3 + + {SPR_FANG, 4, 0, {A_PlayAttackSound}, 0, 0, S_FANG_SKID2}, // S_FANG_SKID1 + {SPR_FANG, 4, 1, {A_DoNPCSkid}, S_FANG_SKID3, 0, S_FANG_SKID2}, // S_FANG_SKID2 + {SPR_FANG, 4, 10, {NULL}, 0, 0, S_FANG_CHOOSEATTACK}, // S_FANG_SKID3 + + {SPR_FANG, 0, 0, {A_RandomState}, S_FANG_LOBSHOT1, S_FANG_FIRESTART1, S_NULL}, // S_FANG_CHOOSEATTACK + + {SPR_FANG, 5, 0, {A_PrepareRepeat}, 3, 0, S_FANG_FIRESTART2}, // S_FANG_FIRESTART1 // Reset loop + {SPR_FANG, 5, 18, {A_LookForBetter}, 1, 0, S_FANG_FIRE1}, // S_FANG_FIRESTART2 + {SPR_FANG, 5, 5, {A_FireShot}, MT_CORK, -16, S_FANG_FIRE2}, // S_FANG_FIRE1 // Start of loop + {SPR_FANG, 6, 5, {NULL}, 0, 0, S_FANG_FIRE3}, // S_FANG_FIRE2 + {SPR_FANG, 7, 5, {NULL}, 0, 0, S_FANG_FIRE4}, // S_FANG_FIRE3 + {SPR_FANG, 5, 5, {NULL}, 2, 0, S_FANG_FIREREPEAT}, // S_FANG_FIRE4 + {SPR_FANG, 5, 0, {A_Repeat}, 3, S_FANG_FIRE1, S_FANG_WAIT1}, // S_FANG_FIREREPEAT // End of loop + + {SPR_FANG, 19, 18, {A_LookForBetter}, 1, 0, S_FANG_LOBSHOT2}, // S_FANG_LOBSHOT1 + {SPR_FANG, 20, 18, {A_BrakLobShot}, MT_FBOMB, 32+(1<<16), S_FANG_WAIT1}, // S_FANG_LOBSHOT2 + + {SPR_FANG, FF_ANIMATE|15, 70, {NULL}, 1, 5, S_FANG_WAIT2}, // S_FANG_WAIT1 + {SPR_FANG, 0, 35, {A_Look}, 1, 0, S_FANG_IDLE1}, // S_FANG_WAIT2 + + {SPR_FANG, 12, 1, {A_Boss5CheckOnGround}, S_FANG_PATHINGSTART2, S_FANG_PINCHPATHINGSTART1, S_FANG_WALLHIT}, // S_FANG_WALLHIT + + {SPR_FANG, 8, 0, {A_PrepareRepeat}, 1, 0, S_FANG_PINCHPATHINGSTART2}, // S_FANG_PINCHPATHINGSTART1 + {SPR_FANG, 8, 0, {A_PlayActiveSound}, 0, 0, S_FANG_PINCHPATHING}, // S_FANG_PINCHPATHINGSTART2 + {SPR_FANG, 8, 0, {A_Boss5FindWaypoint}, 1, 0, S_FANG_PINCHBOUNCE1}, // S_FANG_PINCHPATHING + {SPR_FANG, 8, 2, {A_Thrust}, 0, 1, S_FANG_PINCHBOUNCE2}, // S_FANG_PINCHBOUNCE1 + {SPR_FANG, 9, 2, {NULL}, 0, 0, S_FANG_PINCHBOUNCE3}, // S_FANG_PINCHBOUNCE2 + {SPR_FANG, 10, 2, {A_Boss5Jump}, 0, 0, S_FANG_PINCHBOUNCE4}, // S_FANG_PINCHBOUNCE3 + {SPR_FANG, 10, 1, {A_Boss5CheckFalling}, S_FANG_PINCHSKID1, S_FANG_PINCHFALL1, S_FANG_PINCHBOUNCE4}, // S_FANG_PINCHBOUNCE4 + {SPR_FANG, 12, 1, {A_Boss5CheckOnGround}, S_FANG_PINCHSKID1, 0, S_FANG_PINCHFALL2}, // S_FANG_PINCHFALL1 + {SPR_FANG, 13, 1, {A_Boss5CheckOnGround}, S_FANG_PINCHSKID1, 0, S_FANG_PINCHFALL1}, // S_FANG_PINCHFALL2 + {SPR_FANG, 4, 0, {A_PlayAttackSound}, 0, 0, S_FANG_PINCHSKID2}, // S_FANG_PINCHSKID1 + {SPR_FANG, 4, 1, {A_DoNPCSkid}, S_FANG_PINCHLOBSHOT1, 0, S_FANG_PINCHSKID2}, // S_FANG_PINCHSKID2 + {SPR_FANG, 19, 18, {A_FaceTarget}, 3, 0, S_FANG_PINCHLOBSHOT2}, // S_FANG_PINCHLOBSHOT1 + {SPR_FANG, 20, 30, {A_Boss5MakeItRain}, MT_FBOMB, -16, S_FANG_PINCHLOBSHOT3}, // S_FANG_PINCHLOBSHOT2 + {SPR_FANG, 19, 18, {A_LinedefExecute}, LE_BOSS4DROP, 0, S_FANG_PINCHLOBSHOT4}, // S_FANG_PINCHLOBSHOT3 + {SPR_FANG, 19, 0, {A_Boss5Calm}, 0, 0, S_FANG_PATHINGSTART1}, // S_FANG_PINCHLOBSHOT4 + + {SPR_FANG, 14, 0, {A_DoNPCPain}, 0, 0, S_FANG_DIE2}, // S_FANG_DIE1 + {SPR_FANG, 14, 1, {A_Boss5CheckOnGround}, S_FANG_DIE3, 0, S_FANG_DIE2}, // S_FANG_DIE2 + + {SPR_FANG, 17, 0, {A_Scream}, 0, 0, S_FANG_DIE4}, // S_FANG_DIE3 + {SPR_FANG, 17, 104, {NULL}, 0, 0, S_FANG_DIE5}, // S_FANG_DIE4 + + {SPR_FANG, 11, 0, {A_PlaySound}, sfx_jump, 0, S_FANG_DIE6}, // S_FANG_DIE5 + {SPR_FANG, 11, 1, {A_ZThrust}, 6, (1<<16)|1, S_FANG_DIE7}, // S_FANG_DIE6 + {SPR_FANG, 11, 1, {A_Boss5CheckFalling}, S_FANG_FLEEPATHING1, S_FANG_DIE8, S_FANG_DIE7}, // S_FANG_DIE7 + {SPR_FANG, 12, 1, {A_Boss5CheckOnGround}, S_FANG_FLEEPATHING1, 0, S_FANG_DIE8}, // S_FANG_DIE8 + + {SPR_FANG, 9, 0, {A_PlayActiveSound}, 0, 0, S_FANG_FLEEPATHING2}, // S_FANG_FLEEPATHING1 + {SPR_FANG, 8, 2, {A_Boss5FindWaypoint}, 2, 0, S_FANG_FLEEBOUNCE1}, // S_FANG_FLEEPATHING2 + {SPR_FANG, 9, 2, {NULL}, 0, 0, S_FANG_FLEEBOUNCE2}, // S_FANG_FLEEBOUNCE1 + {SPR_FANG, 10, -1, {A_BossDeath}, 0, 0, S_NULL}, // S_FANG_FLEEBOUNCE2 + + {SPR_FANG, 18, 7*TICRATE, {NULL}, 0, 0, S_NULL}, // S_FANG_KO + + {SPR_FBOM, 0, 1, {A_GhostMe}, 0, 0, S_FBOMB2}, // S_FBOMB1 + {SPR_FBOM, 1, 1, {A_GhostMe}, 0, 0, S_FBOMB1}, // S_FBOMB2 + {SPR_BARX, 0|FF_FULLBRIGHT, 3, {A_SetObjectFlags}, MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP, 0, S_FBOMB_EXPL2}, // S_FBOMB_EXPL1 + {SPR_BARX, 1|FF_FULLBRIGHT, 2, {A_Boss5BombExplode}, MT_TNTDUST, 0, S_FBOMB_EXPL3}, // S_FBOMB_EXPL2 + {SPR_BARX, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_FBOMB_EXPL4}, // S_FBOMB_EXPL3 + {SPR_BARX, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FBOMB_EXPL5}, // S_FBOMB_EXPL4 + {SPR_BARX, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FBOMB_EXPL6}, // S_FBOMB_EXPL5 + {SPR_NULL, 0, 2*TICRATE, {NULL}, 0, 0, S_NULL}, // S_FBOMB_EXPL6 + {SPR_BARD, 0|FF_TRANS90, 2, {NULL}, 0, 0, S_TNTDUST_2}, // S_TNTDUST_1 + {SPR_BARD, 0|FF_TRANS30, 2*TICRATE, {A_SetRandomTics}, 2, TICRATE, S_TNTDUST_3}, // S_TNTDUST_2 + {SPR_BARD, 0|FF_TRANS40, 10, {NULL}, 0, 0, S_TNTDUST_4}, // S_TNTDUST_3 + {SPR_BARD, 0|FF_TRANS50, 10, {NULL}, 0, 0, S_TNTDUST_5}, // S_TNTDUST_4 + {SPR_BARD, 0|FF_TRANS60, 10, {NULL}, 0, 0, S_TNTDUST_6}, // S_TNTDUST_5 + {SPR_BARD, 0|FF_TRANS70, 10, {NULL}, 0, 0, S_TNTDUST_7}, // S_TNTDUST_6 + {SPR_BARD, 0|FF_TRANS80, 10, {NULL}, 0, 0, S_TNTDUST_8}, // S_TNTDUST_7 + {SPR_BARD, 0|FF_TRANS90, 10, {NULL}, 0, 0, S_NULL}, // S_TNTDUST_8 + {SPR_FSGN, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGNA + {SPR_FSGN, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGNB + {SPR_FSGN, 2|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGNC + + // Black Eggman (Boss 7) {SPR_BRAK, 0, 1, {A_SetReactionTime}, 0, 0, S_BLACKEGG_STND2}, // S_BLACKEGG_STND {SPR_BRAK, 0, 7, {A_Look}, 1, 0, S_BLACKEGG_STND2}, // S_BLACKEGG_STND2 {SPR_BRAK, 1, 7, {NULL}, 0, 0, S_BLACKEGG_WALK2}, // S_BLACKEGG_WALK1 @@ -711,7 +1561,7 @@ state_t states[NUMSTATES] = {SPR_BRAK, 21, 3*TICRATE, {NULL}, 0, 0, S_BLACKEGG_DESTROYPLAT2}, // S_BLACKEGG_DESTROYPLAT1 {SPR_BRAK, 21, 1, {A_PlaySound}, sfx_s3k54, 0, S_BLACKEGG_DESTROYPLAT3}, // S_BLACKEGG_DESTROYPLAT2 - {SPR_BRAK, 21, 14, {A_LinedefExecute}, 4200, 0, S_BLACKEGG_STND}, // S_BLACKEGG_DESTROYPLAT3 + {SPR_BRAK, 21, 14, {A_LinedefExecute}, LE_BRAKPLATFORM, 0, S_BLACKEGG_STND}, // S_BLACKEGG_DESTROYPLAT3 {SPR_NULL, 0, 1, {A_CapeChase}, (160 - 20) << 16, 0, S_BLACKEGG_HELPER}, // S_BLACKEGG_HELPER @@ -775,12 +1625,12 @@ state_t states[NUMSTATES] = {SPR_RCKT, 2 + FF_FULLBRIGHT, 6, {A_NapalmScatter}, MT_CYBRAKDEMON_NAPALM_FLAMES + (6<<16), 32 + (16<<16), S_CYBRAKDEMONMISSILE_EXPLODE3}, // S_CYBRAKDEMONMISSILE_EXPLODE2 {SPR_RCKT, 3 + FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_NULL}, // S_CYBRAKDEMONMISSILE_EXPLODE3 - {SPR_FLME, FF_TRANS50|FF_FULLBRIGHT , 15, {NULL}, 0, 0, S_CYBRAKDEMONFLAMESHOT_FLY2}, // S_CYBRAKDEMONFLAMESHOT_FLY1 - {SPR_FLME, FF_TRANS50|FF_FULLBRIGHT|1, 15, {NULL}, 0, 0, S_CYBRAKDEMONFLAMESHOT_FLY3}, // S_CYBRAKDEMONFLAMESHOT_FLY2 - {SPR_FLME, FF_TRANS50|FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_CYBRAKDEMONFLAMESHOT_FLY3}, // S_CYBRAKDEMONFLAMESHOT_FLY3 - {SPR_FLME, FF_TRANS50|FF_FULLBRIGHT|2, 0, {A_SpawnObjectRelative}, 0, MT_CYBRAKDEMON_FLAMEREST, S_NULL}, // S_CYBRAKDEMONFLAMESHOT_DIE + {SPR_FLME, FF_FULLBRIGHT , 15, {NULL}, 0, 0, S_CYBRAKDEMONFLAMESHOT_FLY2}, // S_CYBRAKDEMONFLAMESHOT_FLY1 + {SPR_FLME, FF_FULLBRIGHT|1, 15, {NULL}, 0, 0, S_CYBRAKDEMONFLAMESHOT_FLY3}, // S_CYBRAKDEMONFLAMESHOT_FLY2 + {SPR_FLME, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_CYBRAKDEMONFLAMESHOT_FLY3}, // S_CYBRAKDEMONFLAMESHOT_FLY3 + {SPR_FLME, FF_FULLBRIGHT|2, 0, {A_SpawnObjectRelative}, 0, MT_CYBRAKDEMON_FLAMEREST, S_NULL}, // S_CYBRAKDEMONFLAMESHOT_DIE - {SPR_FLAM, FF_TRANS50|FF_FULLBRIGHT|3, 3, {A_SetFuse}, 10*TICRATE, 0, S_FLAME1}, // S_CYBRAKDEMONFLAMEREST + {SPR_FLAM, FF_FULLBRIGHT, 0, {A_SetFuse}, 10*TICRATE, 0, S_FLAMEREST}, // S_CYBRAKDEMONFLAMEREST {SPR_ELEC, 0 + FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER_INIT2}, // S_CYBRAKDEMONELECTRICBARRIER_INIT1 {SPR_ELEC, 0 + FF_FULLBRIGHT, 0, {A_RemoteAction}, -1, S_CYBRAKDEMON_INVINCIBLERIZE, S_CYBRAKDEMONELECTRICBARRIER_PLAYSOUND}, // S_CYBRAKDEMONELECTRICBARRIER_INIT2 @@ -898,14 +1748,14 @@ state_t states[NUMSTATES] = {SPR_METL, 4, -1, {NULL}, 0, 0, S_NULL}, // S_METALSONIC_FLOAT {SPR_METL, 12, -1, {NULL}, 0, 0, S_METALSONIC_STUN}, // S_METALSONIC_VECTOR {SPR_METL, 0, -1, {NULL}, 0, 0, S_METALSONIC_FLOAT}, // S_METALSONIC_STUN - {SPR_METL, 13, -1, {NULL}, 0, 0, S_NULL}, // S_METALSONIC_BLOCK {SPR_METL, 13, 40, {NULL}, 0, 0, S_METALSONIC_GATHER},// S_METALSONIC_RAISE {SPR_METL, 14, -1, {NULL}, 0, 0, S_NULL}, // S_METALSONIC_GATHER - {SPR_METL, 9, -1, {NULL}, 0, 0, S_METALSONIC_BOUNCE},// S_METALSONIC_DASH + {SPR_METL, 15, -1, {NULL}, 0, 0, S_METALSONIC_BOUNCE},// S_METALSONIC_DASH {SPR_METL, 14, -1, {NULL}, 0, 0, S_NULL}, // S_METALSONIC_BOUNCE + {SPR_METL, 16, -1, {NULL}, 0, 0, S_NULL}, // S_METALSONIC_BADBOUNCE {SPR_METL, 13, -1, {NULL}, 0, 0, S_METALSONIC_GATHER},// S_METALSONIC_SHOOT {SPR_METL, 11, 40, {A_Pain}, 0, 0, S_METALSONIC_FLOAT}, // S_METALSONIC_PAIN - {SPR_METL, 0, -1, {A_BossDeath}, 0, 0, S_NULL}, // S_METALSONIC_DEATH + {SPR_METL, 11, -1, {A_BossDeath}, 0, 0, S_NULL}, // S_METALSONIC_DEATH {SPR_METL, 3, 4, {NULL}, 0, 0, S_METALSONIC_FLEE2}, // S_METALSONIC_FLEE1 {SPR_METL, 4, 4, {A_BossScream}, 0, 0, S_METALSONIC_FLEE3}, // S_METALSONIC_FLEE2 {SPR_METL, 5, 4, {NULL}, 0, 0, S_METALSONIC_FLEE4}, // S_METALSONIC_FLEE3 @@ -925,30 +1775,36 @@ state_t states[NUMSTATES] = {SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30|11, 1, {NULL}, 0, 0, S_MSSHIELD_F1}, // S_MSSHIELD_F12 // Ring - {SPR_RING, FF_ANIMATE, -1, {NULL}, 23, 1, S_RING}, // S_RING + {SPR_RING, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 23, 1, S_RING}, // S_RING - // Blue Sphere Replacement for special stages - {SPR_BBAL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BLUEBALL - {SPR_BBAL, 0, 20, {NULL}, 0, 0, S_NULL}, // S_BLUEBALLSPARK + // Blue Sphere for special stages + {SPR_SPHR, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERE + {SPR_SPHR, FF_FULLBRIGHT|FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 1, 4, S_NULL}, // S_BLUESPHEREBONUS + {SPR_SPHR, 0, 20, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERESPARK - // Gravity Well sprites for Egg Rock's Special Stage - {SPR_GWLG, 0, 1, {NULL}, 0, 0, S_GRAVWELLGREEN2}, // S_GRAVWELLGREEN - {SPR_GWLG, 1, 1, {NULL}, 0, 0, S_GRAVWELLGREEN3}, // S_GRAVWELLGREEN2 - {SPR_GWLG, 2, 1, {NULL}, 0, 0, S_GRAVWELLGREEN}, // S_GRAVWELLGREEN3 + // Bomb Sphere + {SPR_SPHR, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_BOMBSPHERE2}, // S_BOMBSPHERE1 + {SPR_SPHR, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE3}, // S_BOMBSPHERE2 + {SPR_SPHR, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_BOMBSPHERE4}, // S_BOMBSPHERE3 + {SPR_SPHR, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE1}, // S_BOMBSPHERE4 - {SPR_GWLR, 0, 1, {NULL}, 0, 0, S_GRAVWELLRED2}, // S_GRAVWELLRED - {SPR_GWLR, 1, 1, {NULL}, 0, 0, S_GRAVWELLRED3}, // S_GRAVWELLRED2 - {SPR_GWLR, 2, 1, {NULL}, 0, 0, S_GRAVWELLRED}, // S_GRAVWELLRED3 + // NiGHTS Chip + {SPR_NCHP, FF_FULLBRIGHT|FF_ANIMATE, -1, {NULL}, 15, 2, S_NULL}, // S_NIGHTSCHIP + {SPR_NCHP, FF_FULLBRIGHT|FF_ANIMATE|16, -1, {NULL}, 15, 2, S_NULL}, // S_NIGHTSCHIPBONUS - // Individual Team Rings (now with shield attracting action! =P) - {SPR_TRNG, FF_ANIMATE, -1, {NULL}, 23, 1, S_TEAMRING}, // S_TEAMRING1 + // NiGHTS Star + {SPR_NSTR, FF_ANIMATE, -1, {NULL}, 14, 2, S_NULL}, // S_NIGHTSSTAR + {SPR_NSTR, 15, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSSTARXMAS - // Special Stage Token - {SPR_EMMY, FF_ANIMATE|FF_FULLBRIGHT, -1, {NULL}, 6, 2, S_EMMY}, // S_EMMY + // Gravity Well sprites for Egg Rock's Special Stage + {SPR_GWLG, FF_ANIMATE, -1, {NULL}, 2, 1, S_NULL}, // S_GRAVWELLGREEN + {SPR_GWLR, FF_ANIMATE, -1, {NULL}, 2, 1, S_NULL}, // S_GRAVWELLRED + + // Individual Team Rings (now with shield attracting action! =P) + {SPR_TRNG, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 23, 1, S_TEAMRING}, // S_TEAMRING // Special Stage Token - {SPR_TOKE, FF_TRANS50|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_TOKEN - {SPR_TOKE, FF_TRANS50|FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_MOVINGTOKEN}, // S_MOVINGTOKEN + {SPR_TOKE, FF_ANIMATE|FF_FULLBRIGHT, -1, {NULL}, 19, 1, S_TOKEN}, // S_TOKEN // CTF Flags {SPR_RFLG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_REDFLAG @@ -991,19 +1847,16 @@ state_t states[NUMSTATES] = {SPR_CEMG, FF_FULLBRIGHT|5, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG6 {SPR_CEMG, FF_FULLBRIGHT|6, -1, {NULL}, 0, 0, S_NULL}, // S_CEMG7 - // Emeralds (for hunt) - {SPR_EMER, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EMER1 - - // Fan - {SPR_FANS, 0, 1, {A_FanBubbleSpawn}, 2048, 0, S_FAN2}, // S_FAN - {SPR_FANS, 1, 1, {A_FanBubbleSpawn}, 1024, 0, S_FAN3}, // S_FAN2 - {SPR_FANS, 2, 1, {A_FanBubbleSpawn}, 512, 0, S_FAN4}, // S_FAN3 - {SPR_FANS, 3, 1, {A_FanBubbleSpawn}, 1024, 0, S_FAN5}, // S_FAN4 - {SPR_FANS, 4, 1, {A_FanBubbleSpawn}, 512, 0, S_FAN}, // S_FAN5 + // Emerald hunt shards + {SPR_SHRD, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHRD1 + {SPR_SHRD, 1, -1, {NULL}, 0, 0, S_NULL}, // S_SHRD2 + {SPR_SHRD, 2, -1, {NULL}, 0, 0, S_NULL}, // S_SHRD3 // Bubble Source - {SPR_BUBL, 0, 8, {A_BubbleSpawn}, 2048, 0, S_BUBBLES2}, // S_BUBBLES1 - {SPR_BUBL, 1, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES1}, // S_BUBBLES2 + {SPR_BBLS, 0, 8, {A_BubbleSpawn}, 2048, 0, S_BUBBLES2}, // S_BUBBLES1 + {SPR_BBLS, 1, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES3}, // S_BUBBLES2 + {SPR_BBLS, 2, 8, {A_BubbleSpawn}, 2048, 0, S_BUBBLES4}, // S_BUBBLES3 + {SPR_BBLS, 3, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES1}, // S_BUBBLES4 // Level End Sign {SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN2}, // S_SIGN1 @@ -1060,27 +1913,17 @@ state_t states[NUMSTATES] = {SPR_SIGN, 3, -1, {NULL}, 0, 0, S_NULL}, // S_SIGN52 Eggman {SPR_SIGN, 7, -1, {A_SignPlayer}, 0, 0, S_NULL}, // S_SIGN53 Blank - // Steam Riser - {SPR_STEM, 0, 2, {A_SetSolidSteam}, 0, 0, S_STEAM2}, // S_STEAM1 - {SPR_STEM, 1, 2, {A_UnsetSolidSteam}, 0, 0, S_STEAM3}, // S_STEAM2 - {SPR_STEM, 2, 2, {NULL}, 0, 0, S_STEAM4}, // S_STEAM3 - {SPR_STEM, 3, 2, {NULL}, 0, 0, S_STEAM5}, // S_STEAM4 - {SPR_STEM, 4, 2, {NULL}, 0, 0, S_STEAM6}, // S_STEAM5 - {SPR_STEM, 5, 2, {NULL}, 0, 0, S_STEAM7}, // S_STEAM6 - {SPR_STEM, 6, 2, {NULL}, 0, 0, S_STEAM8}, // S_STEAM7 - {SPR_STEM, 7, 18, {NULL}, 0, 0, S_STEAM1}, // S_STEAM8 - // Spike Ball - {SPR_SPIK, 0, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL2}, // S_SPIKEBALL1 - {SPR_SPIK, 1, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL3}, // S_SPIKEBALL2 - {SPR_SPIK, 2, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL4}, // S_SPIKEBALL3 - {SPR_SPIK, 3, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL5}, // S_SPIKEBALL4 - {SPR_SPIK, 4, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL6}, // S_SPIKEBALL5 - {SPR_SPIK, 5, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL7}, // S_SPIKEBALL6 - {SPR_SPIK, 6, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL8}, // S_SPIKEBALL7 - {SPR_SPIK, 7, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL1}, // S_SPIKEBALL8 - - // Red Shield's Spawn + {SPR_SPIK, 0, 1, {NULL}, 0, 0, S_SPIKEBALL2}, // S_SPIKEBALL1 + {SPR_SPIK, 1, 1, {NULL}, 0, 0, S_SPIKEBALL3}, // S_SPIKEBALL2 + {SPR_SPIK, 2, 1, {NULL}, 0, 0, S_SPIKEBALL4}, // S_SPIKEBALL3 + {SPR_SPIK, 3, 1, {NULL}, 0, 0, S_SPIKEBALL5}, // S_SPIKEBALL4 + {SPR_SPIK, 4, 1, {NULL}, 0, 0, S_SPIKEBALL6}, // S_SPIKEBALL5 + {SPR_SPIK, 5, 1, {NULL}, 0, 0, S_SPIKEBALL7}, // S_SPIKEBALL6 + {SPR_SPIK, 6, 1, {NULL}, 0, 0, S_SPIKEBALL8}, // S_SPIKEBALL7 + {SPR_SPIK, 7, 1, {NULL}, 0, 0, S_SPIKEBALL1}, // S_SPIKEBALL8 + + // Elemental Shield's Spawn {SPR_SFLM, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SPINFIRE2}, // S_SPINFIRE1 {SPR_SFLM, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_SPINFIRE3}, // S_SPINFIRE2 {SPR_SFLM, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_SPINFIRE4}, // S_SPINFIRE3 @@ -1090,200 +1933,177 @@ state_t states[NUMSTATES] = // Floor Spike {SPR_USPK, 0,-1, {A_SpikeRetract}, 1, 0, S_SPIKE2}, // S_SPIKE1 -- Fully extended - {SPR_USPK, 5, 2, {A_Pain}, 0, 0, S_SPIKE3}, // S_SPIKE2 - {SPR_USPK, 4, 2, {NULL}, 0, 0, S_SPIKE4}, // S_SPIKE3 + {SPR_USPK, 1, 2, {A_Pain}, 0, 0, S_SPIKE3}, // S_SPIKE2 + {SPR_USPK, 2, 2, {NULL}, 0, 0, S_SPIKE4}, // S_SPIKE3 {SPR_USPK, 3,-1, {A_SpikeRetract}, 0, 0, S_SPIKE5}, // S_SPIKE4 -- Fully retracted - {SPR_USPK, 4, 2, {A_Pain}, 0, 0, S_SPIKE6}, // S_SPIKE5 - {SPR_USPK, 5, 2, {NULL}, 0, 0, S_SPIKE1}, // S_SPIKE6 - {SPR_USPK, 1,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED1 -- Busted spike particles - {SPR_USPK, 2,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED2 + {SPR_USPK, 2, 2, {A_Pain}, 0, 0, S_SPIKE6}, // S_SPIKE5 + {SPR_USPK, 1, 2, {NULL}, 0, 0, S_SPIKE1}, // S_SPIKE6 + {SPR_USPK, 4,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED1 -- Busted spike particles + {SPR_USPK, 5,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED2 + + // Wall Spike + {SPR_WSPK, 0|FF_PAPERSPRITE,-1, {A_SpikeRetract}, 1, 0, S_WALLSPIKE2}, // S_WALLSPIKE1 -- Fully extended + {SPR_WSPK, 1|FF_PAPERSPRITE, 2, {A_Pain}, 0, 0, S_WALLSPIKE3}, // S_WALLSPIKE2 + {SPR_WSPK, 2|FF_PAPERSPRITE, 2, {NULL}, 0, 0, S_WALLSPIKE4}, // S_WALLSPIKE3 + {SPR_WSPK, 3|FF_PAPERSPRITE,-1, {A_SpikeRetract}, 0, 0, S_WALLSPIKE5}, // S_WALLSPIKE4 -- Fully retracted + {SPR_WSPK, 2|FF_PAPERSPRITE, 2, {A_Pain}, 0, 0, S_WALLSPIKE6}, // S_WALLSPIKE5 + {SPR_WSPK, 1|FF_PAPERSPRITE, 2, {NULL}, 0, 0, S_WALLSPIKE1}, // S_WALLSPIKE6 + {SPR_WSPB, 0|FF_PAPERSPRITE,-1, {NULL}, 0, 0, S_NULL}, // S_WALLSPIKEBASE -- Base + {SPR_WSPK, 4,-1, {NULL}, 0, 0, S_NULL}, // S_WALLSPIKED1 -- Busted spike particles + {SPR_WSPK, 5,-1, {NULL}, 0, 0, S_NULL}, // S_WALLSPIKED2 // Starpost - {SPR_STPT, 0 , -1, {NULL}, 0, 0, S_NULL}, // S_STARPOST_IDLE - {SPR_STPT, FF_ANIMATE , -1, {NULL}, 1, 2, S_NULL}, // S_STARPOST_FLASH - {SPR_STPT, FF_ANIMATE|2, 31, {NULL}, 15, 1, S_STARPOST_FLASH}, // S_STARPOST_SPIN + {SPR_STPT, 0 , -1, {NULL}, 0, 0, S_NULL}, // S_STARPOST_IDLE + {SPR_STPT, FF_ANIMATE|17, -1, {NULL}, 5, 1, S_NULL}, // S_STARPOST_FLASH + {SPR_STPT, FF_ANIMATE|13, 2, {NULL}, 1, 1, S_STARPOST_SPIN}, // S_STARPOST_STARTSPIN + {SPR_STPT, FF_ANIMATE|1 , 23, {NULL}, 11, 1, S_STARPOST_ENDSPIN}, // S_STARPOST_SPIN + {SPR_STPT, FF_ANIMATE|15, 2, {NULL}, 1, 1, S_STARPOST_FLASH}, // S_STARPOST_ENDSPIN // Big floating mine - {SPR_BMNE, 0, 5, {NULL}, 0, 0, S_BIGMINE2}, // S_BIGMINE1 - {SPR_BMNE, 1, 5, {NULL}, 0, 0, S_BIGMINE3}, // S_BIGMINE2 - {SPR_BMNE, 2, 5, {NULL}, 0, 0, S_BIGMINE4}, // S_BIGMINE3 - {SPR_BMNE, 3, 5, {NULL}, 0, 0, S_BIGMINE5}, // S_BIGMINE4 - {SPR_BMNE, 4, 5, {NULL}, 0, 0, S_BIGMINE6}, // S_BIGMINE5 - {SPR_BMNE, 5, 5, {NULL}, 0, 0, S_BIGMINE7}, // S_BIGMINE6 - {SPR_BMNE, 6, 5, {NULL}, 0, 0, S_BIGMINE8}, // S_BIGMINE7 - {SPR_BMNE, 7, 5, {NULL}, 0, 0, S_BIGMINE1}, // S_BIGMINE8 + {SPR_BMNE, 0, 2, {A_Look}, ((224<<FRACBITS)|1), 0, S_BIGMINE_IDLE}, // S_BIGMINE_IDLE + {SPR_BMNE, 1, 2, {A_MineRange}, 112, 0, S_BIGMINE_ALERT2}, // S_BIGMINE_ALERT1 + {SPR_BMNE, 2, 2, {A_MineRange}, 112, 0, S_BIGMINE_ALERT3}, // S_BIGMINE_ALERT2 + {SPR_BMNE, 0, 1, {A_Look}, ((224<<FRACBITS)|1), 1, S_BIGMINE_IDLE}, // S_BIGMINE_ALERT3 + {SPR_BMNE, 3, 25, {A_Pain}, 0, 0, S_BIGMINE_SET2}, // S_BIGMINE_SET1 + {SPR_BMNE, 3, 10, {A_SetObjectFlags}, MF_SHOOTABLE, 1, S_BIGMINE_SET3}, // S_BIGMINE_SET1 + {SPR_BMNE, 3, 1, {A_MineExplode}, 0, 0, S_BIGMINE_BLAST1}, // S_BIGMINE_SET3 + {SPR_BMNB, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_BIGMINE_BLAST2}, // S_BIGMINE_BLAST1 + {SPR_BMNB, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_BIGMINE_BLAST3}, // S_BIGMINE_BLAST2 + {SPR_BMNB, 2|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_BIGMINE_BLAST4}, // S_BIGMINE_BLAST3 + {SPR_BMNB, 3|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_BIGMINE_BLAST5}, // S_BIGMINE_BLAST4 + {SPR_NULL, 0, 35, {NULL}, 0, 0, S_NULL}, // S_BIGMINE_BLAST5 // Cannon launcher {SPR_NULL, 0, 1, {A_FindTarget}, MT_PLAYER, 0, S_CANNONLAUNCHER2}, // S_CANNONLAUNCHER1 {SPR_NULL, 0, 1, {A_LobShot}, MT_CANNONBALL, 4*TICRATE, S_CANNONLAUNCHER3}, // S_CANNONLAUNCHER2 {SPR_NULL, 0, 2, {A_SetRandomTics}, TICRATE/2, 3*TICRATE, S_CANNONLAUNCHER1}, // S_CANNONLAUNCHER3 - // Super Ring Box - {SPR_SRBX, 0, 2, {NULL}, 0, 0, S_SUPERRINGBOX1}, // S_SUPERRINGBOX - {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_SUPERRINGBOX}, // S_SUPERRINGBOX1 - {SPR_SRBX, 1, 4, {A_MonitorPop}, 0, 0, S_SUPERRINGBOX3}, // S_SUPERRINGBOX2 - {SPR_YLTV, 2, 4, {NULL}, 0, 0, S_SUPERRINGBOX4}, // S_SUPERRINGBOX3 - {SPR_YLTV, 3, 4, {NULL}, 0, 0, S_SUPERRINGBOX5}, // S_SUPERRINGBOX4 - {SPR_YLTV, 4, 4, {NULL}, 0, 0, S_SUPERRINGBOX6}, // S_SUPERRINGBOX5 - {SPR_SRBX, 1, 18, {A_RingBox}, 0, 0, S_NULL}, // S_SUPERRINGBOX6 - - // Red Team Ring Box - {SPR_RRBX, 0, 2, {NULL}, 0, 0, S_REDRINGBOX1}, // S_REDRINGBOX - {SPR_RRBX, 1, 1, {NULL}, 0, 0, S_REDRINGBOX}, // S_REDRINGBOX1 - - // Blue Team Ring Box - {SPR_BRBX, 0, 2, {NULL}, 0, 0, S_BLUERINGBOX1}, // S_BLUERINGBOX - {SPR_BRBX, 1, 1, {NULL}, 0, 0, S_BLUERINGBOX}, // S_BLUERINGBOX1 - - // Super Sneakers Box - {SPR_SHTV, 0, 2, {NULL}, 0, 0, S_SHTV1}, // S_SHTV - {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_SHTV}, // S_SHTV1 - {SPR_SHTV, 1, 4, {A_MonitorPop}, 0, 0, S_SHTV3}, // S_SHTV2 - {SPR_YLTV, 2, 4, {NULL}, 0, 0, S_SHTV4}, // S_SHTV3 - {SPR_YLTV, 3, 4, {NULL}, 0, 0, S_SHTV5}, // S_SHTV4 - {SPR_YLTV, 4, 4, {NULL}, 0, 0, S_SHTV6}, // S_SHTV5 - {SPR_SHTV, 1, 18, {A_SuperSneakers}, 0, 0, S_NULL}, // S_SHTV6 - - // Invincibility Box - {SPR_PINV, 0, 2, {NULL}, 0, 0, S_PINV1}, // S_PINV - {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_PINV}, // S_PINV1 - {SPR_PINV, 1, 4, {A_MonitorPop}, 0, 0, S_PINV3}, // S_PINV2 - {SPR_PINV, 2, 4, {NULL}, 0, 0, S_PINV4}, // S_PINV3 - {SPR_PINV, 3, 4, {NULL}, 0, 0, S_PINV5}, // S_PINV4 - {SPR_PINV, 4, 4, {NULL}, 0, 0, S_PINV6}, // S_PINV5 - {SPR_PINV, 1, 18, {A_Invincibility}, 0, 0, S_NULL}, // S_PINV6 - - // 1up Box - {SPR_PRUP, 2, 2, {A_1upThinker}, 0, 0, S_PRUP1}, // S_PRUP - {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_PRUP}, // S_PRUP1 - {SPR_PRUP, 3, 4, {A_MonitorPop}, 0, 0, S_PRUP3}, // S_PRUP2 - {SPR_PINV, 2, 4, {NULL}, 0, 0, S_PRUP4}, // S_PRUP3 - {SPR_PINV, 3, 4, {NULL}, 0, 0, S_PRUP5}, // S_PRUP4 - {SPR_PINV, 4, 4, {NULL}, 0, 0, S_PRUP6}, // S_PRUP5 - {SPR_PRUP, 3, 18, {A_ExtraLife}, 0, 0, S_NULL}, // S_PRUP6 - - // Ring Shield Box - {SPR_YLTV, 0, 2, {NULL}, 0, 0, S_YLTV1}, // S_YLTV - {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_YLTV}, // S_YLTV1 - {SPR_YLTV, 1, 4, {A_MonitorPop}, 0, 0, S_YLTV3}, // S_YLTV2 - {SPR_YLTV, 2, 4, {NULL}, 0, 0, S_YLTV4}, // S_YLTV3 - {SPR_YLTV, 3, 4, {NULL}, 0, 0, S_YLTV5}, // S_YLTV4 - {SPR_YLTV, 4, 4, {NULL}, 0, 0, S_YLTV6}, // S_YLTV5 - {SPR_YLTV, 1, 18, {A_RingShield},0, 0, S_NULL}, // S_YLTV6 - - // Force Shield Box - {SPR_BLTV, 0, 2, {NULL}, 0, 0, S_BLTV2}, // S_BLTV1 - {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_BLTV1}, // S_BLTV2 - {SPR_BLTV, 1, 4, {A_MonitorPop}, 0, 0, S_BLTV4}, // S_BLTV3 - {SPR_BLTV, 2, 4, {NULL}, 0, 0, S_BLTV5}, // S_BLTV4 - {SPR_BLTV, 3, 4, {NULL}, 0, 0, S_BLTV6}, // S_BLTV5 - {SPR_BLTV, 4, 4, {NULL}, 0, 0, S_BLTV7}, // S_BLTV6 - {SPR_BLTV, 1, 18, {A_ForceShield}, 0, 0, S_NULL}, // S_BLTV7 - - // Bomb Shield Box - {SPR_BKTV, 0, 2, {NULL}, 0, 0, S_BKTV2}, // S_BKTV1 - {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_BKTV1}, // S_BKTV2 - {SPR_BKTV, 1, 4, {A_MonitorPop}, 0, 0, S_BKTV4}, // S_BKTV3 - {SPR_BKTV, 2, 4, {NULL}, 0, 0, S_BKTV5}, // S_BKTV4 - {SPR_BKTV, 3, 4, {NULL}, 0, 0, S_BKTV6}, // S_BKTV5 - {SPR_BKTV, 4, 4, {NULL}, 0, 0, S_BKTV7}, // S_BKTV6 - {SPR_BKTV, 1, 18, {A_BombShield}, 0, 0, S_NULL}, // S_BKTV7 - - // Jump Shield Box - {SPR_WHTV, 0, 2, {NULL}, 0, 0, S_WHTV2}, // S_WHTV1 - {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_WHTV1}, // S_WHTV2 - {SPR_WHTV, 1, 4, {A_MonitorPop}, 0, 0, S_WHTV4}, // S_WHTV3 - {SPR_WHTV, 2, 4, {NULL}, 0, 0, S_WHTV5}, // S_WHTV4 - {SPR_WHTV, 3, 4, {NULL}, 0, 0, S_WHTV6}, // S_WHTV5 - {SPR_WHTV, 4, 4, {NULL}, 0, 0, S_WHTV7}, // S_WHTV6 - {SPR_WHTV, 1, 18, {A_JumpShield}, 0, 0, S_NULL}, // S_WHTV7 - - // Elemental Shield Box - {SPR_ELTV, 0, 2, {NULL}, 0, 0, S_GRTV1}, // S_GRTV - {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_GRTV}, // S_GRTV1 - {SPR_ELTV, 1, 4, {A_MonitorPop}, 0, 0, S_GRTV3}, // S_GRTV2 - {SPR_ELTV, 2, 4, {NULL}, 0, 0, S_GRTV4}, // S_GRTV3 - {SPR_ELTV, 3, 4, {NULL}, 0, 0, S_GRTV5}, // S_GRTV4 - {SPR_ELTV, 4, 4, {NULL}, 0, 0, S_GRTV6}, // S_GRTV5 - {SPR_ELTV, 1, 18, {A_WaterShield}, 0, 0, S_NULL}, // S_GRTV6 - - // Pity Shield Box - {SPR_GRTV, 0, 2, {NULL}, 0, 0, S_PITV2}, // S_PITV1 - {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_PITV1}, // S_PITV2 - {SPR_GRTV, 1, 4, {A_MonitorPop}, 0, 0, S_PITV4}, // S_PITV3 - {SPR_GRTV, 2, 4, {NULL}, 0, 0, S_PITV5}, // S_PITV4 - {SPR_GRTV, 3, 4, {NULL}, 0, 0, S_PITV6}, // S_PITV5 - {SPR_GRTV, 4, 4, {NULL}, 0, 0, S_PITV7}, // S_PITV6 - {SPR_GRTV, 1, 18, {A_PityShield}, 0, 0, S_NULL}, // S_PITV7 - - // Eggman Box - {SPR_EGGB, 0, 2, {NULL}, 0, 0, S_EGGTV2}, // S_EGGTV1 - {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_EGGTV1}, // S_EGGTV2 - {SPR_EGGB, 1, 4, {A_MonitorPop}, 0, 0, S_EGGTV4}, // S_EGGTV3 - {SPR_BKTV, 2, 4, {NULL}, 0, 0, S_EGGTV5}, // S_EGGTV4 - {SPR_BKTV, 3, 4, {NULL}, 0, 0, S_EGGTV6}, // S_EGGTV5 - {SPR_BKTV, 4, 4, {NULL}, 0, 0, S_EGGTV7}, // S_EGGTV6 - {SPR_EGGB, 1, 18, {A_EggmanBox}, 0, 0, S_NULL}, // S_EGGTV7 - - // Teleport Box - {SPR_MIXU, 0, 2, {NULL}, 0, 0, S_MIXUPBOX2}, // S_MIXUPBOX1 - {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_MIXUPBOX1}, // S_MIXUPBOX2 - {SPR_MIXU, 1, 4, {A_MonitorPop}, 0, 0, S_MIXUPBOX4}, // S_MIXUPBOX3 - {SPR_WHTV, 2, 4, {NULL}, 0, 0, S_MIXUPBOX5}, // S_MIXUPBOX4 - {SPR_WHTV, 3, 4, {NULL}, 0, 0, S_MIXUPBOX6}, // S_MIXUPBOX5 - {SPR_WHTV, 4, 4, {NULL}, 0, 0, S_MIXUPBOX7}, // S_MIXUPBOX6 - {SPR_MIXU, 1, 18, {A_MixUp}, 0, 0, S_NULL}, // S_MIXUPBOX7 - - // Recycler Box - {SPR_RECY, 0, 2, {NULL}, 0, 0, S_RECYCLETV2}, // S_RECYCLETV1 - {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_RECYCLETV1}, // S_RECYCLETV2 - {SPR_RECY, 1, 4, {A_MonitorPop}, 0, 0, S_RECYCLETV4}, // S_RECYCLETV3 - {SPR_GRTV, 2, 4, {NULL}, 0, 0, S_RECYCLETV5}, // S_RECYCLETV4 - {SPR_GRTV, 3, 4, {NULL}, 0, 0, S_RECYCLETV6}, // S_RECYCLETV5 - {SPR_GRTV, 4, 4, {NULL}, 0, 0, S_RECYCLETV7}, // S_RECYCLETV6 - {SPR_RECY, 1, 18, {A_RecyclePowers}, 0, 0, S_NULL}, // S_RECYCLETV7 - - // Question Box - {SPR_QUES, 0, 2, {NULL}, 0, 0, S_RANDOMBOX2}, // S_RANDOMBOX1 - {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_RANDOMBOX1}, // S_RANDOMBOX2 - {SPR_QUES, 0, 1, {A_MonitorPop}, 0, 0, S_NULL}, // S_RANDOMBOX3 - - // Gravity Boots Box - {SPR_GBTV, 0, 2, {NULL}, 0, 0, S_GBTV2}, // S_GBTV1 - {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_GBTV1}, // S_GBTV2 - {SPR_GBTV, 1, 4, {A_MonitorPop}, 0, 0, S_GBTV4}, // S_GBTV3 - {SPR_BLTV, 2, 4, {NULL}, 0, 0, S_GBTV5}, // S_GBTV4 - {SPR_BLTV, 3, 4, {NULL}, 0, 0, S_GBTV6}, // S_GBTV5 - {SPR_BLTV, 4, 4, {NULL}, 0, 0, S_GBTV7}, // S_GBTV6 - {SPR_GBTV, 1, 18, {A_GravityBox}, 0, 0, S_NULL}, // S_GBTV7 - - // Score Box (1k) - {SPR_PTTV, 0, 2, {NULL}, 0, 0, S_SCORETVA2}, // S_SCORETVA1 - {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_SCORETVA1}, // S_SCORETVA2 - {SPR_PTTV, 1, 4, {A_MonitorPop}, 0, 0, S_SCORETVA4}, // S_SCORETVA3 - {SPR_PTTV, 2, 4, {NULL}, 0, 0, S_SCORETVA5}, // S_SCORETVA4 - {SPR_PTTV, 3, 4, {NULL}, 0, 0, S_SCORETVA6}, // S_SCORETVA5 - {SPR_PTTV, 4, 4, {NULL}, 0, 0, S_SCORETVA7}, // S_SCORETVA6 - {SPR_PTTV, 1, 18, {A_AwardScore}, 0, 0, S_NULL}, // S_SCORETVA7 - - // Score Box (10k) - {SPR_PTTV, 5, 2, {NULL}, 0, 0, S_SCORETVB2}, // S_SCORETVB1 - {SPR_MTEX, 0, 1, {NULL}, 0, 0, S_SCORETVB1}, // S_SCORETVB2 - {SPR_PTTV, 6, 4, {A_MonitorPop}, 0, 0, S_SCORETVB4}, // S_SCORETVB3 - {SPR_PTTV, 7, 4, {NULL}, 0, 0, S_SCORETVB5}, // S_SCORETVB4 - {SPR_PTTV, 8, 4, {NULL}, 0, 0, S_SCORETVB6}, // S_SCORETVB5 - {SPR_PTTV, 9, 4, {NULL}, 0, 0, S_SCORETVB7}, // S_SCORETVB6 - {SPR_PTTV, 6, 18, {A_AwardScore}, 0, 0, S_NULL}, // S_SCORETVB7 - - // Monitor Explosion - {SPR_MTEX, 0, 4, {NULL}, 0, 0, S_MONITOREXPLOSION2}, // S_MONITOREXPLOSION1 - {SPR_MTEX, 1, -1, {NULL}, 0, 0, S_NULL}, // S_MONITOREXPLOSION2 - - {SPR_RRBX, 1, 4, {NULL}, 0, 0, S_REDMONITOREXPLOSION2}, // S_REDMONITOREXPLOSION1 - {SPR_RRBX, 2, -1, {NULL}, 0, 0, S_NULL}, // S_REDMONITOREXPLOSION2 - - {SPR_BRBX, 1, 4, {NULL}, 0, 0, S_BLUEMONITOREXPLOSION2}, // S_BLUEMONITOREXPLOSION1 - {SPR_BRBX, 2, -1, {NULL}, 0, 0, S_NULL}, // S_BLUEMONITOREXPLOSION2 + // Monitor Miscellany + {SPR_NSPK, 0, 16, {NULL}, 0, 0, S_BOXSPARKLE2}, // S_BOXSPARKLE1 + {SPR_NSPK, 1, 12, {NULL}, 0, 0, S_BOXSPARKLE3}, // S_BOXSPARKLE2 + {SPR_NSPK, 2, 8, {NULL}, 0, 0, S_BOXSPARKLE4}, // S_BOXSPARKLE3 + {SPR_NSPK, 3, 4, {NULL}, 0, 0, S_NULL}, // S_BOXSPARKLE4 + + {SPR_MSTV, 0, 1, {NULL}, 0, 0, S_SPAWNSTATE}, // S_BOX_FLICKER + {SPR_MSTV, 0, 4, {A_MonitorPop}, 0, 0, S_BOX_POP2}, // S_BOX_POP1 + {SPR_MSTV, 1, -1, {NULL}, 0, 0, S_NULL}, // S_BOX_POP2 + + {SPR_XLTV, 0, 1, {NULL}, 0, 0, S_SPAWNSTATE}, // S_GOLDBOX_FLICKER + {SPR_XLTV, 1, 89, {A_GoldMonitorPop}, 0, 0, S_GOLDBOX_OFF2}, // S_GOLDBOX_OFF1 + {SPR_XLTV, 2, 4, {A_PlayAttackSound}, 0, 0, S_GOLDBOX_OFF3}, // S_GOLDBOX_OFF2 + {SPR_XLTV, 3, 4, {NULL}, 0, 0, S_GOLDBOX_OFF4}, // S_GOLDBOX_OFF3 + {SPR_XLTV, 4, 4, {NULL}, 0, 0, S_GOLDBOX_OFF5}, // S_GOLDBOX_OFF4 + {SPR_XLTV, 5, 2, {NULL}, 0, 0, S_GOLDBOX_OFF6}, // S_GOLDBOX_OFF5 + {SPR_XLTV, 6, 2, {NULL}, 0, 0, S_GOLDBOX_OFF7}, // S_GOLDBOX_OFF6 + {SPR_XLTV, 6, 0, {A_GoldMonitorRestore}, 0, 0, S_SPAWNSTATE}, // S_GOLDBOX_OFF7 + + // Monitor States (one per box) + {SPR_TVMY, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_MYSTERY_BOX + {SPR_TVRI, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_RING_BOX + {SPR_TVPI, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_PITY_BOX + {SPR_TVAT, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_ATTRACT_BOX + {SPR_TVFO, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_FORCE_BOX + {SPR_TVAR, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_ARMAGEDDON_BOX + {SPR_TVWW, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_WHIRLWIND_BOX + {SPR_TVEL, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_ELEMENTAL_BOX + {SPR_TVSS, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_SNEAKERS_BOX + {SPR_TVIV, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_INVULN_BOX + {SPR_TV1U, 0, 2, {A_1upThinker}, 0, 0, S_BOX_FLICKER}, // S_1UP_BOX + {SPR_TVEG, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_EGGMAN_BOX + {SPR_TVMX, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_MIXUP_BOX + {SPR_TVGV, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_GRAVITY_BOX + {SPR_TVRC, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_RECYCLER_BOX + {SPR_TV1K, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_SCORE1K_BOX + {SPR_TVTK, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_SCORE10K_BOX + {SPR_TVFL, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_FLAMEAURA_BOX + {SPR_TVBB, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_BUBBLEWRAP_BOX + {SPR_TVZP, 0, 2, {NULL}, 0, 0, S_BOX_FLICKER}, // S_THUNDERCOIN_BOX + + // Gold Repeat Monitor States (one per box) + {SPR_TVPI, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_PITY_GOLDBOX + {SPR_TVAT, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_ATTRACT_GOLDBOX + {SPR_TVFO, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_FORCE_GOLDBOX + {SPR_TVAR, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_ARMAGEDDON_GOLDBOX + {SPR_TVWW, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_WHIRLWIND_GOLDBOX + {SPR_TVEL, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_ELEMENTAL_GOLDBOX + {SPR_TVSS, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_SNEAKERS_GOLDBOX + {SPR_TVIV, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_INVULN_GOLDBOX + {SPR_TVEG, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_EGGMAN_GOLDBOX + {SPR_TVGV, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_GRAVITY_GOLDBOX + {SPR_TVFL, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_FLAMEAURA_GOLDBOX + {SPR_TVBB, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_BUBBLEWRAP_GOLDBOX + {SPR_TVZP, 1, 2, {A_GoldMonitorSparkle}, 0, 0, S_GOLDBOX_FLICKER}, // S_THUNDERCOIN_GOLDBOX + + // Team Ring Boxes (these are special) + {SPR_TRRI, 0, 2, {NULL}, 0, 0, S_RING_REDBOX2}, // S_RING_REDBOX1 + {SPR_TRRI, 1, 1, {NULL}, 0, 0, S_RING_REDBOX1}, // S_RING_REDBOX2 + {SPR_TRRI, 1, 4, {A_MonitorPop}, 0, 0, S_REDBOX_POP2}, // S_REDBOX_POP1 + {SPR_TRRI, 2, -1, {NULL}, 0, 0, S_NULL}, // S_REDBOX_POP2 + + {SPR_TBRI, 0, 2, {NULL}, 0, 0, S_RING_BLUEBOX2}, // S_RING_BLUEBOX1 + {SPR_TBRI, 1, 1, {NULL}, 0, 0, S_RING_BLUEBOX1}, // S_RING_BLUEBOX2 + {SPR_TBRI, 1, 4, {A_MonitorPop}, 0, 0, S_BLUEBOX_POP2}, // S_BLUEBOX_POP1 + {SPR_TBRI, 2, -1, {NULL}, 0, 0, S_NULL}, // S_BLUEBOX_POP2 + + // Box Icons -- 2 states each, animation and action + {SPR_TVRI, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_RING_ICON2}, // S_RING_ICON1 + {SPR_TVRI, 2, 18, {A_RingBox}, 0, 0, S_NULL}, // S_RING_ICON2 + + {SPR_TVPI, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_PITY_ICON2}, // S_PITY_ICON1 + {SPR_TVPI, 2, 18, {A_GiveShield}, SH_PITY, 0, S_NULL}, // S_PITY_ICON2 + + {SPR_TVAT, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_ATTRACT_ICON2}, // S_ATTRACT_ICON1 + {SPR_TVAT, 2, 18, {A_GiveShield}, SH_ATTRACT, 0, S_NULL}, // S_ATTRACT_ICON2 + + {SPR_TVFO, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_FORCE_ICON2}, // S_FORCE_ICON1 + {SPR_TVFO, 2, 18, {A_GiveShield}, SH_FORCE|1, 0, S_NULL}, // S_FORCE_ICON2 + + {SPR_TVAR, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_ARMAGEDDON_ICON2}, // S_ARMAGEDDON_ICON1 + {SPR_TVAR, 2, 18, {A_GiveShield}, SH_ARMAGEDDON, 0, S_NULL}, // S_ARMAGEDDON_ICON2 + + {SPR_TVWW, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_WHIRLWIND_ICON2}, // S_WHIRLWIND_ICON1 + {SPR_TVWW, 2, 18, {A_GiveShield}, SH_WHIRLWIND, 0, S_NULL}, // S_WHIRLWIND_ICON2 + + {SPR_TVEL, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_ELEMENTAL_ICON2}, // S_ELEMENTAL_ICON1 + {SPR_TVEL, 2, 18, {A_GiveShield}, SH_ELEMENTAL, 0, S_NULL}, // S_ELEMENTAL_ICON2 + + {SPR_TVSS, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_SNEAKERS_ICON2}, // S_SNEAKERS_ICON1 + {SPR_TVSS, 2, 18, {A_SuperSneakers}, 0, 0, S_NULL}, // S_SNEAKERS_ICON2 + + {SPR_TVIV, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_INVULN_ICON2}, // S_INVULN_ICON1 + {SPR_TVIV, 2, 18, {A_Invincibility}, 0, 0, S_NULL}, // S_INVULN_ICON2 + + {SPR_TV1U, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_1UP_ICON2}, // S_1UP_ICON1 + {SPR_TV1U, 2, 18, {A_ExtraLife}, 0, 0, S_NULL}, // S_1UP_ICON2 + + {SPR_TVEG, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_EGGMAN_ICON2}, // S_EGGMAN_ICON1 + {SPR_TVEG, 2, 18, {A_EggmanBox}, 0, 0, S_NULL}, // S_EGGMAN_ICON2 + + {SPR_TVMX, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_MIXUP_ICON2}, // S_MIXUP_ICON1 + {SPR_TVMX, 2, 18, {A_MixUp}, 0, 0, S_NULL}, // S_MIXUP_ICON2 + + {SPR_TVGV, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_GRAVITY_ICON2}, // S_GRAVITY_ICON1 + {SPR_TVGV, 2, 18, {A_GravityBox}, 0, 0, S_NULL}, // S_GRAVITY_ICON2 + + {SPR_TVRC, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_RECYCLER_ICON2}, // S_RECYCLER_ICON1 + {SPR_TVRC, 2, 18, {A_RecyclePowers}, 0, 0, S_NULL}, // S_RECYCLER_ICON2 + + {SPR_TV1K, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_SCORE1K_ICON2}, // S_SCORE1K_ICON1 + {SPR_TV1K, 2, 18, {A_AwardScore}, 0, 0, S_NULL}, // S_SCORE1K_ICON2 + + {SPR_TVTK, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_SCORE10K_ICON2}, // S_SCORE10K_ICON1 + {SPR_TVTK, 2, 18, {A_AwardScore}, 0, 0, S_NULL}, // S_SCORE10K_ICON2 + + {SPR_TVFL, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_FLAMEAURA_ICON2}, // S_FLAMEAURA_ICON1 + {SPR_TVFL, 2, 18, {A_GiveShield}, SH_FLAMEAURA, 0, S_NULL}, // S_FLAMEAURA_ICON2 + + {SPR_TVBB, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_BUBBLEWRAP_ICON2}, // S_BUBBLEWRAP_ICON1 + {SPR_TVBB, 2, 18, {A_GiveShield}, SH_BUBBLEWRAP, 0, S_NULL}, // S_BUBBLERWAP_ICON2 + + {SPR_TVZP, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_THUNDERCOIN_ICON2}, // S_THUNDERCOIN_ICON1 + {SPR_TVZP, 2, 18, {A_GiveShield}, SH_THUNDERCOIN, 0, S_NULL}, // S_THUNDERCOIN_ICON2 + + // --- {SPR_MISL, FF_FULLBRIGHT, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_ROCKET}, // S_ROCKET @@ -1311,39 +2131,60 @@ state_t states[NUMSTATES] = {SPR_CBLL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CANNONBALL1 - {SPR_AROW, 0, 1, {A_ArrowCheck}, 0, 0, S_ARROW}, // S_ARROW - {SPR_AROW, 1, 1, {A_ArrowCheck}, 0, 0, S_ARROWUP}, // S_ARROWUP - {SPR_AROW, 2, 1, {A_ArrowCheck}, 0, 0, S_ARROWDOWN}, // S_ARROWDOWN - - {SPR_CFIR, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_DEMONFIRE2}, // S_DEMONFIRE1 - {SPR_CFIR, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_DEMONFIRE3}, // S_DEMONFIRE2 - {SPR_CFIR, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_DEMONFIRE4}, // S_DEMONFIRE3 - {SPR_CFIR, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_DEMONFIRE5}, // S_DEMONFIRE4 - {SPR_CFIR, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_DEMONFIRE6}, // S_DEMONFIRE5 - {SPR_CFIR, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_DEMONFIRE1}, // S_DEMONFIRE6 - - // GFZ Flower - {SPR_FWR1, 0, 14, {NULL}, 0, 0, S_GFZFLOWERA2}, // S_GFZFLOWERA - {SPR_FWR1, 1, 14, {NULL}, 0, 0, S_GFZFLOWERA}, // S_GFZFLOWERA2 - - {SPR_FWR2, 0, 7, {NULL}, 0, 0, S_GFZFLOWERB2}, // S_GFZFLOWERB1 - {SPR_FWR2, 1, 7, {NULL}, 0, 0, S_GFZFLOWERB1}, // S_GFZFLOWERB1 - - {SPR_FWR3, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GFZFLOWERC1 - - {SPR_BUS1, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BERRYBUSH - {SPR_BUS2, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BUSH - - {SPR_THZP, 0, 4, {NULL}, 0, 0, S_THZPLANT2}, // S_THZPLANT1 - {SPR_THZP, 1, 4, {NULL}, 0, 0, S_THZPLANT3}, // S_THZPLANT1 - {SPR_THZP, 2, 4, {NULL}, 0, 0, S_THZPLANT4}, // S_THZPLANT1 - {SPR_THZP, 3, 4, {NULL}, 0, 0, S_THZPLANT1}, // S_THZPLANT1 + {SPR_AROW, 0, -1, {NULL}, 0, 0, S_NULL}, // S_ARROW + {SPR_AROW, FF_ANIMATE, TICRATE, {A_ArrowBonks}, 7, 2, S_NULL}, // S_ARROWBONK + + {SPR_CFIR, FF_FULLBRIGHT|FF_ANIMATE, -1, {NULL}, 5, 2, S_NULL}, // S_DEMONFIRE + + // GFZ flowers + {SPR_FWR1, FF_ANIMATE, -1, {NULL}, 7, 3, S_NULL}, // S_GFZFLOWERA + {SPR_FWR2, FF_ANIMATE, -1, {NULL}, 19, 3, S_NULL}, // S_GFZFLOWERB + {SPR_FWR3, FF_ANIMATE, -1, {NULL}, 11, 4, S_NULL}, // S_GFZFLOWERC + + {SPR_BUS3, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BLUEBERRYBUSH + {SPR_BUS1, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BERRYBUSH + {SPR_BUS2, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BUSH + + // Trees + {SPR_TRE1, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GFZTREE + {SPR_TRE1, 1, -1, {NULL}, 0, 0, S_NULL}, // S_GFZBERRYTREE + {SPR_TRE1, 2, -1, {NULL}, 0, 0, S_NULL}, // S_GFZCHERRYTREE + {SPR_TRE2, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CHECKERTREE + {SPR_TRE2, 1, -1, {NULL}, 0, 0, S_NULL}, // S_CHECKERSUNSETTREE + {SPR_TRE3, 0, -1, {NULL}, 0, 0, S_NULL}, // S_FHZTREE + {SPR_TRE3, 1, -1, {NULL}, 0, 0, S_NULL}, // S_FHZPINKTREE + {SPR_TRE4, 0, -1, {NULL}, 0, 0, S_NULL}, // S_POLYGONTREE + {SPR_TRE5, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BUSHTREE + {SPR_TRE5, 1, -1, {NULL}, 0, 0, S_NULL}, // S_BUSHREDTREE + {SPR_TRE6, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SPRINGTREE + + // THZ flowers + {SPR_THZP, FF_ANIMATE, -1, {NULL}, 7, 4, S_NULL}, // S_THZFLOWERA + {SPR_FWR5, FF_ANIMATE, -1, {NULL}, 19, 2, S_NULL}, // S_THZFLOWERB + {SPR_FWR6, FF_ANIMATE, -1, {NULL}, 19, 2, S_NULL}, // S_THZFLOWERC + + // THZ Steam Whistle tree/bush + {SPR_THZT, 0, -1, {NULL}, 0, 0, S_NULL}, // S_THZTREE + {SPR_THZT, 1|FF_PAPERSPRITE, 40, {NULL}, 0, 0, S_THZTREEBRANCH2}, // S_THZTREEBRANCH1 + {SPR_THZT, 2|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH3}, // S_THZTREEBRANCH2 + {SPR_THZT, 3|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH4}, // S_THZTREEBRANCH3 + {SPR_THZT, 4|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH5}, // S_THZTREEBRANCH4 + {SPR_THZT, 5|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH6}, // S_THZTREEBRANCH5 + {SPR_THZT, 6|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH7}, // S_THZTREEBRANCH6 + {SPR_THZT, 7|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH8}, // S_THZTREEBRANCH7 + {SPR_THZT, 8|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH9}, // S_THZTREEBRANCH8 + {SPR_THZT, 9|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH10}, // S_THZTREEBRANCH9 + {SPR_THZT, 10|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH11}, // S_THZTREEBRANCH10 + {SPR_THZT, 11|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH12}, // S_THZTREEBRANCH11 + {SPR_THZT, 12|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH13}, // S_THZTREEBRANCH12 + {SPR_THZT, 13|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_THZTREEBRANCH1}, // S_THZTREEBRANCH13 // THZ Alarm {SPR_ALRM, FF_FULLBRIGHT, 35, {A_Scream}, 0, 0, S_ALARM1}, // S_ALARM1 // Deep Sea Gargoyle {SPR_GARG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GARGOYLE + {SPR_GARG, 1, -1, {NULL}, 0, 0, S_NULL}, // S_BIGGARGOYLE // DSZ Seaweed {SPR_SEWE, 0, -1, {NULL}, 0, 0, S_SEAWEED2}, // S_SEAWEED1 @@ -1374,14 +2215,34 @@ state_t states[NUMSTATES] = // Blue Crystal {SPR_BCRY, FF_TRANS30, -1, {NULL}, 0, 0, S_NULL}, // S_BLUECRYSTAL1 + // Kelp + {SPR_KELP, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KELP + + // DSZ Stalagmites + {SPR_DSTG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_DSZSTALAGMITE + {SPR_DSTG, 1, -1, {NULL}, 0, 0, S_NULL}, // S_DSZ2STALAGMITE + + // DSZ Light beam + {SPR_LIBE, 0|FF_TRANS80|FF_FULLBRIGHT|FF_PAPERSPRITE, 4, {A_LightBeamReset}, 0, 0, S_LIGHTBEAM2}, // S_LIGHTBEAM1 + {SPR_LIBE, 0|FF_TRANS70|FF_FULLBRIGHT|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_LIGHTBEAM3}, // S_LIGHTBEAM2 + {SPR_LIBE, 0|FF_TRANS60|FF_FULLBRIGHT|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_LIGHTBEAM4}, // S_LIGHTBEAM3 + {SPR_LIBE, 0|FF_TRANS50|FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {NULL}, 0, 0, S_LIGHTBEAM5}, // S_LIGHTBEAM4 + {SPR_LIBE, 0|FF_TRANS40|FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {NULL}, 0, 0, S_LIGHTBEAM6}, // S_LIGHTBEAM5 + {SPR_LIBE, 0|FF_TRANS30|FF_FULLBRIGHT|FF_PAPERSPRITE, 9, {NULL}, 0, 0, S_LIGHTBEAM7}, // S_LIGHTBEAM6 + {SPR_LIBE, 0|FF_TRANS40|FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {NULL}, 0, 0, S_LIGHTBEAM8}, // S_LIGHTBEAM7 + {SPR_LIBE, 0|FF_TRANS50|FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {NULL}, 0, 0, S_LIGHTBEAM9}, // S_LIGHTBEAM8 + {SPR_LIBE, 0|FF_TRANS60|FF_FULLBRIGHT|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_LIGHTBEAM10}, // S_LIGHTBEAM9 + {SPR_LIBE, 0|FF_TRANS70|FF_FULLBRIGHT|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_LIGHTBEAM11}, // S_LIGHTBEAM10 + {SPR_LIBE, 0|FF_TRANS80|FF_FULLBRIGHT|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_LIGHTBEAM12}, // S_LIGHTBEAM11 + {SPR_NULL, 0, 2, {A_SetRandomTics}, 4, 35, S_LIGHTBEAM1}, // S_LIGHTBEAM12 + // CEZ Chain {SPR_CHAN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZCHAIN // Flame - {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_FLAME2}, // S_FLAME1 - {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS50|1, 3, {NULL}, 0, 0, S_FLAME3}, // S_FLAME2 - {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS50|2, 3, {NULL}, 0, 0, S_FLAME4}, // S_FLAME3 - {SPR_FLAM, FF_FULLBRIGHT|FF_TRANS50|3, 3, {NULL}, 0, 0, S_FLAME1}, // S_FLAME4 + {SPR_FLAM, FF_FULLBRIGHT|FF_ANIMATE, 3*8, {A_FlameParticle}, 7, 3, S_FLAME}, // S_FLAME + {SPR_FLAM, FF_FULLBRIGHT|FF_ANIMATE|8, TICRATE, {NULL}, 3, 3, S_NULL}, // S_FLAMEPARTICLE + {SPR_FLAM, FF_FULLBRIGHT|FF_ANIMATE, -1, {NULL}, 7, 3, S_NULL}, // S_FLAMEREST // Eggman statue {SPR_ESTA, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGSTATUE1 @@ -1390,31 +2251,103 @@ state_t states[NUMSTATES] = {SPR_NULL, 0, -1, {NULL}, 0, 0, S_SLING2}, // S_SLING1 {SPR_NULL, 0, -1, {A_SlingAppear}, 0, 0, S_NULL}, // S_SLING2 - // Small Mace Chain - {SPR_SMCH, 0, 1, {A_MaceRotate}, 0, 0, S_SMALLMACECHAIN}, // S_SMALLMACECHAIN - - // Big Mace Chain - {SPR_BMCH, 0, 1, {A_MaceRotate}, 0, 0, S_BIGMACECHAIN}, // S_BIGMACECHAIN - - // Small Mace - {SPR_SMCE, 0, 1, {A_MaceRotate}, 0, 0, S_SMALLMACE}, // S_SMALLMACE - - // Big Mace - {SPR_BMCE, 0, 1, {A_MaceRotate}, 0, 0, S_BIGMACE}, // S_BIGMACE - - // CEZ Flower - {SPR_FWR4, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZFLOWER1 + // CEZ maces and chains + {SPR_SMCH, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SMALLMACECHAIN + {SPR_BMCH, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BIGMACECHAIN + {SPR_SMCE, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SMALLMACE + {SPR_BMCE, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BIGMACE + {SPR_SMCH, 1, -1, {NULL}, 0, 0, S_NULL}, // S_SMALLGRABCHAIN + {SPR_BMCH, 1, -1, {NULL}, 0, 0, S_NULL}, // S_BIGGRABCHAIN + + // Yellow spring on a ball + {SPR_YSPB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YELLOWSPRINGBALL + {SPR_YSPB, 4, 4, {A_Pain}, 0, 0, S_YELLOWSPRINGBALL3}, // S_YELLOWSPRINGBALL2 + {SPR_YSPB, 3, 1, {NULL}, 0, 0, S_YELLOWSPRINGBALL4}, // S_YELLOWSPRINGBALL3 + {SPR_YSPB, 2, 1, {NULL}, 0, 0, S_YELLOWSPRINGBALL5}, // S_YELLOWSPRINGBALL4 + {SPR_YSPB, 1, 1, {NULL}, 0, 0, S_YELLOWSPRINGBALL}, // S_YELLOWSPRINGBALL5 + + // Red spring on a ball + {SPR_RSPB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_REDSPRINGBALL + {SPR_RSPB, 4, 4, {A_Pain}, 0, 0, S_REDSPRINGBALL3}, // S_REDSPRINGBALL2 + {SPR_RSPB, 3, 1, {NULL}, 0, 0, S_REDSPRINGBALL4}, // S_REDSPRINGBALL3 + {SPR_RSPB, 2, 1, {NULL}, 0, 0, S_REDSPRINGBALL5}, // S_REDSPRINGBALL4 + {SPR_RSPB, 1, 1, {NULL}, 0, 0, S_REDSPRINGBALL}, // S_REDSPRINGBALL5 + + // Small Firebar + {SPR_SFBR, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_SMALLFIREBAR2}, // S_SMALLFIREBAR1 + {SPR_SFBR, FF_FULLBRIGHT| 1, 1, {NULL}, 0, 0, S_SMALLFIREBAR3}, // S_SMALLFIREBAR2 + {SPR_SFBR, FF_FULLBRIGHT| 2, 1, {A_FlameParticle}, 0, 0, S_SMALLFIREBAR4}, // S_SMALLFIREBAR3 + {SPR_SFBR, FF_FULLBRIGHT| 3, 1, {NULL}, 0, 0, S_SMALLFIREBAR5}, // S_SMALLFIREBAR4 + {SPR_SFBR, FF_FULLBRIGHT| 4, 1, {NULL}, 0, 0, S_SMALLFIREBAR6}, // S_SMALLFIREBAR5 + {SPR_SFBR, FF_FULLBRIGHT| 5, 1, {NULL}, 0, 0, S_SMALLFIREBAR7}, // S_SMALLFIREBAR6 + {SPR_SFBR, FF_FULLBRIGHT| 6, 1, {A_FlameParticle}, 0, 0, S_SMALLFIREBAR8}, // S_SMALLFIREBAR7 + {SPR_SFBR, FF_FULLBRIGHT| 7, 1, {NULL}, 0, 0, S_SMALLFIREBAR9}, // S_SMALLFIREBAR8 + {SPR_SFBR, FF_FULLBRIGHT| 8, 1, {NULL}, 0, 0, S_SMALLFIREBAR10}, // S_SMALLFIREBAR9 + {SPR_SFBR, FF_FULLBRIGHT| 9, 1, {NULL}, 0, 0, S_SMALLFIREBAR11}, // S_SMALLFIREBAR10 + {SPR_SFBR, FF_FULLBRIGHT|10, 1, {A_FlameParticle}, 0, 0, S_SMALLFIREBAR12}, // S_SMALLFIREBAR11 + {SPR_SFBR, FF_FULLBRIGHT|11, 1, {NULL}, 0, 0, S_SMALLFIREBAR13}, // S_SMALLFIREBAR12 + {SPR_SFBR, FF_FULLBRIGHT|12, 1, {NULL}, 0, 0, S_SMALLFIREBAR14}, // S_SMALLFIREBAR13 + {SPR_SFBR, FF_FULLBRIGHT|13, 1, {NULL}, 0, 0, S_SMALLFIREBAR15}, // S_SMALLFIREBAR14 + {SPR_SFBR, FF_FULLBRIGHT|14, 1, {A_FlameParticle}, 0, 0, S_SMALLFIREBAR16}, // S_SMALLFIREBAR15 + {SPR_SFBR, FF_FULLBRIGHT|15, 1, {NULL}, 0, 0, S_SMALLFIREBAR1}, // S_SMALLFIREBAR16 + + // Big Firebar + {SPR_BFBR, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_BIGFIREBAR2}, // S_BIGFIREBAR1 + {SPR_BFBR, FF_FULLBRIGHT| 1, 1, {NULL}, 0, 0, S_BIGFIREBAR3}, // S_BIGFIREBAR2 + {SPR_BFBR, FF_FULLBRIGHT| 2, 1, {A_FlameParticle}, 0, 0, S_BIGFIREBAR4}, // S_BIGFIREBAR3 + {SPR_BFBR, FF_FULLBRIGHT| 3, 1, {NULL}, 0, 0, S_BIGFIREBAR5}, // S_BIGFIREBAR4 + {SPR_BFBR, FF_FULLBRIGHT| 4, 1, {NULL}, 0, 0, S_BIGFIREBAR6}, // S_BIGFIREBAR5 + {SPR_BFBR, FF_FULLBRIGHT| 5, 1, {NULL}, 0, 0, S_BIGFIREBAR7}, // S_BIGFIREBAR6 + {SPR_BFBR, FF_FULLBRIGHT| 6, 1, {A_FlameParticle}, 0, 0, S_BIGFIREBAR8}, // S_BIGFIREBAR7 + {SPR_BFBR, FF_FULLBRIGHT| 7, 1, {NULL}, 0, 0, S_BIGFIREBAR9}, // S_BIGFIREBAR8 + {SPR_BFBR, FF_FULLBRIGHT| 8, 1, {NULL}, 0, 0, S_BIGFIREBAR10}, // S_BIGFIREBAR9 + {SPR_BFBR, FF_FULLBRIGHT| 9, 1, {NULL}, 0, 0, S_BIGFIREBAR11}, // S_BIGFIREBAR10 + {SPR_BFBR, FF_FULLBRIGHT|10, 1, {A_FlameParticle}, 0, 0, S_BIGFIREBAR12}, // S_BIGFIREBAR11 + {SPR_BFBR, FF_FULLBRIGHT|11, 1, {NULL}, 0, 0, S_BIGFIREBAR13}, // S_BIGFIREBAR12 + {SPR_BFBR, FF_FULLBRIGHT|12, 1, {NULL}, 0, 0, S_BIGFIREBAR14}, // S_BIGFIREBAR13 + {SPR_BFBR, FF_FULLBRIGHT|13, 1, {NULL}, 0, 0, S_BIGFIREBAR15}, // S_BIGFIREBAR14 + {SPR_BFBR, FF_FULLBRIGHT|14, 1, {A_FlameParticle}, 0, 0, S_BIGFIREBAR16}, // S_BIGFIREBAR15 + {SPR_BFBR, FF_FULLBRIGHT|15, 1, {NULL}, 0, 0, S_BIGFIREBAR1}, // S_BIGFIREBAR16 + + {SPR_FWR4, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZFLOWER + {SPR_BANR, 1, -1, {NULL}, 0, 0, S_NULL}, // S_CEZPOLE + + {SPR_BANR, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_CEZBANNER + + {SPR_PINE, 0, -1, {NULL}, 0, 0, S_NULL}, // S_PINETREE + {SPR_CEZB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZBUSH1 + {SPR_CEZB, 1, -1, {NULL}, 0, 0, S_NULL}, // S_CEZBUSH2 + + {SPR_CNDL, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_CANDLE + {SPR_CNDL, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_CANDLEPRICKET + + {SPR_FLMH, 0, -1, {NULL}, 0, 0, S_NULL}, // S_FLAMEHOLDER + + {SPR_CTRC, FF_FULLBRIGHT|FF_ANIMATE, 8*3, {A_FlameParticle}, 3, 3, S_FIRETORCH}, // S_FIRETORCH + + {SPR_CFLG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_WAVINGFLAG + {SPR_CFLG, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_WAVINGFLAGSEG + + {SPR_CSTA, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CRAWLASTATUE + + {SPR_CBBS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_FACESTABBERSTATUE + + {SPR_CBBS, 0, 5, {A_Look}, 768*FRACUNIT, 0, S_SUSPICIOUSFACESTABBERSTATUE_WAIT}, // S_SUSPICIOUSFACESTABBERSTATUE_WAIT + {SPR_CBBS, FF_ANIMATE, 23, {NULL}, 6, 1, S_SUSPICIOUSFACESTABBERSTATUE_BURST2}, // S_SUSPICIOUSFACESTABBERSTATUE_BURST1 + {SPR_NULL, 0, 40, {A_StatueBurst}, MT_FACESTABBER, S_FACESTABBER_CHARGE2, S_NULL}, // S_SUSPICIOUSFACESTABBERSTATUE_BURST2 + + {SPR_CABR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BRAMBLES // Big Tumbleweed - {SPR_BTBL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BIGTUMBLEWEED - {SPR_BTBL, 0, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL2}, // S_BIGTUMBLEWEED_ROLL1 - {SPR_BTBL, 1, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL3}, // S_BIGTUMBLEWEED_ROLL2 - {SPR_BTBL, 2, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL4}, // S_BIGTUMBLEWEED_ROLL3 - {SPR_BTBL, 3, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL5}, // S_BIGTUMBLEWEED_ROLL4 - {SPR_BTBL, 4, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL6}, // S_BIGTUMBLEWEED_ROLL5 - {SPR_BTBL, 5, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL7}, // S_BIGTUMBLEWEED_ROLL6 - {SPR_BTBL, 6, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL8}, // S_BIGTUMBLEWEED_ROLL7 - {SPR_BTBL, 7, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL1}, // S_BIGTUMBLEWEED_ROLL8 + {SPR_BTBL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BIGTUMBLEWEED + {SPR_BTBL, 0, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL2}, // S_BIGTUMBLEWEED_ROLL1 + {SPR_BTBL, 1, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL3}, // S_BIGTUMBLEWEED_ROLL2 + {SPR_BTBL, 2, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL4}, // S_BIGTUMBLEWEED_ROLL3 + {SPR_BTBL, 3, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL5}, // S_BIGTUMBLEWEED_ROLL4 + {SPR_BTBL, 4, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL6}, // S_BIGTUMBLEWEED_ROLL5 + {SPR_BTBL, 5, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL7}, // S_BIGTUMBLEWEED_ROLL6 + {SPR_BTBL, 6, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL8}, // S_BIGTUMBLEWEED_ROLL7 + {SPR_BTBL, 7, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL1}, // S_BIGTUMBLEWEED_ROLL8 // Little Tumbleweed {SPR_STBL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_LITTLETUMBLEWEED @@ -1432,53 +2365,116 @@ state_t states[NUMSTATES] = {SPR_CACT, 1, -1, {NULL}, 0, 0, S_NULL}, // S_CACTI2 {SPR_CACT, 2, -1, {NULL}, 0, 0, S_NULL}, // S_CACTI3 {SPR_CACT, 3, -1, {NULL}, 0, 0, S_NULL}, // S_CACTI4 + {SPR_CACT, 4, -1, {NULL}, 0, 0, S_NULL}, // S_CACTI5 + {SPR_CACT, 5, -1, {NULL}, 0, 0, S_NULL}, // S_CACTI6 + {SPR_CACT, 6, -1, {NULL}, 0, 0, S_NULL}, // S_CACTI7 + {SPR_CACT, 7, -1, {NULL}, 0, 0, S_NULL}, // S_CACTI8 + {SPR_CACT, 8, -1, {NULL}, 0, 0, S_NULL}, // S_CACTI9 + + // Warning Signs + {SPR_WWSG, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_ARIDSIGN_CAUTION + {SPR_WWS2, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_ARIDSIGN_CACTI + {SPR_WWS3, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_ARIDSIGN_SHARPTURN + + // Oil lamp + {SPR_OILL, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_OILLAMP + {SPR_OILF, FF_TRANS90|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_OILLAMPFLARE + + // TNT barrel + {SPR_BARR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_TNTBARREL_STND1 + {SPR_BARX, 0|FF_FULLBRIGHT, 3, {A_SetObjectFlags}, MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP, 0, S_TNTBARREL_EXPL2}, // S_TNTBARREL_EXPL1 + {SPR_BARX, 1|FF_FULLBRIGHT, 2, {A_TNTExplode}, MT_TNTDUST, 0, S_TNTBARREL_EXPL3}, // S_TNTBARREL_EXPL2 + {SPR_BARX, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_TNTBARREL_EXPL4}, // S_TNTBARREL_EXPL3 + {SPR_BARX, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL5}, // S_TNTBARREL_EXPL4 + {SPR_BARX, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL6}, // S_TNTBARREL_EXPL5 + {SPR_NULL, 0, 35, {NULL}, 0, 0, S_NULL}, // S_TNTBARREL_EXPL6 + {SPR_BARR, 1|FF_ANIMATE, -1, {NULL}, 7, 2, S_NULL}, // S_TNTBARREL_FLYING + + // TNT proximity shell + {SPR_REMT, 0, 10, {A_Look}, 33554433, 0, S_PROXIMITY_TNT}, // S_PROXIMITY_TNT + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER2}, // S_PROXIMITY_TNT_TRIGGER1 + {SPR_REMT, 0, 16, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER3}, // S_PROXIMITY_TNT_TRIGGER2 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER4}, // S_PROXIMITY_TNT_TRIGGER3 + {SPR_REMT, 0, 16, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER5}, // S_PROXIMITY_TNT_TRIGGER4 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER6}, // S_PROXIMITY_TNT_TRIGGER5 + {SPR_REMT, 0, 4, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER7}, // S_PROXIMITY_TNT_TRIGGER6 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER8}, // S_PROXIMITY_TNT_TRIGGER7 + {SPR_REMT, 0, 4, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER9}, // S_PROXIMITY_TNT_TRIGGER8 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER10}, // S_PROXIMITY_TNT_TRIGGER9 + {SPR_REMT, 0, 4, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER11}, // S_PROXIMITY_TNT_TRIGGER10 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER12}, // S_PROXIMITY_TNT_TRIGGER11 + {SPR_REMT, 0, 4, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER13}, // S_PROXIMITY_TNT_TRIGGER12 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER14}, // S_PROXIMITY_TNT_TRIGGER13 + {SPR_REMT, 0, 2, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER15}, // S_PROXIMITY_TNT_TRIGGER14 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER16}, // S_PROXIMITY_TNT_TRIGGER15 + {SPR_REMT, 0, 2, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER17}, // S_PROXIMITY_TNT_TRIGGER16 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER18}, // S_PROXIMITY_TNT_TRIGGER17 + {SPR_REMT, 0, 2, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER19}, // S_PROXIMITY_TNT_TRIGGER18 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER20}, // S_PROXIMITY_TNT_TRIGGER19 + {SPR_REMT, 0, 2, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER21}, // S_PROXIMITY_TNT_TRIGGER20 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER22}, // S_PROXIMITY_TNT_TRIGGER21 + {SPR_REMT, 0, 2, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER23}, // S_PROXIMITY_TNT_TRIGGER22 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_TNTBARREL_EXPL1}, // S_PROXIMITY_TNT_TRIGGER23 + + // Dust devil + {SPR_NULL, 0, 1, {A_DustDevilThink}, 0, 0, S_DUSTDEVIL}, //S_DUSTDEVIL + {SPR_TAZD, 1|FF_PAPERSPRITE|FF_TRANS70, 2 * TICRATE, {NULL}, 0, 0, S_DUSTLAYER2}, // S_DUSTLAYER1 + {SPR_TAZD, 1|FF_PAPERSPRITE|FF_TRANS70, 5, {NULL}, 0, 0, S_DUSTLAYER3}, // S_DUSTLAYER2 + {SPR_TAZD, 1|FF_PAPERSPRITE|FF_TRANS80, 5, {NULL}, 0, 0, S_DUSTLAYER4}, // S_DUSTLAYER3 + {SPR_TAZD, 1|FF_PAPERSPRITE|FF_TRANS80, 5, {NULL}, 0, 0, S_DUSTLAYER5}, // S_DUSTLAYER4 + {SPR_TAZD, 1|FF_PAPERSPRITE|FF_TRANS90, 5, {NULL}, 0, 0, S_NULL}, // S_DUSTLAYER5 + {SPR_ADST, 0|FF_ANIMATE, 24, {NULL}, 3, 8, S_NULL}, // S_ARIDDUST1 + {SPR_ADST, 3|FF_ANIMATE, 24, {NULL}, 3, 8, S_NULL}, // S_ARIDDUST2 + {SPR_ADST, 6|FF_ANIMATE, 24, {NULL}, 3, 8, S_NULL}, // S_ARIDDUST3 + + // Minecart + {SPR_NULL, 0, 1, {NULL}, 0, 0, S_MINECART_IDLE}, // S_MINECART_IDLE + {SPR_NULL, 0, 0, {A_KillSegments}, 0, 0, S_TNTBARREL_EXPL3}, // S_MINECART_DTH1 + {SPR_MCRT, 8|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTEND + {SPR_MCRT, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTSEG_FRONT + {SPR_MCRT, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTSEG_BACK + {SPR_MCRT, 2|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 2, 3, S_NULL}, // S_MINECARTSEG_LEFT + {SPR_MCRT, 5|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 2, 3, S_NULL}, // S_MINECARTSEG_RIGHT + {SPR_LCKN, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_MINECARTSIDEMARK1 + {SPR_LCKN, 0|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_MINECARTSIDEMARK2 + {SPR_MCSP, FF_FULLBRIGHT, 1, {A_MinecartSparkThink}, 0, 0, S_MINECARTSPARK}, // S_MINECARTSPARK + + // Saloon door + {SPR_SALD, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SALOONDOOR + {SPR_NON2, 0, -1, {A_SaloonDoorSpawn}, 0, 0, S_NULL}, // S_SALONDOORTHINKER + + // Train cameo + {SPR_NULL, 0, -1, {NULL}, 0, 0, S_TRAINCAMEOSPAWNER_2}, // S_TRAINCAMEOSPAWNER_1 + {SPR_NULL, 0, 14, {A_TrainCameo}, 20, 18, S_TRAINCAMEOSPAWNER_3}, // S_TRAINCAMEOSPAWNER_2 + {SPR_NULL, 0, 1, {A_Repeat}, 1, 0, S_TRAINCAMEOSPAWNER_4}, // S_TRAINCAMEOSPAWNER_3 + {SPR_NULL, 0, 18, {A_TrainCameo2}, 20, 44, S_TRAINCAMEOSPAWNER_5}, // S_TRAINCAMEOSPAWNER_4 + {SPR_NULL, 0, 1, {A_Repeat}, 5, S_TRAINCAMEOSPAWNER_4, S_NULL}, // S_TRAINCAMEOSPAWNER_5 + {SPR_NULL, 0, 2, {A_SmokeTrailer}, MT_SMOKE, 0, S_TRAINPUFFMAKER}, // S_TRAINPUFFMAKER + + {SPR_ADST, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_TRAINDUST + {SPR_STEA, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_TRAINSTEAM // Flame jet {SPR_NULL, 0, 2*TICRATE, {NULL}, 0, 0, S_FLAMEJETSTART}, // S_FLAMEJETSTND {SPR_NULL, 0, 3*TICRATE, {A_ToggleFlameJet}, 0, 0, S_FLAMEJETSTOP}, // S_FLAMEJETSTART {SPR_NULL, 0, 1, {A_ToggleFlameJet}, 0, 0, S_FLAMEJETSTND}, // S_FLAMEJETSTOP - {SPR_FLME, FF_TRANS50 , 4, {NULL}, 0, 0, S_FLAMEJETFLAME2}, // S_FLAMEJETFLAME1 - {SPR_FLME, FF_TRANS60|1, 5, {NULL}, 0, 0, S_FLAMEJETFLAME3}, // S_FLAMEJETFLAME2 - {SPR_FLME, FF_TRANS70|2, 11, {NULL}, 0, 0, S_NULL}, // S_FLAMEJETFLAME3 + {SPR_FLME, FF_FULLBRIGHT , 4, {NULL}, 0, 0, S_FLAMEJETFLAME2}, // S_FLAMEJETFLAME1 + {SPR_FLME, FF_FULLBRIGHT|1, 5, {NULL}, 0, 0, S_FLAMEJETFLAME3}, // S_FLAMEJETFLAME2 + {SPR_FLME, FF_FULLBRIGHT|2, 11, {NULL}, 0, 0, S_NULL}, // S_FLAMEJETFLAME3 // Spinning flame jets // A: Counter-clockwise - {SPR_NULL, 0, 1, {NULL}, 0, 0, S_FJSPINAXISA2}, // S_FJSPINAXISA1 - {SPR_NULL, 0, 1, {A_Thrust}, 10, 1, S_FJSPINAXISA3}, // S_FJSPINAXISA2 - {SPR_NULL, 0, 0, {A_Thrust}, 0, 1, S_FJSPINAXISA4}, // S_FJSPINAXISA3 - {SPR_NULL, 0, 0, {A_SpawnObjectRelative}, 0, MT_FJSPINHELPERA, S_FJSPINAXISA5}, // S_FJSPINAXISA4 - {SPR_NULL, 0, 2, {A_FindTarget}, MT_FJSPINHELPERA, 0, S_FJSPINAXISA6}, // S_FJSPINAXISA5 - {SPR_NULL, 0, 1, {A_Thrust}, -10, 1, S_FJSPINAXISA7}, // S_FJSPINAXISA6 - {SPR_NULL, 0, 1, {A_Thrust}, 0, 1, S_FJSPINAXISA8}, // S_FJSPINAXISA7 - {SPR_NULL, 0, 0, {A_FireShot}, MT_FLAMEJETFLAMEB, -64, S_FJSPINAXISA9}, // S_FJSPINAXISA8 - {SPR_NULL, 0, 3, {A_ChangeAngleRelative}, 6, 6, S_FJSPINAXISA8}, // S_FJSPINAXISA9 - - {SPR_NULL, 0, 1, {NULL}, 0, 0, S_FJSPINHELPERA2}, // S_FJSPINHELPERA1 - {SPR_NULL, 0, 0, {A_FindTarget}, MT_FJSPINAXISA, 0, S_FJSPINHELPERA3}, // S_FJSPINHELPERA2 - {SPR_NULL, 0, 1, {A_CapeChase}, 0, (64<<16), S_FJSPINHELPERA3}, // S_FJSPINHELPERA3 + {SPR_NULL, 0, 1, {A_TrapShot}, MT_FLAMEJETFLAMEB, -(16<<16)|(1<<15)|64, S_FJSPINAXISA2}, // S_FJSPINAXISA1 + {SPR_NULL, 0, 2, {A_ChangeAngleRelative}, 6, 6, S_FJSPINAXISA1}, // S_FJSPINAXISA2 // B: Clockwise - {SPR_NULL, 0, 1, {NULL}, 0, 0, S_FJSPINAXISB2}, // S_FJSPINAXISB1 - {SPR_NULL, 0, 1, {A_Thrust}, 10, 1, S_FJSPINAXISB3}, // S_FJSPINAXISB2 - {SPR_NULL, 0, 0, {A_Thrust}, 0, 1, S_FJSPINAXISB4}, // S_FJSPINAXISB3 - {SPR_NULL, 0, 0, {A_SpawnObjectRelative}, 0, MT_FJSPINHELPERB, S_FJSPINAXISB5}, // S_FJSPINAXISB4 - {SPR_NULL, 0, 2, {A_FindTarget}, MT_FJSPINHELPERB, 0, S_FJSPINAXISB6}, // S_FJSPINAXISB5 - {SPR_NULL, 0, 1, {A_Thrust}, -10, 1, S_FJSPINAXISB7}, // S_FJSPINAXISB6 - {SPR_NULL, 0, 1, {A_Thrust}, 0, 1, S_FJSPINAXISB8}, // S_FJSPINAXISB7 - {SPR_NULL, 0, 0, {A_FireShot}, MT_FLAMEJETFLAMEB, -64, S_FJSPINAXISB9}, // S_FJSPINAXISB8 - {SPR_NULL, 0, 3, {A_ChangeAngleRelative}, -6, -6, S_FJSPINAXISB8}, // S_FJSPINAXISB9 - - {SPR_NULL, 0, 1, {NULL}, 0, 0, S_FJSPINHELPERB2}, // S_FJSPINHELPERB1 - {SPR_NULL, 0, 0, {A_FindTarget}, MT_FJSPINAXISB, 0, S_FJSPINHELPERB3}, // S_FJSPINHELPERB2 - {SPR_NULL, 0, 1, {A_CapeChase}, 0, (64<<16), S_FJSPINHELPERB3}, // S_FJSPINHELPERB3 + {SPR_NULL, 0, 1, {A_TrapShot}, MT_FLAMEJETFLAMEB, -(16<<16)|(1<<15)|64, S_FJSPINAXISB2}, // S_FJSPINAXISB1 + {SPR_NULL, 0, 2, {A_ChangeAngleRelative}, -6, -6, S_FJSPINAXISB1}, // S_FJSPINAXISB2 // Blade's flame - {SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40|1, 1, {A_MoveRelative}, 0, 5, S_FLAMEJETFLAMEB2}, // S_FLAMEJETFLAMEB1 - {SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40|2, 1, {A_MoveRelative}, 0, 7, S_FLAMEJETFLAMEB3}, // S_FLAMEJETFLAMEB2 - {SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40|3,24, {NULL}, 0, 0, S_FLAMEJETFLAMEB4}, // S_FLAMEJETFLAMEB3 - {SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40|4,24, {NULL}, 0, 0, S_FLAMEJETFLAMEB5}, // S_FLAMEJETFLAMEB4 - {SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40|5,24, {NULL}, 0, 0, S_FLAMEJETFLAMEB6}, // S_FLAMEJETFLAMEB5 - {SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40|6,12, {NULL}, 0, 0, S_NULL}, // S_FLAMEJETFLAMEB6 + {SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40, 1, {A_MoveRelative}, 0, 5, S_FLAMEJETFLAMEB2}, // S_FLAMEJETFLAMEB1 + {SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40, 1, {A_MoveRelative}, 0, 7, S_FLAMEJETFLAMEB3}, // S_FLAMEJETFLAMEB2 + {SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40|FF_ANIMATE, (12*7), {NULL}, 7, 12, S_NULL}, // S_FLAMEJETFLAMEB3 // Trapgoyles {SPR_GARG, 0, 67, {NULL}, 0, 0, S_TRAPGOYLE_CHECK}, // S_TRAPGOYLE @@ -1530,6 +2526,62 @@ state_t states[NUMSTATES] = {SPR_XMS1, 0, -1, {NULL}, 0, 0, S_NULL}, // S_XMASPOLE {SPR_XMS2, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CANDYCANE {SPR_XMS3, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SNOWMAN + {SPR_XMS3, 1, -1, {NULL}, 0, 0, S_NULL}, // S_SNOWMANHAT + {SPR_XMS4, 0, -1, {NULL}, 0, 0, S_NULL}, // S_LAMPPOST1 + {SPR_XMS4, 1, -1, {NULL}, 0, 0, S_NULL}, // S_LAMPPOST2 + {SPR_XMS5, 0, -1, {NULL}, 0, 0, S_NULL}, // S_HANGSTAR + // Xmas GFZ bushes + {SPR_BUS3, 1, -1, {NULL}, 0, 0, S_NULL}, // S_XMASBLUEBERRYBUSH + {SPR_BUS1, 1, -1, {NULL}, 0, 0, S_NULL}, // S_XMASBERRYBUSH + {SPR_BUS2, 1, -1, {NULL}, 0, 0, S_NULL}, // S_XMASBUSH + // FHZ + {SPR_FHZI, 0, -1, {NULL}, 0, 0, S_NULL}, // S_FHZICE1 + {SPR_FHZI, 1, -1, {NULL}, 0, 0, S_NULL}, // S_FHZICE2 + + // Halloween Scenery + // Pumpkins + {SPR_PUMK, 0, -1, {NULL}, 0, 0, S_NULL}, // S_JACKO1 + {SPR_PUMK, 3|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_JACKO1OVERLAY_2}, // S_JACKO1OVERLAY_1 + {SPR_PUMK, 4|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_JACKO1OVERLAY_3}, // S_JACKO1OVERLAY_2 + {SPR_PUMK, 5|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_JACKO1OVERLAY_4}, // S_JACKO1OVERLAY_3 + {SPR_PUMK, 4|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_JACKO1OVERLAY_1}, // S_JACKO1OVERLAY_4 + {SPR_PUMK, 1, -1, {NULL}, 0, 0, S_NULL}, // S_JACKO2 + {SPR_PUMK, 6|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_JACKO2OVERLAY_2}, // S_JACKO2OVERLAY_1 + {SPR_PUMK, 7|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_JACKO2OVERLAY_3}, // S_JACKO2OVERLAY_2 + {SPR_PUMK, 8|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_JACKO2OVERLAY_4}, // S_JACKO2OVERLAY_3 + {SPR_PUMK, 7|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_JACKO2OVERLAY_1}, // S_JACKO2OVERLAY_4 + {SPR_PUMK, 2, -1, {NULL}, 0, 0, S_NULL}, // S_JACKO3 + {SPR_PUMK, 9|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_JACKO3OVERLAY_2}, // S_JACKO3OVERLAY_1 + {SPR_PUMK, 10|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_JACKO3OVERLAY_3}, // S_JACKO3OVERLAY_2 + {SPR_PUMK, 11|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_JACKO3OVERLAY_4}, // S_JACKO3OVERLAY_3 + {SPR_PUMK, 10|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_JACKO3OVERLAY_1}, // S_JACKO3OVERLAY_4 + // Dr Seuss Trees + {SPR_HHPL, 2, -1, {A_ConnectToGround}, MT_HHZTREE_PART, 0, S_NULL}, // S_HHZTREE_TOP, + {SPR_HHPL, 1, -1, {NULL}, 0, 0, S_NULL}, // S_HHZTREE_TRUNK, + {SPR_HHPL, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_HHZTREE_LEAF, + // Mushroom + {SPR_SHRM, 4, 3, {NULL}, 0, 0, S_HHZSHROOM_2}, // S_HHZSHROOM_1, + {SPR_SHRM, 3, 3, {NULL}, 0, 0, S_HHZSHROOM_3}, // S_HHZSHROOM_2, + {SPR_SHRM, 2, 2, {NULL}, 0, 0, S_HHZSHROOM_4}, // S_HHZSHROOM_3, + {SPR_SHRM, 1, 1, {NULL}, 0, 0, S_HHZSHROOM_5}, // S_HHZSHROOM_4, + {SPR_SHRM, 0, 1, {NULL}, 0, 0, S_HHZSHROOM_6}, // S_HHZSHROOM_5, + {SPR_SHRM, 1, 4, {NULL}, 0, 0, S_HHZSHROOM_7}, // S_HHZSHROOM_6, + {SPR_SHRM, 2, 2, {NULL}, 0, 0, S_HHZSHROOM_8}, // S_HHZSHROOM_7, + {SPR_SHRM, 3, 3, {NULL}, 0, 0, S_HHZSHROOM_9}, // S_HHZSHROOM_8, + {SPR_SHRM, 4, 3, {NULL}, 0, 0, S_HHZSHROOM_10}, // S_HHZSHROOM_9, + {SPR_SHRM, 3, 3, {NULL}, 0, 0, S_HHZSHROOM_11}, // S_HHZSHROOM_10, + {SPR_SHRM, 5, 2, {NULL}, 0, 0, S_HHZSHROOM_12}, // S_HHZSHROOM_11, + {SPR_SHRM, 6, 1, {NULL}, 0, 0, S_HHZSHROOM_13}, // S_HHZSHROOM_12, + {SPR_SHRM, 7, 1, {NULL}, 0, 0, S_HHZSHROOM_14}, // S_HHZSHROOM_13, + {SPR_SHRM, 6, 4, {NULL}, 0, 0, S_HHZSHROOM_15}, // S_HHZSHROOM_14, + {SPR_SHRM, 5, 2, {NULL}, 0, 0, S_HHZSHROOM_16}, // S_HHZSHROOM_15, + {SPR_SHRM, 3, 3, {NULL}, 0, 0, S_HHZSHROOM_1}, // S_HHZSHROOM_16, + // Misc + {SPR_HHZM, 0, -1, {NULL}, 0, 0, S_NULL}, // S_HHZGRASS, + {SPR_HHZM, 1, -1, {NULL}, 0, 0, S_NULL}, // S_HHZTENT1, + {SPR_HHZM, 2, -1, {NULL}, 0, 0, S_NULL}, // S_HHZTENT2, + {SPR_HHZM, 4, -1, {NULL}, 0, 0, S_NULL}, // S_HHZSTALAGMITE_TALL, + {SPR_HHZM, 5, -1, {NULL}, 0, 0, S_NULL}, // S_HHZSTALAGMITE_SHORT, // Loads of Botanic Serenity bullshit {SPR_BSZ1, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BSZTALLFLOWER_RED @@ -1550,12 +2602,12 @@ state_t states[NUMSTATES] = {SPR_BSZ3, 3, -1, {NULL}, 0, 0, S_NULL}, // S_BSZSHORTFLOWER_CYAN {SPR_BSZ3, 4, -1, {NULL}, 0, 0, S_NULL}, // S_BSZSHORTFLOWER_YELLOW {SPR_BSZ3, 5, -1, {NULL}, 0, 0, S_NULL}, // S_BSZSHORTFLOWER_ORANGE - {SPR_BSZ4, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BSZTULIP_RED - {SPR_BSZ4, 1, -1, {NULL}, 0, 0, S_NULL}, // S_BSZTULIP_PURPLE - {SPR_BSZ4, 2, -1, {NULL}, 0, 0, S_NULL}, // S_BSZTULIP_BLUE - {SPR_BSZ4, 3, -1, {NULL}, 0, 0, S_NULL}, // S_BSZTULIP_CYAN - {SPR_BSZ4, 4, -1, {NULL}, 0, 0, S_NULL}, // S_BSZTULIP_YELLOW - {SPR_BSZ4, 5, -1, {NULL}, 0, 0, S_NULL}, // S_BSZTULIP_ORANGE + {SPR_BST1, FF_ANIMATE, -1, {NULL}, 11, 4, S_NULL}, // S_BSZTULIP_RED + {SPR_BST2, FF_ANIMATE, -1, {NULL}, 11, 4, S_NULL}, // S_BSZTULIP_PURPLE + {SPR_BST3, FF_ANIMATE, -1, {NULL}, 11, 4, S_NULL}, // S_BSZTULIP_BLUE + {SPR_BST4, FF_ANIMATE, -1, {NULL}, 11, 4, S_NULL}, // S_BSZTULIP_CYAN + {SPR_BST5, FF_ANIMATE, -1, {NULL}, 11, 4, S_NULL}, // S_BSZTULIP_YELLOW + {SPR_BST6, FF_ANIMATE, -1, {NULL}, 11, 4, S_NULL}, // S_BSZTULIP_ORANGE {SPR_BSZ5, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BSZCLUSTER_RED {SPR_BSZ5, 1, -1, {NULL}, 0, 0, S_NULL}, // S_BSZCLUSTER_PURPLE {SPR_BSZ5, 2, -1, {NULL}, 0, 0, S_NULL}, // S_BSZCLUSTER_BLUE @@ -1576,8 +2628,10 @@ state_t states[NUMSTATES] = {SPR_BSZ7, 5, -1, {NULL}, 0, 0, S_NULL}, // S_BSZVINE_ORANGE {SPR_BSZ8, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BSZSHRUB {SPR_BSZ8, 1, -1, {NULL}, 0, 0, S_NULL}, // S_BSZCLOVER - {SPR_BSZ8, 2, -1, {NULL}, 0, 0, S_NULL}, // S_BSZFISH - {SPR_BSZ8, 3, -1, {NULL}, 0, 0, S_NULL}, // S_BSZSUNFLOWER + {SPR_BSZ8, 2, -1, {NULL}, 0, 0, S_NULL}, // S_BIG_PALMTREE_TRUNK + {SPR_BSZ8, 3, -1, {A_ConnectToGround}, MT_BIG_PALMTREE_TRUNK, 0, S_NULL}, // S_BIG_PALMTREE_TOP + {SPR_BSZ8, 4, -1, {NULL}, 0, 0, S_NULL}, // S_PALMTREE_TRUNK + {SPR_BSZ8, 5, -1, {A_ConnectToGround}, MT_PALMTREE_TRUNK, 0, S_NULL}, // S_PALMTREE_TOP // Disco ball {SPR_DBAL, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_DBALL2}, // S_DBALL1 @@ -1607,39 +2661,71 @@ state_t states[NUMSTATES] = {SPR_ARMA, FF_TRANS40|14, 2, {NULL}, 0, 0, S_ARMA16}, // S_ARMA15 {SPR_ARMA, FF_TRANS40|15, 2, {NULL}, 0, 0, S_ARMA1 }, // S_ARMA16 - {SPR_ARMF, FF_FULLBRIGHT , 3, {NULL}, 0, 0, S_ARMF2 }, // S_ARMF1 - {SPR_ARMF, FF_FULLBRIGHT| 1, 3, {NULL}, 0, 0, S_ARMF3 }, // S_ARMF2 - {SPR_ARMF, FF_FULLBRIGHT| 2, 3, {NULL}, 0, 0, S_ARMF4 }, // S_ARMF3 - {SPR_ARMF, FF_FULLBRIGHT| 3, 3, {NULL}, 0, 0, S_ARMF5 }, // S_ARMF4 - {SPR_ARMF, FF_FULLBRIGHT| 4, 3, {NULL}, 0, 0, S_ARMF6 }, // S_ARMF5 - {SPR_ARMF, FF_FULLBRIGHT| 5, 3, {NULL}, 0, 0, S_ARMF7 }, // S_ARMF6 - {SPR_ARMF, FF_FULLBRIGHT| 6, 3, {NULL}, 0, 0, S_ARMF8 }, // S_ARMF7 - {SPR_ARMF, FF_FULLBRIGHT| 7, 3, {NULL}, 0, 0, S_ARMF9 }, // S_ARMF8 - {SPR_ARMF, FF_FULLBRIGHT| 8, 3, {NULL}, 0, 0, S_ARMF10}, // S_ARMF9 - {SPR_ARMF, FF_FULLBRIGHT| 9, 3, {NULL}, 0, 0, S_ARMF11}, // S_ARMF10 - {SPR_ARMF, FF_FULLBRIGHT|10, 3, {NULL}, 0, 0, S_ARMF12}, // S_ARMF11 - {SPR_ARMF, FF_FULLBRIGHT|11, 3, {NULL}, 0, 0, S_ARMF13}, // S_ARMF12 - {SPR_ARMF, FF_FULLBRIGHT|12, 3, {NULL}, 0, 0, S_ARMF14}, // S_ARMF13 - {SPR_ARMF, FF_FULLBRIGHT|13, 3, {NULL}, 0, 0, S_ARMF15}, // S_ARMF14 - {SPR_ARMF, FF_FULLBRIGHT|14, 3, {NULL}, 0, 0, S_ARMF16}, // S_ARMF15 - {SPR_ARMF, FF_FULLBRIGHT|15, 3, {NULL}, 0, 0, S_ARMF1 }, // S_ARMF16 - - {SPR_ARMB, FF_FULLBRIGHT| 0, 3, {NULL}, 1, 0, S_ARMB2 }, // S_ARMB1 - {SPR_ARMB, FF_FULLBRIGHT| 1, 3, {NULL}, 1, 0, S_ARMB3 }, // S_ARMB2 - {SPR_ARMB, FF_FULLBRIGHT| 2, 3, {NULL}, 1, 0, S_ARMB4 }, // S_ARMB3 - {SPR_ARMB, FF_FULLBRIGHT| 3, 3, {NULL}, 1, 0, S_ARMB5 }, // S_ARMB4 - {SPR_ARMB, FF_FULLBRIGHT| 4, 3, {NULL}, 1, 0, S_ARMB6 }, // S_ARMB5 - {SPR_ARMB, FF_FULLBRIGHT| 5, 3, {NULL}, 1, 0, S_ARMB7 }, // S_ARMB6 - {SPR_ARMB, FF_FULLBRIGHT| 6, 3, {NULL}, 1, 0, S_ARMB8 }, // S_ARMB7 - {SPR_ARMB, FF_FULLBRIGHT| 7, 3, {NULL}, 1, 0, S_ARMB9 }, // S_ARMB8 - {SPR_ARMB, FF_FULLBRIGHT| 8, 3, {NULL}, 1, 0, S_ARMB10}, // S_ARMB9 - {SPR_ARMB, FF_FULLBRIGHT| 9, 3, {NULL}, 1, 0, S_ARMB11}, // S_ARMB10 - {SPR_ARMB, FF_FULLBRIGHT|10, 3, {NULL}, 1, 0, S_ARMB12}, // S_ARMB11 - {SPR_ARMB, FF_FULLBRIGHT|11, 3, {NULL}, 1, 0, S_ARMB13}, // S_ARMB12 - {SPR_ARMB, FF_FULLBRIGHT|12, 3, {NULL}, 1, 0, S_ARMB14}, // S_ARMB13 - {SPR_ARMB, FF_FULLBRIGHT|13, 3, {NULL}, 1, 0, S_ARMB15}, // S_ARMB14 - {SPR_ARMB, FF_FULLBRIGHT|14, 3, {NULL}, 1, 0, S_ARMB16}, // S_ARMB15 - {SPR_ARMB, FF_FULLBRIGHT|15, 3, {NULL}, 1, 0, S_ARMB1 }, // S_ARMB16 + {SPR_ARMF, FF_FULLBRIGHT , 2, {NULL}, 0, 0, S_ARMF2 }, // S_ARMF1 + {SPR_ARMF, FF_FULLBRIGHT| 1, 2, {NULL}, 0, 0, S_ARMF3 }, // S_ARMF2 + {SPR_ARMF, FF_FULLBRIGHT| 2, 2, {NULL}, 0, 0, S_ARMF4 }, // S_ARMF3 + {SPR_ARMF, FF_FULLBRIGHT| 3, 2, {NULL}, 0, 0, S_ARMF5 }, // S_ARMF4 + {SPR_ARMF, FF_FULLBRIGHT| 4, 2, {NULL}, 0, 0, S_ARMF6 }, // S_ARMF5 + {SPR_ARMF, FF_FULLBRIGHT| 5, 2, {NULL}, 0, 0, S_ARMF7 }, // S_ARMF6 + {SPR_ARMF, FF_FULLBRIGHT| 6, 2, {NULL}, 0, 0, S_ARMF8 }, // S_ARMF7 + {SPR_ARMF, FF_FULLBRIGHT| 7, 2, {NULL}, 0, 0, S_ARMF9 }, // S_ARMF8 + {SPR_ARMF, FF_FULLBRIGHT| 8, 2, {NULL}, 0, 0, S_ARMF10}, // S_ARMF9 + {SPR_ARMF, FF_FULLBRIGHT| 9, 2, {NULL}, 0, 0, S_ARMF11}, // S_ARMF10 + {SPR_ARMF, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_ARMF12}, // S_ARMF11 + {SPR_ARMF, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_ARMF13}, // S_ARMF12 + {SPR_ARMF, FF_FULLBRIGHT|12, 2, {NULL}, 0, 0, S_ARMF14}, // S_ARMF13 + {SPR_ARMF, FF_FULLBRIGHT|13, 2, {NULL}, 0, 0, S_ARMF15}, // S_ARMF14 + {SPR_ARMF, FF_FULLBRIGHT|14, 2, {NULL}, 0, 0, S_ARMF16}, // S_ARMF15 + {SPR_ARMF, FF_FULLBRIGHT|15, 2, {NULL}, 0, 0, S_ARMF17}, // S_ARMF16 + {SPR_ARMB, FF_FULLBRIGHT , 2, {NULL}, 0, 0, S_ARMF18}, // S_ARMF17 + {SPR_ARMB, FF_FULLBRIGHT| 1, 2, {NULL}, 0, 0, S_ARMF19}, // S_ARMF18 + {SPR_ARMB, FF_FULLBRIGHT| 2, 2, {NULL}, 0, 0, S_ARMF20}, // S_ARMF19 + {SPR_ARMB, FF_FULLBRIGHT| 3, 2, {NULL}, 0, 0, S_ARMF21}, // S_ARMF20 + {SPR_ARMB, FF_FULLBRIGHT| 4, 2, {NULL}, 0, 0, S_ARMF22}, // S_ARMF21 + {SPR_ARMB, FF_FULLBRIGHT| 5, 2, {NULL}, 0, 0, S_ARMF23}, // S_ARMF22 + {SPR_ARMB, FF_FULLBRIGHT| 6, 2, {NULL}, 0, 0, S_ARMF24}, // S_ARMF23 + {SPR_ARMB, FF_FULLBRIGHT| 7, 2, {NULL}, 0, 0, S_ARMF25}, // S_ARMF24 + {SPR_ARMB, FF_FULLBRIGHT| 8, 2, {NULL}, 0, 0, S_ARMF26}, // S_ARMF25 + {SPR_ARMB, FF_FULLBRIGHT| 9, 2, {NULL}, 0, 0, S_ARMF27}, // S_ARMF26 + {SPR_ARMB, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_ARMF28}, // S_ARMF27 + {SPR_ARMB, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_ARMF29}, // S_ARMF28 + {SPR_ARMB, FF_FULLBRIGHT|12, 2, {NULL}, 0, 0, S_ARMF30}, // S_ARMF29 + {SPR_ARMB, FF_FULLBRIGHT|13, 2, {NULL}, 0, 0, S_ARMF31}, // S_ARMF30 + {SPR_ARMB, FF_FULLBRIGHT|14, 2, {NULL}, 0, 0, S_ARMF32}, // S_ARMF31 + {SPR_ARMB, FF_FULLBRIGHT|15, 2, {NULL}, 0, 0, S_ARMF1 }, // S_ARMF32 + + {SPR_ARMB, FF_FULLBRIGHT , 2, {NULL}, 1, 0, S_ARMB2 }, // S_ARMB1 + {SPR_ARMB, FF_FULLBRIGHT| 1, 2, {NULL}, 1, 0, S_ARMB3 }, // S_ARMB2 + {SPR_ARMB, FF_FULLBRIGHT| 2, 2, {NULL}, 1, 0, S_ARMB4 }, // S_ARMB3 + {SPR_ARMB, FF_FULLBRIGHT| 3, 2, {NULL}, 1, 0, S_ARMB5 }, // S_ARMB4 + {SPR_ARMB, FF_FULLBRIGHT| 4, 2, {NULL}, 1, 0, S_ARMB6 }, // S_ARMB5 + {SPR_ARMB, FF_FULLBRIGHT| 5, 2, {NULL}, 1, 0, S_ARMB7 }, // S_ARMB6 + {SPR_ARMB, FF_FULLBRIGHT| 6, 2, {NULL}, 1, 0, S_ARMB8 }, // S_ARMB7 + {SPR_ARMB, FF_FULLBRIGHT| 7, 2, {NULL}, 1, 0, S_ARMB9 }, // S_ARMB8 + {SPR_ARMB, FF_FULLBRIGHT| 8, 2, {NULL}, 1, 0, S_ARMB10}, // S_ARMB9 + {SPR_ARMB, FF_FULLBRIGHT| 9, 2, {NULL}, 1, 0, S_ARMB11}, // S_ARMB10 + {SPR_ARMB, FF_FULLBRIGHT|10, 2, {NULL}, 1, 0, S_ARMB12}, // S_ARMB11 + {SPR_ARMB, FF_FULLBRIGHT|11, 2, {NULL}, 1, 0, S_ARMB13}, // S_ARMB12 + {SPR_ARMB, FF_FULLBRIGHT|12, 2, {NULL}, 1, 0, S_ARMB14}, // S_ARMB13 + {SPR_ARMB, FF_FULLBRIGHT|13, 2, {NULL}, 1, 0, S_ARMB15}, // S_ARMB14 + {SPR_ARMB, FF_FULLBRIGHT|14, 2, {NULL}, 1, 0, S_ARMB16}, // S_ARMB15 + {SPR_ARMB, FF_FULLBRIGHT|15, 2, {NULL}, 1, 0, S_ARMB17}, // S_ARMB16 + {SPR_ARMF, FF_FULLBRIGHT , 2, {NULL}, 1, 0, S_ARMB18}, // S_ARMB17 + {SPR_ARMF, FF_FULLBRIGHT| 1, 2, {NULL}, 1, 0, S_ARMB19}, // S_ARMB18 + {SPR_ARMF, FF_FULLBRIGHT| 2, 2, {NULL}, 1, 0, S_ARMB20}, // S_ARMB19 + {SPR_ARMF, FF_FULLBRIGHT| 3, 2, {NULL}, 1, 0, S_ARMB21}, // S_ARMB20 + {SPR_ARMF, FF_FULLBRIGHT| 4, 2, {NULL}, 1, 0, S_ARMB22}, // S_ARMB21 + {SPR_ARMF, FF_FULLBRIGHT| 5, 2, {NULL}, 1, 0, S_ARMB23}, // S_ARMB22 + {SPR_ARMF, FF_FULLBRIGHT| 6, 2, {NULL}, 1, 0, S_ARMB24}, // S_ARMB23 + {SPR_ARMF, FF_FULLBRIGHT| 7, 2, {NULL}, 1, 0, S_ARMB25}, // S_ARMB24 + {SPR_ARMF, FF_FULLBRIGHT| 8, 2, {NULL}, 1, 0, S_ARMB26}, // S_ARMB25 + {SPR_ARMF, FF_FULLBRIGHT| 9, 2, {NULL}, 1, 0, S_ARMB27}, // S_ARMB26 + {SPR_ARMF, FF_FULLBRIGHT|10, 2, {NULL}, 1, 0, S_ARMB28}, // S_ARMB27 + {SPR_ARMF, FF_FULLBRIGHT|11, 2, {NULL}, 1, 0, S_ARMB29}, // S_ARMB28 + {SPR_ARMF, FF_FULLBRIGHT|12, 2, {NULL}, 1, 0, S_ARMB30}, // S_ARMB29 + {SPR_ARMF, FF_FULLBRIGHT|13, 2, {NULL}, 1, 0, S_ARMB31}, // S_ARMB30 + {SPR_ARMF, FF_FULLBRIGHT|14, 2, {NULL}, 1, 0, S_ARMB32}, // S_ARMB31 + {SPR_ARMF, FF_FULLBRIGHT|15, 2, {NULL}, 1, 0, S_ARMB1 }, // S_ARMB32 {SPR_WIND, FF_TRANS70 , 2, {NULL}, 0, 0, S_WIND2}, // S_WIND1 {SPR_WIND, FF_TRANS70|1, 2, {NULL}, 0, 0, S_WIND3}, // S_WIND2 @@ -1663,6 +2749,8 @@ state_t states[NUMSTATES] = {SPR_MAGN, FF_FULLBRIGHT|FF_TRANS40|10, 2, {NULL}, 0, 0, S_MAGN12}, // S_MAGN11 {SPR_MAGN, FF_FULLBRIGHT|FF_TRANS40|11, 2, {NULL}, 0, 0, S_MAGN1 }, // S_MAGN12 + {SPR_MAGN, FF_FULLBRIGHT|FF_TRANS10|12, 2, {NULL}, 0, 0, S_MAGN1 }, // S_MAGN13 + {SPR_FORC, FF_TRANS50 , 3, {NULL}, 0, 0, S_FORC2 }, // S_FORC1 {SPR_FORC, FF_TRANS50|1, 3, {NULL}, 0, 0, S_FORC3 }, // S_FORC2 {SPR_FORC, FF_TRANS50|2, 3, {NULL}, 0, 0, S_FORC4 }, // S_FORC3 @@ -1685,6 +2773,8 @@ state_t states[NUMSTATES] = {SPR_FORC, FF_TRANS50|18, 3, {NULL}, 0, 0, S_FORC20}, // S_FORC19 {SPR_FORC, FF_TRANS50|19, 3, {NULL}, 0, 0, S_FORC11}, // S_FORC20 + {SPR_FORC, FF_TRANS50|20, -1, {NULL}, 0, 0, S_NULL}, // S_FORC21 + {SPR_ELEM, FF_TRANS50 , 4, {NULL}, 0, 0, S_ELEM2 }, // S_ELEM1 {SPR_ELEM, FF_TRANS50| 1, 4, {NULL}, 0, 0, S_ELEM3 }, // S_ELEM2 {SPR_ELEM, FF_TRANS50| 2, 4, {NULL}, 0, 0, S_ELEM4 }, // S_ELEM3 @@ -1698,25 +2788,105 @@ state_t states[NUMSTATES] = {SPR_ELEM, FF_TRANS50|10, 4, {NULL}, 0, 0, S_ELEM12}, // S_ELEM11 {SPR_ELEM, FF_TRANS50|11, 4, {NULL}, 0, 0, S_ELEM1 }, // S_ELEM12 - {SPR_ELEM, FF_FULLBRIGHT|12, 3, {NULL}, 0, 0, S_ELEMF2}, // S_ELEMF1 - {SPR_ELEM, FF_FULLBRIGHT|13, 3, {NULL}, 0, 0, S_ELEMF3}, // S_ELEMF2 - {SPR_ELEM, FF_FULLBRIGHT|14, 3, {NULL}, 0, 0, S_ELEMF4}, // S_ELEMF3 - {SPR_ELEM, FF_FULLBRIGHT|15, 3, {NULL}, 0, 0, S_ELEMF5}, // S_ELEMF4 - {SPR_ELEM, FF_FULLBRIGHT|16, 3, {NULL}, 0, 0, S_ELEMF6}, // S_ELEMF5 - {SPR_ELEM, FF_FULLBRIGHT|17, 3, {NULL}, 0, 0, S_ELEMF7}, // S_ELEMF6 - {SPR_ELEM, FF_FULLBRIGHT|18, 3, {NULL}, 0, 0, S_ELEMF8}, // S_ELEMF7 - {SPR_ELEM, FF_FULLBRIGHT|19, 3, {NULL}, 0, 0, S_ELEMF1}, // S_ELEMF8 - - {SPR_PITY, FF_TRANS20 , 1, {NULL}, 0, 0, S_PITY2 }, // S_PITY1 - {SPR_PITY, FF_TRANS20|1, 1, {NULL}, 0, 0, S_PITY3 }, // S_PITY2 - {SPR_PITY, FF_TRANS20 , 1, {NULL}, 0, 0, S_PITY4 }, // S_PITY3 - {SPR_PITY, FF_TRANS20|2, 1, {NULL}, 0, 0, S_PITY5 }, // S_PITY4 - {SPR_PITY, FF_TRANS20 , 1, {NULL}, 0, 0, S_PITY6 }, // S_PITY5 - {SPR_PITY, FF_TRANS20|3, 1, {NULL}, 0, 0, S_PITY7 }, // S_PITY6 - {SPR_PITY, FF_TRANS20 , 1, {NULL}, 0, 0, S_PITY8 }, // S_PITY7 - {SPR_PITY, FF_TRANS20|4, 1, {NULL}, 0, 0, S_PITY9 }, // S_PITY8 - {SPR_PITY, FF_TRANS20 , 1, {NULL}, 0, 0, S_PITY10}, // S_PITY9 - {SPR_PITY, FF_TRANS20|5, 1, {NULL}, 0, 0, S_PITY1 }, // S_PITY10 + {SPR_NULL, 0, 1, {NULL}, 0, 0, S_ELEM14}, // S_ELEM13 + {SPR_ELEM, FF_TRANS50|11, 1, {NULL}, 0, 0, S_ELEM1 }, // S_ELEM14 + + {SPR_ELEM, FF_FULLBRIGHT|12, 3, {NULL}, 0, 0, S_ELEMF2 }, // S_ELEMF1 + {SPR_ELEM, FF_FULLBRIGHT|13, 3, {NULL}, 0, 0, S_ELEMF3 }, // S_ELEMF2 + {SPR_ELEM, FF_FULLBRIGHT|14, 3, {NULL}, 0, 0, S_ELEMF4 }, // S_ELEMF3 + {SPR_ELEM, FF_FULLBRIGHT|15, 3, {NULL}, 0, 0, S_ELEMF5 }, // S_ELEMF4 + {SPR_ELEM, FF_FULLBRIGHT|16, 3, {NULL}, 0, 0, S_ELEMF6 }, // S_ELEMF5 + {SPR_ELEM, FF_FULLBRIGHT|17, 3, {NULL}, 0, 0, S_ELEMF7 }, // S_ELEMF6 + {SPR_ELEM, FF_FULLBRIGHT|18, 3, {NULL}, 0, 0, S_ELEMF8 }, // S_ELEMF7 + {SPR_ELEM, FF_FULLBRIGHT|19, 3, {NULL}, 0, 0, S_ELEMF1 }, // S_ELEMF8 + + {SPR_ELEM, FF_FULLBRIGHT|20, 1, {NULL}, 0, 0, S_ELEMF10}, // S_ELEMF9 + {SPR_NULL, 0, 1, {NULL}, 0, 0, S_ELEMF1 }, // S_ELEMF10 + + {SPR_PITY, FF_TRANS30 , 2, {NULL}, 0, 0, S_PITY2}, // S_PITY1 + {SPR_PITY, FF_TRANS30|1, 2, {NULL}, 0, 0, S_PITY3}, // S_PITY2 + {SPR_PITY, FF_TRANS30|2, 2, {NULL}, 0, 0, S_PITY4}, // S_PITY3 + {SPR_PITY, FF_TRANS20|3, 2, {NULL}, 0, 0, S_PITY5}, // S_PITY4 + {SPR_PITY, FF_TRANS30|4, 2, {NULL}, 0, 0, S_PITY6}, // S_PITY5 + {SPR_PITY, FF_TRANS20|5, 2, {NULL}, 0, 0, S_PITY1}, // S_PITY6 + + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40 , 2, {NULL}, 0, 0, S_FIRS2}, // S_FIRS1 + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|1, 2, {NULL}, 0, 0, S_FIRS3}, // S_FIRS2 + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|2, 2, {NULL}, 0, 0, S_FIRS4}, // S_FIRS3 + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|3, 2, {NULL}, 0, 0, S_FIRS5}, // S_FIRS4 + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|4, 2, {NULL}, 0, 0, S_FIRS6}, // S_FIRS5 + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|5, 2, {NULL}, 0, 0, S_FIRS7}, // S_FIRS6 + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|6, 2, {NULL}, 0, 0, S_FIRS8}, // S_FIRS7 + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|7, 2, {NULL}, 0, 0, S_FIRS9}, // S_FIRS8 + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|8, 2, {NULL}, 0, 0, S_FIRS1}, // S_FIRS9 + + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|18, 1, {NULL}, 0, 0, S_FIRS11}, // S_FIRS10 + {SPR_NULL, 0, 1, {NULL}, 0, 0, S_FIRS1 }, // S_FIRS11 + + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40| 9, 2, {NULL}, 0, 0, S_FIRSB2}, // S_FIRSB1 + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|10, 2, {NULL}, 0, 0, S_FIRSB3}, // S_FIRSB2 + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|11, 2, {NULL}, 0, 0, S_FIRSB4}, // S_FIRSB3 + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|12, 2, {NULL}, 0, 0, S_FIRSB5}, // S_FIRSB4 + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|13, 2, {NULL}, 0, 0, S_FIRSB6}, // S_FIRSB5 + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|14, 2, {NULL}, 0, 0, S_FIRSB7}, // S_FIRSB6 + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|15, 2, {NULL}, 0, 0, S_FIRSB8}, // S_FIRSB7 + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|16, 2, {NULL}, 0, 0, S_FIRSB9}, // S_FIRSB8 + {SPR_FIRS, FF_FULLBRIGHT|FF_TRANS40|17, 2, {NULL}, 0, 0, S_FIRSB1}, // S_FIRSB9 + + {SPR_NULL, 0, 2, {NULL}, 0, 0, S_FIRSB1 }, // S_FIRSB10 + + {SPR_BUBS, FF_TRANS30 , 3, {NULL}, 0, 0, S_BUBS2}, // S_BUBS1 + {SPR_BUBS, FF_TRANS30|1, 3, {NULL}, 0, 0, S_BUBS3}, // S_BUBS2 + {SPR_BUBS, FF_TRANS30|2, 3, {NULL}, 0, 0, S_BUBS4}, // S_BUBS3 + {SPR_BUBS, FF_TRANS30|3, 3, {NULL}, 0, 0, S_BUBS5}, // S_BUBS4 + {SPR_BUBS, FF_TRANS30|4, 3, {NULL}, 0, 0, S_BUBS6}, // S_BUBS5 + {SPR_BUBS, FF_TRANS30|5, 3, {NULL}, 0, 0, S_BUBS7}, // S_BUBS6 + {SPR_BUBS, FF_TRANS30|6, 3, {NULL}, 0, 0, S_BUBS8}, // S_BUBS7 + {SPR_BUBS, FF_TRANS30|7, 3, {NULL}, 0, 0, S_BUBS9}, // S_BUBS8 + {SPR_BUBS, FF_TRANS30|8, 3, {NULL}, 0, 0, S_BUBS1}, // S_BUBS9 + + {SPR_NULL, 0, 3, {NULL}, 0, 0, S_BUBS1}, // S_BUBS10 + {SPR_NULL, 0, 4*3, {NULL}, 0, 0, S_BUBS1}, // S_BUBS11 + + {SPR_BUBS, FF_TRANS30| 9, 3, {NULL}, 0, 0, S_BUBSB2}, // S_BUBSB1 + {SPR_BUBS, FF_TRANS30|10, 3, {NULL}, 0, 0, S_BUBSB3}, // S_BUBSB2 + {SPR_BUBS, FF_TRANS30|11, 3, {NULL}, 0, 0, S_BUBSB4}, // S_BUBSB3 + {SPR_BUBS, FF_TRANS30|10, 3, {NULL}, 0, 0, S_BUBSB1}, // S_BUBSB4 + + {SPR_BUBS, FF_TRANS30|12, 3, {NULL}, 0, 0, S_BUBSB3}, // S_BUBSB5 + {SPR_BUBS, FF_TRANS30|13, 3, {NULL}, 0, 0, S_BUBSB5}, // S_BUBSB6 + + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20 , 2, {NULL}, 0, 0, S_ZAPS2 }, // S_ZAPS1 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 1, 2, {NULL}, 0, 0, S_ZAPS3 }, // S_ZAPS2 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 2, 2, {NULL}, 0, 0, S_ZAPS4 }, // S_ZAPS3 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 3, 2, {NULL}, 0, 0, S_ZAPS5 }, // S_ZAPS4 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 4, 2, {NULL}, 0, 0, S_ZAPS6 }, // S_ZAPS5 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 5, 2, {NULL}, 0, 0, S_ZAPS7 }, // S_ZAPS6 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 6, 2, {NULL}, 0, 0, S_ZAPS8 }, // S_ZAPS7 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 7, 2, {NULL}, 0, 0, S_ZAPS9 }, // S_ZAPS8 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 8, 2, {NULL}, 0, 0, S_ZAPS10}, // S_ZAPS9 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 9, 2, {NULL}, 0, 0, S_ZAPS11}, // S_ZAPS10 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20|10, 2, {NULL}, 0, 0, S_ZAPS12}, // S_ZAPS11 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20|11, 2, {NULL}, 0, 0, S_ZAPS13}, // S_ZAPS12 + {SPR_NULL, 0, 9*2, {NULL}, 0, 0, S_ZAPS14}, // S_ZAPS13 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 9, 2, {NULL}, 0, 0, S_ZAPS15}, // S_ZAPS14 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20|10, 2, {NULL}, 0, 0, S_ZAPS16}, // S_ZAPS15 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20|11, 2, {NULL}, 0, 0, S_ZAPS1 }, // S_ZAPS16 + + {SPR_NULL, 0, 12*2, {NULL}, 0, 0, S_ZAPSB2 }, // S_ZAPSB1 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 8, 2, {NULL}, 0, 0, S_ZAPSB3 }, // S_ZAPSB2 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 7, 2, {NULL}, 0, 0, S_ZAPSB4 }, // S_ZAPSB3 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 6, 2, {NULL}, 0, 0, S_ZAPSB5 }, // S_ZAPSB4 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 5, 2, {NULL}, 0, 0, S_ZAPSB6 }, // S_ZAPSB5 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 4, 2, {NULL}, 0, 0, S_ZAPSB7 }, // S_ZAPSB6 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 3, 2, {NULL}, 0, 0, S_ZAPSB8 }, // S_ZAPSB7 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 2, 2, {NULL}, 0, 0, S_ZAPSB9 }, // S_ZAPSB8 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20| 1, 2, {NULL}, 0, 0, S_ZAPSB10}, // S_ZAPSB9 + {SPR_ZAPS, FF_FULLBRIGHT|FF_TRANS20 , 2, {NULL}, 0, 0, S_ZAPSB11}, // S_ZAPSB10 + {SPR_NULL, 0, 15*2, {NULL}, 0, 0, S_ZAPSB2 }, // S_ZAPSB11 + + // Thunder spark + {SPR_SSPK, FF_ANIMATE, 18, {NULL}, 1, 2, S_NULL}, // S_THUNDERCOIN_SPARK // Invincibility Sparkles {SPR_IVSP, FF_ANIMATE, 32, {NULL}, 31, 1, S_NULL}, // S_IVSP @@ -1728,43 +2898,212 @@ state_t states[NUMSTATES] = {SPR_SSPK, 1, 2, {NULL}, 0, 0, S_SSPK5}, // S_SSPK4 {SPR_SSPK, 0, 2, {NULL}, 0, 0, S_NULL}, // S_SSPK5 - // Freed Birdie - {SPR_BIRD, 0, 4, {NULL}, 0, 0, S_BIRD2}, // S_BIRD1 - {SPR_BIRD, 0, 4, {A_Chase}, 0, 0, S_BIRD3}, // S_BIRD2 - {SPR_BIRD, 1, 4, {A_Chase}, 0, 0, S_BIRD2}, // S_BIRD3 - - // Freed Bunny - {SPR_BUNY, 0, 4, {NULL}, 0, 0, S_BUNNY2}, // S_BUNNY1 - {SPR_BUNY, 0, 64, {NULL}, 0, 0, S_BUNNY3}, // S_BUNNY2 - {SPR_BUNY, 1, 2, {A_BunnyHop}, 6, 3, S_BUNNY4}, // S_BUNNY3 - {SPR_BUNY, 1, 2, {A_Chase}, 0, 0, S_BUNNY5}, // S_BUNNY4 - {SPR_BUNY, 1, 2, {A_Chase}, 0, 0, S_BUNNY6}, // S_BUNNY5 - {SPR_BUNY, 1, 2, {A_Chase}, 0, 0, S_BUNNY7}, // S_BUNNY6 - {SPR_BUNY, 1, 2, {A_Chase}, 0, 0, S_BUNNY8}, // S_BUNNY7 - {SPR_BUNY, 1, 2, {A_Chase}, 0, 0, S_BUNNY9}, // S_BUNNY8 - {SPR_BUNY, 1, 2, {A_Chase}, 0, 0, S_BUNNY10}, // S_BUNNY9 - {SPR_BUNY, 1, 2, {A_Chase}, 0, 0, S_BUNNY2}, // S_BUNNY10 - - // Freed Mouse - {SPR_MOUS, 0, 2, {A_MouseThink}, 0, 0, S_MOUSE2}, // S_MOUSE1 - {SPR_MOUS, 1, 2, {A_MouseThink}, 0, 0, S_MOUSE1}, // S_MOUSE2 - - // Freed Chicken - {SPR_CHIC, 0, 7, {A_Chase}, 3, 0, S_CHICKENHOP}, // S_CHICKEN1 - {SPR_CHIC, 0, 1, {A_BunnyHop}, 4, 2, S_CHICKENFLY1}, // S_CHICKENHOP - {SPR_CHIC, 1, 2, {A_ChickenCheck}, 0, 0, S_CHICKENFLY2}, // S_CHICKENFLY1 - {SPR_CHIC, 2, 2, {NULL}, 0, 0, S_CHICKENFLY1}, // S_CHICKENFLY2 - - // Freed Cow - {SPR_COWZ, 0, 4, {A_Chase}, 3, 0, S_COW2}, // S_COW1 - {SPR_COWZ, 1, 4, {A_Chase}, 3, 0, S_COW3}, // S_COW2 - {SPR_COWZ, 2, 4, {A_Chase}, 3, 0, S_COW4}, // S_COW3 - {SPR_COWZ, 3, 4, {A_Chase}, 3, 0, S_COW1}, // S_COW4 - - // Freed Birdie - {SPR_RBRD, 0, 4, {NULL}, 0, 0, S_RBIRD2}, // S_RBIRD1 - {SPR_RBRD, 0, 4, {A_Chase}, 0, 0, S_RBIRD3}, // S_RBIRD2 - {SPR_RBRD, 1, 4, {A_Chase}, 0, 0, S_RBIRD2}, // S_RBIRD3 + // Flicky-sized bubble + {SPR_FBUB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_FLICKY_BUBBLE + + // Bluebird + {SPR_FL01, 0, 2, {A_FlickyCheck}, S_FLICKY_01_FLAP1, S_FLICKY_01_FLAP1, S_FLICKY_01_OUT}, // S_FLICKY_01_OUT + {SPR_FL01, 1, 3, {A_FlickyFly}, 4*FRACUNIT, 16*FRACUNIT, S_FLICKY_01_FLAP2}, // S_FLICKY_01_FLAP1 + {SPR_FL01, 2, 3, {A_FlickyFly}, 4*FRACUNIT, 16*FRACUNIT, S_FLICKY_01_FLAP3}, // S_FLICKY_01_FLAP2 + {SPR_FL01, 3, 3, {A_FlickyFly}, 4*FRACUNIT, 16*FRACUNIT, S_FLICKY_01_FLAP1}, // S_FLICKY_01_FLAP3 + {SPR_FL01, FF_ANIMATE|1, -1, {NULL}, 2, 3, S_NULL}, // S_FLICKY_01_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_FLICKY_01, 384*FRACUNIT, S_FLICKY_01_CENTER}, // S_FLICKY_01_CENTER + + // Rabbit + {SPR_FL02, 0, 2, {A_FlickyCheck}, S_FLICKY_02_AIM, 0, S_FLICKY_02_OUT}, // S_FLICKY_02_OUT + {SPR_FL02, 1, 1, {A_FlickyAim}, ANG30, 32*FRACUNIT, S_FLICKY_02_HOP}, // S_FLICKY_02_AIM + {SPR_FL02, 1, 1, {A_FlickyHop}, 6*FRACUNIT, 4*FRACUNIT, S_FLICKY_02_UP}, // S_FLICKY_02_HOP + {SPR_FL02, 2, 2, {A_FlickyCheck}, S_FLICKY_02_AIM, S_FLICKY_02_DOWN, S_FLICKY_02_UP}, // S_FLICKY_02_UP + {SPR_FL02, 3, 2, {A_FlickyCheck}, S_FLICKY_02_AIM, 0, S_FLICKY_02_DOWN}, // S_FLICKY_02_DOWN + {SPR_FL02, FF_ANIMATE|1, -1, {NULL}, 2, 4, S_NULL}, // S_FLICKY_02_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_FLICKY_02, 384*FRACUNIT, S_FLICKY_02_CENTER}, // S_FLICKY_02_CENTER + + // Chicken + {SPR_FL03, 0, 2, {A_FlickyCheck}, S_FLICKY_03_AIM, S_FLICKY_03_FLAP1, S_FLICKY_03_OUT}, // S_FLICKY_03_OUT + {SPR_FL03, 1, 1, {A_FlickyAim}, ANGLE_45, 32*FRACUNIT, S_FLICKY_03_HOP}, // S_FLICKY_03_AIM + {SPR_FL03, 1, 1, {A_FlickyHop}, 7*FRACUNIT, 2*FRACUNIT, S_FLICKY_03_UP}, // S_FLICKY_03_HOP + {SPR_FL03, 2, 2, {A_FlickyFlutter}, S_FLICKY_03_HOP, S_FLICKY_03_FLAP1, S_FLICKY_03_UP}, // S_FLICKY_03_UP + {SPR_FL03, 3, 2, {A_FlickyFlutter}, S_FLICKY_03_HOP, 0, S_FLICKY_03_FLAP2}, // S_FLICKY_03_FLAP1 + {SPR_FL03, 4, 2, {A_FlickyFlutter}, S_FLICKY_03_HOP, 0, S_FLICKY_03_FLAP1}, // S_FLICKY_03_FLAP2 + {SPR_FL03, FF_ANIMATE|1, -1, {NULL}, 2, 4, S_NULL}, // S_FLICKY_03_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_FLICKY_03, 384*FRACUNIT, S_FLICKY_03_CENTER}, // S_FLICKY_03_CENTER + + // Seal + {SPR_FL04, 0, 2, {A_FlickyCheck}, S_FLICKY_04_AIM, 0, S_FLICKY_04_OUT}, // S_FLICKY_04_OUT + {SPR_FL04, 1, 1, {A_FlickyAim}, ANG30, 32*FRACUNIT, S_FLICKY_04_HOP}, // S_FLICKY_04_AIM + {SPR_FL04, 1, 1, {A_FlickyHop}, 3*FRACUNIT, 2*FRACUNIT, S_FLICKY_04_UP}, // S_FLICKY_04_HOP + {SPR_FL04, 2, 4, {A_FlickyCheck}, S_FLICKY_04_AIM, S_FLICKY_04_DOWN, S_FLICKY_04_UP}, // S_FLICKY_04_UP + {SPR_FL04, 3, 4, {A_FlickyCheck}, S_FLICKY_04_AIM, 0, S_FLICKY_04_DOWN}, // S_FLICKY_04_DOWN + {SPR_FL04, 3, 4, {A_FlickyFly}, 2*FRACUNIT, 48*FRACUNIT, S_FLICKY_04_SWIM2}, // S_FLICKY_04_SWIM1 + {SPR_FL04, 4, 4, {A_FlickyCoast}, FRACUNIT, S_FLICKY_04_SWIM1, S_FLICKY_04_SWIM3}, // S_FLICKY_04_SWIM2 + {SPR_FL04, 3, 4, {A_FlickyCoast}, FRACUNIT, S_FLICKY_04_SWIM1, S_FLICKY_04_SWIM4}, // S_FLICKY_04_SWIM3 + {SPR_FL04, 5, 4, {A_FlickyCoast}, FRACUNIT, S_FLICKY_04_SWIM1, S_FLICKY_04_SWIM1}, // S_FLICKY_04_SWIM4 + {SPR_FL04, FF_ANIMATE|1, -1, {NULL}, 2, 4, S_NULL}, // S_FLICKY_04_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_FLICKY_04, 384*FRACUNIT, S_FLICKY_04_CENTER}, // S_FLICKY_04_CENTER + + // Pig + {SPR_FL05, 0, 2, {A_FlickyCheck}, S_FLICKY_05_AIM, 0, S_FLICKY_05_OUT}, // S_FLICKY_05_OUT + {SPR_FL05, 1, 1, {A_FlickyAim}, ANG20, 32*FRACUNIT, S_FLICKY_05_HOP}, // S_FLICKY_05_AIM + {SPR_FL05, 1, 1, {A_FlickyHop}, 4*FRACUNIT, 3*FRACUNIT, S_FLICKY_05_UP}, // S_FLICKY_05_HOP + {SPR_FL05, 2, 2, {A_FlickyCheck}, S_FLICKY_05_AIM, S_FLICKY_05_DOWN, S_FLICKY_05_UP}, // S_FLICKY_05_UP + {SPR_FL05, 3, 2, {A_FlickyCheck}, S_FLICKY_05_AIM, 0, S_FLICKY_05_DOWN}, // S_FLICKY_05_DOWN + {SPR_FL05, FF_ANIMATE|1, -1, {NULL}, 2, 4, S_NULL}, // S_FLICKY_05_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_FLICKY_05, 384*FRACUNIT, S_FLICKY_05_CENTER}, // S_FLICKY_05_CENTER + + // Chipmunk + {SPR_FL06, 0, 2, {A_FlickyCheck}, S_FLICKY_06_AIM, 0, S_FLICKY_06_OUT}, // S_FLICKY_06_OUT + {SPR_FL06, 1, 1, {A_FlickyAim}, ANGLE_90, 32*FRACUNIT, S_FLICKY_06_HOP}, // S_FLICKY_06_AIM + {SPR_FL06, 1, 1, {A_FlickyHop}, 5*FRACUNIT, 6*FRACUNIT, S_FLICKY_06_UP}, // S_FLICKY_06_HOP + {SPR_FL06, 2, 2, {A_FlickyCheck}, S_FLICKY_06_AIM, S_FLICKY_06_DOWN, S_FLICKY_06_UP}, // S_FLICKY_06_UP + {SPR_FL06, 3, 2, {A_FlickyCheck}, S_FLICKY_06_AIM, 0, S_FLICKY_06_DOWN}, // S_FLICKY_06_DOWN + {SPR_FL06, FF_ANIMATE|1, -1, {NULL}, 2, 4, S_NULL}, // S_FLICKY_06_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_FLICKY_06, 384*FRACUNIT, S_FLICKY_06_CENTER}, // S_FLICKY_06_CENTER + + // Penguin + {SPR_FL07, 0, 2, {A_FlickyCheck}, S_FLICKY_07_AIML, 0, S_FLICKY_07_OUT}, // S_FLICKY_07_OUT + {SPR_FL07, 1, 1, {A_FlickyAim}, ANG30, 32*FRACUNIT, S_FLICKY_07_HOPL}, // S_FLICKY_07_AIML + {SPR_FL07, 1, 1, {A_FlickyHop}, 4*FRACUNIT, 2*FRACUNIT, S_FLICKY_07_UPL}, // S_FLICKY_07_HOPL + {SPR_FL07, 2, 4, {A_FlickyCheck}, S_FLICKY_07_AIMR, S_FLICKY_07_DOWNL, S_FLICKY_07_UPL}, // S_FLICKY_07_UPL + {SPR_FL07, 1, 4, {A_FlickyCheck}, S_FLICKY_07_AIMR, 0, S_FLICKY_07_DOWNL}, // S_FLICKY_07_DOWNL + {SPR_FL07, 1, 1, {A_FlickyAim}, ANG30, 32*FRACUNIT, S_FLICKY_07_HOPR}, // S_FLICKY_07_AIMR + {SPR_FL07, 1, 1, {A_FlickyHop}, 4*FRACUNIT, 2*FRACUNIT, S_FLICKY_07_UPR}, // S_FLICKY_07_HOPR + {SPR_FL07, 3, 4, {A_FlickyCheck}, S_FLICKY_07_AIML, S_FLICKY_07_DOWNR, S_FLICKY_07_UPR}, // S_FLICKY_07_UPR + {SPR_FL07, 1, 4, {A_FlickyCheck}, S_FLICKY_07_AIML, 0, S_FLICKY_07_DOWNR}, // S_FLICKY_07_DOWNR + {SPR_FL07, 4, 4, {A_FlickyFly}, 3*FRACUNIT, 72*FRACUNIT, S_FLICKY_07_SWIM2}, // S_FLICKY_07_SWIM1 + {SPR_FL07, 5, 4, {A_FlickyCoast}, FRACUNIT, S_FLICKY_07_SWIM1, S_FLICKY_07_SWIM3}, // S_FLICKY_07_SWIM2 + {SPR_FL07, 6, 4, {A_FlickyCoast}, 2*FRACUNIT, S_FLICKY_07_SWIM1, S_FLICKY_07_SWIM3}, // S_FLICKY_07_SWIM3 + {SPR_FL07, FF_ANIMATE|1, -1, {NULL}, 2, 4, S_NULL}, // S_FLICKY_07_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_FLICKY_07, 384*FRACUNIT, S_FLICKY_07_CENTER}, // S_FLICKY_07_CENTER + + // Fish + {SPR_FL08, 0, 2, {A_FlickyCheck}, S_FLICKY_08_AIM, 0, S_FLICKY_08_OUT}, // S_FLICKY_08_OUT + {SPR_FL08, 2, 1, {A_FlickyAim}, ANG30, 32*FRACUNIT, S_FLICKY_08_HOP}, // S_FLICKY_08_AIM + {SPR_FL08, 2, 1, {A_FlickyFlounder}, 2*FRACUNIT, 1*FRACUNIT, S_FLICKY_08_FLAP1}, // S_FLICKY_08_HOP + {SPR_FL08, 0, 4, {A_FlickyCheck}, S_FLICKY_08_AIM, 0, S_FLICKY_08_FLAP2}, // S_FLICKY_08_FLAP1 + {SPR_FL08, 1, 4, {A_FlickyCheck}, S_FLICKY_08_AIM, 0, S_FLICKY_08_FLAP3}, // S_FLICKY_08_FLAP2 + {SPR_FL08, 0, 4, {A_FlickyCheck}, S_FLICKY_08_AIM, 0, S_FLICKY_08_FLAP4}, // S_FLICKY_08_FLAP3 + {SPR_FL08, 2, 4, {A_FlickyCheck}, S_FLICKY_08_AIM, 0, S_FLICKY_08_FLAP1}, // S_FLICKY_08_FLAP4 + {SPR_FL08, 0, 4, {A_FlickyFly}, 3*FRACUNIT, 64*FRACUNIT, S_FLICKY_08_SWIM2}, // S_FLICKY_08_SWIM1 + {SPR_FL08, 1, 4, {A_FlickyCoast}, FRACUNIT, S_FLICKY_08_SWIM1, S_FLICKY_08_SWIM3}, // S_FLICKY_08_SWIM2 + {SPR_FL08, 0, 4, {A_FlickyCoast}, FRACUNIT, S_FLICKY_08_SWIM1, S_FLICKY_08_SWIM4}, // S_FLICKY_08_SWIM3 + {SPR_FL08, 2, 4, {A_FlickyCoast}, FRACUNIT, S_FLICKY_08_SWIM1, S_FLICKY_08_SWIM4}, // S_FLICKY_08_SWIM4 + {SPR_FL08, FF_ANIMATE, -1, {NULL}, 2, 4, S_NULL}, // S_FLICKY_08_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_FLICKY_08, 384*FRACUNIT, S_FLICKY_08_CENTER}, // S_FLICKY_08_CENTER + + // Ram + {SPR_FL09, 0, 2, {A_FlickyCheck}, S_FLICKY_09_AIM, 0, S_FLICKY_09_OUT}, // S_FLICKY_09_OUT + {SPR_FL09, 1, 1, {A_FlickyAim}, ANG30, 32*FRACUNIT, S_FLICKY_09_HOP}, // S_FLICKY_09_AIM + {SPR_FL09, 1, 1, {A_FlickyHop}, 7*FRACUNIT, 2*FRACUNIT, S_FLICKY_09_UP}, // S_FLICKY_09_HOP + {SPR_FL09, 2, 2, {A_FlickyCheck}, S_FLICKY_09_AIM, S_FLICKY_09_DOWN, S_FLICKY_09_UP}, // S_FLICKY_09_UP + {SPR_FL09, 3, 2, {A_FlickyCheck}, S_FLICKY_09_AIM, 0, S_FLICKY_09_DOWN}, // S_FLICKY_09_DOWN + {SPR_FL09, FF_ANIMATE|1, -1, {NULL}, 2, 4, S_NULL}, // S_FLICKY_09_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_FLICKY_09, 384*FRACUNIT, S_FLICKY_09_CENTER}, // S_FLICKY_09_CENTER + + // Puffin + {SPR_FL10, 0, 2, {A_FlickyCheck}, S_FLICKY_10_FLAP1, S_FLICKY_10_FLAP1, S_FLICKY_10_OUT}, // S_FLICKY_10_OUT + {SPR_FL10, 1, 3, {A_FlickySoar}, 4*FRACUNIT, 16*FRACUNIT, S_FLICKY_10_FLAP2}, // S_FLICKY_10_FLAP1 + {SPR_FL10, 2, 3, {A_FlickySoar}, 4*FRACUNIT, 16*FRACUNIT, S_FLICKY_10_FLAP1}, // S_FLICKY_10_FLAP2 + {SPR_FL10, FF_ANIMATE|1, -1, {NULL}, 1, 3, S_NULL}, // S_FLICKY_10_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_FLICKY_10, 384*FRACUNIT, S_FLICKY_10_CENTER}, // S_FLICKY_10_CENTER + + // Cow + {SPR_FL11, 0, 2, {A_FlickyCheck}, S_FLICKY_11_AIM, 0, S_FLICKY_11_OUT}, // S_FLICKY_11_OUT + {SPR_FL11, 1, 1, {A_FlickyAim}, ANGLE_90, 64*FRACUNIT, S_FLICKY_11_RUN1}, // S_FLICKY_11_AIM + {SPR_FL11, 1, 3, {A_FlickyHop}, FRACUNIT/2, 2*FRACUNIT, S_FLICKY_11_RUN2}, // S_FLICKY_11_RUN1 + {SPR_FL11, 2, 4, {A_FlickyHop}, FRACUNIT/2, 2*FRACUNIT, S_FLICKY_11_RUN3}, // S_FLICKY_11_RUN2 + {SPR_FL11, 3, 4, {A_FlickyHop}, FRACUNIT/2, 2*FRACUNIT, S_FLICKY_11_AIM}, // S_FLICKY_11_RUN3 + {SPR_FL11, FF_ANIMATE|1, -1, {NULL}, 2, 4, S_NULL}, // S_FLICKY_11_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_FLICKY_11, 384*FRACUNIT, S_FLICKY_11_CENTER}, // S_FLICKY_11_CENTER + + // Rat + {SPR_FL12, 0, 2, {A_FlickyCheck}, S_FLICKY_12_AIM, 0, S_FLICKY_12_OUT}, // S_FLICKY_12_OUT + {SPR_FL12, 1, 1, {A_FlickyAim}, ANGLE_90, 32*FRACUNIT, S_FLICKY_12_RUN1}, // S_FLICKY_12_AIM + {SPR_FL12, 1, 2, {A_FlickyHop}, 1, 12*FRACUNIT, S_FLICKY_12_RUN2}, // S_FLICKY_12_RUN1 + {SPR_FL12, 2, 3, {A_FlickyHop}, 1, 12*FRACUNIT, S_FLICKY_12_RUN3}, // S_FLICKY_12_RUN2 + {SPR_FL12, 3, 3, {A_FlickyHop}, 1, 12*FRACUNIT, S_FLICKY_12_AIM}, // S_FLICKY_12_RUN3 + {SPR_FL12, FF_ANIMATE|1, -1, {NULL}, 2, 4, S_NULL}, // S_FLICKY_12_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_FLICKY_12, 384*FRACUNIT, S_FLICKY_12_CENTER}, // S_FLICKY_12_CENTER + + // Bear + {SPR_FL13, 0, 2, {A_FlickyCheck}, S_FLICKY_13_AIM, 0, S_FLICKY_13_OUT}, // S_FLICKY_13_OUT + {SPR_FL13, 1, 1, {A_FlickyAim}, ANG30, 32*FRACUNIT, S_FLICKY_13_HOP}, // S_FLICKY_13_AIM + {SPR_FL13, 1, 1, {A_FlickyHop}, 5*FRACUNIT, 3*FRACUNIT, S_FLICKY_13_UP}, // S_FLICKY_13_HOP + {SPR_FL13, 2, 2, {A_FlickyCheck}, S_FLICKY_13_AIM, S_FLICKY_13_DOWN, S_FLICKY_13_UP}, // S_FLICKY_13_UP + {SPR_FL13, 3, 2, {A_FlickyCheck}, S_FLICKY_13_AIM, 0, S_FLICKY_13_DOWN}, // S_FLICKY_13_DOWN + {SPR_FL13, FF_ANIMATE|1, -1, {NULL}, 2, 4, S_NULL}, // S_FLICKY_13_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_FLICKY_13, 384*FRACUNIT, S_FLICKY_13_CENTER}, // S_FLICKY_13_CENTER + + // Dove + {SPR_FL14, 0, 2, {A_FlickyCheck}, S_FLICKY_14_FLAP1, S_FLICKY_14_FLAP1, S_FLICKY_14_OUT}, // S_FLICKY_14_OUT + {SPR_FL14, 1, 3, {A_FlickySoar}, 4*FRACUNIT, 32*FRACUNIT, S_FLICKY_14_FLAP2}, // S_FLICKY_14_FLAP1 + {SPR_FL14, 2, 3, {A_FlickySoar}, 4*FRACUNIT, 32*FRACUNIT, S_FLICKY_14_FLAP3}, // S_FLICKY_14_FLAP2 + {SPR_FL14, 3, 3, {A_FlickySoar}, 4*FRACUNIT, 32*FRACUNIT, S_FLICKY_14_FLAP1}, // S_FLICKY_14_FLAP3 + {SPR_FL14, FF_ANIMATE|1, -1, {NULL}, 2, 3, S_NULL}, // S_FLICKY_14_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_FLICKY_14, 384*FRACUNIT, S_FLICKY_14_CENTER}, // S_FLICKY_14_CENTER + + // Cat + {SPR_FL15, 0, 2, {A_FlickyCheck}, S_FLICKY_15_AIM, 0, S_FLICKY_15_OUT}, // S_FLICKY_15_OUT + {SPR_FL15, 1, 1, {A_FlickyAim}, ANG30, 32*FRACUNIT, S_FLICKY_15_HOP}, // S_FLICKY_15_AIM + {SPR_FL15, 1, 1, {A_FlickyFlounder}, 2*FRACUNIT, 6*FRACUNIT, S_FLICKY_15_UP}, // S_FLICKY_15_HOP + {SPR_FL15, 2, 2, {A_FlickyCheck}, S_FLICKY_15_AIM, S_FLICKY_15_DOWN, S_FLICKY_15_UP}, // S_FLICKY_15_UP + {SPR_FL15, 3, 2, {A_FlickyCheck}, S_FLICKY_15_AIM, 0, S_FLICKY_15_DOWN}, // S_FLICKY_15_DOWN + {SPR_FL15, FF_ANIMATE|1, -1, {NULL}, 2, 4, S_NULL}, // S_FLICKY_15_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_FLICKY_15, 384*FRACUNIT, S_FLICKY_15_CENTER}, // S_FLICKY_15_CENTER + + // Canary + {SPR_FL16, 0, 2, {A_FlickyHeightCheck}, S_FLICKY_16_FLAP1, 0, S_FLICKY_16_OUT}, // S_FLICKY_16_OUT + {SPR_FL16, 1, 3, {A_FlickyFly}, 4*FRACUNIT, 8*FRACUNIT, S_FLICKY_16_FLAP2}, // S_FLICKY_16_FLAP1 + {SPR_FL16, 2, 3, {A_SetObjectFlags}, MF_NOGRAVITY, 1, S_FLICKY_16_FLAP3}, // S_FLICKY_16_FLAP2 + {SPR_FL16, 3, 3, {A_FlickyHeightCheck}, S_FLICKY_16_FLAP1, 0, S_FLICKY_16_FLAP3}, // S_FLICKY_16_FLAP3 + {SPR_FL16, FF_ANIMATE|1, -1, {NULL}, 2, 3, S_NULL}, // S_FLICKY_16_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_FLICKY_16, 384*FRACUNIT, S_FLICKY_16_CENTER}, // S_FLICKY_16_CENTER + + // Spider + {SPR_FS01, 0, 2, {A_FlickyCheck}, S_SECRETFLICKY_01_AIM, 0, S_SECRETFLICKY_01_OUT}, // S_SECRETFLICKY_01_OUT + {SPR_FS01, 1, 1, {A_FlickyAim}, ANG30, 32*FRACUNIT, S_SECRETFLICKY_01_HOP}, // S_SECRETFLICKY_01_AIM + {SPR_FS01, 1, 1, {A_FlickyFlounder}, 2*FRACUNIT, 6*FRACUNIT, S_SECRETFLICKY_01_UP}, // S_SECRETFLICKY_01_HOP + {SPR_FS01, 2, 2, {A_FlickyCheck}, S_SECRETFLICKY_01_AIM, S_SECRETFLICKY_01_DOWN, S_SECRETFLICKY_01_UP}, // S_SECRETFLICKY_01_UP + {SPR_FS01, 3, 2, {A_FlickyCheck}, S_SECRETFLICKY_01_AIM, 0, S_SECRETFLICKY_01_DOWN}, // S_SECRETFLICKY_01_DOWN + {SPR_FS01, FF_ANIMATE|1, -1, {NULL}, 2, 4, S_NULL}, // S_SECRETFLICKY_01_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_SECRETFLICKY_01, 384*FRACUNIT, S_SECRETFLICKY_01_CENTER}, // S_SECRETFLICKY_01_CENTER + + // Bat + {SPR_FS02, 0, 2, {A_FlickyHeightCheck}, S_SECRETFLICKY_02_FLAP1, S_SECRETFLICKY_02_FLAP1, S_SECRETFLICKY_02_OUT}, // S_SECRETFLICKY_02_OUT + {SPR_FS02, 1, 3, {A_FlickyFly}, 4*FRACUNIT, 16*FRACUNIT, S_SECRETFLICKY_02_FLAP2}, // S_SECRETFLICKY_02_FLAP1 + {SPR_FS02, 2, 3, {A_FlickyFly}, 4*FRACUNIT, 16*FRACUNIT, S_SECRETFLICKY_02_FLAP3}, // S_SECRETFLICKY_02_FLAP2 + {SPR_FS02, 3, 3, {A_FlickyFly}, 4*FRACUNIT, 16*FRACUNIT, S_SECRETFLICKY_02_FLAP1}, // S_SECRETFLICKY_02_FLAP3 + {SPR_FS02, FF_ANIMATE|1, -1, {NULL}, 2, 2, S_NULL}, // S_SECRETFLICKY_02_STAND + {SPR_NULL, 0, 15, {A_FlickyCenter}, MT_SECRETFLICKY_02, 384*FRACUNIT, S_SECRETFLICKY_02_CENTER}, // S_SECRETFLICKY_02_CENTER + + // Fan + {SPR_FANS, 0, 1, {A_FanBubbleSpawn}, 2048, 0, S_FAN2}, // S_FAN + {SPR_FANS, 1, 1, {A_FanBubbleSpawn}, 1024, 0, S_FAN3}, // S_FAN2 + {SPR_FANS, 2, 1, {A_FanBubbleSpawn}, 512, 0, S_FAN4}, // S_FAN3 + {SPR_FANS, 3, 1, {A_FanBubbleSpawn}, 1024, 0, S_FAN5}, // S_FAN4 + {SPR_FANS, 4, 1, {A_FanBubbleSpawn}, 512, 0, S_FAN}, // S_FAN5 + + // Steam Riser + {SPR_STEM, 0, 2, {A_SetSolidSteam}, 0, 0, S_STEAM2}, // S_STEAM1 + {SPR_STEM, 1, 2, {A_UnsetSolidSteam}, 0, 0, S_STEAM3}, // S_STEAM2 + {SPR_STEM, 2, 2, {NULL}, 0, 0, S_STEAM4}, // S_STEAM3 + {SPR_STEM, 3, 2, {NULL}, 0, 0, S_STEAM5}, // S_STEAM4 + {SPR_STEM, 4, 2, {NULL}, 0, 0, S_STEAM6}, // S_STEAM5 + {SPR_STEM, 5, 2, {NULL}, 0, 0, S_STEAM7}, // S_STEAM6 + {SPR_STEM, 6, 2, {NULL}, 0, 0, S_STEAM8}, // S_STEAM7 + {SPR_NULL, 0, 18, {NULL}, 0, 0, S_STEAM1}, // S_STEAM8 + + // Bumpers + {SPR_BUMP, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 3, 4, S_NULL}, // S_BUMPER + {SPR_BUMP, FF_ANIMATE|4, 12, {A_Pain}, 1, 3, S_BUMPER}, //S_BUMPERHIT + + // Balloons + {SPR_BLON, FF_ANIMATE, -1, {NULL}, 2, 5, S_NULL}, // S_BALLOON + {SPR_BLON, 3, 0, {A_RemoteDamage}, 0, 1, S_BALLOONPOP2}, // S_BALLOONPOP1 + {SPR_BLON, 3, 1, {A_Pain}, 0, 0, S_BALLOONPOP3}, // S_BALLOONPOP2 + {SPR_BLON, 4, 1, {NULL}, 0, 0, S_BALLOONPOP4}, // S_BALLOONPOP3 + {SPR_NULL, 0, TICRATE, {A_CheckFlags2}, MF2_AMBUSH, S_BALLOONPOP5, S_NULL}, // S_BALLOONPOP4 + {SPR_NULL, 0, 15*TICRATE, {NULL}, 0, 0, S_BALLOONPOP6}, // S_BALLOONPOP5 + {SPR_NULL, 0, 0, {A_SpawnFreshCopy}, 0, 0, S_NULL}, // S_BALLOONPOP6 // Yellow Spring {SPR_SPRY, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YELLOWSPRING @@ -1807,6 +3146,46 @@ state_t states[NUMSTATES] = {SPR_RSPR, 2, 1, {NULL}, 0, 0, S_RDIAG8}, // S_RDIAG7 {SPR_RSPR, 1, 1, {NULL}, 0, 0, S_RDIAG1}, // S_RDIAG8 + // Blue Diagonal Spring + {SPR_BSPR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BDIAG1 + {SPR_BSPR, 1, 1, {A_Pain}, 0, 0, S_BDIAG3}, // S_BDIAG2 + {SPR_BSPR, 2, 1, {NULL}, 0, 0, S_BDIAG4}, // S_BDIAG3 + {SPR_BSPR, 3, 1, {NULL}, 0, 0, S_BDIAG5}, // S_BDIAG4 + {SPR_BSPR, 4, 1, {NULL}, 0, 0, S_BDIAG6}, // S_BDIAG5 + {SPR_BSPR, 3, 1, {NULL}, 0, 0, S_BDIAG7}, // S_BDIAG6 + {SPR_BSPR, 2, 1, {NULL}, 0, 0, S_BDIAG8}, // S_BDIAG7 + {SPR_BSPR, 1, 1, {NULL}, 0, 0, S_BDIAG1}, // S_BDIAG8 + + // Yellow Side Spring + {SPR_SSWY, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YHORIZ1 + {SPR_SSWY, 1, 1, {A_Pain}, 0, 0, S_YHORIZ3}, // S_YHORIZ2 + {SPR_SSWY, 2, 1, {NULL}, 0, 0, S_YHORIZ4}, // S_YHORIZ3 + {SPR_SSWY, 3, 1, {NULL}, 0, 0, S_YHORIZ5}, // S_YHORIZ4 + {SPR_SSWY, 4, 1, {NULL}, 0, 0, S_YHORIZ6}, // S_YHORIZ5 + {SPR_SSWY, 3, 1, {NULL}, 0, 0, S_YHORIZ7}, // S_YHORIZ6 + {SPR_SSWY, 2, 1, {NULL}, 0, 0, S_YHORIZ8}, // S_YHORIZ7 + {SPR_SSWY, 1, 1, {NULL}, 0, 0, S_YHORIZ1}, // S_YHORIZ8 + + // Red Side Spring + {SPR_SSWR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_RHORIZ1 + {SPR_SSWR, 1, 1, {A_Pain}, 0, 0, S_RHORIZ3}, // S_RHORIZ2 + {SPR_SSWR, 2, 1, {NULL}, 0, 0, S_RHORIZ4}, // S_RHORIZ3 + {SPR_SSWR, 3, 1, {NULL}, 0, 0, S_RHORIZ5}, // S_RHORIZ4 + {SPR_SSWR, 4, 1, {NULL}, 0, 0, S_RHORIZ6}, // S_RHORIZ5 + {SPR_SSWR, 3, 1, {NULL}, 0, 0, S_RHORIZ7}, // S_RHORIZ6 + {SPR_SSWR, 2, 1, {NULL}, 0, 0, S_RHORIZ8}, // S_RHORIZ7 + {SPR_SSWR, 1, 1, {NULL}, 0, 0, S_RHORIZ1}, // S_RHORIZ8 + + // Blue Side Spring + {SPR_SSWB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BHORIZ1 + {SPR_SSWB, 1, 1, {A_Pain}, 0, 0, S_BHORIZ3}, // S_BHORIZ2 + {SPR_SSWB, 2, 1, {NULL}, 0, 0, S_BHORIZ4}, // S_BHORIZ3 + {SPR_SSWB, 3, 1, {NULL}, 0, 0, S_BHORIZ5}, // S_BHORIZ4 + {SPR_SSWB, 4, 1, {NULL}, 0, 0, S_BHORIZ6}, // S_BHORIZ5 + {SPR_SSWB, 3, 1, {NULL}, 0, 0, S_BHORIZ7}, // S_BHORIZ6 + {SPR_SSWB, 2, 1, {NULL}, 0, 0, S_BHORIZ8}, // S_BHORIZ7 + {SPR_SSWB, 1, 1, {NULL}, 0, 0, S_BHORIZ1}, // S_BHORIZ8 + // Rain {SPR_RAIN, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_RAIN1 {SPR_RAIN, FF_TRANS50, 1, {NULL}, 0, 0, S_RAIN1}, // S_RAINRETURN @@ -1840,17 +3219,33 @@ state_t states[NUMSTATES] = {SPR_SMOK, FF_TRANS50|4, 8, {NULL}, 0, 0, S_NULL}, // S_SMOKE5 // Bubbles - {SPR_BUBP, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_SMALLBUBBLE1}, // S_SMALLBUBBLE - {SPR_BUBP, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_SMALLBUBBLE}, // S_SMALLBUBBLE1 - {SPR_BUBO, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_MEDIUMBUBBLE1}, // S_MEDIUMBUBBLE - {SPR_BUBO, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_MEDIUMBUBBLE}, // S_MEDIUMBUBBLE1 + {SPR_BUBL, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_SMALLBUBBLE}, // S_SMALLBUBBLE + {SPR_BUBL, FF_TRANS50|1, 1, {A_BubbleRise}, 0, 1024, S_MEDIUMBUBBLE}, // S_MEDIUMBUBBLE // Extra Large Bubble (breathable) - {SPR_BUBN, FF_TRANS50|FF_FULLBRIGHT, 16, {A_BubbleRise}, 0, 1024, S_EXTRALARGEBUBBLE}, // S_LARGEBUBBLE - {SPR_BUBM, FF_TRANS50|FF_FULLBRIGHT, 16, {A_BubbleRise}, 0, 1024, S_EXTRALARGEBUBBLE}, // S_EXTRALARGEBUBBLE + {SPR_BUBL, FF_TRANS50|FF_FULLBRIGHT|2, 8, {A_BubbleRise}, 0, 1024, S_LARGEBUBBLE2}, // S_LARGEBUBBLE1 + {SPR_BUBL, FF_TRANS50|FF_FULLBRIGHT|3, 8, {A_BubbleRise}, 0, 1024, S_EXTRALARGEBUBBLE}, // S_LARGEBUBBLE2 + {SPR_BUBL, FF_TRANS50|FF_FULLBRIGHT|4, 16, {A_BubbleRise}, 0, 1024, S_EXTRALARGEBUBBLE}, // S_EXTRALARGEBUBBLE // Extra Large Bubble goes POP! - {SPR_POPP, 0, 16, {NULL}, 0, 0, S_NULL}, // S_POP1 + {SPR_BUBL, 5, 16, {NULL}, 0, 0, S_NULL}, // S_POP1 + + {SPR_WZAP, FF_TRANS10|FF_ANIMATE|FF_RANDOMANIM, 4, {NULL}, 3, 2, S_NULL}, // S_WATERZAP + + // Spindash dust + {SPR_DUST, 0, 7, {NULL}, 0, 0, S_SPINDUST2}, // S_SPINDUST1 + {SPR_DUST, 1, 6, {NULL}, 0, 0, S_SPINDUST3}, // S_SPINDUST2 + {SPR_DUST, FF_TRANS30|2, 4, {NULL}, 0, 0, S_SPINDUST4}, // S_SPINDUST3 + {SPR_DUST, FF_TRANS60|3, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST4 + {SPR_BUBL, 0, 7, {NULL}, 0, 0, S_SPINDUST_BUBBLE2}, // S_SPINDUST_BUBBLE1 + {SPR_BUBL, 0, 6, {NULL}, 0, 0, S_SPINDUST_BUBBLE3}, // S_SPINDUST_BUBBLE2 + {SPR_BUBL, FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_BUBBLE4}, // S_SPINDUST_BUBBLE3 + {SPR_BUBL, FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_BUBBLE4 + {SPR_FPRT, 0, 7, {NULL}, 0, 0, S_SPINDUST_FIRE2}, // S_SPINDUST_FIRE1 + {SPR_FPRT, 0, 6, {NULL}, 0, 0, S_SPINDUST_FIRE3}, // S_SPINDUST_FIRE2 + {SPR_FPRT, FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_FIRE4}, // S_SPINDUST_FIRE3 + {SPR_FPRT, FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_FIRE4 + {SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50, 2, {NULL}, 0, 0, S_FOG2}, // S_FOG1 {SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50|1, 2, {NULL}, 0, 0, S_FOG3}, // S_FOG2 @@ -1868,11 +3263,10 @@ state_t states[NUMSTATES] = {SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50|13, 2, {NULL}, 0, 0, S_NULL}, // S_FOG14 // Flower Seed - {SPR_SEED, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_SEED + {SPR_SEED, FF_FULLBRIGHT|FF_ANIMATE, -1, {NULL}, 2, 2, S_NULL}, // S_SEED // Particle sprite - {SPR_PRTL, FF_FULLBRIGHT|FF_TRANS70, 2*TICRATE, {NULL}, 0, 0, S_NULL}, // S_PARTICLE - {SPR_NULL, 0, 1, {A_ParticleSpawn}, 0, 0, S_PARTICLEGEN}, // S_PARTICLEGEN + {SPR_PRTL, 0, 2*TICRATE, {NULL}, 0, 0, S_NULL}, // S_PARTICLE {SPR_SCOR, 0, 32, {A_ScoreRise}, 0, 0, S_NULL}, // S_SCRA - 100 {SPR_SCOR, 1, 32, {A_ScoreRise}, 0, 0, S_NULL}, // S_SCRB - 200 @@ -1885,6 +3279,7 @@ state_t states[NUMSTATES] = {SPR_SCOR, 8, 32, {A_ScoreRise}, 0, 0, S_NULL}, // S_SCRI - 4000 (mario mode) {SPR_SCOR, 9, 32, {A_ScoreRise}, 0, 0, S_NULL}, // S_SCRJ - 8000 (mario mode) {SPR_SCOR, 10, 32, {A_ScoreRise}, 0, 0, S_NULL}, // S_SCRK - 1UP (mario mode) + {SPR_SCOR, 11, 32, {A_ScoreRise}, 0, 0, S_NULL}, // S_SCRL - 10 // Drowning Timer Numbers {SPR_DRWN, 0, 40, {NULL}, 0, 0, S_NULL}, // S_ZERO1 @@ -1894,13 +3289,22 @@ state_t states[NUMSTATES] = {SPR_DRWN, 4, 40, {NULL}, 0, 0, S_NULL}, // S_FOUR1 {SPR_DRWN, 5, 40, {NULL}, 0, 0, S_NULL}, // S_FIVE1 - {SPR_TTAG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_TTAG1 + {SPR_DRWN, 6, 40, {NULL}, 0, 0, S_NULL}, // S_ZERO2 + {SPR_DRWN, 7, 40, {NULL}, 0, 0, S_NULL}, // S_ONE2 + {SPR_DRWN, 8, 40, {NULL}, 0, 0, S_NULL}, // S_TWO2 + {SPR_DRWN, 9, 40, {NULL}, 0, 0, S_NULL}, // S_THREE2 + {SPR_DRWN, 10, 40, {NULL}, 0, 0, S_NULL}, // S_FOUR2 + {SPR_DRWN, 11, 40, {NULL}, 0, 0, S_NULL}, // S_FIVE2 + + {SPR_LCKN, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_LOCKON1 + {SPR_LCKN, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_LOCKON2 + + {SPR_TTAG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_TTAG // CTF Sign - {SPR_GFLG, 0, 1, {NULL}, 0, 0, S_GOTFLAG2}, // S_GOTFLAG1 - {SPR_GFLG, 1, 1, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG2 - {SPR_GFLG, 0, 1, {NULL}, 0, 0, S_GOTFLAG4}, // S_GOTFLAG3 - {SPR_GFLG, 2, 1, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG4 + {SPR_GFLG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG + + {SPR_CORK, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CORK // Red Rings (thrown) {SPR_RRNG, FF_FULLBRIGHT, 1, {A_ThrownRing}, 0, 0, S_RRNG2}, // S_RRNG1 @@ -1912,16 +3316,16 @@ state_t states[NUMSTATES] = {SPR_RRNG, FF_FULLBRIGHT|6, 1, {A_ThrownRing}, 0, 0, S_RRNG1}, // S_RRNG7 // Weapon Ring Ammo - {SPR_RNGB, FF_ANIMATE, -1, {NULL}, 34, 1, S_BOUNCERINGAMMO}, // S_BOUNCERINGAMMO - {SPR_RNGR, FF_ANIMATE, -1, {NULL}, 34, 1, S_RAILRINGAMMO}, // S_RAILRINGAMMO - {SPR_RNGI, FF_ANIMATE, -1, {NULL}, 34, 1, S_INFINITYRINGAMMO}, // S_INFINITYRINGAMMO - {SPR_RNGA, FF_ANIMATE, -1, {NULL}, 34, 1, S_AUTOMATICRINGAMMO}, // S_AUTOMATICRINGAMMO - {SPR_RNGE, FF_ANIMATE, -1, {NULL}, 34, 1, S_EXPLOSIONRINGAMMO}, // S_EXPLOSIONRINGAMMO - {SPR_RNGS, FF_ANIMATE, -1, {NULL}, 34, 1, S_SCATTERRINGAMMO}, // S_SCATTERRINGAMMO - {SPR_RNGG, FF_ANIMATE, -1, {NULL}, 34, 1, S_GRENADERINGAMMO}, // S_GRENADERINGAMMO + {SPR_RNGB, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 34, 1, S_BOUNCERINGAMMO}, // S_BOUNCERINGAMMO + {SPR_RNGR, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 34, 1, S_RAILRINGAMMO}, // S_RAILRINGAMMO + {SPR_RNGI, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 34, 1, S_INFINITYRINGAMMO}, // S_INFINITYRINGAMMO + {SPR_RNGA, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 34, 1, S_AUTOMATICRINGAMMO}, // S_AUTOMATICRINGAMMO + {SPR_RNGE, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 34, 1, S_EXPLOSIONRINGAMMO}, // S_EXPLOSIONRINGAMMO + {SPR_RNGS, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 34, 1, S_SCATTERRINGAMMO}, // S_SCATTERRINGAMMO + {SPR_RNGG, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 34, 1, S_GRENADERINGAMMO}, // S_GRENADERINGAMMO // Bounce Ring Pickup - {SPR_PIKB, FF_ANIMATE, -1, {NULL}, 15, 1, S_BOUNCEPICKUP}, // S_BOUNCEPICKUP + {SPR_PIKB, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 15, 1, S_BOUNCEPICKUP}, // S_BOUNCEPICKUP {SPR_PIKB, 0, 1, {NULL}, 0, 0, S_BOUNCEPICKUPFADE2}, // S_BOUNCEPICKUPFADE1 {SPR_PIKB, 2, 1, {NULL}, 0, 0, S_BOUNCEPICKUPFADE3}, // S_BOUNCEPICKUPFADE2 @@ -1933,7 +3337,7 @@ state_t states[NUMSTATES] = {SPR_PIKB, 14, 1, {NULL}, 0, 0, S_BOUNCEPICKUPFADE1}, // S_BOUNCEPICKUPFADE8 // Rail Ring Pickup - {SPR_PIKR, FF_ANIMATE, -1, {NULL}, 15, 1, S_RAILPICKUP}, // S_RAILPICKUP + {SPR_PIKR, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 15, 1, S_RAILPICKUP}, // S_RAILPICKUP {SPR_PIKR, 0, 1, {NULL}, 0, 0, S_RAILPICKUPFADE2}, // S_RAILPICKUPFADE1 {SPR_PIKR, 2, 1, {NULL}, 0, 0, S_RAILPICKUPFADE3}, // S_RAILPICKUPFADE2 @@ -1945,7 +3349,7 @@ state_t states[NUMSTATES] = {SPR_PIKR, 14, 1, {NULL}, 0, 0, S_RAILPICKUPFADE1}, // S_RAILPICKUPFADE8 // Auto Ring Pickup - {SPR_PIKA, FF_ANIMATE, -1, {NULL}, 15, 1, S_AUTOPICKUP}, // S_AUTOPICKUP + {SPR_PIKA, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 15, 1, S_AUTOPICKUP}, // S_AUTOPICKUP {SPR_PIKA, 0, 1, {NULL}, 0, 0, S_AUTOPICKUPFADE2}, // S_AUTOPICKUPFADE1 {SPR_PIKA, 2, 1, {NULL}, 0, 0, S_AUTOPICKUPFADE3}, // S_AUTOPICKUPFADE2 @@ -1957,7 +3361,7 @@ state_t states[NUMSTATES] = {SPR_PIKA, 14, 1, {NULL}, 0, 0, S_AUTOPICKUPFADE1}, // S_AUTOPICKUPFADE8 // Explode Ring Pickup - {SPR_PIKE, FF_ANIMATE, -1, {NULL}, 15, 1, S_EXPLODEPICKUP}, // S_EXPLODEPICKUP + {SPR_PIKE, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 15, 1, S_EXPLODEPICKUP}, // S_EXPLODEPICKUP {SPR_PIKE, 0, 1, {NULL}, 0, 0, S_EXPLODEPICKUPFADE2}, // S_EXPLODEPICKUPFADE1 {SPR_PIKE, 2, 1, {NULL}, 0, 0, S_EXPLODEPICKUPFADE3}, // S_EXPLODEPICKUPFADE2 @@ -1969,7 +3373,7 @@ state_t states[NUMSTATES] = {SPR_PIKE, 14, 1, {NULL}, 0, 0, S_EXPLODEPICKUPFADE1}, // S_EXPLODEPICKUPFADE8 // Scatter Ring Pickup - {SPR_PIKS, FF_ANIMATE, -1, {NULL}, 15, 1, S_SCATTERPICKUP}, // S_SCATTERPICKUP + {SPR_PIKS, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 15, 1, S_SCATTERPICKUP}, // S_SCATTERPICKUP {SPR_PIKS, 0, 1, {NULL}, 0, 0, S_SCATTERPICKUPFADE2}, // S_SCATTERPICKUPFADE1 {SPR_PIKS, 2, 1, {NULL}, 0, 0, S_SCATTERPICKUPFADE3}, // S_SCATTERPICKUPFADE2 @@ -1981,7 +3385,7 @@ state_t states[NUMSTATES] = {SPR_PIKS, 14, 1, {NULL}, 0, 0, S_SCATTERPICKUPFADE1}, // S_SCATTERPICKUPFADE8 // Grenade Ring Pickup - {SPR_PIKG, FF_ANIMATE, -1, {NULL}, 15, 1, S_GRENADEPICKUP}, // S_GRENADEPICKUP + {SPR_PIKG, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 15, 1, S_GRENADEPICKUP}, // S_GRENADEPICKUP {SPR_PIKG, 0, 1, {NULL}, 0, 0, S_GRENADEPICKUPFADE2}, // S_GRENADEPICKUPFADE1 {SPR_PIKG, 2, 1, {NULL}, 0, 0, S_GRENADEPICKUPFADE3}, // S_GRENADEPICKUPFADE2 @@ -2101,25 +3505,25 @@ state_t states[NUMSTATES] = {SPR_FBLL, FF_FULLBRIGHT|6, 3, {NULL}, 0, 0, S_NULL}, // S_FIREBALLEXP3 // Turtle Shell - {SPR_SHLL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHELL - {SPR_SHLL, 0, 2, {NULL}, 0, 0, S_SHELL2}, // S_SHELL1 - {SPR_SHLL, 1, 2, {NULL}, 0, 0, S_SHELL3}, // S_SHELL2 - {SPR_SHLL, 2, 2, {NULL}, 0, 0, S_SHELL4}, // S_SHELL3 - {SPR_SHLL, 3, 2, {NULL}, 0, 0, S_SHELL1}, // S_SHELL4 + {SPR_SHLL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHELL // Puma (Mario fireball) - {SPR_PUMA, FF_FULLBRIGHT, 3, {A_FishJump}, 0, 0, S_PUMA2}, // S_PUMA1 - {SPR_PUMA, FF_FULLBRIGHT|1, 3, {A_FishJump}, 0, 0, S_PUMA3}, // S_PUMA2 - {SPR_PUMA, FF_FULLBRIGHT|2, 3, {A_FishJump}, 0, 0, S_PUMA1}, // S_PUMA3 - {SPR_PUMA, FF_FULLBRIGHT|3, 3, {A_FishJump}, 0, 0, S_PUMA5}, // S_PUMA4 - {SPR_PUMA, FF_FULLBRIGHT|4, 3, {A_FishJump}, 0, 0, S_PUMA6}, // S_PUMA5 - {SPR_PUMA, FF_FULLBRIGHT|5, 3, {A_FishJump}, 0, 0, S_PUMA4}, // S_PUMA6 + {SPR_PUMA, FF_FULLBRIGHT|2, 1, {A_FishJump}, 0, MT_PUMATRAIL, S_PUMA_START2}, // S_PUMA_START1 + {SPR_PUMA, FF_FULLBRIGHT|2, 1, {A_PlaySound}, sfx_s3k70, 1, S_PUMA_UP1}, // S_PUMA_START2 + {SPR_PUMA, FF_FULLBRIGHT , 2, {A_FishJump}, 0, MT_PUMATRAIL, S_PUMA_UP2}, // S_PUMA_UP1 + {SPR_PUMA, FF_FULLBRIGHT|1, 2, {A_FishJump}, 0, MT_PUMATRAIL, S_PUMA_UP3}, // S_PUMA_UP2 + {SPR_PUMA, FF_FULLBRIGHT|2, 2, {A_FishJump}, 0, MT_PUMATRAIL, S_PUMA_UP1}, // S_PUMA_UP3 + {SPR_PUMA, FF_FULLBRIGHT|3, 2, {A_FishJump}, 0, MT_PUMATRAIL, S_PUMA_DOWN2}, // S_PUMA_DOWN1 + {SPR_PUMA, FF_FULLBRIGHT|4, 2, {A_FishJump}, 0, MT_PUMATRAIL, S_PUMA_DOWN3}, // S_PUMA_DOWN2 + {SPR_PUMA, FF_FULLBRIGHT|5, 2, {A_FishJump}, 0, MT_PUMATRAIL, S_PUMA_DOWN1}, // S_PUMA_DOWN3 + + {SPR_PUMA, FF_FULLBRIGHT|FF_TRANS20|6, 4, {NULL}, 0, 0, S_PUMATRAIL2}, // S_PUMATRAIL1 + {SPR_PUMA, FF_FULLBRIGHT|FF_TRANS40|6, 5, {A_SetScale}, FRACUNIT, 1, S_PUMATRAIL3}, // S_PUMATRAIL2 + {SPR_PUMA, FF_FULLBRIGHT|FF_TRANS50|7, 4, {NULL}, 0, 0, S_PUMATRAIL4}, // S_PUMATRAIL3 + {SPR_PUMA, FF_FULLBRIGHT|FF_TRANS60|8, 3, {NULL}, 0, 0, S_NULL}, // S_PUMATRAIL4 // Hammer - {SPR_HAMM, 0, 3, {NULL}, 0, 0, S_HAMMER2}, // S_HAMMER1 - {SPR_HAMM, 1, 3, {NULL}, 0, 0, S_HAMMER3}, // S_HAMMER2 - {SPR_HAMM, 2, 3, {NULL}, 0, 0, S_HAMMER4}, // S_HAMMER3 - {SPR_HAMM, 3, 3, {NULL}, 0, 0, S_HAMMER1}, // S_HAMMER4 + {SPR_HAMM, FF_ANIMATE, -1, {NULL}, 4, 3, S_NULL}, // S_HAMMER // Koopa {SPR_KOOP, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KOOPA1 @@ -2139,8 +3543,8 @@ state_t states[NUMSTATES] = {SPR_TOAD, 0, -1, {NULL}, 0, 0, S_NULL}, // S_TOAD // Nights Drone - {SPR_NDRN, 0, -1, {NULL}, 0, 0, S_NIGHTSDRONE2}, // S_NIGHTSDRONE1 - {SPR_NDRN, 0, -1, {NULL}, 0, 0, S_NIGHTSDRONE1}, // S_NIGHTSDRONE2 + {SPR_NDRN, 0, -1, {NULL}, 0, 0, S_NIGHTSDRONE_MAN2}, // S_NIGHTSDRONE_MAN1 + {SPR_NDRN, 0, -1, {NULL}, 0, 0, S_NIGHTSDRONE_MAN1}, // S_NIGHTSDRONE_MAN2 // Sparkling point (RETURN TO THE GOAL, etc) {SPR_IVSP, 0, 1, {A_GhostMe}, 0, 0, S_NIGHTSDRONE_SPARKLING2}, // S_NIGHTSDRONE_SPARKLING1 @@ -2161,100 +3565,10 @@ state_t states[NUMSTATES] = {SPR_IVSP, 30, 1, {A_GhostMe}, 0, 0, S_NIGHTSDRONE_SPARKLING1}, // S_NIGHTSDRONE_SPARKLING16 // NiGHTS GOAL banner (inside the sparkles!) - {SPR_GOAL, 0, 4, {NULL}, 0, 0, S_NIGHTSGOAL2}, // S_NIGHTSGOAL1 - {SPR_GOAL, 1, 4, {NULL}, 0, 0, S_NIGHTSGOAL3}, // S_NIGHTSGOAL2 - {SPR_GOAL, 2, 4, {NULL}, 0, 0, S_NIGHTSGOAL4}, // S_NIGHTSGOAL3 - {SPR_GOAL, 3, 4, {NULL}, 0, 0, S_NIGHTSGOAL1}, // S_NIGHTSGOAL4 - - // Nights Player, Flying and Drilling - {SPR_SUPE, 0, 1, {NULL}, 0, 0, S_NIGHTSFLY1B}, // S_NIGHTSFLY1A - {SPR_SUPE, 1, 1, {NULL}, 0, 0, S_NIGHTSFLY1A}, // S_NIGHTSFLY1B - {SPR_NDRL, 0, 2, {NULL}, 0, 0, S_NIGHTSDRILL1B}, // S_NIGHTSDRILL1A - {SPR_NDRL, 1, 2, {NULL}, 0, 0, S_NIGHTSDRILL1C}, // S_NIGHTSDRILL1B - {SPR_NDRL, 2, 2, {NULL}, 0, 0, S_NIGHTSDRILL1D}, // S_NIGHTSDRILL1C - {SPR_NDRL, 3, 2, {NULL}, 0, 0, S_NIGHTSDRILL1A}, // S_NIGHTSDRILL1D - {SPR_SUPE, 2, 1, {NULL}, 0, 0, S_NIGHTSFLY2B}, // S_NIGHTSFLY2A - {SPR_SUPE, 3, 1, {NULL}, 0, 0, S_NIGHTSFLY2A}, // S_NIGHTSFLY2B - {SPR_NDRL, 4, 2, {NULL}, 0, 0, S_NIGHTSDRILL2B}, // S_NIGHTSDRILL2A - {SPR_NDRL, 5, 2, {NULL}, 0, 0, S_NIGHTSDRILL2C}, // S_NIGHTSDRILL2B - {SPR_NDRL, 6, 2, {NULL}, 0, 0, S_NIGHTSDRILL2D}, // S_NIGHTSDRILL2C - {SPR_NDRL, 7, 2, {NULL}, 0, 0, S_NIGHTSDRILL2A}, // S_NIGHTSDRILL2D - {SPR_SUPE, 4, 1, {NULL}, 0, 0, S_NIGHTSFLY3B}, // S_NIGHTSFLY3A - {SPR_SUPE, 5, 1, {NULL}, 0, 0, S_NIGHTSFLY3A}, // S_NIGHTSFLY3B - {SPR_NDRL, 8, 2, {NULL}, 0, 0, S_NIGHTSDRILL3B}, // S_NIGHTSDRILL3A - {SPR_NDRL, 9, 2, {NULL}, 0, 0, S_NIGHTSDRILL3C}, // S_NIGHTSDRILL3B - {SPR_NDRL, 10, 2, {NULL}, 0, 0, S_NIGHTSDRILL3D}, // S_NIGHTSDRILL3C - {SPR_NDRL, 11, 2, {NULL}, 0, 0, S_NIGHTSDRILL3A}, // S_NIGHTSDRILL3D - {SPR_SUPE, 6, 1, {NULL}, 0, 0, S_NIGHTSFLY4B}, // S_NIGHTSFLY4A - {SPR_SUPE, 7, 1, {NULL}, 0, 0, S_NIGHTSFLY4A}, // S_NIGHTSFLY4B - {SPR_NDRL, 12, 2, {NULL}, 0, 0, S_NIGHTSDRILL4B}, // S_NIGHTSDRILL4A - {SPR_NDRL, 13, 2, {NULL}, 0, 0, S_NIGHTSDRILL4C}, // S_NIGHTSDRILL4B - {SPR_NDRL, 14, 2, {NULL}, 0, 0, S_NIGHTSDRILL4D}, // S_NIGHTSDRILL4C - {SPR_NDRL, 15, 2, {NULL}, 0, 0, S_NIGHTSDRILL4A}, // S_NIGHTSDRILL4D - {SPR_SUPE, 8, 1, {NULL}, 0, 0, S_NIGHTSFLY5B}, // S_NIGHTSFLY5A - {SPR_SUPE, 9, 1, {NULL}, 0, 0, S_NIGHTSFLY5A}, // S_NIGHTSFLY5B - {SPR_NDRL, 16, 2, {NULL}, 0, 0, S_NIGHTSDRILL5B}, // S_NIGHTSDRILL5A - {SPR_NDRL, 17, 2, {NULL}, 0, 0, S_NIGHTSDRILL5C}, // S_NIGHTSDRILL5B - {SPR_NDRL, 18, 2, {NULL}, 0, 0, S_NIGHTSDRILL5D}, // S_NIGHTSDRILL5C - {SPR_NDRL, 19, 2, {NULL}, 0, 0, S_NIGHTSDRILL5A}, // S_NIGHTSDRILL5D - {SPR_SUPE, 10, 1, {NULL}, 0, 0, S_NIGHTSFLY6B}, // S_NIGHTSFLY6A - {SPR_SUPE, 11, 1, {NULL}, 0, 0, S_NIGHTSFLY6A}, // S_NIGHTSFLY6B - {SPR_NDRL, 20, 2, {NULL}, 0, 0, S_NIGHTSDRILL6B}, // S_NIGHTSDRILL6A - {SPR_NDRL, 21, 2, {NULL}, 0, 0, S_NIGHTSDRILL6C}, // S_NIGHTSDRILL6B - {SPR_NDRL, 22, 2, {NULL}, 0, 0, S_NIGHTSDRILL6D}, // S_NIGHTSDRILL6C - {SPR_NDRL, 23, 2, {NULL}, 0, 0, S_NIGHTSDRILL6A}, // S_NIGHTSDRILL6D - {SPR_SUPE, 12, 1, {NULL}, 0, 0, S_NIGHTSFLY7B}, // S_NIGHTSFLY7A - {SPR_SUPE, 13, 1, {NULL}, 0, 0, S_NIGHTSFLY7A}, // S_NIGHTSFLY7B - {SPR_NDRL, 24, 2, {NULL}, 0, 0, S_NIGHTSDRILL7B}, // S_NIGHTSDRILL7A - {SPR_NDRL, 25, 2, {NULL}, 0, 0, S_NIGHTSDRILL7C}, // S_NIGHTSDRILL7B - {SPR_NDRL, 26, 2, {NULL}, 0, 0, S_NIGHTSDRILL7D}, // S_NIGHTSDRILL7C - {SPR_NDRL, 27, 2, {NULL}, 0, 0, S_NIGHTSDRILL7A}, // S_NIGHTSDRILL7D - {SPR_SUPE, 14, 1, {NULL}, 0, 0, S_NIGHTSFLY8B}, // S_NIGHTSFLY8A - {SPR_SUPE, 15, 1, {NULL}, 0, 0, S_NIGHTSFLY8A}, // S_NIGHTSFLY8B - {SPR_NDRL, 28, 2, {NULL}, 0, 0, S_NIGHTSDRILL8B}, // S_NIGHTSDRILL8A - {SPR_NDRL, 29, 2, {NULL}, 0, 0, S_NIGHTSDRILL8C}, // S_NIGHTSDRILL8B - {SPR_NDRL, 30, 2, {NULL}, 0, 0, S_NIGHTSDRILL8D}, // S_NIGHTSDRILL8C - {SPR_NDRL, 31, 2, {NULL}, 0, 0, S_NIGHTSDRILL8A}, // S_NIGHTSDRILL8D - {SPR_SUPE, 16, 1, {NULL}, 0, 0, S_NIGHTSFLY9B}, // S_NIGHTSFLY9A - {SPR_SUPE, 17, 1, {NULL}, 0, 0, S_NIGHTSFLY9A}, // S_NIGHTSFLY9B - {SPR_NDRL, 32, 2, {NULL}, 0, 0, S_NIGHTSDRILL9B}, // S_NIGHTSDRILL9A - {SPR_NDRL, 33, 2, {NULL}, 0, 0, S_NIGHTSDRILL9C}, // S_NIGHTSDRILL9B - {SPR_NDRL, 34, 2, {NULL}, 0, 0, S_NIGHTSDRILL9D}, // S_NIGHTSDRILL9C - {SPR_NDRL, 35, 2, {NULL}, 0, 0, S_NIGHTSDRILL9A}, // S_NIGHTSDRILL9D - - // Nights Player, Falling - {SPR_SUPZ, 0, 1, {NULL}, 0, 0, S_NIGHTSHURT2}, // S_NIGHTSHURT1 - {SPR_SUPZ, 1, 1, {NULL}, 0, 0, S_NIGHTSHURT3}, // S_NIGHTSHURT2 - {SPR_SUPZ, 2, 1, {NULL}, 0, 0, S_NIGHTSHURT4}, // S_NIGHTSHURT3 - {SPR_SUPZ, 3, 1, {NULL}, 0, 0, S_NIGHTSHURT5}, // S_NIGHTSHURT4 - {SPR_SUPZ, 4, 1, {NULL}, 0, 0, S_NIGHTSHURT6}, // S_NIGHTSHURT5 - {SPR_SUPZ, 5, 1, {NULL}, 0, 0, S_NIGHTSHURT7}, // S_NIGHTSHURT6 - {SPR_SUPZ, 6, 1, {NULL}, 0, 0, S_NIGHTSHURT8}, // S_NIGHTSHURT7 - {SPR_SUPZ, 7, 1, {NULL}, 0, 0, S_NIGHTSHURT9}, // S_NIGHTSHURT8 - {SPR_SUPZ, 8, 1, {NULL}, 0, 0, S_NIGHTSHURT10}, // S_NIGHTSHURT9 - {SPR_SUPZ, 9, 1, {NULL}, 0, 0, S_NIGHTSHURT11}, // S_NIGHTSHURT10 - {SPR_SUPZ, 10, 1, {NULL}, 0, 0, S_NIGHTSHURT12}, // S_NIGHTSHURT11 - {SPR_SUPZ, 11, 1, {NULL}, 0, 0, S_NIGHTSHURT13}, // S_NIGHTSHURT12 - {SPR_SUPZ, 12, 1, {NULL}, 0, 0, S_NIGHTSHURT14}, // S_NIGHTSHURT13 - {SPR_SUPZ, 13, 1, {NULL}, 0, 0, S_NIGHTSHURT15}, // S_NIGHTSHURT14 - {SPR_SUPZ, 14, 1, {NULL}, 0, 0, S_NIGHTSHURT16}, // S_NIGHTSHURT15 - {SPR_SUPZ, 15, 1, {NULL}, 0, 0, S_NIGHTSHURT17}, // S_NIGHTSHURT16 - {SPR_SUPZ, 0, 1, {NULL}, 0, 0, S_NIGHTSHURT18}, // S_NIGHTSHURT17 - {SPR_SUPZ, 1, 1, {NULL}, 0, 0, S_NIGHTSHURT19}, // S_NIGHTSHURT18 - {SPR_SUPZ, 2, 1, {NULL}, 0, 0, S_NIGHTSHURT20}, // S_NIGHTSHURT19 - {SPR_SUPZ, 3, 1, {NULL}, 0, 0, S_NIGHTSHURT21}, // S_NIGHTSHURT20 - {SPR_SUPZ, 4, 1, {NULL}, 0, 0, S_NIGHTSHURT22}, // S_NIGHTSHURT21 - {SPR_SUPZ, 5, 1, {NULL}, 0, 0, S_NIGHTSHURT23}, // S_NIGHTSHURT22 - {SPR_SUPZ, 6, 1, {NULL}, 0, 0, S_NIGHTSHURT24}, // S_NIGHTSHURT23 - {SPR_SUPZ, 7, 1, {NULL}, 0, 0, S_NIGHTSHURT25}, // S_NIGHTSHURT24 - {SPR_SUPZ, 8, 1, {NULL}, 0, 0, S_NIGHTSHURT26}, // S_NIGHTSHURT25 - {SPR_SUPZ, 9, 1, {NULL}, 0, 0, S_NIGHTSHURT27}, // S_NIGHTSHURT26 - {SPR_SUPZ, 10, 1, {NULL}, 0, 0, S_NIGHTSHURT28}, // S_NIGHTSHURT27 - {SPR_SUPZ, 11, 1, {NULL}, 0, 0, S_NIGHTSHURT29}, // S_NIGHTSHURT28 - {SPR_SUPZ, 12, 1, {NULL}, 0, 0, S_NIGHTSHURT30}, // S_NIGHTSHURT29 - {SPR_SUPZ, 13, 1, {NULL}, 0, 0, S_NIGHTSHURT31}, // S_NIGHTSHURT30 - {SPR_SUPZ, 14, 1, {NULL}, 0, 0, S_NIGHTSHURT32}, // S_NIGHTSHURT31 - {SPR_SUPZ, 15, 1, {NULL}, 0, 0, S_NIGHTSFLY1A}, // S_NIGHTSHURT32 + {SPR_GOAL, 0, 4, {NULL}, 0, 0, S_NIGHTSDRONE_GOAL2}, // S_NIGHTSDRONE_GOAL1 + {SPR_GOAL, 1, 4, {NULL}, 0, 0, S_NIGHTSDRONE_GOAL3}, // S_NIGHTSDRONE_GOAL2 + {SPR_GOAL, 2, 4, {NULL}, 0, 0, S_NIGHTSDRONE_GOAL4}, // S_NIGHTSDRONE_GOAL3 + {SPR_GOAL, 3, 4, {NULL}, 0, 0, S_NIGHTSDRONE_GOAL1}, // S_NIGHTSDRONE_GOAL4 // Nights Sparkle {SPR_NSPK, FF_FULLBRIGHT, 140, {NULL}, 0, 0, S_NIGHTSPARKLE2}, // S_NIGHTSPARKLE1 @@ -2310,24 +3624,16 @@ state_t states[NUMSTATES] = {SPR_NSCR, FF_FULLBRIGHT|18, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSCORE90_2 {SPR_NSCR, FF_FULLBRIGHT|19, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSCORE100_2 - {SPR_NWNG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSWING - {SPR_NWNG, 1, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSWING_XMAS - // NiGHTS Paraloop Powerups - {SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP1 - {SPR_NPRU, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP2 - {SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP3 - {SPR_NPRU, 1, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP4 - {SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP5 - {SPR_NPRU, 2, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP6 - {SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP7 - {SPR_NPRU, 3, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP8 - {SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP9 - {SPR_NPRU, 4, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP10 + {SPR_NPRU, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSSUPERLOOP + {SPR_NPRU, 1, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSDRILLREFILL + {SPR_NPRU, 2, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSHELPER + {SPR_NPRU, 3, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSEXTRATIME + {SPR_NPRU, 4, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSLINKFREEZE {SPR_CAPS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGCAPSULE - // Orbiting Chaos Emeralds for NiGHTS + // Orbiting Chaos Emeralds/Ideya for NiGHTS {SPR_CEMG, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM1}, // S_ORBITEM1 {SPR_CEMG, FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM2}, // S_ORBITEM2 {SPR_CEMG, FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM3}, // S_ORBITEM3 @@ -2336,37 +3642,161 @@ state_t states[NUMSTATES] = {SPR_CEMG, FF_FULLBRIGHT|5, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6 {SPR_CEMG, FF_FULLBRIGHT|6, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7 {SPR_CEMG, FF_FULLBRIGHT|7, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8 - {SPR_CEMG, FF_FULLBRIGHT|8, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM9 - {SPR_CEMG, FF_FULLBRIGHT|9, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM10 - {SPR_CEMG, FF_FULLBRIGHT|10, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM11 - {SPR_CEMG, FF_FULLBRIGHT|11, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM12 - {SPR_CEMG, FF_FULLBRIGHT|12, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM13 - {SPR_CEMG, FF_FULLBRIGHT|13, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM14 - {SPR_CEMG, FF_FULLBRIGHT|14, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM15 - {SPR_CEMG, FF_FULLBRIGHT|15, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM16 + {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA1}, // S_ORBIDYA1 + {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA2}, // S_ORBIDYA2 + {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA3}, // S_ORBIDYA3 + {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA4}, // S_ORBIDYA4 + {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA5}, // S_ORBIDYA5 // Flicky helper for NiGHTS - {SPR_BIRD, 0, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER2}, // S_NIGHTOPIANHELPER1 - {SPR_BIRD, 0, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER3}, // S_NIGHTOPIANHELPER2 - {SPR_BIRD, 0, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER4}, // S_NIGHTOPIANHELPER3 - {SPR_BIRD, 0, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER5}, // S_NIGHTOPIANHELPER4 - {SPR_BIRD, 1, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER6}, // S_NIGHTOPIANHELPER5 - {SPR_BIRD, 1, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER7}, // S_NIGHTOPIANHELPER6 - {SPR_BIRD, 1, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER8}, // S_NIGHTOPIANHELPER7 - {SPR_BIRD, 1, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER1}, // S_NIGHTOPIANHELPER8 - - {SPR_NULL, 0, 35, {NULL}, 0, 0, S_CRUMBLE2}, // S_CRUMBLE1 - {SPR_NULL, 0, 105, {A_Scream}, 0, 0, S_NULL}, // S_CRUMBLE2 + {SPR_FL01, 1, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER2}, // S_NIGHTOPIANHELPER1 + {SPR_FL01, 1, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER3}, // S_NIGHTOPIANHELPER2 + {SPR_FL01, 1, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER4}, // S_NIGHTOPIANHELPER3 + {SPR_FL01, 2, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER5}, // S_NIGHTOPIANHELPER4 + {SPR_FL01, 2, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER6}, // S_NIGHTOPIANHELPER5 + {SPR_FL01, 2, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER7}, // S_NIGHTOPIANHELPER6 + {SPR_FL01, 3, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER8}, // S_NIGHTOPIANHELPER7 + {SPR_FL01, 3, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER9}, // S_NIGHTOPIANHELPER8 + {SPR_FL01, 3, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER1}, // S_NIGHTOPIANHELPER9 + + // Nightopian + {SPR_NTPN, 0, 4, {A_Look}, 0, 0, S_PIAN0}, // S_PIAN0 + {SPR_NTPN, 0, 4, {A_JetgThink}, 0, 0, S_PIAN2}, // S_PIAN1 + {SPR_NTPN, 1, 4, {NULL}, 0, 0, S_PIAN3}, // S_PIAN2 + {SPR_NTPN, 2, 4, {NULL}, 0, 0, S_PIAN4}, // S_PIAN3 + {SPR_NTPN, 3, 4, {NULL}, 0, 0, S_PIAN5}, // S_PIAN4 + {SPR_NTPN, 2, 4, {NULL}, 0, 0, S_PIAN6}, // S_PIAN5 + {SPR_NTPN, 1, 4, {NULL}, 0, 0, S_PIAN1}, // S_PIAN6 + {SPR_NTPN, 5|FF_ANIMATE, 4, {NULL}, 1, 4, S_PIAN1}, // S_PIANSING + + // Shleep + {SPR_SHLP, 0, 15, {NULL}, 0, 0, S_SHLEEP2}, // S_SHLEEP1 + {SPR_SHLP, 1, 15, {NULL}, 0, 0, S_SHLEEP3}, // S_SHLEEP2 + {SPR_SHLP, 2, 15, {NULL}, 0, 0, S_SHLEEP4}, // S_SHLEEP3 + {SPR_SHLP, 1, 15, {NULL}, 0, 0, S_SHLEEP1}, // S_SHLEEP4 + {SPR_SHLP, 3, 1, {A_Scream}, 0, 0, S_SHLEEPBOUNCE2}, // S_SHLEEPBOUNCE1 + {SPR_SHLP, 3, 1, {A_ZThrust}, 9, 0, S_SHLEEPBOUNCE3}, // S_SHLEEPBOUNCE2 + {SPR_SHLP, 3, 400, {A_SetObjectFlags}, MF_SLIDEME|MF_ENEMY|MF_BOUNCE|MF_NOCLIP|MF_NOCLIPHEIGHT, 0, S_NULL}, // S_SHLEEPBOUNCE3 + + // Secret badniks and hazards, shhhh + {SPR_PENG, 0, 2, {A_Look}, 0, 0, S_PENGUINATOR_LOOK}, // S_PENGUINATOR_LOOK + {SPR_PENG, 0, 2, {A_Chase}, 0, 0, S_PENGUINATOR_WADDLE2}, // S_PENGUINATOR_WADDLE1 + {SPR_PENG, 1, 2, {A_Chase}, 0, 0, S_PENGUINATOR_WADDLE3}, // S_PENGUINATOR_WADDLE2 + {SPR_PENG, 0, 2, {A_Chase}, 0, 0, S_PENGUINATOR_WADDLE4}, // S_PENGUINATOR_WADDLE3 + {SPR_PENG, 2, 2, {A_Chase}, 0, 0, S_PENGUINATOR_WADDLE1}, // S_PENGUINATOR_WADDLE4 + {SPR_PENG, 0, 0, {A_FaceTarget}, 0, 0, S_PENGUINATOR_SLIDE2}, // S_PENGUINATOR_SLIDE1 + {SPR_PENG, 3, 5, {A_BunnyHop}, 4, 10, S_PENGUINATOR_SLIDE3}, // S_PENGUINATOR_SLIDE2 + {SPR_PENG, 4, 90, {A_PlayAttackSound}, 0, 0, S_PENGUINATOR_SLIDE4}, // S_PENGUINATOR_SLIDE3 + {SPR_PENG, 3, 5, {A_Thrust}, 0, 1, S_PENGUINATOR_SLIDE5}, // S_PENGUINATOR_SLIDE4 + {SPR_PENG, 0, 5, {A_FaceTarget}, 0, 0, S_PENGUINATOR_LOOK}, // S_PENGUINATOR_SLIDE5 + + {SPR_POPH, 0, 2, {A_Look}, (2048<<16)|1, 0, S_POPHAT_LOOK}, // S_POPHAT_LOOK + {SPR_POPH, 1, 2, {A_LobShot}, MT_POPSHOT, (70<<16)|60, S_POPHAT_SHOOT2}, // S_POPHAT_SHOOT1 + {SPR_POPH, 2, 1, {NULL}, 0, 0, S_POPHAT_SHOOT3}, // S_POPHAT_SHOOT2 + {SPR_POPH, 0, 57, {NULL}, 0, 0, S_POPHAT_LOOK}, // S_POPHAT_SHOOT3 + + {SPR_HIVE, 0, 5, {A_Look}, 1, 1, S_HIVEELEMENTAL_LOOK}, // S_HIVEELEMENTAL_LOOK + {SPR_HIVE, 0, 14, {A_PlaySound}, sfx_s3k76, 1, S_HIVEELEMENTAL_PREPARE2}, // S_HIVEELEMENTAL_PREPARE1 + {SPR_HIVE, 0, 6, {A_PlaySound}, sfx_s3k8c, 1, S_HIVEELEMENTAL_SHOOT1}, // S_HIVEELEMENTAL_PREPARE2 + {SPR_HIVE, 1, 4, {A_WhoCaresIfYourSonIsABee}, (MT_BUMBLEBORE<<16)|4, (1<<16)|32, S_HIVEELEMENTAL_SHOOT2}, // S_HIVEELEMENTAL_SHOOT1 + {SPR_HIVE, 2, 2, {NULL}, 0, 0, S_HIVEELEMENTAL_DORMANT}, // S_HIVEELEMENTAL_SHOOT2 + {SPR_HIVE, 0, 5, {A_ParentTriesToSleep}, S_HIVEELEMENTAL_PREPARE1, 0, S_HIVEELEMENTAL_DORMANT}, // S_HIVEELEMENTAL_DORMANT + {SPR_HIVE, 3, 35, {A_Pain}, 0, 0, S_HIVEELEMENTAL_LOOK}, // S_HIVEELEMENTAL_PAIN + {SPR_HIVE, 3, 2, {A_BossScream}, 1, MT_SONIC3KBOSSEXPLODE, S_HIVEELEMENTAL_DIE2}, // S_HIVEELEMENTAL_DIE1 + {SPR_NULL, 0, 2, {A_BossScream}, 1, MT_SONIC3KBOSSEXPLODE, S_HIVEELEMENTAL_DIE3}, // S_HIVEELEMENTAL_DIE2 + {SPR_NULL, 0, 0, {A_Repeat}, 7, S_HIVEELEMENTAL_DIE1, S_XPLD_FLICKY}, // S_HIVEELEMENTAL_DIE3 + + {SPR_BUMB, 1, 10, {NULL}, 0, 0, S_BUMBLEBORE_LOOK1}, // S_BUMBLEBORE_SPAWN + {SPR_BUMB, 0, 4, {A_Look}, 1, 1, S_BUMBLEBORE_LOOK2}, // S_BUMBLEBORE_LOOK1 + {SPR_BUMB, 1, 4, {A_Look}, 1, 1, S_BUMBLEBORE_LOOK1}, // S_BUMBLEBORE_LOOK2 + {SPR_BUMB, 0, 4, {A_JetbThink}, 0, 0, S_BUMBLEBORE_FLY2}, // S_BUMBLEBORE_FLY1 + {SPR_BUMB, 1, 4, {A_JetbThink}, 0, 0, S_BUMBLEBORE_FLY1}, // S_BUMBLEBORE_FLY2 + {SPR_BUMB, 2|FF_FULLBRIGHT, 12, {A_ZThrust}, 4, (1<<16)|1, S_BUMBLEBORE_FALL1}, // S_BUMBLEBORE_RAISE + {SPR_BUMB, 2|FF_FULLBRIGHT, 0, {A_ZThrust}, -8, (1<<16)|1, S_BUMBLEBORE_FALL2}, // S_BUMBLEBORE_FALL1 + {SPR_BUMB, 2|FF_FULLBRIGHT, 300, {NULL}, 0, 0, S_BUMBLEBORE_DIE}, // S_BUMBLEBORE_FALL2 + {SPR_BUMB, 4, 3, {A_MultiShotDist}, (MT_DUST<<16)|6, -40, S_BUMBLEBORE_STUCK2}, // S_BUMBLEBORE_STUCK1 + {SPR_BUMB, 5, 120, {NULL}, 0, 0, S_BUMBLEBORE_DIE}, // S_BUMBLEBORE_STUCK2 + {SPR_BUMB, 5, 0, {A_CryingToMomma}, 0, 0, S_XPLD1}, // S_BUMBLEBORE_DIE + + {SPR_BBUZ, 0, 2, {NULL}, 0, 0, S_BBUZZFLY2}, // S_BBUZZFLY1 + {SPR_BBUZ, 1, 2, {NULL}, 0, 0, S_BBUZZFLY1}, // S_BBUZZFLY2 - {SPR_SUPT, 0, 4, {A_Scream}, 0, 0, S_SUPERTRANS2}, // S_SUPERTRANS1 - {SPR_SUPT, 1, 4, {NULL}, 0, 0, S_SUPERTRANS3}, // S_SUPERTRANS2 - {SPR_SUPT, FF_FULLBRIGHT|2, 4, {NULL}, 0, 0, S_SUPERTRANS4}, // S_SUPERTRANS3 - {SPR_SUPT, 3, 3, {NULL}, 0, 0, S_SUPERTRANS5}, // S_SUPERTRANS4 - {SPR_SUPT, 4, 3, {NULL}, 0, 0, S_SUPERTRANS6}, // S_SUPERTRANS5 - {SPR_SUPT, 5, 3, {NULL}, 0, 0, S_SUPERTRANS7}, // S_SUPERTRANS6 - {SPR_SUPT, 6, 3, {NULL}, 0, 0, S_SUPERTRANS8}, // S_SUPERTRANS7 - {SPR_SUPT, 7, 3, {NULL}, 0, 0, S_SUPERTRANS9}, // S_SUPERTRANS8 - {SPR_SUPT, 8, 16, {NULL}, 0, 0, S_NIGHTSDRONE1}, // S_SUPERTRANS9 + {SPR_FMCE, 0, 20, {NULL}, 0, 0, S_SMASHSPIKE_EASE1}, // S_SMASHSPIKE_FLOAT + {SPR_FMCE, 0, 4, {A_ZThrust}, 4, (1<<16)|1, S_SMASHSPIKE_EASE2}, // S_SMASHSPIKE_EASE1 + {SPR_FMCE, 0, 4, {A_ZThrust}, 0, (1<<16)|1, S_SMASHSPIKE_FALL}, // S_SMASHSPIKE_EASE2 + {SPR_FMCE, 0, 2, {A_ZThrust}, -6, 1, S_SMASHSPIKE_FALL}, // S_SMASHSPIKE_FALL + {SPR_FMCE, 1, 2, {A_MultiShotDist}, (MT_DUST<<16)|10, -48, S_SMASHSPIKE_STOMP2}, // S_SMASHSPIKE_STOMP1 + {SPR_FMCE, 2, 14, {NULL}, 0, 0, S_SMASHSPIKE_RISE1}, // S_SMASHSPIKE_STOMP2 + {SPR_FMCE, 1, 2, {NULL}, 0, 0, S_SMASHSPIKE_RISE2}, // S_SMASHSPIKE_RISE1 + {SPR_FMCE, 0, 2, {A_ZThrust}, 6, (1<<16)|1, S_SMASHSPIKE_RISE2}, // S_SMASHSPIKE_RISE2 + + {SPR_CACO, 0, 5, {A_Look}, (1100<<16)|1, 0, S_CACO_LOOK}, // S_CACO_LOOK + {SPR_CACO, 1, 0, {A_MultiShotDist}, (MT_DUST<<16)|7, -48, S_CACO_WAKE2}, // S_CACO_WAKE1 + {SPR_CACO, 1, 10, {A_ZThrust}, 4, (1<<16)|1, S_CACO_WAKE3}, // S_CACO_WAKE2 + {SPR_CACO, 2, 8, {A_ZThrust}, 2, (1<<16)|1, S_CACO_WAKE4}, // S_CACO_WAKE3 + {SPR_CACO, 2, 4, {A_ZThrust}, 0, (1<<16)|1, S_CACO_ROAR}, // S_CACO_WAKE4 + {SPR_CACO, 2, 10, {A_PlayActiveSound}, 0, 0, S_CACO_CHASE}, // S_CACO_ROAR + {SPR_CACO, 2, 5, {A_JetChase}, 0, 0, S_CACO_CHASE_REPEAT}, // S_CACO_CHASE + {SPR_CACO, 2, 0, {A_Repeat}, 5, S_CACO_CHASE, S_CACO_RANDOM}, // S_CACO_CHASE_REPEAT + {SPR_CACO, 2, 0, {A_RandomState}, S_CACO_PREPARE_SOUND, S_CACO_CHASE, S_CACO_RANDOM}, // S_CACO_RANDOM + {SPR_CACO, 2, 8, {A_PlaySound}, sfx_s3k95, 1, S_CACO_PREPARE1}, // S_CACO_PREPARE_SOUND + {SPR_CACO, 3, 8, {NULL}, 0, 0, S_CACO_PREPARE2}, // S_CACO_PREPARE1 + {SPR_CACO, 4|FF_FULLBRIGHT, 8, {NULL}, 0, 0, S_CACO_PREPARE3}, // S_CACO_PREPARE2 + {SPR_CACO, 5|FF_FULLBRIGHT, 8, {NULL}, 0, 0, S_CACO_SHOOT_SOUND}, // S_CACO_PREPARE3 + {SPR_CACO, 4|FF_FULLBRIGHT, 0, {A_PlaySound}, sfx_s3k4e, 1, S_CACO_SHOOT1}, // S_CACO_SHOOT_SOUND + {SPR_CACO, 4|FF_FULLBRIGHT, 0, {A_SpawnParticleRelative}, 0, S_CACOFIRE_EXPLODE1, S_CACO_SHOOT2}, // S_CACO_SHOOT1 + {SPR_CACO, 4|FF_FULLBRIGHT, 6, {A_FireShot}, MT_CACOFIRE, -24, S_CACO_CLOSE}, // S_CACO_SHOOT2 + {SPR_CACO, 3, 15, {NULL}, 0, 0, S_CACO_CHASE}, // S_CACO_CLOSE + {SPR_CACO, 10, 0, {A_SetObjectFlags}, MF_NOBLOCKMAP, 0, S_CACO_DIE_GIB1}, // S_CACO_DIE_FLAGS + {SPR_CACO, 10, 0, {A_NapalmScatter}, (7<<16)|MT_CACOSHARD, (30<<16)|20, S_CACO_DIE_GIB2}, // S_CACO_DIE_GIB1 + {SPR_CACO, 10, 0, {A_NapalmScatter}, (10<<16)|MT_CACOSHARD, (24<<16)|32, S_CACO_DIE_SCREAM}, // S_CACO_DIE_GIB2 + {SPR_CACO, 10, 0, {A_Scream}, 0, 0, S_CACO_DIE_SHATTER}, // S_CACO_DIE_SCREAM + {SPR_CACO, 10, 0, {A_PlaySound}, sfx_pumpkn, 1, S_CACO_DIE_FALL}, // S_CACO_DIE_SHATTER + {SPR_CACO, 10, 250, {A_FlickySpawn}, (1<<16), 0, S_NULL}, // S_CACO_DIE_FALL + + {SPR_CACO, 6, 0, {A_RandomState}, S_CACOSHARD1_1, S_CACOSHARD2_1, S_NULL}, // S_CACOSHARD_RANDOMIZE + {SPR_CACO, 6, 3, {NULL}, 0, 0, S_CACOSHARD1_2}, // S_CACOSHARD1_1 + {SPR_CACO, 7, 3, {NULL}, 0, 0, S_CACOSHARD1_1}, // S_CACOSHARD1_2 + {SPR_CACO, 8, 3, {NULL}, 0, 0, S_CACOSHARD2_2}, // S_CACOSHARD2_1 + {SPR_CACO, 9, 3, {NULL}, 0, 0, S_CACOSHARD2_1}, // S_CACOSHARD2_2 + {SPR_BAL2, FF_FULLBRIGHT, 2, {A_GhostMe}, 0, 0, S_CACOFIRE2}, // S_CACOFIRE1 + {SPR_BAL2, 1|FF_FULLBRIGHT, 2, {A_GhostMe}, 0, 0, S_CACOFIRE3}, // S_CACOFIRE2 + {SPR_BAL2, FF_FULLBRIGHT, 0, {A_PlayActiveSound}, 0, 0, S_CACOFIRE1}, // S_CACOFIRE3 + {SPR_BAL2, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_CACOFIRE_EXPLODE2}, // S_CACOFIRE_EXPLODE1 + {SPR_BAL2, 3|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_CACOFIRE_EXPLODE3}, // S_CACOFIRE_EXPLODE2 + {SPR_BAL2, 4|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_CACOFIRE_EXPLODE4}, // S_CACOFIRE_EXPLODE3 + {SPR_BAL2, 5|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_CACOFIRE_EXPLODE4 + + {SPR_SBOB, 1, 10, {A_ZThrust}, -2, (1<<16)|1, S_SPINBOBERT_MOVE_UP}, // S_SPINBOBERT_MOVE_FLIPUP + {SPR_SBOB, 0, 45, {A_ZThrust}, 4, (1<<16)|1, S_SPINBOBERT_MOVE_FLIPDOWN}, // S_SPINBOBERT_MOVE_UP + {SPR_SBOB, 1, 10, {A_ZThrust}, 2, (1<<16)|1, S_SPINBOBERT_MOVE_DOWN}, // S_SPINBOBERT_MOVE_FLIPDOWN + {SPR_SBOB, 2, 45, {A_ZThrust}, -4, (1<<16)|1, S_SPINBOBERT_MOVE_FLIPUP}, // S_SPINBOBERT_MOVE_DOWN + {SPR_SBSK, FF_FULLBRIGHT, 1, {A_RotateSpikeBall}, 0, 0, S_SPINBOBERT_FIRE_GHOST}, // S_SPINBOBERT_FIRE_MOVE + {SPR_SBSK, FF_FULLBRIGHT, 0, {A_SpawnParticleRelative}, 0, S_SPINBOBERT_FIRE_TRAIL1, S_SPINBOBERT_FIRE_MOVE}, // S_SPINBOBERT_FIRE_GHOST + {SPR_SBFL, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SPINBOBERT_FIRE_TRAIL2}, // S_SPINBOBERT_FIRE_TRAIL1 + {SPR_SBFL, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SPINBOBERT_FIRE_TRAIL3}, // S_SPINBOBERT_FIRE_TRAIL2 + {SPR_SBFL, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_SPINBOBERT_FIRE_TRAIL3 + + {SPR_HBAT, 0, 5, {A_Look}, (900<<16)|1, 0, S_HANGSTER_LOOK}, // S_HANGSTER_LOOK + {SPR_HBAT, 1, 0, {A_MultiShotDist}, (MT_DUST<<16)|10, -34, S_HANGSTER_SWOOP2}, // S_HANGSTER_SWOOP1 + {SPR_HBAT, 1, 2, {A_ZThrust}, -8, (1<<16)|1, S_HANGSTER_SWOOP2}, // S_HANGSTER_SWOOP2 + {SPR_HBAT, 1, 6, {A_ZThrust}, -5, (1<<16), S_HANGSTER_ARC2}, // S_HANGSTER_ARC1 + {SPR_HBAT, 1, 5, {A_ZThrust}, -2, (1<<16), S_HANGSTER_ARC3}, // S_HANGSTER_ARC2 + {SPR_HBAT, 1, 1, {A_ZThrust}, 0, (1<<16), S_HANGSTER_FLY1}, // S_HANGSTER_ARC3 + {SPR_HBAT, 1, 4, {A_Thrust}, 6, 1, S_HANGSTER_FLY2}, // S_HANGSTER_FLY1 + {SPR_HBAT, 2, 1, {A_PlaySound}, sfx_s3k52, 1, S_HANGSTER_FLY3}, // S_HANGSTER_FLY2 + {SPR_HBAT, 3, 4, {A_Thrust}, 6, 1, S_HANGSTER_FLY4}, // S_HANGSTER_FLY3 + {SPR_HBAT, 2, 1, {A_Thrust}, 6, 1, S_HANGSTER_FLYREPEAT}, // S_HANGSTER_FLY4 + {SPR_HBAT, 2, 0, {A_Repeat}, 12, S_HANGSTER_FLY1, S_HANGSTER_ARCUP1}, // S_HANGSTER_FLYREPEAT + {SPR_HBAT, 1, 5, {A_ZThrust}, 2, (1<<16), S_HANGSTER_ARCUP2}, // S_HANGSTER_ARCUP1 + {SPR_HBAT, 1, 6, {A_ZThrust}, 5, (1<<16), S_HANGSTER_ARCUP3}, // S_HANGSTER_ARCUP2 + {SPR_HBAT, 1, 1, {A_ZThrust}, 0, (1<<16), S_HANGSTER_RETURN1}, // S_HANGSTER_ARCUP3 + {SPR_HBAT, 1, 1, {A_ZThrust}, 8, (1<<16), S_HANGSTER_RETURN2}, // S_HANGSTER_RETURN1 + {SPR_HBAT, 3, 1, {NULL}, 0, 0, S_HANGSTER_RETURN1}, // S_HANGSTER_RETURN2 + {SPR_HBAT, 0, 15, {NULL}, 0, 0, S_HANGSTER_LOOK}, // S_HANGSTER_RETURN3 + + {SPR_NULL, 0, 35, {NULL}, 0, 0, S_CRUMBLE2}, // S_CRUMBLE1 + {SPR_NULL, 0, 105, {A_Scream}, 0, 0, S_NULL}, // S_CRUMBLE2 // Spark {SPR_SPRK, FF_TRANS40 , 1, {NULL}, 0, 0, S_SPRK2}, // S_SPRK1 @@ -2387,10 +3817,15 @@ state_t states[NUMSTATES] = {SPR_SPRK, FF_TRANS90|3, 1, {NULL}, 0, 0, S_NULL}, // S_SPRK16 // Robot Explosion - {SPR_BOM1, 0, 1, {A_Scream}, 0, 0, S_XPLD2}, // S_XPLD1 - {SPR_BOM1, 1, 5, {NULL}, 0, 0, S_XPLD3}, // S_XPLD2 - {SPR_BOM1, 2, 5, {NULL}, 0, 0, S_XPLD4}, // S_XPLD3 - {SPR_BOM1, 3, 5, {NULL}, 0, 0, S_NULL}, // S_XPLD4 + {SPR_BOM1, 0, 0, {A_FlickySpawn}, 0, 0, S_XPLD1}, // S_XPLD_FLICKY + {SPR_BOM1, 0, 2, {A_Scream}, 0, 0, S_XPLD2}, // S_XPLD1 + {SPR_BOM1, 1, 2, {NULL}, 0, 0, S_XPLD3}, // S_XPLD2 + {SPR_BOM1, 2, 3, {NULL}, 0, 0, S_XPLD4}, // S_XPLD3 + {SPR_BOM1, 3, 3, {NULL}, 0, 0, S_XPLD5}, // S_XPLD4 + {SPR_BOM1, 4, 4, {NULL}, 0, 0, S_XPLD6}, // S_XPLD5 + {SPR_BOM1, 5, 4, {NULL}, 0, 0, S_NULL}, // S_XPLD6 + + {SPR_BOM1, FF_ANIMATE, 21, {NULL}, 5, 4, S_INVISIBLE}, // S_XPLD_EGGTRAP // Underwater Explosion {SPR_BOM4, 0, 3, {A_Scream}, 0, 0, S_WPLD2}, // S_WPLD1 @@ -2400,88 +3835,32 @@ state_t states[NUMSTATES] = {SPR_BOM4, 4, 3, {NULL}, 0, 0, S_WPLD6}, // S_WPLD5 {SPR_BOM4, 5, 3, {NULL}, 0, 0, S_NULL}, // S_WPLD6 + {SPR_DUST, FF_TRANS40, 4, {NULL}, 0, 0, S_DUST2}, // S_DUST1 + {SPR_DUST, 1|FF_TRANS50, 5, {NULL}, 0, 0, S_DUST3}, // S_DUST2 + {SPR_DUST, 2|FF_TRANS60, 3, {NULL}, 0, 0, S_DUST4}, // S_DUST3 + {SPR_DUST, 3|FF_TRANS70, 2, {NULL}, 0, 0, S_NULL}, // S_DUST4 + + {SPR_WDDB, FF_ANIMATE, -1, {A_DebrisRandom}, 7, 2, S_NULL}, // S_WOODDEBRIS + {SPR_NULL, 0, 1, {A_RockSpawn}, 0, 0, S_ROCKSPAWN}, // S_ROCKSPAWN - {SPR_ROIA, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEA}, // S_ROCKCRUMBLEA - {SPR_ROIB, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEB}, // S_ROCKCRUMBLEB - {SPR_ROIC, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEC}, // S_ROCKCRUMBLEC - {SPR_ROID, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLED}, // S_ROCKCRUMBLED - {SPR_ROIE, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEE}, // S_ROCKCRUMBLEE - {SPR_ROIF, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEF}, // S_ROCKCRUMBLEF - {SPR_ROIG, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEG}, // S_ROCKCRUMBLEG - {SPR_ROIH, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEH}, // S_ROCKCRUMBLEH - {SPR_ROII, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEI}, // S_ROCKCRUMBLEI - {SPR_ROIJ, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEJ}, // S_ROCKCRUMBLEJ - {SPR_ROIK, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEK}, // S_ROCKCRUMBLEK - {SPR_ROIL, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEL}, // S_ROCKCRUMBLEL - {SPR_ROIM, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEM}, // S_ROCKCRUMBLEM - {SPR_ROIN, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEN}, // S_ROCKCRUMBLEN - {SPR_ROIO, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEO}, // S_ROCKCRUMBLEO - {SPR_ROIP, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEP}, // S_ROCKCRUMBLEP - - {SPR_SRBA, 0, 5, {A_Look}, 0, 0, S_SRB1_CRAWLA1}, // S_SRB1_CRAWLA1 - {SPR_SRBA, 0, 3, {A_Chase}, 0, 0, S_SRB1_CRAWLA3}, // S_SRB1_CRAWLA2 - {SPR_SRBA, 1, 3, {A_Chase}, 0, 0, S_SRB1_CRAWLA4}, // S_SRB1_CRAWLA3 - {SPR_SRBA, 2, 3, {A_Chase}, 0, 0, S_SRB1_CRAWLA2}, // S_SRB1_CRAWLA4 - - {SPR_SRBB, 0, 2, {A_Look}, 0, 0, S_SRB1_BAT2}, // S_SRB1_BAT1 - {SPR_SRBB, 1, 2, {A_Look}, 0, 0, S_SRB1_BAT1}, // S_SRB1_BAT2 - {SPR_SRBB, 0, 2, {A_BuzzFly}, 0, 0, S_SRB1_BAT4}, // S_SRB1_BAT3 - {SPR_SRBB, 1, 2, {A_BuzzFly}, 0, 0, S_SRB1_BAT3}, // S_SRB1_BAT4 - - {SPR_SRBC, 0, 2, {A_Look}, 0, 0, S_SRB1_ROBOFISH1}, // S_SRB1_ROBOFISH1 - {SPR_SRBC, 1, 2, {A_BuzzFly}, 0, 0, S_SRB1_ROBOFISH3}, // S_SRB1_ROBOFISH2 - {SPR_SRBC, 0, 2, {A_BuzzFly}, 0, 0, S_SRB1_ROBOFISH2}, // S_SRB1_ROBOFISH3 - - {SPR_SRBD, 0, 2, {A_Look}, 0, 0, S_SRB1_VOLCANOGUY1}, // S_SRB1_VOLCANOGUY1 - {SPR_SRBD, 0, 2, {A_BuzzFly}, 0, 0, S_SRB1_VOLCANOGUY2}, // S_SRB1_VOLCANOGUY2 - - {SPR_SRBE, 0, 2, {A_BunnyHop}, 7, 2, S_SRB1_HOPPY2}, // S_SRB1_HOPPY1 - {SPR_SRBE, 1, 2, {A_BunnyHop}, 7, -2, S_SRB1_HOPPY1}, // S_SRB1_HOPPY2 - - {SPR_SRBE, 0, 2, {A_BunnyHop}, 4, 2, S_SRB1_HOPPYWATER2}, // S_SRB1_HOPPYWATER1 - {SPR_SRBE, 1, 2, {A_BunnyHop}, 4, -2, S_SRB1_HOPPYWATER1}, // S_SRB1_HOPPYWATER2 - - {SPR_SRBF, 0, 2, {A_BunnyHop}, 7, 0, S_SRB1_HOPPYSKYLAB1}, // S_SRB1_HOPPYSKYLAB1 - - {SPR_SRBG, 0, 16, {A_MoveAbsolute}, 0, 5, S_SRB1_MMZFLYING2}, // S_SRB1_MMZFLYING1 - {SPR_SRBG, 0, 16, {A_MoveAbsolute}, 180, 5, S_SRB1_MMZFLYING3}, // S_SRB1_MMZFLYING2 - {SPR_SRBG, 0, 1, {A_MoveAbsolute}, 0, 5, S_SRB1_MMZFLYING4}, // S_SRB1_MMZFLYING3 - {SPR_SRBG, 0, 7, {A_MoveAbsolute}, 0, 5, S_SRB1_MMZFLYING5}, // S_SRB1_MMZFLYING4 - {SPR_SRBG, 0, 8, {A_MoveAbsolute}, 180, 5, S_SRB1_MMZFLYING1}, // S_SRB1_MMZFLYING5 - - {SPR_SRBH, 0, 16, {A_MoveAbsolute}, 180, 5, S_SRB1_UFO2}, // S_SRB1_UFO1 - {SPR_SRBH, 0, 16, {A_MoveAbsolute}, 0, 5, S_SRB1_UFO1}, // S_SRB1_UFO2 - - {SPR_SRBI, 0, 4, {A_MoveAbsolute}, 0, 7, S_SRB1_GRAYBOT2}, // S_SRB1_GRAYBOT1 - {SPR_SRBI, 1, 4, {A_MoveAbsolute}, 0, 7, S_SRB1_GRAYBOT3}, // S_SRB1_GRAYBOT2 - {SPR_SRBI, 0, 4, {A_MoveAbsolute}, 0, 7, S_SRB1_GRAYBOT4}, // S_SRB1_GRAYBOT3 - {SPR_SRBI, 1, 4, {A_MoveAbsolute}, 180, 7, S_SRB1_GRAYBOT5}, // S_SRB1_GRAYBOT4 - {SPR_SRBI, 0, 4, {A_MoveAbsolute}, 180, 7, S_SRB1_GRAYBOT6}, // S_SRB1_GRAYBOT5 - {SPR_SRBI, 1, 4, {A_MoveAbsolute}, 180, 7, S_SRB1_GRAYBOT1}, // S_SRB1_GRAYBOT6 - - {SPR_SRBJ, 0, 8, {A_MoveAbsolute}, 0, 5, S_SRB1_ROBOTOPOLIS2}, // S_SRB1_ROBOTOPOLIS1 - {SPR_SRBJ, 1, 8, {A_MoveAbsolute}, 0, -5, S_SRB1_ROBOTOPOLIS1}, // S_SRB1_ROBOTOPOLIS2 - - {SPR_SRBK, 0, 8, {A_MoveAbsolute}, 0, 5, S_SRB1_RBZBUZZ2}, // S_SRB1_RBZBUZZ1 - {SPR_SRBK, 1, 8, {A_MoveAbsolute}, 0, -5, S_SRB1_RBZBUZZ1}, // S_SRB1_RBZBUZZ2 - - {SPR_SRBL, 0, 35, {A_ZThrust}, 4, (1<<16)+1, S_SRB1_RBZSPIKES2}, // S_SRB1_RBZSPIKES1 - {SPR_SRBL, 0, 35, {A_ZThrust}, -4, (1<<16)+1, S_SRB1_RBZSPIKES1}, // S_SRB1_RBZSPIKES2 - - {SPR_SRBM, 0, 4, {NULL}, 0, 0, S_SRB1_METALSONIC2}, // S_SRB1_METALSONIC1 - {SPR_SRBM, 1, 4, {NULL}, 0, 0, S_SRB1_METALSONIC3}, // S_SRB1_METALSONIC2 - {SPR_SRBM, 2, 4, {NULL}, 0, 0, S_SRB1_METALSONIC1}, // S_SRB1_METALSONIC3 - - {SPR_SRBN, 0, 2, {A_MoveAbsolute}, 0, 7, S_SRB1_GOLDBOT2}, // S_SRB1_GOLDBOT1 - {SPR_SRBN, 1, 2, {A_MoveAbsolute}, 0, 7, S_SRB1_GOLDBOT3}, // S_SRB1_GOLDBOT2 - {SPR_SRBN, 0, 2, {A_MoveAbsolute}, 0, 7, S_SRB1_GOLDBOT4}, // S_SRB1_GOLDBOT3 - {SPR_SRBN, 1, 2, {A_MoveAbsolute}, 180, 7, S_SRB1_GOLDBOT5}, // S_SRB1_GOLDBOT4 - {SPR_SRBN, 0, 2, {A_MoveAbsolute}, 180, 7, S_SRB1_GOLDBOT6}, // S_SRB1_GOLDBOT5 - {SPR_SRBN, 1, 2, {A_MoveAbsolute}, 180, 7, S_SRB1_GOLDBOT1}, // S_SRB1_GOLDBOT6 - - {SPR_SRBO, 0, 2, {A_Look}, 0, 0, S_SRB1_GENREX1}, // S_SRB1_GENREX1 - {SPR_SRBO, 0, 2, {A_BuzzFly}, 0, 0, S_SRB1_GENREX2}, // S_SRB1_GENREX2 + {SPR_ROIA, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEA + {SPR_ROIB, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEB + {SPR_ROIC, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEC + {SPR_ROID, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLED + {SPR_ROIE, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEE + {SPR_ROIF, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEF + {SPR_ROIG, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEG + {SPR_ROIH, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEH + {SPR_ROII, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEI + {SPR_ROIJ, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEJ + {SPR_ROIK, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEK + {SPR_ROIL, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEL + {SPR_ROIM, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEM + {SPR_ROIN, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEN + {SPR_ROIO, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEO + {SPR_ROIP, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEP + #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK #endif @@ -2505,7 +3884,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed + 0, // speed 0, // radius 0, // height 0, // display offset @@ -2574,7 +3953,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = -1, // doomednum S_PLAY_STND, // spawnstate 1, // spawnhealth - S_PLAY_RUN1, // seestate + S_PLAY_WALK, // seestate sfx_None, // seesound 0, // reactiontime sfx_thok, // attacksound @@ -2582,9 +3961,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MT_THOK, // painchance sfx_None, // painsound S_NULL, // meleestate - S_PLAY_ATK1, // missilestate - S_PLAY_DIE, // deathstate - S_NULL, // xdeathstate + S_PLAY_ROLL, // missilestate + S_PLAY_DEAD, // deathstate + S_PLAY_DRWN, // xdeathstate sfx_None, // deathsound 1, // speed 16*FRACUNIT, // radius @@ -2594,7 +3973,34 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MT_THOK, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE, // flags - (statenum_t)MT_THOK // raisestate + MT_NULL // raisestate + }, + + { // MT_TAILSOVERLAY + -1, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 16*FRACUNIT, // radius + 48*FRACUNIT, // height + 2, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate }, { // MT_BLUECRAWLA @@ -2610,7 +4016,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound 3, // speed @@ -2637,7 +4043,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound 3, // speed @@ -2664,7 +4070,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_FISH3, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_FISH4, // xdeathstate sfx_pop, // deathsound 0, // speed @@ -2691,12 +4097,12 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound 4*FRACUNIT, // speed - 20*FRACUNIT, // radius - 24*FRACUNIT, // height + 28*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage @@ -2718,12 +4124,12 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound 8*FRACUNIT, // speed - 20*FRACUNIT, // radius - 24*FRACUNIT, // height + 28*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage @@ -2732,33 +4138,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_AQUABUZZ - 124, // doomednum - S_BBUZZFLY1, // spawnstate - 1, // spawnhealth - S_BBUZZFLY1, // seestate - sfx_None, // seesound - 2, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - TICRATE, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_XPLD1, // deathstate - S_NULL, // xdeathstate - sfx_pop, // deathsound - 6*FRACUNIT, // speed - 20*FRACUNIT, // radius - 24*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_gbeep, // activesound - MF_SLIDEME|MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE|MF_NOGRAVITY, // flags - S_NULL // raisestate - }, - { // MT_JETTBOMBER 105, // doomednum S_JETBLOOK1, // spawnstate @@ -2772,7 +4151,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound 1*FRACUNIT, // speed @@ -2799,7 +4178,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_JETGSHOOT1, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound 1*FRACUNIT, // speed @@ -2820,13 +4199,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_CCOMMAND3, // seestate sfx_None, // seesound 2*TICRATE, // reactiontime - sfx_None, // attacksound + sfx_s3k60, // attacksound S_CCOMMAND3, // painstate 200, // painchance sfx_dmpain, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound 3, // speed @@ -2835,7 +4214,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // display offset 100, // mass 0, // damage - sfx_None, // activesound + sfx_s3k5d, // activesound MF_SLIDEME|MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags S_NULL // raisestate }, @@ -2853,14 +4232,14 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate - S_DETON16, // xdeathstate + S_XPLD_FLICKY, // deathstate + S_NULL, // xdeathstate sfx_pop, // deathsound 1*FRACUNIT, // speed 20*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset - 100, // mass + 0, // mass 1, // damage sfx_None, // activesound MF_ENEMY|MF_SHOOTABLE|MF_NOGRAVITY|MF_MISSILE, // flags @@ -2880,7 +4259,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_SKIM3, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound 8, // speed @@ -2934,7 +4313,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_s3k64, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed @@ -2948,30 +4327,111 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = (statenum_t)MT_JETTBULLET// raisestate }, - { // MT_SHARP + { // MT_SPINCUSHION 112, // doomednum - S_SHARP_ROAM1, // spawnstate + S_SPINCUSHION_LOOK, // spawnstate 1, // spawnhealth - S_SHARP_ROAM2, // seestate + S_SPINCUSHION_CHASE1, // seestate sfx_None, // seesound 3*TICRATE, // reactiontime sfx_s3kd8s, // attacksound S_NULL, // painstate 5*TICRATE, // painchance + sfx_shrpsp, // painsound + S_SPINCUSHION_STOP1, // meleestate + S_SPINCUSHION_AIM1, // missilestate + S_XPLD_FLICKY, // deathstate + S_SPINCUSHION_STOP3, // xdeathstate + sfx_pop, // deathsound + 2, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + DMG_SPIKE, // mass + 0, // damage + sfx_s3kaa, // activesound + MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE|MF_BOUNCE, // flags + S_NULL // raisestate + }, + + { // MT_CRUSHSTACEAN + 126, // doomednum + S_CRUSHSTACEAN_ROAM1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 32, // reactiontime + sfx_s3k6b, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_CRUSHSTACEAN_PUNCH1, // missilestate + S_XPLD_FLICKY, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 8, // speed + 24*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags + S_NULL // raisestate + }, + + { // MT_CRUSHCLAW + -1, // doomednum + S_CRUSHCLAW_AIM, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 16, // reactiontime + sfx_s3k6b, // attacksound + S_NULL, // painstate + 0, // painchance sfx_None, // painsound S_NULL, // meleestate - S_SHARP_AIM1, // missilestate + S_CRUSHCLAW_OUT,// missilestate S_XPLD1, // deathstate - S_SHARP_SPIN, // xdeathstate + S_NULL, // xdeathstate sfx_pop, // deathsound - 2, // speed - 16*FRACUNIT, // radius + 1, // speed + 22*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - 100, // mass + (sfx_s3k49<<8), // mass + 0, // damage + sfx_s3kd2l, // activesound + MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MT_CRUSHCHAIN // raisestate + }, + + { // MT_CRUSHCHAIN + -1, // doomednum + S_CRUSHCHAIN, // spawnstate + 0, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 0, // radius + 0, // height + 0, // display offset + 0, // mass 0, // damage sfx_None, // activesound - MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE|MF_BOUNCE, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags S_NULL // raisestate }, @@ -2988,7 +4448,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound 8, // speed @@ -3015,7 +4475,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound FRACUNIT, // speed @@ -3033,26 +4493,26 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 115, // doomednum S_VULTURE_STND, // spawnstate 1, // spawnhealth - S_VULTURE_VTOL1,// seestate + S_VULTURE_DRIFT,// seestate sfx_None, // seesound - 2, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate + TICRATE/2, // reactiontime + sfx_s3k60, // attacksound + S_VULTURE_STUNNED, // painstate S_NULL, // painchance - sfx_None, // painsound + sfx_s3k96, // painsound S_NULL, // meleestate S_VULTURE_ZOOM1,// missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - 3, // speed + 5, // speed 12*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset TICRATE, // mass 0, // damage sfx_jet, // activesound - MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE|MF_NOGRAVITY, // flags + MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE|MF_NOGRAVITY|MF_SLIDEME, // flags S_NULL // raisestate }, @@ -3069,7 +4529,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound 5*FRACUNIT, // speed @@ -3103,7 +4563,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 4*FRACUNIT, // radius 8*FRACUNIT, // height 0, // display offset - 100, // mass + DMG_SPIKE, // mass 1, // damage sfx_None, // activesound MF_PAIN|MF_NOGRAVITY, // flags @@ -3114,58 +4574,85 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 117, // doomednum S_ROBOHOOD_LOOK, // spawnstate 1, // spawnhealth - S_ROBOHOOD_STND, // seestate + S_ROBOHOOD_STAND, // seestate sfx_None, // seesound TICRATE, // reactiontime sfx_None, // attacksound - S_ROBOHOOD_JUMP, // painstate + S_NULL, // painstate 0, // painchance sfx_None, // painsound - S_NULL, // meleestate - S_ROBOHOOD_SHOOT, // missilestate - S_XPLD1, // deathstate - S_ROBOHOOD_JUMP2, // xdeathstate + S_ROBOHOOD_JUMP3, // meleestate + S_ROBOHOOD_FIRE1, // missilestate + S_XPLD_FLICKY, // deathstate + S_NULL, // xdeathstate sfx_pop, // deathsound - 0, // speed + 3, // speed 24*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage - sfx_None, // activesound + sfx_s3k4a, // activesound MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags - S_ROBOHOOD_FALL // raisestate + S_ROBOHOOD_JUMP1 // raisestate }, { // MT_FACESTABBER 118, // doomednum S_FACESTABBER_STND1, // spawnstate - 1, // spawnhealth + 2, // spawnhealth S_FACESTABBER_STND1, // seestate sfx_None, // seesound - 35, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate + 70, // reactiontime + sfx_zoom, // attacksound + S_FACESTABBER_PAIN, // painstate 0, // painchance - sfx_None, // painsound + sfx_dmpain, // painsound S_FACESTABBER_CHARGE1, // meleestate - S_NULL, // missilestate - S_XPLD1, // deathstate + S_FACESTABBER_CHARGE1, // missilestate + S_FACESTABBER_DIE1, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound + sfx_cybdth, // deathsound 3, // speed 32*FRACUNIT, // radius - 64*FRACUNIT, // height + 72*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage - sfx_None, // activesound - MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags + sfx_s3kc5s, // activesound + MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE|MF_SLIDEME, // flags S_NULL // raisestate }, - { // MT_EGGGUARD - 119, // doomednum + { // MT_FACESTABBERSPEAR + -1, // doomednum + S_FACESTABBERSPEAR, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 35, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 32*FRACUNIT, // radius + 72*FRACUNIT, // height + 0, // display offset + DMG_SPIKE, // mass + 0, // damage + sfx_None, // activesound + MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_EGGGUARD + 119, // doomednum S_EGGGUARD_STND, // spawnstate 1, // spawnhealth S_EGGGUARD_WALK1,// seestate @@ -3177,7 +4664,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_EGGGUARD_RUN1, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound 6, // speed @@ -3204,7 +4691,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_s3k7b, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_EGGSHIELDBREAK,// deathstate S_NULL, // xdeathstate sfx_wbreak, // deathsound 3, // speed @@ -3220,56 +4707,137 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_GSNAPPER 120, // doomednum - S_GSNAPPER_STND,// spawnstate + S_SNAPPER_SPAWN,// spawnstate 1, // spawnhealth S_GSNAPPER1, // seestate sfx_None, // seesound - 32, // reactiontime + 10, // reactiontime sfx_None, // attacksound S_NULL, // painstate 200, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_SNAPPER_XPLD, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - 3, // speed + 4, // speed 24*FRACUNIT, // radius - 24*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage - sfx_None, // activesound + sfx_s3k7e, // activesound MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags S_NULL // raisestate }, + { // MT_SNAPPER_LEG + -1, // doomednum + S_SNAPPER_LEG, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 6*FRACUNIT, // radius + 12*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SCENERY|MF_PAIN|MF_NOCLIPHEIGHT|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + S_SNAPPER_LEGRAISE // raisestate + }, + + { // MT_SNAPPER_HEAD + -1, // doomednum + S_SNAPPER_HEAD, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 6*FRACUNIT, // radius + 12*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_PAIN|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + { // MT_MINUS 121, // doomednum - S_MINUS_STND, // spawnstate + S_MINUS_INIT, // spawnstate 1, // spawnhealth - S_MINUS_DIGGING,// seestate + S_MINUS_DIGGING1,// seestate sfx_None, // seesound 32, // reactiontime - sfx_s3k82, // attacksound + sfx_s3kccs, // attacksound S_NULL, // painstate 200, // painchance sfx_None, // painsound - S_MINUS_DOWNWARD1,// meleestate + S_MINUS_BURST0, // meleestate S_MINUS_POPUP, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - 12, // speed + 17, // speed 24*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage - sfx_mindig, // activesound - MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags - S_MINUS_UPWARD1 // raisestate + sfx_s3kd3s, // activesound + MF_ENEMY|MF_NOCLIPTHING, // flags + S_MINUS_BURST1 // raisestate + }, + + { // MT_MINUSDIRT + -1, // doomednum + S_MINUSDIRT1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING, // flags + S_NULL // raisestate }, { // MT_SPRINGSHELL @@ -3285,7 +4853,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_spring, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound 6, // speed @@ -3312,7 +4880,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_spring, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound 6, // speed @@ -3339,7 +4907,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound 2, // speed @@ -3373,16 +4941,70 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 13*FRACUNIT, // radius 26*FRACUNIT, // height 0, // display offset - 0, // mass + DMG_SPIKE, // mass 8*FRACUNIT, // damage sfx_None, // activesound MF_PAIN|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING, // flags S_NULL // raisestate }, + { // MT_CANARIVORE + 134, // doomednum + S_CANARIVORE_LOOK, // spawnstate + 1, // spawnhealth + S_CANARIVORE_AWAKEN1, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_XPLD_FLICKY, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 0, // speed + 12*FRACUNIT, // radius + 80*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_SPAWNCEILING|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_CANARIVORE_GAS + -1, // doomednum + S_CANARIVOREGAS_1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_s3k5d, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIP|MF_SPECIAL, // flags + S_NULL // raisestate + }, + { // MT_BOSSEXPLODE -1, // doomednum - S_BPLD1, // spawnstate + S_BOSSEXPLODE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -3612,7 +5234,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 2*FRACUNIT, // speed + 4*FRACUNIT, // speed 13*FRACUNIT, // radius 26*FRACUNIT, // height 0, // display offset @@ -3670,7 +5292,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8*FRACUNIT, // radius 14*FRACUNIT, // height 0, // display offset - 100, // mass + DMG_FIRE, // mass 1, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY|MF_FIRE, // flags @@ -3832,13 +5454,40 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 4*FRACUNIT, // radius 4*FRACUNIT, // height 0, // display offset - 4, // mass + DMG_WATER, // mass 0, // damage sfx_None, // activesound MF_PAIN, // flags S_NULL // raisestate }, + { // MT_GOOPTRAIL + -1, // doomednum + S_GOOPTRAIL, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 3, // speed + 4*FRACUNIT, // radius + 4*FRACUNIT, // height + 0, // display offset + 4, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + { // MT_EGGMOBILE3 202, // doomednum S_EGGMOBILE3_STND, // spawnstate @@ -3960,14 +5609,14 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_BPLD1, // deathstate + S_BOSSEXPLODE, // deathstate S_NULL, // xdeathstate sfx_cybdth, // deathsound 48*FRACUNIT, // speed 34*FRACUNIT, // radius 68*FRACUNIT, // height 0, // display offset - 100, // mass + DMG_SPIKE, // mass 1, // damage sfx_mswing, // activesound MF_PAIN|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags @@ -3994,44 +5643,71 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 20*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset - 4, // mass + DMG_FIRE, // mass 0, // damage sfx_None, // activesound MF_NOGRAVITY|MF_PAIN|MF_FIRE, // flags S_NULL // raisestate }, - { // MT_BLACKEGGMAN - 206, // doomednum - S_BLACKEGG_STND, // spawnstate + { // MT_FANG + 204, // doomednum + S_FANG_IDLE1, // spawnstate 8, // spawnhealth - S_BLACKEGG_WALK1, // seestate + S_FANG_PATHINGSTART1, // seestate sfx_None, // seesound - 8*TICRATE, // reactiontime + 0, // reactiontime + sfx_skid, // attacksound + S_FANG_PAIN1, // painstate + 0, // painchance + sfx_s3k5d, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_FANG_DIE1, // deathstate + S_FANG_KO, // xdeathstate + sfx_s3k90, // deathsound + 0, // speed + 24*FRACUNIT, // radius + 60*FRACUNIT, // height + 0, // display offset + 0, // mass + 3, // damage + sfx_boingf, // activesound + MF_SPECIAL|MF_BOSS|MF_SHOOTABLE, // flags + S_NULL // raisestate + }, + + { // MT_FBOMB + -1, // doomednum + S_FBOMB1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_s3k51, // seesound + 0, // reactiontime sfx_None, // attacksound - S_BLACKEGG_PAIN1, // painstate + S_NULL, // painstate 0, // painchance sfx_None, // painsound - S_BLACKEGG_HITFACE1, // meleestate - S_BLACKEGG_MISSILE1, // missilestate - S_BLACKEGG_DIE1, // deathstate - S_BLACKEGG_GOOP, // xdeathstate - sfx_None, // deathsound - 1, // speed - 48*FRACUNIT, // radius - 160*FRACUNIT, // height + S_NULL, // meleestate + S_NULL, // missilestate + S_FBOMB_EXPL1, // deathstate + S_NULL, // xdeathstate + sfx_s3k4e, // deathsound + 20*FRACUNIT, // speed + 24*FRACUNIT, // radius + 48*FRACUNIT, // height 0, // display offset 0, // mass - 3, // damage + 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_BOSS,// flags - S_BLACKEGG_JUMP1 // raisestate + MF_NOBLOCKMAP|MF_MISSILE, // flags + S_NULL // raisestate }, - { // MT_BLACKEGGMAN_HELPER + { // MT_TNTDUST -1, // doomednum - S_BLACKEGG_HELPER, // spawnstate - 8, // spawnhealth + S_TNTDUST_1, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 0, // reactiontime @@ -4044,18 +5720,152 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 1, // speed - 48*FRACUNIT, // radius + 20*FRACUNIT, // speed + 16*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + { // MT_FSGNA + -1, // doomednum + S_FSGNA, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_mspogo, // deathsound + 0, // speed + 124*FRACUNIT, // radius + 124*FRACUNIT, // height + 0, // display offset 0, // mass - 1, // damage + 0, // damage sfx_None, // activesound - MF_SOLID|MF_NOGRAVITY, // flags + MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_BLACKEGGMAN_GOOPFIRE + { // MT_FSGNB + -1, // doomednum + S_FSGNB, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_FSGNC, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 124*FRACUNIT, // radius + 640*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY|MF_SOLID, // flags + S_NULL // raisestate + }, + + { // MT_FANGWAYPOINT + 294, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + FRACUNIT, // radius + FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOTHINK, // flags + S_NULL // raisestate + }, + + { // MT_BLACKEGGMAN + 206, // doomednum + S_BLACKEGG_STND, // spawnstate + 8, // spawnhealth + S_BLACKEGG_WALK1, // seestate + sfx_None, // seesound + 8*TICRATE, // reactiontime + sfx_None, // attacksound + S_BLACKEGG_PAIN1, // painstate + 0, // painchance + sfx_None, // painsound + S_BLACKEGG_HITFACE1, // meleestate + S_BLACKEGG_MISSILE1, // missilestate + S_BLACKEGG_DIE1, // deathstate + S_BLACKEGG_GOOP, // xdeathstate + sfx_None, // deathsound + 1, // speed + 48*FRACUNIT, // radius + 160*FRACUNIT, // height + 0, // display offset + 0, // mass + 3, // damage + sfx_None, // activesound + MF_SPECIAL|MF_BOSS,// flags + S_BLACKEGG_JUMP1 // raisestate + }, + + { // MT_BLACKEGGMAN_HELPER + -1, // doomednum + S_BLACKEGG_HELPER, // spawnstate + 8, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 1, // speed + 48*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 0, // mass + 1, // damage + sfx_None, // activesound + MF_SOLID|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_BLACKEGGMAN_GOOPFIRE -1, // doomednum S_BLACKEGG_GOOP1, // spawnstate 1000, // spawnhealth @@ -4074,8 +5884,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 30*FRACUNIT, // speed 11*FRACUNIT, // radius 8*FRACUNIT, // height - 0, // display offset - 100, // mass + 100, // display offset + 0, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags @@ -4095,14 +5905,14 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_BPLD1, // deathstate + S_BOSSEXPLODE, // deathstate S_NULL, // xdeathstate sfx_bexpld, // deathsound 10*FRACUNIT, // speed 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - 100, // mass + 0, // mass 1, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags @@ -4156,7 +5966,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 48*FRACUNIT, // radius 160*FRACUNIT, // height 0, // display offset - 100, // mass + DMG_ELECTRIC, // mass 1, // damage sfx_beelec, // activesound MF_PAIN|MF_FIRE|MF_NOGRAVITY|MF_PUSHABLE, // flags @@ -4183,7 +5993,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 11*FRACUNIT, // radius 8*FRACUNIT, // height 0, // display offset - 100, // mass + 0, // mass 32*FRACUNIT, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags @@ -4210,7 +6020,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - 100, // mass + 0, // mass 1, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags @@ -4226,7 +6036,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + MT_NULL, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -4237,7 +6047,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - 100, // mass + DMG_FIRE, // mass 1, // damage sfx_None, // activesound MF_PAIN|MF_FIRE|MF_RUNSPAWNFUNC, // flags @@ -4257,7 +6067,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_BPLD1, // deathstate + S_BOSSEXPLODE, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 10*FRACUNIT, // speed @@ -4284,7 +6094,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_BPLD1, // deathstate + S_BOSSEXPLODE, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 10*FRACUNIT, // speed @@ -4307,7 +6117,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + 20*TICRATE, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -4318,7 +6128,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - 20*TICRATE, // mass + 0, // mass 48*FRACUNIT, // damage sfx_s3k5d, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_BOUNCE|MF_GRENADEBOUNCE, // flags @@ -4345,7 +6155,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - 100, // mass + 0, // mass 32*FRACUNIT, // damage sfx_s3k99, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_BOUNCE, // flags @@ -4372,7 +6182,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - 100, // mass + 0, // mass 1, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE, // flags @@ -4445,7 +6255,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_METALSONIC_PAIN, // painstate S_METALSONIC_VECTOR,// painchance sfx_dmpain, // painsound - S_METALSONIC_BLOCK, // meleestate + S_METALSONIC_BADBOUNCE, // meleestate S_METALSONIC_SHOOT, // missilestate S_METALSONIC_DEATH, // deathstate S_METALSONIC_FLEE1, // xdeathstate @@ -4454,7 +6264,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 16*FRACUNIT, // radius 48*FRACUNIT, // height 0, // display offset - sfx_mspogo, // mass + 0, // mass 3, // damage sfx_mswarp, // activesound MF_NOGRAVITY|MF_BOSS|MF_SLIDEME, // flags @@ -4569,20 +6379,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BLUEBALL - -1, // doomednum - S_BLUEBALL, // spawnstate + { // MT_BLUESPHERE + 1706, // doomednum + S_BLUESPHERE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - MT_NULL, // reactiontime + MT_FLINGBLUESPHERE, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_BLUEBALLSPARK, // deathstate + S_BLUESPHERESPARK, // deathstate S_NULL, // xdeathstate sfx_s3k65, // deathsound 38*FRACUNIT, // speed @@ -4593,25 +6403,52 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // damage sfx_None, // activesound MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate + S_BLUESPHEREBONUS // raisestate }, - { // MT_REDTEAMRING - 308, // doomednum - S_TEAMRING, // spawnstate + { // MT_FLINGBLUESPHERE + -1, // doomednum + S_BLUESPHERE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - MT_FLINGRING, // reactiontime + MT_FLINGBLUESPHERE, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + MT_BLUESPHERE, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_BLUESPHERESPARK, // deathstate + S_NULL, // xdeathstate + sfx_s3k65, // deathsound + 38*FRACUNIT, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL, // flags + S_BLUESPHEREBONUS // raisestate + }, + + { // MT_BOMBSPHERE + 520, // doomednum + S_BOMBSPHERE1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + MT_NULL, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_BOSSEXPLODE, // deathstate S_NULL, // xdeathstate - sfx_itemup, // deathsound + sfx_cybdth, // deathsound 38*FRACUNIT, // speed 16*FRACUNIT, // radius 24*FRACUNIT, // height @@ -4623,8 +6460,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BLUETEAMRING - 309, // doomednum + { // MT_REDTEAMRING + 308, // doomednum S_TEAMRING, // spawnstate 1000, // spawnhealth S_NULL, // seestate @@ -4650,13 +6487,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_EMMY - 312, // doomednum - S_EMMY, // spawnstate + { // MT_BLUETEAMRING + 309, // doomednum + S_TEAMRING, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + MT_FLINGRING, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -4665,23 +6502,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // missilestate S_SPRK1, // deathstate S_NULL, // xdeathstate - sfx_token, // deathsound - 0, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height + sfx_itemup, // deathsound + 38*FRACUNIT, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags S_NULL // raisestate }, { // MT_TOKEN - -1, // doomednum - S_TOKEN, // spawnstate + 312, // doomednum + S_TOKEN, // spawnstate 1000, // spawnhealth - S_MOVINGTOKEN, // seestate + S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound @@ -4690,17 +6527,17 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_SPRK1, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed + 0, // speed 8*FRACUNIT, // radius 16*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage + 1, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP, // flags + MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags S_NULL // raisestate }, @@ -4759,7 +6596,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_EMBLEM - -1, // doomednum + 322, // doomednum S_EMBLEM1, // spawnstate 1000, // spawnhealth S_NULL, // seestate @@ -4970,7 +6807,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_EMERHUNT 320, // doomednum - S_EMER1, // spawnstate + S_SHRD1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -4985,8 +6822,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_cgot, // deathsound 8, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 12*FRACUNIT, // radius + 42*FRACUNIT, // height 0, // display offset 4, // mass 0, // damage @@ -4996,7 +6833,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_EMERALDSPAWN - 323, // doomednum + 321, // doomednum S_INVISIBLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate @@ -5103,40 +6940,67 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BLUESPRING - 552, // doomednum - S_BLUESPRING, // spawnstate + { // MT_BUMPER + 542, // doomednum + S_BUMPER, // spawnstate 1000, // spawnhealth - S_BLUESPRING2, // seestate + S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 5, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance - sfx_spring, // painsound + -1, // painchance + sfx_s3kaa, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 20*FRACUNIT, // radius - 16*FRACUNIT, // height + 32*FRACUNIT, // radius + 64*FRACUNIT, // height 0, // display offset - 11*FRACUNIT, // mass + 16*FRACUNIT, // mass 0, // damage sfx_None, // activesound - MF_SOLID|MF_SPRING, // flags - S_BLUESPRING2 // raisestate + MF_SPRING|MF_NOGRAVITY, // flags + S_BUMPERHIT // raisestate + }, + + { // MT_BALLOON + 543, // doomednum + S_BALLOON, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 2, // painchance + sfx_s3k77, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_BALLOONPOP2, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 32*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // display offset + 20*FRACUNIT, // mass + 0, // damage + sfx_None, // activesound + MF_SPRING|MF_NOGRAVITY, // flags + S_BALLOONPOP1 // raisestate }, { // MT_YELLOWSPRING 550, // doomednum S_YELLOWSPRING, // spawnstate 1000, // spawnhealth - S_YELLOWSPRING2,// seestate + S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -5153,7 +7017,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 20*FRACUNIT, // mass 0, // damage sfx_None, // activesound - MF_SOLID|MF_SPRING, // flags + MF_SPRING, // flags S_YELLOWSPRING2 // raisestate }, @@ -5161,9 +7025,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 551, // doomednum S_REDSPRING, // spawnstate 1000, // spawnhealth - S_REDSPRING2, // seestate + S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -5180,17 +7044,44 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 32*FRACUNIT, // mass 0, // damage sfx_None, // activesound - MF_SOLID|MF_SPRING, // flags + MF_SPRING, // flags S_REDSPRING2 // raisestate }, + { // MT_BLUESPRING + 552, // doomednum + S_BLUESPRING, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_spring, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 20*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 11*FRACUNIT, // mass + 0, // damage + sfx_None, // activesound + MF_SPRING, // flags + S_BLUESPRING2 // raisestate + }, + { // MT_YELLOWDIAG 555, // doomednum S_YDIAG1, // spawnstate 1, // spawnhealth - S_YDIAG2, // seestate + S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -5207,7 +7098,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 20*FRACUNIT, // mass 20*FRACUNIT, // damage sfx_None, // activesound - MF_SOLID|MF_SPRING, // flags + MF_SPRING, // flags S_YDIAG2 // raisestate }, @@ -5215,9 +7106,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 556, // doomednum S_RDIAG1, // spawnstate 1, // spawnhealth - S_RDIAG2, // seestate + S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -5234,11 +7125,119 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 32*FRACUNIT, // mass 32*FRACUNIT, // damage sfx_None, // activesound - MF_SOLID|MF_SPRING, // flags + MF_SPRING, // flags S_RDIAG2 // raisestate }, - { // MT_BUBBLES + { // MT_BLUEDIAG + 557, // doomednum + S_BDIAG1, // spawnstate + 1, // spawnhealth + S_BDIAG2, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_spring, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 11*FRACUNIT, // mass + 11*FRACUNIT, // damage + sfx_None, // activesound + MF_SPRING, // flags + S_BDIAG2 // raisestate + }, + + { // MT_YELLOWHORIZ + 558, // doomednum + S_YHORIZ1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_spring, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 0, // mass + 36*FRACUNIT, // damage + sfx_None, // activesound + MF_SPRING|MF_NOGRAVITY, // flags + S_YHORIZ2 // raisestate + }, + + { // MT_REDHORIZ + 559, // doomednum + S_RHORIZ1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_spring, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 0, // mass + 72*FRACUNIT, // damage + sfx_None, // activesound + MF_SPRING|MF_NOGRAVITY, // flags + S_RHORIZ2 // raisestate + }, + + { // MT_BLUEHORIZ + 560, // doomednum + S_BHORIZ1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_spring, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 0, // mass + 1*FRACUNIT, // damage + sfx_None, // activesound + MF_SPRING|MF_NOGRAVITY, // flags + S_BHORIZ2 // raisestate + }, + + { // MT_BUBBLES 500, // doomednum S_BUBBLES1, // spawnstate 1000, // spawnhealth @@ -5293,33 +7292,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_SPIKEBALL - -1, // doomednum - S_SPIKEBALL1, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 10*FRACUNIT, // speed - 4*FRACUNIT, // radius - 8*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_PAIN|MF_NOGRAVITY, // flags - S_NULL // raisestate - }, - - { // MT_SPECIALSPIKEBALL 521, // doomednum S_SPIKEBALL1, // spawnstate 1000, // spawnhealth @@ -5337,12 +7309,12 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 10*FRACUNIT, // speed 12*FRACUNIT, // radius - 24*FRACUNIT, // height + 8*FRACUNIT, // height 0, // display offset - 100, // mass + DMG_SPIKE, // mass 1, // damage sfx_None, // activesound - MF_SPECIAL|MF_NOGRAVITY, // flags + MF_PAIN|MF_NOGRAVITY, // flags S_NULL // raisestate }, @@ -5366,7 +7338,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8*FRACUNIT, // radius 14*FRACUNIT, // height 0, // display offset - 100, // mass + DMG_FIRE, // mass 1, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY|MF_FIRE, // flags @@ -5384,7 +7356,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // painstate 0, // painchance sfx_s3k64, // painsound - S_NULL, // meleestate + S_SPIKE4, // meleestate S_NULL, // missilestate S_SPIKED1, // deathstate S_SPIKED2, // xdeathstate @@ -5396,7 +7368,61 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 4, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_WALLSPIKE + 522, // doomednum + S_WALLSPIKE1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_s3k64, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_WALLSPIKED1, // deathstate + S_WALLSPIKED2, // xdeathstate + sfx_mspogo, // deathsound + 2*TICRATE, // speed + 16*FRACUNIT, // radius + 14*FRACUNIT, // height + 0, // display offset + 4, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SCENERY|MF_NOCLIPHEIGHT|MF_PAPERCOLLISION, // flags + S_NULL // raisestate + }, + + { // MT_WALLSPIKEBASE + -1, // doomednum + S_WALLSPIKEBASE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 7*FRACUNIT, // radius + 14*FRACUNIT, // height + 0, // display offset + 4, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPTHING, // flags S_NULL // raisestate }, @@ -5408,7 +7434,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_STARPOST_SPIN, // painstate + S_STARPOST_STARTSPIN, // painstate 0, // painchance sfx_strpst, // painsound S_NULL, // meleestate @@ -5418,7 +7444,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 8, // speed 64*FRACUNIT, // radius - 80*FRACUNIT, // height + 128*FRACUNIT, // height 0, // display offset 4, // mass 0, // damage @@ -5428,61 +7454,61 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_BIGMINE - 524, // doomednum - S_BIGMINE1, // spawnstate + 1012, // doomednum + S_BIGMINE_IDLE, // spawnstate 1, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound + S_BIGMINE_ALERT1, // seestate + sfx_s3k5c, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - TICRATE, // painchance - sfx_None, // painsound - S_NULL, // meleestate + 0, // painchance + sfx_s3k86, // painsound + S_BIGMINE_SET1, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_BIGMINE_SET2, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 2*FRACUNIT, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 28*FRACUNIT, // radius + 56*FRACUNIT, // height 0, // display offset MT_UWEXPLODE, // mass - 64*FRACUNIT, // damage - sfx_gbeep, // activesound - MF_SPECIAL|MF_NOGRAVITY, // flags + 0, // damage + sfx_s3k9e, // activesound + MF_SPECIAL|MF_NOGRAVITY|MF_SHOOTABLE|MF_ENEMY, // flags S_NULL // raisestate }, - { // MT_BIGAIRMINE - 527, // doomednum - S_BIGMINE1, // spawnstate + { // MT_BLASTEXECUTOR + 756, // doomednum + S_INVISIBLE, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - TICRATE, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate - sfx_bexpld, // deathsound - 2*FRACUNIT, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + sfx_None, // deathsound + 8, // speed + 32*FRACUNIT, // radius + 16*FRACUNIT, // height 0, // display offset - MT_BOSSEXPLODE, // mass - 64*FRACUNIT, // damage - sfx_gbeep, // activesound - MF_SPECIAL|MF_NOGRAVITY, // flags + 4, // mass + 0, // damage + sfx_None, // activesound + MF_SHOOTABLE|MF_NOGRAVITY|MF_NOCLIPTHING, // flags S_NULL // raisestate }, { // MT_CANNONLAUNCHER - 525, // doomednum + 1123, // doomednum S_CANNONLAUNCHER1, // spawnstate 1, // spawnhealth S_NULL, // seestate @@ -5508,877 +7534,1008 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_SUPERRINGBOX - 400, // doomednum - S_SUPERRINGBOX, // spawnstate + { // MT_BOXSPARKLE + -1, // doomednum + S_BOXSPARKLE1, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_SUPERRINGBOX, // painstate + S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SUPERRINGBOX2,// deathstate + S_NULL, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_MONITOREXPLOSION, // speed + 3*FRACUNIT, // speed 16*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset 100, // mass - MT_RINGICO, // damage + 0, // damage sfx_None, // activesound - MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags + MF_NOGRAVITY|MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIPHEIGHT, // flags S_NULL // raisestate }, - { // MT_REDRINGBOX - 414, // doomednum - S_REDRINGBOX, // spawnstate + { // MT_RING_BOX + 400, // doomednum + S_RING_BOX, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_REDRINGBOX, // painstate + S_RING_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SUPERRINGBOX2,// deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_REDMONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 1, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - MT_RINGICO, // damage + MT_RING_ICON, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - { // MT_BLUERINGBOX - 415, // doomednum - S_BLUERINGBOX, // spawnstate + { // MT_PITY_BOX + 401, // doomednum + S_PITY_BOX, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_BLUERINGBOX, // painstate + S_PITY_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SUPERRINGBOX2,// deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_BLUEMONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 1, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - MT_RINGICO, // damage + MT_PITY_ICON, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - { // MT_SNEAKERTV - 407, // doomednum - S_SHTV, // spawnstate + { // MT_ATTRACT_BOX + 402, // doomednum + S_ATTRACT_BOX, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_SHTV, // painstate + S_ATTRACT_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SHTV2, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_MONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 1, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - MT_SHOESICO, // damage + MT_ATTRACT_ICON,// damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - { // MT_INV - 408, // doomednum - S_PINV, // spawnstate + { // MT_FORCE_BOX + 403, // doomednum + S_FORCE_BOX, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_PINV, // painstate + S_FORCE_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_PINV2, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_MONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 1, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - MT_INVCICO, // damage + MT_FORCE_ICON, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - // 1-up box - { // MT_PRUP - 409, // doomednum - S_PRUP, // spawnstate + { // MT_ARMAGEDDON_BOX + 404, // doomednum + S_ARMAGEDDON_BOX, // spawnstate 1, // spawnhealth - S_PLAY_BOX1, // seestate + S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_PRUP, // painstate + S_ARMAGEDDON_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_PRUP2, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_MONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 1, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - MT_1UPICO, // damage + MT_ARMAGEDDON_ICON, // damage sfx_None, // activesound - MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_RUNSPAWNFUNC, // flags + MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - { // MT_YELLOWTV - 402, // doomednum - S_YLTV, // spawnstate + { // MT_WHIRLWIND_BOX + 405, // doomednum + S_WHIRLWIND_BOX, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_YLTV, // painstate + S_WHIRLWIND_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_YLTV2, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_MONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 1, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - MT_YSHIELDICO, // damage + MT_WHIRLWIND_ICON, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - { // MT_BLUETV - 403, // doomednum - S_BLTV1, // spawnstate + { // MT_ELEMENTAL_BOX + 406, // doomednum + S_ELEMENTAL_BOX, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_BLTV1, // painstate + S_ELEMENTAL_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_BLTV3, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_MONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 1, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - MT_BSHIELDICO, // damage + MT_ELEMENTAL_ICON, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - // bomb shield box - { // MT_BLACKTV - 404, // doomednum - S_BKTV1, // spawnstate + { // MT_SNEAKERS_BOX + 407, // doomednum + S_SNEAKERS_BOX, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_BKTV1, // painstate + S_SNEAKERS_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_BKTV3, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_MONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset + 1, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height + 0, // display offset 100, // mass - MT_KSHIELDICO, // damage + MT_SNEAKERS_ICON, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - // jump shield box - { // MT_WHITETV - 405, // doomednum - S_WHTV1, // spawnstate + { // MT_INVULN_BOX + 408, // doomednum + S_INVULN_BOX, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_WHTV1, // painstate + S_INVULN_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_WHTV3, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_MONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 1, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - MT_WSHIELDICO, // damage + MT_INVULN_ICON, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - { // MT_GREENTV - 406, // doomednum - S_GRTV, // spawnstate + { // MT_1UP_BOX + 409, // doomednum + S_1UP_BOX, // spawnstate 1, // spawnhealth - S_NULL, // seestate + S_PLAY_BOX1, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_GRTV, // painstate + S_1UP_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_GRTV2, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_MONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 1, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - MT_GSHIELDICO, // damage + MT_1UP_ICON, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - { // MT_PITYTV - 401, // doomednum - S_PITV1, // spawnstate + { // MT_EGGMAN_BOX + 410, // doomednum + S_EGGMAN_BOX, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_PITV1, // painstate + S_EGGMAN_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_PITV3, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_MONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 0, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - MT_PITYSHIELDICO, // damage + MT_EGGMAN_ICON, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - { // MT_EGGMANBOX - 410, // doomednum - S_EGGTV1, // spawnstate + { // MT_MIXUP_BOX + 411, // doomednum + S_MIXUP_BOX, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_EGGTV1, // painstate + S_MIXUP_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_EGGTV3, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_MONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 1, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - MT_EGGMANICO, // damage + MT_MIXUP_ICON, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - { // MT_MIXUPBOX - 411, // doomednum - S_MIXUPBOX1, // spawnstate + { // MT_MYSTERY_BOX + -1, //412, // doomednum + S_MYSTERY_BOX, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_MIXUPBOX1, // painstate + S_MYSTERY_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_MIXUPBOX3, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_MONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 0, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - MT_MIXUPICO, // damage + MT_UNKNOWN, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - { // MT_RECYCLETV - 416, // doomednum - S_RECYCLETV1, // spawnstate + { // MT_GRAVITY_BOX + 413, // doomednum + S_GRAVITY_BOX, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_RECYCLETV1, // painstate + S_GRAVITY_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_RECYCLETV3, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_MONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 0, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - MT_RECYCLEICO, // damage + MT_GRAVITY_ICON, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - { // MT_RECYCLEICO - -1, // doomednum - S_RECYCLETV3, // spawnstate + { // MT_RECYCLER_BOX + 416, // doomednum + S_RECYCLER_BOX, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_NULL, // painstate + S_RECYCLER_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound - 2*FRACUNIT, // speed - 8*FRACUNIT, // radius - 14*FRACUNIT, // height + sfx_pop, // deathsound + 1, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - 62*FRACUNIT, // damage + MT_RECYCLER_ICON, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags + MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - { // MT_QUESTIONBOX - 412, // doomednum - S_RANDOMBOX1, // spawnstate + { // MT_SCORE1K_BOX + 418, // doomednum + S_SCORE1K_BOX, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_RANDOMBOX1, // painstate + S_SCORE1K_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_RANDOMBOX3, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_MONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 0, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage + MT_SCORE1K_ICON, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - { // MT_GRAVITYBOX - 413, // doomednum - S_GBTV1, // spawnstate + { // MT_SCORE10K_BOX + 419, // doomednum + S_SCORE10K_BOX, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_GBTV1, // painstate + S_SCORE10K_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_GBTV3, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_MONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 0, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - MT_GRAVITYICO, // damage - sfx_cgot, // activesound + MT_SCORE10K_ICON, // damage + sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - { // MT_SCORETVSMALL - 418, // doomednum - S_SCORETVA1, // spawnstate + { // MT_FLAMEAURA_BOX + 420, // doomednum + S_FLAMEAURA_BOX, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_token, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_SCORETVA1, // painstate + S_FLAMEAURA_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SCORETVA3, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_MONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 1, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - MT_SCOREICOSMALL, // damage + MT_FLAMEAURA_ICON, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - { // MT_SCORETVLARGE - 419, // doomednum - S_SCORETVB1, // spawnstate + { // MT_BUBBLEWRAP_BOX + 421, // doomednum + S_BUBBLEWRAP_BOX, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_token, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_SCORETVB1, // painstate + S_BUBBLEWRAP_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SCORETVB3, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - MT_MONITOREXPLOSION, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 1, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - MT_SCOREICOLARGE, // damage + MT_BUBBLEWRAP_ICON, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - { // MT_MONITOREXPLOSION - -1, // doomednum - S_MONITOREXPLOSION1, // spawnstate - 0, // spawnhealth + { // MT_THUNDERCOIN_BOX + 422, // doomednum + S_THUNDERCOIN_BOX, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_XPLD1, // painstate + S_THUNDERCOIN_BOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_BOX_POP1, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 8*FRACUNIT, // radius - 8*FRACUNIT, // height + sfx_pop, // deathsound + 1, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset - MT_EXPLODE, // mass - 0, // damage + 100, // mass + MT_THUNDERCOIN_ICON, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY, // flags + MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, - { // MT_REDMONITOREXPLOSION - -1, // doomednum - S_REDMONITOREXPLOSION1, // spawnstate - 0, // spawnhealth + { // MT_PITY_GOLDBOX + 431, // doomednum + S_PITY_GOLDBOX, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime - sfx_None, // attacksound - S_XPLD1, // painstate + sfx_monton, // attacksound + S_PITY_GOLDBOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_GOLDBOX_OFF1, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound + sfx_pop, // deathsound 0, // speed - 8*FRACUNIT, // radius - 8*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset - MT_EXPLODE, // mass - 0, // damage + 100, // mass + MT_PITY_ICON, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY, // flags + MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags S_NULL // raisestate }, - { // MT_BLUEMONITOREXPLOSION - -1, // doomednum - S_BLUEMONITOREXPLOSION1, // spawnstate - 0, // spawnhealth + { // MT_ATTRACT_GOLDBOX + 432, // doomednum + S_ATTRACT_GOLDBOX, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime - sfx_None, // attacksound - S_XPLD1, // painstate + sfx_monton, // attacksound + S_ATTRACT_GOLDBOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_GOLDBOX_OFF1, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound + sfx_pop, // deathsound 0, // speed - 8*FRACUNIT, // radius - 8*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset - MT_EXPLODE, // mass - 0, // damage + 100, // mass + MT_ATTRACT_ICON,// damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY, // flags + MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags S_NULL // raisestate }, - { // MT_RINGICO - -1, // doomednum - S_SUPERRINGBOX2, // spawnstate - 1, // spawnhealth - S_NULL, // seestate - sfx_itemup, // seesound - 10, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 2*FRACUNIT, // speed - 8*FRACUNIT, // radius - 14*FRACUNIT, // height - 0, // display offset - 100, // mass - 62*FRACUNIT, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags - S_NULL // raisestate - }, - - { // MT_SHOESICO - -1, // doomednum - S_SHTV2, // spawnstate + { // MT_FORCE_GOLDBOX + 433, // doomednum + S_FORCE_GOLDBOX, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate + sfx_monton, // attacksound + S_FORCE_GOLDBOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_GOLDBOX_OFF1, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound - 2*FRACUNIT, // speed - 8*FRACUNIT, // radius - 14*FRACUNIT, // height + sfx_pop, // deathsound + 0, // speed + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass - 62*FRACUNIT, // damage + MT_FORCE_ICON, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags + MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags S_NULL // raisestate }, - { // MT_INVCICO - -1, // doomednum - S_PINV2, // spawnstate + { // MT_ARMAGEDDON_GOLDBOX + 434, // doomednum + S_ARMAGEDDON_GOLDBOX, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate + sfx_monton, // attacksound + S_ARMAGEDDON_GOLDBOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_GOLDBOX_OFF1, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound - 2*FRACUNIT, // speed - 8*FRACUNIT, // radius - 14*FRACUNIT, // height + sfx_pop, // deathsound + 0, // speed + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass - 62*FRACUNIT, // damage + MT_ARMAGEDDON_ICON, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags + MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags S_NULL // raisestate }, - { // MT_1UPICO - -1, // doomednum - S_PRUP2, // spawnstate + { // MT_WHIRLWIND_GOLDBOX + 435, // doomednum + S_WHIRLWIND_GOLDBOX, // spawnstate 1, // spawnhealth - S_PLAY_ICON1, // seestate + S_NULL, // seestate sfx_None, // seesound 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate + sfx_monton, // attacksound + S_WHIRLWIND_GOLDBOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_GOLDBOX_OFF1, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound - 2*FRACUNIT, // speed - 8*FRACUNIT, // radius - 14*FRACUNIT, // height + sfx_pop, // deathsound + 0, // speed + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass - 62*FRACUNIT, // damage + MT_WHIRLWIND_ICON, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags + MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags S_NULL // raisestate }, - { // MT_YSHIELDICO - -1, // doomednum - S_YLTV2, // spawnstate + { // MT_ELEMENTAL_GOLDBOX + 436, // doomednum + S_ELEMENTAL_GOLDBOX, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_shield, // seesound + sfx_None, // seesound 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate + sfx_monton, // attacksound + S_ELEMENTAL_GOLDBOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_GOLDBOX_OFF1, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound - 2*FRACUNIT, // speed - 8*FRACUNIT, // radius - 14*FRACUNIT, // height + sfx_pop, // deathsound + 0, // speed + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass - 62*FRACUNIT, // damage + MT_ELEMENTAL_ICON, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags + MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags S_NULL // raisestate }, - { // MT_BSHIELDICO - -1, // doomednum - S_BLTV3, // spawnstate + { // MT_SNEAKERS_GOLDBOX + 437, // doomednum + S_SNEAKERS_GOLDBOX, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_shield, // seesound + sfx_None, // seesound 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate + sfx_monton, // attacksound + S_SNEAKERS_GOLDBOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_GOLDBOX_OFF1, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound - 2*FRACUNIT, // speed - 8*FRACUNIT, // radius - 14*FRACUNIT, // height + sfx_pop, // deathsound + 0, // speed + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass - 62*FRACUNIT, // damage + MT_SNEAKERS_ICON, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags + MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags S_NULL // raisestate }, - { // MT_KSHIELDICO - -1, // doomednum - S_BKTV3, // spawnstate + { // MT_INVULN_GOLDBOX + 438, // doomednum + S_INVULN_GOLDBOX, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_shield, // seesound + sfx_None, // seesound 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate + sfx_monton, // attacksound + S_INVULN_GOLDBOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_GOLDBOX_OFF1, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound - 2*FRACUNIT, // speed - 8*FRACUNIT, // radius - 14*FRACUNIT, // height + sfx_pop, // deathsound + 0, // speed + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass - 62*FRACUNIT, // damage + MT_INVULN_ICON, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags + MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags S_NULL // raisestate }, - { // MT_WSHIELDICO - -1, // doomednum - S_WHTV3, // spawnstate + { // MT_EGGMAN_GOLDBOX + 440, // doomednum + S_EGGMAN_GOLDBOX, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_shield, // seesound + sfx_None, // seesound 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate + sfx_monton, // attacksound + S_EGGMAN_GOLDBOX, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_GOLDBOX_OFF1, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound - 2*FRACUNIT, // speed - 8*FRACUNIT, // radius - 14*FRACUNIT, // height + sfx_pop, // deathsound + 0, // speed + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass - 62*FRACUNIT, // damage + MT_EGGMAN_ICON, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags + MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags S_NULL // raisestate }, - { // MT_GSHIELDICO - -1, // doomednum - S_GRTV2, // spawnstate + { // MT_GRAVITY_GOLDBOX + 443, // doomednum + S_GRAVITY_GOLDBOX, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_shield, // seesound + sfx_None, // seesound + 8, // reactiontime + sfx_monton, // attacksound + S_GRAVITY_GOLDBOX, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_GOLDBOX_OFF1, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 0, // speed + 20*FRACUNIT, // radius + 44*FRACUNIT, // height + 0, // display offset + 100, // mass + MT_GRAVITY_ICON, // damage + sfx_None, // activesound + MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags + S_NULL // raisestate + }, + + { // MT_FLAMEAURA_GOLDBOX + 450, // doomednum + S_FLAMEAURA_GOLDBOX, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_monton, // attacksound + S_FLAMEAURA_GOLDBOX, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_GOLDBOX_OFF1, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 0, // speed + 20*FRACUNIT, // radius + 44*FRACUNIT, // height + 0, // display offset + 100, // mass + MT_FLAMEAURA_ICON, // damage + sfx_None, // activesound + MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags + S_NULL // raisestate + }, + + { // MT_BUBBLEWRAP_GOLDBOX + 451, // doomednum + S_BUBBLEWRAP_GOLDBOX, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_monton, // attacksound + S_BUBBLEWRAP_GOLDBOX, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_GOLDBOX_OFF1, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 0, // speed + 20*FRACUNIT, // radius + 44*FRACUNIT, // height + 0, // display offset + 100, // mass + MT_BUBBLEWRAP_ICON, // damage + sfx_None, // activesound + MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags + S_NULL // raisestate + }, + + { // MT_THUNDERCOIN_GOLDBOX + 452, // doomednum + S_THUNDERCOIN_GOLDBOX, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_monton, // attacksound + S_THUNDERCOIN_GOLDBOX, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_GOLDBOX_OFF1, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 0, // speed + 20*FRACUNIT, // radius + 44*FRACUNIT, // height + 0, // display offset + 100, // mass + MT_THUNDERCOIN_ICON, // damage + sfx_None, // activesound + MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE, // flags + S_NULL // raisestate + }, + + { // MT_RING_REDBOX + 414, // doomednum + S_RING_REDBOX1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound - S_NULL, // painstate + S_RING_REDBOX1, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_REDBOX_POP1, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound - 2*FRACUNIT, // speed - 8*FRACUNIT, // radius - 14*FRACUNIT, // height + sfx_pop, // deathsound + 0, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - 62*FRACUNIT, // damage + MT_RING_ICON, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags + MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags + S_NULL // raisestate + }, + + { // MT_RING_BLUEBOX + 415, // doomednum + S_RING_BLUEBOX1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_RING_BLUEBOX1, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_BLUEBOX_POP1, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 0, // speed + 18*FRACUNIT, // radius + 40*FRACUNIT, // height + 0, // display offset + 100, // mass + MT_RING_ICON, // damage + sfx_None, // activesound + MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, + { // MT_RING_ICON + -1, // doomednum + S_RING_ICON1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_itemup, // seesound + 10, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 2*FRACUNIT, // speed + 8*FRACUNIT, // radius + 14*FRACUNIT, // height + 0, // display offset + 100, // mass + 62*FRACUNIT, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags + S_NULL // raisestate + }, - { // MT_PITYSHIELDICO + { // MT_PITY_ICON -1, // doomednum - S_PITV3, // spawnstate + S_PITY_ICON1, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_shield, // seesound @@ -6403,12 +8560,12 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_EGGMANICO + { // MT_ATTRACT_ICON -1, // doomednum - S_EGGTV3, // spawnstate + S_ATTRACT_ICON1, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_None, // seesound + sfx_attrsg, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -6430,12 +8587,12 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_MIXUPICO + { // MT_FORCE_ICON -1, // doomednum - S_MIXUPBOX3, // spawnstate + S_FORCE_ICON1, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_None, // seesound + sfx_forcsg, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -6457,13 +8614,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_GRAVITYICO + { // MT_ARMAGEDDON_ICON -1, // doomednum - S_GBTV3, // spawnstate + S_ARMAGEDDON_ICON1, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_None, // seesound - 20*TICRATE, // reactiontime + sfx_armasg, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -6484,13 +8641,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_SCOREICOSMALL + { // MT_WHIRLWIND_ICON -1, // doomednum - S_SCORETVA3, // spawnstate + S_WHIRLWIND_ICON1, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_token, // seesound - 1000, // reactiontime + sfx_wirlsg, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -6511,13 +8668,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_SCOREICOLARGE + { // MT_ELEMENTAL_ICON -1, // doomednum - S_SCORETVB3, // spawnstate + S_ELEMENTAL_ICON1, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_token, // seesound - 10000, // reactiontime + sfx_elemsg, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -6538,12 +8695,12 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_ROCKET + { // MT_SNEAKERS_ICON -1, // doomednum - S_ROCKET, // spawnstate - 1000, // spawnhealth + S_SNEAKERS_ICON1, // spawnstate + 1, // spawnhealth S_NULL, // seestate - sfx_rlaunc, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -6554,23 +8711,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 20*FRACUNIT, // speed - 11*FRACUNIT, // radius - 8*FRACUNIT, // height + 2*FRACUNIT, // speed + 8*FRACUNIT, // radius + 14*FRACUNIT, // height 0, // display offset 100, // mass - 20, // damage + 62*FRACUNIT, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags S_NULL // raisestate }, - { // MT_LASER + { // MT_INVULN_ICON -1, // doomednum - S_LASER, // spawnstate - 1000, // spawnhealth + S_INVULN_ICON1, // spawnstate + 1, // spawnhealth S_NULL, // seestate - sfx_rlaunc, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -6581,23 +8738,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 20*FRACUNIT, // speed - 11*FRACUNIT, // radius - 8*FRACUNIT, // height + 2*FRACUNIT, // speed + 8*FRACUNIT, // radius + 14*FRACUNIT, // height 0, // display offset 100, // mass - 20, // damage + 62*FRACUNIT, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags S_NULL // raisestate }, - { // MT_TORPEDO + { // MT_1UP_ICON -1, // doomednum - S_TORPEDO, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_rlaunc, // seesound + S_1UP_ICON1, // spawnstate + 1, // spawnhealth + S_PLAY_ICON1, // seestate + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -6605,24 +8762,24 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_MINE_BOOM1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_cybdth, // deathsound - 20*FRACUNIT, // speed - 11*FRACUNIT, // radius - 8*FRACUNIT, // height + sfx_None, // deathsound + 2*FRACUNIT, // speed + 8*FRACUNIT, // radius + 14*FRACUNIT, // height 0, // display offset 100, // mass - 20, // damage + 62*FRACUNIT, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags S_NULL // raisestate }, - { // MT_TORPEDO2 + { // MT_EGGMAN_ICON -1, // doomednum - S_TORPEDO, // spawnstate - 1000, // spawnhealth + S_EGGMAN_ICON1, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime @@ -6632,26 +8789,26 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_MINE_BOOM1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_cybdth, // deathsound - 20*FRACUNIT, // speed - 11*FRACUNIT, // radius - 8*FRACUNIT, // height + sfx_None, // deathsound + 2*FRACUNIT, // speed + 8*FRACUNIT, // radius + 14*FRACUNIT, // height 0, // display offset 100, // mass - 20, // damage + 62*FRACUNIT, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags S_NULL // raisestate }, - { // MT_ENERGYBALL + { // MT_MIXUP_ICON -1, // doomednum - S_ENERGYBALL1, // spawnstate - 1000, // spawnhealth + S_MIXUP_ICON1, // spawnstate + 1, // spawnhealth S_NULL, // seestate - sfx_s3k54, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -6662,185 +8819,185 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 40*FRACUNIT, // speed - 60*FRACUNIT, // radius - 120*FRACUNIT, // height + 2*FRACUNIT, // speed + 8*FRACUNIT, // radius + 14*FRACUNIT, // height 0, // display offset 100, // mass - 20, // damage + 62*FRACUNIT, // damage sfx_None, // activesound - MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags S_NULL // raisestate }, - { // MT_MINE + { // MT_GRAVITY_ICON -1, // doomednum - S_MINE1, // spawnstate + S_GRAVITY_ICON1, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 20*TICRATE, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_MINE_BOOM1, // deathstate - S_MINE_BOOM1, // xdeathstate - sfx_cybdth, // deathsound - 0, // speed + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 2*FRACUNIT, // speed 8*FRACUNIT, // radius - 10*FRACUNIT, // height + 14*FRACUNIT, // height 0, // display offset 100, // mass - 64*FRACUNIT, // damage + 62*FRACUNIT, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags S_NULL // raisestate }, - { // MT_JETTBULLET + { // MT_RECYCLER_ICON -1, // doomednum - S_JETBULLET1, // spawnstate + S_RECYCLER_ICON1, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 32, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 200, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 20*FRACUNIT, // speed - 4*FRACUNIT, // radius - 8*FRACUNIT, // height + 2*FRACUNIT, // speed + 8*FRACUNIT, // radius + 14*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 62*FRACUNIT, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags S_NULL // raisestate }, - { // MT_TURRETLASER + { // MT_SCORE1K_ICON -1, // doomednum - S_TURRETLASER, // spawnstate - 1000, // spawnhealth + S_SCORE1K_ICON1, // spawnstate + 1, // spawnhealth S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime + sfx_chchng, // seesound + 1000, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_TURRETLASEREXPLODE1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_turhit, // deathsound - 50*FRACUNIT, // speed - 12*FRACUNIT, // radius - 24*FRACUNIT, // height + sfx_None, // deathsound + 2*FRACUNIT, // speed + 8*FRACUNIT, // radius + 14*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 62*FRACUNIT, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags S_NULL // raisestate }, - { // MT_CANNONBALL + { // MT_SCORE10K_ICON -1, // doomednum - S_CANNONBALL1, // spawnstate + S_SCORE10K_ICON1, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_cannon, // seesound - 32, // reactiontime + sfx_chchng, // seesound + 10000, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 200, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_cybdth, // deathsound - 16*FRACUNIT, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + sfx_None, // deathsound + 2*FRACUNIT, // speed + 8*FRACUNIT, // radius + 14*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 62*FRACUNIT, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags S_NULL // raisestate }, - { // MT_CANNONBALLDECOR - 526, // doomednum - S_CANNONBALL1, // spawnstate + { // MT_FLAMEAURA_ICON + -1, // doomednum + S_FLAMEAURA_ICON1, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_None, // seesound - 32, // reactiontime + sfx_s3k3e, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 200, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 16*FRACUNIT, // speed - 20*FRACUNIT, // radius - 40*FRACUNIT, // height + 2*FRACUNIT, // speed + 8*FRACUNIT, // radius + 14*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 62*FRACUNIT, // damage sfx_None, // activesound - MF_SOLID|MF_PUSHABLE|MF_SLIDEME, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags S_NULL // raisestate }, - { // MT_ARROW + { // MT_BUBBLEWRAP_ICON -1, // doomednum - S_ARROW, // spawnstate + S_BUBBLEWRAP_ICON1, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_None, // seesound - 32, // reactiontime + sfx_s3k3f, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 200, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate - S_ARROWDOWN, // xdeathstate + S_NULL, // xdeathstate sfx_None, // deathsound - 16*FRACUNIT, // speed - 4*FRACUNIT, // radius - 8*FRACUNIT, // height + 2*FRACUNIT, // speed + 8*FRACUNIT, // radius + 14*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 62*FRACUNIT, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags - S_ARROWUP // raisestate + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags + S_NULL // raisestate }, - { // MT_DEMONFIRE + { // MT_THUNDERCOIN_ICON -1, // doomednum - S_DEMONFIRE1, // spawnstate + S_THUNDERCOIN_ICON1, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_None, // seesound + sfx_s3k41, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -6851,23 +9008,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 16*FRACUNIT, // speed + 2*FRACUNIT, // speed 8*FRACUNIT, // radius - 8*FRACUNIT, // height + 14*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 62*FRACUNIT, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON, // flags S_NULL // raisestate }, - { // MT_GFZFLOWER1 - 800, // doomednum - S_GFZFLOWERA, // spawnstate + { // MT_ROCKET + -1, // doomednum + S_ROCKET, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_None, // seesound + sfx_rlaunc, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -6878,23 +9035,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 20*FRACUNIT, // speed + 11*FRACUNIT, // radius + 8*FRACUNIT, // height 0, // display offset - 100, // mass - 0, // damage + 0, // mass + 20, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_GFZFLOWER2 - 801, // doomednum - S_GFZFLOWERB1, // spawnstate + { // MT_LASER + -1, // doomednum + S_LASER, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_None, // seesound + sfx_rlaunc, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -6905,23 +9062,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 96*FRACUNIT, // height + 20*FRACUNIT, // speed + 11*FRACUNIT, // radius + 8*FRACUNIT, // height 0, // display offset - 100, // mass - 0, // damage + 0, // mass + 20, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_GFZFLOWER3 - 802, // doomednum - S_GFZFLOWERC1, // spawnstate + { // MT_TORPEDO + -1, // doomednum + S_TORPEDO, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_None, // seesound + sfx_rlaunc, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -6929,23 +9086,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_MINE_BOOM1, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 8*FRACUNIT, // radius - 32*FRACUNIT, // height + sfx_cybdth, // deathsound + 20*FRACUNIT, // speed + 11*FRACUNIT, // radius + 8*FRACUNIT, // height 0, // display offset - 100, // mass - 0, // damage + 0, // mass + 20, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_BERRYBUSH - 804, // doomednum - S_BERRYBUSH, // spawnstate + { // MT_TORPEDO2 + -1, // doomednum + S_TORPEDO, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -6956,26 +9113,26 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_MINE_BOOM1, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + sfx_cybdth, // deathsound + 20*FRACUNIT, // speed + 11*FRACUNIT, // radius + 8*FRACUNIT, // height 0, // display offset - 100, // mass - 0, // damage + 0, // mass + 20, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_BUSH - 805, // doomednum - S_BUSH, // spawnstate + { // MT_ENERGYBALL + -1, // doomednum + S_ENERGYBALL1, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_None, // seesound + sfx_s3k54, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -6986,21 +9143,21 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 40*FRACUNIT, // speed + 60*FRACUNIT, // radius + 120*FRACUNIT, // height 0, // display offset - 100, // mass - 0, // damage + 0, // mass + 20, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags S_NULL // raisestate }, - { // MT_THZPLANT - 900, // doomednum - S_THZPLANT1, // spawnstate - 1000, // spawnhealth + { // MT_MINE + -1, // doomednum + S_MINE1, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime @@ -7010,50 +9167,50 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 8, // speed + S_MINE_BOOM1, // deathstate + S_MINE_BOOM1, // xdeathstate + sfx_cybdth, // deathsound + 0, // speed 8*FRACUNIT, // radius - 32*FRACUNIT, // height + 10*FRACUNIT, // height 0, // display offset - 16, // mass - 0, // damage + 0, // mass + 64*FRACUNIT, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_MISSILE, // flags S_NULL // raisestate }, - { // MT_ALARM - 901, // doomednum - S_ALARM1, // spawnstate - 1000, // spawnhealth + { // MT_JETTBULLET + -1, // doomednum + S_JETBULLET1, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 32, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + 200, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_XPLD1, // deathstate S_NULL, // xdeathstate - sfx_alarm, // deathsound - 1, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height + sfx_None, // deathsound + 20*FRACUNIT, // speed + 4*FRACUNIT, // radius + 8*FRACUNIT, // height 0, // display offset - 4, // mass - 0, // damage + 0, // mass + 1, // damage sfx_None, // activesound - MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY, // flags + MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_GARGOYLE - 1000, // doomednum - S_GARGOYLE, // spawnstate + { // MT_TURRETLASER + -1, // doomednum + S_TURRETLASER, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7064,78 +9221,105 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_TURRETLASEREXPLODE1, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound - 21*FRACUNIT, // speed + sfx_turhit, // deathsound + 50*FRACUNIT, // speed + 12*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 0, // mass + 1, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_CANNONBALL + -1, // doomednum + S_CANNONBALL1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_cannon, // seesound + 32, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 200, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_XPLD1, // deathstate + S_NULL, // xdeathstate + sfx_cybdth, // deathsound + 16*FRACUNIT, // speed 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset - 100, // mass + 0, // mass 1, // damage - sfx_statu2, // activesound - MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags + sfx_None, // activesound + MF_NOBLOCKMAP|MF_MISSILE, // flags S_NULL // raisestate }, - { // MT_SEAWEED - 1001, // doomednum - S_SEAWEED1, // spawnstate - 1000, // spawnhealth + { // MT_CANNONBALLDECOR + 1124, // doomednum + S_CANNONBALL1, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 32, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + 200, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_XPLD1, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 24*FRACUNIT, // radius - 56*FRACUNIT, // height + 16*FRACUNIT, // speed + 20*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage + 1, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SOLID|MF_PUSHABLE|MF_SLIDEME, // flags S_NULL // raisestate }, - { // MT_WATERDRIP - 1002, // doomednum - S_DRIPA1, // spawnstate - 1000, // spawnhealth + { // MT_ARROW + -1, // doomednum + S_ARROW, // spawnstate + 1, // spawnhealth S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime + sfx_s3ka0, // seesound + 32, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + 200, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_ARROWBONK, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 1*FRACUNIT, // radius - 15*FRACUNIT, // height + sfx_s3k52, // deathsound + 16*FRACUNIT, // speed + 4*FRACUNIT, // radius + 8*FRACUNIT, // height 0, // display offset - 4, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SPAWNCEILING|MF_NOGRAVITY, // flags + DMG_SPIKE, // mass + 1, // damage + sfx_s3k51, // activesound + MF_NOBLOCKMAP|MF_MISSILE, // flags S_NULL // raisestate }, - { // MT_WATERDROP + { // MT_DEMONFIRE -1, // doomednum - S_DRIPB1, // spawnstate - 1000, // spawnhealth + S_DEMONFIRE, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime @@ -7145,23 +9329,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_DRIPC1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_wdrip1, // deathsound - 0, // speed - 2*FRACUNIT, // radius + sfx_None, // deathsound + 16*FRACUNIT, // speed + 8*FRACUNIT, // radius 8*FRACUNIT, // height 0, // display offset - 8, // mass - 0, // damage + 0, // mass + 1, // damage sfx_None, // activesound - MF_SPECIAL|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_CORAL1 - 1003, // doomednum - S_CORAL1, // spawnstate + { // MT_GFZFLOWER1 + 800, // doomednum + S_GFZFLOWERA, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7176,19 +9360,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 16*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset - 4, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_CORAL2 - 1004, // doomednum - S_CORAL2, // spawnstate + { // MT_GFZFLOWER2 + 801, // doomednum + S_GFZFLOWERB, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7203,19 +9387,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 16*FRACUNIT, // radius + 96*FRACUNIT, // height 0, // display offset - 4, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_CORAL3 - 1005, // doomednum - S_CORAL3, // spawnstate + { // MT_GFZFLOWER3 + 802, // doomednum + S_GFZFLOWERC, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7231,18 +9415,18 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset - 4, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_BLUECRYSTAL - 1006, // doomednum - S_BLUECRYSTAL1, // spawnstate + { // MT_BLUEBERRYBUSH + 803, // doomednum + S_BLUEBERRYBUSH, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7257,19 +9441,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset - 4, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_CHAIN - 1100, // doomednum - S_CEZCHAIN, // spawnstate + { // MT_BERRYBUSH + 804, // doomednum + S_BERRYBUSH, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7283,20 +9467,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed - 4*FRACUNIT, // radius - 128*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset - 16, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SPAWNCEILING|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_FLAME - 1101, // doomednum - S_FLAME1, // spawnstate + { // MT_BUSH + 805, // doomednum + S_BUSH, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7311,19 +9495,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8*FRACUNIT, // radius + 16*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_PAIN|MF_FIRE, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_EGGSTATUE - 1102, // doomednum - S_EGGSTATUE1, // spawnstate + { // MT_GFZTREE + 806, // doomednum + S_GFZTREE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7338,23 +9522,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 32*FRACUNIT, // radius - 240*FRACUNIT, // height + 20*FRACUNIT, // radius + 128*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 0, // damage sfx_None, // activesound - MF_SOLID|MF_PUSHABLE|MF_SCENERY, // flags + MF_SOLID|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_MACEPOINT - 1104, // doomednum - S_INVISIBLE, // spawnstate + { // MT_GFZBERRYTREE + 807, // doomednum + S_GFZBERRYTREE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -7364,24 +9548,24 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 10*FRACUNIT, // speed - 128*FRACUNIT, // radius - 1*FRACUNIT, // height + 0, // speed + 20*FRACUNIT, // radius + 128*FRACUNIT, // height 0, // display offset - 10000, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_SOLID|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_SWINGMACEPOINT - 1105, // doomednum - S_INVISIBLE, // spawnstate + { // MT_GFZCHERRYTREE + 808, // doomednum + S_GFZCHERRYTREE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -7391,24 +9575,24 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 10*FRACUNIT, // speed - 128*FRACUNIT, // radius - 1*FRACUNIT, // height + 0, // speed + 20*FRACUNIT, // radius + 128*FRACUNIT, // height 0, // display offset - 10000, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_SOLID|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_HANGMACEPOINT - 1106, // doomednum - S_INVISIBLE, // spawnstate + { // MT_CHECKERTREE + 809, // doomednum + S_CHECKERTREE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -7418,24 +9602,24 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 10*FRACUNIT, // speed - 128*FRACUNIT, // radius - 1*FRACUNIT, // height + 0, // speed + 20*FRACUNIT, // radius + 200*FRACUNIT, // height 0, // display offset - 10000, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_SPINMACEPOINT - 1107, // doomednum - S_INVISIBLE, // spawnstate + { // MT_CHECKERSUNSETTREE + 810, // doomednum + S_CHECKERSUNSETTREE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -7445,24 +9629,24 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 10*FRACUNIT, // speed - 128*FRACUNIT, // radius - 1*FRACUNIT, // height + 0, // speed + 20*FRACUNIT, // radius + 200*FRACUNIT, // height 0, // display offset - 200, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_HIDDEN_SLING - 1108, // doomednum - S_SLING1, // spawnstate + { // MT_FHZTREE + 2102, // doomednum + S_FHZTREE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -7472,47 +9656,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 10*FRACUNIT, // speed - 8*FRACUNIT, // radius - 8*FRACUNIT, // height + 0, // speed + 20*FRACUNIT, // radius + 200*FRACUNIT, // height 0, // display offset - 0, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_SMALLMACECHAIN - -1, // doomednum - S_SMALLMACECHAIN, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 24*FRACUNIT, // speed - 24*FRACUNIT, // radius - 48*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate - }, - - { // MT_BIGMACECHAIN - -1, // doomednum - S_BIGMACECHAIN, // spawnstate + { // MT_FHZPINKTREE + 2103, // doomednum + S_FHZPINKTREE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7526,20 +9683,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 48*FRACUNIT, // speed - 48*FRACUNIT, // radius - 96*FRACUNIT, // height + 0, // speed + 20*FRACUNIT, // radius + 200*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL|MF_NOCLIPHEIGHT, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_SMALLMACE - -1, // doomednum - S_SMALLMACE, // spawnstate + { // MT_POLYGONTREE + 811, // doomednum + S_POLYGONTREE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7553,20 +9710,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 24*FRACUNIT, // speed - 17*FRACUNIT, // radius - 34*FRACUNIT, // height + 0, // speed + 20*FRACUNIT, // radius + 200*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage - sfx_mswing, // activesound - MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_BIGMACE - -1, // doomednum - S_BIGMACE, // spawnstate + { // MT_BUSHTREE + 812, // doomednum + S_BUSHTREE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7580,20 +9737,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 48*FRACUNIT, // speed - 34*FRACUNIT, // radius - 68*FRACUNIT, // height + 0, // speed + 20*FRACUNIT, // radius + 200*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage - sfx_mswing, // activesound - MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_CEZFLOWER - 1103, // doomednum - S_CEZFLOWER1, // spawnstate + { // MT_BUSHREDTREE + 813, // doomednum + S_BUSHREDTREE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7608,8 +9765,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 20*FRACUNIT, // radius + 200*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage @@ -7618,11 +9775,11 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BIGTUMBLEWEED - 1200, // doomednum - S_BIGTUMBLEWEED,// spawnstate + { // MT_SPRINGTREE + 1600, // doomednum + S_SPRINGTREE, // spawnstate 1000, // spawnhealth - S_BIGTUMBLEWEED_ROLL1, // seestate + S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound @@ -7635,21 +9792,21 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 24*FRACUNIT, // radius - 48*FRACUNIT, // height + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage - sfx_s3k64, // activesound - MF_SPECIAL|MF_BOUNCE, // flags + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_LITTLETUMBLEWEED - 1201, // doomednum - S_LITTLETUMBLEWEED,// spawnstate + { // MT_THZFLOWER1 + 900, // doomednum + S_THZFLOWERA, // spawnstate 1000, // spawnhealth - S_LITTLETUMBLEWEED_ROLL1, // seestate + S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound @@ -7661,20 +9818,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 12*FRACUNIT, // radius - 24*FRACUNIT, // height + 8, // speed + 8*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset - 100, // mass - 1, // damage - sfx_s3k64, // activesound - MF_SPECIAL|MF_BOUNCE, // flags + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_CACTI1 - 1203, // doomednum - S_CACTI1, // spawnstate + { // MT_THZFLOWER2 + 902, // doomednum + S_THZFLOWERB, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7688,20 +9845,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 8, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 64*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_CACTI2 - 1204, // doomednum - S_CACTI2, // spawnstate + { // MT_THZFLOWER3 + 903, // doomednum + S_THZFLOWERC, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7715,20 +9872,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 8, // speed 16*FRACUNIT, // radius 64*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_CACTI3 - 1205, // doomednum - S_CACTI3, // spawnstate + { // MT_THZTREE + 904, // doomednum + S_THZTREE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7742,20 +9899,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 8, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 64*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_CACTI4 - 1206, // doomednum - S_CACTI4, // spawnstate + { // MT_THZTREEBRANCH + -1, // doomednum + S_THZTREEBRANCH1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7769,20 +9926,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 80*FRACUNIT, // height + 8, // speed + 1*FRACUNIT, // radius + 1*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_FLAMEJET - 1300, // doomednum - S_FLAMEJETSTND, // spawnstate + { // MT_ALARM + 901, // doomednum + S_ALARM1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7795,21 +9952,21 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + sfx_alarm, // deathsound + 1, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height 0, // display offset - 100, // mass + 4, // mass 0, // damage sfx_None, // activesound - MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOSECTOR, // flags + MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_VERTICALFLAMEJET - 1301, // doomednum - S_FLAMEJETSTND, // spawnstate + { // MT_GARGOYLE + 1000, // doomednum + S_GARGOYLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7823,20 +9980,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 21*FRACUNIT, // speed 16*FRACUNIT, // radius 40*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOSECTOR, // flags + 1, // damage + sfx_statu2, // activesound + MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags S_NULL // raisestate }, - { // MT_FLAMEJETFLAME - -1, // doomednum - S_FLAMEJETFLAME1, // spawnstate + { // MT_BIGGARGOYLE + 1009, // doomednum + S_BIGGARGOYLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7850,20 +10007,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 5*FRACUNIT, // speed - 8*FRACUNIT, // radius - 8*FRACUNIT, // height + 12*FRACUNIT, // speed + 32*FRACUNIT, // radius + 80*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_MISSILE|MF_FIRE, // flags + 1, // damage + sfx_statu2, // activesound + MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags S_NULL // raisestate }, - { // MT_FJSPINAXISA - 3575, // doomednum - S_FJSPINAXISA1, // spawnstate + { // MT_SEAWEED + 1001, // doomednum + S_SEAWEED1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7877,20 +10034,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 10*FRACUNIT, // speed - 16*FRACUNIT, // radius - 1*FRACUNIT, // height + 0, // speed + 24*FRACUNIT, // radius + 56*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 0, // damage sfx_None, // activesound - MF_NOCLIP|MF_NOCLIPTHING|MF_NOGRAVITY|MF_NOSECTOR, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_FJSPINHELPERA - -1, // doomednum - S_FJSPINHELPERA1,// spawnstate + { // MT_WATERDRIP + 1002, // doomednum + S_DRIPA1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7904,20 +10061,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 10*FRACUNIT, // speed - 16*FRACUNIT, // radius - 1*FRACUNIT, // height + 0, // speed + 1*FRACUNIT, // radius + 15*FRACUNIT, // height 0, // display offset - 100, // mass - 1, // damage + 4, // mass + 0, // damage sfx_None, // activesound - MF_NOCLIP|MF_NOCLIPTHING|MF_NOGRAVITY|MF_NOSECTOR, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_FJSPINAXISB - 3576, // doomednum - S_FJSPINAXISB1, // spawnstate + { // MT_WATERDROP + -1, // doomednum + S_DRIPB1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7928,23 +10085,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_DRIPC1, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound - 10*FRACUNIT, // speed - 16*FRACUNIT, // radius - 1*FRACUNIT, // height + sfx_wdrip1, // deathsound + 0, // speed + 2*FRACUNIT, // radius + 8*FRACUNIT, // height 0, // display offset - 100, // mass - 1, // damage + 8, // mass + 0, // damage sfx_None, // activesound - MF_NOCLIP|MF_NOCLIPTHING|MF_NOGRAVITY|MF_NOSECTOR, // flags + MF_SPECIAL|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_FJSPINHELPERB - -1, // doomednum - S_FJSPINHELPERB1,// spawnstate + { // MT_CORAL1 + 1003, // doomednum + S_CORAL1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -7958,23 +10115,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 10*FRACUNIT, // speed - 16*FRACUNIT, // radius - 1*FRACUNIT, // height + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height 0, // display offset - 100, // mass - 1, // damage + 4, // mass + 0, // damage sfx_None, // activesound - MF_NOCLIP|MF_NOCLIPTHING|MF_NOGRAVITY|MF_NOSECTOR, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_FLAMEJETFLAMEB - -1, // doomednum - S_FLAMEJETFLAMEB1, // spawnstate + { // MT_CORAL2 + 1004, // doomednum + S_CORAL2, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_fire, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -7985,20 +10142,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 18, // speed - 16*FRACUNIT, // radius - 24*FRACUNIT, // height + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height 0, // display offset - 100, // mass - 1, // damage + 4, // mass + 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_MISSILE|MF_FIRE|MF_NOBLOCKMAP|MF_RUNSPAWNFUNC, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_TRAPGOYLE - 1500, // doomednum - S_TRAPGOYLE, // spawnstate + { // MT_CORAL3 + 1005, // doomednum + S_CORAL3, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8012,20 +10169,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 21*FRACUNIT, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height 0, // display offset - 100, // mass - 1, // damage - sfx_statu2, // activesound - MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags + 4, // mass + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_TRAPGOYLEUP - 1501, // doomednum - S_TRAPGOYLEUP, // spawnstate + { // MT_BLUECRYSTAL + 1006, // doomednum + S_BLUECRYSTAL1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8039,20 +10196,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 21*FRACUNIT, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height 0, // display offset - 100, // mass - 1, // damage - sfx_statu2, // activesound - MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags + 4, // mass + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_TRAPGOYLEDOWN - 1502, // doomednum - S_TRAPGOYLEDOWN,// spawnstate + { // MT_KELP + 1007, // doomednum + S_KELP, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8066,20 +10223,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 21*FRACUNIT, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 292*FRACUNIT, // height 0, // display offset - 100, // mass - 1, // damage - sfx_statu2, // activesound - MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags + 4, // mass + 0, // damage + sfx_None, // activesound + MF_SCENERY|MF_NOBLOCKMAP, // flags S_NULL // raisestate }, - { // MT_TRAPGOYLELONG - 1503, // doomednum - S_TRAPGOYLELONG,// spawnstate + { // MT_DSZSTALAGMITE + 1008, // doomednum + S_DSZSTALAGMITE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8093,47 +10250,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 21*FRACUNIT, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_statu2, // activesound - MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags - S_NULL // raisestate - }, - - { // MT_TARGET - 1504, // doomednum - S_TARGET_IDLE, // spawnstate - 1, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 32, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 200, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_TARGET_HIT1, // deathstate - S_TARGET_ALLDONE, // xdeathstate - sfx_None, // deathsound 0, // speed - 24*FRACUNIT, // radius - 32*FRACUNIT, // height + 8*FRACUNIT, // radius + 116*FRACUNIT, // height 0, // display offset - 100, // mass + 4, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE, // flags + MF_SCENERY|MF_SOLID, // flags S_NULL // raisestate }, - { // MT_STALAGMITE0 - 1900, // doomednum - S_STG0, // spawnstate + { // MT_DSZ2STALAGMITE + 1011, // doomednum + S_DSZ2STALAGMITE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8148,19 +10278,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 8*FRACUNIT, // radius + 116*FRACUNIT, // height 0, // display offset - 100, // mass + 4, // mass 0, // damage sfx_None, // activesound - MF_NOCLIP|MF_SCENERY, // flags + MF_SCENERY|MF_SOLID, // flags S_NULL // raisestate }, - { // MT_STALAGMITE1 - 1901, // doomednum - S_STG1, // spawnstate + { // MT_LIGHTBEAM + 1010, // doomednum + S_LIGHTBEAM1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8175,19 +10305,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 16*FRACUNIT, // radius + 16*FRACUNIT, // height 0, // display offset - 100, // mass + 4, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SCENERY|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_STALAGMITE2 - 1902, // doomednum - S_STG2, // spawnstate + { // MT_CHAIN + 1100, // doomednum + S_CEZCHAIN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8201,27 +10331,27 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 8, // speed + 4*FRACUNIT, // radius + 128*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SPAWNCEILING|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_STALAGMITE3 - 1903, // doomednum - S_STG3, // spawnstate + { // MT_FLAME + 1101, // doomednum + S_FLAME, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + MT_FLAMEPARTICLE, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -8229,19 +10359,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 8*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset - 100, // mass + DMG_FIRE, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOGRAVITY|MF_PAIN|MF_FIRE, // flags S_NULL // raisestate }, - { // MT_STALAGMITE4 - 1904, // doomednum - S_STG4, // spawnstate + { // MT_FLAMEPARTICLE + -1, // doomednum + S_FLAMEPARTICLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8256,19 +10386,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + FRACUNIT, // radius + FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_STALAGMITE5 - 1905, // doomednum - S_STG5, // spawnstate + { // MT_EGGSTATUE + 1102, // doomednum + S_EGGSTATUE1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8283,23 +10413,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 32*FRACUNIT, // radius + 240*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage + 1, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SOLID|MF_PUSHABLE|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_STALAGMITE6 - 1906, // doomednum - S_STG6, // spawnstate + { // MT_MACEPOINT + 1104, // doomednum + S_INVISIBLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -8309,24 +10439,24 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 10*FRACUNIT, // speed + 128*FRACUNIT, // radius + 1*FRACUNIT, // height 0, // display offset - 100, // mass + 10000, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_STALAGMITE7 - 1907, // doomednum - S_STG7, // spawnstate + { // MT_CHAINMACEPOINT + 1105, // doomednum + S_INVISIBLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -8336,24 +10466,24 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 10*FRACUNIT, // speed + 128*FRACUNIT, // radius + 1*FRACUNIT, // height 0, // display offset - 100, // mass + 10000, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_STALAGMITE8 - 1908, // doomednum - S_STG8, // spawnstate + { // MT_SPRINGBALLPOINT + 1106, // doomednum + S_INVISIBLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -8363,24 +10493,24 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 10*FRACUNIT, // speed + 128*FRACUNIT, // radius + 1*FRACUNIT, // height 0, // display offset - 100, // mass + 10000, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_STALAGMITE9 - 1909, // doomednum - S_STG9, // spawnstate + { // MT_CHAINPOINT + 1107, // doomednum + S_INVISIBLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -8390,24 +10520,24 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 10*FRACUNIT, // speed + 128*FRACUNIT, // radius + 1*FRACUNIT, // height 0, // display offset - 100, // mass + 10000, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_XMASPOLE - 1850, // doomednum - S_XMASPOLE, // spawnstate + { // MT_HIDDEN_SLING + 1108, // doomednum + S_SLING1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -8417,24 +10547,24 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 10*FRACUNIT, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height 0, // display offset - 100, // mass + 0, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_CANDYCANE - 1851, // doomednum - S_CANDYCANE, // spawnstate + { // MT_FIREBARPOINT + 1109, // doomednum + S_INVISIBLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -8444,24 +10574,24 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed - 8*FRACUNIT, // radius - 32*FRACUNIT, // height + 10*FRACUNIT, // speed + 128*FRACUNIT, // radius + 1*FRACUNIT, // height 0, // display offset - 16, // mass + 200, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_SNOWMAN - 1852, // doomednum - S_SNOWMAN, // spawnstate + { // MT_CUSTOMMACEPOINT + 1110, // doomednum + S_INVISIBLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -8471,23 +10601,47 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 25*FRACUNIT, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 10*FRACUNIT, // speed + 128*FRACUNIT, // radius + 1*FRACUNIT, // height 0, // display offset - 100, // mass - 1, // damage + 200, // mass + 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, - // No, I did not do all of this by hand. - // I made a script to make all of these for me. - // Ha HA. ~Inuyasha - { // MT_BSZTALLFLOWER_RED - 1400, // doomednum - S_BSZTALLFLOWER_RED, // spawnstate + { // MT_SMALLMACECHAIN + -1, // doomednum + S_SMALLMACECHAIN, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 24*FRACUNIT, // speed + 17*FRACUNIT, // radius + 34*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_SCENERY|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_BIGMACECHAIN + -1, // doomednum + S_BIGMACECHAIN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8501,20 +10655,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 48*FRACUNIT, // speed + 34*FRACUNIT, // radius + 68*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage + 1, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SCENERY|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_BSZTALLFLOWER_PURPLE - 1401, // doomednum - S_BSZTALLFLOWER_PURPLE, // spawnstate + { // MT_SMALLMACE + -1, // doomednum + S_SMALLMACE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8528,20 +10682,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + 24*FRACUNIT, // speed + 17*FRACUNIT, // radius + 34*FRACUNIT, // height + 1, // display offset + 0, // mass + 1, // damage + sfx_s3kc9s, //sfx_mswing, -- activesound + MF_SCENERY|MF_PAIN|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_BSZTALLFLOWER_BLUE - 1402, // doomednum - S_BSZTALLFLOWER_BLUE, // spawnstate + { // MT_BIGMACE + -1, // doomednum + S_BIGMACE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8555,20 +10709,47 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + 48*FRACUNIT, // speed + 34*FRACUNIT, // radius + 68*FRACUNIT, // height + 1, // display offset + 0, // mass + 1, // damage + sfx_s3kc9s, //sfx_mswing, -- activesound + MF_SCENERY|MF_PAIN|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_BSZTALLFLOWER_CYAN - 1403, // doomednum - S_BSZTALLFLOWER_CYAN, // spawnstate + { // MT_SMALLGRABCHAIN + -1, // doomednum + S_SMALLGRABCHAIN, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 24*FRACUNIT, // speed + 17*FRACUNIT, // radius + 34*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_SCENERY|MF_SPECIAL|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_BIGGRABCHAIN + -1, // doomednum + S_BIGGRABCHAIN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8582,101 +10763,128 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 48*FRACUNIT, // speed + 34*FRACUNIT, // radius + 68*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage + 1, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SCENERY|MF_SPECIAL|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_BSZTALLFLOWER_YELLOW - 1404, // doomednum - S_BSZTALLFLOWER_YELLOW, // spawnstate + { // MT_YELLOWSPRINGBALL + -1, // doomednum + S_YELLOWSPRINGBALL, // spawnstate 1000, // spawnhealth - S_NULL, // seestate + S_YELLOWSPRINGBALL2, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance - sfx_None, // painsound + sfx_spring, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass + 24*FRACUNIT, // speed + 17*FRACUNIT, // radius + 34*FRACUNIT, // height + 1, // display offset + 20*FRACUNIT, // mass 0, // damage - sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags - S_NULL // raisestate + sfx_mswing, // activesound + MF_SCENERY|MF_SPRING|MF_NOGRAVITY, // flags + S_YELLOWSPRINGBALL2 // raisestate }, - { // MT_BSZTALLFLOWER_ORANGE - 1405, // doomednum - S_BSZTALLFLOWER_ORANGE, // spawnstate + { // MT_REDSPRINGBALL + -1, // doomednum + S_REDSPRINGBALL, // spawnstate + 1000, // spawnhealth + S_REDSPRINGBALL2, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_spring, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 24*FRACUNIT, // speed + 17*FRACUNIT, // radius + 34*FRACUNIT, // height + 1, // display offset + 32*FRACUNIT, // mass + 0, // damage + sfx_mswing, // activesound + MF_SCENERY|MF_SPRING|MF_NOGRAVITY, // flags + S_REDSPRINGBALL2 // raisestate + }, + + { // MT_SMALLFIREBAR + -1, // doomednum + S_SMALLFIREBAR1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + MT_FLAMEPARTICLE, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // speed + 17*FRACUNIT, // radius + 34*FRACUNIT, // height 0, // display offset - 100, // mass - 0, // damage + DMG_FIRE, // mass + 1, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SCENERY|MF_PAIN|MF_FIRE|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_BSZFLOWER_RED - 1410, // doomednum - S_BSZFLOWER_RED, // spawnstate + { // MT_BIGFIREBAR + -1, // doomednum + S_BIGFIREBAR1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + MT_FLAMEPARTICLE, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage + 48*FRACUNIT, // speed + 34*FRACUNIT, // radius + 68*FRACUNIT, // height + 1, // display offset + DMG_FIRE, // mass + 1, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SCENERY|MF_PAIN|MF_FIRE|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_BSZFLOWER_PURPLE - 1411, // doomednum - S_BSZFLOWER_PURPLE, // spawnstate + { // MT_CEZFLOWER + 1103, // doomednum + S_CEZFLOWER, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8692,7 +10900,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 40*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage @@ -8701,9 +10909,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BSZFLOWER_BLUE - 1412, // doomednum - S_BSZFLOWER_BLUE, // spawnstate + { // MT_CEZPOLE + 1117, // doomednum + S_CEZPOLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8718,8 +10926,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 40*FRACUNIT, // radius + 224*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage @@ -8728,9 +10936,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BSZFLOWER_CYAN - 1413, // doomednum - S_BSZFLOWER_CYAN, // spawnstate + { // MT_CEZBANNER + -1, // doomednum + S_CEZBANNER, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8745,8 +10953,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 40*FRACUNIT, // radius + 224*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage @@ -8755,9 +10963,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BSZFLOWER_YELLOW - 1414, // doomednum - S_BSZFLOWER_YELLOW, // spawnstate + { // MT_PINETREE + 1114, // doomednum + S_PINETREE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8773,18 +10981,18 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 628*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOGRAVITY|MF_SOLID|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_BSZFLOWER_ORANGE - 1415, // doomednum - S_BSZFLOWER_ORANGE, // spawnstate + { // MT_CEZBUSH1 + 1115, // doomednum + S_CEZBUSH1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8800,7 +11008,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage @@ -8809,9 +11017,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BSZSHORTFLOWER_RED - 1420, // doomednum - S_BSZSHORTFLOWER_RED, // spawnstate + { // MT_CEZBUSH2 + 1116, // doomednum + S_CEZBUSH2, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8826,8 +11034,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 3*FRACUNIT, // radius + 48*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage @@ -8836,9 +11044,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BSZSHORTFLOWER_PURPLE - 1421, // doomednum - S_BSZSHORTFLOWER_PURPLE, // spawnstate + { // MT_CANDLE + 1119, // doomednum + S_CANDLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8853,19 +11061,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 8*FRACUNIT, // radius + 48*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_BSZSHORTFLOWER_BLUE - 1422, // doomednum - S_BSZSHORTFLOWER_BLUE, // spawnstate + { // MT_CANDLEPRICKET + 1120, // doomednum + S_CANDLEPRICKET, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8880,19 +11088,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 8*FRACUNIT, // radius + 176*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SOLID, // flags S_NULL // raisestate }, - { // MT_BSZSHORTFLOWER_CYAN - 1423, // doomednum - S_BSZSHORTFLOWER_CYAN, // spawnstate + { // MT_FLAMEHOLDER + 1121, // doomednum + S_FLAMEHOLDER, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8907,26 +11115,26 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // radius + 80*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SOLID, // flags S_NULL // raisestate }, - { // MT_BSZSHORTFLOWER_YELLOW - 1424, // doomednum - S_BSZSHORTFLOWER_YELLOW, // spawnstate + { // MT_FIRETORCH + 1122, // doomednum + S_FIRETORCH, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + MT_FLAMEPARTICLE, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -8935,18 +11143,18 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 80*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_BSZSHORTFLOWER_ORANGE - 1425, // doomednum - S_BSZSHORTFLOWER_ORANGE, // spawnstate + { // MT_WAVINGFLAG + 1118, // doomednum + S_WAVINGFLAG, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8961,19 +11169,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 4*FRACUNIT, // radius + 104*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SOLID, // flags S_NULL // raisestate }, - { // MT_BSZTULIP_RED - 1430, // doomednum - S_BSZTULIP_RED, // spawnstate + { // MT_WAVINGFLAGSEG + -1, // doomednum + S_WAVINGFLAGSEG, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -8988,19 +11196,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 4*FRACUNIT, // radius + 1, // height -- this is not a typo 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_BSZTULIP_PURPLE - 1431, // doomednum - S_BSZTULIP_PURPLE, // spawnstate + { // MT_CRAWLASTATUE + 1111, // doomednum + S_CRAWLASTATUE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -9016,18 +11224,18 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 40*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags S_NULL // raisestate }, - { // MT_BSZTULIP_BLUE - 1432, // doomednum - S_BSZTULIP_BLUE, // spawnstate + { // MT_FACESTABBERSTATUE + 1112, // doomednum + S_FACESTABBERSTATUE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -9042,22 +11250,22 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 32*FRACUNIT, // radius + 72*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags S_NULL // raisestate }, - { // MT_BSZTULIP_CYAN - 1433, // doomednum - S_BSZTULIP_CYAN, // spawnstate + { // MT_SUSPICIOUSFACESTABBERSTATUE + 1113, // doomednum + S_SUSPICIOUSFACESTABBERSTATUE_WAIT, // spawnstate 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound + S_SUSPICIOUSFACESTABBERSTATUE_BURST1, // seestate + sfx_s3k6f, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -9069,19 +11277,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 32*FRACUNIT, // radius + 72*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags - S_NULL // raisestate + MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags + MT_ROCKCRUMBLE3 // raisestate }, - { // MT_BSZTULIP_YELLOW - 1434, // doomednum - S_BSZTULIP_YELLOW, // spawnstate + { // MT_BRAMBLES + 1125, // doomednum + S_BRAMBLES, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -9096,21 +11304,21 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius + 48*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SCENERY|MF_NOBLOCKMAP, // flags S_NULL // raisestate }, - { // MT_BSZTULIP_ORANGE - 1435, // doomednum - S_BSZTULIP_ORANGE, // spawnstate + { // MT_BIGTUMBLEWEED + 1200, // doomednum + S_BIGTUMBLEWEED,// spawnstate 1000, // spawnhealth - S_NULL, // seestate + S_BIGTUMBLEWEED_ROLL1, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound @@ -9123,21 +11331,21 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // radius + 48*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + 1, // damage + sfx_s3k64, // activesound + MF_SPECIAL|MF_BOUNCE, // flags S_NULL // raisestate }, - { // MT_BSZCLUSTER_RED - 1440, // doomednum - S_BSZCLUSTER_RED, // spawnstate + { // MT_LITTLETUMBLEWEED + 1201, // doomednum + S_LITTLETUMBLEWEED,// spawnstate 1000, // spawnhealth - S_NULL, // seestate + S_LITTLETUMBLEWEED_ROLL1, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound @@ -9150,19 +11358,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 12*FRACUNIT, // radius + 24*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + 1, // damage + sfx_s3k64, // activesound + MF_SPECIAL|MF_BOUNCE, // flags S_NULL // raisestate }, - { // MT_BSZCLUSTER_PURPLE - 1441, // doomednum - S_BSZCLUSTER_PURPLE, // spawnstate + { // MT_CACTI1 + 1203, // doomednum + S_CACTI1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -9187,9 +11395,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BSZCLUSTER_BLUE - 1442, // doomednum - S_BSZCLUSTER_BLUE, // spawnstate + { // MT_CACTI2 + 1204, // doomednum + S_CACTI2, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -9205,7 +11413,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 64*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage @@ -9214,9 +11422,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BSZCLUSTER_CYAN - 1443, // doomednum - S_BSZCLUSTER_CYAN, // spawnstate + { // MT_CACTI3 + 1205, // doomednum + S_CACTI3, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -9241,9 +11449,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BSZCLUSTER_YELLOW - 1444, // doomednum - S_BSZCLUSTER_YELLOW, // spawnstate + { // MT_CACTI4 + 1206, // doomednum + S_CACTI4, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -9259,7 +11467,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 80*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage @@ -9268,9 +11476,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BSZCLUSTER_ORANGE - 1445, // doomednum - S_BSZCLUSTER_ORANGE, // spawnstate + { // MT_CACTI5 + 1207, // doomednum + S_CACTI5, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -9285,19 +11493,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 32*FRACUNIT, // radius + 96*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SOLID|MF_SCENERY|MF_PAIN, // flags S_NULL // raisestate }, - { // MT_BSZBUSH_RED - 1450, // doomednum - S_BSZBUSH_RED, // spawnstate + { // MT_CACTI6 + 1208, // doomednum + S_CACTI6, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -9312,19 +11520,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 20*FRACUNIT, // radius + 128*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SOLID|MF_SCENERY|MF_PAIN, // flags S_NULL // raisestate }, - { // MT_BSZBUSH_PURPLE - 1451, // doomednum - S_BSZBUSH_PURPLE, // spawnstate + { // MT_CACTI7 + 1209, // doomednum + S_CACTI7, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -9339,19 +11547,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // radius + 224*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SOLID|MF_SCENERY|MF_PAIN, // flags S_NULL // raisestate }, - { // MT_BSZBUSH_BLUE - 1452, // doomednum - S_BSZBUSH_BLUE, // spawnstate + { // MT_CACTI8 + 1210, // doomednum + S_CACTI8, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -9366,19 +11574,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // radius + 256*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SOLID|MF_SCENERY|MF_PAIN, // flags S_NULL // raisestate }, - { // MT_BSZBUSH_CYAN - 1453, // doomednum - S_BSZBUSH_CYAN, // spawnstate + { // MT_CACTI9 + 1211, // doomednum + S_CACTI9, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -9393,19 +11601,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 48*FRACUNIT, // radius + 96*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SOLID|MF_SCENERY|MF_PAIN, // flags S_NULL // raisestate }, - { // MT_BSZBUSH_YELLOW - 1454, // doomednum - S_BSZBUSH_YELLOW, // spawnstate + { // MT_ARIDSIGN_CAUTION + 1212, // doomednum + S_ARIDSIGN_CAUTION, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -9420,19 +11628,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 22*FRACUNIT, // radius + 64*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SCENERY|MF_SOLID|MF_PAPERCOLLISION, // flags S_NULL // raisestate }, - { // MT_BSZBUSH_ORANGE - 1455, // doomednum - S_BSZBUSH_ORANGE, // spawnstate + { // MT_ARIDSIGN_CACTI + 1213, // doomednum + S_ARIDSIGN_CACTI, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -9447,19 +11655,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 22*FRACUNIT, // radius + 64*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SCENERY|MF_SOLID|MF_PAPERCOLLISION, // flags S_NULL // raisestate }, - { // MT_BSZVINE_RED - 1460, // doomednum - S_BSZVINE_RED, // spawnstate + { // MT_ARIDSIGN_SHARPTURN + 1214, // doomednum + S_ARIDSIGN_SHARPTURN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -9475,22 +11683,22 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 192*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SCENERY|MF_SOLID|MF_PAPERCOLLISION, // flags S_NULL // raisestate }, - { // MT_BSZVINE_PURPLE - 1461, // doomednum - S_BSZVINE_PURPLE, // spawnstate - 1000, // spawnhealth + { // MT_OILLAMP + 1215, // doomednum + S_OILLAMP, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -9501,50 +11709,50 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 22*FRACUNIT, // radius + 64*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage - sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + sfx_s3k4b, // activesound + MF_SCENERY|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SPAWNCEILING, // flags S_NULL // raisestate }, - { // MT_BSZVINE_BLUE - 1462, // doomednum - S_BSZVINE_BLUE, // spawnstate - 1000, // spawnhealth + { // MT_TNTBARREL + 1216, // doomednum + S_TNTBARREL_STND1, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate + 0, // reactiontime + sfx_bowl, // attacksound + S_TNTBARREL_EXPL1, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate + S_TNTBARREL_FLYING, // missilestate + S_TNTBARREL_EXPL1, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound + sfx_s3k4e, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // radius + 63*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SOLID|MF_SHOOTABLE|MF_ENEMY|MF_PUSHABLE, // flags S_NULL // raisestate }, - { // MT_BSZVINE_CYAN - 1463, // doomednum - S_BSZVINE_CYAN, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime + { // MT_PROXIMITYTNT + 1217, // doomednum + S_PROXIMITY_TNT, // spawnstate + 1, // spawnhealth + S_PROXIMITY_TNT_TRIGGER1, // seestate + sfx_s3k5c, // seesound + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -9553,25 +11761,25 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound + sfx_s3k4e, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 64*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage - sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + sfx_s3k89, // activesound + MF_SOLID, // flags S_NULL // raisestate }, - { // MT_BSZVINE_YELLOW - 1464, // doomednum - S_BSZVINE_YELLOW, // spawnstate - 1000, // spawnhealth + { // MT_DUSTDEVIL + 1218, // doomednum + S_DUSTDEVIL, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -9581,24 +11789,24 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 2, // speed + 80*FRACUNIT, // radius + 416*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage - sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + sfx_s3k4b, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_BSZVINE_ORANGE - 1465, // doomednum - S_BSZVINE_ORANGE, // spawnstate - 1000, // spawnhealth + { // MT_DUSTLAYER + -1, // doomednum + S_DUSTLAYER1, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -9609,23 +11817,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 64*FRACUNIT, // radius + 256*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_BSZSHRUB - 1470, // doomednum - S_BSZSHRUB, // spawnstate - 1000, // spawnhealth + { // MT_ARIDDUST + -1, // doomednum + S_ARIDDUST1, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -9637,49 +11845,49 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOCLIPHEIGHT, // flags S_NULL // raisestate }, - { // MT_BSZCLOVER - 1471, // doomednum - S_BSZCLOVER, // spawnstate - 1000, // spawnhealth + { // MT_MINECART + -1, // doomednum + S_MINECART_IDLE,// spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 24*FRACUNIT, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance - sfx_None, // painsound + sfx_statu2, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_MINECART_DTH1,// deathstate S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius + sfx_s3k59, // deathsound + 20*FRACUNIT, // speed + 22*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage - sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags - S_NULL // raisestate + sfx_s3k76, // activesound + MF_PUSHABLE, // flags + MT_MINECARTSIDEMARK // raisestate }, - { // MT_BSZFISH - 1472, // doomednum - S_BSZFISH, // spawnstate - 1000, // spawnhealth + { // MT_MINECARTSEG + -1, // doomednum + S_INVISIBLE, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -9690,23 +11898,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius + FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP, // flags S_NULL // raisestate }, - { // MT_BSZSUNFLOWER - 1473, // doomednum - S_BSZSUNFLOWER, // spawnstate + { // MT_MINECARTSPAWNER + 1219, // doomednum + S_INVISIBLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -9717,23 +11925,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 22*FRACUNIT, // radius + 16*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_SPECIAL, // flags S_NULL // raisestate }, - { // MT_DBALL - 1875, // doomednum - S_DBALL1, // spawnstate - 1000, // spawnhealth + { // MT_MINECARTEND + 1220, // doomednum + S_MINECARTEND, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -9743,24 +11951,24 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed - 16*FRACUNIT, // radius - 54*FRACUNIT, // height + 0, // speed + 32*FRACUNIT, // radius + 160*FRACUNIT, // height 0, // display offset - 16, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SPAWNCEILING|MF_NOGRAVITY|MF_SCENERY, // flags + MF_SPECIAL|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_EGGSTATUE2 - 1876, // doomednum - S_EGGSTATUE2, // spawnstate - 1000, // spawnhealth + { // MT_MINECARTENDSOLID + -1, // doomednum + S_INVISIBLE, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -9771,185 +11979,185 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 20*FRACUNIT, // radius - 96*FRACUNIT, // height + 32*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 0, // damage sfx_None, // activesound - MF_SOLID|MF_PUSHABLE|MF_SCENERY, // flags + MF_SOLID|MF_PAPERCOLLISION|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_GREENORB + { // MT_MINECARTSIDEMARK -1, // doomednum - S_ELEM1, // spawnstate - 1000, // spawnhealth - S_ELEMF1, // seestate + S_MINECARTSIDEMARK2, // spawnstate + 1, // spawnhealth + S_NULL, // seestate sfx_None, // seesound 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate - SKINCOLOR_NONE, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - SH_ELEMENTAL, // speed - 64*FRACUNIT, // radius - 64*FRACUNIT, // height - 1, // display offset - 16, // mass + 0, // speed + 22*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_YELLOWORB + { // MT_MINECARTSPARK -1, // doomednum - S_MAGN1, // spawnstate - 1000, // spawnhealth + S_MINECARTSPARK,// spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate - SKINCOLOR_NONE, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - SH_ATTRACT, // speed - 64*FRACUNIT, // radius - 64*FRACUNIT, // height - 1, // display offset - 16, // mass + 0, // speed + 2*FRACUNIT, // radius + 2*FRACUNIT, // height + 0, // display offset + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + MF_BOUNCE|MF_NOCLIPTHING|MF_GRENADEBOUNCE, // flags S_NULL // raisestate }, - { // MT_BLUEORB + { // MT_SALOONDOOR -1, // doomednum - S_FORC1, // spawnstate - 1000, // spawnhealth + S_SALOONDOOR, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound - S_FORC11, // painstate - SKINCOLOR_NONE, // painchance + S_NULL, // painstate + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - SH_FORCE, // speed - 64*FRACUNIT, // radius - 64*FRACUNIT, // height - 1, // display offset - 16, // mass + 0, // speed + 48*FRACUNIT, // radius + 160*FRACUNIT, // height + 0, // display offset + 100, // mass 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + sfx_s3k90, // activesound + MF_SOLID|MF_NOGRAVITY|MF_RUNSPAWNFUNC|MF_PAPERCOLLISION|MF_NOCLIPHEIGHT, // flags S_NULL // raisestate }, - { // MT_BLACKORB - -1, // doomednum - S_ARMA1, // spawnstate - 1000, // spawnhealth - S_ARMF1, // seestate + { // MT_SALOONDOORTHINKER + 1221, // doomednum + S_SALOONDOORTHINKER, // spawnstate + 1, // spawnhealth + S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate - SKINCOLOR_NONE, // painchance + 0, // painchance sfx_None, // painsound - S_ARMB1, // meleestate + S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - SH_BOMB, // speed - 64*FRACUNIT, // radius - 64*FRACUNIT, // height - 1, // display offset - 16, // mass + 0, // speed + 96*FRACUNIT, // radius + 160*FRACUNIT, // height + 0, // display offset + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags S_NULL // raisestate }, - { // MT_WHITEORB - -1, // doomednum - S_WIND1, // spawnstate - 1000, // spawnhealth + { // MT_TRAINCAMEOSPAWNER + 1222, // doomednum + S_TRAINCAMEOSPAWNER_1, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate - SKINCOLOR_NONE, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - SH_JUMP, // speed - 64*FRACUNIT, // radius - 64*FRACUNIT, // height - 1, // display offset - 16, // mass + 0, // speed + 28*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOGRAVITY|MF_NOCLIP, // flags S_NULL // raisestate }, - { // MT_PITYORB + { // MT_TRAINSEG -1, // doomednum - S_PITY1, // spawnstate - 1000, // spawnhealth + S_INVISIBLE, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate - SKINCOLOR_NONE, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - SH_PITY, // speed - 64*FRACUNIT, // radius - 64*FRACUNIT, // height - 1, // display offset - 16, // mass + 0, // speed + FRACUNIT, // radius + FRACUNIT, // height + 0, // display offset + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags S_NULL // raisestate }, - { // MT_IVSP - -1, // doomednum - S_IVSP, // spawnstate - 1000, // spawnhealth + { // MT_TRAINDUSTSPAWNER + 1223, // doomednum + S_INVISIBLE, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -9959,24 +12167,24 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed - 64*FRACUNIT, // radius - 64*FRACUNIT, // height - 2, // display offset - 16, // mass + 0, // speed + FRACUNIT, // radius + FRACUNIT, // height + 0, // display offset + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP, // flags S_NULL // raisestate }, - { // MT_SUPERSPARK - -1, // doomednum - S_SSPK1, // spawnstate + { // MT_TRAINSTEAMSPAWNER + 1224, // doomednum + S_INVISIBLE, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -9987,23 +12195,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8*FRACUNIT, // radius - 8*FRACUNIT, // height + FRACUNIT, // radius + FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP, // flags S_NULL // raisestate }, - { // MT_BIRD - -1, // doomednum - S_BIRD1, // spawnstate - 1000, // spawnhealth - S_BIRD1, // seestate + { // MT_MINECARTSWITCHPOINT + 1229, // doomednum + S_INVISIBLE, // spawnstate + 1, // spawnhealth + S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -10013,23 +12221,22 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height + 0, // speed + FRACUNIT, // radius + 160*FRACUNIT, // height 0, // display offset - 16, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOCLIPTHING|MF_FLOAT|MF_NOGRAVITY, // flags + MF_SPECIAL|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags S_NULL // raisestate }, - // freed bunny - { // MT_BUNNY - -1, // doomednum - S_BUNNY1, // spawnstate + { // MT_FLAMEJET + 1300, // doomednum + S_FLAMEJETSTND, // spawnstate 1000, // spawnhealth - S_BUNNY1, // seestate + S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound @@ -10041,51 +12248,51 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed + 0, // speed 16*FRACUNIT, // radius - 16*FRACUNIT, // height + 40*FRACUNIT, // height 0, // display offset - 16, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOCLIPTHING|MF_FLOAT, // flags + MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOSECTOR, // flags S_NULL // raisestate }, - { // MT_MOUSE - -1, // doomednum - S_MOUSE1, // spawnstate - 1, // spawnhealth + { // MT_VERTICALFLAMEJET + 1301, // doomednum + S_FLAMEJETSTND, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 1, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 200, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 20*FRACUNIT, // speed - 4*FRACUNIT, // radius - 4*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOCLIPTHING, // flags + MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOSECTOR, // flags S_NULL // raisestate }, - { // MT_CHICKEN + { // MT_FLAMEJETFLAME -1, // doomednum - S_CHICKEN1, // spawnstate + S_FLAMEJETFLAME1, // spawnstate 1000, // spawnhealth - S_CHICKEN1, // seestate + S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -10095,49 +12302,49 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 1, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height + 5*FRACUNIT, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height 0, // display offset - 16, // mass + DMG_FIRE, // mass 0, // damage sfx_None, // activesound - MF_NOCLIPTHING|MF_FLOAT, // flags + MF_NOGRAVITY|MF_MISSILE|MF_FIRE, // flags S_NULL // raisestate }, - { // MT_COW - -1, // doomednum - S_COW1, // spawnstate - 1, // spawnhealth + { // MT_FJSPINAXISA + 1302, // doomednum + S_FJSPINAXISA1, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 1, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 200, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 4, // speed - 4*FRACUNIT, // radius - 4*FRACUNIT, // height + 10*FRACUNIT, // speed + 16*FRACUNIT, // radius + 1*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage + 1, // damage sfx_None, // activesound - MF_NOCLIPTHING, // flags + MF_NOCLIP|MF_NOCLIPTHING|MF_NOGRAVITY|MF_NOSECTOR, // flags S_NULL // raisestate }, - { // MT_REDBIRD - -1, // doomednum - S_RBIRD1, // spawnstate + { // MT_FJSPINAXISB + 1303, // doomednum + S_FJSPINAXISB1, // spawnstate 1000, // spawnhealth - S_RBIRD1, // seestate + S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound @@ -10149,23 +12356,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed + 10*FRACUNIT, // speed 16*FRACUNIT, // radius - 16*FRACUNIT, // height + 1*FRACUNIT, // height 0, // display offset - 16, // mass - 0, // damage + 100, // mass + 1, // damage sfx_None, // activesound - MF_NOCLIPTHING|MF_FLOAT|MF_NOGRAVITY, // flags + MF_NOCLIP|MF_NOCLIPTHING|MF_NOGRAVITY|MF_NOSECTOR, // flags S_NULL // raisestate }, - { // MT_RAIN + { // MT_FLAMEJETFLAMEB -1, // doomednum - S_RAIN1, // spawnstate + S_FLAMEJETFLAMEB1, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_None, // seesound + sfx_fire, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -10176,20 +12383,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - -24*FRACUNIT, // speed - 1*FRACUNIT, // radius - 8*FRACUNIT, // height + 18, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height 0, // display offset - 4, // mass - 0, // damage + DMG_FIRE, // mass + 1, // damage sfx_None, // activesound - MF_NOBLOCKMAP, // flags + MF_NOGRAVITY|MF_MISSILE|MF_FIRE|MF_NOBLOCKMAP|MF_RUNSPAWNFUNC, // flags S_NULL // raisestate }, - { // MT_SNOWFLAKE - -1, // doomednum - S_SNOW1, // spawnstate + { // MT_TRAPGOYLE + 1500, // doomednum + S_TRAPGOYLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -10203,20 +12410,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - -2*FRACUNIT, // speed - 4*FRACUNIT, // radius - 4*FRACUNIT, // height + 21*FRACUNIT, // speed + 16*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset - 4, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP, // flags + 100, // mass + 1, // damage + sfx_statu2, // activesound + MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags S_NULL // raisestate }, - { // MT_SPLISH - -1, // doomednum - S_SPLISH1, // spawnstate + { // MT_TRAPGOYLEUP + 1501, // doomednum + S_TRAPGOYLEUP, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -10230,20 +12437,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 6*FRACUNIT, // radius - 1*FRACUNIT, // height + 21*FRACUNIT, // speed + 16*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass 1, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + sfx_statu2, // activesound + MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags S_NULL // raisestate }, - { // MT_SMOKE - -1, // doomednum - S_SMOKE1, // spawnstate + { // MT_TRAPGOYLEDOWN + 1502, // doomednum + S_TRAPGOYLEDOWN,// spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -10257,20 +12464,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 20*FRACUNIT, // radius - 16*FRACUNIT, // height + 21*FRACUNIT, // speed + 16*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY, // flags + 1, // damage + sfx_statu2, // activesound + MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags S_NULL // raisestate }, - { // MT_SMALLBUBBLE - -1, // doomednum - S_SMALLBUBBLE, // spawnstate + { // MT_TRAPGOYLELONG + 1503, // doomednum + S_TRAPGOYLELONG,// spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -10284,47 +12491,47 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed - 4*FRACUNIT, // radius - 4*FRACUNIT, // height + 21*FRACUNIT, // speed + 16*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset - 16, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + 100, // mass + 1, // damage + sfx_statu2, // activesound + MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags S_NULL // raisestate }, - { // MT_MEDIUMBUBBLE - -1, // doomednum - S_MEDIUMBUBBLE, // spawnstate - 1000, // spawnhealth + { // MT_TARGET + 1504, // doomednum + S_TARGET_IDLE, // spawnstate + 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 32, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + 200, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate + S_TARGET_HIT1, // deathstate + S_TARGET_ALLDONE, // xdeathstate sfx_None, // deathsound - 8, // speed - 8*FRACUNIT, // radius - 8*FRACUNIT, // height + 0, // speed + 24*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset - 16, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + MF_SPECIAL|MF_SHOOTABLE, // flags S_NULL // raisestate }, - { // MT_EXTRALARGEBUBBLE - -1, // doomednum - S_LARGEBUBBLE, // spawnstate + { // MT_STALAGMITE0 + 1900, // doomednum + S_STG0, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -10335,24 +12542,24 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_POP1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_gasp, // deathsound - 8, // speed - 8*FRACUNIT, // radius - 12*FRACUNIT, // height + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset - 16, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_TFOG - -1, // doomednum - S_FOG1, // spawnstate - 1, // spawnhealth + { // MT_STALAGMITE1 + 1901, // doomednum + S_STG1, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime @@ -10367,18 +12574,18 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 40*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_SEED - -1, // doomednum - S_SEED, // spawnstate + { // MT_STALAGMITE2 + 1902, // doomednum + S_STG2, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -10392,20 +12599,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - -2*FRACUNIT, // speed - 4*FRACUNIT, // radius - 4*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset - 4, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_PARTICLE - -1, // doomednum - S_PARTICLE, // spawnstate + { // MT_STALAGMITE3 + 1903, // doomednum + S_STG3, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -10419,20 +12626,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 4*FRACUNIT, // speed - 4*FRACUNIT, // radius - 4*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset - 4, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_PARTICLEGEN - 757, // doomednum - S_PARTICLEGEN, // spawnstate + { // MT_STALAGMITE4 + 1904, // doomednum + S_STG4, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -10446,21 +12653,21 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed - 1*FRACUNIT, // radius - 1*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset - 16, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_SCORE - -1, // doomednum - S_SCRA, // spawnstate - 1, // spawnhealth + { // MT_STALAGMITE5 + 1905, // doomednum + S_STG5, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime @@ -10473,20 +12680,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 3*FRACUNIT, // speed - 8*FRACUNIT, // radius - 8*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_DROWNNUMBERS - -1, // doomednum - S_ZERO1, // spawnstate + { // MT_STALAGMITE6 + 1906, // doomednum + S_STG6, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -10500,20 +12707,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed - 8*FRACUNIT, // radius - 8*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset - 16, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_GOTEMERALD - -1, // doomednum - S_CEMG1, // spawnstate + { // MT_STALAGMITE7 + 1907, // doomednum + S_STG7, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -10522,25 +12729,25 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // painstate 0, // painchance sfx_None, // painsound - S_ORBITEM1, // meleestate + S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset - 16, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_TAG - -1, // doomednum - S_TTAG1, // spawnstate + { // MT_STALAGMITE8 + 1908, // doomednum + S_STG8, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -10554,20 +12761,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed + 0, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 40*FRACUNIT, // height 0, // display offset - 16, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_GOTFLAG - -1, // doomednum - S_GOTFLAG1, // spawnstate + { // MT_STALAGMITE9 + 1909, // doomednum + S_STG9, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -10581,20 +12788,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed - 64*FRACUNIT, // radius - 32*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset - 16, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_GOTFLAG2 - -1, // doomednum - S_GOTFLAG3, // spawnstate + { // MT_XMASPOLE + 1850, // doomednum + S_XMASPOLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -10608,24 +12815,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed - 64*FRACUNIT, // radius - 32*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset - 16, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - // ambient water 1a (large) - { // MT_AWATERA - 700, // doomednum - S_INVISIBLE, // spawnstate - 35, // spawnhealth + { // MT_CANDYCANE + 1851, // doomednum + S_CANDYCANE, // spawnstate + 1000, // spawnhealth S_NULL, // seestate - sfx_amwtr1, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -10636,24 +12842,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height + 8, // speed + 8*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - // ambient water 1b (large) - { // MT_AWATERB - 701, // doomednum - S_INVISIBLE, // spawnstate - 35, // spawnhealth + { // MT_SNOWMAN + 1852, // doomednum + S_SNOWMAN, // spawnstate + 1000, // spawnhealth S_NULL, // seestate - sfx_amwtr2, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -10664,24 +12869,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 25*FRACUNIT, // speed 16*FRACUNIT, // radius - 16*FRACUNIT, // height + 64*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage + 1, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags + MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags S_NULL // raisestate }, - // ambient water 2a (medium) - { // MT_AWATERC - 702, // doomednum - S_INVISIBLE, // spawnstate - 35, // spawnhealth + { // MT_SNOWMANHAT + 1853, // doomednum + S_SNOWMANHAT, // spawnstate + 1000, // spawnhealth S_NULL, // seestate - sfx_amwtr3, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -10692,24 +12896,23 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 25*FRACUNIT, // speed 16*FRACUNIT, // radius - 16*FRACUNIT, // height + 80*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage + 1, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags + MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags S_NULL // raisestate }, - // ambient water 2b (medium) - { // MT_AWATERD - 703, // doomednum - S_INVISIBLE, // spawnstate - 35, // spawnhealth + { // MT_LAMPPOST1 + 1854, // doomednum + S_LAMPPOST1, // spawnstate + 1000, // spawnhealth S_NULL, // seestate - sfx_amwtr4, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -10721,23 +12924,22 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height + 8*FRACUNIT, // radius + 120*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage + 1, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags + MF_SOLID, // flags S_NULL // raisestate }, - // ambient water 3a (small) - { // MT_AWATERE - 704, // doomednum - S_INVISIBLE, // spawnstate - 35, // spawnhealth + { // MT_LAMPPOST2 + 1855, // doomednum + S_LAMPPOST2, // spawnstate + 1000, // spawnhealth S_NULL, // seestate - sfx_amwtr5, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -10749,23 +12951,22 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height + 8*FRACUNIT, // radius + 120*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage + 1, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags + MF_SOLID, // flags S_NULL // raisestate }, - // ambient water 3b (small) - { // MT_AWATERF - 705, // doomednum - S_INVISIBLE, // spawnstate - 35, // spawnhealth + { // MT_HANGSTAR + 1856, // doomednum + S_HANGSTAR, // spawnstate + 1000, // spawnhealth S_NULL, // seestate - sfx_amwtr6, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -10777,23 +12978,22 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height + 4*FRACUNIT, // radius + 80*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage + 1, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SPAWNCEILING|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, - // ambient water 4a (extra large) - { // MT_AWATERG - 706, // doomednum - S_INVISIBLE, // spawnstate - 35, // spawnhealth + { // MT_XMASBLUEBERRYBUSH + 1859, // doomednum + S_XMASBLUEBERRYBUSH, // spawnstate + 1000, // spawnhealth S_NULL, // seestate - sfx_amwtr7, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -10806,22 +13006,21 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 16*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - // ambient water 4b (extra large) - { // MT_AWATERH - 707, // doomednum - S_INVISIBLE, // spawnstate - 35, // spawnhealth + { // MT_XMASBERRYBUSH + 1857, // doomednum + S_XMASBERRYBUSH, // spawnstate + 1000, // spawnhealth S_NULL, // seestate - sfx_amwtr8, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -10834,25 +13033,25 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 16*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_RANDOMAMBIENT - 708, // doomednum - S_INVISIBLE, // spawnstate - 512, // spawnhealth: repeat speed + { // MT_XMASBUSH + 1858, // doomednum + S_XMASBUSH, // spawnstate + 1000, // spawnhealth S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -10860,26 +13059,26 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset - 1000, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_AMBIENT, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_RANDOMAMBIENT2 - 709, // doomednum - S_INVISIBLE, // spawnstate - 220, // spawnhealth: repeat speed + { // MT_FHZICE1 + 2100, // doomednum + S_FHZICE1, // spawnstate + 1000, // spawnhealth S_NULL, // seestate - sfx_ambin2, // seesound - 0, // reactiontime + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -10888,401 +13087,402 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset - 1000, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_AMBIENT, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_REDRING - -1, // doomednum - S_RRNG1, // spawnstate + { // MT_FHZICE2 + 2101, // doomednum + S_FHZICE2, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_thok, // seesound - 0, // reactiontime + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_itemup, // deathsound - 60*FRACUNIT, // speed - 16*FRACUNIT, // radius - 24*FRACUNIT, // height + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, -// Ring ammo: Health = amount given - { // MT_BOUNCERING - 301, // doomednum - S_BOUNCERINGAMMO, // spawnstate - 10, // spawnhealth + { // MT_JACKO1 + 2006, // doomednum + S_JACKO1, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_itemup, // deathsound - 60*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height + sfx_None, // deathsound + 0, // speed + FRACUNIT, // radius + FRACUNIT, // height 0, // display offset - pw_bouncering, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate + MF_NOBLOCKMAP|MF_SCENERY, // flags + S_JACKO1OVERLAY_1 // raisestate }, - { // MT_RAILRING - 302, // doomednum - S_RAILRINGAMMO, // spawnstate - 5, // spawnhealth + { // MT_JACKO2 + 2007, // doomednum + S_JACKO2, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_itemup, // deathsound - 60*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height + sfx_None, // deathsound + 0, // speed + FRACUNIT, // radius + FRACUNIT, // height 0, // display offset - pw_railring, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate + MF_NOBLOCKMAP|MF_SCENERY, // flags + S_JACKO2OVERLAY_1 // raisestate }, - { // MT_INFINITYRING - 303, // doomednum - S_INFINITYRINGAMMO,// spawnstate - 80, // spawnhealth + { // MT_JACKO3 + 2008, // doomednum + S_JACKO3, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_itemup, // deathsound - 60*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height + sfx_None, // deathsound + 0, // speed + FRACUNIT, // radius + FRACUNIT, // height 0, // display offset - pw_infinityring,// mass + 100, // mass 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate + MF_NOBLOCKMAP|MF_SCENERY, // flags + S_JACKO3OVERLAY_1 // raisestate }, - { // MT_AUTOMATICRING - 304, // doomednum - S_AUTOMATICRINGAMMO, // spawnstate - 40, // spawnhealth + { // MT_HHZTREE_TOP + 2010, // doomednum + S_HHZTREE_TOP, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_itemup, // deathsound - 60*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height + sfx_None, // deathsound + 0, // speed + FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset - pw_automaticring, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOTHINK|MF_SCENERY|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags S_NULL // raisestate }, - { // MT_EXPLOSIONRING - 305, // doomednum - S_EXPLOSIONRINGAMMO, // spawnstate - 5, // spawnhealth - S_NULL, // seestate + { // MT_HHZTREE_PART + -1, // doomednum + S_HHZTREE_TRUNK,// spawnstate + 1000, // spawnhealth + S_HHZTREE_LEAF, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_itemup, // deathsound - 60*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height + sfx_None, // deathsound + 0, // speed + FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset - pw_explosionring, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOTHINK|MF_SCENERY|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_SCATTERRING - 306, // doomednum - S_SCATTERRINGAMMO, // spawnstate - 5, // spawnhealth + { // MT_HHZSHROOM + 2009, // doomednum + S_HHZSHROOM_1, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_itemup, // deathsound - 60*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height + sfx_None, // deathsound + 0, // speed + FRACUNIT, // radius + FRACUNIT, // height 0, // display offset - pw_scatterring, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_SCENERY|MF_NOBLOCKMAP, // flags S_NULL // raisestate }, - { // MT_GRENADERING - 307, // doomednum - S_GRENADERINGAMMO, // spawnstate - 10, // spawnhealth + { // MT_HHZGRASS + 2001, // doomednum + S_HHZGRASS, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_itemup, // deathsound - 60*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height + sfx_None, // deathsound + 0, // speed + FRACUNIT, // radius + FRACUNIT, // height 0, // display offset - pw_grenadering, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOTHINK|MF_SCENERY|MF_NOBLOCKMAP, // flags S_NULL // raisestate }, -// Ring panels: Reactiontime = amount given - { // MT_BOUNCEPICKUP - 330, // doomednum - S_BOUNCEPICKUP, // spawnstate - 1, // spawnhealth + { // MT_HHZTENTACLE1 + 2002, // doomednum + S_HHZTENT1, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 10, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 1, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_BOUNCEPICKUPFADE1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_ncitem, // deathsound - 60*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height + sfx_None, // deathsound + 0, // speed + FRACUNIT, // radius + FRACUNIT, // height 0, // display offset - pw_bouncering, // mass - 2*TICRATE, // damage + 100, // mass + 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOTHINK|MF_SCENERY|MF_NOBLOCKMAP, // flags S_NULL // raisestate }, - { // MT_RAILPICKUP - 331, // doomednum - S_RAILPICKUP, // spawnstate - 1, // spawnhealth + { // MT_HHZTENTACLE2 + 2003, // doomednum + S_HHZTENT2, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 5, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 2, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_RAILPICKUPFADE1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_ncitem, // deathsound - 60*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height + sfx_None, // deathsound + 0, // speed + FRACUNIT, // radius + FRACUNIT, // height 0, // display offset - pw_railring, // mass - 2*TICRATE, // damage + 100, // mass + 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOTHINK|MF_SCENERY|MF_NOBLOCKMAP, // flags S_NULL // raisestate }, - { // MT_AUTOPICKUP - 332, // doomednum - S_AUTOPICKUP, // spawnstate - 1, // spawnhealth + { // MT_HHZSTALAGMITE_TALL + 2004, // doomednum + S_HHZSTALAGMITE_TALL, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 40, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 4, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_AUTOPICKUPFADE1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_ncitem, // deathsound - 60*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height + sfx_None, // deathsound + 0, // speed + FRACUNIT, // radius + FRACUNIT, // height 0, // display offset - pw_automaticring, // mass - 2*TICRATE, // damage + 100, // mass + 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOTHINK|MF_SCENERY|MF_NOBLOCKMAP, // flags S_NULL // raisestate }, - { // MT_EXPLODEPICKUP - 333, // doomednum - S_EXPLODEPICKUP,// spawnstate - 1, // spawnhealth + { // MT_HHZSTALAGMITE_SHORT + 2005, // doomednum + S_HHZSTALAGMITE_SHORT, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 5, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 8, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_EXPLODEPICKUPFADE1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_ncitem, // deathsound - 60*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height + sfx_None, // deathsound + 0, // speed + FRACUNIT, // radius + FRACUNIT, // height 0, // display offset - pw_explosionring, // mass - 2*TICRATE, // damage + 100, // mass + 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOTHINK|MF_SCENERY|MF_NOBLOCKMAP, // flags S_NULL // raisestate }, - { // MT_SCATTERPICKUP - 334, // doomednum - S_SCATTERPICKUP,// spawnstate - 1, // spawnhealth + // No, I did not do all of this by hand. + // I made a script to make all of these for me. + // Ha HA. ~Inuyasha + { // MT_BSZTALLFLOWER_RED + 1400, // doomednum + S_BSZTALLFLOWER_RED, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 5, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 8, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SCATTERPICKUPFADE1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_ncitem, // deathsound - 60*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset - pw_scatterring, // mass - 2*TICRATE, // damage + 100, // mass + 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_GRENADEPICKUP - 335, // doomednum - S_GRENADEPICKUP,// spawnstate - 1, // spawnhealth + { // MT_BSZTALLFLOWER_PURPLE + 1401, // doomednum + S_BSZTALLFLOWER_PURPLE, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 10, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 8, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_GRENADEPICKUPFADE1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_ncitem, // deathsound - 60*FRACUNIT, // speed - 24*FRACUNIT, // radius - 24*FRACUNIT, // height + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset - pw_grenadering, // mass - 2*TICRATE, // damage + 100, // mass + 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_THROWNBOUNCE - -1, // doomednum - S_THROWNBOUNCE1,// spawnstate + { // MT_BSZTALLFLOWER_BLUE + 1402, // doomednum + S_BSZTALLFLOWER_BLUE, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_bnce1, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -11290,53 +13490,53 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_itemup, // deathsound - 60*FRACUNIT, // speed + sfx_None, // deathsound + 0, // speed 16*FRACUNIT, // radius - 24*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage - sfx_bnce1, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY|MF_BOUNCE, // flags + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_THROWNINFINITY - -1, // doomednum - S_THROWNINFINITY1, // spawnstate + { // MT_BSZTALLFLOWER_CYAN + 1403, // doomednum + S_BSZTALLFLOWER_CYAN, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_thok, // seesound - 0, // reactiontime + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_itemup, // deathsound - 60*FRACUNIT, // speed + sfx_None, // deathsound + 0, // speed 16*FRACUNIT, // radius - 24*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_THROWNAUTOMATIC - -1, // doomednum - S_THROWNAUTOMATIC1, // spawnstate + { // MT_BSZTALLFLOWER_YELLOW + 1404, // doomednum + S_BSZTALLFLOWER_YELLOW, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_thok, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -11344,26 +13544,26 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_itemup, // deathsound - 60*FRACUNIT, // speed + sfx_None, // deathsound + 0, // speed 16*FRACUNIT, // radius - 24*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_THROWNSCATTER - -1, // doomednum - S_THROWNSCATTER,// spawnstate + { // MT_BSZTALLFLOWER_ORANGE + 1405, // doomednum + S_BSZTALLFLOWER_ORANGE, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_bnce2, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -11371,185 +13571,158 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_itemup, // deathsound - 60*FRACUNIT, // speed + sfx_None, // deathsound + 0, // speed 16*FRACUNIT, // radius - 24*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_THROWNEXPLOSION - -1, // doomednum - S_THROWNEXPLOSION1, // spawnstate + { // MT_BSZFLOWER_RED + 1410, // doomednum + S_BSZFLOWER_RED, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_cannon, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 192*FRACUNIT, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_RINGEXPLODE, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound - 60*FRACUNIT, // speed + sfx_None, // deathsound + 0, // speed 16*FRACUNIT, // radius - 24*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_THROWNGRENADE - -1, // doomednum - S_THROWNGRENADE1, // spawnstate + { // MT_BSZFLOWER_PURPLE + 1411, // doomednum + S_BSZFLOWER_PURPLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_thok, // seesound + sfx_None, // seesound 8, // reactiontime - sfx_gbeep, // attacksound + sfx_None, // attacksound S_NULL, // painstate - 192*FRACUNIT, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_RINGEXPLODE, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound - 30*FRACUNIT, // speed + sfx_None, // deathsound + 0, // speed 16*FRACUNIT, // radius - 24*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset - 6*TICRATE, // mass (<-- Looking for the Grenade Ring's fuse? It's right here!) - 1, // damage - sfx_s3k5d, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_BOUNCE|MF_GRENADEBOUNCE, // flags + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_COIN - 1800, // doomednum - S_COIN1, // spawnstate + { // MT_BSZFLOWER_BLUE + 1412, // doomednum + S_BSZFLOWER_BLUE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - MT_FLINGCOIN, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_COINSPARKLE1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_mario4, // deathsound - 60*FRACUNIT, // speed + sfx_None, // deathsound + 0, // speed 16*FRACUNIT, // radius - 24*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_FLINGCOIN - -1, // doomednum - S_COIN1, // spawnstate + { // MT_BSZFLOWER_CYAN + 1413, // doomednum + S_BSZFLOWER_CYAN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - MT_FLINGCOIN, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - MT_COIN, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_COINSPARKLE1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_mario4, // deathsound - 60*FRACUNIT, // speed - 15*FRACUNIT, // radius - 24*FRACUNIT, // height - 0, // display offset - 100, // mass + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_GOOMBA - 1801, // doomednum - S_GOOMBA1, // spawnstate - 1, // spawnhealth - S_GOOMBA2, // seestate + { // MT_BSZFLOWER_YELLOW + 1414, // doomednum + S_BSZFLOWER_YELLOW, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate sfx_None, // seesound - 32, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 200, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_GOOMBA_DEAD, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_mario5, // deathsound - 6, // speed - 24*FRACUNIT, // radius + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_BLUEGOOMBA - 1802, // doomednum - S_BLUEGOOMBA1, // spawnstate - 1, // spawnhealth - S_BLUEGOOMBA2, // seestate - sfx_None, // seesound - 32, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 170, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_BLUEGOOMBA_DEAD, // deathstate - S_NULL, // xdeathstate - sfx_mario5, // deathsound - 6, // speed - 24*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags - S_NULL // raisestate - }, - - { // MT_FIREFLOWER - 1803, // doomednum - S_FIREFLOWER1, // spawnstate + { // MT_BSZFLOWER_ORANGE + 1415, // doomednum + S_BSZFLOWER_ORANGE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -11562,7 +13735,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate - sfx_mario3, // deathsound + sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 32*FRACUNIT, // height @@ -11570,41 +13743,41 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_FIREBALL - -1, // doomednum - S_FIREBALL1, // spawnstate + { // MT_BSZSHORTFLOWER_RED + 1420, // doomednum + S_BSZSHORTFLOWER_RED, // spawnstate 1000, // spawnhealth - S_FIREBALLEXP1, // seestate + S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound - S_FIREBALLEXP1, // meleestate - S_FIREBALLEXP1, // missilestate - S_FIREBALLEXP1, // deathstate - S_FIREBALLEXP1, // xdeathstate - sfx_mario1, // deathsound - 10*FRACUNIT, // speed - 4*FRACUNIT, // radius - 8*FRACUNIT, // height + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_FIRE|MF_MISSILE, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_SHELL - 1804, // doomednum - S_SHELL, // spawnstate - 1, // spawnhealth + { // MT_BSZSHORTFLOWER_PURPLE + 1421, // doomednum + S_BSZSHORTFLOWER_PURPLE, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime @@ -11617,46 +13790,47 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 20*FRACUNIT, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage - sfx_mario1, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_BOUNCE, // flags + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_PUMA - 1805, // doomednum - S_PUMA1, // spawnstate + { // MT_BSZSHORTFLOWER_BLUE + 1422, // doomednum + S_BSZSHORTFLOWER_BLUE, // spawnstate 1000, // spawnhealth - S_PUMA1, // seestate + S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound - S_PUMA4, // meleestate + S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate - S_PUMA6, // xdeathstate + S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_PAIN|MF_FIRE, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_HAMMER - -1, // doomednum - S_HAMMER1, // spawnstate + + { // MT_BSZSHORTFLOWER_CYAN + 1423, // doomednum + S_BSZSHORTFLOWER_CYAN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -11671,18 +13845,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 4*FRACUNIT, // radius - 8*FRACUNIT, // height + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_PAIN, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_KOOPA - 1806, // doomednum - S_KOOPA1, // spawnstate + + { // MT_BSZSHORTFLOWER_YELLOW + 1424, // doomednum + S_BSZSHORTFLOWER_YELLOW, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -11698,18 +13873,18 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 48*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_PAIN, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_KOOPAFLAME - -1, // doomednum - S_KOOPAFLAME1, // spawnstate + { // MT_BSZSHORTFLOWER_ORANGE + 1425, // doomednum + S_BSZSHORTFLOWER_ORANGE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -11723,20 +13898,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 5*FRACUNIT, // speed - 8*FRACUNIT, // radius - 8*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_MISSILE|MF_FIRE, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_AXE - 1807, // doomednum - S_AXE1, // spawnstate + { // MT_BSZTULIP_RED + 1430, // doomednum + S_BSZTULIP_RED, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -11751,19 +13926,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_MARIOBUSH1 - 1808, // doomednum - S_MARIOBUSH1, // spawnstate + { // MT_BSZTULIP_PURPLE + 1431, // doomednum + S_BSZTULIP_PURPLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -11788,9 +13963,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_MARIOBUSH2 - 1809, // doomednum - S_MARIOBUSH2, // spawnstate + { // MT_BSZTULIP_BLUE + 1432, // doomednum + S_BSZTULIP_BLUE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -11815,9 +13990,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_TOAD - 1810, // doomednum - S_TOAD, // spawnstate + { // MT_BSZTULIP_CYAN + 1433, // doomednum + S_BSZTULIP_CYAN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -11832,7 +14007,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8*FRACUNIT, // radius + 16*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset 100, // mass @@ -11842,9 +14017,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_AXIS - 1700, // doomednum - S_INVISIBLE, // spawnstate + { // MT_BSZTULIP_YELLOW + 1434, // doomednum + S_BSZTULIP_YELLOW, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -11858,20 +14033,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 10*FRACUNIT, // speed - 256*FRACUNIT, // radius - 1*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_AXISTRANSFER - 1701, // doomednum - S_INVISIBLE, // spawnstate + { // MT_BSZTULIP_ORANGE + 1435, // doomednum + S_BSZTULIP_ORANGE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -11885,20 +14060,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 10, // speed + 0, // speed 16*FRACUNIT, // radius - 1, // height + 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_AXISTRANSFERLINE - 1702, // doomednum - S_INVISIBLE, // spawnstate + { // MT_BSZCLUSTER_RED + 1440, // doomednum + S_BSZCLUSTER_RED, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -11912,27 +14087,27 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 10, // speed - 32*FRACUNIT, // radius - 1, // height + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_NIGHTSDRONE - 1703, // doomednum - S_NIGHTSDRONE1, // spawnstate - 120, // spawnhealth + { // MT_BSZCLUSTER_PURPLE + 1441, // doomednum + S_BSZCLUSTER_PURPLE, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -11941,25 +14116,25 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 56*FRACUNIT, // height - 1, // display offset - 1000, // mass + 32*FRACUNIT, // height + 0, // display offset + 100, // mass 0, // damage - sfx_ideya, // activesound - MF_SPECIAL, // flags + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_NIGHTSGOAL - -1, // doomednum - S_NIGHTSGOAL1, // spawnstate + { // MT_BSZCLUSTER_BLUE + 1442, // doomednum + S_BSZCLUSTER_BLUE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -11968,47 +14143,47 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 56*FRACUNIT, // height - -1, // display offset - 1000, // mass + 32*FRACUNIT, // height + 0, // display offset + 100, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_NIGHTSCHAR - -1, // doomednum - S_NIGHTSFLY1A, // spawnstate + { // MT_BSZCLUSTER_CYAN + 1443, // doomednum + S_BSZCLUSTER_CYAN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound - S_NIGHTSFLY1A, // painstate - 255, // painchance + S_NULL, // painstate + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NIGHTSFLY1A, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 48*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset - 1000, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOCLIP|MF_NOGRAVITY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_NIGHTSPARKLE - -1, // doomednum - S_NIGHTSPARKLE1,// spawnstate + { // MT_BSZCLUSTER_YELLOW + 1444, // doomednum + S_BSZCLUSTER_YELLOW, // spawnstate 1000, // spawnhealth - S_NIGHTSPARKLESUPER1, // seestate + S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound @@ -12021,19 +14196,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 2*FRACUNIT, // radius - 4*FRACUNIT, // height + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_NIGHTSLOOPHELPER - -1, // doomednum - S_NIGHTSLOOPHELPER,// spawnstate + { // MT_BSZCLUSTER_ORANGE + 1445, // doomednum + S_BSZCLUSTER_ORANGE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -12048,22 +14223,22 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 4*FRACUNIT, // radius - 4*FRACUNIT, // height + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_NIGHTSBUMPER - 1704, // doomednum - S_NIGHTSBUMPER1,// spawnstate - 1, // spawnhealth + { // MT_BSZBUSH_RED + 1450, // doomednum + S_BSZBUSH_RED, // spawnstate + 1000, // spawnhealth S_NULL, // seestate - sfx_nbmper, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -12074,22 +14249,22 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 21000, // speed - 32*FRACUNIT, // radius - 64*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_SCENERY|MF_SPECIAL|MF_NOGRAVITY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_HOOP - -1, // doomednum - S_HOOP, // spawnstate + { // MT_BSZBUSH_PURPLE + 1451, // doomednum + S_BSZBUSH_PURPLE, // spawnstate 1000, // spawnhealth - S_HOOP_XMASA, // seestate + S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound @@ -12101,20 +14276,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 1, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset - 4, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_HOOPCOLLIDE - -1, // doomednum - S_INVISIBLE, // spawnstate + { // MT_BSZBUSH_BLUE + 1452, // doomednum + S_BSZBUSH_BLUE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -12128,20 +14303,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 1, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset - 4, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_SPECIAL|MF_NOTHINK, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_HOOPCENTER - -1, // doomednum - S_INVISIBLE, // spawnstate + { // MT_BSZBUSH_CYAN + 1453, // doomednum + S_BSZBUSH_CYAN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -12155,20 +14330,20 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 1, // speed - 2*FRACUNIT, // radius - 4*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset - 4, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_NIGHTSCORE - -1, // doomednum - S_NIGHTSCORE10, // spawnstate + { // MT_BSZBUSH_YELLOW + 1454, // doomednum + S_BSZBUSH_YELLOW, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -12180,188 +14355,188 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate - S_NIGHTSCORE10_2, // xdeathstate + S_NULL, // xdeathstate sfx_None, // deathsound - 1, // speed - 8*FRACUNIT, // radius - 8*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset - 4, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_NIGHTSWING - 1706, // doomednum - S_NIGHTSWING, // spawnstate + { // MT_BSZBUSH_ORANGE + 1455, // doomednum + S_BSZBUSH_ORANGE, // spawnstate 1000, // spawnhealth - S_NIGHTSWING_XMAS, // seestate + S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance - sfx_itemup, // painsound - S_RING, // meleestate + sfx_None, // painsound + S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 1, // speed - 12*FRACUNIT, // radius - 24*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset - 4, // mass + 100, // mass 0, // damage - sfx_ncitem, // activesound - MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_NIGHTSSUPERLOOP - 1707, // doomednum - S_NIGHTSPOWERUP1, // spawnstate + { // MT_BSZVINE_RED + 1460, // doomednum + S_BSZVINE_RED, // spawnstate 1000, // spawnhealth - S_NIGHTSPOWERUP2, // seestate + S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_ncspec, // deathsound - 20*TICRATE, // speed + sfx_None, // deathsound + 0, // speed 16*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset - 1000, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_NIGHTSITEM, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_NIGHTSDRILLREFILL - 1708, // doomednum - S_NIGHTSPOWERUP3, // spawnstate + { // MT_BSZVINE_PURPLE + 1461, // doomednum + S_BSZVINE_PURPLE, // spawnstate 1000, // spawnhealth - S_NIGHTSPOWERUP4, // seestate + S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_ncspec, // deathsound - 96*20, // speed + sfx_None, // deathsound + 0, // speed 16*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset - 1000, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_NIGHTSITEM, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_NIGHTSHELPER - 1709, // doomednum - S_NIGHTSPOWERUP5, // spawnstate + { // MT_BSZVINE_BLUE + 1462, // doomednum + S_BSZVINE_BLUE, // spawnstate 1000, // spawnhealth - S_NIGHTSPOWERUP6, // seestate + S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_ncspec, // deathsound - 20*TICRATE, // speed + sfx_None, // deathsound + 0, // speed 16*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset - 1000, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_NIGHTSITEM, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_NIGHTSEXTRATIME - 1711, // doomednum - S_NIGHTSPOWERUP7, // spawnstate + { // MT_BSZVINE_CYAN + 1463, // doomednum + S_BSZVINE_CYAN, // spawnstate 1000, // spawnhealth - S_NIGHTSPOWERUP8, // seestate + S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_ncspec, // deathsound - 30*TICRATE, // speed + sfx_None, // deathsound + 0, // speed 16*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset - 1000, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_NIGHTSITEM, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_NIGHTSLINKFREEZE - 1712, // doomednum - S_NIGHTSPOWERUP9, // spawnstate + { // MT_BSZVINE_YELLOW + 1464, // doomednum + S_BSZVINE_YELLOW, // spawnstate 1000, // spawnhealth - S_NIGHTSPOWERUP10, // seestate + S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_SPRK1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_ncspec, // deathsound - 15*TICRATE, // speed + sfx_None, // deathsound + 0, // speed 16*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset - 1000, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_NIGHTSITEM, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_EGGCAPSULE - 1710, // doomednum - S_EGGCAPSULE, // spawnstate - 20, // spawnhealth + { // MT_BSZVINE_ORANGE + 1465, // doomednum + S_BSZVINE_ORANGE, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -12372,27 +14547,26 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 72*FRACUNIT, // radius - 144*FRACUNIT, // height + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset 100, // mass - 1, // damage + 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - // the flicky that orbits the player when they have a Nightopian helper - { // MT_NIGHTOPIANHELPER - -1, // doomednum - S_NIGHTOPIANHELPER1, // spawnstate + { // MT_BSZSHRUB + 1470, // doomednum + S_BSZSHRUB, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -12401,18 +14575,18 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 16*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset - 16, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_TELEPORTMAN - 751, // doomednum - S_INVISIBLE, // spawnstate + { // MT_BSZCLOVER + 1471, // doomednum + S_BSZCLOVER, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -12427,19 +14601,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8, // radius - 8, // height + 16*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset - 10, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_ALTVIEWMAN - 752, // doomednum - S_INVISIBLE, // spawnstate + { // MT_BIG_PALMTREE_TRUNK + -1, // doomednum + S_BIG_PALMTREE_TRUNK, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -12454,51 +14628,50 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8, // radius - 8, // height + 16*FRACUNIT, // radius + 160*FRACUNIT, // height 0, // display offset - 10, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_CRUMBLEOBJ - -1, // doomednum - S_CRUMBLE1, // spawnstate + { // MT_BIG_PALMTREE_TOP + 1473, // doomednum + S_BIG_PALMTREE_TOP, // spawnstate 1000, // spawnhealth - S_CRUMBLE1, // seestate - 0, // seesound - 1, // reactiontime - 0, // attacksound + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound S_NULL, // painstate - 200, // painchance - 0, // painsound - 0, // meleestate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate - sfx_crumbl, // deathsound - 3, // speed - 1*FRACUNIT, // radius - 1*FRACUNIT, // height + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 160*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage - 0, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + sfx_None, // activesound + MF_RUNSPAWNFUNC|MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - // Waypoint for zoom tubes - { // MT_TUBEWAYPOINT - 753, // doomednum - S_INVISIBLE, // spawnstate + { // MT_PALMTREE_TRUNK + -1, // doomednum + S_PALMTREE_TRUNK, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -12509,20 +14682,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 1*FRACUNIT, // radius - 2*FRACUNIT, // height + 16*FRACUNIT, // radius + 80*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - // for use with wind and current effects - { // MT_PUSH - 754, // doomednum - S_INVISIBLE, // spawnstate + { // MT_PALMTREE_TOP + 1475, // doomednum + S_PALMTREE_TOP, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -12537,20 +14709,19 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8, // radius - 8, // height + 16*FRACUNIT, // radius + 80*FRACUNIT, // height 0, // display offset - 10, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + MF_RUNSPAWNFUNC|MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, - // for use with wind and current effects - { // MT_PULL - 755, // doomednum - S_INVISIBLE, // spawnstate + { // MT_DBALL + 1875, // doomednum + S_DBALL1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -12564,24 +14735,24 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 8, // radius - 8, // height + 8, // speed + 16*FRACUNIT, // radius + 54*FRACUNIT, // height 0, // display offset - 10, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SPAWNCEILING|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_GHOST - -1, // doomednum - S_THOK, // spawnstate - 1, // spawnhealth + { // MT_EGGSTATUE2 + 1876, // doomednum + S_EGGSTATUE2, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -12592,269 +14763,269 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 48*FRACUNIT, // height + 20*FRACUNIT, // radius + 96*FRACUNIT, // height 0, // display offset - 1000, // mass - 8, // damage + 100, // mass + 1, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY, // flags + MF_SOLID|MF_PUSHABLE|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_OVERLAY + { // MT_ELEMENTAL_ORB -1, // doomednum - S_NULL, // spawnstate - 1, // spawnhealth - S_NULL, // seestate + S_ELEM1, // spawnstate + 1000, // spawnhealth + S_ELEMF1, // seestate sfx_None, // seesound 0, // reactiontime sfx_None, // attacksound - S_NULL, // painstate - 3, // painchance + S_ELEM13, // painstate + SKINCOLOR_NONE, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 1*FRACUNIT, // radius - 1*FRACUNIT, // height - 0, // display offset - 1000, // mass - 8, // damage + SH_ELEMENTAL, // speed + 64*FRACUNIT, // radius + 64*FRACUNIT, // height + 4, // display offset + 16, // mass + 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY, // flags - S_NULL // raisestate + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + S_ELEMF9 // raisestate }, - { // MT_POLYANCHOR - 760, // doomednum - S_INVISIBLE, // spawnstate - 1, // spawnhealth + { // MT_ATTRACT_ORB + -1, // doomednum + S_MAGN1, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound - S_NULL, // painstate - 3, // painchance + S_MAGN13, // painstate + SKINCOLOR_NONE, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 1*FRACUNIT, // radius - 1*FRACUNIT, // height - 0, // display offset - 1000, // mass - 8, // damage + SH_ATTRACT, // speed + 64*FRACUNIT, // radius + 64*FRACUNIT, // height + 4, // display offset + 16, // mass + 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_NOCLIP, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_POLYSPAWN - 761, // doomednum - S_INVISIBLE, // spawnstate - 1, // spawnhealth + { // MT_FORCE_ORB + -1, // doomednum + S_FORC1, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound - S_NULL, // painstate - 3, // painchance + S_FORC11, // painstate + SKINCOLOR_NONE, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 1*FRACUNIT, // radius - 1*FRACUNIT, // height - 0, // display offset - 1000, // mass - 8, // damage + SH_FORCE, // speed + 64*FRACUNIT, // radius + 64*FRACUNIT, // height + 4, // display offset + 16, // mass + 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_NOCLIP, // flags - S_NULL // raisestate + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + S_FORC21 // raisestate }, - { // MT_POLYSPAWNCRUSH - 762, // doomednum - S_INVISIBLE, // spawnstate - 1, // spawnhealth - S_NULL, // seestate + { // MT_ARMAGEDDON_ORB + -1, // doomednum + S_ARMA1, // spawnstate + 1000, // spawnhealth + S_ARMF1, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 3, // painchance + SKINCOLOR_NONE, // painchance sfx_None, // painsound - S_NULL, // meleestate + S_ARMB1, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 1*FRACUNIT, // radius - 1*FRACUNIT, // height - 0, // display offset - 1000, // mass - 8, // damage + SH_ARMAGEDDON, // speed + 64*FRACUNIT, // radius + 64*FRACUNIT, // height + 4, // display offset + 16, // mass + 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_NOCLIP, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_SKYBOX - 780, // doomednum - S_INVISIBLE, // spawnstate + { // MT_WHIRLWIND_ORB + -1, // doomednum + S_WIND1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + SKINCOLOR_NONE, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 12*FRACUNIT, // radius - 24*FRACUNIT, // height - 0, // display offset - 10, // mass + SH_WHIRLWIND, // speed + 64*FRACUNIT, // radius + 64*FRACUNIT, // height + 4, // display offset + 16, // mass 0, // damage sfx_None, // activesound - MF_SCENERY|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_SPARK + { // MT_PITY_ORB -1, // doomednum - S_SPRK1, // spawnstate + S_PITY1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + SKINCOLOR_NONE, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 8, // speed - 32*FRACUNIT, // radius - 32*FRACUNIT, // height - 2, // display offset + SH_PITY, // speed + 64*FRACUNIT, // radius + 64*FRACUNIT, // height + 4, // display offset 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_EXPLODE + { // MT_FLAMEAURA_ORB -1, // doomednum - S_XPLD1, // spawnstate - 1, // spawnhealth - S_NULL, // seestate + S_FIRSB1, // spawnstate + 1000, // spawnhealth + S_FIRS1, // seestate sfx_None, // seesound - 32, // reactiontime + 8, // reactiontime sfx_None, // attacksound - S_NULL, // painstate - 200, // painchance + S_FIRSB10, // painstate + SKINCOLOR_NONE, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 1*FRACUNIT, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 100, // mass + SH_FLAMEAURA, // speed + 64*FRACUNIT, // radius + 64*FRACUNIT, // height + -4, // display offset + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags - S_NULL // raisestate + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + S_FIRS10 // raisestate }, - { // MT_UWEXPLODE + { // MT_BUBBLEWRAP_ORB -1, // doomednum - S_WPLD1, // spawnstate - 1, // spawnhealth - S_NULL, // seestate + S_BUBSB1, // spawnstate + 1000, // spawnhealth + S_BUBS1, // seestate sfx_None, // seesound - 32, // reactiontime + 8, // reactiontime sfx_None, // attacksound - S_NULL, // painstate - 200, // painchance + S_BUBSB5, // painstate + SKINCOLOR_NONE, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 1*FRACUNIT, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass + SH_BUBBLEWRAP, // speed + 64*FRACUNIT, // radius + 64*FRACUNIT, // height + 4, // display offset + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags - S_NULL // raisestate + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + S_BUBS10 // raisestate }, - { // MT_ROCKSPAWNER - 1202, // doomednum - S_ROCKSPAWN, // spawnstate + { // MT_THUNDERCOIN_ORB + -1, // doomednum + S_ZAPSB1, // spawnstate 1000, // spawnhealth - S_NULL, // seestate + S_ZAPS1, // seestate sfx_None, // seesound - 0, // reactiontime + 8, // reactiontime sfx_None, // attacksound - S_NULL, // painstate - 255, // painchance + S_ZAPSB11, // painstate + SKINCOLOR_NONE, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 1000, // mass + SH_THUNDERCOIN, // speed + 64*FRACUNIT, // radius + 64*FRACUNIT, // height + -4, // display offset + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY, // flags - S_NULL // raisestate + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + S_ZAPS14 // raisestate }, - { // MT_FALLINGROCK + { // MT_THUNDERCOIN_SPARK -1, // doomednum - S_ROCKCRUMBLEA, // spawnstate - 1000, // spawnhealth + S_THUNDERCOIN_SPARK, // spawnstate + 1, // spawnhealth S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -12862,53 +15033,53 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 4*FRACUNIT, // radius + 4*FRACUNIT, // height 0, // display offset - 4, // mass + 100, // mass 0, // damage - sfx_rocks1, // activesound - MF_PAIN|MF_BOUNCE, // flags + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_ROCKCRUMBLE1 + { // MT_IVSP -1, // doomednum - S_ROCKCRUMBLEA, // spawnstate + S_IVSP, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 1000, // mass + 8, // speed + 64*FRACUNIT, // radius + 64*FRACUNIT, // height + 3, // display offset + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags S_NULL // raisestate }, - { // MT_ROCKCRUMBLE2 + { // MT_SUPERSPARK -1, // doomednum - S_ROCKCRUMBLEB, // spawnstate - 1000, // spawnhealth + S_SSPK1, // spawnstate + 1, // spawnhealth S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -12917,747 +15088,748 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 8*FRACUNIT, // height 0, // display offset - 1000, // mass + 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, - { // MT_ROCKCRUMBLE3 + // Bluebird + { // MT_FLICKY_01 -1, // doomednum - S_ROCKCRUMBLEC, //spawnstate + S_FLICKY_01_OUT, // spawnstate 1000, // spawnhealth - S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + S_FLICKY_01_STAND, // seestate + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 8, // speed 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 20*FRACUNIT, // height 0, // display offset - 1000, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate + MF_NOCLIPTHING, // flags + S_FLICKY_BUBBLE // raisestate }, - { // MT_ROCKCRUMBLE4 - -1, // doomednum - S_ROCKCRUMBLED, // spawnstate + { // MT_FLICKY_01_CENTER + 2200, // doomednum + S_FLICKY_01_CENTER, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 8, // speed 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 20*FRACUNIT, // height 0, // display offset - 1000, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate }, - { // MT_ROCKCRUMBLE5 + { // MT_FLICKY_02 -1, // doomednum - S_ROCKCRUMBLEE, // spawnstate + S_FLICKY_02_OUT, // spawnstate 1000, // spawnhealth - S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + S_FLICKY_02_STAND, // seestate + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 8, // speed 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 20*FRACUNIT, // height 0, // display offset - 1000, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate + MF_NOCLIPTHING, // flags + S_FLICKY_BUBBLE // raisestate }, - { // MT_ROCKCRUMBLE6 - -1, // doomednum - S_ROCKCRUMBLEF, // spawnstate + { // MT_FLICKY_02_CENTER + 2201, // doomednum + S_FLICKY_02_CENTER, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 8, // speed 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 20*FRACUNIT, // height 0, // display offset - 1000, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate }, - { // MT_ROCKCRUMBLE7 + { // MT_FLICKY_03 -1, // doomednum - S_ROCKCRUMBLEG, // spawnstate + S_FLICKY_03_OUT, // spawnstate 1000, // spawnhealth - S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + S_FLICKY_03_STAND, // seestate + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 8, // speed 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 20*FRACUNIT, // height 0, // display offset - 1000, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate + MF_NOCLIPTHING, // flags + S_FLICKY_BUBBLE // raisestate }, - { // MT_ROCKCRUMBLE8 - -1, // doomednum - S_ROCKCRUMBLEH, // spawnstate + { // MT_FLICKY_03_CENTER + 2202, // doomednum + S_FLICKY_03_CENTER, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 8, // speed 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 20*FRACUNIT, // height 0, // display offset - 1000, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate }, - { // MT_ROCKCRUMBLE9 + { // MT_FLICKY_04 -1, // doomednum - S_ROCKCRUMBLEI, // spawnstate + S_FLICKY_04_OUT, // spawnstate 1000, // spawnhealth - S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + S_FLICKY_04_STAND, // seestate + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound - S_NULL, // meleestate + S_FLICKY_04_SWIM1, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 8, // speed 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 20*FRACUNIT, // height 0, // display offset - 1000, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + MF_NOCLIPTHING, // flags S_NULL // raisestate }, - { // MT_ROCKCRUMBLE10 - -1, // doomednum - S_ROCKCRUMBLEJ, // spawnstate + { // MT_FLICKY_04_CENTER + 2203, // doomednum + S_FLICKY_04_CENTER, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 8, // speed 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 20*FRACUNIT, // height 0, // display offset - 1000, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate }, - { // MT_ROCKCRUMBLE11 + { // MT_FLICKY_05 -1, // doomednum - S_ROCKCRUMBLEK, // spawnstate + S_FLICKY_05_OUT, // spawnstate 1000, // spawnhealth - S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + S_FLICKY_05_STAND, // seestate + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 8, // speed 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 20*FRACUNIT, // height 0, // display offset - 1000, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate + MF_NOCLIPTHING, // flags + S_FLICKY_BUBBLE // raisestate }, - { // MT_ROCKCRUMBLE12 - -1, // doomednum - S_ROCKCRUMBLEL, // spawnstate + { // MT_FLICKY_05_CENTER + 2204, // doomednum + S_FLICKY_05_CENTER, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 8, // speed 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 20*FRACUNIT, // height 0, // display offset - 1000, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate }, - { // MT_ROCKCRUMBLE13 + { // MT_FLICKY_06 -1, // doomednum - S_ROCKCRUMBLEM, // spawnstate + S_FLICKY_06_OUT, // spawnstate 1000, // spawnhealth - S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + S_FLICKY_06_STAND, // seestate + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 8, // speed 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 20*FRACUNIT, // height 0, // display offset - 1000, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate + MF_NOCLIPTHING, // flags + S_FLICKY_BUBBLE // raisestate }, - { // MT_ROCKCRUMBLE14 - -1, // doomednum - S_ROCKCRUMBLEN, // spawnstate + { // MT_FLICKY_06_CENTER + 2205, // doomednum + S_FLICKY_06_CENTER, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 8, // speed 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 20*FRACUNIT, // height 0, // display offset - 1000, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate }, - { // MT_ROCKCRUMBLE15 + { // MT_FLICKY_07 -1, // doomednum - S_ROCKCRUMBLEO, // spawnstate + S_FLICKY_07_OUT, // spawnstate 1000, // spawnhealth - S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + S_FLICKY_07_STAND, // seestate + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound - S_NULL, // meleestate + S_FLICKY_07_SWIM1, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 8, // speed 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 20*FRACUNIT, // height 0, // display offset - 1000, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + MF_NOCLIPTHING, // flags S_NULL // raisestate }, - { // MT_ROCKCRUMBLE16 - -1, // doomednum - S_ROCKCRUMBLEP, // spawnstate + { // MT_FLICKY_07_CENTER + 2206, // doomednum + S_FLICKY_07_CENTER, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime + sfx_None, // seesound + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 255, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 0, // speed + 8, // speed 8*FRACUNIT, // radius - 16*FRACUNIT, // height + 20*FRACUNIT, // height 0, // display offset - 1000, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate }, - { // MT_SRB1_CRAWLA - 4000, // doomednum - S_SRB1_CRAWLA1, // spawnstate - 1, // spawnhealth - S_SRB1_CRAWLA2, // seestate + { // MT_FLICKY_08 + -1, // doomednum + S_FLICKY_08_OUT, // spawnstate + 1000, // spawnhealth + S_FLICKY_08_STAND, // seestate sfx_None, // seesound - 32, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 200, // painchance + 0, // painchance sfx_None, // painsound - S_NULL, // meleestate + S_FLICKY_08_SWIM1, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound - 3, // speed - 20*FRACUNIT, // radius - 40*FRACUNIT, // height + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY, // flags + MF_NOCLIPTHING, // flags S_NULL // raisestate }, - { // MT_SRB1_BAT - 4001, // doomednum - S_SRB1_BAT1, // spawnstate - 1, // spawnhealth - S_SRB1_BAT3, // seestate + { // MT_FLICKY_08_CENTER + 2207, // doomednum + S_FLICKY_08_CENTER, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate sfx_None, // seesound - 2, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 3072, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound - 4*FRACUNIT, // speed - 17*FRACUNIT, // radius - 40*FRACUNIT, // height + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_SLIDEME, // flags - S_NULL // raisestate + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate }, - { // MT_SRB1_ROBOFISH - 4002, // doomednum - S_SRB1_ROBOFISH1, // spawnstate - 1, // spawnhealth - S_SRB1_ROBOFISH2, // seestate + { // MT_FLICKY_09 + -1, // doomednum + S_FLICKY_09_OUT, // spawnstate + 1000, // spawnhealth + S_FLICKY_09_STAND, // seestate sfx_None, // seesound - 2, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 3072, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound - 4*FRACUNIT, // speed - 22*FRACUNIT, // radius - 32*FRACUNIT, // height + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_SLIDEME, // flags - S_NULL // raisestate + MF_NOCLIPTHING, // flags + S_FLICKY_BUBBLE // raisestate }, - { // MT_SRB1_VOLCANOGUY - 4003, // doomednum - S_SRB1_VOLCANOGUY1, // spawnstate - 1, // spawnhealth - S_SRB1_VOLCANOGUY2, // seestate + { // MT_FLICKY_09_CENTER + 2208, // doomednum + S_FLICKY_09_CENTER, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate sfx_None, // seesound - 2, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 3072, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound - 4*FRACUNIT, // speed - 20*FRACUNIT, // radius - 40*FRACUNIT, // height + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_SLIDEME, // flags - S_NULL // raisestate + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate }, - { // MT_SRB1_HOPPY - 4004, // doomednum - S_SRB1_HOPPY1, // spawnstate - 1, // spawnhealth - S_SRB1_HOPPY1, // seestate + { // MT_FLICKY_10 + -1, // doomednum + S_FLICKY_10_OUT, // spawnstate + 1000, // spawnhealth + S_FLICKY_10_STAND, // seestate sfx_None, // seesound - 2, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 3072, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound - FRACUNIT, // speed - 20*FRACUNIT, // radius - 32*FRACUNIT, // height + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY, // flags - S_NULL // raisestate + MF_NOCLIPTHING, // flags + S_FLICKY_BUBBLE // raisestate }, - { // MT_SRB1_HOPPYWATER - 4005, // doomednum - S_SRB1_HOPPYWATER1, // spawnstate - 1, // spawnhealth - S_SRB1_HOPPYWATER1, // seestate + { // MT_FLICKY_10_CENTER + 2209, // doomednum + S_FLICKY_10_CENTER, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate sfx_None, // seesound - 2, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 3072, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound - FRACUNIT, // speed - 20*FRACUNIT, // radius - 32*FRACUNIT, // height + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY, // flags - S_NULL // raisestate + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate }, - { // MT_SRB1_HOPPYSKYLAB - 4006, // doomednum - S_SRB1_HOPPYSKYLAB1, // spawnstate - 1, // spawnhealth - S_SRB1_HOPPYSKYLAB1, // seestate + { // MT_FLICKY_11 + -1, // doomednum + S_FLICKY_11_OUT, // spawnstate + 1000, // spawnhealth + S_FLICKY_11_STAND, // seestate sfx_None, // seesound - 2, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 3072, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound - FRACUNIT, // speed - 10*FRACUNIT, // radius - 34*FRACUNIT, // height + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY, // flags - S_NULL // raisestate + MF_NOCLIPTHING, // flags + S_FLICKY_BUBBLE // raisestate }, - { // MT_SRB1_MMZFLYING - 4007, // doomednum - S_SRB1_MMZFLYING1, // spawnstate - 1, // spawnhealth - S_SRB1_MMZFLYING1, // seestate + { // MT_FLICKY_11_CENTER + 2210, // doomednum + S_FLICKY_11_CENTER, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate sfx_None, // seesound - 32, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 200, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound - FRACUNIT, // speed - 24*FRACUNIT, // radius - 32*FRACUNIT, // height + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_FLOAT, // flags - S_NULL // raisestate + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate }, - { // MT_SRB1_UFO - 4008, // doomednum - S_SRB1_UFO1, // spawnstate - 1, // spawnhealth - S_SRB1_UFO1, // seestate + { // MT_FLICKY_12 + -1, // doomednum + S_FLICKY_12_OUT, // spawnstate + 1000, // spawnhealth + S_FLICKY_12_STAND, // seestate sfx_None, // seesound - 32, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 200, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound - 3, // speed - 24*FRACUNIT, // radius - 32*FRACUNIT, // height + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_FLOAT|MF_SPAWNCEILING, // flags - S_NULL // raisestate + MF_NOCLIPTHING, // flags + S_FLICKY_BUBBLE // raisestate }, - { // MT_SRB1_GRAYBOT - 4009, // doomednum - S_SRB1_GRAYBOT1,// spawnstate - 1, // spawnhealth - S_SRB1_GRAYBOT1,// seestate + { // MT_FLICKY_12_CENTER + 2211, // doomednum + S_FLICKY_12_CENTER, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate sfx_None, // seesound - 32, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 200, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound - 3, // speed - 21*FRACUNIT, // radius - 69*FRACUNIT, // height + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_FLOAT, // flags - S_NULL // raisestate + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate }, - { // MT_SRB1_ROBOTOPOLIS - 4010, // doomednum - S_SRB1_ROBOTOPOLIS1, // spawnstate - 1, // spawnhealth - S_SRB1_ROBOTOPOLIS1, // seestate + { // MT_FLICKY_13 + -1, // doomednum + S_FLICKY_13_OUT, // spawnstate + 1000, // spawnhealth + S_FLICKY_13_STAND, // seestate sfx_None, // seesound - 32, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 200, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound - 3, // speed - 36*FRACUNIT, // radius - 62*FRACUNIT, // height + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_FLOAT, // flags - S_NULL // raisestate + MF_NOCLIPTHING, // flags + S_FLICKY_BUBBLE // raisestate }, - { // MT_SRB1_RBZBUZZ - 4011, // doomednum - S_SRB1_RBZBUZZ1,// spawnstate - 1, // spawnhealth - S_SRB1_RBZBUZZ1,// seestate + { // MT_FLICKY_13_CENTER + 2212, // doomednum + S_FLICKY_13_CENTER, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate sfx_None, // seesound - 32, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 200, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound - 3, // speed - 44*FRACUNIT, // radius - 45*FRACUNIT, // height + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_FLOAT, // flags - S_NULL // raisestate + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate }, - { // MT_SRB1_RBZSPIKES - 4012, // doomednum - S_SRB1_RBZSPIKES1, // spawnstate - 1, // spawnhealth - S_SRB1_RBZSPIKES1, // seestate + { // MT_FLICKY_14 + -1, // doomednum + S_FLICKY_14_OUT, // spawnstate + 1000, // spawnhealth + S_FLICKY_14_STAND, // seestate sfx_None, // seesound - 32, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 200, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound - 3, // speed - 10*FRACUNIT, // radius - 53*FRACUNIT, // height + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SOLID|MF_ENEMY|MF_NOGRAVITY|MF_FLOAT, // flags - S_NULL // raisestate + MF_NOCLIPTHING, // flags + S_FLICKY_BUBBLE // raisestate }, - { // MT_SRB1_METALSONIC - 4013, // doomednum - S_SRB1_METALSONIC1, // spawnstate + { // MT_FLICKY_14_CENTER + 2213, // doomednum + S_FLICKY_14_CENTER, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -13671,75 +15843,101 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 21*FRACUNIT, // speed - 16*FRACUNIT, // radius - 40*FRACUNIT, // height + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags - S_NULL // raisestate + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate }, - { // MT_SRB1_GOLDBOT - 4014, // doomednum - S_SRB1_GOLDBOT1,// spawnstate - 1, // spawnhealth - S_SRB1_GOLDBOT1,// seestate + { // MT_FLICKY_15 + -1, // doomednum + S_FLICKY_15_OUT, // spawnstate + 1000, // spawnhealth + S_FLICKY_15_STAND, // seestate sfx_None, // seesound - 32, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 200, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound - 3, // speed - 21*FRACUNIT, // radius - 69*FRACUNIT, // height + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_FLOAT, // flags - S_NULL // raisestate + MF_NOCLIPTHING, // flags + S_FLICKY_BUBBLE // raisestate }, - { // MT_SRB1_GENREX - 4015, // doomednum - S_SRB1_GENREX1, // spawnstate - 1, // spawnhealth - S_SRB1_GENREX2, // seestate + { // MT_FLICKY_15_CENTER + 2214, // doomednum + S_FLICKY_15_CENTER, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate sfx_None, // seesound - 2, // reactiontime + 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 3072, // painchance + 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD1, // deathstate + S_NULL, // deathstate S_NULL, // xdeathstate - sfx_pop, // deathsound - 4*FRACUNIT, // speed - 17*FRACUNIT, // radius - 40*FRACUNIT, // height + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_SLIDEME, // flags - S_NULL // raisestate + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate }, -#ifdef SEENAMES - { // MT_NAMECHECK + { // MT_FLICKY_16 -1, // doomednum - S_NAMECHECK, // spawnstate + S_FLICKY_16_OUT, // spawnstate + 1000, // spawnhealth + S_FLICKY_16_STAND, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIPTHING, // flags + S_FLICKY_BUBBLE // raisestate + }, + + { // MT_FLICKY_16_CENTER + 2215, // doomednum + S_FLICKY_16_CENTER, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -13753,11 +15951,4047 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 60*FRACUNIT, // speed - 30*FRACUNIT, // radius - 40*FRACUNIT, // height + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height 0, // display offset - 100, // mass + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate + }, + + { // MT_SECRETFLICKY_01 + -1, // doomednum + S_SECRETFLICKY_01_OUT, // spawnstate + 1000, // spawnhealth + S_SECRETFLICKY_01_STAND, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIPTHING, // flags + S_FLICKY_BUBBLE // raisestate + }, + + { // MT_SECRETFLICKY_01_CENTER + 2216, // doomednum + S_SECRETFLICKY_01_CENTER, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate + }, + + { // MT_SECRETFLICKY_02 + -1, // doomednum + S_SECRETFLICKY_02_OUT, // spawnstate + 1000, // spawnhealth + S_SECRETFLICKY_02_STAND, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIPTHING, // flags + S_FLICKY_BUBBLE // raisestate + }, + + { // MT_SECRETFLICKY_02_CENTER + 2217, // doomednum + S_SECRETFLICKY_02_CENTER, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 20*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate + }, + + { // MT_SEED + -1, // doomednum + S_SEED, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + -2*FRACUNIT, // speed + 4*FRACUNIT, // radius + 4*FRACUNIT, // height + 0, // display offset + 4, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_RAIN + -1, // doomednum + S_RAIN1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + -24*FRACUNIT, // speed + 1*FRACUNIT, // radius + 8*FRACUNIT, // height + 0, // display offset + 4, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP, // flags + S_NULL // raisestate + }, + + { // MT_SNOWFLAKE + -1, // doomednum + S_SNOW1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + -2*FRACUNIT, // speed + 4*FRACUNIT, // radius + 4*FRACUNIT, // height + 0, // display offset + 4, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP, // flags + S_NULL // raisestate + }, + + { // MT_SPLISH + -1, // doomednum + S_SPLISH1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 6*FRACUNIT, // radius + 1*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_SMOKE + -1, // doomednum + S_SMOKE1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 20*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_SMALLBUBBLE + -1, // doomednum + S_SMALLBUBBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 4*FRACUNIT, // radius + 4*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_MEDIUMBUBBLE + -1, // doomednum + S_MEDIUMBUBBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_EXTRALARGEBUBBLE + -1, // doomednum + S_LARGEBUBBLE1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_POP1, // deathstate + S_NULL, // xdeathstate + sfx_gasp, // deathsound + 8, // speed + 23*FRACUNIT, // radius + 43*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_WATERZAP + -1, // doomednum + S_WATERZAP, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 4*FRACUNIT, // radius + 4*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_SPINDUST + -1, // doomednum + S_SPINDUST1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 4*FRACUNIT, // speed + 4*FRACUNIT, // radius + 4*FRACUNIT, // height + 0, // display offset + 4, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP, // flags + S_NULL // raisestate + }, + + { // MT_TFOG + -1, // doomednum + S_FOG1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP, // flags + S_NULL // raisestate + }, + + { // MT_PARTICLE + -1, // doomednum + S_PARTICLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 4*FRACUNIT, // speed + 4*FRACUNIT, // radius + 4*FRACUNIT, // height + 1, // display offset + 4, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP, // flags + S_NULL // raisestate + }, + + { // MT_PARTICLEGEN + 757, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 1*FRACUNIT, // radius + 1*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_SCORE + -1, // doomednum + S_SCRA, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 3*FRACUNIT, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 1, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_DROWNNUMBERS + -1, // doomednum + S_ZERO1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 113, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_GOTEMERALD + -1, // doomednum + S_CEMG1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_ORBITEM1, // meleestate + S_ORBIDYA1, // missilestate + S_XPLD1, // deathstate + S_NULL, // xdeathstate + sfx_s3k8a, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 112, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_LOCKON + -1, // doomednum + S_LOCKON1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 111, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_TAG + -1, // doomednum + S_TTAG, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 111, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_GOTFLAG + -1, // doomednum + S_GOTFLAG, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 64*FRACUNIT, // radius + 32*FRACUNIT, // height + 111, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + // ambient water 1a (large) + { // MT_AWATERA + 700, // doomednum + S_INVISIBLE, // spawnstate + 35, // spawnhealth + S_NULL, // seestate + sfx_amwtr1, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags + S_NULL // raisestate + }, + + // ambient water 1b (large) + { // MT_AWATERB + 701, // doomednum + S_INVISIBLE, // spawnstate + 35, // spawnhealth + S_NULL, // seestate + sfx_amwtr2, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags + S_NULL // raisestate + }, + + // ambient water 2a (medium) + { // MT_AWATERC + 702, // doomednum + S_INVISIBLE, // spawnstate + 35, // spawnhealth + S_NULL, // seestate + sfx_amwtr3, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags + S_NULL // raisestate + }, + + // ambient water 2b (medium) + { // MT_AWATERD + 703, // doomednum + S_INVISIBLE, // spawnstate + 35, // spawnhealth + S_NULL, // seestate + sfx_amwtr4, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags + S_NULL // raisestate + }, + + // ambient water 3a (small) + { // MT_AWATERE + 704, // doomednum + S_INVISIBLE, // spawnstate + 35, // spawnhealth + S_NULL, // seestate + sfx_amwtr5, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags + S_NULL // raisestate + }, + + // ambient water 3b (small) + { // MT_AWATERF + 705, // doomednum + S_INVISIBLE, // spawnstate + 35, // spawnhealth + S_NULL, // seestate + sfx_amwtr6, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags + S_NULL // raisestate + }, + + // ambient water 4a (extra large) + { // MT_AWATERG + 706, // doomednum + S_INVISIBLE, // spawnstate + 35, // spawnhealth + S_NULL, // seestate + sfx_amwtr7, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags + S_NULL // raisestate + }, + + // ambient water 4b (extra large) + { // MT_AWATERH + 707, // doomednum + S_INVISIBLE, // spawnstate + 35, // spawnhealth + S_NULL, // seestate + sfx_amwtr8, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags + S_NULL // raisestate + }, + + { // MT_RANDOMAMBIENT + 708, // doomednum + S_INVISIBLE, // spawnstate + 512, // spawnhealth: repeat speed + S_NULL, // seestate + sfx_ambint, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_None, // activesound + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_AMBIENT, // flags + S_NULL // raisestate + }, + + { // MT_RANDOMAMBIENT2 + 709, // doomednum + S_INVISIBLE, // spawnstate + 220, // spawnhealth: repeat speed + S_NULL, // seestate + sfx_ambin2, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_None, // activesound + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_AMBIENT, // flags + S_NULL // raisestate + }, + + { // MT_MACHINEAMBIENCE + 710, // doomednum + S_INVISIBLE, // spawnstate + 24, // spawnhealth: repeat speed + S_NULL, // seestate + sfx_ambmac, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 200, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 1*FRACUNIT, // speed + 16*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 20, // damage + sfx_None, // activesound + MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_AMBIENT, // flags + S_NULL // raisestate + }, + + { // MT_CORK + -1, // doomednum + S_CORK, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_corkp, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SMOKE1, // deathstate + S_NULL, // xdeathstate + sfx_corkh, // deathsound + 60*FRACUNIT, // speed + 16*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 0, // mass + 1, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_REDRING + -1, // doomednum + S_RRNG1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_wepfir, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_itemup, // deathsound + 60*FRACUNIT, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 0, // mass + 1, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + +// Ring ammo: Health = amount given + { // MT_BOUNCERING + 301, // doomednum + S_BOUNCERINGAMMO, // spawnstate + 10, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_itemup, // deathsound + 60*FRACUNIT, // speed + 24*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + pw_bouncering, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_RAILRING + 302, // doomednum + S_RAILRINGAMMO, // spawnstate + 5, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_itemup, // deathsound + 60*FRACUNIT, // speed + 24*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + pw_railring, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_INFINITYRING + 303, // doomednum + S_INFINITYRINGAMMO,// spawnstate + 80, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_itemup, // deathsound + 60*FRACUNIT, // speed + 24*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + pw_infinityring,// mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_AUTOMATICRING + 304, // doomednum + S_AUTOMATICRINGAMMO, // spawnstate + 40, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_itemup, // deathsound + 60*FRACUNIT, // speed + 24*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + pw_automaticring, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_EXPLOSIONRING + 305, // doomednum + S_EXPLOSIONRINGAMMO, // spawnstate + 5, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_itemup, // deathsound + 60*FRACUNIT, // speed + 24*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + pw_explosionring, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_SCATTERRING + 306, // doomednum + S_SCATTERRINGAMMO, // spawnstate + 5, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_itemup, // deathsound + 60*FRACUNIT, // speed + 24*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + pw_scatterring, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_GRENADERING + 307, // doomednum + S_GRENADERINGAMMO, // spawnstate + 10, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_itemup, // deathsound + 60*FRACUNIT, // speed + 24*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + pw_grenadering, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + +// Ring panels: Reactiontime = amount given + { // MT_BOUNCEPICKUP + 330, // doomednum + S_BOUNCEPICKUP, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 10, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 1, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_BOUNCEPICKUPFADE1, // deathstate + S_NULL, // xdeathstate + sfx_ncitem, // deathsound + 60*FRACUNIT, // speed + 24*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + pw_bouncering, // mass + 2*TICRATE, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_RAILPICKUP + 331, // doomednum + S_RAILPICKUP, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 5, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 2, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_RAILPICKUPFADE1, // deathstate + S_NULL, // xdeathstate + sfx_ncitem, // deathsound + 60*FRACUNIT, // speed + 24*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + pw_railring, // mass + 2*TICRATE, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_AUTOPICKUP + 332, // doomednum + S_AUTOPICKUP, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 40, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 4, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_AUTOPICKUPFADE1, // deathstate + S_NULL, // xdeathstate + sfx_ncitem, // deathsound + 60*FRACUNIT, // speed + 24*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + pw_automaticring, // mass + 2*TICRATE, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_EXPLODEPICKUP + 333, // doomednum + S_EXPLODEPICKUP,// spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 5, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 8, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_EXPLODEPICKUPFADE1, // deathstate + S_NULL, // xdeathstate + sfx_ncitem, // deathsound + 60*FRACUNIT, // speed + 24*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + pw_explosionring, // mass + 2*TICRATE, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_SCATTERPICKUP + 334, // doomednum + S_SCATTERPICKUP,// spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 5, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 8, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SCATTERPICKUPFADE1, // deathstate + S_NULL, // xdeathstate + sfx_ncitem, // deathsound + 60*FRACUNIT, // speed + 24*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + pw_scatterring, // mass + 2*TICRATE, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_GRENADEPICKUP + 335, // doomednum + S_GRENADEPICKUP,// spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 10, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 8, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_GRENADEPICKUPFADE1, // deathstate + S_NULL, // xdeathstate + sfx_ncitem, // deathsound + 60*FRACUNIT, // speed + 24*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + pw_grenadering, // mass + 2*TICRATE, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_THROWNBOUNCE + -1, // doomednum + S_THROWNBOUNCE1,// spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_bnce1, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_itemup, // deathsound + 60*FRACUNIT, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 0, // mass + 1, // damage + sfx_bnce1, // activesound + MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY|MF_BOUNCE, // flags + S_NULL // raisestate + }, + + { // MT_THROWNINFINITY + -1, // doomednum + S_THROWNINFINITY1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_wepfir, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_itemup, // deathsound + 60*FRACUNIT, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 0, // mass + 1, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_THROWNAUTOMATIC + -1, // doomednum + S_THROWNAUTOMATIC1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_wepfir, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_itemup, // deathsound + 60*FRACUNIT, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 0, // mass + 1, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_THROWNSCATTER + -1, // doomednum + S_THROWNSCATTER,// spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_bnce2, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_itemup, // deathsound + 60*FRACUNIT, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 0, // mass + 1, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_THROWNEXPLOSION + -1, // doomednum + S_THROWNEXPLOSION1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_cannon, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 192*FRACUNIT, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_RINGEXPLODE, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 60*FRACUNIT, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 0, // mass + 1, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_THROWNGRENADE + -1, // doomednum + S_THROWNGRENADE1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_wepfir, // seesound + 6*TICRATE, // reactiontime (<-- Looking for the Grenade Ring's fuse? It's right here! Again!) + sfx_gbeep, // attacksound + S_NULL, // painstate + 192*FRACUNIT, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_RINGEXPLODE, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 30*FRACUNIT, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 0, // mass + 1, // damage + sfx_s3k5d, // activesound + MF_NOBLOCKMAP|MF_MISSILE|MF_BOUNCE|MF_GRENADEBOUNCE, // flags + S_NULL // raisestate + }, + + { // MT_COIN + 1800, // doomednum + S_COIN1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + MT_FLINGCOIN, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_COINSPARKLE1, // deathstate + S_NULL, // xdeathstate + sfx_mario4, // deathsound + 60*FRACUNIT, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_FLINGCOIN + -1, // doomednum + S_COIN1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + MT_FLINGCOIN, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + MT_COIN, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_COINSPARKLE1, // deathstate + S_NULL, // xdeathstate + sfx_mario4, // deathsound + 60*FRACUNIT, // speed + 15*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL, // flags + S_NULL // raisestate + }, + + { // MT_GOOMBA + 1801, // doomednum + S_GOOMBA1, // spawnstate + 1, // spawnhealth + S_GOOMBA2, // seestate + sfx_None, // seesound + 32, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 200, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_GOOMBA_DEAD, // deathstate + S_NULL, // xdeathstate + sfx_mario5, // deathsound + 6, // speed + 24*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags + S_NULL // raisestate + }, + + { // MT_BLUEGOOMBA + 1802, // doomednum + S_BLUEGOOMBA1, // spawnstate + 1, // spawnhealth + S_BLUEGOOMBA2, // seestate + sfx_None, // seesound + 32, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 170, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_BLUEGOOMBA_DEAD, // deathstate + S_NULL, // xdeathstate + sfx_mario5, // deathsound + 6, // speed + 24*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags + S_NULL // raisestate + }, + + { // MT_FIREFLOWER + 1803, // doomednum + S_FIREFLOWER1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL, // flags + S_NULL // raisestate + }, + + { // MT_FIREBALL + -1, // doomednum + S_FIREBALL1, // spawnstate + 1000, // spawnhealth + S_FIREBALLEXP1, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_FIREBALLEXP1, // meleestate + S_FIREBALLEXP1, // missilestate + S_FIREBALLEXP1, // deathstate + S_FIREBALLEXP1, // xdeathstate + sfx_mario1, // deathsound + 10*FRACUNIT, // speed + 4*FRACUNIT, // radius + 8*FRACUNIT, // height + 0, // display offset + DMG_FIRE, // mass + 1, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_FIRE|MF_MISSILE, // flags + S_NULL // raisestate + }, + + { // MT_SHELL + 1804, // doomednum + S_SHELL, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 16, // speed + 16*FRACUNIT, // radius + 20*FRACUNIT, // height + 0, // display offset + 0, // mass + 1, // damage + sfx_mario1, // activesound + MF_SPECIAL|MF_SHOOTABLE|MF_BOUNCE, // flags + S_NULL // raisestate + }, + + { // MT_PUMA + 1805, // doomednum + S_PUMA_START1, // spawnstate + 1000, // spawnhealth + S_PUMA_START1, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_PUMA_DOWN1, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_PUMA_DOWN3, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + DMG_FIRE, // mass + 0, // damage + sfx_None, // activesound + MF_PAIN|MF_FIRE, // flags + S_NULL // raisestate + }, + + { // MT_PUMATRAIL + -1, // doomednum + S_PUMATRAIL1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 2*FRACUNIT, // radius + 4*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_HAMMER + -1, // doomednum + S_HAMMER, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 4*FRACUNIT, // radius + 8*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_PAIN, // flags + S_NULL // raisestate + }, + { // MT_KOOPA + 1806, // doomednum + S_KOOPA1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 48*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_PAIN, // flags + S_NULL // raisestate + }, + + { // MT_KOOPAFLAME + -1, // doomednum + S_KOOPAFLAME1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 5*FRACUNIT, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 0, // display offset + DMG_FIRE, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_MISSILE|MF_FIRE, // flags + S_NULL // raisestate + }, + + { // MT_AXE + 1807, // doomednum + S_AXE1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL, // flags + S_NULL // raisestate + }, + + { // MT_MARIOBUSH1 + 1808, // doomednum + S_MARIOBUSH1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_MARIOBUSH2 + 1809, // doomednum + S_MARIOBUSH2, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_TOAD + 1810, // doomednum + S_TOAD, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_AXIS + 1700, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 10*FRACUNIT, // speed + 256*FRACUNIT, // radius + 1*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP, // flags + S_NULL // raisestate + }, + + { // MT_AXISTRANSFER + 1701, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 10, // speed + 16*FRACUNIT, // radius + 1, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP, // flags + S_NULL // raisestate + }, + + { // MT_AXISTRANSFERLINE + 1702, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 10, // speed + 32*FRACUNIT, // radius + 1, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSDRONE + 1703, // doomednum + S_INVISIBLE, // spawnstate + 120, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 80*FRACUNIT, // height + 1, // display offset + 1000, // mass + 0, // damage + sfx_ideya, // activesound + MF_NOGRAVITY|MF_NOCLIP|MF_SPECIAL, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSDRONE_MAN + -1, // doomednum + S_INVISIBLE, // spawnstate + 120, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NIGHTSDRONE_MAN1, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 56*FRACUNIT, // height + 1, // display offset + 1000, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSDRONE_SPARKLING + -1, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NIGHTSDRONE_SPARKLING1, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 1, // display offset + 1000, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSDRONE_GOAL + -1, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NIGHTSDRONE_GOAL1, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + -1, // display offset + 1000, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSPARKLE + -1, // doomednum + S_NIGHTSPARKLE1,// spawnstate + 1000, // spawnhealth + S_NIGHTSPARKLESUPER1, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 2*FRACUNIT, // radius + 4*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSLOOPHELPER + -1, // doomednum + S_NIGHTSLOOPHELPER,// spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 4*FRACUNIT, // radius + 4*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSBUMPER + 1704, // doomednum + S_NIGHTSBUMPER1,// spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_nbmper, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 21000, // speed + 32*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SCENERY|MF_SPECIAL|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_HOOP + -1, // doomednum + S_HOOP, // spawnstate + 1000, // spawnhealth + S_HOOP_XMASA, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 1, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 4, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_HOOPCOLLIDE + -1, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 1, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 4, // mass + 0, // damage + sfx_None, // activesound + MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_SPECIAL|MF_NOTHINK, // flags + S_NULL // raisestate + }, + + { // MT_HOOPCENTER + -1, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 1, // speed + 2*FRACUNIT, // radius + 4*FRACUNIT, // height + 0, // display offset + 4, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSCORE + -1, // doomednum + S_NIGHTSCORE10, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NIGHTSCORE10_2, // xdeathstate + sfx_None, // deathsound + 1, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 0, // display offset + 4, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSCHIP + -1, // doomednum + S_NIGHTSCHIP, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + MT_FLINGNIGHTSCHIP, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_s3k33, // painsound + S_RING, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_ncchip, // deathsound + 1, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 4, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NIGHTSCHIPBONUS // raisestate + }, + + { // MT_FLINGNIGHTSCHIP + -1, // doomednum + S_NIGHTSCHIP, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + MT_FLINGNIGHTSCHIP, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + MT_NIGHTSCHIP, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_ncchip, // deathsound + 38*FRACUNIT, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL, // flags + S_NIGHTSCHIPBONUS // raisestate + }, + + { // MT_NIGHTSSTAR + -1, // doomednum + S_NIGHTSSTAR, // spawnstate + 1000, // spawnhealth + S_NIGHTSSTARXMAS, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_s3k33, // painsound + S_RING, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_ncitem, // deathsound + 1, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 4, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSSUPERLOOP + 1707, // doomednum + S_NIGHTSSUPERLOOP, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_ncspec, // deathsound + 20*TICRATE, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_NIGHTSITEM, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSDRILLREFILL + 1708, // doomednum + S_NIGHTSDRILLREFILL, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_ncspec, // deathsound + 96*20, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_NIGHTSITEM, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSHELPER + 1709, // doomednum + S_NIGHTSHELPER, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_ncspec, // deathsound + 20*TICRATE, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_NIGHTSITEM, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSEXTRATIME + 1711, // doomednum + S_NIGHTSEXTRATIME, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_ncspec, // deathsound + 30*TICRATE, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_NIGHTSITEM, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSLINKFREEZE + 1712, // doomednum + S_NIGHTSLINKFREEZE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_ncspec, // deathsound + 15*TICRATE, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_NIGHTSITEM, // flags + S_NULL // raisestate + }, + + { // MT_EGGCAPSULE + 1710, // doomednum + S_EGGCAPSULE, // spawnstate + 20, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 72*FRACUNIT, // radius + 144*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_SPECIAL, // flags + S_NULL // raisestate + }, + + { // MT_IDEYAANCHOR + 1714, // doomednum + S_INVISIBLE, // spawnstate + 0, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 1*FRACUNIT, // radius + 2*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTOPIANHELPER + -1, // doomednum + S_NIGHTOPIANHELPER1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_PIAN + 1602, // doomednum + S_PIAN0, // spawnstate + 1000, // spawnhealth + S_PIAN1, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 200, // painchance + sfx_None, // painsound + S_PIANSING, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + FRACUNIT, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_SHLEEP + 1601, // doomednum + S_SHLEEP1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 200, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_SHLEEPBOUNCE1, // deathstate + S_NULL, // xdeathstate + sfx_peww, // deathsound + 0, // speed + 24*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_PENGUINATOR + 129, // doomednum + S_PENGUINATOR_LOOK, // spawnstate + 1, // spawnhealth + S_PENGUINATOR_WADDLE1, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_ngjump, // attacksound + S_NULL, // painstate + 200, // painchance + sfx_None, // painsound + S_PENGUINATOR_SLIDE1, // meleestate + S_PENGUINATOR_SLIDE1, // missilestate + S_XPLD_FLICKY, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 5, // speed + 24*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_SLIDEME, // flags + S_NULL // raisestate + }, + + { // MT_POPHAT + 130, // doomednum -- happy anniversary! + S_POPHAT_LOOK, // spawnstate + 1, // spawnhealth + S_POPHAT_SHOOT1, // seestate + sfx_None, // seesound + 1, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 200, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_XPLD_FLICKY, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 0, // speed + 24*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY, // flags + S_NULL // raisestate + }, + + { // MT_POPSHOT + -1, // doomednum + S_ROCKCRUMBLEI, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_cannon, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 200, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_XPLD1, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_MISSILE, // flags + S_NULL // raisestate + }, + + { // MT_HIVEELEMENTAL + 127, // doomednum + S_HIVEELEMENTAL_LOOK, // spawnstate + 2, // spawnhealth + S_HIVEELEMENTAL_PREPARE1, // seestate + sfx_s3k74, // seesound + 0, // reactiontime + sfx_s3k91, // attacksound + S_HIVEELEMENTAL_PAIN, // painstate + 0, // painchance + sfx_dmpain, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_HIVEELEMENTAL_DIE1, // deathstate + S_NULL, // xdeathstate + sfx_cybdth, // deathsound + 6*FRACUNIT, // speed + 30*FRACUNIT, // radius + 80*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_s3k72, // activesound + MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY, // flags + S_NULL // raisestate + }, + + { // MT_BUMBLEBORE + 128, // doomednum + S_BUMBLEBORE_SPAWN, // spawnstate + 0, // spawnhealth -- this is how you do drones... + S_BUMBLEBORE_FLY1, // seestate + sfx_s3k8e, // seesound + 2, // reactiontime + sfx_s3k9e, // attacksound + S_BUMBLEBORE_STUCK1, // painstate + 0, // painchance + sfx_None, // painsound + S_BUMBLEBORE_RAISE, // meleestate + S_NULL, // missilestate + S_BUMBLEBORE_DIE, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 4*FRACUNIT, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_SLIDEME, // flags + S_NULL // raisestate + }, + + { // MT_BUBBLEBUZZ + 124, // doomednum + S_BBUZZFLY1, // spawnstate + 1, // spawnhealth + S_BBUZZFLY1, // seestate + sfx_None, // seesound + 2, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + TICRATE, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_XPLD_FLICKY, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 6*FRACUNIT, // speed + 20*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_gbeep, // activesound + MF_SLIDEME|MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_SMASHINGSPIKEBALL + 2000, // doomednum + S_SMASHSPIKE_FLOAT, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 18*FRACUNIT, // radius + 28*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_PAIN, // flags + S_NULL // raisestate + }, + + { // MT_CACOLANTERN + 132, // doomednum + S_CACO_LOOK, // spawnstate + 1, // spawnhealth + S_CACO_WAKE1, // seestate + sfx_s3k8a, // seesound + 32, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 200, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_CACO_DIE_FLAGS, // deathstate + S_NULL, // xdeathstate + sfx_lntdie, // deathsound + FRACUNIT, // speed + 32*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_lntsit, // activesound + MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_CACOSHARD + -1, // doomednum + S_CACOSHARD_RANDOMIZE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 200, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_lntdie, // deathsound + FRACUNIT, // speed + FRACUNIT, // radius + FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_MISSILE|MF_NOBLOCKMAP|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate + }, + + { // MT_CACOFIRE + -1, // doomednum + S_CACOFIRE1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_s3k70, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 200, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_CACOFIRE_EXPLODE1, // deathstate + S_NULL, // xdeathstate + sfx_s3k81, // deathsound + 20*FRACUNIT, // speed + 16*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 0, // mass + 20, // damage + sfx_s3k48, // activesound + MF_MISSILE|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_SPINBOBERT + 131, // doomednum + S_SPINBOBERT_MOVE_FLIPUP, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_s3ka0, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 200, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_XPLD1, // deathstate + S_NULL, // xdeathstate + sfx_s3k92, // deathsound + 20*FRACUNIT, // speed + 32*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 20, // damage + sfx_s3k48, // activesound + MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_SPINBOBERT_FIRE1 + -1, // doomednum + S_SPINBOBERT_FIRE_MOVE, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 200, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_XPLD1, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 10*FRACUNIT, // speed + 16*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + (sfx_ghosty<<8),// mass + 20, // damage + sfx_None, // activesound + MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_SPINBOBERT_FIRE2 + -1, // doomednum + S_SPINBOBERT_FIRE_MOVE, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 200, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_XPLD1, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + -10*FRACUNIT, // speed - only difference from above + 16*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + (sfx_ghosty<<8),// mass + 20, // damage + sfx_None, // activesound + MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_HANGSTER + 133, // doomednum + S_HANGSTER_LOOK, // spawnstate + 1, // spawnhealth + S_HANGSTER_SWOOP1, // seestate + sfx_s3ka0, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 200, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_XPLD_FLICKY, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 20*FRACUNIT, // speed + 24*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 20, // damage + sfx_s3k48, // activesound + MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_SPAWNCEILING, // flags + S_NULL // raisestate + }, + + { // MT_TELEPORTMAN + 751, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8, // radius + 8, // height + 0, // display offset + 10, // mass + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_ALTVIEWMAN + 752, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8, // radius + 8, // height + 0, // display offset + 10, // mass + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_CRUMBLEOBJ + -1, // doomednum + S_CRUMBLE1, // spawnstate + 1000, // spawnhealth + S_CRUMBLE1, // seestate + 0, // seesound + 1, // reactiontime + 0, // attacksound + S_NULL, // painstate + 200, // painchance + 0, // painsound + 0, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_crumbl, // deathsound + 3, // speed + 1*FRACUNIT, // radius + 1*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + 0, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + // Waypoint for zoom tubes + { // MT_TUBEWAYPOINT + 753, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 1*FRACUNIT, // radius + 2*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + // for use with wind and current effects + { // MT_PUSH + 754, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8, // radius + 8, // height + 0, // display offset + 10, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + // for use with wind and current effects + { // MT_PULL + 755, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8, // radius + 8, // height + 0, // display offset + 10, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_GHOST + -1, // doomednum + S_THOK, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 48*FRACUNIT, // height + 1, // display offset + 1000, // mass + 8, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_OVERLAY + -1, // doomednum + S_NULL, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 3, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 1*FRACUNIT, // radius + 1*FRACUNIT, // height + 0, // display offset + 1000, // mass + 8, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_ANGLEMAN + 758, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8, // radius + 8, // height + 0, // display offset + 10, // mass + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_POLYANCHOR + 760, // doomednum + S_INVISIBLE, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 3, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 1*FRACUNIT, // radius + 1*FRACUNIT, // height + 0, // display offset + 1000, // mass + 8, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_NOCLIP, // flags + S_NULL // raisestate + }, + + { // MT_POLYSPAWN + 761, // doomednum + S_INVISIBLE, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 3, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 1*FRACUNIT, // radius + 1*FRACUNIT, // height + 0, // display offset + 1000, // mass + 8, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_NOCLIP, // flags + S_NULL // raisestate + }, + + { // MT_POLYSPAWNCRUSH + 762, // doomednum + S_INVISIBLE, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 3, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 1*FRACUNIT, // radius + 1*FRACUNIT, // height + 0, // display offset + 1000, // mass + 8, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_NOCLIP, // flags + S_NULL // raisestate + }, + + { // MT_SKYBOX + 780, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 12*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 10, // mass + 0, // damage + sfx_None, // activesound + MF_SCENERY|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_SPARK + -1, // doomednum + S_SPRK1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 32*FRACUNIT, // radius + 32*FRACUNIT, // height + 2, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_EXPLODE + -1, // doomednum + S_XPLD1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 32, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 200, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 1*FRACUNIT, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_UWEXPLODE + -1, // doomednum + S_WPLD1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 32, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 200, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 1*FRACUNIT, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_DUST + -1, // doomednum + S_DUST1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 3*FRACUNIT, // speed + FRACUNIT, // radius + FRACUNIT, // height + 0, // display offset + 4, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP, // flags + S_NULL // raisestate + }, + + { // MT_WOODDEBRIS + -1, // doomednum + S_WOODDEBRIS, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_RUNSPAWNFUNC|MF_NOCLIPHEIGHT|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_ROCKSPAWNER + 1202, // doomednum + S_ROCKSPAWN, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_FALLINGROCK + -1, // doomednum + S_ROCKCRUMBLEA, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_ambint, // seesound + 4, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_rocks1, // activesound + MF_PAIN|MF_BOUNCE, // flags + S_NULL // raisestate + }, + + { // MT_ROCKCRUMBLE1 + -1, // doomednum + S_ROCKCRUMBLEA, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_ambint, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_ROCKCRUMBLE2 + -1, // doomednum + S_ROCKCRUMBLEB, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_ambint, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_ROCKCRUMBLE3 + -1, // doomednum + S_ROCKCRUMBLEC, //spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_ambint, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_ROCKCRUMBLE4 + -1, // doomednum + S_ROCKCRUMBLED, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_ambint, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_ROCKCRUMBLE5 + -1, // doomednum + S_ROCKCRUMBLEE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_ambint, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_ROCKCRUMBLE6 + -1, // doomednum + S_ROCKCRUMBLEF, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_ambint, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_ROCKCRUMBLE7 + -1, // doomednum + S_ROCKCRUMBLEG, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_ambint, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_ROCKCRUMBLE8 + -1, // doomednum + S_ROCKCRUMBLEH, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_ambint, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_ROCKCRUMBLE9 + -1, // doomednum + S_ROCKCRUMBLEI, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_ambint, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_ROCKCRUMBLE10 + -1, // doomednum + S_ROCKCRUMBLEJ, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_ambint, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_ROCKCRUMBLE11 + -1, // doomednum + S_ROCKCRUMBLEK, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_ambint, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_ROCKCRUMBLE12 + -1, // doomednum + S_ROCKCRUMBLEL, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_ambint, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_ROCKCRUMBLE13 + -1, // doomednum + S_ROCKCRUMBLEM, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_ambint, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_ROCKCRUMBLE14 + -1, // doomednum + S_ROCKCRUMBLEN, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_ambint, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_ROCKCRUMBLE15 + -1, // doomednum + S_ROCKCRUMBLEO, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_ambint, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_ROCKCRUMBLE16 + -1, // doomednum + S_ROCKCRUMBLEP, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_ambint, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + +#ifdef SEENAMES + { // MT_NAMECHECK + -1, // doomednum + S_NAMECHECK, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 60*FRACUNIT, // speed + 30*FRACUNIT, // radius + 40*FRACUNIT, // height + 0, // display offset + 0, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY|MF_NOSECTOR, // flags diff --git a/src/info.h b/src/info.h index 0700494f94c2190cb523be3b65680d5391684008..13abfa5f60249d91afd05bc0fba7b35376f41a44 100644 --- a/src/info.h +++ b/src/info.h @@ -28,17 +28,22 @@ void A_Explode(); void A_Pain(); void A_Fall(); void A_MonitorPop(); +void A_GoldMonitorPop(); +void A_GoldMonitorRestore(); +void A_GoldMonitorSparkle(); void A_Look(); void A_Chase(); void A_FaceStabChase(); +void A_FaceStabRev(); +void A_FaceStabHurl(); +void A_FaceStabMiss(); +void A_StatueBurst(); void A_FaceTarget(); void A_FaceTracer(); void A_Scream(); void A_BossDeath(); void A_CustomPower(); // Use this for a custom power void A_GiveWeapon(); // Gives the player weapon(s) -void A_JumpShield(); // Obtained Jump Shield -void A_RingShield(); // Obtained Ring Shield void A_RingBox(); // Obtained Ring Box Tails void A_Invincibility(); // Obtained Invincibility Box void A_SuperSneakers(); // Obtained Super Sneakers Box @@ -49,13 +54,9 @@ void A_BubbleRise(); // Bubbles float to surface void A_BubbleCheck(); // Don't draw if not underwater void A_AwardScore(); void A_ExtraLife(); // Extra Life -void A_BombShield(); // Obtained Bomb Shield -void A_WaterShield(); // Obtained Water Shield -void A_ForceShield(); // Obtained Force Shield -void A_PityShield(); // Obtained Pity Shield. We're... sorry. +void A_GiveShield(); // Obtained Shield void A_GravityBox(); void A_ScoreRise(); // Rise the score logo -void A_ParticleSpawn(); void A_AttractChase(); // Ring Chase void A_DropMine(); // Drop Mine from Skim or Jetty-Syn Bomber void A_FishJump(); // Fish Jump @@ -78,7 +79,6 @@ void A_DetonChase(); // Deton Chaser void A_CapeChase(); // Fake little Super Sonic cape void A_RotateSpikeBall(); // Spike ball rotation void A_SlingAppear(); -void A_MaceRotate(); void A_UnidusBall(); void A_RockSpawn(); void A_SetFuse(); @@ -101,13 +101,23 @@ void A_JetJawRoam(); void A_JetJawChomp(); void A_PointyThink(); void A_CheckBuddy(); +void A_HoodFire(); void A_HoodThink(); -void A_ArrowCheck(); +void A_HoodFall(); +void A_ArrowBonks(); void A_SnailerThink(); void A_SharpChase(); void A_SharpSpin(); +void A_SharpDecel(); +void A_CrushstaceanWalk(); +void A_CrushstaceanPunch(); +void A_CrushclawAim(); +void A_CrushclawLaunch(); void A_VultureVtol(); void A_VultureCheck(); +void A_VultureHover(); +void A_VultureBlast(); +void A_VultureFly(); void A_SkimChase(); void A_SkullAttack(); void A_LobShot(); @@ -208,6 +218,53 @@ void A_BrakFireShot(); void A_BrakLobShot(); void A_NapalmScatter(); void A_SpawnFreshCopy(); +void A_FlickySpawn(); +void A_FlickyCenter(); +void A_FlickyAim(); +void A_FlickyFly(); +void A_FlickySoar(); +void A_FlickyCoast(); +void A_FlickyHop(); +void A_FlickyFlounder(); +void A_FlickyCheck(); +void A_FlickyHeightCheck(); +void A_FlickyFlutter(); +void A_FlameParticle(); +void A_FadeOverlay(); +void A_Boss5Jump(); +void A_LightBeamReset(); +void A_MineExplode(); +void A_MineRange(); +void A_ConnectToGround(); +void A_SpawnParticleRelative(); +void A_MultiShotDist(); +void A_WhoCaresIfYourSonIsABee(); +void A_ParentTriesToSleep(); +void A_CryingToMomma(); +void A_CheckFlags2(); +void A_Boss5FindWaypoint(); +void A_DoNPCSkid(); +void A_DoNPCPain(); +void A_PrepareRepeat(); +void A_Boss5ExtraRepeat(); +void A_Boss5Calm(); +void A_Boss5CheckOnGround(); +void A_Boss5CheckFalling(); +void A_Boss5PinchShot(); +void A_Boss5MakeItRain(); +void A_LookForBetter(); +void A_Boss5BombExplode(); +void A_DustDevilThink(); +void A_TNTExplode(); +void A_DebrisRandom(); +void A_TrainCameo(); +void A_TrainCameo2(); +void A_CanarivoreGas(); +void A_KillSegments(); +void A_SnapperSpawn(); +void A_SnapperThinker(); +void A_SaloonDoorSpawn(); +void A_MinecartSparkThink(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 512 @@ -224,33 +281,38 @@ typedef enum sprite SPR_PLAY, // Enemies - SPR_POSS, - SPR_SPOS, - SPR_FISH, // Greenflower Fish + SPR_POSS, // Crawla (Blue) + SPR_SPOS, // Crawla (Red) + SPR_FISH, // SDURF SPR_BUZZ, // Buzz (Gold) SPR_RBUZ, // Buzz (Red) SPR_JETB, // Jetty-Syn Bomber - SPR_JETW, // Jetty-Syn Water Bomber SPR_JETG, // Jetty-Syn Gunner SPR_CCOM, // Crawla Commander SPR_DETN, // Deton SPR_SKIM, // Skim mine dropper - SPR_TRET, + SPR_TRET, // Industrial Turret SPR_TURR, // Pop-Up Turret SPR_SHRP, // Sharp + SPR_CRAB, // Crushstacean SPR_JJAW, // Jet Jaw SPR_SNLR, // Snailer - SPR_VLTR, // Vulture + SPR_VLTR, // BASH SPR_PNTY, // Pointy SPR_ARCH, // Robo-Hood - SPR_CBFS, // CastleBot FaceStabber (Egg Knight?) + SPR_CBFS, // Castlebot Facestabber + SPR_STAB, // Castlebot Facestabber spear aura SPR_SPSH, // Egg Guard - SPR_ESHI, // Egg Shield for Egg Guard + SPR_ESHI, // Egg Guard's shield SPR_GSNP, // Green Snapper + SPR_GSNL, // Green Snapper leg + SPR_GSNH, // Green Snapper head SPR_MNUS, // Minus + SPR_MNUD, // Minus dirt SPR_SSHL, // Spring Shell SPR_UNID, // Unidus - SPR_BBUZ, // AquaBuzz, for Azure Temple + SPR_CANA, // Canarivore + SPR_CANG, // Canarivore gas // Generic Boss Items SPR_JETF, // Boss jet fumes @@ -275,7 +337,11 @@ typedef enum sprite SPR_EFIR, // Boss 4 jet flame // Boss 5 (Arid Canyon) - SPR_EGGQ, + SPR_FANG, // replaces EGGQ + SPR_FBOM, + SPR_FSGN, + SPR_BARX, // bomb explosion (also used by barrel) + SPR_BARD, // bomb dust (also used by barrel) // Boss 6 (Red Volcano) SPR_EGGR, @@ -303,48 +369,55 @@ typedef enum sprite // Collectible Items SPR_RING, SPR_TRNG, // Team Rings - SPR_EMMY, // emerald test SPR_TOKE, // Special Stage Token SPR_RFLG, // Red CTF Flag SPR_BFLG, // Blue CTF Flag - SPR_NWNG, // NiGHTS Wing collectable item. + SPR_SPHR, // Sphere + SPR_NCHP, // NiGHTS chip + SPR_NSTR, // NiGHTS star SPR_EMBM, // Emblem SPR_CEMG, // Chaos Emeralds - SPR_EMER, // Emerald Hunt + SPR_SHRD, // Emerald Hunt // Interactive Objects - SPR_FANS, - SPR_BUBL, // water bubble source + SPR_BBLS, // water bubble source SPR_SIGN, // Level end sign - SPR_STEM, // Steam riser SPR_SPIK, // Spike Ball SPR_SFLM, // Spin fire SPR_USPK, // Floor spike + SPR_WSPK, // Wall spike + SPR_WSPB, // Wall spike base SPR_STPT, // Starpost SPR_BMNE, // Big floating mine // Monitor Boxes - SPR_SRBX, - SPR_RRBX, - SPR_BRBX, - SPR_SHTV, - SPR_PINV, - SPR_YLTV, - SPR_BLTV, // Force shield - SPR_BKTV, // Bomb shield TV - SPR_WHTV, // Jump shield TV - SPR_GRTV, // Pity shield TV - SPR_ELTV, // Elemental shield TV - SPR_EGGB, // Eggman box - SPR_MIXU, // Player mixing monitor - SPR_RECY, // Recycler (power mixing) monitor - SPR_QUES, // Random monitor - SPR_GBTV, // Gravity boots TV - SPR_PRUP, // 1up - SPR_PTTV, // Score TVs - - // Monitor Miscellany - SPR_MTEX, // Exploding monitor + SPR_MSTV, // MiSc TV sprites + SPR_XLTV, // eXtra Large TV sprites + + SPR_TRRI, // Red team: 10 RIngs + SPR_TBRI, // Blue team: 10 RIngs + + SPR_TVRI, // 10 RIng + SPR_TVPI, // PIty shield + SPR_TVAT, // ATtraction shield + SPR_TVFO, // FOrce shield + SPR_TVAR, // ARmageddon shield + SPR_TVWW, // WhirlWind shield + SPR_TVEL, // ELemental shield + SPR_TVSS, // Super Sneakers + SPR_TVIV, // InVincibility + SPR_TV1U, // 1Up + SPR_TV1P, // 1uP (textless) + SPR_TVEG, // EGgman + SPR_TVMX, // MiXup + SPR_TVMY, // MYstery + SPR_TVGV, // GraVity boots + SPR_TVRC, // ReCycler + SPR_TV1K, // 1,000 points (1 K) + SPR_TVTK, // 10,000 points (Ten K) + SPR_TVFL, // FLame shield + SPR_TVBB, // BuBble shield + SPR_TVZP, // Thunder shield (ZaP) // Projectiles SPR_MISL, @@ -364,9 +437,20 @@ typedef enum sprite SPR_FWR4, SPR_BUS1, // GFZ Bush w/ berries SPR_BUS2, // GFZ Bush w/o berries + SPR_BUS3, // GFZ Bush w/ BLUE berries + // Trees (both GFZ and misc) + SPR_TRE1, // GFZ + SPR_TRE2, // Checker + SPR_TRE3, // Frozen Hillside + SPR_TRE4, // Polygon + SPR_TRE5, // Bush tree + SPR_TRE6, // Spring tree // Techno Hill Scenery - SPR_THZP, // Techno Hill Zone Plant + SPR_THZP, // THZ1 Steam Flower + SPR_FWR5, // THZ1 Spin flower (red) + SPR_FWR6, // THZ1 Spin flower (yellow) + SPR_THZT, // Steam Whistle tree/bush SPR_ALRM, // THZ2 Alarm // Deep Sea Scenery @@ -377,6 +461,9 @@ typedef enum sprite SPR_CRL2, // Coral 2 SPR_CRL3, // Coral 3 SPR_BCRY, // Blue Crystal + SPR_KELP, // Kelp + SPR_DSTG, // DSZ Stalagmites + SPR_LIBE, // DSZ Light beam // Castle Eggman Scenery SPR_CHAN, // CEZ Chain @@ -386,11 +473,41 @@ typedef enum sprite SPR_BMCH, // Big Mace Chain SPR_SMCE, // Small Mace SPR_BMCE, // Big Mace + SPR_YSPB, // Yellow spring on a ball + SPR_RSPB, // Red spring on a ball + SPR_SFBR, // Small Firebar + SPR_BFBR, // Big Firebar + SPR_BANR, // Banner/pole + SPR_PINE, // Pine Tree + SPR_CEZB, // Bush + SPR_CNDL, // Candle/pricket + SPR_FLMH, // Flame holder + SPR_CTRC, // Fire torch + SPR_CFLG, // Waving flag/segment + SPR_CSTA, // Crawla statue + SPR_CBBS, // Facestabber statue + SPR_CABR, // Brambles // Arid Canyon Scenery SPR_BTBL, // Big tumbleweed SPR_STBL, // Small tumbleweed SPR_CACT, // Cacti sprites + SPR_WWSG, // Caution Sign + SPR_WWS2, // Cacti Sign + SPR_WWS3, // Sharp Turn Sign + SPR_OILL, // Oil lamp + SPR_OILF, // Oil lamp flare + SPR_BARR, // TNT barrel + SPR_REMT, // TNT proximity shell + SPR_TAZD, // Dust devil + SPR_ADST, // Arid dust + SPR_MCRT, // Minecart + SPR_MCSP, // Minecart spark + SPR_NON2, // Saloon door thinker + SPR_SALD, // Saloon door + SPR_TRAE, // Train cameo locomotive + SPR_TRAI, // Train cameo wagon + SPR_STEA, // Train steam // Red Volcano Scenery SPR_FLME, // Flame jet @@ -401,15 +518,30 @@ typedef enum sprite // Egg Rock Scenery // Christmas Scenery - SPR_XMS1, - SPR_XMS2, - SPR_XMS3, + SPR_XMS1, // Christmas Pole + SPR_XMS2, // Candy Cane + SPR_XMS3, // Snowman + SPR_XMS4, // Lamppost + SPR_XMS5, // Hanging Star + SPR_FHZI, // FHZ Ice + + // Halloween Scenery + SPR_PUMK, // Pumpkins + SPR_HHPL, // Dr Seuss Trees + SPR_SHRM, // Mushroom + SPR_HHZM, // Misc // Botanic Serenity Scenery SPR_BSZ1, // Tall flowers SPR_BSZ2, // Medium flowers SPR_BSZ3, // Small flowers - SPR_BSZ4, // Tulip + //SPR_BSZ4, -- Tulips + SPR_BST1, // Red tulip + SPR_BST2, // Purple tulip + SPR_BST3, // Blue tulip + SPR_BST4, // Cyan tulip + SPR_BST5, // Yellow tulip + SPR_BST6, // Orange tulip SPR_BSZ5, // Cluster of Tulips SPR_BSZ6, // Bush SPR_BSZ7, // Vine @@ -426,28 +558,52 @@ typedef enum sprite SPR_ARMB, // Armageddon Shield Ring, Back SPR_WIND, // Whirlwind Shield Orb SPR_MAGN, // Attract Shield Orb - SPR_ELEM, // Elemental Shield Orb and Fire + SPR_ELEM, // Elemental Shield Orb SPR_FORC, // Force Shield Orb SPR_PITY, // Pity Shield Orb + SPR_FIRS, // Flame Shield Orb + SPR_BUBS, // Bubble Shield Orb + SPR_ZAPS, // Thunder Shield Orb SPR_IVSP, // invincibility sparkles SPR_SSPK, // Super Sonic Spark SPR_GOAL, // Special Stage goal (here because lol NiGHTS) - // Freed Animals - SPR_BIRD, // Birdie freed! - SPR_BUNY, // Bunny freed! - SPR_MOUS, // Mouse - SPR_CHIC, // Chicken - SPR_COWZ, // Cow - SPR_RBRD, // Red Birdie in Bubble + // Flickies + SPR_FBUB, // Flicky-sized bubble + SPR_FL01, // Bluebird + SPR_FL02, // Rabbit + SPR_FL03, // Chicken + SPR_FL04, // Seal + SPR_FL05, // Pig + SPR_FL06, // Chipmunk + SPR_FL07, // Penguin + SPR_FL08, // Fish + SPR_FL09, // Ram + SPR_FL10, // Puffin + SPR_FL11, // Cow + SPR_FL12, // Rat + SPR_FL13, // Bear + SPR_FL14, // Dove + SPR_FL15, // Cat + SPR_FL16, // Canary + SPR_FS01, // Spider + SPR_FS02, // Bat // Springs - SPR_SPRY, // yellow spring - SPR_SPRR, // red spring - SPR_SPRB, // Blue springs + SPR_FANS, // Fan + SPR_STEM, // Steam riser + SPR_BUMP, // Bumpers + SPR_BLON, // Balloons + SPR_SPRY, // Yellow spring + SPR_SPRR, // Red spring + SPR_SPRB, // Blue spring SPR_YSPR, // Yellow Diagonal Spring SPR_RSPR, // Red Diagonal Spring + SPR_BSPR, // Blue Diagonal Spring + SPR_SSWY, // Yellow Side Spring + SPR_SSWR, // Red Side Spring + SPR_SSWB, // Blue Side Spring // Environmental Effects SPR_RAIN, // Rain @@ -455,11 +611,10 @@ typedef enum sprite SPR_SPLH, // Water Splish SPR_SPLA, // Water Splash SPR_SMOK, - SPR_BUBP, // Small bubble - SPR_BUBO, // Medium bubble - SPR_BUBN, // Large bubble - SPR_BUBM, // Extra Large (would you like fries with that?) bubble - SPR_POPP, // Extra Large bubble goes POP! + SPR_BUBL, // Bubble + SPR_WZAP, + SPR_DUST, // Spindash dust + SPR_FPRT, // Spindash dust (flame) SPR_TFOG, // Teleport Fog SPR_SEED, // Sonic CD flower seed SPR_PRTL, // Particle (for fans, etc.) @@ -467,9 +622,12 @@ typedef enum sprite // Game Indicators SPR_SCOR, // Score logo SPR_DRWN, // Drowning Timer + SPR_LCKN, // Target SPR_TTAG, // Tag Sign SPR_GFLG, // Got Flag sign + SPR_CORK, + // Ring Weapons SPR_RRNG, // Red Ring SPR_RNGB, // Bounce Ring @@ -510,23 +668,39 @@ typedef enum sprite // NiGHTS Stuff SPR_NDRN, // NiGHTS drone - SPR_SUPE, // NiGHTS character flying - SPR_SUPZ, // NiGHTS hurt - SPR_NDRL, // NiGHTS character drilling SPR_NSPK, // NiGHTS sparkle SPR_NBMP, // NiGHTS Bumper SPR_HOOP, // NiGHTS hoop sprite SPR_NSCR, // NiGHTS score sprite SPR_NPRU, // Nights Powerups SPR_CAPS, // Capsule thingy for NiGHTS - SPR_SUPT, // Super Sonic Transformation (NiGHTS) + SPR_IDYA, // Ideya + SPR_NTPN, // Nightopian + SPR_SHLP, // Shleep + + // Secret badniks and hazards, shhhh + SPR_PENG, + SPR_POPH, + SPR_HIVE, + SPR_BUMB, + SPR_BBUZ, + SPR_FMCE, + SPR_HMCE, + SPR_CACO, + SPR_BAL2, + SPR_SBOB, + SPR_SBFL, + SPR_SBSK, + SPR_HBAT, // Debris - SPR_SPRK, // spark + SPR_SPRK, // Sparkle SPR_BOM1, // Robot Explosion SPR_BOM2, // Boss Explosion 1 SPR_BOM3, // Boss Explosion 2 SPR_BOM4, // Underwater Explosion + SPR_BMNB, // Mine Explosion + SPR_WDDB, // Wood Debris // Crumbly rocks SPR_ROIA, @@ -546,35 +720,121 @@ typedef enum sprite SPR_ROIO, SPR_ROIP, - // Blue Spheres - SPR_BBAL, - // Gravity Well Objects SPR_GWLG, SPR_GWLR, - // SRB1 Sprites - SPR_SRBA, - SPR_SRBB, - SPR_SRBC, - SPR_SRBD, - SPR_SRBE, - SPR_SRBF, - SPR_SRBG, - SPR_SRBH, - SPR_SRBI, - SPR_SRBJ, - SPR_SRBK, - SPR_SRBL, - SPR_SRBM, - SPR_SRBN, - SPR_SRBO, - SPR_FIRSTFREESLOT, SPR_LASTFREESLOT = SPR_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1, NUMSPRITES } spritenum_t; +// Make sure to be conscious of FF_FRAMEMASK and the fact sprite2 is stored as a UINT8 whenever you change this table. +// Currently, FF_FRAMEMASK is 0xff, or 255 - but the second half is used by FF_SPR2SUPER, so the limitation is 0x7f. +// Since this is zero-based, there can be at most 128 different SPR2_'s without changing that. +typedef enum playersprite +{ + SPR2_STND = 0, + SPR2_WAIT, + SPR2_WALK, + SPR2_SKID, + SPR2_RUN , + SPR2_DASH, + SPR2_PAIN, + SPR2_STUN, + SPR2_DEAD, + SPR2_DRWN, // drown + SPR2_ROLL, + SPR2_GASP, + SPR2_JUMP, + SPR2_SPNG, // spring + SPR2_FALL, + SPR2_EDGE, + SPR2_RIDE, + + SPR2_SPIN, // spindash + + SPR2_FLY , + SPR2_SWIM, + SPR2_TIRE, // tired + + SPR2_GLID, // glide + SPR2_CLNG, // cling + SPR2_CLMB, // climb + + SPR2_FLT , // float + SPR2_FRUN, // float run + + SPR2_BNCE, // bounce + SPR2_BLND, // bounce landing + + SPR2_FIRE, // fire + + SPR2_TWIN, // twinspin + + SPR2_MLEE, // melee + SPR2_MLEL, // melee land + + SPR2_TRNS, // transformation + + SPR2_NSTD, // NiGHTS stand + SPR2_NFLT, // NiGHTS float + SPR2_NSTN, // NiGHTS stun + SPR2_NPUL, // NiGHTS pull + SPR2_NATK, // NiGHTS attack + + // NiGHTS flight + SPR2_NGT0, + SPR2_NGT1, + SPR2_NGT2, + SPR2_NGT3, + SPR2_NGT4, + SPR2_NGT5, + SPR2_NGT6, + SPR2_NGT7, + SPR2_NGT8, + SPR2_NGT9, + SPR2_NGTA, + SPR2_NGTB, + SPR2_NGTC, + + // NiGHTS drill + SPR2_DRL0, + SPR2_DRL1, + SPR2_DRL2, + SPR2_DRL3, + SPR2_DRL4, + SPR2_DRL5, + SPR2_DRL6, + SPR2_DRL7, + SPR2_DRL8, + SPR2_DRL9, + SPR2_DRLA, + SPR2_DRLB, + SPR2_DRLC, + + // c: + SPR2_TAL0, + SPR2_TAL1, + SPR2_TAL2, + SPR2_TAL3, + SPR2_TAL4, + SPR2_TAL5, + SPR2_TAL6, + SPR2_TAL7, + SPR2_TAL8, + SPR2_TAL9, + SPR2_TALA, + SPR2_TALB, + + SPR2_SIGN, // end sign head + SPR2_LIFE, // life monitor icon + + SPR2_FIRSTFREESLOT, + SPR2_LASTFREESLOT = 0x7f, + NUMPLAYERSPRITES +} playersprite_t; + typedef enum state { S_NULL, @@ -592,61 +852,65 @@ typedef enum state // Thok S_THOK, + // Player S_PLAY_STND, - S_PLAY_TAP1, - S_PLAY_TAP2, - S_PLAY_RUN1, - S_PLAY_RUN2, - S_PLAY_RUN3, - S_PLAY_RUN4, - S_PLAY_RUN5, - S_PLAY_RUN6, - S_PLAY_RUN7, - S_PLAY_RUN8, - S_PLAY_SPD1, - S_PLAY_SPD2, - S_PLAY_SPD3, - S_PLAY_SPD4, - S_PLAY_ATK1, - S_PLAY_ATK2, - S_PLAY_ATK3, - S_PLAY_ATK4, - S_PLAY_SPRING, - S_PLAY_FALL1, - S_PLAY_FALL2, - S_PLAY_ABL1, - S_PLAY_ABL2, - S_PLAY_SPC1, - S_PLAY_SPC2, - S_PLAY_SPC3, - S_PLAY_SPC4, - S_PLAY_CLIMB1, - S_PLAY_CLIMB2, - S_PLAY_CLIMB3, - S_PLAY_CLIMB4, - S_PLAY_CLIMB5, - S_PLAY_GASP, + S_PLAY_WAIT, + S_PLAY_WALK, + S_PLAY_SKID, + S_PLAY_RUN, + S_PLAY_DASH, S_PLAY_PAIN, - S_PLAY_DIE, - S_PLAY_TEETER1, - S_PLAY_TEETER2, - S_PLAY_CARRY, - S_PLAY_SUPERSTAND, - S_PLAY_SUPERWALK1, - S_PLAY_SUPERWALK2, - S_PLAY_SUPERFLY1, - S_PLAY_SUPERFLY2, - S_PLAY_SUPERTEETER, - S_PLAY_SUPERHIT, - S_PLAY_SUPERTRANS1, - S_PLAY_SUPERTRANS2, - S_PLAY_SUPERTRANS3, - S_PLAY_SUPERTRANS4, - S_PLAY_SUPERTRANS5, - S_PLAY_SUPERTRANS6, - S_PLAY_SUPERTRANS7, - S_PLAY_SUPERTRANS8, - S_PLAY_SUPERTRANS9, // This has special significance in the code. If you add more frames, search for it and make the appropriate changes. + S_PLAY_STUN, + S_PLAY_DEAD, + S_PLAY_DRWN, + S_PLAY_ROLL, + S_PLAY_GASP, + S_PLAY_JUMP, + S_PLAY_SPRING, + S_PLAY_FALL, + S_PLAY_EDGE, + S_PLAY_RIDE, + + // CA2_SPINDASH + S_PLAY_SPINDASH, + + // CA_FLY/SWIM + S_PLAY_FLY, + S_PLAY_SWIM, + S_PLAY_FLY_TIRED, + + // CA_GLIDEANDCLIMB + S_PLAY_GLIDE, + S_PLAY_CLING, + S_PLAY_CLIMB, + + // CA_FLOAT/CA_SLOWFALL + S_PLAY_FLOAT, + S_PLAY_FLOAT_RUN, + + // CA_BOUNCE + S_PLAY_BOUNCE, + S_PLAY_BOUNCE_LANDING, + + // CA2_GUNSLINGER + S_PLAY_FIRE, + S_PLAY_FIRE_FINISH, + + // CA_TWINSPIN + S_PLAY_TWINSPIN, + + // CA2_MELEE + S_PLAY_MELEE, + S_PLAY_MELEE_FINISH, + S_PLAY_MELEE_LANDING, + + // SF_SUPER + S_PLAY_SUPER_TRANS1, + S_PLAY_SUPER_TRANS2, + S_PLAY_SUPER_TRANS3, + S_PLAY_SUPER_TRANS4, + S_PLAY_SUPER_TRANS5, + S_PLAY_SUPER_TRANS6, // technically the player goes here but it's an infinite tic state S_OBJPLACE_DUMMY, @@ -661,6 +925,61 @@ typedef enum state // Level end sign overlay (uses player sprite) S_PLAY_SIGN, + // NiGHTS character (uses player sprite) + S_PLAY_NIGHTS_TRANS1, + S_PLAY_NIGHTS_TRANS2, + S_PLAY_NIGHTS_TRANS3, + S_PLAY_NIGHTS_TRANS4, + S_PLAY_NIGHTS_TRANS5, + S_PLAY_NIGHTS_TRANS6, + + S_PLAY_NIGHTS_STAND, + S_PLAY_NIGHTS_FLOAT, + S_PLAY_NIGHTS_STUN, + S_PLAY_NIGHTS_PULL, + S_PLAY_NIGHTS_ATTACK, + + S_PLAY_NIGHTS_FLY0, + S_PLAY_NIGHTS_DRILL0, + S_PLAY_NIGHTS_FLY1, + S_PLAY_NIGHTS_DRILL1, + S_PLAY_NIGHTS_FLY2, + S_PLAY_NIGHTS_DRILL2, + S_PLAY_NIGHTS_FLY3, + S_PLAY_NIGHTS_DRILL3, + S_PLAY_NIGHTS_FLY4, + S_PLAY_NIGHTS_DRILL4, + S_PLAY_NIGHTS_FLY5, + S_PLAY_NIGHTS_DRILL5, + S_PLAY_NIGHTS_FLY6, + S_PLAY_NIGHTS_DRILL6, + S_PLAY_NIGHTS_FLY7, + S_PLAY_NIGHTS_DRILL7, + S_PLAY_NIGHTS_FLY8, + S_PLAY_NIGHTS_DRILL8, + S_PLAY_NIGHTS_FLY9, + S_PLAY_NIGHTS_DRILL9, + S_PLAY_NIGHTS_FLYA, + S_PLAY_NIGHTS_DRILLA, + S_PLAY_NIGHTS_FLYB, + S_PLAY_NIGHTS_DRILLB, + S_PLAY_NIGHTS_FLYC, + S_PLAY_NIGHTS_DRILLC, + + // c: + S_TAILSOVERLAY_STAND, + S_TAILSOVERLAY_0DEGREES, + S_TAILSOVERLAY_PLUS30DEGREES, + S_TAILSOVERLAY_PLUS60DEGREES, + S_TAILSOVERLAY_MINUS30DEGREES, + S_TAILSOVERLAY_MINUS60DEGREES, + S_TAILSOVERLAY_RUN, + S_TAILSOVERLAY_FLY, + S_TAILSOVERLAY_TIRE, + S_TAILSOVERLAY_PAIN, + S_TAILSOVERLAY_GASP, + S_TAILSOVERLAY_EDGE, + // Blue Crawla S_POSS_STND, S_POSS_RUN1, @@ -697,10 +1016,6 @@ typedef enum state S_RBUZZFLY1, S_RBUZZFLY2, - // AquaBuzz - S_BBUZZFLY1, - S_BBUZZFLY2, - // Jetty-Syn Bomber S_JETBLOOK1, S_JETBLOOK2, @@ -737,7 +1052,6 @@ typedef enum state S_DETON13, S_DETON14, S_DETON15, - S_DETON16, // Skim Mine Dropper S_SKIM1, @@ -779,14 +1093,40 @@ typedef enum state S_TURRETPOPDOWN7, S_TURRETPOPDOWN8, - // Sharp - S_SHARP_ROAM1, - S_SHARP_ROAM2, - S_SHARP_AIM1, - S_SHARP_AIM2, - S_SHARP_AIM3, - S_SHARP_AIM4, - S_SHARP_SPIN, + // Spincushion + S_SPINCUSHION_LOOK, + S_SPINCUSHION_CHASE1, + S_SPINCUSHION_CHASE2, + S_SPINCUSHION_CHASE3, + S_SPINCUSHION_CHASE4, + S_SPINCUSHION_AIM1, + S_SPINCUSHION_AIM2, + S_SPINCUSHION_AIM3, + S_SPINCUSHION_AIM4, + S_SPINCUSHION_AIM5, + S_SPINCUSHION_SPIN1, + S_SPINCUSHION_SPIN2, + S_SPINCUSHION_SPIN3, + S_SPINCUSHION_SPIN4, + S_SPINCUSHION_STOP1, + S_SPINCUSHION_STOP2, + S_SPINCUSHION_STOP3, + S_SPINCUSHION_STOP4, + + // Crushstacean + S_CRUSHSTACEAN_ROAM1, + S_CRUSHSTACEAN_ROAM2, + S_CRUSHSTACEAN_ROAM3, + S_CRUSHSTACEAN_ROAM4, + S_CRUSHSTACEAN_ROAMPAUSE, + S_CRUSHSTACEAN_PUNCH1, + S_CRUSHSTACEAN_PUNCH2, + S_CRUSHCLAW_AIM, + S_CRUSHCLAW_OUT, + S_CRUSHCLAW_STAY, + S_CRUSHCLAW_IN, + S_CRUSHCLAW_WAIT, + S_CRUSHCHAIN, // Jet Jaw S_JETJAW_ROAM1, @@ -819,15 +1159,10 @@ typedef enum state // Vulture S_VULTURE_STND, - S_VULTURE_VTOL1, - S_VULTURE_VTOL2, - S_VULTURE_VTOL3, - S_VULTURE_VTOL4, + S_VULTURE_DRIFT, S_VULTURE_ZOOM1, S_VULTURE_ZOOM2, - S_VULTURE_ZOOM3, - S_VULTURE_ZOOM4, - S_VULTURE_ZOOM5, + S_VULTURE_STUNNED, // Pointy S_POINTY1, @@ -835,13 +1170,14 @@ typedef enum state // Robo-Hood S_ROBOHOOD_LOOK, - S_ROBOHOOD_STND, - S_ROBOHOOD_SHOOT, - S_ROBOHOOD_JUMP, + S_ROBOHOOD_STAND, + S_ROBOHOOD_FIRE1, + S_ROBOHOOD_FIRE2, + S_ROBOHOOD_JUMP1, S_ROBOHOOD_JUMP2, - S_ROBOHOOD_FALL, + S_ROBOHOOD_JUMP3, - // CastleBot FaceStabber + // Castlebot Facestabber S_FACESTABBER_STND1, S_FACESTABBER_STND2, S_FACESTABBER_STND3, @@ -852,6 +1188,11 @@ typedef enum state S_FACESTABBER_CHARGE2, S_FACESTABBER_CHARGE3, S_FACESTABBER_CHARGE4, + S_FACESTABBER_PAIN, + S_FACESTABBER_DIE1, + S_FACESTABBER_DIE2, + S_FACESTABBER_DIE3, + S_FACESTABBERSPEAR, // Egg Guard S_EGGGUARD_STND, @@ -869,17 +1210,34 @@ typedef enum state // Egg Shield for Egg Guard S_EGGSHIELD, + S_EGGSHIELDBREAK, // Green Snapper + S_SNAPPER_SPAWN, + S_SNAPPER_SPAWN2, S_GSNAPPER_STND, S_GSNAPPER1, S_GSNAPPER2, S_GSNAPPER3, S_GSNAPPER4, + S_SNAPPER_XPLD, + S_SNAPPER_LEG, + S_SNAPPER_LEGRAISE, + S_SNAPPER_HEAD, // Minus + S_MINUS_INIT, S_MINUS_STND, - S_MINUS_DIGGING, + S_MINUS_DIGGING1, + S_MINUS_DIGGING2, + S_MINUS_DIGGING3, + S_MINUS_DIGGING4, + S_MINUS_BURST0, + S_MINUS_BURST1, + S_MINUS_BURST2, + S_MINUS_BURST3, + S_MINUS_BURST4, + S_MINUS_BURST5, S_MINUS_POPUP, S_MINUS_UPWARD1, S_MINUS_UPWARD2, @@ -898,6 +1256,15 @@ typedef enum state S_MINUS_DOWNWARD7, S_MINUS_DOWNWARD8, + // Minus dirt + S_MINUSDIRT1, + S_MINUSDIRT2, + S_MINUSDIRT3, + S_MINUSDIRT4, + S_MINUSDIRT5, + S_MINUSDIRT6, + S_MINUSDIRT7, + // Spring Shell S_SSHELL_STND, S_SSHELL_RUN1, @@ -925,14 +1292,30 @@ typedef enum state S_UNIDUS_RUN, S_UNIDUS_BALL, + // Canarivore + S_CANARIVORE_LOOK, + S_CANARIVORE_AWAKEN1, + S_CANARIVORE_AWAKEN2, + S_CANARIVORE_AWAKEN3, + S_CANARIVORE_GAS1, + S_CANARIVORE_GAS2, + S_CANARIVORE_GAS3, + S_CANARIVORE_GAS4, + S_CANARIVORE_GAS5, + S_CANARIVORE_GASREPEAT, + S_CANARIVORE_CLOSE1, + S_CANARIVORE_CLOSE2, + S_CANARIVOREGAS_1, + S_CANARIVOREGAS_2, + S_CANARIVOREGAS_3, + S_CANARIVOREGAS_4, + S_CANARIVOREGAS_5, + S_CANARIVOREGAS_6, + S_CANARIVOREGAS_7, + S_CANARIVOREGAS_8, + // Boss Explosion - S_BPLD1, - S_BPLD2, - S_BPLD3, - S_BPLD4, - S_BPLD5, - S_BPLD6, - S_BPLD7, + S_BOSSEXPLODE, // S3&K Boss Explosion S_SONIC3KBOSSEXPLOSION1, @@ -1034,6 +1417,7 @@ typedef enum state S_GOOP1, S_GOOP2, S_GOOP3, + S_GOOPTRAIL, // Boss 3 S_EGGMOBILE3_STND, @@ -1152,6 +1536,96 @@ typedef enum state S_JETFLAME1, S_JETFLAME2, + // Boss 5 + S_FANG_IDLE1, + S_FANG_IDLE2, + S_FANG_IDLE3, + S_FANG_IDLE4, + S_FANG_IDLE5, + S_FANG_IDLE6, + S_FANG_IDLE7, + S_FANG_IDLE8, + S_FANG_PAIN1, + S_FANG_PAIN2, + S_FANG_PATHINGSTART1, + S_FANG_PATHINGSTART2, + S_FANG_PATHING, + S_FANG_BOUNCE1, + S_FANG_BOUNCE2, + S_FANG_BOUNCE3, + S_FANG_BOUNCE4, + S_FANG_FALL1, + S_FANG_FALL2, + S_FANG_CHECKPATH1, + S_FANG_CHECKPATH2, + S_FANG_PATHINGCONT1, + S_FANG_PATHINGCONT2, + S_FANG_PATHINGCONT3, + S_FANG_SKID1, + S_FANG_SKID2, + S_FANG_SKID3, + S_FANG_CHOOSEATTACK, + S_FANG_FIRESTART1, + S_FANG_FIRESTART2, + S_FANG_FIRE1, + S_FANG_FIRE2, + S_FANG_FIRE3, + S_FANG_FIRE4, + S_FANG_FIREREPEAT, + S_FANG_LOBSHOT1, + S_FANG_LOBSHOT2, + S_FANG_WAIT1, + S_FANG_WAIT2, + S_FANG_WALLHIT, + S_FANG_PINCHPATHINGSTART1, + S_FANG_PINCHPATHINGSTART2, + S_FANG_PINCHPATHING, + S_FANG_PINCHBOUNCE1, + S_FANG_PINCHBOUNCE2, + S_FANG_PINCHBOUNCE3, + S_FANG_PINCHBOUNCE4, + S_FANG_PINCHFALL1, + S_FANG_PINCHFALL2, + S_FANG_PINCHSKID1, + S_FANG_PINCHSKID2, + S_FANG_PINCHLOBSHOT1, + S_FANG_PINCHLOBSHOT2, + S_FANG_PINCHLOBSHOT3, + S_FANG_PINCHLOBSHOT4, + S_FANG_DIE1, + S_FANG_DIE2, + S_FANG_DIE3, + S_FANG_DIE4, + S_FANG_DIE5, + S_FANG_DIE6, + S_FANG_DIE7, + S_FANG_DIE8, + S_FANG_FLEEPATHING1, + S_FANG_FLEEPATHING2, + S_FANG_FLEEBOUNCE1, + S_FANG_FLEEBOUNCE2, + S_FANG_KO, + + S_FBOMB1, + S_FBOMB2, + S_FBOMB_EXPL1, + S_FBOMB_EXPL2, + S_FBOMB_EXPL3, + S_FBOMB_EXPL4, + S_FBOMB_EXPL5, + S_FBOMB_EXPL6, + S_TNTDUST_1, + S_TNTDUST_2, + S_TNTDUST_3, + S_TNTDUST_4, + S_TNTDUST_5, + S_TNTDUST_6, + S_TNTDUST_7, + S_TNTDUST_8, + S_FSGNA, + S_FSGNB, + S_FSGNC, + // Black Eggman (Boss 7) S_BLACKEGG_STND, S_BLACKEGG_STND2, @@ -1388,7 +1862,7 @@ typedef enum state // S_PLAY_TAP1 S_METALSONIC_WAIT1, S_METALSONIC_WAIT2, - // S_PLAY_RUN1 + // S_PLAY_WALK S_METALSONIC_WALK1, S_METALSONIC_WALK2, S_METALSONIC_WALK3, @@ -1406,11 +1880,11 @@ typedef enum state S_METALSONIC_FLOAT, S_METALSONIC_VECTOR, S_METALSONIC_STUN, - S_METALSONIC_BLOCK, S_METALSONIC_RAISE, S_METALSONIC_GATHER, S_METALSONIC_DASH, S_METALSONIC_BOUNCE, + S_METALSONIC_BADBOUNCE, S_METALSONIC_SHOOT, S_METALSONIC_PAIN, S_METALSONIC_DEATH, @@ -1436,27 +1910,33 @@ typedef enum state S_RING, // Blue Sphere for special stages - S_BLUEBALL, - S_BLUEBALLSPARK, + S_BLUESPHERE, + S_BLUESPHEREBONUS, + S_BLUESPHERESPARK, + + // Bomb Sphere + S_BOMBSPHERE1, + S_BOMBSPHERE2, + S_BOMBSPHERE3, + S_BOMBSPHERE4, + + // NiGHTS Chip + S_NIGHTSCHIP, + S_NIGHTSCHIPBONUS, + + // NiGHTS Star + S_NIGHTSSTAR, + S_NIGHTSSTARXMAS, // Gravity Wells for special stages S_GRAVWELLGREEN, - S_GRAVWELLGREEN2, - S_GRAVWELLGREEN3, - S_GRAVWELLRED, - S_GRAVWELLRED2, - S_GRAVWELLRED3, // Individual Team Rings S_TEAMRING, - // Special Stage Token - S_EMMY, - // Special Stage Token S_TOKEN, - S_MOVINGTOKEN, // CTF Flags S_REDFLAG, @@ -1499,18 +1979,16 @@ typedef enum state S_CEMG6, S_CEMG7, - // Emeralds (for hunt) - S_EMER1, - - S_FAN, - S_FAN2, - S_FAN3, - S_FAN4, - S_FAN5, + // Emerald hunt shards + S_SHRD1, + S_SHRD2, + S_SHRD3, // Bubble Source S_BUBBLES1, S_BUBBLES2, + S_BUBBLES3, + S_BUBBLES4, // Level End Sign S_SIGN1, @@ -1567,16 +2045,6 @@ typedef enum state S_SIGN52, // Eggman S_SIGN53, - // Steam Riser - S_STEAM1, - S_STEAM2, - S_STEAM3, - S_STEAM4, - S_STEAM5, - S_STEAM6, - S_STEAM7, - S_STEAM8, - // Spike Ball S_SPIKEBALL1, S_SPIKEBALL2, @@ -1587,7 +2055,7 @@ typedef enum state S_SPIKEBALL7, S_SPIKEBALL8, - // Fire Shield's Spawn + // Elemental Shield's Spawn S_SPINFIRE1, S_SPINFIRE2, S_SPINFIRE3, @@ -1605,190 +2073,169 @@ typedef enum state S_SPIKED1, S_SPIKED2, + // Wall spikes + S_WALLSPIKE1, + S_WALLSPIKE2, + S_WALLSPIKE3, + S_WALLSPIKE4, + S_WALLSPIKE5, + S_WALLSPIKE6, + S_WALLSPIKEBASE, + S_WALLSPIKED1, + S_WALLSPIKED2, + // Starpost S_STARPOST_IDLE, S_STARPOST_FLASH, + S_STARPOST_STARTSPIN, S_STARPOST_SPIN, + S_STARPOST_ENDSPIN, // Big floating mine - S_BIGMINE1, - S_BIGMINE2, - S_BIGMINE3, - S_BIGMINE4, - S_BIGMINE5, - S_BIGMINE6, - S_BIGMINE7, - S_BIGMINE8, + S_BIGMINE_IDLE, + S_BIGMINE_ALERT1, + S_BIGMINE_ALERT2, + S_BIGMINE_ALERT3, + S_BIGMINE_SET1, + S_BIGMINE_SET2, + S_BIGMINE_SET3, + S_BIGMINE_BLAST1, + S_BIGMINE_BLAST2, + S_BIGMINE_BLAST3, + S_BIGMINE_BLAST4, + S_BIGMINE_BLAST5, // Cannon Launcher S_CANNONLAUNCHER1, S_CANNONLAUNCHER2, S_CANNONLAUNCHER3, - // Super Ring Box - S_SUPERRINGBOX, - S_SUPERRINGBOX1, - S_SUPERRINGBOX2, - S_SUPERRINGBOX3, - S_SUPERRINGBOX4, - S_SUPERRINGBOX5, - S_SUPERRINGBOX6, - - // Red Team Ring Box - S_REDRINGBOX, - S_REDRINGBOX1, - - // Blue Team Ring Box - S_BLUERINGBOX, - S_BLUERINGBOX1, - - // Super Sneakers Box - S_SHTV, - S_SHTV1, - S_SHTV2, - S_SHTV3, - S_SHTV4, - S_SHTV5, - S_SHTV6, - - // Invincibility Box - S_PINV, - S_PINV1, - S_PINV2, - S_PINV3, - S_PINV4, - S_PINV5, - S_PINV6, - - // 1up Box - S_PRUP, - S_PRUP1, - S_PRUP2, - S_PRUP3, - S_PRUP4, - S_PRUP5, - S_PRUP6, - - // Ring Shield Box - S_YLTV, - S_YLTV1, - S_YLTV2, - S_YLTV3, - S_YLTV4, - S_YLTV5, - S_YLTV6, - - // Force Shield Box - S_BLTV1, - S_BLTV2, - S_BLTV3, - S_BLTV4, - S_BLTV5, - S_BLTV6, - S_BLTV7, - - // Bomb Shield Box - S_BKTV1, - S_BKTV2, - S_BKTV3, - S_BKTV4, - S_BKTV5, - S_BKTV6, - S_BKTV7, - - // Jump Shield Box - S_WHTV1, - S_WHTV2, - S_WHTV3, - S_WHTV4, - S_WHTV5, - S_WHTV6, - S_WHTV7, - - // Water Shield Box - S_GRTV, - S_GRTV1, - S_GRTV2, - S_GRTV3, - S_GRTV4, - S_GRTV5, - S_GRTV6, - - // Pity Shield Box - S_PITV1, - S_PITV2, - S_PITV3, - S_PITV4, - S_PITV5, - S_PITV6, - S_PITV7, - - // Eggman Box - S_EGGTV1, - S_EGGTV2, - S_EGGTV3, - S_EGGTV4, - S_EGGTV5, - S_EGGTV6, - S_EGGTV7, - - // Teleport Box - S_MIXUPBOX1, - S_MIXUPBOX2, - S_MIXUPBOX3, - S_MIXUPBOX4, - S_MIXUPBOX5, - S_MIXUPBOX6, - S_MIXUPBOX7, - - // Recycler Box - S_RECYCLETV1, - S_RECYCLETV2, - S_RECYCLETV3, - S_RECYCLETV4, - S_RECYCLETV5, - S_RECYCLETV6, - S_RECYCLETV7, - - // Question Box - S_RANDOMBOX1, - S_RANDOMBOX2, - S_RANDOMBOX3, - - // Gravity Boots Box - S_GBTV1, - S_GBTV2, - S_GBTV3, - S_GBTV4, - S_GBTV5, - S_GBTV6, - S_GBTV7, - - // Score boxes - S_SCORETVA1, - S_SCORETVA2, - S_SCORETVA3, - S_SCORETVA4, - S_SCORETVA5, - S_SCORETVA6, - S_SCORETVA7, - S_SCORETVB1, - S_SCORETVB2, - S_SCORETVB3, - S_SCORETVB4, - S_SCORETVB5, - S_SCORETVB6, - S_SCORETVB7, - - // Monitor Explosion - S_MONITOREXPLOSION1, - S_MONITOREXPLOSION2, - - S_REDMONITOREXPLOSION1, - S_REDMONITOREXPLOSION2, - - S_BLUEMONITOREXPLOSION1, - S_BLUEMONITOREXPLOSION2, + // Monitor Miscellany + S_BOXSPARKLE1, + S_BOXSPARKLE2, + S_BOXSPARKLE3, + S_BOXSPARKLE4, + + S_BOX_FLICKER, + S_BOX_POP1, + S_BOX_POP2, + + S_GOLDBOX_FLICKER, + S_GOLDBOX_OFF1, + S_GOLDBOX_OFF2, + S_GOLDBOX_OFF3, + S_GOLDBOX_OFF4, + S_GOLDBOX_OFF5, + S_GOLDBOX_OFF6, + S_GOLDBOX_OFF7, + + // Monitor States (one per box) + S_MYSTERY_BOX, + S_RING_BOX, + S_PITY_BOX, + S_ATTRACT_BOX, + S_FORCE_BOX, + S_ARMAGEDDON_BOX, + S_WHIRLWIND_BOX, + S_ELEMENTAL_BOX, + S_SNEAKERS_BOX, + S_INVULN_BOX, + S_1UP_BOX, + S_EGGMAN_BOX, + S_MIXUP_BOX, + S_GRAVITY_BOX, + S_RECYCLER_BOX, + S_SCORE1K_BOX, + S_SCORE10K_BOX, + S_FLAMEAURA_BOX, + S_BUBBLEWRAP_BOX, + S_THUNDERCOIN_BOX, + + // Gold Repeat Monitor States (one per box) + S_PITY_GOLDBOX, + S_ATTRACT_GOLDBOX, + S_FORCE_GOLDBOX, + S_ARMAGEDDON_GOLDBOX, + S_WHIRLWIND_GOLDBOX, + S_ELEMENTAL_GOLDBOX, + S_SNEAKERS_GOLDBOX, + S_INVULN_GOLDBOX, + S_EGGMAN_GOLDBOX, + S_GRAVITY_GOLDBOX, + S_FLAMEAURA_GOLDBOX, + S_BUBBLEWRAP_GOLDBOX, + S_THUNDERCOIN_GOLDBOX, + + // Team Ring Boxes (these are special) + S_RING_REDBOX1, + S_RING_REDBOX2, + S_REDBOX_POP1, + S_REDBOX_POP2, + + S_RING_BLUEBOX1, + S_RING_BLUEBOX2, + S_BLUEBOX_POP1, + S_BLUEBOX_POP2, + + // Box Icons -- 2 states each, animation and action + S_RING_ICON1, + S_RING_ICON2, + + S_PITY_ICON1, + S_PITY_ICON2, + + S_ATTRACT_ICON1, + S_ATTRACT_ICON2, + + S_FORCE_ICON1, + S_FORCE_ICON2, + + S_ARMAGEDDON_ICON1, + S_ARMAGEDDON_ICON2, + + S_WHIRLWIND_ICON1, + S_WHIRLWIND_ICON2, + + S_ELEMENTAL_ICON1, + S_ELEMENTAL_ICON2, + + S_SNEAKERS_ICON1, + S_SNEAKERS_ICON2, + + S_INVULN_ICON1, + S_INVULN_ICON2, + + S_1UP_ICON1, + S_1UP_ICON2, + + S_EGGMAN_ICON1, + S_EGGMAN_ICON2, + + S_MIXUP_ICON1, + S_MIXUP_ICON2, + + S_GRAVITY_ICON1, + S_GRAVITY_ICON2, + + S_RECYCLER_ICON1, + S_RECYCLER_ICON2, + + S_SCORE1K_ICON1, + S_SCORE1K_ICON2, + + S_SCORE10K_ICON1, + S_SCORE10K_ICON2, + + S_FLAMEAURA_ICON1, + S_FLAMEAURA_ICON2, + + S_BUBBLEWRAP_ICON1, + S_BUBBLEWRAP_ICON2, + + S_THUNDERCOIN_ICON1, + S_THUNDERCOIN_ICON2, + + // --- S_ROCKET, @@ -1819,39 +2266,60 @@ typedef enum state // Arrow S_ARROW, - S_ARROWUP, - S_ARROWDOWN, + S_ARROWBONK, // Trapgoyle Demon fire - S_DEMONFIRE1, - S_DEMONFIRE2, - S_DEMONFIRE3, - S_DEMONFIRE4, - S_DEMONFIRE5, - S_DEMONFIRE6, + S_DEMONFIRE, + // GFZ flowers S_GFZFLOWERA, - S_GFZFLOWERA2, - - S_GFZFLOWERB1, - S_GFZFLOWERB2, - - S_GFZFLOWERC1, + S_GFZFLOWERB, + S_GFZFLOWERC, + S_BLUEBERRYBUSH, S_BERRYBUSH, S_BUSH, - // THZ Plant - S_THZPLANT1, - S_THZPLANT2, - S_THZPLANT3, - S_THZPLANT4, + // Trees (both GFZ and misc) + S_GFZTREE, + S_GFZBERRYTREE, + S_GFZCHERRYTREE, + S_CHECKERTREE, + S_CHECKERSUNSETTREE, + S_FHZTREE, // Frozen Hillside + S_FHZPINKTREE, + S_POLYGONTREE, + S_BUSHTREE, + S_BUSHREDTREE, + S_SPRINGTREE, + + // THZ flowers + S_THZFLOWERA, // THZ1 Steam flower + S_THZFLOWERB, // THZ1 Spin flower (red) + S_THZFLOWERC, // THZ1 Spin flower (yellow) + + // THZ Steam Whistle tree/bush + S_THZTREE, + S_THZTREEBRANCH1, + S_THZTREEBRANCH2, + S_THZTREEBRANCH3, + S_THZTREEBRANCH4, + S_THZTREEBRANCH5, + S_THZTREEBRANCH6, + S_THZTREEBRANCH7, + S_THZTREEBRANCH8, + S_THZTREEBRANCH9, + S_THZTREEBRANCH10, + S_THZTREEBRANCH11, + S_THZTREEBRANCH12, + S_THZTREEBRANCH13, // THZ Alarm S_ALARM1, // Deep Sea Gargoyle S_GARGOYLE, + S_BIGGARGOYLE, // DSZ Seaweed S_SEAWEED1, @@ -1882,14 +2350,34 @@ typedef enum state // Blue Crystal S_BLUECRYSTAL1, + // Kelp, + S_KELP, + + // DSZ Stalagmites + S_DSZSTALAGMITE, + S_DSZ2STALAGMITE, + + // DSZ Light beam + S_LIGHTBEAM1, + S_LIGHTBEAM2, + S_LIGHTBEAM3, + S_LIGHTBEAM4, + S_LIGHTBEAM5, + S_LIGHTBEAM6, + S_LIGHTBEAM7, + S_LIGHTBEAM8, + S_LIGHTBEAM9, + S_LIGHTBEAM10, + S_LIGHTBEAM11, + S_LIGHTBEAM12, + // CEZ Chain S_CEZCHAIN, // Flame - S_FLAME1, - S_FLAME2, - S_FLAME3, - S_FLAME4, + S_FLAME, + S_FLAMEPARTICLE, + S_FLAMEREST, // Eggman Statue S_EGGSTATUE1, @@ -1898,19 +2386,82 @@ typedef enum state S_SLING1, S_SLING2, - // CEZ Small Mace Chain + // CEZ maces and chains S_SMALLMACECHAIN, - - // CEZ Big Mace Chain S_BIGMACECHAIN, - - // CEZ Small Mace S_SMALLMACE, - - // CEZ Big Mace S_BIGMACE, - - S_CEZFLOWER1, + S_SMALLGRABCHAIN, + S_BIGGRABCHAIN, + + // Yellow spring on a ball + S_YELLOWSPRINGBALL, + S_YELLOWSPRINGBALL2, + S_YELLOWSPRINGBALL3, + S_YELLOWSPRINGBALL4, + S_YELLOWSPRINGBALL5, + + // Red spring on a ball + S_REDSPRINGBALL, + S_REDSPRINGBALL2, + S_REDSPRINGBALL3, + S_REDSPRINGBALL4, + S_REDSPRINGBALL5, + + // Small Firebar + S_SMALLFIREBAR1, + S_SMALLFIREBAR2, + S_SMALLFIREBAR3, + S_SMALLFIREBAR4, + S_SMALLFIREBAR5, + S_SMALLFIREBAR6, + S_SMALLFIREBAR7, + S_SMALLFIREBAR8, + S_SMALLFIREBAR9, + S_SMALLFIREBAR10, + S_SMALLFIREBAR11, + S_SMALLFIREBAR12, + S_SMALLFIREBAR13, + S_SMALLFIREBAR14, + S_SMALLFIREBAR15, + S_SMALLFIREBAR16, + + // Big Firebar + S_BIGFIREBAR1, + S_BIGFIREBAR2, + S_BIGFIREBAR3, + S_BIGFIREBAR4, + S_BIGFIREBAR5, + S_BIGFIREBAR6, + S_BIGFIREBAR7, + S_BIGFIREBAR8, + S_BIGFIREBAR9, + S_BIGFIREBAR10, + S_BIGFIREBAR11, + S_BIGFIREBAR12, + S_BIGFIREBAR13, + S_BIGFIREBAR14, + S_BIGFIREBAR15, + S_BIGFIREBAR16, + + S_CEZFLOWER, + S_CEZPOLE, + S_CEZBANNER, + S_PINETREE, + S_CEZBUSH1, + S_CEZBUSH2, + S_CANDLE, + S_CANDLEPRICKET, + S_FLAMEHOLDER, + S_FIRETORCH, + S_WAVINGFLAG, + S_WAVINGFLAGSEG, + S_CRAWLASTATUE, + S_FACESTABBERSTATUE, + S_SUSPICIOUSFACESTABBERSTATUE_WAIT, + S_SUSPICIOUSFACESTABBERSTATUE_BURST1, + S_SUSPICIOUSFACESTABBERSTATUE_BURST2, + S_BRAMBLES, // Big Tumbleweed S_BIGTUMBLEWEED, @@ -1939,6 +2490,95 @@ typedef enum state S_CACTI2, S_CACTI3, S_CACTI4, + S_CACTI5, + S_CACTI6, + S_CACTI7, + S_CACTI8, + S_CACTI9, + + // Warning signs sprites + S_ARIDSIGN_CAUTION, + S_ARIDSIGN_CACTI, + S_ARIDSIGN_SHARPTURN, + + // Oil lamp + S_OILLAMP, + S_OILLAMPFLARE, + + // TNT barrel + S_TNTBARREL_STND1, + S_TNTBARREL_EXPL1, + S_TNTBARREL_EXPL2, + S_TNTBARREL_EXPL3, + S_TNTBARREL_EXPL4, + S_TNTBARREL_EXPL5, + S_TNTBARREL_EXPL6, + S_TNTBARREL_FLYING, + + // TNT proximity shell + S_PROXIMITY_TNT, + S_PROXIMITY_TNT_TRIGGER1, + S_PROXIMITY_TNT_TRIGGER2, + S_PROXIMITY_TNT_TRIGGER3, + S_PROXIMITY_TNT_TRIGGER4, + S_PROXIMITY_TNT_TRIGGER5, + S_PROXIMITY_TNT_TRIGGER6, + S_PROXIMITY_TNT_TRIGGER7, + S_PROXIMITY_TNT_TRIGGER8, + S_PROXIMITY_TNT_TRIGGER9, + S_PROXIMITY_TNT_TRIGGER10, + S_PROXIMITY_TNT_TRIGGER11, + S_PROXIMITY_TNT_TRIGGER12, + S_PROXIMITY_TNT_TRIGGER13, + S_PROXIMITY_TNT_TRIGGER14, + S_PROXIMITY_TNT_TRIGGER15, + S_PROXIMITY_TNT_TRIGGER16, + S_PROXIMITY_TNT_TRIGGER17, + S_PROXIMITY_TNT_TRIGGER18, + S_PROXIMITY_TNT_TRIGGER19, + S_PROXIMITY_TNT_TRIGGER20, + S_PROXIMITY_TNT_TRIGGER21, + S_PROXIMITY_TNT_TRIGGER22, + S_PROXIMITY_TNT_TRIGGER23, + + // Dust devil + S_DUSTDEVIL, + S_DUSTLAYER1, + S_DUSTLAYER2, + S_DUSTLAYER3, + S_DUSTLAYER4, + S_DUSTLAYER5, + S_ARIDDUST1, + S_ARIDDUST2, + S_ARIDDUST3, + + // Minecart + S_MINECART_IDLE, + S_MINECART_DTH1, + S_MINECARTEND, + S_MINECARTSEG_FRONT, + S_MINECARTSEG_BACK, + S_MINECARTSEG_LEFT, + S_MINECARTSEG_RIGHT, + S_MINECARTSIDEMARK1, + S_MINECARTSIDEMARK2, + S_MINECARTSPARK, + + // Saloon door + S_SALOONDOOR, + S_SALOONDOORTHINKER, + + // Train cameo + S_TRAINCAMEOSPAWNER_1, + S_TRAINCAMEOSPAWNER_2, + S_TRAINCAMEOSPAWNER_3, + S_TRAINCAMEOSPAWNER_4, + S_TRAINCAMEOSPAWNER_5, + S_TRAINPUFFMAKER, + + // Train + S_TRAINDUST, + S_TRAINSTEAM, // Flame jet S_FLAMEJETSTND, @@ -1951,36 +2591,13 @@ typedef enum state // Spinning flame jets S_FJSPINAXISA1, // Counter-clockwise S_FJSPINAXISA2, - S_FJSPINAXISA3, - S_FJSPINAXISA4, - S_FJSPINAXISA5, - S_FJSPINAXISA6, - S_FJSPINAXISA7, - S_FJSPINAXISA8, - S_FJSPINAXISA9, - S_FJSPINHELPERA1, - S_FJSPINHELPERA2, - S_FJSPINHELPERA3, S_FJSPINAXISB1, // Clockwise S_FJSPINAXISB2, - S_FJSPINAXISB3, - S_FJSPINAXISB4, - S_FJSPINAXISB5, - S_FJSPINAXISB6, - S_FJSPINAXISB7, - S_FJSPINAXISB8, - S_FJSPINAXISB9, - S_FJSPINHELPERB1, - S_FJSPINHELPERB2, - S_FJSPINHELPERB3, // Blade's flame S_FLAMEJETFLAMEB1, S_FLAMEJETFLAMEB2, S_FLAMEJETFLAMEB3, - S_FLAMEJETFLAMEB4, - S_FLAMEJETFLAMEB5, - S_FLAMEJETFLAMEB6, // Trapgoyles S_TRAPGOYLE, @@ -2028,7 +2645,63 @@ typedef enum state // Xmas-specific stuff S_XMASPOLE, S_CANDYCANE, - S_SNOWMAN, + S_SNOWMAN, // normal + S_SNOWMANHAT, // with hat + scarf + S_LAMPPOST1, // normal + S_LAMPPOST2, // with snow + S_HANGSTAR, + // Xmas GFZ bushes + S_XMASBLUEBERRYBUSH, + S_XMASBERRYBUSH, + S_XMASBUSH, + // FHZ + S_FHZICE1, + S_FHZICE2, + + // Halloween Scenery + // Pumpkins + S_JACKO1, + S_JACKO1OVERLAY_1, + S_JACKO1OVERLAY_2, + S_JACKO1OVERLAY_3, + S_JACKO1OVERLAY_4, + S_JACKO2, + S_JACKO2OVERLAY_1, + S_JACKO2OVERLAY_2, + S_JACKO2OVERLAY_3, + S_JACKO2OVERLAY_4, + S_JACKO3, + S_JACKO3OVERLAY_1, + S_JACKO3OVERLAY_2, + S_JACKO3OVERLAY_3, + S_JACKO3OVERLAY_4, + // Dr Seuss Trees + S_HHZTREE_TOP, + S_HHZTREE_TRUNK, + S_HHZTREE_LEAF, + // Mushroom + S_HHZSHROOM_1, + S_HHZSHROOM_2, + S_HHZSHROOM_3, + S_HHZSHROOM_4, + S_HHZSHROOM_5, + S_HHZSHROOM_6, + S_HHZSHROOM_7, + S_HHZSHROOM_8, + S_HHZSHROOM_9, + S_HHZSHROOM_10, + S_HHZSHROOM_11, + S_HHZSHROOM_12, + S_HHZSHROOM_13, + S_HHZSHROOM_14, + S_HHZSHROOM_15, + S_HHZSHROOM_16, + // Misc + S_HHZGRASS, + S_HHZTENT1, + S_HHZTENT2, + S_HHZSTALAGMITE_TALL, + S_HHZSTALAGMITE_SHORT, // Botanic Serenity's loads of scenery states S_BSZTALLFLOWER_RED, @@ -2075,8 +2748,10 @@ typedef enum state S_BSZVINE_ORANGE, S_BSZSHRUB, S_BSZCLOVER, - S_BSZFISH, - S_BSZSUNFLOWER, + S_BIG_PALMTREE_TRUNK, + S_BIG_PALMTREE_TOP, + S_PALMTREE_TRUNK, + S_PALMTREE_TOP, S_DBALL1, S_DBALL2, @@ -2120,6 +2795,22 @@ typedef enum state S_ARMF14, S_ARMF15, S_ARMF16, + S_ARMF17, + S_ARMF18, + S_ARMF19, + S_ARMF20, + S_ARMF21, + S_ARMF22, + S_ARMF23, + S_ARMF24, + S_ARMF25, + S_ARMF26, + S_ARMF27, + S_ARMF28, + S_ARMF29, + S_ARMF30, + S_ARMF31, + S_ARMF32, S_ARMB1, S_ARMB2, @@ -2137,6 +2828,22 @@ typedef enum state S_ARMB14, S_ARMB15, S_ARMB16, + S_ARMB17, + S_ARMB18, + S_ARMB19, + S_ARMB20, + S_ARMB21, + S_ARMB22, + S_ARMB23, + S_ARMB24, + S_ARMB25, + S_ARMB26, + S_ARMB27, + S_ARMB28, + S_ARMB29, + S_ARMB30, + S_ARMB31, + S_ARMB32, S_WIND1, S_WIND2, @@ -2159,6 +2866,7 @@ typedef enum state S_MAGN10, S_MAGN11, S_MAGN12, + S_MAGN13, S_FORC1, S_FORC2, @@ -2182,6 +2890,8 @@ typedef enum state S_FORC19, S_FORC20, + S_FORC21, + S_ELEM1, S_ELEM2, S_ELEM3, @@ -2195,6 +2905,9 @@ typedef enum state S_ELEM11, S_ELEM12, + S_ELEM13, + S_ELEM14, + S_ELEMF1, S_ELEMF2, S_ELEMF3, @@ -2203,6 +2916,8 @@ typedef enum state S_ELEMF6, S_ELEMF7, S_ELEMF8, + S_ELEMF9, + S_ELEMF10, S_PITY1, S_PITY2, @@ -2210,10 +2925,84 @@ typedef enum state S_PITY4, S_PITY5, S_PITY6, - S_PITY7, - S_PITY8, - S_PITY9, - S_PITY10, + + S_FIRS1, + S_FIRS2, + S_FIRS3, + S_FIRS4, + S_FIRS5, + S_FIRS6, + S_FIRS7, + S_FIRS8, + S_FIRS9, + + S_FIRS10, + S_FIRS11, + + S_FIRSB1, + S_FIRSB2, + S_FIRSB3, + S_FIRSB4, + S_FIRSB5, + S_FIRSB6, + S_FIRSB7, + S_FIRSB8, + S_FIRSB9, + + S_FIRSB10, + + S_BUBS1, + S_BUBS2, + S_BUBS3, + S_BUBS4, + S_BUBS5, + S_BUBS6, + S_BUBS7, + S_BUBS8, + S_BUBS9, + + S_BUBS10, + S_BUBS11, + + S_BUBSB1, + S_BUBSB2, + S_BUBSB3, + S_BUBSB4, + + S_BUBSB5, + S_BUBSB6, + + S_ZAPS1, + S_ZAPS2, + S_ZAPS3, + S_ZAPS4, + S_ZAPS5, + S_ZAPS6, + S_ZAPS7, + S_ZAPS8, + S_ZAPS9, + S_ZAPS10, + S_ZAPS11, + S_ZAPS12, + S_ZAPS13, // blank frame + S_ZAPS14, + S_ZAPS15, + S_ZAPS16, + + S_ZAPSB1, // blank frame + S_ZAPSB2, + S_ZAPSB3, + S_ZAPSB4, + S_ZAPSB5, + S_ZAPSB6, + S_ZAPSB7, + S_ZAPSB8, + S_ZAPSB9, + S_ZAPSB10, + S_ZAPSB11, // blank frame + + //Thunder spark + S_THUNDERCOIN_SPARK, // Invincibility Sparkles S_IVSP, @@ -2225,57 +3014,228 @@ typedef enum state S_SSPK4, S_SSPK5, - // Freed Birdie - S_BIRD1, - S_BIRD2, - S_BIRD3, - - // Freed Bunny - S_BUNNY1, - S_BUNNY2, - S_BUNNY3, - S_BUNNY4, - S_BUNNY5, - S_BUNNY6, - S_BUNNY7, - S_BUNNY8, - S_BUNNY9, - S_BUNNY10, - - // Freed Mouse - S_MOUSE1, - S_MOUSE2, - - // Freed Chicken - S_CHICKEN1, - S_CHICKENHOP, - S_CHICKENFLY1, - S_CHICKENFLY2, - - // Freed Cow - S_COW1, - S_COW2, - S_COW3, - S_COW4, - - // Red Birdie in Bubble - S_RBIRD1, - S_RBIRD2, - S_RBIRD3, + // Flicky-sized bubble + S_FLICKY_BUBBLE, + + // Bluebird + S_FLICKY_01_OUT, + S_FLICKY_01_FLAP1, + S_FLICKY_01_FLAP2, + S_FLICKY_01_FLAP3, + S_FLICKY_01_STAND, + S_FLICKY_01_CENTER, + + // Rabbit + S_FLICKY_02_OUT, + S_FLICKY_02_AIM, + S_FLICKY_02_HOP, + S_FLICKY_02_UP, + S_FLICKY_02_DOWN, + S_FLICKY_02_STAND, + S_FLICKY_02_CENTER, + + // Chicken + S_FLICKY_03_OUT, + S_FLICKY_03_AIM, + S_FLICKY_03_HOP, + S_FLICKY_03_UP, + S_FLICKY_03_FLAP1, + S_FLICKY_03_FLAP2, + S_FLICKY_03_STAND, + S_FLICKY_03_CENTER, + + // Seal + S_FLICKY_04_OUT, + S_FLICKY_04_AIM, + S_FLICKY_04_HOP, + S_FLICKY_04_UP, + S_FLICKY_04_DOWN, + S_FLICKY_04_SWIM1, + S_FLICKY_04_SWIM2, + S_FLICKY_04_SWIM3, + S_FLICKY_04_SWIM4, + S_FLICKY_04_STAND, + S_FLICKY_04_CENTER, + + // Pig + S_FLICKY_05_OUT, + S_FLICKY_05_AIM, + S_FLICKY_05_HOP, + S_FLICKY_05_UP, + S_FLICKY_05_DOWN, + S_FLICKY_05_STAND, + S_FLICKY_05_CENTER, + + // Chipmunk + S_FLICKY_06_OUT, + S_FLICKY_06_AIM, + S_FLICKY_06_HOP, + S_FLICKY_06_UP, + S_FLICKY_06_DOWN, + S_FLICKY_06_STAND, + S_FLICKY_06_CENTER, + + // Penguin + S_FLICKY_07_OUT, + S_FLICKY_07_AIML, + S_FLICKY_07_HOPL, + S_FLICKY_07_UPL, + S_FLICKY_07_DOWNL, + S_FLICKY_07_AIMR, + S_FLICKY_07_HOPR, + S_FLICKY_07_UPR, + S_FLICKY_07_DOWNR, + S_FLICKY_07_SWIM1, + S_FLICKY_07_SWIM2, + S_FLICKY_07_SWIM3, + S_FLICKY_07_STAND, + S_FLICKY_07_CENTER, + + // Fish + S_FLICKY_08_OUT, + S_FLICKY_08_AIM, + S_FLICKY_08_HOP, + S_FLICKY_08_FLAP1, + S_FLICKY_08_FLAP2, + S_FLICKY_08_FLAP3, + S_FLICKY_08_FLAP4, + S_FLICKY_08_SWIM1, + S_FLICKY_08_SWIM2, + S_FLICKY_08_SWIM3, + S_FLICKY_08_SWIM4, + S_FLICKY_08_STAND, + S_FLICKY_08_CENTER, + + // Ram + S_FLICKY_09_OUT, + S_FLICKY_09_AIM, + S_FLICKY_09_HOP, + S_FLICKY_09_UP, + S_FLICKY_09_DOWN, + S_FLICKY_09_STAND, + S_FLICKY_09_CENTER, + + // Puffin + S_FLICKY_10_OUT, + S_FLICKY_10_FLAP1, + S_FLICKY_10_FLAP2, + S_FLICKY_10_STAND, + S_FLICKY_10_CENTER, + + // Cow + S_FLICKY_11_OUT, + S_FLICKY_11_AIM, + S_FLICKY_11_RUN1, + S_FLICKY_11_RUN2, + S_FLICKY_11_RUN3, + S_FLICKY_11_STAND, + S_FLICKY_11_CENTER, + + // Rat + S_FLICKY_12_OUT, + S_FLICKY_12_AIM, + S_FLICKY_12_RUN1, + S_FLICKY_12_RUN2, + S_FLICKY_12_RUN3, + S_FLICKY_12_STAND, + S_FLICKY_12_CENTER, + + // Bear + S_FLICKY_13_OUT, + S_FLICKY_13_AIM, + S_FLICKY_13_HOP, + S_FLICKY_13_UP, + S_FLICKY_13_DOWN, + S_FLICKY_13_STAND, + S_FLICKY_13_CENTER, + + // Dove + S_FLICKY_14_OUT, + S_FLICKY_14_FLAP1, + S_FLICKY_14_FLAP2, + S_FLICKY_14_FLAP3, + S_FLICKY_14_STAND, + S_FLICKY_14_CENTER, + + // Cat + S_FLICKY_15_OUT, + S_FLICKY_15_AIM, + S_FLICKY_15_HOP, + S_FLICKY_15_UP, + S_FLICKY_15_DOWN, + S_FLICKY_15_STAND, + S_FLICKY_15_CENTER, + + // Canary + S_FLICKY_16_OUT, + S_FLICKY_16_FLAP1, + S_FLICKY_16_FLAP2, + S_FLICKY_16_FLAP3, + S_FLICKY_16_STAND, + S_FLICKY_16_CENTER, + + // Spider + S_SECRETFLICKY_01_OUT, + S_SECRETFLICKY_01_AIM, + S_SECRETFLICKY_01_HOP, + S_SECRETFLICKY_01_UP, + S_SECRETFLICKY_01_DOWN, + S_SECRETFLICKY_01_STAND, + S_SECRETFLICKY_01_CENTER, + + // Bat + S_SECRETFLICKY_02_OUT, + S_SECRETFLICKY_02_FLAP1, + S_SECRETFLICKY_02_FLAP2, + S_SECRETFLICKY_02_FLAP3, + S_SECRETFLICKY_02_STAND, + S_SECRETFLICKY_02_CENTER, + + // Fan + S_FAN, + S_FAN2, + S_FAN3, + S_FAN4, + S_FAN5, + // Steam Riser + S_STEAM1, + S_STEAM2, + S_STEAM3, + S_STEAM4, + S_STEAM5, + S_STEAM6, + S_STEAM7, + S_STEAM8, + + // Bumpers + S_BUMPER, + S_BUMPERHIT, + + // Balloons + S_BALLOON, + S_BALLOONPOP1, + S_BALLOONPOP2, + S_BALLOONPOP3, + S_BALLOONPOP4, + S_BALLOONPOP5, + S_BALLOONPOP6, + + // Yellow Spring S_YELLOWSPRING, S_YELLOWSPRING2, S_YELLOWSPRING3, S_YELLOWSPRING4, S_YELLOWSPRING5, + // Red Spring S_REDSPRING, S_REDSPRING2, S_REDSPRING3, S_REDSPRING4, S_REDSPRING5, - // Blue Springs + // Blue Spring S_BLUESPRING, S_BLUESPRING2, S_BLUESPRING3, @@ -2302,6 +3262,46 @@ typedef enum state S_RDIAG7, S_RDIAG8, + // Blue Diagonal Spring + S_BDIAG1, + S_BDIAG2, + S_BDIAG3, + S_BDIAG4, + S_BDIAG5, + S_BDIAG6, + S_BDIAG7, + S_BDIAG8, + + // Yellow Side Spring + S_YHORIZ1, + S_YHORIZ2, + S_YHORIZ3, + S_YHORIZ4, + S_YHORIZ5, + S_YHORIZ6, + S_YHORIZ7, + S_YHORIZ8, + + // Red Side Spring + S_RHORIZ1, + S_RHORIZ2, + S_RHORIZ3, + S_RHORIZ4, + S_RHORIZ5, + S_RHORIZ6, + S_RHORIZ7, + S_RHORIZ8, + + // Blue Side Spring + S_BHORIZ1, + S_BHORIZ2, + S_BHORIZ3, + S_BHORIZ4, + S_BHORIZ5, + S_BHORIZ6, + S_BHORIZ7, + S_BHORIZ8, + // Rain S_RAIN1, S_RAINRETURN, @@ -2336,14 +3336,29 @@ typedef enum state // Bubbles S_SMALLBUBBLE, - S_SMALLBUBBLE1, S_MEDIUMBUBBLE, - S_MEDIUMBUBBLE1, - S_LARGEBUBBLE, + S_LARGEBUBBLE1, + S_LARGEBUBBLE2, S_EXTRALARGEBUBBLE, // breathable S_POP1, // Extra Large bubble goes POP! + S_WATERZAP, + + // Spindash dust + S_SPINDUST1, + S_SPINDUST2, + S_SPINDUST3, + S_SPINDUST4, + S_SPINDUST_BUBBLE1, + S_SPINDUST_BUBBLE2, + S_SPINDUST_BUBBLE3, + S_SPINDUST_BUBBLE4, + S_SPINDUST_FIRE1, + S_SPINDUST_FIRE2, + S_SPINDUST_FIRE3, + S_SPINDUST_FIRE4, + S_FOG1, S_FOG2, S_FOG3, @@ -2362,7 +3377,6 @@ typedef enum state S_SEED, S_PARTICLE, - S_PARTICLEGEN, // Score Logos S_SCRA, // 100 @@ -2376,6 +3390,7 @@ typedef enum state S_SCRI, // 4000 (mario) S_SCRJ, // 8000 (mario) S_SCRK, // 1UP (mario) + S_SCRL, // 10 // Drowning Timer Numbers S_ZERO1, @@ -2385,14 +3400,23 @@ typedef enum state S_FOUR1, S_FIVE1, + S_ZERO2, + S_ONE2, + S_TWO2, + S_THREE2, + S_FOUR2, + S_FIVE2, + + S_LOCKON1, + S_LOCKON2, + // Tag Sign - S_TTAG1, + S_TTAG, // Got Flag Sign - S_GOTFLAG1, - S_GOTFLAG2, - S_GOTFLAG3, - S_GOTFLAG4, + S_GOTFLAG, + + S_CORK, // Red Ring S_RRNG1, @@ -2567,20 +3591,19 @@ typedef enum state S_FIREBALLEXP2, S_FIREBALLEXP3, S_SHELL, - S_SHELL1, - S_SHELL2, - S_SHELL3, - S_SHELL4, - S_PUMA1, - S_PUMA2, - S_PUMA3, - S_PUMA4, - S_PUMA5, - S_PUMA6, - S_HAMMER1, - S_HAMMER2, - S_HAMMER3, - S_HAMMER4, + S_PUMA_START1, + S_PUMA_START2, + S_PUMA_UP1, + S_PUMA_UP2, + S_PUMA_UP3, + S_PUMA_DOWN1, + S_PUMA_DOWN2, + S_PUMA_DOWN3, + S_PUMATRAIL1, + S_PUMATRAIL2, + S_PUMATRAIL3, + S_PUMATRAIL4, + S_HAMMER, S_KOOPA1, S_KOOPA2, S_KOOPAFLAME1, @@ -2594,8 +3617,8 @@ typedef enum state S_TOAD, // Nights-specific stuff - S_NIGHTSDRONE1, - S_NIGHTSDRONE2, + S_NIGHTSDRONE_MAN1, + S_NIGHTSDRONE_MAN2, S_NIGHTSDRONE_SPARKLING1, S_NIGHTSDRONE_SPARKLING2, S_NIGHTSDRONE_SPARKLING3, @@ -2612,97 +3635,10 @@ typedef enum state S_NIGHTSDRONE_SPARKLING14, S_NIGHTSDRONE_SPARKLING15, S_NIGHTSDRONE_SPARKLING16, - S_NIGHTSGOAL1, - S_NIGHTSGOAL2, - S_NIGHTSGOAL3, - S_NIGHTSGOAL4, - - S_NIGHTSFLY1A, - S_NIGHTSFLY1B, - S_NIGHTSDRILL1A, - S_NIGHTSDRILL1B, - S_NIGHTSDRILL1C, - S_NIGHTSDRILL1D, - S_NIGHTSFLY2A, - S_NIGHTSFLY2B, - S_NIGHTSDRILL2A, - S_NIGHTSDRILL2B, - S_NIGHTSDRILL2C, - S_NIGHTSDRILL2D, - S_NIGHTSFLY3A, - S_NIGHTSFLY3B, - S_NIGHTSDRILL3A, - S_NIGHTSDRILL3B, - S_NIGHTSDRILL3C, - S_NIGHTSDRILL3D, - S_NIGHTSFLY4A, - S_NIGHTSFLY4B, - S_NIGHTSDRILL4A, - S_NIGHTSDRILL4B, - S_NIGHTSDRILL4C, - S_NIGHTSDRILL4D, - S_NIGHTSFLY5A, - S_NIGHTSFLY5B, - S_NIGHTSDRILL5A, - S_NIGHTSDRILL5B, - S_NIGHTSDRILL5C, - S_NIGHTSDRILL5D, - S_NIGHTSFLY6A, - S_NIGHTSFLY6B, - S_NIGHTSDRILL6A, - S_NIGHTSDRILL6B, - S_NIGHTSDRILL6C, - S_NIGHTSDRILL6D, - S_NIGHTSFLY7A, - S_NIGHTSFLY7B, - S_NIGHTSDRILL7A, - S_NIGHTSDRILL7B, - S_NIGHTSDRILL7C, - S_NIGHTSDRILL7D, - S_NIGHTSFLY8A, - S_NIGHTSFLY8B, - S_NIGHTSDRILL8A, - S_NIGHTSDRILL8B, - S_NIGHTSDRILL8C, - S_NIGHTSDRILL8D, - S_NIGHTSFLY9A, - S_NIGHTSFLY9B, - S_NIGHTSDRILL9A, - S_NIGHTSDRILL9B, - S_NIGHTSDRILL9C, - S_NIGHTSDRILL9D, - S_NIGHTSHURT1, - S_NIGHTSHURT2, - S_NIGHTSHURT3, - S_NIGHTSHURT4, - S_NIGHTSHURT5, - S_NIGHTSHURT6, - S_NIGHTSHURT7, - S_NIGHTSHURT8, - S_NIGHTSHURT9, - S_NIGHTSHURT10, - S_NIGHTSHURT11, - S_NIGHTSHURT12, - S_NIGHTSHURT13, - S_NIGHTSHURT14, - S_NIGHTSHURT15, - S_NIGHTSHURT16, - S_NIGHTSHURT17, - S_NIGHTSHURT18, - S_NIGHTSHURT19, - S_NIGHTSHURT20, - S_NIGHTSHURT21, - S_NIGHTSHURT22, - S_NIGHTSHURT23, - S_NIGHTSHURT24, - S_NIGHTSHURT25, - S_NIGHTSHURT26, - S_NIGHTSHURT27, - S_NIGHTSHURT28, - S_NIGHTSHURT29, - S_NIGHTSHURT30, - S_NIGHTSHURT31, - S_NIGHTSHURT32, + S_NIGHTSDRONE_GOAL1, + S_NIGHTSDRONE_GOAL2, + S_NIGHTSDRONE_GOAL3, + S_NIGHTSDRONE_GOAL4, S_NIGHTSPARKLE1, S_NIGHTSPARKLE2, @@ -2753,20 +3689,12 @@ typedef enum state S_NIGHTSCORE90_2, S_NIGHTSCORE100_2, - S_NIGHTSWING, - S_NIGHTSWING_XMAS, - // NiGHTS Paraloop Powerups - S_NIGHTSPOWERUP1, - S_NIGHTSPOWERUP2, - S_NIGHTSPOWERUP3, - S_NIGHTSPOWERUP4, - S_NIGHTSPOWERUP5, - S_NIGHTSPOWERUP6, - S_NIGHTSPOWERUP7, - S_NIGHTSPOWERUP8, - S_NIGHTSPOWERUP9, - S_NIGHTSPOWERUP10, + S_NIGHTSSUPERLOOP, + S_NIGHTSDRILLREFILL, + S_NIGHTSHELPER, + S_NIGHTSEXTRATIME, + S_NIGHTSLINKFREEZE, S_EGGCAPSULE, // Orbiting Chaos Emeralds @@ -2778,14 +3706,11 @@ typedef enum state S_ORBITEM6, S_ORBITEM7, S_ORBITEM8, - S_ORBITEM9, - S_ORBITEM10, - S_ORBITEM11, - S_ORBITEM12, - S_ORBITEM13, - S_ORBITEM14, - S_ORBITEM15, - S_ORBITEM16, + S_ORBIDYA1, + S_ORBIDYA2, + S_ORBIDYA3, + S_ORBIDYA4, + S_ORBIDYA5, // "Flicky" helper S_NIGHTOPIANHELPER1, @@ -2796,20 +3721,146 @@ typedef enum state S_NIGHTOPIANHELPER6, S_NIGHTOPIANHELPER7, S_NIGHTOPIANHELPER8, + S_NIGHTOPIANHELPER9, + + // Nightopian + S_PIAN0, + S_PIAN1, + S_PIAN2, + S_PIAN3, + S_PIAN4, + S_PIAN5, + S_PIAN6, + S_PIANSING, + + // Shleep + S_SHLEEP1, + S_SHLEEP2, + S_SHLEEP3, + S_SHLEEP4, + S_SHLEEPBOUNCE1, + S_SHLEEPBOUNCE2, + S_SHLEEPBOUNCE3, + + // Secret badniks and hazards, shhhh + S_PENGUINATOR_LOOK, + S_PENGUINATOR_WADDLE1, + S_PENGUINATOR_WADDLE2, + S_PENGUINATOR_WADDLE3, + S_PENGUINATOR_WADDLE4, + S_PENGUINATOR_SLIDE1, + S_PENGUINATOR_SLIDE2, + S_PENGUINATOR_SLIDE3, + S_PENGUINATOR_SLIDE4, + S_PENGUINATOR_SLIDE5, + + S_POPHAT_LOOK, + S_POPHAT_SHOOT1, + S_POPHAT_SHOOT2, + S_POPHAT_SHOOT3, + + S_HIVEELEMENTAL_LOOK, + S_HIVEELEMENTAL_PREPARE1, + S_HIVEELEMENTAL_PREPARE2, + S_HIVEELEMENTAL_SHOOT1, + S_HIVEELEMENTAL_SHOOT2, + S_HIVEELEMENTAL_DORMANT, + S_HIVEELEMENTAL_PAIN, + S_HIVEELEMENTAL_DIE1, + S_HIVEELEMENTAL_DIE2, + S_HIVEELEMENTAL_DIE3, + + S_BUMBLEBORE_SPAWN, + S_BUMBLEBORE_LOOK1, + S_BUMBLEBORE_LOOK2, + S_BUMBLEBORE_FLY1, + S_BUMBLEBORE_FLY2, + S_BUMBLEBORE_RAISE, + S_BUMBLEBORE_FALL1, + S_BUMBLEBORE_FALL2, + S_BUMBLEBORE_STUCK1, + S_BUMBLEBORE_STUCK2, + S_BUMBLEBORE_DIE, + + S_BBUZZFLY1, + S_BBUZZFLY2, + + S_SMASHSPIKE_FLOAT, + S_SMASHSPIKE_EASE1, + S_SMASHSPIKE_EASE2, + S_SMASHSPIKE_FALL, + S_SMASHSPIKE_STOMP1, + S_SMASHSPIKE_STOMP2, + S_SMASHSPIKE_RISE1, + S_SMASHSPIKE_RISE2, + + S_CACO_LOOK, + S_CACO_WAKE1, + S_CACO_WAKE2, + S_CACO_WAKE3, + S_CACO_WAKE4, + S_CACO_ROAR, + S_CACO_CHASE, + S_CACO_CHASE_REPEAT, + S_CACO_RANDOM, + S_CACO_PREPARE_SOUND, + S_CACO_PREPARE1, + S_CACO_PREPARE2, + S_CACO_PREPARE3, + S_CACO_SHOOT_SOUND, + S_CACO_SHOOT1, + S_CACO_SHOOT2, + S_CACO_CLOSE, + S_CACO_DIE_FLAGS, + S_CACO_DIE_GIB1, + S_CACO_DIE_GIB2, + S_CACO_DIE_SCREAM, + S_CACO_DIE_SHATTER, + S_CACO_DIE_FALL, + S_CACOSHARD_RANDOMIZE, + S_CACOSHARD1_1, + S_CACOSHARD1_2, + S_CACOSHARD2_1, + S_CACOSHARD2_2, + S_CACOFIRE1, + S_CACOFIRE2, + S_CACOFIRE3, + S_CACOFIRE_EXPLODE1, + S_CACOFIRE_EXPLODE2, + S_CACOFIRE_EXPLODE3, + S_CACOFIRE_EXPLODE4, + + S_SPINBOBERT_MOVE_FLIPUP, + S_SPINBOBERT_MOVE_UP, + S_SPINBOBERT_MOVE_FLIPDOWN, + S_SPINBOBERT_MOVE_DOWN, + S_SPINBOBERT_FIRE_MOVE, + S_SPINBOBERT_FIRE_GHOST, + S_SPINBOBERT_FIRE_TRAIL1, + S_SPINBOBERT_FIRE_TRAIL2, + S_SPINBOBERT_FIRE_TRAIL3, + + S_HANGSTER_LOOK, + S_HANGSTER_SWOOP1, + S_HANGSTER_SWOOP2, + S_HANGSTER_ARC1, + S_HANGSTER_ARC2, + S_HANGSTER_ARC3, + S_HANGSTER_FLY1, + S_HANGSTER_FLY2, + S_HANGSTER_FLY3, + S_HANGSTER_FLY4, + S_HANGSTER_FLYREPEAT, + S_HANGSTER_ARCUP1, + S_HANGSTER_ARCUP2, + S_HANGSTER_ARCUP3, + S_HANGSTER_RETURN1, + S_HANGSTER_RETURN2, + S_HANGSTER_RETURN3, S_CRUMBLE1, S_CRUMBLE2, - S_SUPERTRANS1, - S_SUPERTRANS2, - S_SUPERTRANS3, - S_SUPERTRANS4, - S_SUPERTRANS5, - S_SUPERTRANS6, - S_SUPERTRANS7, - S_SUPERTRANS8, - S_SUPERTRANS9, - // Spark S_SPRK1, S_SPRK2, @@ -2829,10 +3880,14 @@ typedef enum state S_SPRK16, // Robot Explosion + S_XPLD_FLICKY, S_XPLD1, S_XPLD2, S_XPLD3, S_XPLD4, + S_XPLD5, + S_XPLD6, + S_XPLD_EGGTRAP, // Underwater Explosion S_WPLD1, @@ -2842,6 +3897,13 @@ typedef enum state S_WPLD5, S_WPLD6, + S_DUST1, + S_DUST2, + S_DUST3, + S_DUST4, + + S_WOODDEBRIS, + S_ROCKSPAWN, S_ROCKCRUMBLEA, @@ -2861,70 +3923,6 @@ typedef enum state S_ROCKCRUMBLEO, S_ROCKCRUMBLEP, - S_SRB1_CRAWLA1, - S_SRB1_CRAWLA2, - S_SRB1_CRAWLA3, - S_SRB1_CRAWLA4, - - S_SRB1_BAT1, - S_SRB1_BAT2, - S_SRB1_BAT3, - S_SRB1_BAT4, - - S_SRB1_ROBOFISH1, - S_SRB1_ROBOFISH2, - S_SRB1_ROBOFISH3, - - S_SRB1_VOLCANOGUY1, - S_SRB1_VOLCANOGUY2, - - S_SRB1_HOPPY1, - S_SRB1_HOPPY2, - - S_SRB1_HOPPYWATER1, - S_SRB1_HOPPYWATER2, - - S_SRB1_HOPPYSKYLAB1, - - S_SRB1_MMZFLYING1, - S_SRB1_MMZFLYING2, - S_SRB1_MMZFLYING3, - S_SRB1_MMZFLYING4, - S_SRB1_MMZFLYING5, - - S_SRB1_UFO1, - S_SRB1_UFO2, - - S_SRB1_GRAYBOT1, - S_SRB1_GRAYBOT2, - S_SRB1_GRAYBOT3, - S_SRB1_GRAYBOT4, - S_SRB1_GRAYBOT5, - S_SRB1_GRAYBOT6, - - S_SRB1_ROBOTOPOLIS1, - S_SRB1_ROBOTOPOLIS2, - - S_SRB1_RBZBUZZ1, - S_SRB1_RBZBUZZ2, - - S_SRB1_RBZSPIKES1, - S_SRB1_RBZSPIKES2, - - S_SRB1_METALSONIC1, - S_SRB1_METALSONIC2, - S_SRB1_METALSONIC3, - - S_SRB1_GOLDBOT1, - S_SRB1_GOLDBOT2, - S_SRB1_GOLDBOT3, - S_SRB1_GOLDBOT4, - S_SRB1_GOLDBOT5, - S_SRB1_GOLDBOT6, - - S_SRB1_GENREX1, - S_SRB1_GENREX2, - #ifdef SEENAMES S_NAMECHECK, #endif @@ -2947,7 +3945,10 @@ typedef struct extern state_t states[NUMSTATES]; extern char sprnames[NUMSPRITES + 1][5]; +extern char spr2names[NUMPLAYERSPRITES][5]; +extern playersprite_t spr2defaults[NUMPLAYERSPRITES]; extern state_t *astate; +extern playersprite_t free_spr2; typedef enum mobj_type { @@ -2956,37 +3957,46 @@ typedef enum mobj_type MT_THOK, // Thok! mobj MT_PLAYER, + MT_TAILSOVERLAY, // c: // Enemies - MT_BLUECRAWLA, - MT_REDCRAWLA, - MT_GFZFISH, // Greenflower Fish - MT_GOLDBUZZ, - MT_REDBUZZ, - MT_AQUABUZZ, // AquaBuzz for ATZ + MT_BLUECRAWLA, // Crawla (Blue) + MT_REDCRAWLA, // Crawla (Red) + MT_GFZFISH, // SDURF + MT_GOLDBUZZ, // Buzz (Gold) + MT_REDBUZZ, // Buzz (Red) MT_JETTBOMBER, // Jetty-Syn Bomber MT_JETTGUNNER, // Jetty-Syn Gunner MT_CRAWLACOMMANDER, // Crawla Commander MT_DETON, // Deton MT_SKIM, // Skim mine dropper - MT_TURRET, - MT_POPUPTURRET, - MT_SHARP, // Sharp + MT_TURRET, // Industrial Turret + MT_POPUPTURRET, // Pop-Up Turret + MT_SPINCUSHION, // Spincushion + MT_CRUSHSTACEAN, // Crushstacean + MT_CRUSHCLAW, // Big meaty claw + MT_CRUSHCHAIN, // Chain MT_JETJAW, // Jet Jaw MT_SNAILER, // Snailer - MT_VULTURE, // Vulture + MT_VULTURE, // BASH MT_POINTY, // Pointy MT_POINTYBALL, // Pointy Ball MT_ROBOHOOD, // Robo-Hood - MT_FACESTABBER, // CastleBot FaceStabber + MT_FACESTABBER, // Castlebot Facestabber + MT_FACESTABBERSPEAR, // Castlebot Facestabber spear aura MT_EGGGUARD, // Egg Guard - MT_EGGSHIELD, // Egg Shield for Egg Guard + MT_EGGSHIELD, // Egg Guard's shield MT_GSNAPPER, // Green Snapper + MT_SNAPPER_LEG, // Green Snapper leg + MT_SNAPPER_HEAD, // Green Snapper head MT_MINUS, // Minus + MT_MINUSDIRT, // Minus dirt MT_SPRINGSHELL, // Spring Shell MT_YELLOWSHELL, // Spring Shell (yellow) MT_UNIDUS, // Unidus MT_UNIBALL, // Unidus Ball + MT_CANARIVORE, // Canarivore + MT_CANARIVORE_GAS, // Canarivore gas // Generic Boss Items MT_BOSSEXPLODE, @@ -3010,6 +4020,7 @@ typedef enum mobj_type MT_BOSSTANK2, MT_BOSSSPIGOT, MT_GOOP, + MT_GOOPTRAIL, // Boss 3 MT_EGGMOBILE3, @@ -3021,6 +4032,14 @@ typedef enum mobj_type MT_EGGMOBILE4_MACE, MT_JETFLAME, + // Boss 5 + MT_FANG, + MT_FBOMB, + MT_TNTDUST, // also used by barrel + MT_FSGNA, + MT_FSGNB, + MT_FANGWAYPOINT, + // Black Eggman (Boss 7) MT_BLACKEGGMAN, MT_BLACKEGGMAN_HELPER, @@ -3049,11 +4068,12 @@ typedef enum mobj_type // Collectible Items MT_RING, MT_FLINGRING, // Lost ring - MT_BLUEBALL, // Blue sphere replacement for special stages + MT_BLUESPHERE, // Blue sphere for special stages + MT_FLINGBLUESPHERE, // Lost blue sphere + MT_BOMBSPHERE, MT_REDTEAMRING, //Rings collectable by red team. MT_BLUETEAMRING, //Rings collectable by blue team. - MT_EMMY, // emerald token for special stage - MT_TOKEN, // Special Stage Token (uncollectible part) + MT_TOKEN, // Special Stage token for special stage MT_REDFLAG, // Red CTF Flag MT_BLUEFLAG, // Blue CTF Flag MT_EMBLEM, @@ -3070,66 +4090,97 @@ typedef enum mobj_type // Springs and others MT_FAN, - MT_STEAM, // Steam riser - MT_BLUESPRING, + MT_STEAM, + MT_BUMPER, + MT_BALLOON, + MT_YELLOWSPRING, MT_REDSPRING, - MT_YELLOWDIAG, // Yellow Diagonal Spring - MT_REDDIAG, // Red Diagonal Spring + MT_BLUESPRING, + MT_YELLOWDIAG, + MT_REDDIAG, + MT_BLUEDIAG, + MT_YELLOWHORIZ, + MT_REDHORIZ, + MT_BLUEHORIZ, // Interactive Objects MT_BUBBLES, // Bubble source MT_SIGN, // Level end sign MT_SPIKEBALL, // Spike Ball - MT_SPECIALSPIKEBALL, MT_SPINFIRE, MT_SPIKE, + MT_WALLSPIKE, + MT_WALLSPIKEBASE, MT_STARPOST, MT_BIGMINE, - MT_BIGAIRMINE, + MT_BLASTEXECUTOR, MT_CANNONLAUNCHER, - // Monitor Boxes - MT_SUPERRINGBOX, - MT_REDRINGBOX, - MT_BLUERINGBOX, - MT_SNEAKERTV, - MT_INV, - MT_PRUP, // 1up Box - MT_YELLOWTV, - MT_BLUETV, - MT_BLACKTV, // Bomb shield TV - MT_WHITETV, // Jump shield TV - MT_GREENTV, - MT_PITYTV, // Pity Shield TV - MT_EGGMANBOX, - MT_MIXUPBOX, - MT_RECYCLETV, - MT_RECYCLEICO, - MT_QUESTIONBOX, - MT_GRAVITYBOX, - MT_SCORETVSMALL, - MT_SCORETVLARGE, - // Monitor miscellany - MT_MONITOREXPLOSION, - MT_REDMONITOREXPLOSION, - MT_BLUEMONITOREXPLOSION, - MT_RINGICO, - MT_SHOESICO, - MT_INVCICO, - MT_1UPICO, - MT_YSHIELDICO, - MT_BSHIELDICO, - MT_KSHIELDICO, - MT_WSHIELDICO, - MT_GSHIELDICO, - MT_PITYSHIELDICO, - MT_EGGMANICO, - MT_MIXUPICO, - MT_GRAVITYICO, - MT_SCOREICOSMALL, - MT_SCOREICOLARGE, + MT_BOXSPARKLE, + + // Monitor boxes -- regular + MT_RING_BOX, + MT_PITY_BOX, + MT_ATTRACT_BOX, + MT_FORCE_BOX, + MT_ARMAGEDDON_BOX, + MT_WHIRLWIND_BOX, + MT_ELEMENTAL_BOX, + MT_SNEAKERS_BOX, + MT_INVULN_BOX, + MT_1UP_BOX, + MT_EGGMAN_BOX, + MT_MIXUP_BOX, + MT_MYSTERY_BOX, + MT_GRAVITY_BOX, + MT_RECYCLER_BOX, + MT_SCORE1K_BOX, + MT_SCORE10K_BOX, + MT_FLAMEAURA_BOX, + MT_BUBBLEWRAP_BOX, + MT_THUNDERCOIN_BOX, + + // Monitor boxes -- repeating (big) boxes + MT_PITY_GOLDBOX, + MT_ATTRACT_GOLDBOX, + MT_FORCE_GOLDBOX, + MT_ARMAGEDDON_GOLDBOX, + MT_WHIRLWIND_GOLDBOX, + MT_ELEMENTAL_GOLDBOX, + MT_SNEAKERS_GOLDBOX, + MT_INVULN_GOLDBOX, + MT_EGGMAN_GOLDBOX, + MT_GRAVITY_GOLDBOX, + MT_FLAMEAURA_GOLDBOX, + MT_BUBBLEWRAP_GOLDBOX, + MT_THUNDERCOIN_GOLDBOX, + + // Monitor boxes -- special + MT_RING_REDBOX, + MT_RING_BLUEBOX, + + // Monitor icons + MT_RING_ICON, + MT_PITY_ICON, + MT_ATTRACT_ICON, + MT_FORCE_ICON, + MT_ARMAGEDDON_ICON, + MT_WHIRLWIND_ICON, + MT_ELEMENTAL_ICON, + MT_SNEAKERS_ICON, + MT_INVULN_ICON, + MT_1UP_ICON, + MT_EGGMAN_ICON, + MT_MIXUP_ICON, + MT_GRAVITY_ICON, + MT_RECYCLER_ICON, + MT_SCORE1K_ICON, + MT_SCORE10K_ICON, + MT_FLAMEAURA_ICON, + MT_BUBBLEWRAP_ICON, + MT_THUNDERCOIN_ICON, // Projectiles MT_ROCKET, @@ -3149,15 +4200,35 @@ typedef enum mobj_type MT_GFZFLOWER1, MT_GFZFLOWER2, MT_GFZFLOWER3, + + MT_BLUEBERRYBUSH, MT_BERRYBUSH, MT_BUSH, + // Trees (both GFZ and misc) + MT_GFZTREE, + MT_GFZBERRYTREE, + MT_GFZCHERRYTREE, + MT_CHECKERTREE, + MT_CHECKERSUNSETTREE, + MT_FHZTREE, // Frozen Hillside + MT_FHZPINKTREE, + MT_POLYGONTREE, + MT_BUSHTREE, + MT_BUSHREDTREE, + MT_SPRINGTREE, + // Techno Hill Scenery - MT_THZPLANT, // THZ Plant + MT_THZFLOWER1, + MT_THZFLOWER2, + MT_THZFLOWER3, + MT_THZTREE, // Steam whistle tree/bush + MT_THZTREEBRANCH, // branch of said tree MT_ALARM, // Deep Sea Scenery MT_GARGOYLE, // Deep Sea Gargoyle + MT_BIGGARGOYLE, // Deep Sea Gargoyle (Big) MT_SEAWEED, // DSZ Seaweed MT_WATERDRIP, // Dripping Water source MT_WATERDROP, // Water drop from dripping water @@ -3165,21 +4236,49 @@ typedef enum mobj_type MT_CORAL2, // Coral 2 MT_CORAL3, // Coral 3 MT_BLUECRYSTAL, // Blue Crystal + MT_KELP, // Kelp + MT_DSZSTALAGMITE, // Deep Sea 1 Stalagmite + MT_DSZ2STALAGMITE, // Deep Sea 2 Stalagmite + MT_LIGHTBEAM, // DSZ Light beam // Castle Eggman Scenery MT_CHAIN, // CEZ Chain MT_FLAME, // Flame (has corona) + MT_FLAMEPARTICLE, MT_EGGSTATUE, // Eggman Statue MT_MACEPOINT, // Mace rotation point - MT_SWINGMACEPOINT, // Mace swinging point - MT_HANGMACEPOINT, // Hangable mace chain - MT_SPINMACEPOINT, // Spin/Controllable mace chain + MT_CHAINMACEPOINT, // Combination of chains and maces point + MT_SPRINGBALLPOINT, // Spring ball point + MT_CHAINPOINT, // Mace chain MT_HIDDEN_SLING, // Spin mace chain (activatable) + MT_FIREBARPOINT, // Firebar + MT_CUSTOMMACEPOINT, // Custom mace MT_SMALLMACECHAIN, // Small Mace Chain MT_BIGMACECHAIN, // Big Mace Chain MT_SMALLMACE, // Small Mace MT_BIGMACE, // Big Mace - MT_CEZFLOWER, + MT_SMALLGRABCHAIN, // Small Grab Chain + MT_BIGGRABCHAIN, // Big Grab Chain + MT_YELLOWSPRINGBALL, // Yellow spring on a ball + MT_REDSPRINGBALL, // Red spring on a ball + MT_SMALLFIREBAR, // Small Firebar + MT_BIGFIREBAR, // Big Firebar + MT_CEZFLOWER, // Flower + MT_CEZPOLE, // Pole + MT_CEZBANNER, // Banner + MT_PINETREE, // Pine Tree + MT_CEZBUSH1, // Bush 1 + MT_CEZBUSH2, // Bush 2 + MT_CANDLE, // Candle + MT_CANDLEPRICKET, // Candle pricket + MT_FLAMEHOLDER, // Flame holder + MT_FIRETORCH, // Fire torch + MT_WAVINGFLAG, // Waving flag + MT_WAVINGFLAGSEG, // Waving flag segment + MT_CRAWLASTATUE, // Crawla statue + MT_FACESTABBERSTATUE, // Facestabber statue + MT_SUSPICIOUSFACESTABBERSTATUE, // :eggthinking: + MT_BRAMBLES, // Brambles // Arid Canyon Scenery MT_BIGTUMBLEWEED, @@ -3188,6 +4287,34 @@ typedef enum mobj_type MT_CACTI2, MT_CACTI3, MT_CACTI4, + MT_CACTI5, // Harmful Cactus 1 + MT_CACTI6, // Harmful Cactus 2 + MT_CACTI7, // Harmful Cactus 3 + MT_CACTI8, // Harmful Cactus 4 + MT_CACTI9, // Harmful Cactus 5 + MT_ARIDSIGN_CAUTION, // Caution Sign + MT_ARIDSIGN_CACTI, // Cacti Sign + MT_ARIDSIGN_SHARPTURN, // Sharp Turn Sign + MT_OILLAMP, + MT_TNTBARREL, + MT_PROXIMITYTNT, + MT_DUSTDEVIL, + MT_DUSTLAYER, + MT_ARIDDUST, + MT_MINECART, + MT_MINECARTSEG, + MT_MINECARTSPAWNER, + MT_MINECARTEND, + MT_MINECARTENDSOLID, + MT_MINECARTSIDEMARK, + MT_MINECARTSPARK, + MT_SALOONDOOR, + MT_SALOONDOORTHINKER, + MT_TRAINCAMEOSPAWNER, + MT_TRAINSEG, + MT_TRAINDUSTSPAWNER, + MT_TRAINSTEAMSPAWNER, + MT_MINECARTSWITCHPOINT, // Red Volcano Scenery MT_FLAMEJET, @@ -3195,9 +4322,7 @@ typedef enum mobj_type MT_FLAMEJETFLAME, MT_FJSPINAXISA, // Counter-clockwise - MT_FJSPINHELPERA, MT_FJSPINAXISB, // Clockwise - MT_FJSPINHELPERB, MT_FLAMEJETFLAMEB, // Blade's flame @@ -3227,7 +4352,34 @@ typedef enum mobj_type // Christmas Scenery MT_XMASPOLE, MT_CANDYCANE, - MT_SNOWMAN, + MT_SNOWMAN, // normal + MT_SNOWMANHAT, // with hat + scarf + MT_LAMPPOST1, // normal + MT_LAMPPOST2, // with snow + MT_HANGSTAR, + // Xmas GFZ bushes + MT_XMASBLUEBERRYBUSH, + MT_XMASBERRYBUSH, + MT_XMASBUSH, + // FHZ + MT_FHZICE1, + MT_FHZICE2, + + // Halloween Scenery + // Pumpkins + MT_JACKO1, + MT_JACKO2, + MT_JACKO3, + // Dr Seuss Trees + MT_HHZTREE_TOP, + MT_HHZTREE_PART, + // Misc + MT_HHZSHROOM, + MT_HHZGRASS, + MT_HHZTENTACLE1, + MT_HHZTENTACLE2, + MT_HHZSTALAGMITE_TALL, + MT_HHZSTALAGMITE_SHORT, // Botanic Serenity scenery MT_BSZTALLFLOWER_RED, @@ -3274,30 +4426,67 @@ typedef enum mobj_type MT_BSZVINE_ORANGE, MT_BSZSHRUB, MT_BSZCLOVER, - MT_BSZFISH, - MT_BSZSUNFLOWER, + MT_BIG_PALMTREE_TRUNK, + MT_BIG_PALMTREE_TOP, + MT_PALMTREE_TRUNK, + MT_PALMTREE_TOP, // Misc scenery MT_DBALL, MT_EGGSTATUE2, // Powerup Indicators - MT_GREENORB, // Elemental shield mobj - MT_YELLOWORB, // Attract shield mobj - MT_BLUEORB, // Force shield mobj - MT_BLACKORB, // Armageddon shield mobj - MT_WHITEORB, // Whirlwind shield mobj - MT_PITYORB, // Pity shield mobj - MT_IVSP, // invincibility sparkles + MT_ELEMENTAL_ORB, // Elemental shield mobj + MT_ATTRACT_ORB, // Attract shield mobj + MT_FORCE_ORB, // Force shield mobj + MT_ARMAGEDDON_ORB, // Armageddon shield mobj + MT_WHIRLWIND_ORB, // Whirlwind shield mobj + MT_PITY_ORB, // Pity shield mobj + MT_FLAMEAURA_ORB, // Flame shield mobj + MT_BUBBLEWRAP_ORB, // Bubble shield mobj + MT_THUNDERCOIN_ORB, // Thunder shield mobj + MT_THUNDERCOIN_SPARK, // Thunder spark + MT_IVSP, // Invincibility sparkles MT_SUPERSPARK, // Super Sonic Spark - // Freed Animals - MT_BIRD, // Birdie freed! - MT_BUNNY, // Bunny freed! - MT_MOUSE, // Mouse - MT_CHICKEN, // Chicken - MT_COW, // Cow - MT_REDBIRD, // Red Birdie in Bubble + // Flickies + MT_FLICKY_01, // Bluebird + MT_FLICKY_01_CENTER, + MT_FLICKY_02, // Rabbit + MT_FLICKY_02_CENTER, + MT_FLICKY_03, // Chicken + MT_FLICKY_03_CENTER, + MT_FLICKY_04, // Seal + MT_FLICKY_04_CENTER, + MT_FLICKY_05, // Pig + MT_FLICKY_05_CENTER, + MT_FLICKY_06, // Chipmunk + MT_FLICKY_06_CENTER, + MT_FLICKY_07, // Penguin + MT_FLICKY_07_CENTER, + MT_FLICKY_08, // Fish + MT_FLICKY_08_CENTER, + MT_FLICKY_09, // Ram + MT_FLICKY_09_CENTER, + MT_FLICKY_10, // Puffin + MT_FLICKY_10_CENTER, + MT_FLICKY_11, // Cow + MT_FLICKY_11_CENTER, + MT_FLICKY_12, // Rat + MT_FLICKY_12_CENTER, + MT_FLICKY_13, // Bear + MT_FLICKY_13_CENTER, + MT_FLICKY_14, // Dove + MT_FLICKY_14_CENTER, + MT_FLICKY_15, // Cat + MT_FLICKY_15_CENTER, + MT_FLICKY_16, // Canary + MT_FLICKY_16_CENTER, + MT_SECRETFLICKY_01, // Spider + MT_SECRETFLICKY_01_CENTER, + MT_SECRETFLICKY_02, // Bat + MT_SECRETFLICKY_02_CENTER, + MT_SEED, // Environmental Effects MT_RAIN, // Rain @@ -3307,8 +4496,9 @@ typedef enum mobj_type MT_SMALLBUBBLE, // small bubble MT_MEDIUMBUBBLE, // medium bubble MT_EXTRALARGEBUBBLE, // extra large bubble + MT_WATERZAP, + MT_SPINDUST, // Spindash dust MT_TFOG, - MT_SEED, MT_PARTICLE, MT_PARTICLEGEN, // For fans, etc. @@ -3316,9 +4506,9 @@ typedef enum mobj_type MT_SCORE, // score logo MT_DROWNNUMBERS, // Drowning Timer MT_GOTEMERALD, // Chaos Emerald (intangible) + MT_LOCKON, // Target MT_TAG, // Tag Sign MT_GOTFLAG, // Got Flag sign - MT_GOTFLAG2, // Got Flag sign // Ambient Sounds MT_AWATERA, // Ambient Water Sound 1 @@ -3331,6 +4521,9 @@ typedef enum mobj_type MT_AWATERH, // Ambient Water Sound 8 MT_RANDOMAMBIENT, MT_RANDOMAMBIENT2, + MT_MACHINEAMBIENCE, + + MT_CORK, // Ring Weapons MT_REDRING, @@ -3365,6 +4558,7 @@ typedef enum mobj_type MT_FIREBALL, MT_SHELL, MT_PUMA, + MT_PUMATRAIL, MT_HAMMER, MT_KOOPA, MT_KOOPAFLAME, @@ -3378,8 +4572,9 @@ typedef enum mobj_type MT_AXISTRANSFER, MT_AXISTRANSFERLINE, MT_NIGHTSDRONE, - MT_NIGHTSGOAL, - MT_NIGHTSCHAR, + MT_NIGHTSDRONE_MAN, + MT_NIGHTSDRONE_SPARKLING, + MT_NIGHTSDRONE_GOAL, MT_NIGHTSPARKLE, MT_NIGHTSLOOPHELPER, MT_NIGHTSBUMPER, // NiGHTS Bumper @@ -3387,14 +4582,38 @@ typedef enum mobj_type MT_HOOPCOLLIDE, // Collision detection for NiGHTS hoops MT_HOOPCENTER, // Center of a hoop MT_NIGHTSCORE, - MT_NIGHTSWING, + MT_NIGHTSCHIP, // NiGHTS Chip + MT_FLINGNIGHTSCHIP, // Lost NiGHTS Chip + MT_NIGHTSSTAR, // NiGHTS Star MT_NIGHTSSUPERLOOP, MT_NIGHTSDRILLREFILL, MT_NIGHTSHELPER, MT_NIGHTSEXTRATIME, MT_NIGHTSLINKFREEZE, MT_EGGCAPSULE, + MT_IDEYAANCHOR, MT_NIGHTOPIANHELPER, // the actual helper object that orbits you + MT_PIAN, // decorative singing friend + MT_SHLEEP, // almost-decorative sleeping enemy + + // Secret badniks and hazards, shhhh + MT_PENGUINATOR, + MT_POPHAT, + MT_POPSHOT, + + MT_HIVEELEMENTAL, + MT_BUMBLEBORE, + + MT_BUBBLEBUZZ, + + MT_SMASHINGSPIKEBALL, + MT_CACOLANTERN, + MT_CACOSHARD, + MT_CACOFIRE, + MT_SPINBOBERT, + MT_SPINBOBERT_FIRE1, + MT_SPINBOBERT_FIRE2, + MT_HANGSTER, // Utility Objects MT_TELEPORTMAN, @@ -3405,6 +4624,7 @@ typedef enum mobj_type MT_PULL, MT_GHOST, MT_OVERLAY, + MT_ANGLEMAN, MT_POLYANCHOR, MT_POLYSPAWN, MT_POLYSPAWNCRUSH, @@ -3416,6 +4636,8 @@ typedef enum mobj_type MT_SPARK, //spark MT_EXPLODE, // Robot Explosion MT_UWEXPLODE, // Underwater Explosion + MT_DUST, + MT_WOODDEBRIS, MT_ROCKSPAWNER, MT_FALLINGROCK, MT_ROCKCRUMBLE1, @@ -3435,22 +4657,6 @@ typedef enum mobj_type MT_ROCKCRUMBLE15, MT_ROCKCRUMBLE16, - MT_SRB1_CRAWLA, - MT_SRB1_BAT, - MT_SRB1_ROBOFISH, - MT_SRB1_VOLCANOGUY, - MT_SRB1_HOPPY, - MT_SRB1_HOPPYWATER, - MT_SRB1_HOPPYSKYLAB, - MT_SRB1_MMZFLYING, - MT_SRB1_UFO, - MT_SRB1_GRAYBOT, - MT_SRB1_ROBOTOPOLIS, - MT_SRB1_RBZBUZZ, - MT_SRB1_RBZSPIKES, - MT_SRB1_METALSONIC, - MT_SRB1_GOLDBOT, - MT_SRB1_GENREX, #ifdef SEENAMES MT_NAMECHECK, #endif diff --git a/src/locale/en.po b/src/locale/en.po index ce451080212f0a667de8fdcfde074e8faf6dccbb..5f45920798552f8a67343a4ea79bf4e620675f14 100644 --- a/src/locale/en.po +++ b/src/locale/en.po @@ -1377,11 +1377,6 @@ msgstr "" msgid "modifiedgame is false, you can unlock secrets\n" msgstr "" -#: d_netcmd.c:4599 -#, c-format -msgid "Valid skin numbers are 0 to %d (-1 disables)\n" -msgstr "" - #: d_netcmd.c:4617 d_netcmd.c:4629 msgid "You may not change your name when chat is muted.\n" msgstr "" diff --git a/src/locale/srb2.pot b/src/locale/srb2.pot index c61cbcc973c5a97cc6872ab7b439ca8e48f1a9ea..552e9edb113d787934760436aacec5075a2f4377 100644 --- a/src/locale/srb2.pot +++ b/src/locale/srb2.pot @@ -1362,11 +1362,6 @@ msgstr "" msgid "No CHEAT-marked variables are changed -- Cheats are disabled.\n" msgstr "" -#: d_netcmd.c:4439 -#, c-format -msgid "Valid skin numbers are 0 to %d (-1 disables)\n" -msgstr "" - #: d_netcmd.c:4457 d_netcmd.c:4469 msgid "You may not change your name when chat is muted.\n" msgstr "" diff --git a/src/lua_baselib.c b/src/lua_baselib.c index d3443312a5edd697bd9db5fb6e13fa32194883ad..755b76835390f6b6df7c3fb111f81a3445d7a08e 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -31,8 +31,10 @@ #include "lua_libs.h" #include "lua_hud.h" // hud_running errors -#define NOHUD if (hud_running) return luaL_error(L, "HUD rendering code should not call this function!"); - +#define NOHUD if (hud_running)\ +return luaL_error(L, "HUD rendering code should not call this function!"); +#define INLEVEL if (gamestate != GS_LEVEL)\ +return luaL_error(L, "This function can only be used in a level!"); boolean luaL_checkboolean(lua_State *L, int narg) { luaL_checktype(L, narg, LUA_TBOOLEAN); @@ -136,11 +138,85 @@ static int lib_chatprintf(lua_State *L) return 0; } -static int lib_evalMath(lua_State *L) +static const struct { + const char *meta; + const char *utype; +} meta2utype[] = { + {META_STATE, "state_t"}, + {META_MOBJINFO, "mobjinfo_t"}, + {META_SFXINFO, "sfxinfo_t"}, + + {META_MOBJ, "mobj_t"}, + {META_MAPTHING, "mapthing_t"}, + + {META_PLAYER, "player_t"}, + {META_TICCMD, "ticcmd_t"}, + {META_SKIN, "skin_t"}, + {META_POWERS, "player_t.powers"}, + {META_SOUNDSID, "skin_t.soundsid"}, + + {META_VERTEX, "vertex_t"}, + {META_LINE, "line_t"}, + {META_SIDE, "side_t"}, + {META_SUBSECTOR, "subsector_t"}, + {META_SECTOR, "sector_t"}, + {META_FFLOOR, "ffloor_t"}, +#ifdef HAVE_LUA_SEGS + {META_SEG, "seg_t"}, + {META_NODE, "node_t"}, +#endif + {META_MAPHEADER, "mapheader_t"}, + + {META_CVAR, "consvar_t"}, + + {META_SECTORLINES, "sector_t.lines"}, + {META_SIDENUM, "line_t.sidenum"}, +#ifdef HAVE_LUA_SEGS + {META_NODEBBOX, "node_t.bbox"}, + {META_NODECHILDREN, "node_t.children"}, +#endif + + {META_BBOX, "bbox"}, + + {META_HUDINFO, "hudinfo_t"}, + {META_PATCH, "patch_t"}, + {META_COLORMAP, "colormap"}, + {META_CAMERA, "camera_t"}, + + {META_ACTION, "action"}, + {NULL, NULL} +}; + +// goes through the above list and returns the utype string for the userdata type +// returns "unknown" instead if we couldn't find the right userdata type +static const char *GetUserdataUType(lua_State *L) { - const char *word = luaL_checkstring(L, 1); - LUA_Deprecated(L, "EvalMath(string)", "_G[string]"); - lua_pushinteger(L, LUA_EvalMath(word)); + UINT8 i; + lua_getmetatable(L, -1); + + for (i = 0; meta2utype[i].meta; i++) + { + luaL_getmetatable(L, meta2utype[i].meta); + if (lua_rawequal(L, -1, -2)) + { + lua_pop(L, 2); + return meta2utype[i].utype; + } + lua_pop(L, 1); + } + + lua_pop(L, 1); + return "unknown"; +} + +// Return a string representing the type of userdata the given var is +// e.g. players[0] -> "player_t" +// or players[0].powers -> "player_t.powers" +static int lib_userdataType(lua_State *L) +{ + lua_settop(L, 1); // pop everything except arg 1 (in case somebody decided to add more) + luaL_checktype(L, 1, LUA_TUSERDATA); + lua_pushstring(L, GetUserdataUType(L)); return 1; } @@ -199,15 +275,7 @@ static int lib_pRandomRange(lua_State *L) return 1; } -// Deprecated, macros, etc. -static int lib_pRandom(lua_State *L) -{ - NOHUD - LUA_Deprecated(L, "P_Random", "P_RandomByte"); - lua_pushinteger(L, P_RandomByte()); - return 1; -} - +// Macros. static int lib_pSignedRandom(lua_State *L) { NOHUD @@ -274,6 +342,41 @@ static int lib_pClosestPointOnLine(lua_State *L) return 2; } +static int lib_pPointOnLineSide(lua_State *L) +{ + int n = lua_gettop(L); + fixed_t x = luaL_checkfixed(L, 1); + fixed_t y = luaL_checkfixed(L, 2); + //HUDSAFE + if (lua_isuserdata(L, 3)) // use a real linedef to get our points + { + line_t *line = *((line_t **)luaL_checkudata(L, 3, META_LINE)); + if (!line) + return LUA_ErrInvalid(L, "line_t"); + lua_pushinteger(L, P_PointOnLineSide(x, y, line)); + } + else // use custom coordinates of our own! + { + vertex_t v1, v2; // fake vertexes + line_t junk; // fake linedef + + if (n < 6) + return luaL_error(L, "arguments 3 to 6 not all given (expected 4 fixed-point integers)"); + + v1.x = luaL_checkfixed(L, 3); + v1.y = luaL_checkfixed(L, 4); + v2.x = luaL_checkfixed(L, 5); + v2.y = luaL_checkfixed(L, 6); + + junk.v1 = &v1; + junk.v2 = &v2; + junk.dx = v2.x - v1.x; + junk.dy = v2.y - v1.y; + lua_pushinteger(L, P_PointOnLineSide(x, y, &junk)); + } + return 1; +} + // P_ENEMY ///////////// @@ -281,6 +384,7 @@ static int lib_pCheckMeleeRange(lua_State *L) { mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); NOHUD + INLEVEL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_CheckMeleeRange(actor)); @@ -291,6 +395,7 @@ static int lib_pJetbCheckMeleeRange(lua_State *L) { mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); NOHUD + INLEVEL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_JetbCheckMeleeRange(actor)); @@ -301,6 +406,7 @@ static int lib_pFaceStabCheckMeleeRange(lua_State *L) { mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); NOHUD + INLEVEL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_FaceStabCheckMeleeRange(actor)); @@ -311,6 +417,7 @@ static int lib_pSkimCheckMeleeRange(lua_State *L) { mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); NOHUD + INLEVEL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_SkimCheckMeleeRange(actor)); @@ -321,6 +428,7 @@ static int lib_pCheckMissileRange(lua_State *L) { mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); NOHUD + INLEVEL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_CheckMissileRange(actor)); @@ -331,6 +439,7 @@ static int lib_pNewChaseDir(lua_State *L) { mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); NOHUD + INLEVEL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); P_NewChaseDir(actor); @@ -344,6 +453,7 @@ static int lib_pLookForPlayers(lua_State *L) boolean allaround = lua_optboolean(L, 3); boolean tracer = lua_optboolean(L, 4); NOHUD + INLEVEL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_LookForPlayers(actor, allaround, tracer, dist)); @@ -360,16 +470,35 @@ static int lib_pSpawnMobj(lua_State *L) fixed_t z = luaL_checkfixed(L, 3); mobjtype_t type = luaL_checkinteger(L, 4); NOHUD + INLEVEL if (type >= NUMMOBJTYPES) return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type), META_MOBJ); return 1; } +static int lib_pSpawnMobjFromMobj(lua_State *L) +{ + mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + fixed_t x = luaL_checkfixed(L, 2); + fixed_t y = luaL_checkfixed(L, 3); + fixed_t z = luaL_checkfixed(L, 4); + mobjtype_t type = luaL_checkinteger(L, 5); + NOHUD + INLEVEL + if (!actor) + return LUA_ErrInvalid(L, "mobj_t"); + if (type >= NUMMOBJTYPES) + return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); + LUA_PushUserdata(L, P_SpawnMobjFromMobj(actor, x, y, z, type), META_MOBJ); + return 1; +} + static int lib_pRemoveMobj(lua_State *L) { mobj_t *th = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); NOHUD + INLEVEL if (!th) return LUA_ErrInvalid(L, "mobj_t"); if (th->player) @@ -378,12 +507,51 @@ static int lib_pRemoveMobj(lua_State *L) return 0; } +// P_IsValidSprite2 technically doesn't exist, and probably never should... but too much would need to be exposed to allow this to be checked by other methods. + +static int lib_pIsValidSprite2(lua_State *L) +{ + mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + UINT8 spr2 = (UINT8)luaL_checkinteger(L, 2); + //HUDSAFE + INLEVEL + if (!mobj) + return LUA_ErrInvalid(L, "mobj_t"); + lua_pushboolean(L, (mobj->skin && (((skin_t *)mobj->skin)->sprites[spr2].numframes))); + return 1; +} + +// P_SpawnLockOn doesn't exist either, but we want to expose making a local mobj without encouraging hacks. + +static int lib_pSpawnLockOn(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + mobj_t *lockon = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + statenum_t state = luaL_checkinteger(L, 3); + NOHUD + INLEVEL + if (!lockon) + return LUA_ErrInvalid(L, "mobj_t"); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + if (state >= NUMSTATES) + return luaL_error(L, "state %d out of range (0 - %d)", state, NUMSTATES-1); + if (P_IsLocalPlayer(player)) // Only display it on your own view. + { + mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker + visual->target = lockon; + P_SetMobjStateNF(visual, state); + } + return 0; +} + static int lib_pSpawnMissile(lua_State *L) { mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *dest = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); mobjtype_t type = luaL_checkinteger(L, 3); NOHUD + INLEVEL if (!source || !dest) return LUA_ErrInvalid(L, "mobj_t"); if (type >= NUMMOBJTYPES) @@ -401,6 +569,7 @@ static int lib_pSpawnXYZMissile(lua_State *L) fixed_t y = luaL_checkfixed(L, 5); fixed_t z = luaL_checkfixed(L, 6); NOHUD + INLEVEL if (!source || !dest) return LUA_ErrInvalid(L, "mobj_t"); if (type >= NUMMOBJTYPES) @@ -420,6 +589,7 @@ static int lib_pSpawnPointMissile(lua_State *L) fixed_t y = luaL_checkfixed(L, 7); fixed_t z = luaL_checkfixed(L, 8); NOHUD + INLEVEL if (!source) return LUA_ErrInvalid(L, "mobj_t"); if (type >= NUMMOBJTYPES) @@ -437,6 +607,7 @@ static int lib_pSpawnAlteredDirectionMissile(lua_State *L) fixed_t z = luaL_checkfixed(L, 5); INT32 shiftingAngle = (INT32)luaL_checkinteger(L, 5); NOHUD + INLEVEL if (!source) return LUA_ErrInvalid(L, "mobj_t"); if (type >= NUMMOBJTYPES) @@ -450,6 +621,7 @@ static int lib_pColorTeamMissile(lua_State *L) mobj_t *missile = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); player_t *source = *((player_t **)luaL_checkudata(L, 2, META_PLAYER)); NOHUD + INLEVEL if (!missile) return LUA_ErrInvalid(L, "mobj_t"); if (!source) @@ -466,6 +638,7 @@ static int lib_pSPMAngle(lua_State *L) UINT8 allowaim = (UINT8)luaL_optinteger(L, 4, 0); UINT32 flags2 = (UINT32)luaL_optinteger(L, 5, 0); NOHUD + INLEVEL if (!source) return LUA_ErrInvalid(L, "mobj_t"); if (type >= NUMMOBJTYPES) @@ -480,6 +653,7 @@ static int lib_pSpawnPlayerMissile(lua_State *L) mobjtype_t type = luaL_checkinteger(L, 2); UINT32 flags2 = (UINT32)luaL_optinteger(L, 3, 0); NOHUD + INLEVEL if (!source) return LUA_ErrInvalid(L, "mobj_t"); if (type >= NUMMOBJTYPES) @@ -492,6 +666,7 @@ static int lib_pMobjFlip(lua_State *L) { mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); //HUDSAFE + INLEVEL if (!mobj) return LUA_ErrInvalid(L, "mobj_t"); lua_pushinteger(L, P_MobjFlip(mobj)); @@ -502,6 +677,7 @@ static int lib_pGetMobjGravity(lua_State *L) { mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); //HUDSAFE + INLEVEL if (!mobj) return LUA_ErrInvalid(L, "mobj_t"); lua_pushfixed(L, P_GetMobjGravity(mobj)); @@ -524,6 +700,7 @@ static int lib_pFlashPal(lua_State *L) UINT16 type = (UINT16)luaL_checkinteger(L, 2); UINT16 duration = (UINT16)luaL_checkinteger(L, 3); NOHUD + INLEVEL if (!pl) return LUA_ErrInvalid(L, "player_t"); P_FlashPal(pl, type, duration); @@ -534,6 +711,7 @@ static int lib_pGetClosestAxis(lua_State *L) { mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); //HUDSAFE + INLEVEL if (!source) return LUA_ErrInvalid(L, "mobj_t"); LUA_PushUserdata(L, P_GetClosestAxis(source), META_MOBJ); @@ -552,6 +730,7 @@ static int lib_pSpawnParaloop(lua_State *L) statenum_t nstate = luaL_optinteger(L, 8, S_NULL); boolean spawncenter = lua_optboolean(L, 9); NOHUD + INLEVEL if (type >= NUMMOBJTYPES) return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); if (nstate >= NUMSTATES) @@ -565,6 +744,7 @@ static int lib_pBossTargetPlayer(lua_State *L) mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); boolean closest = lua_optboolean(L, 2); NOHUD + INLEVEL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_BossTargetPlayer(actor, closest)); @@ -575,6 +755,7 @@ static int lib_pSupermanLook4Players(lua_State *L) { mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); NOHUD + INLEVEL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_SupermanLook4Players(actor)); @@ -586,6 +767,7 @@ static int lib_pSetScale(lua_State *L) mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); fixed_t newscale = luaL_checkfixed(L, 2); NOHUD + INLEVEL if (!mobj) return LUA_ErrInvalid(L, "mobj_t"); if (newscale < FRACUNIT/100) @@ -599,6 +781,7 @@ static int lib_pInsideANonSolidFFloor(lua_State *L) mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); ffloor_t *rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR)); //HUDSAFE + INLEVEL if (!mobj) return LUA_ErrInvalid(L, "mobj_t"); if (!rover) @@ -611,6 +794,7 @@ static int lib_pCheckDeathPitCollide(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); //HUDSAFE + INLEVEL if (!mo) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_CheckDeathPitCollide(mo)); @@ -622,6 +806,7 @@ static int lib_pCheckSolidLava(lua_State *L) mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); ffloor_t *rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR)); //HUDSAFE + INLEVEL if (!mo) return LUA_ErrInvalid(L, "mobj_t"); if (!rover) @@ -635,6 +820,7 @@ static int lib_pCanRunOnWater(lua_State *L) player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); ffloor_t *rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR)); //HUDSAFE + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); if (!rover) @@ -643,6 +829,19 @@ static int lib_pCanRunOnWater(lua_State *L) return 1; } +static int lib_pMaceRotate(lua_State *L) +{ + mobj_t *center = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + INT32 baserot = luaL_checkinteger(L, 2); + INT32 baseprevrot = luaL_checkinteger(L, 3); + NOHUD + INLEVEL + if (!center) + return LUA_ErrInvalid(L, "mobj_t"); + P_MaceRotate(center, baserot, baseprevrot); + return 0; +} + // P_USER //////////// @@ -650,6 +849,7 @@ static int lib_pGetPlayerHeight(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); //HUDSAFE + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); lua_pushfixed(L, P_GetPlayerHeight(player)); @@ -660,6 +860,7 @@ static int lib_pGetPlayerSpinHeight(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); //HUDSAFE + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); lua_pushfixed(L, P_GetPlayerSpinHeight(player)); @@ -670,6 +871,7 @@ static int lib_pGetPlayerControlDirection(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); //HUDSAFE + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); lua_pushinteger(L, P_GetPlayerControlDirection(player)); @@ -681,16 +883,41 @@ static int lib_pAddPlayerScore(lua_State *L) player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); UINT32 amount = (UINT32)luaL_checkinteger(L, 2); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_AddPlayerScore(player, amount); return 0; } +static int lib_pStealPlayerScore(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + UINT32 amount = (UINT32)luaL_checkinteger(L, 2); + NOHUD + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_StealPlayerScore(player, amount); + return 0; +} + +static int lib_pGetJumpFlags(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + NOHUD + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + lua_pushinteger(L, P_GetJumpFlags(player)); + return 1; +} + static int lib_pPlayerInPain(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); //HUDSAFE + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); lua_pushboolean(L, P_PlayerInPain(player)); @@ -702,6 +929,7 @@ static int lib_pDoPlayerPain(lua_State *L) player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); mobj_t *source = NULL, *inflictor = NULL; NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) @@ -716,6 +944,7 @@ static int lib_pResetPlayer(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_ResetPlayer(player); @@ -726,6 +955,7 @@ static int lib_pIsObjectInGoop(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); //HUDSAFE + INLEVEL if (!mo) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_IsObjectInGoop(mo)); @@ -736,6 +966,7 @@ static int lib_pIsObjectOnGround(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); //HUDSAFE + INLEVEL if (!mo) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_IsObjectOnGround(mo)); @@ -746,6 +977,7 @@ static int lib_pInSpaceSector(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); //HUDSAFE + INLEVEL if (!mo) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_InSpaceSector(mo)); @@ -756,6 +988,7 @@ static int lib_pInQuicksand(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); //HUDSAFE + INLEVEL if (!mo) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_InQuicksand(mo)); @@ -768,6 +1001,7 @@ static int lib_pSetObjectMomZ(lua_State *L) fixed_t value = luaL_checkfixed(L, 2); boolean relative = lua_optboolean(L, 3); NOHUD + INLEVEL if (!mo) return LUA_ErrInvalid(L, "mobj_t"); P_SetObjectMomZ(mo, value, relative); @@ -778,6 +1012,7 @@ static int lib_pRestoreMusic(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); if (P_IsLocalPlayer(player)) @@ -789,6 +1024,7 @@ static int lib_pSpawnShieldOrb(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_SpawnShieldOrb(player); @@ -799,6 +1035,7 @@ static int lib_pSpawnGhostMobj(lua_State *L) { mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); NOHUD + INLEVEL if (!mobj) return LUA_ErrInvalid(L, "mobj_t"); LUA_PushUserdata(L, P_SpawnGhostMobj(mobj), META_MOBJ); @@ -810,6 +1047,7 @@ static int lib_pGivePlayerRings(lua_State *L) player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); INT32 num_rings = (INT32)luaL_checkinteger(L, 2); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_GivePlayerRings(player, num_rings); @@ -821,16 +1059,31 @@ static int lib_pGivePlayerLives(lua_State *L) player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); INT32 numlives = (INT32)luaL_checkinteger(L, 2); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_GivePlayerLives(player, numlives); return 0; } +static int lib_pGiveCoopLives(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + INT32 numlives = (INT32)luaL_checkinteger(L, 2); + boolean sound = (boolean)lua_opttrueboolean(L, 3); + NOHUD + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_GiveCoopLives(player, numlives, sound); + return 0; +} + static int lib_pResetScore(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_ResetScore(player); @@ -841,29 +1094,44 @@ static int lib_pDoJumpShield(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_DoJumpShield(player); return 0; } +static int lib_pDoBubbleBounce(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + NOHUD + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_DoBubbleBounce(player); + return 0; +} + static int lib_pBlackOw(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_BlackOw(player); return 0; } -static int lib_pElementalFireTrail(lua_State *L) +static int lib_pElementalFire(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + boolean cropcircle = lua_optboolean(L, 2); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); - P_ElementalFireTrail(player); + P_ElementalFire(player, cropcircle); return 0; } @@ -871,6 +1139,7 @@ static int lib_pDoPlayerExit(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_DoPlayerExit(player); @@ -883,6 +1152,7 @@ static int lib_pInstaThrust(lua_State *L) angle_t angle = luaL_checkangle(L, 2); fixed_t move = luaL_checkfixed(L, 3); NOHUD + INLEVEL if (!mo) return LUA_ErrInvalid(L, "mobj_t"); P_InstaThrust(mo, angle, move); @@ -918,10 +1188,13 @@ static int lib_pReturnThrustY(lua_State *L) static int lib_pLookForEnemies(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + boolean nonenemies = lua_opttrueboolean(L, 2); + boolean bullet = lua_optboolean(L, 3); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); - lua_pushboolean(L, P_LookForEnemies(player)); + LUA_PushUserdata(L, P_LookForEnemies(player, nonenemies, bullet), META_MOBJ); return 1; } @@ -931,6 +1204,7 @@ static int lib_pNukeEnemies(lua_State *L) mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); fixed_t radius = luaL_checkfixed(L, 3); NOHUD + INLEVEL if (!inflictor || !source) return LUA_ErrInvalid(L, "mobj_t"); P_NukeEnemies(inflictor, source, radius); @@ -942,6 +1216,7 @@ static int lib_pHomingAttack(lua_State *L) mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *enemy = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); NOHUD + INLEVEL if (!source || !enemy) return LUA_ErrInvalid(L, "mobj_t"); P_HomingAttack(source, enemy); @@ -952,6 +1227,7 @@ static int lib_pSuperReady(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); //HUDSAFE + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); lua_pushboolean(L, P_SuperReady(player)); @@ -963,6 +1239,7 @@ static int lib_pDoJump(lua_State *L) player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); boolean soundandstate = (boolean)lua_opttrueboolean(L, 2); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_DoJump(player, soundandstate); @@ -973,6 +1250,7 @@ static int lib_pSpawnThokMobj(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_SpawnThokMobj(player); @@ -984,6 +1262,7 @@ static int lib_pSpawnSpinMobj(lua_State *L) player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); mobjtype_t type = luaL_checkinteger(L, 2); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); if (type >= NUMMOBJTYPES) @@ -998,12 +1277,25 @@ static int lib_pTelekinesis(lua_State *L) fixed_t thrust = luaL_checkfixed(L, 2); fixed_t range = luaL_checkfixed(L, 3); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_Telekinesis(player, thrust, range); return 0; } +static int lib_pSwitchShield(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + UINT16 shield = luaL_checkinteger(L, 2); + NOHUD + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_SwitchShield(player, shield); + return 0; +} + // P_MAP /////////// @@ -1014,6 +1306,7 @@ static int lib_pCheckPosition(lua_State *L) fixed_t x = luaL_checkfixed(L, 2); fixed_t y = luaL_checkfixed(L, 3); NOHUD + INLEVEL if (!thing) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_CheckPosition(thing, x, y)); @@ -1030,6 +1323,7 @@ static int lib_pTryMove(lua_State *L) fixed_t y = luaL_checkfixed(L, 3); boolean allowdropoff = lua_optboolean(L, 4); NOHUD + INLEVEL if (!thing) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_TryMove(thing, x, y, allowdropoff)); @@ -1044,6 +1338,7 @@ static int lib_pMove(lua_State *L) mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); fixed_t speed = luaL_checkfixed(L, 2); NOHUD + INLEVEL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_Move(actor, speed)); @@ -1060,6 +1355,7 @@ static int lib_pTeleportMove(lua_State *L) fixed_t y = luaL_checkfixed(L, 3); fixed_t z = luaL_checkfixed(L, 4); NOHUD + INLEVEL if (!thing) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_TeleportMove(thing, x, y, z)); @@ -1072,6 +1368,7 @@ static int lib_pSlideMove(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); NOHUD + INLEVEL if (!mo) return LUA_ErrInvalid(L, "mobj_t"); P_SlideMove(mo); @@ -1082,6 +1379,7 @@ static int lib_pBounceMove(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); NOHUD + INLEVEL if (!mo) return LUA_ErrInvalid(L, "mobj_t"); P_BounceMove(mo); @@ -1093,6 +1391,7 @@ static int lib_pCheckSight(lua_State *L) mobj_t *t1 = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *t2 = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); //HUDSAFE? + INLEVEL if (!t1 || !t2) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_CheckSight(t1, t2)); @@ -1107,6 +1406,7 @@ static int lib_pCheckHoopPosition(lua_State *L) fixed_t z = luaL_checkfixed(L, 4); fixed_t radius = luaL_checkfixed(L, 5); NOHUD + INLEVEL if (!hoopthing) return LUA_ErrInvalid(L, "mobj_t"); P_CheckHoopPosition(hoopthing, x, y, z, radius); @@ -1118,10 +1418,12 @@ static int lib_pRadiusAttack(lua_State *L) mobj_t *spot = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); fixed_t damagedist = luaL_checkfixed(L, 3); + UINT8 damagetype = luaL_optinteger(L, 4, 0); NOHUD + INLEVEL if (!spot || !source) return LUA_ErrInvalid(L, "mobj_t"); - P_RadiusAttack(spot, source, damagedist); + P_RadiusAttack(spot, source, damagedist, damagetype); return 0; } @@ -1132,6 +1434,7 @@ static int lib_pFloorzAtPos(lua_State *L) fixed_t z = luaL_checkfixed(L, 3); fixed_t height = luaL_checkfixed(L, 4); //HUDSAFE + INLEVEL lua_pushfixed(L, P_FloorzAtPos(x, y, z, height)); return 1; } @@ -1141,6 +1444,7 @@ static int lib_pDoSpring(lua_State *L) mobj_t *spring = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *object = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); NOHUD + INLEVEL if (!spring || !object) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_DoSpring(spring, object)); @@ -1154,6 +1458,7 @@ static int lib_pRemoveShield(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_RemoveShield(player); @@ -1164,7 +1469,9 @@ static int lib_pDamageMobj(lua_State *L) { mobj_t *target = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)), *inflictor = NULL, *source = NULL; INT32 damage; + UINT8 damagetype; NOHUD + INLEVEL if (!target) return LUA_ErrInvalid(L, "mobj_t"); if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) @@ -1172,21 +1479,25 @@ static int lib_pDamageMobj(lua_State *L) if (!lua_isnone(L, 3) && lua_isuserdata(L, 3)) source = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); damage = (INT32)luaL_optinteger(L, 4, 1); - lua_pushboolean(L, P_DamageMobj(target, inflictor, source, damage)); + damagetype = (UINT8)luaL_optinteger(L, 5, 0); + lua_pushboolean(L, P_DamageMobj(target, inflictor, source, damage, damagetype)); return 1; } static int lib_pKillMobj(lua_State *L) { mobj_t *target = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)), *inflictor = NULL, *source = NULL; + UINT8 damagetype; NOHUD + INLEVEL if (!target) return LUA_ErrInvalid(L, "mobj_t"); if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) inflictor = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); if (!lua_isnone(L, 3) && lua_isuserdata(L, 3)) source = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); - P_KillMobj(target, inflictor, source); + damagetype = (UINT8)luaL_optinteger(L, 4, 0); + P_KillMobj(target, inflictor, source, damagetype); return 0; } @@ -1195,10 +1506,11 @@ static int lib_pPlayerRingBurst(lua_State *L) player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); INT32 num_rings = (INT32)luaL_optinteger(L, 2, -1); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); if (num_rings == -1) - num_rings = player->health - 1; + num_rings = player->rings; P_PlayerRingBurst(player, num_rings); return 0; } @@ -1207,6 +1519,7 @@ static int lib_pPlayerWeaponPanelBurst(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_PlayerWeaponPanelBurst(player); @@ -1217,17 +1530,30 @@ static int lib_pPlayerWeaponAmmoBurst(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_PlayerWeaponAmmoBurst(player); return 0; } +static int lib_pPlayerWeaponPanelOrAmmoBurst(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + NOHUD + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_PlayerWeaponPanelOrAmmoBurst(player); + return 0; +} + static int lib_pPlayerEmeraldBurst(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); boolean toss = lua_optboolean(L, 2); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_PlayerEmeraldBurst(player, toss); @@ -1239,6 +1565,7 @@ static int lib_pPlayerFlagBurst(lua_State *L) player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); boolean toss = lua_optboolean(L, 2); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_PlayerFlagBurst(player, toss); @@ -1250,6 +1577,7 @@ static int lib_pPlayRinglossSound(lua_State *L) mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); player_t *player = NULL; NOHUD + INLEVEL if (!source) return LUA_ErrInvalid(L, "mobj_t"); if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) @@ -1268,6 +1596,7 @@ static int lib_pPlayDeathSound(lua_State *L) mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); player_t *player = NULL; NOHUD + INLEVEL if (!source) return LUA_ErrInvalid(L, "mobj_t"); if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) @@ -1286,6 +1615,7 @@ static int lib_pPlayVictorySound(lua_State *L) mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); player_t *player = NULL; NOHUD + INLEVEL if (!source) return LUA_ErrInvalid(L, "mobj_t"); if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) @@ -1303,6 +1633,7 @@ static int lib_pPlayLivesJingle(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_PlayLivesJingle(player); @@ -1314,6 +1645,7 @@ static int lib_pCanPickupItem(lua_State *L) player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); boolean weapon = lua_optboolean(L, 2); //HUDSAFE + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); lua_pushboolean(L, P_CanPickupItem(player, weapon)); @@ -1324,12 +1656,24 @@ static int lib_pDoNightsScore(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_DoNightsScore(player); return 0; } +static int lib_pDoMatchSuper(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + NOHUD + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_DoMatchSuper(player); + return 0; +} + // P_SPEC //////////// @@ -1339,6 +1683,7 @@ static int lib_pThrust(lua_State *L) angle_t angle = luaL_checkangle(L, 2); fixed_t move = luaL_checkfixed(L, 3); NOHUD + INLEVEL if (!mo) return LUA_ErrInvalid(L, "mobj_t"); P_Thrust(mo, angle, move); @@ -1350,6 +1695,7 @@ static int lib_pSetMobjStateNF(lua_State *L) mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); statenum_t state = luaL_checkinteger(L, 2); NOHUD + INLEVEL if (!mobj) return LUA_ErrInvalid(L, "mobj_t"); if (state >= NUMSTATES) @@ -1365,6 +1711,7 @@ static int lib_pDoSuperTransformation(lua_State *L) player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); boolean giverings = lua_optboolean(L, 2); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_DoSuperTransformation(player, giverings); @@ -1375,6 +1722,7 @@ static int lib_pExplodeMissile(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); NOHUD + INLEVEL if (!mo) return LUA_ErrInvalid(L, "mobj_t"); P_ExplodeMissile(mo); @@ -1387,18 +1735,92 @@ static int lib_pPlayerTouchingSectorSpecial(lua_State *L) INT32 section = (INT32)luaL_checkinteger(L, 2); INT32 number = (INT32)luaL_checkinteger(L, 3); //HUDSAFE + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); LUA_PushUserdata(L, P_PlayerTouchingSectorSpecial(player, section, number), META_SECTOR); return 1; } +static int lib_pFindLowestFloorSurrounding(lua_State *L) +{ + sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); + //HUDSAFE + INLEVEL + if (!sector) + return LUA_ErrInvalid(L, "sector_t"); + lua_pushfixed(L, P_FindLowestFloorSurrounding(sector)); + return 1; +} + +static int lib_pFindHighestFloorSurrounding(lua_State *L) +{ + sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); + //HUDSAFE + INLEVEL + if (!sector) + return LUA_ErrInvalid(L, "sector_t"); + lua_pushfixed(L, P_FindHighestFloorSurrounding(sector)); + return 1; +} + +static int lib_pFindNextHighestFloor(lua_State *L) +{ + sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); + fixed_t currentheight; + //HUDSAFE + INLEVEL + if (!sector) + return LUA_ErrInvalid(L, "sector_t"); + // defaults to floorheight of sector arg + currentheight = (fixed_t)luaL_optinteger(L, 2, sector->floorheight); + lua_pushfixed(L, P_FindNextHighestFloor(sector, currentheight)); + return 1; +} + +static int lib_pFindNextLowestFloor(lua_State *L) +{ + sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); + fixed_t currentheight; + //HUDSAFE + INLEVEL + if (!sector) + return LUA_ErrInvalid(L, "sector_t"); + // defaults to floorheight of sector arg + currentheight = (fixed_t)luaL_optinteger(L, 2, sector->floorheight); + lua_pushfixed(L, P_FindNextLowestFloor(sector, currentheight)); + return 1; +} + +static int lib_pFindLowestCeilingSurrounding(lua_State *L) +{ + sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); + //HUDSAFE + INLEVEL + if (!sector) + return LUA_ErrInvalid(L, "sector_t"); + lua_pushfixed(L, P_FindLowestCeilingSurrounding(sector)); + return 1; +} + +static int lib_pFindHighestCeilingSurrounding(lua_State *L) +{ + sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); + //HUDSAFE + INLEVEL + if (!sector) + return LUA_ErrInvalid(L, "sector_t"); + lua_pushfixed(L, P_FindHighestCeilingSurrounding(sector)); + return 1; +} + static int lib_pFindSpecialLineFromTag(lua_State *L) { INT16 special = (INT16)luaL_checkinteger(L, 1); INT16 line = (INT16)luaL_checkinteger(L, 2); INT32 start = (INT32)luaL_optinteger(L, 3, -1); NOHUD + INLEVEL lua_pushinteger(L, P_FindSpecialLineFromTag(special, line, start)); return 1; } @@ -1408,6 +1830,7 @@ static int lib_pSwitchWeather(lua_State *L) INT32 weathernum = (INT32)luaL_checkinteger(L, 1); player_t *user = NULL; NOHUD + INLEVEL if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) // if a player, setup weather for only the player, otherwise setup weather for all players user = *((player_t **)luaL_checkudata(L, 2, META_PLAYER)); if (!user) // global @@ -1423,6 +1846,7 @@ static int lib_pLinedefExecute(lua_State *L) mobj_t *actor = NULL; sector_t *caller = NULL; NOHUD + INLEVEL if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) actor = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); if (!lua_isnone(L, 3) && lua_isuserdata(L, 3)) @@ -1435,6 +1859,7 @@ static int lib_pSpawnLightningFlash(lua_State *L) { sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); NOHUD + INLEVEL if (!sector) return LUA_ErrInvalid(L, "sector_t"); P_SpawnLightningFlash(sector); @@ -1446,8 +1871,11 @@ static int lib_pFadeLight(lua_State *L) INT16 tag = (INT16)luaL_checkinteger(L, 1); INT32 destvalue = (INT32)luaL_checkinteger(L, 2); INT32 speed = (INT32)luaL_checkinteger(L, 3); + boolean ticbased = lua_optboolean(L, 4); + boolean force = lua_optboolean(L, 5); NOHUD - P_FadeLight(tag, destvalue, speed); + INLEVEL + P_FadeLight(tag, destvalue, speed, ticbased, force); return 0; } @@ -1455,6 +1883,7 @@ static int lib_pThingOnSpecial3DFloor(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); NOHUD + INLEVEL if (!mo) return LUA_ErrInvalid(L, "mobj_t"); LUA_PushUserdata(L, P_ThingOnSpecial3DFloor(mo), META_SECTOR); @@ -1465,6 +1894,7 @@ static int lib_pIsFlagAtBase(lua_State *L) { mobjtype_t flag = luaL_checkinteger(L, 1); NOHUD + INLEVEL if (flag >= NUMMOBJTYPES) return luaL_error(L, "mobj type %d out of range (0 - %d)", flag, NUMMOBJTYPES-1); lua_pushboolean(L, P_IsFlagAtBase(flag)); @@ -1476,6 +1906,7 @@ static int lib_pSetupLevelSky(lua_State *L) INT32 skynum = (INT32)luaL_checkinteger(L, 1); player_t *user = NULL; NOHUD + INLEVEL if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) // if a player, setup sky for only the player, otherwise setup sky for all players user = *((player_t **)luaL_checkudata(L, 2, META_PLAYER)); if (!user) // global @@ -1494,6 +1925,7 @@ static int lib_pSetSkyboxMobj(lua_State *L) int w = 0; NOHUD + INLEVEL if (!lua_isnil(L,1)) // nil leaves mo as NULL to remove the skybox rendering. { mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); // otherwise it is a skybox mobj. @@ -1540,6 +1972,7 @@ static int lib_pStartQuake(lua_State *L) static mappoint_t q_epicenter = {0,0,0}; NOHUD + INLEVEL // While technically we don't support epicenter and radius, // we get their values anyway if they exist. @@ -1601,6 +2034,7 @@ static int lib_evCrumbleChain(lua_State *L) sector_t *sec = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); ffloor_t *rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR)); NOHUD + INLEVEL if (!sec) return LUA_ErrInvalid(L, "sector_t"); if (!rover) @@ -1609,6 +2043,33 @@ static int lib_evCrumbleChain(lua_State *L) return 0; } +static int lib_evStartCrumble(lua_State *L) +{ + sector_t *sec = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); + ffloor_t *rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR)); + boolean floating = lua_optboolean(L, 3); + player_t *player = NULL; + fixed_t origalpha; + boolean crumblereturn = lua_optboolean(L, 6); + NOHUD + if (!sec) + return LUA_ErrInvalid(L, "sector_t"); + if (!rover) + return LUA_ErrInvalid(L, "ffloor_t"); + if (!lua_isnone(L, 4) && lua_isuserdata(L, 4)) + { + player = *((player_t **)luaL_checkudata(L, 4, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!lua_isnone(L,5)) + origalpha = luaL_checkfixed(L, 5); + else + origalpha = rover->alpha; + lua_pushboolean(L, EV_StartCrumble(sec, rover, floating, player, origalpha, crumblereturn) != 0); + return 0; +} + #ifdef ESLOPE // P_SLOPES //////////// @@ -1675,6 +2136,7 @@ static int lib_rPointInSubsector(lua_State *L) fixed_t x = luaL_checkfixed(L, 1); fixed_t y = luaL_checkfixed(L, 2); //HUDSAFE + INLEVEL LUA_PushUserdata(L, R_PointInSubsector(x, y), META_SUBSECTOR); return 1; } @@ -1709,6 +2171,7 @@ static int lib_rSetPlayerSkin(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); NOHUD + INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); if (lua_isnoneornil(L, 2)) @@ -2022,6 +2485,7 @@ static int lib_sOriginPlaying(lua_State *L) { void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); NOHUD + INLEVEL if (!origin) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, S_OriginPlaying(origin)); @@ -2043,6 +2507,7 @@ static int lib_sSoundPlaying(lua_State *L) void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); sfxenum_t id = luaL_checkinteger(L, 2); NOHUD + INLEVEL if (!origin) return LUA_ErrInvalid(L, "mobj_t"); if (id >= NUMSFX) @@ -2051,6 +2516,31 @@ static int lib_sSoundPlaying(lua_State *L) return 1; } +// This doesn't really exist, but we're providing it as a handy netgame-safe wrapper for stuff that should be locally handled. + +static int lib_sStartMusicCaption(lua_State *L) +{ + player_t *player = NULL; + const char *caption = luaL_checkstring(L, 1); + UINT16 lifespan = (UINT16)luaL_checkinteger(L, 2); + //HUDSAFE + INLEVEL + + if (!lua_isnone(L, 3) && lua_isuserdata(L, 3)) + { + player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + + if (lifespan && (!player || P_IsLocalPlayer(player))) + { + strlcpy(S_sfx[sfx_None].caption, caption, sizeof(S_sfx[sfx_None].caption)); + S_StartCaption(sfx_None, -1, lifespan); + } + return 0; +} + // G_GAME //////////// @@ -2058,6 +2548,7 @@ static int lib_gBuildMapName(lua_State *L) { INT32 map = luaL_optinteger(L, 1, gamemap); //HUDSAFE + INLEVEL lua_pushstring(L, G_BuildMapName(map)); return 1; } @@ -2066,6 +2557,7 @@ static int lib_gDoReborn(lua_State *L) { INT32 playernum = luaL_checkinteger(L, 1); NOHUD + INLEVEL if (playernum >= MAXPLAYERS) return luaL_error(L, "playernum %d out of range (0 - %d)", playernum, MAXPLAYERS-1); G_DoReborn(playernum); @@ -2078,6 +2570,7 @@ static int lib_gSetCustomExitVars(lua_State *L) { int n = lua_gettop(L); // Num arguments NOHUD + INLEVEL // LUA EXTENSION: Custom exit like support // Supported: @@ -2119,6 +2612,7 @@ static int lib_gIsSpecialStage(lua_State *L) { INT32 mapnum = luaL_optinteger(L, 1, gamemap); //HUDSAFE + INLEVEL lua_pushboolean(L, G_IsSpecialStage(mapnum)); return 1; } @@ -2126,6 +2620,7 @@ static int lib_gIsSpecialStage(lua_State *L) static int lib_gGametypeUsesLives(lua_State *L) { //HUDSAFE + INLEVEL lua_pushboolean(L, G_GametypeUsesLives()); return 1; } @@ -2133,6 +2628,7 @@ static int lib_gGametypeUsesLives(lua_State *L) static int lib_gGametypeHasTeams(lua_State *L) { //HUDSAFE + INLEVEL lua_pushboolean(L, G_GametypeHasTeams()); return 1; } @@ -2140,6 +2636,7 @@ static int lib_gGametypeHasTeams(lua_State *L) static int lib_gGametypeHasSpectators(lua_State *L) { //HUDSAFE + INLEVEL lua_pushboolean(L, G_GametypeHasSpectators()); return 1; } @@ -2147,6 +2644,7 @@ static int lib_gGametypeHasSpectators(lua_State *L) static int lib_gRingSlingerGametype(lua_State *L) { //HUDSAFE + INLEVEL lua_pushboolean(L, G_RingSlingerGametype()); return 1; } @@ -2154,6 +2652,7 @@ static int lib_gRingSlingerGametype(lua_State *L) static int lib_gPlatformGametype(lua_State *L) { //HUDSAFE + INLEVEL lua_pushboolean(L, G_PlatformGametype()); return 1; } @@ -2161,6 +2660,7 @@ static int lib_gPlatformGametype(lua_State *L) static int lib_gTagGametype(lua_State *L) { //HUDSAFE + INLEVEL lua_pushboolean(L, G_TagGametype()); return 1; } @@ -2210,7 +2710,7 @@ static luaL_Reg lib[] = { {"print", lib_print}, {"chatprint", lib_chatprint}, {"chatprintf", lib_chatprintf}, - {"EvalMath", lib_evalMath}, + {"userdataType", lib_userdataType}, {"IsPlayerAdmin", lib_isPlayerAdmin}, // m_random @@ -2218,13 +2718,13 @@ static luaL_Reg lib[] = { {"P_RandomByte",lib_pRandomByte}, {"P_RandomKey",lib_pRandomKey}, {"P_RandomRange",lib_pRandomRange}, - {"P_Random",lib_pRandom}, // DEPRECATED {"P_SignedRandom",lib_pSignedRandom}, // MACRO {"P_RandomChance",lib_pRandomChance}, // MACRO // p_maputil {"P_AproxDistance",lib_pAproxDistance}, {"P_ClosestPointOnLine",lib_pClosestPointOnLine}, + {"P_PointOnLineSide",lib_pPointOnLineSide}, // p_enemy {"P_CheckMeleeRange", lib_pCheckMeleeRange}, @@ -2238,7 +2738,10 @@ static luaL_Reg lib[] = { // p_mobj // don't add P_SetMobjState or P_SetPlayerMobjState, use "mobj.state = S_NEWSTATE" instead. {"P_SpawnMobj",lib_pSpawnMobj}, + {"P_SpawnMobjFromMobj",lib_pSpawnMobjFromMobj}, {"P_RemoveMobj",lib_pRemoveMobj}, + {"P_IsValidSprite2", lib_pIsValidSprite2}, + {"P_SpawnLockOn", lib_pSpawnLockOn}, {"P_SpawnMissile",lib_pSpawnMissile}, {"P_SpawnXYZMissile",lib_pSpawnXYZMissile}, {"P_SpawnPointMissile",lib_pSpawnPointMissile}, @@ -2259,12 +2762,15 @@ static luaL_Reg lib[] = { {"P_CheckDeathPitCollide",lib_pCheckDeathPitCollide}, {"P_CheckSolidLava",lib_pCheckSolidLava}, {"P_CanRunOnWater",lib_pCanRunOnWater}, + {"P_MaceRotate",lib_pMaceRotate}, // p_user {"P_GetPlayerHeight",lib_pGetPlayerHeight}, {"P_GetPlayerSpinHeight",lib_pGetPlayerSpinHeight}, {"P_GetPlayerControlDirection",lib_pGetPlayerControlDirection}, {"P_AddPlayerScore",lib_pAddPlayerScore}, + {"P_StealPlayerScore",lib_pStealPlayerScore}, + {"P_GetJumpFlags",lib_pGetJumpFlags}, {"P_PlayerInPain",lib_pPlayerInPain}, {"P_DoPlayerPain",lib_pDoPlayerPain}, {"P_ResetPlayer",lib_pResetPlayer}, @@ -2278,10 +2784,12 @@ static luaL_Reg lib[] = { {"P_SpawnGhostMobj",lib_pSpawnGhostMobj}, {"P_GivePlayerRings",lib_pGivePlayerRings}, {"P_GivePlayerLives",lib_pGivePlayerLives}, + {"P_GiveCoopLives",lib_pGiveCoopLives}, {"P_ResetScore",lib_pResetScore}, {"P_DoJumpShield",lib_pDoJumpShield}, + {"P_DoBubbleBounce",lib_pDoBubbleBounce}, {"P_BlackOw",lib_pBlackOw}, - {"P_ElementalFireTrail",lib_pElementalFireTrail}, + {"P_ElementalFire",lib_pElementalFire}, {"P_DoPlayerExit",lib_pDoPlayerExit}, {"P_InstaThrust",lib_pInstaThrust}, {"P_ReturnThrustX",lib_pReturnThrustX}, @@ -2294,6 +2802,7 @@ static luaL_Reg lib[] = { {"P_SpawnThokMobj",lib_pSpawnThokMobj}, {"P_SpawnSpinMobj",lib_pSpawnSpinMobj}, {"P_Telekinesis",lib_pTelekinesis}, + {"P_SwitchShield",lib_pSwitchShield}, // p_map {"P_CheckPosition",lib_pCheckPosition}, @@ -2315,6 +2824,7 @@ static luaL_Reg lib[] = { {"P_PlayerRingBurst",lib_pPlayerRingBurst}, {"P_PlayerWeaponPanelBurst",lib_pPlayerWeaponPanelBurst}, {"P_PlayerWeaponAmmoBurst",lib_pPlayerWeaponAmmoBurst}, + {"P_PlayerWeaponPanelOrAmmoBurst", lib_pPlayerWeaponPanelOrAmmoBurst}, {"P_PlayerEmeraldBurst",lib_pPlayerEmeraldBurst}, {"P_PlayerFlagBurst",lib_pPlayerFlagBurst}, {"P_PlayRinglossSound",lib_pPlayRinglossSound}, @@ -2323,6 +2833,7 @@ static luaL_Reg lib[] = { {"P_PlayLivesJingle",lib_pPlayLivesJingle}, {"P_CanPickupItem",lib_pCanPickupItem}, {"P_DoNightsScore",lib_pDoNightsScore}, + {"P_DoMatchSuper",lib_pDoMatchSuper}, // p_spec {"P_Thrust",lib_pThrust}, @@ -2330,6 +2841,12 @@ static luaL_Reg lib[] = { {"P_DoSuperTransformation",lib_pDoSuperTransformation}, {"P_ExplodeMissile",lib_pExplodeMissile}, {"P_PlayerTouchingSectorSpecial",lib_pPlayerTouchingSectorSpecial}, + {"P_FindLowestFloorSurrounding",lib_pFindLowestFloorSurrounding}, + {"P_FindHighestFloorSurrounding",lib_pFindHighestFloorSurrounding}, + {"P_FindNextHighestFloor",lib_pFindNextHighestFloor}, + {"P_FindNextLowestFloor",lib_pFindNextLowestFloor}, + {"P_FindLowestCeilingSurrounding",lib_pFindLowestCeilingSurrounding}, + {"P_FindHighestCeilingSurrounding",lib_pFindHighestCeilingSurrounding}, {"P_FindSpecialLineFromTag",lib_pFindSpecialLineFromTag}, {"P_SwitchWeather",lib_pSwitchWeather}, {"P_LinedefExecute",lib_pLinedefExecute}, @@ -2341,6 +2858,7 @@ static luaL_Reg lib[] = { {"P_SetSkyboxMobj",lib_pSetSkyboxMobj}, {"P_StartQuake",lib_pStartQuake}, {"EV_CrumbleChain",lib_evCrumbleChain}, + {"EV_StartCrumble",lib_evStartCrumble}, #ifdef ESLOPE // p_slopes @@ -2377,6 +2895,7 @@ static luaL_Reg lib[] = { {"S_OriginPlaying",lib_sOriginPlaying}, {"S_IdPlaying",lib_sIdPlaying}, {"S_SoundPlaying",lib_sSoundPlaying}, + {"S_StartMusicCaption", lib_sStartMusicCaption}, // g_game {"G_BuildMapName",lib_gBuildMapName}, diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index dced4e43c169c8cfe17d5cea81e65c5f9dec0311..98d18d8db06713c4eed15cc9b5364d858956589d 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -22,7 +22,15 @@ #include "lua_libs.h" #include "lua_hud.h" // hud_running errors -#define NOHUD if (hud_running) return luaL_error(L, "HUD rendering code should not call this function!"); +// for functions not allowed in hud.add hooks +#define NOHUD if (hud_running)\ +return luaL_error(L, "HUD rendering code should not call this function!"); +// for functions not allowed in hooks or coroutines (supercedes above) +#define NOHOOK if (!lua_lumploading)\ + return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); +// for functions only allowed within a level +#define INLEVEL if (gamestate != GS_LEVEL)\ +return luaL_error(L, "This function can only be used in a level!"); static const char *cvname = NULL; @@ -83,7 +91,7 @@ deny: CONS_Alert(CONS_WARNING, M_GetText("Illegal lua command received from %s\n"), player_names[playernum]); if (server) { - XBOXSTATIC UINT8 bufn[2]; + UINT8 bufn[2]; bufn[0] = (UINT8)playernum; bufn[1] = KICK_MSG_CON_FAIL; @@ -183,7 +191,7 @@ static int lib_comAddCommand(lua_State *L) strlwr(name); luaL_checktype(L, 2, LUA_TFUNCTION); - NOHUD + NOHOOK if (lua_gettop(L) >= 3) { // For the third argument, only take a boolean or a number. lua_settop(L, 3); @@ -295,7 +303,7 @@ static int lib_cvRegisterVar(lua_State *L) consvar_t *cvar; luaL_checktype(L, 1, LUA_TTABLE); lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one. - NOHUD + NOHOOK cvar = lua_newuserdata(L, sizeof(consvar_t)); luaL_getmetatable(L, META_CVAR); lua_setmetatable(L, -2); @@ -423,6 +431,7 @@ static int lib_consPrintf(lua_State *L) if (n < 2) return luaL_error(L, "CONS_Printf requires at least two arguments: player and text."); //HUDSAFE + INLEVEL plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); if (!plr) return LUA_ErrInvalid(L, "player_t"); diff --git a/src/lua_hook.h b/src/lua_hook.h index 252960edf50ee88072262f0d57d28569f32182d2..9fcc365940a785ca021f524eb5587d2c0e021b1e 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -43,6 +43,11 @@ enum hook { hook_PlayerMsg, hook_HurtMsg, hook_PlayerSpawn, + hook_ShieldSpawn, + hook_ShieldSpecial, + hook_MobjMoveBlocked, + hook_MapThingSpawn, + hook_FollowMobj, hook_PlayerQuit, hook_MAX // last hook @@ -63,21 +68,26 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher); // Hook for P_Touch #define LUAh_MobjFuse(mo) LUAh_MobjHook(mo, hook_MobjFuse) // Hook for mobj->fuse == 0 by mobj type boolean LUAh_MobjThinker(mobj_t *mo); // Hook for P_MobjThinker or P_SceneryThinker by mobj type #define LUAh_BossThinker(mo) LUAh_MobjHook(mo, hook_BossThinker) // Hook for P_GenericBossThinker by mobj type -UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage); // Hook for P_DamageMobj by mobj type (Should mobj take damage?) -boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage); // Hook for P_DamageMobj by mobj type (Mobj actually takes damage!) -boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source); // Hook for P_KillMobj by mobj type +UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); // Hook for P_DamageMobj by mobj type (Should mobj take damage?) +boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); // Hook for P_DamageMobj by mobj type (Mobj actually takes damage!) +boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for P_KillMobj by mobj type #define LUAh_BossDeath(mo) LUAh_MobjHook(mo, hook_BossDeath) // Hook for A_BossDeath by mobj type #define LUAh_MobjRemoved(mo) LUAh_MobjHook(mo, hook_MobjRemoved) // Hook for P_RemoveMobj by mobj type #define LUAh_JumpSpecial(player) LUAh_PlayerHook(player, hook_JumpSpecial) // Hook for P_DoJumpStuff (Any-jumping) #define LUAh_AbilitySpecial(player) LUAh_PlayerHook(player, hook_AbilitySpecial) // Hook for P_DoJumpStuff (Double-jumping) -#define LUAh_SpinSpecial(player) LUAh_PlayerHook(player, hook_SpinSpecial) // Hook for P_DoSpinDash (Spin button effect) +#define LUAh_SpinSpecial(player) LUAh_PlayerHook(player, hook_SpinSpecial) // Hook for P_DoSpinAbility (Spin button effect) #define LUAh_JumpSpinSpecial(player) LUAh_PlayerHook(player, hook_JumpSpinSpecial) // Hook for P_DoJumpStuff (Spin button effect (mid-air)) boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages -boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages +boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for hurt messages #define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer +#define LUAh_ShieldSpawn(player) LUAh_PlayerHook(player, hook_ShieldSpawn) // Hook for P_SpawnShieldOrb +#define LUAh_ShieldSpecial(player) LUAh_PlayerHook(player, hook_ShieldSpecial) // Hook for shield abilities +#define LUAh_MobjMoveBlocked(mo) LUAh_MobjHook(mo, hook_MobjMoveBlocked) // Hook for P_XYMovement (when movement is blocked) +boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnMapThing by mobj type +boolean LUAh_FollowMobj(player_t *player, mobj_t *mo); // Hook for P_PlayerAfterThink Smiles mobj-following void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 948eca84c76bf6fc138dd8d1dea5afcb918dc99b..d605499e291488eb7499b78621c944fb2ab86d5f 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -54,6 +54,11 @@ const char *const hookNames[hook_MAX+1] = { "PlayerMsg", "HurtMsg", "PlayerSpawn", + "ShieldSpawn", + "ShieldSpecial", + "MobjMoveBlocked", + "MapThingSpawn", + "FollowMobj", "PlayerQuit", NULL }; @@ -106,8 +111,8 @@ static int lib_addHook(lua_State *L) luaL_checktype(L, 1, LUA_TFUNCTION); - if (hud_running) - return luaL_error(L, "HUD rendering code should not call this function!"); + if (!lua_lumploading) + return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); switch(hook.type) { @@ -125,6 +130,8 @@ static int lib_addHook(lua_State *L) case hook_BossDeath: case hook_MobjRemoved: case hook_HurtMsg: + case hook_MobjMoveBlocked: + case hook_MapThingSpawn: hook.s.mt = MT_NULL; if (lua_isnumber(L, 2)) hook.s.mt = lua_tonumber(L, 2); @@ -183,6 +190,8 @@ static int lib_addHook(lua_State *L) case hook_MobjDeath: case hook_BossDeath: case hook_MobjRemoved: + case hook_MobjMoveBlocked: + case hook_MapThingSpawn: lastp = &mobjhooks[hook.s.mt]; break; case hook_JumpSpecial: @@ -190,6 +199,9 @@ static int lib_addHook(lua_State *L) case hook_SpinSpecial: case hook_JumpSpinSpecial: case hook_PlayerSpawn: + case hook_FollowMobj: + case hook_ShieldSpawn: + case hook_ShieldSpecial: lastp = &playerhooks; break; case hook_LinedefExecute: @@ -597,7 +609,7 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher) } // Hook for P_DamageMobj by mobj type (Should mobj take damage?) -UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage) +UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { hook_p hookp; UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no. @@ -651,14 +663,16 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damage); + lua_pushinteger(gL, damagetype); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 0)) { + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + if (lua_pcall(gL, 5, 1, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -680,7 +694,7 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 } // Hook for P_DamageMobj by mobj type (Mobj actually takes damage!) -boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage) +boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { hook_p hookp; boolean hooked = false; @@ -729,14 +743,16 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damage); + lua_pushinteger(gL, damagetype); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 0)) { + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + if (lua_pcall(gL, 5, 1, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -753,7 +769,7 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 } // Hook for P_KillMobj by mobj type -boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source) +boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype) { hook_p hookp; boolean hooked = false; @@ -799,13 +815,15 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source) LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); + lua_pushinteger(gL, damagetype); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - if (lua_pcall(gL, 3, 1, 0)) { + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + if (lua_pcall(gL, 4, 1, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1007,7 +1025,7 @@ boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg) // Hook for hurt messages -boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source) +boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype) { hook_p hookp; boolean hooked = false; @@ -1025,13 +1043,15 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source) LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); + lua_pushinteger(gL, damagetype); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - if (lua_pcall(gL, 3, 1, 0)) { + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + if (lua_pcall(gL, 4, 1, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1076,6 +1096,106 @@ void LUAh_NetArchiveHook(lua_CFunction archFunc) // stack: tables } +boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing) +{ + hook_p hookp; + boolean hooked = false; + if (!gL || !(hooksAvailable[hook_MapThingSpawn/8] & (1<<(hook_MapThingSpawn%8)))) + return false; + + lua_settop(gL, 0); + + // Look for all generic mobj map thing spawn hooks + for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) + if (hookp->type == hook_MapThingSpawn) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, mo, META_MOBJ); + LUA_PushUserdata(gL, mthing, META_MAPTHING); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); + if (lua_pcall(gL, 2, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; + lua_pop(gL, 1); + } + + for (hookp = mobjhooks[mo->type]; hookp; hookp = hookp->next) + if (hookp->type == hook_MapThingSpawn) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, mo, META_MOBJ); + LUA_PushUserdata(gL, mthing, META_MAPTHING); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); + if (lua_pcall(gL, 2, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return hooked; +} + +// Hook for P_PlayerAfterThink Smiles mobj-following +boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj) +{ + hook_p hookp; + boolean hooked = false; + if (!gL || !(hooksAvailable[hook_FollowMobj/8] & (1<<(hook_FollowMobj%8)))) + return 0; + + lua_settop(gL, 0); + + for (hookp = playerhooks; hookp; hookp = hookp->next) + if (hookp->type == hook_FollowMobj) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, player, META_PLAYER); + LUA_PushUserdata(gL, mobj, META_MOBJ); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); + if (lua_pcall(gL, 2, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return hooked; +} + void LUAh_PlayerQuit(player_t *plr, int reason) { hook_p hookp; diff --git a/src/lua_hud.h b/src/lua_hud.h index f96618e0729f48be23ae20ae7d4068fd9fc54aed..7f928f7c4a1c82de246a417173166bfd4e81cb58 100644 --- a/src/lua_hud.h +++ b/src/lua_hud.h @@ -24,7 +24,7 @@ enum hud { // NiGHTS mode hud_nightslink, hud_nightsdrill, - hud_nightsrings, + hud_nightsspheres, hud_nightsscore, hud_nightstime, hud_nightsrecords, @@ -42,3 +42,4 @@ boolean LUA_HudEnabled(enum hud option); void LUAh_GameHUD(player_t *stplyr); void LUAh_ScoresHUD(void); +void LUAh_TitleHUD(void); diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index b16125395a98fbd29aaf87078169bb0b8041da6e..f3a1ba210f226fc21dec536500b4507b8a2983d3 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -12,6 +12,7 @@ #include "doomdef.h" #ifdef HAVE_BLUA +#include "fastcmp.h" #include "r_defs.h" #include "r_local.h" #include "st_stuff.h" // hudinfo[] @@ -19,6 +20,7 @@ #include "i_video.h" // rendermode #include "p_local.h" // camera_t #include "screen.h" // screen width/height +#include "m_random.h" // m_random #include "v_video.h" #include "w_wad.h" #include "z_zone.h" @@ -62,12 +64,14 @@ static const char *const hud_disable_options[] = { enum hudinfo { hudinfo_x = 0, - hudinfo_y + hudinfo_y, + hudinfo_f }; static const char *const hudinfo_opt[] = { "x", "y", + "f", NULL}; enum patch { @@ -87,11 +91,13 @@ static const char *const patch_opt[] = { enum hudhook { hudhook_game = 0, - hudhook_scores + hudhook_scores, + hudhook_title }; static const char *const hudhook_opt[] = { "game", "scores", + "title", NULL}; // alignment types for v.drawString @@ -195,6 +201,9 @@ static int hudinfo_get(lua_State *L) case hudinfo_y: lua_pushinteger(L, info->y); break; + case hudinfo_f: + lua_pushinteger(L, info->f); + break; } return 1; } @@ -213,6 +222,9 @@ static int hudinfo_set(lua_State *L) case hudinfo_y: info->y = (INT32)luaL_checkinteger(L, 3); break; + case hudinfo_f: + info->f = (INT32)luaL_checkinteger(L, 3); + break; } return 0; } @@ -226,7 +238,12 @@ static int hudinfo_num(lua_State *L) static int colormap_get(lua_State *L) { - return luaL_error(L, "colormap is not a struct."); + const UINT8 *colormap = *((UINT8 **)luaL_checkudata(L, 1, META_COLORMAP)); + UINT32 i = luaL_checkinteger(L, 2); + if (i >= 256) + return luaL_error(L, "colormap index %d out of range (0 - %d)", i, 255); + lua_pushinteger(L, colormap[i]); + return 1; } static int patch_get(lua_State *L) @@ -338,6 +355,158 @@ static int libd_cachePatch(lua_State *L) return 1; } +// v.getSpritePatch(sprite, [frame, [angle]]) +static int libd_getSpritePatch(lua_State *L) +{ + UINT32 i; // sprite prefix + UINT32 frame = 0; // 'A' + UINT8 angle = 0; + spritedef_t *sprdef; + spriteframe_t *sprframe; + HUDONLY + + if (lua_isnumber(L, 1)) // sprite number given, e.g. SPR_THOK + { + i = lua_tonumber(L, 1); + if (i >= NUMSPRITES) + return 0; + } + else if (lua_isstring(L, 1)) // sprite prefix name given, e.g. "THOK" + { + const char *name = lua_tostring(L, 1); + for (i = 0; i < NUMSPRITES; i++) + if (fastcmp(name, sprnames[i])) + break; + if (i >= NUMSPRITES) + return 0; + } + else + return 0; + + if (i == SPR_PLAY) // Use getSprite2Patch instead! + return 0; + + sprdef = &sprites[i]; + + // set frame number + frame = luaL_optinteger(L, 2, 0); + frame &= FF_FRAMEMASK; // ignore any bits that are not the actual frame, just in case + if (frame >= sprdef->numframes) + return 0; + // set angle number + sprframe = &sprdef->spriteframes[frame]; + angle = luaL_optinteger(L, 3, 1); + + // convert WAD editor angle numbers (1-8) to internal angle numbers (0-7) + // keep 0 the same since we'll make it default to angle 1 (which is internally 0) + // in case somebody didn't know that angle 0 really just maps all 8 angles to the same patch + if (angle != 0) + angle--; + + if (angle >= 8) // out of range? + return 0; + + // push both the patch and it's "flip" value + LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_STATIC), META_PATCH); + lua_pushboolean(L, (sprframe->flip & (1<<angle)) != 0); + return 2; +} + +// v.getSprite2Patch(skin, sprite, [super?,] [frame, [angle]]) +static int libd_getSprite2Patch(lua_State *L) +{ + INT32 i; // skin number + playersprite_t j; // sprite2 prefix + UINT32 frame = 0; // 'A' + UINT8 angle = 0; + spritedef_t *sprdef; + spriteframe_t *sprframe; + boolean super = false; // add FF_SPR2SUPER to sprite2 if true + HUDONLY + + // get skin first! + if (lua_isnumber(L, 1)) // find skin by number + { + i = lua_tonumber(L, 1); + if (i < 0 || i >= MAXSKINS) + return luaL_error(L, "skin number %d out of range (0 - %d)", i, MAXSKINS-1); + if (i >= numskins) + return 0; + } + else // find skin by name + { + const char *name = luaL_checkstring(L, 1); + for (i = 0; i < numskins; i++) + if (fastcmp(skins[i].name, name)) + break; + if (i >= numskins) + return 0; + } + + lua_remove(L, 1); // remove skin now + + if (lua_isnumber(L, 1)) // sprite number given, e.g. SPR2_STND + { + j = lua_tonumber(L, 1); + if (j & FF_SPR2SUPER) // e.g. SPR2_STND|FF_SPR2SUPER + { + super = true; + j &= ~FF_SPR2SUPER; // remove flag so the next check doesn't fail + } + if (j >= free_spr2) + return 0; + } + else if (lua_isstring(L, 1)) // sprite prefix name given, e.g. "STND" + { + const char *name = lua_tostring(L, 1); + for (j = 0; j < free_spr2; j++) + if (fastcmp(name, spr2names[j])) + break; + // if you want super flags you'll have to use the optional boolean following this + if (j >= free_spr2) + return 0; + } + else + return 0; + + if (lua_isboolean(L, 2)) // optional boolean for superness + { + super = lua_toboolean(L, 2); // note: this can override FF_SPR2SUPER from sprite number + lua_remove(L, 2); // remove + } + // if it's not boolean then just assume it's the frame number + + if (super) + j |= FF_SPR2SUPER; + + j = P_GetSkinSprite2(&skins[i], j, NULL); // feed skin and current sprite2 through to change sprite2 used if necessary + + sprdef = &skins[i].sprites[j]; + + // set frame number + frame = luaL_optinteger(L, 2, 0); + frame &= FF_FRAMEMASK; // ignore any bits that are not the actual frame, just in case + if (frame >= sprdef->numframes) + return 0; + // set angle number + sprframe = &sprdef->spriteframes[frame]; + angle = luaL_optinteger(L, 3, 1); + + // convert WAD editor angle numbers (1-8) to internal angle numbers (0-7) + // keep 0 the same since we'll make it default to angle 1 (which is internally 0) + // in case somebody didn't know that angle 0 really just maps all 8 angles to the same patch + if (angle != 0) + angle--; + + if (angle >= 8) // out of range? + return 0; + + // push both the patch and it's "flip" value + LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_STATIC), META_PATCH); + lua_pushboolean(L, (sprframe->flip & (1<<angle)) != 0); + return 2; +} + static int libd_draw(lua_State *L) { INT32 x, y, flags; @@ -519,6 +688,30 @@ static int libd_getColormap(lua_State *L) return 1; } +static int libd_fadeScreen(lua_State *L) +{ + UINT16 color = luaL_checkinteger(L, 1); + UINT8 strength = luaL_checkinteger(L, 2); + const UINT8 maxstrength = ((color & 0xFF00) ? 32 : 10); + + HUDONLY + + if (!strength) + return 0; + + if (strength > maxstrength) + return luaL_error(L, "%s fade strength %d out of range (0 - %d)", ((color & 0xFF00) ? "COLORMAP" : "TRANSMAP"), strength, maxstrength); + + if (strength == maxstrength) // Allow as a shortcut for drawfill... + { + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, ((color & 0xFF00) ? 31 : color)); + return 0; + } + + V_DrawFadeScreen(color, strength); + return 0; +} + static int libd_width(lua_State *L) { HUDONLY @@ -560,6 +753,67 @@ static int libd_renderer(lua_State *L) return 1; } +// M_RANDOM +////////////// + +static int libd_RandomFixed(lua_State *L) +{ + HUDONLY + lua_pushfixed(L, M_RandomFixed()); + return 1; +} + +static int libd_RandomByte(lua_State *L) +{ + HUDONLY + lua_pushinteger(L, M_RandomByte()); + return 1; +} + +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; +} + +static int libd_RandomRange(lua_State *L) +{ + INT32 a = (INT32)luaL_checkinteger(L, 1); + 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; +} + +// Macros. +static int libd_SignedRandom(lua_State *L) +{ + HUDONLY + lua_pushinteger(L, M_SignedRandom()); + return 1; +} + +static int libd_RandomChance(lua_State *L) +{ + fixed_t p = luaL_checkfixed(L, 1); + HUDONLY + lua_pushboolean(L, M_RandomChance(p)); + return 1; +} + // 30/10/18 Lat': Get cv_translucenthud's value for HUD rendering as a normal V_xxTRANS int // Could as well be thrown in global vars for ease of access but I guess it makes sense for it to be a HUD fn static int libd_getlocaltransflag(lua_State *L) @@ -570,16 +824,30 @@ static int libd_getlocaltransflag(lua_State *L) } static luaL_Reg lib_draw[] = { + // cache {"patchExists", libd_patchExists}, {"cachePatch", libd_cachePatch}, + {"getSpritePatch", libd_getSpritePatch}, + {"getSprite2Patch", libd_getSprite2Patch}, + {"getColormap", libd_getColormap}, + // drawing {"draw", libd_draw}, {"drawScaled", libd_drawScaled}, {"drawNum", libd_drawNum}, {"drawPaddedNum", libd_drawPaddedNum}, {"drawFill", libd_drawFill}, {"drawString", libd_drawString}, + {"fadeScreen", libd_fadeScreen}, + // misc {"stringWidth", libd_stringWidth}, - {"getColormap", libd_getColormap}, + // m_random + {"RandomFixed",libd_RandomFixed}, + {"RandomByte",libd_RandomByte}, + {"RandomKey",libd_RandomKey}, + {"RandomRange",libd_RandomRange}, + {"SignedRandom",libd_SignedRandom}, // MACRO + {"RandomChance",libd_RandomChance}, // MACRO + // properties {"width", libd_width}, {"height", libd_height}, {"dupx", libd_dupx}, @@ -630,6 +898,9 @@ static int lib_hudadd(lua_State *L) luaL_checktype(L, 1, LUA_TFUNCTION); field = luaL_checkoption(L, 2, "game", hudhook_opt); + if (!lua_lumploading) + return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); + lua_getfield(L, LUA_REGISTRYINDEX, "HUD"); I_Assert(lua_istable(L, -1)); lua_rawgeti(L, -1, field+2); // HUD[2+] @@ -669,6 +940,9 @@ int LUA_HudLib(lua_State *L) lua_newtable(L); lua_rawseti(L, -2, 3); // HUD[2] = scores rendering functions array + + lua_newtable(L); + lua_rawseti(L, -2, 4); // HUD[3] = title rendering functions array lua_setfield(L, LUA_REGISTRYINDEX, "HUD"); luaL_newmetatable(L, META_HUDINFO); @@ -781,4 +1055,29 @@ void LUAh_ScoresHUD(void) hud_running = false; } +void LUAh_TitleHUD(void) +{ + if (!gL || !(hudAvailable & (1<<hudhook_title))) + return; + + hud_running = true; + lua_pop(gL, -1); + + lua_getfield(gL, LUA_REGISTRYINDEX, "HUD"); + I_Assert(lua_istable(gL, -1)); + lua_rawgeti(gL, -1, 4); // HUD[4] = rendering funcs + I_Assert(lua_istable(gL, -1)); + + lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw + I_Assert(lua_istable(gL, -1)); + lua_remove(gL, -3); // pop HUD + lua_pushnil(gL); + while (lua_next(gL, -3) != 0) { + lua_pushvalue(gL, -3); // graphics library (HUD[1]) + LUA_Call(gL, 1); + } + lua_pop(gL, -1); + hud_running = false; +} + #endif diff --git a/src/lua_infolib.c b/src/lua_infolib.c index 9b22170f93d3d0ea28870b708528a0cc4cc4ebff..55afa387462ecb04a801b90edcb3f00f0aa5120b 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -31,6 +31,7 @@ enum sfxinfo_read { sfxinfor_singular, sfxinfor_priority, sfxinfor_flags, // "pitch" + sfxinfor_caption, sfxinfor_skinsound }; const char *const sfxinfo_ropt[] = { @@ -38,18 +39,21 @@ const char *const sfxinfo_ropt[] = { "singular", "priority", "flags", + "caption", "skinsound", NULL}; enum sfxinfo_write { sfxinfow_singular = 0, sfxinfow_priority, - sfxinfow_flags // "pitch" + sfxinfow_flags, // "pitch" + sfxinfow_caption }; const char *const sfxinfo_wopt[] = { "singular", "priority", "flags", + "caption", NULL}; // @@ -91,6 +95,116 @@ static int lib_sprnamelen(lua_State *L) return 1; } +// +// Player Sprite Names +// + +// push sprite name +static int lib_getSpr2name(lua_State *L) +{ + playersprite_t i; + + lua_remove(L, 1); // don't care about spr2names[] dummy userdata. + + if (lua_isnumber(L, 1)) + { + i = lua_tonumber(L, 1); + if (i >= free_spr2) + return 0; + lua_pushlstring(L, spr2names[i], 4); + return 1; + } + else if (lua_isstring(L, 1)) + { + const char *name = lua_tostring(L, 1); + for (i = 0; i < free_spr2; i++) + if (fastcmp(name, spr2names[i])) + { + lua_pushinteger(L, i); + return 1; + } + } + return 0; +} + +static int lib_getSpr2default(lua_State *L) +{ + playersprite_t i; + + lua_remove(L, 1); // don't care about spr2defaults[] dummy userdata. + + if (lua_isnumber(L, 1)) + i = lua_tonumber(L, 1); + else if (lua_isstring(L, 1)) + { + const char *name = lua_tostring(L, 1); + for (i = 0; i < free_spr2; i++) + if (fastcmp(name, spr2names[i])) + break; + } + else + return luaL_error(L, "spr2defaults[] invalid index"); + + if (i >= free_spr2) + return 0; + + lua_pushinteger(L, spr2defaults[i]); + return 1; +} + +static int lib_setSpr2default(lua_State *L) +{ + playersprite_t i; + UINT8 j = 0; + + lua_remove(L, 1); // don't care about spr2defaults[] dummy userdata. + + if (lua_isnumber(L, 1)) + i = lua_tonumber(L, 1); + else if (lua_isstring(L, 1)) + { + const char *name = lua_tostring(L, 1); + for (i = 0; i < free_spr2; i++) + { + if (fastcmp(name, spr2names[i])) + break; + } + if (i == free_spr2) + return luaL_error(L, "spr2defaults[] invalid index"); + } + else + return luaL_error(L, "spr2defaults[] invalid index"); + + if (i < SPR2_FIRSTFREESLOT || i >= free_spr2) + return luaL_error(L, "spr2defaults[] index %d out of range (%d - %d)", i, SPR2_FIRSTFREESLOT, free_spr2-1); + + if (lua_isnumber(L, 2)) + j = lua_tonumber(L, 2); + else if (lua_isstring(L, 2)) + { + const char *name = lua_tostring(L, 2); + for (j = 0; j < free_spr2; j++) + { + if (fastcmp(name, spr2names[j])) + break; + } + if (j == free_spr2) + return luaL_error(L, "spr2defaults[] invalid index"); + } + + if (j >= free_spr2) + j = 0; // return luaL_error(L, "spr2defaults[] set %d out of range (%d - %d)", j, 0, free_spr2-1); + + spr2defaults[i] = j; + return 0; +} + +static int lib_spr2namelen(lua_State *L) +{ + lua_pushinteger(L, free_spr2); + return 1; +} + //////////////// // STATE INFO // //////////////// @@ -202,6 +316,18 @@ static int lib_setState(lua_State *L) case LUA_TSTRING: // It's a string, expect the name of a built-in action LUA_SetActionByName(state, lua_tostring(L, 3)); break; + case LUA_TUSERDATA: // It's a userdata, expect META_ACTION of a built-in action + { + actionf_t *action = *((actionf_t **)luaL_checkudata(L, 3, META_ACTION)); + + if (!action) + return luaL_error(L, "not a valid action?"); + + state->action = *action; + state->action.acv = action->acv; + state->action.acp1 = action->acp1; + break; + } case LUA_TFUNCTION: // It's a function (a Lua function or a C function? either way!) lua_getfield(L, LUA_REGISTRYINDEX, LREG_STATEACTION); I_Assert(lua_istable(L, -1)); @@ -351,9 +477,8 @@ static int state_get(lua_State *L) return 0; // Just what is this?? // get the function from the global // because the metatable will trigger. - lua_getglobal(L, name); // actually gets from LREG_ACTIONS if applicable, and pushes a new C closure if not. - lua_pushstring(L, name); // push the name we found. - return 2; // return both the function and its name, in case somebody wanted to do a comparison by name or something? + lua_getglobal(L, name); // actually gets from LREG_ACTIONS if applicable, and pushes a META_ACTION userdata if not. + return 1; // return just the function } else if (fastcmp(field,"var1")) number = st->var1; else if (fastcmp(field,"var2")) @@ -397,6 +522,18 @@ static int state_set(lua_State *L) case LUA_TSTRING: // It's a string, expect the name of a built-in action LUA_SetActionByName(st, lua_tostring(L, 3)); break; + case LUA_TUSERDATA: // It's a userdata, expect META_ACTION of a built-in action + { + actionf_t *action = *((actionf_t **)luaL_checkudata(L, 3, META_ACTION)); + + if (!action) + return luaL_error(L, "not a valid action?"); + + st->action = *action; + st->action.acv = action->acv; + st->action.acp1 = action->acp1; + break; + } case LUA_TFUNCTION: // It's a function (a Lua function or a C function? either way!) lua_getfield(L, LUA_REGISTRYINDEX, LREG_STATEACTION); I_Assert(lua_istable(L, -1)); @@ -731,8 +868,8 @@ static int lib_getSfxInfo(lua_State *L) lua_remove(L, 1); i = luaL_checkinteger(L, 1); - if (i >= NUMSFX) - return luaL_error(L, "sfxinfo[] index %d out of range (0 - %d)", i, NUMSFX-1); + if (i == 0 || i >= NUMSFX) + return luaL_error(L, "sfxinfo[] index %d out of range (1 - %d)", i, NUMSFX-1); LUA_PushUserdata(L, &S_sfx[i], META_SFXINFO); return 1; } @@ -745,9 +882,9 @@ static int lib_setSfxInfo(lua_State *L) lua_remove(L, 1); { UINT32 i = luaL_checkinteger(L, 1); - if (i >= NUMSFX) - return luaL_error(L, "sfxinfo[] index %d out of range (0 - %d)", i, NUMSFX-1); - info = &S_sfx[i]; // get the mobjinfo to assign to. + if (i == 0 || i >= NUMSFX) + return luaL_error(L, "sfxinfo[] index %d out of range (1 - %d)", i, NUMSFX-1); + info = &S_sfx[i]; // get the sfxinfo to assign to. } luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table. lua_remove(L, 1); // pop mobjtype num, don't need it any more. @@ -776,6 +913,9 @@ static int lib_setSfxInfo(lua_State *L) case sfxinfow_flags: info->pitch = (INT32)luaL_checkinteger(L, 3); break; + case sfxinfow_caption: + strlcpy(info->caption, luaL_checkstring(L, 3), sizeof(info->caption)); + break; default: break; } @@ -813,11 +953,14 @@ static int sfxinfo_get(lua_State *L) case sfxinfor_flags: lua_pushinteger(L, sfx->pitch); return 1; + case sfxinfor_caption: + lua_pushstring(L, sfx->caption); + return 1; case sfxinfor_skinsound: lua_pushinteger(L, sfx->skinsound); return 1; default: - return luaL_error(L, "impossible error"); + return luaL_error(L, "Field does not exist in sfxinfo_t"); } return 0; } @@ -848,8 +991,11 @@ static int sfxinfo_set(lua_State *L) case sfxinfow_flags: sfx->pitch = luaL_checkinteger(L, 1); break; + case sfxinfow_caption: + strlcpy(sfx->caption, luaL_checkstring(L, 1), sizeof(sfx->caption)); + break; default: - return luaL_error(L, "impossible error"); + return luaL_error(L, "Field does not exist in sfxinfo_t"); } return 0; } @@ -923,6 +1069,29 @@ int LUA_InfoLib(lua_State *L) lua_setmetatable(L, -2); lua_setglobal(L, "sprnames"); + lua_newuserdata(L, 0); + lua_createtable(L, 0, 2); + lua_pushcfunction(L, lib_getSpr2name); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, lib_spr2namelen); + lua_setfield(L, -2, "__len"); + lua_setmetatable(L, -2); + lua_setglobal(L, "spr2names"); + + lua_newuserdata(L, 0); + lua_createtable(L, 0, 2); + lua_pushcfunction(L, lib_getSpr2default); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, lib_setSpr2default); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, lib_spr2namelen); + lua_setfield(L, -2, "__len"); + lua_setmetatable(L, -2); + lua_setglobal(L, "spr2defaults"); + lua_newuserdata(L, 0); lua_createtable(L, 0, 2); lua_pushcfunction(L, lib_getState); diff --git a/src/lua_libs.h b/src/lua_libs.h index 9c6050bea359375a7e229063edb181d6f0733390..827c1d7987713ae0440fb31665226c839748fa71 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -38,6 +38,10 @@ extern lua_State *gL; #define META_SUBSECTOR "SUBSECTOR_T*" #define META_SECTOR "SECTOR_T*" #define META_FFLOOR "FFLOOR_T*" +#ifdef HAVE_LUA_SEGS +#define META_SEG "SEG_T*" +#define META_NODE "NODE_T*" +#endif #ifdef ESLOPE #define META_SLOPE "PSLOPE_T*" #define META_VECTOR2 "VECTOR2_T" @@ -49,12 +53,20 @@ extern lua_State *gL; #define META_SECTORLINES "SECTOR_T*LINES" #define META_SIDENUM "LINE_T*SIDENUM" +#ifdef HAVE_LUA_SEGS +#define META_NODEBBOX "NODE_T*BBOX" +#define META_NODECHILDREN "NODE_T*CHILDREN" +#endif + +#define META_BBOX "BOUNDING_BOX" #define META_HUDINFO "HUDINFO_T*" #define META_PATCH "PATCH_T*" #define META_COLORMAP "COLORMAP" #define META_CAMERA "CAMERA_T*" +#define META_ACTION "ACTIONF_T*" + boolean luaL_checkboolean(lua_State *L, int narg); int LUA_EnumLib(lua_State *L); diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 35542fdceed0c9fc8f973810059d2cb2e6985b2a..c5555009f849c8addd92c641a2db1d6414f6bba5 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -207,6 +207,82 @@ static const char *const ffloor_opt[] = { "alpha", NULL}; +#ifdef HAVE_LUA_SEGS +enum seg_e { + seg_valid = 0, + seg_v1, + seg_v2, + seg_side, + seg_offset, + seg_angle, + seg_sidedef, + seg_linedef, + seg_frontsector, + seg_backsector, +}; + +static const char *const seg_opt[] = { + "valid", + "v1", + "v2", + "side", + "offset", + "angle", + "sidedef", + "linedef", + "frontsector", + "backsector", + NULL}; + +enum node_e { + node_valid = 0, + node_x, + node_y, + node_dx, + node_dy, + node_bbox, + node_children, +}; + +static const char *const node_opt[] = { + "valid", + "x", + "y", + "dx", + "dy", + "bbox", + "children", + NULL}; + +enum nodechild_e { + nodechild_valid = 0, + nodechild_right, + nodechild_left, +}; + +static const char *const nodechild_opt[] = { + "valid", + "right", + "left", + NULL}; +#endif + +enum bbox_e { + bbox_valid = 0, + bbox_top, + bbox_bottom, + bbox_left, + bbox_right, +}; + +static const char *const bbox_opt[] = { + "valid", + "top", + "bottom", + "left", + "right", + NULL}; + #ifdef ESLOPE enum slope_e { slope_valid = 0, @@ -251,12 +327,19 @@ static const char *const vector_opt[] = { static const char *const array_opt[] ={"iterate",NULL}; static const char *const valid_opt[] ={"valid",NULL}; +/////////////////////////////////// +// sector list iterate functions // +/////////////////////////////////// + // iterates through a sector's thinglist! static int lib_iterateSectorThinglist(lua_State *L) { mobj_t *state = NULL; mobj_t *thing = NULL; + if (gamestate != GS_LEVEL) + return luaL_error(L, "This function can only be used in a level!"); + if (lua_gettop(L) < 2) return luaL_error(L, "Don't call sector.thinglist() directly, use it as 'for rover in sector.thinglist do <block> end'."); @@ -290,6 +373,9 @@ static int lib_iterateSectorFFloors(lua_State *L) ffloor_t *state = NULL; ffloor_t *ffloor = NULL; + if (gamestate != GS_LEVEL) + return luaL_error(L, "This function can only be used in a level!"); + if (lua_gettop(L) < 2) return luaL_error(L, "Don't call sector.ffloors() directly, use it as 'for rover in sector.ffloors do <block> end'."); @@ -325,6 +411,10 @@ static int sector_iterate(lua_State *L) return 3; } +//////////////////// +// sector.lines[] // +//////////////////// + // sector.lines, i -> sector.lines[i] // sector.lines.valid, for validity checking static int sectorlines_get(lua_State *L) @@ -386,6 +476,10 @@ static int sectorlines_num(lua_State *L) return 1; } +////////////// +// sector_t // +////////////// + static int sector_get(lua_State *L) { sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); @@ -552,6 +646,10 @@ static int sector_num(lua_State *L) return 1; } +///////////////// +// subsector_t // +///////////////// + static int subsector_get(lua_State *L) { subsector_t *subsector = *((subsector_t **)luaL_checkudata(L, 1, META_SUBSECTOR)); @@ -591,6 +689,10 @@ static int subsector_num(lua_State *L) return 1; } +//////////// +// line_t // +//////////// + static int line_get(lua_State *L) { line_t *line = *((line_t **)luaL_checkudata(L, 1, META_LINE)); @@ -688,6 +790,10 @@ static int line_num(lua_State *L) return 1; } +//////////////////// +// line.sidenum[] // +//////////////////// + static int sidenum_get(lua_State *L) { UINT16 *sidenum = *((UINT16 **)luaL_checkudata(L, 1, META_SIDENUM)); @@ -716,6 +822,10 @@ static int sidenum_get(lua_State *L) return 1; } +//////////// +// side_t // +//////////// + static int side_get(lua_State *L) { side_t *side = *((side_t **)luaL_checkudata(L, 1, META_SIDE)); @@ -817,6 +927,10 @@ static int side_num(lua_State *L) return 1; } +////////////// +// vertex_t // +////////////// + static int vertex_get(lua_State *L) { vertex_t *vertex = *((vertex_t **)luaL_checkudata(L, 1, META_VERTEX)); @@ -856,9 +970,293 @@ static int vertex_num(lua_State *L) return 1; } +#ifdef HAVE_LUA_SEGS + +/////////// +// seg_t // +/////////// + +static int seg_get(lua_State *L) +{ + seg_t *seg = *((seg_t **)luaL_checkudata(L, 1, META_SEG)); + enum seg_e field = luaL_checkoption(L, 2, seg_opt[0], seg_opt); + + if (!seg) + { + if (field == seg_valid) { + lua_pushboolean(L, 0); + return 1; + } + return luaL_error(L, "accessed seg_t doesn't exist anymore."); + } + + switch(field) + { + case seg_valid: // valid + lua_pushboolean(L, 1); + return 1; + case seg_v1: + LUA_PushUserdata(L, seg->v1, META_VERTEX); + return 1; + case seg_v2: + LUA_PushUserdata(L, seg->v2, META_VERTEX); + return 1; + case seg_side: + lua_pushinteger(L, seg->side); + return 1; + case seg_offset: + lua_pushfixed(L, seg->offset); + return 1; + case seg_angle: + lua_pushangle(L, seg->angle); + return 1; + case seg_sidedef: + LUA_PushUserdata(L, seg->sidedef, META_SIDE); + return 1; + case seg_linedef: + LUA_PushUserdata(L, seg->linedef, META_LINE); + return 1; + case seg_frontsector: + LUA_PushUserdata(L, seg->frontsector, META_SECTOR); + return 1; + case seg_backsector: + LUA_PushUserdata(L, seg->backsector, META_SECTOR); + return 1; + } + return 0; +} + +static int seg_num(lua_State *L) +{ + seg_t *seg = *((seg_t **)luaL_checkudata(L, 1, META_SEG)); + lua_pushinteger(L, seg-segs); + return 1; +} + +//////////// +// node_t // +//////////// + +static int node_get(lua_State *L) +{ + node_t *node = *((node_t **)luaL_checkudata(L, 1, META_NODE)); + enum node_e field = luaL_checkoption(L, 2, node_opt[0], node_opt); + + if (!node) + { + if (field == node_valid) { + lua_pushboolean(L, 0); + return 1; + } + return luaL_error(L, "accessed node_t doesn't exist anymore."); + } + + switch(field) + { + case node_valid: // valid + lua_pushboolean(L, 1); + return 1; + case node_x: + lua_pushfixed(L, node->x); + return 1; + case node_y: + lua_pushfixed(L, node->y); + return 1; + case node_dx: + lua_pushfixed(L, node->x); + return 1; + case node_dy: + lua_pushfixed(L, node->x); + return 1; + case node_bbox: + LUA_PushUserdata(L, node->bbox, META_NODEBBOX); + return 1; + case node_children: + LUA_PushUserdata(L, node->children, META_NODECHILDREN); + return 1; + } + return 0; +} + +static int node_num(lua_State *L) +{ + node_t *node = *((node_t **)luaL_checkudata(L, 1, META_NODE)); + lua_pushinteger(L, node-nodes); + return 1; +} + +/////////////// +// node.bbox // +/////////////// + +/* +// node.bbox[i][j]: i = 0 or 1, j = 0 1 2 or 3 +// NOTE: 2D arrays are NOT double pointers, +// the second bbox will be directly after the first in memory (hence the way the bbox is pushed here) +// this function handles the [i] part, bbox_get handles the [j] part +static int nodebbox_get(lua_State *L) +{ + fixed_t *bbox = *((fixed_t **)luaL_checkudata(L, 1, META_NODEBBOX)); + int i; + lua_settop(L, 2); + if (!lua_isnumber(L, 2)) + { + int field = luaL_checkoption(L, 2, NULL, valid_opt); + if (!bbox) + { + if (field == 0) { + lua_pushboolean(L, 0); + return 1; + } + return luaL_error(L, "accessed node_t doesn't exist anymore."); + } else if (field == 0) { + lua_pushboolean(L, 1); + return 1; + } + } + + i = lua_tointeger(L, 2); + if (i < 0 || i > 1) + return 0; + LUA_PushUserdata(L, bbox + i*4*sizeof(fixed_t), META_BBOX); + return 1; +} +*/ +static int nodebbox_call(lua_State *L) +{ + fixed_t *bbox = *((fixed_t **)luaL_checkudata(L, 1, META_NODEBBOX)); + int i, j; + int n = lua_gettop(L); + + if (!bbox) + return luaL_error(L, "accessed node bbox doesn't exist anymore."); + if (n < 3) + return luaL_error(L, "arguments 2 and/or 3 not given (expected node.bbox(child, coord))"); + // get child + if (!lua_isnumber(L, 2)) { + enum nodechild_e field = luaL_checkoption(L, 2, nodechild_opt[0], nodechild_opt); + switch (field) { + case nodechild_right: i = 0; break; + case nodechild_left: i = 1; break; + default: + return luaL_error(L, "invalid node child \"%s\".", lua_tostring(L, 2)); + } + } + else { + i = lua_tointeger(L, 2); + if (i < 0 || i > 1) + return 0; + } + // get bbox coord + if (!lua_isnumber(L, 3)) { + enum bbox_e field = luaL_checkoption(L, 3, bbox_opt[0], bbox_opt); + switch (field) { + case bbox_top: j = BOXTOP; break; + case bbox_bottom: j = BOXBOTTOM; break; + case bbox_left: j = BOXLEFT; break; + case bbox_right: j = BOXRIGHT; break; + default: + return luaL_error(L, "invalid bbox coordinate \"%s\".", lua_tostring(L, 3)); + } + } + else { + j = lua_tointeger(L, 3); + if (j < 0 || j > 3) + return 0; + } + lua_pushinteger(L, bbox[i*4 + j]); + return 1; +} + +///////////////////// +// node.children[] // +///////////////////// + +// node.children[i]: i = 0 or 1 +static int nodechildren_get(lua_State *L) +{ + UINT16 *children = *((UINT16 **)luaL_checkudata(L, 1, META_NODECHILDREN)); + int i; + lua_settop(L, 2); + if (!lua_isnumber(L, 2)) + { + enum nodechild_e field = luaL_checkoption(L, 2, nodechild_opt[0], nodechild_opt); + if (!children) + { + if (field == nodechild_valid) { + lua_pushboolean(L, 0); + return 1; + } + return luaL_error(L, "accessed node_t doesn't exist anymore."); + } else if (field == nodechild_valid) { + lua_pushboolean(L, 1); + return 1; + } else switch (field) { + case nodechild_right: i = 0; break; + case nodechild_left: i = 1; break; + default: return 0; + } + } + else { + i = lua_tointeger(L, 2); + if (i < 0 || i > 1) + return 0; + } + lua_pushinteger(L, children[i]); + return 1; +} +#endif + +////////// +// bbox // +////////// + +// bounding box (aka fixed_t array with four elements) +// NOTE: may be useful for polyobjects or other things later +static int bbox_get(lua_State *L) +{ + fixed_t *bbox = *((fixed_t **)luaL_checkudata(L, 1, META_BBOX)); + int i; + lua_settop(L, 2); + if (!lua_isnumber(L, 2)) + { + enum bbox_e field = luaL_checkoption(L, 2, bbox_opt[0], bbox_opt); + if (!bbox) + { + if (field == bbox_valid) { + lua_pushboolean(L, 0); + return 1; + } + return luaL_error(L, "accessed bbox doesn't exist anymore."); + } else if (field == bbox_valid) { + lua_pushboolean(L, 1); + return 1; + } else switch (field) { + case bbox_top: i = BOXTOP; break; + case bbox_bottom: i = BOXBOTTOM; break; + case bbox_left: i = BOXLEFT; break; + case bbox_right: i = BOXRIGHT; break; + default: return 0; + } + } + else { + i = lua_tointeger(L, 2); + if (i < 0 || i > 3) + return 0; + } + lua_pushinteger(L, bbox[i]); + return 1; +} + +/////////////// +// sectors[] // +/////////////// + static int lib_iterateSectors(lua_State *L) { size_t i = 0; + if (gamestate != GS_LEVEL) + return luaL_error(L, "This function can only be used in a level!"); if (lua_gettop(L) < 2) return luaL_error(L, "Don't call sectors.iterate() directly, use it as 'for sector in sectors.iterate do <block> end'."); lua_settop(L, 2); @@ -876,6 +1274,8 @@ static int lib_iterateSectors(lua_State *L) static int lib_getSector(lua_State *L) { int field; + if (gamestate != GS_LEVEL) + return luaL_error(L, "You cannot access this outside of a level!"); lua_settop(L, 2); lua_remove(L, 1); // dummy userdata table is unused. if (lua_isnumber(L, 1)) @@ -902,9 +1302,15 @@ static int lib_numsectors(lua_State *L) return 1; } +////////////////// +// subsectors[] // +////////////////// + static int lib_iterateSubsectors(lua_State *L) { size_t i = 0; + if (gamestate != GS_LEVEL) + return luaL_error(L, "This function can only be used in a level!"); if (lua_gettop(L) < 2) return luaL_error(L, "Don't call subsectors.iterate() directly, use it as 'for subsector in subsectors.iterate do <block> end'."); lua_settop(L, 2); @@ -922,6 +1328,8 @@ static int lib_iterateSubsectors(lua_State *L) static int lib_getSubsector(lua_State *L) { int field; + if (gamestate != GS_LEVEL) + return luaL_error(L, "You cannot access this outside of a level!"); lua_settop(L, 2); lua_remove(L, 1); // dummy userdata table is unused. if (lua_isnumber(L, 1)) @@ -948,9 +1356,15 @@ static int lib_numsubsectors(lua_State *L) return 1; } +///////////// +// lines[] // +///////////// + static int lib_iterateLines(lua_State *L) { size_t i = 0; + if (gamestate != GS_LEVEL) + return luaL_error(L, "This function can only be used in a level!"); if (lua_gettop(L) < 2) return luaL_error(L, "Don't call lines.iterate() directly, use it as 'for line in lines.iterate do <block> end'."); lua_settop(L, 2); @@ -968,6 +1382,8 @@ static int lib_iterateLines(lua_State *L) static int lib_getLine(lua_State *L) { int field; + if (gamestate != GS_LEVEL) + return luaL_error(L, "You cannot access this outside of a level!"); lua_settop(L, 2); lua_remove(L, 1); // dummy userdata table is unused. if (lua_isnumber(L, 1)) @@ -994,9 +1410,15 @@ static int lib_numlines(lua_State *L) return 1; } +///////////// +// sides[] // +///////////// + static int lib_iterateSides(lua_State *L) { size_t i = 0; + if (gamestate != GS_LEVEL) + return luaL_error(L, "This function can only be used in a level!"); if (lua_gettop(L) < 2) return luaL_error(L, "Don't call sides.iterate() directly, use it as 'for side in sides.iterate do <block> end'."); lua_settop(L, 2); @@ -1014,6 +1436,8 @@ static int lib_iterateSides(lua_State *L) static int lib_getSide(lua_State *L) { int field; + if (gamestate != GS_LEVEL) + return luaL_error(L, "You cannot access this outside of a level!"); lua_settop(L, 2); lua_remove(L, 1); // dummy userdata table is unused. if (lua_isnumber(L, 1)) @@ -1040,9 +1464,15 @@ static int lib_numsides(lua_State *L) return 1; } +//////////////// +// vertexes[] // +//////////////// + static int lib_iterateVertexes(lua_State *L) { size_t i = 0; + if (gamestate != GS_LEVEL) + return luaL_error(L, "This function can only be used in a level!"); if (lua_gettop(L) < 2) return luaL_error(L, "Don't call vertexes.iterate() directly, use it as 'for vertex in vertexes.iterate do <block> end'."); lua_settop(L, 2); @@ -1060,6 +1490,8 @@ static int lib_iterateVertexes(lua_State *L) static int lib_getVertex(lua_State *L) { int field; + if (gamestate != GS_LEVEL) + return luaL_error(L, "You cannot access this outside of a level!"); lua_settop(L, 2); lua_remove(L, 1); // dummy userdata table is unused. if (lua_isnumber(L, 1)) @@ -1086,6 +1518,121 @@ static int lib_numvertexes(lua_State *L) return 1; } +#ifdef HAVE_LUA_SEGS + +//////////// +// segs[] // +//////////// + +static int lib_iterateSegs(lua_State *L) +{ + size_t i = 0; + if (gamestate != GS_LEVEL) + return luaL_error(L, "This function can only be used in a level!"); + if (lua_gettop(L) < 2) + return luaL_error(L, "Don't call segs.iterate() directly, use it as 'for seg in segs.iterate do <block> end'."); + lua_settop(L, 2); + lua_remove(L, 1); // state is unused. + if (!lua_isnil(L, 1)) + i = (size_t)(*((seg_t **)luaL_checkudata(L, 1, META_SEG)) - segs)+1; + if (i < numsegs) + { + LUA_PushUserdata(L, &segs[i], META_SEG); + return 1; + } + return 0; +} + +static int lib_getSeg(lua_State *L) +{ + int field; + if (gamestate != GS_LEVEL) + return luaL_error(L, "You cannot access this outside of a level!"); + lua_settop(L, 2); + lua_remove(L, 1); // dummy userdata table is unused. + if (lua_isnumber(L, 1)) + { + size_t i = lua_tointeger(L, 1); + if (i >= numsegs) + return 0; + LUA_PushUserdata(L, &segs[i], META_SEG); + return 1; + } + field = luaL_checkoption(L, 1, NULL, array_opt); + switch(field) + { + case 0: // iterate + lua_pushcfunction(L, lib_iterateSegs); + return 1; + } + return 0; +} + +static int lib_numsegs(lua_State *L) +{ + lua_pushinteger(L, numsegs); + return 1; +} + +///////////// +// nodes[] // +///////////// + +static int lib_iterateNodes(lua_State *L) +{ + size_t i = 0; + if (gamestate != GS_LEVEL) + return luaL_error(L, "This function can only be used in a level!"); + if (lua_gettop(L) < 2) + return luaL_error(L, "Don't call nodes.iterate() directly, use it as 'for node in nodes.iterate do <block> end'."); + lua_settop(L, 2); + lua_remove(L, 1); // state is unused. + if (!lua_isnil(L, 1)) + i = (size_t)(*((node_t **)luaL_checkudata(L, 1, META_NODE)) - nodes)+1; + if (i < numsegs) + { + LUA_PushUserdata(L, &nodes[i], META_NODE); + return 1; + } + return 0; +} + +static int lib_getNode(lua_State *L) +{ + int field; + if (gamestate != GS_LEVEL) + return luaL_error(L, "You cannot access this outside of a level!"); + lua_settop(L, 2); + lua_remove(L, 1); // dummy userdata table is unused. + if (lua_isnumber(L, 1)) + { + size_t i = lua_tointeger(L, 1); + if (i >= numnodes) + return 0; + LUA_PushUserdata(L, &nodes[i], META_NODE); + return 1; + } + field = luaL_checkoption(L, 1, NULL, array_opt); + switch(field) + { + case 0: // iterate + lua_pushcfunction(L, lib_iterateNodes); + return 1; + } + return 0; +} + +static int lib_numnodes(lua_State *L) +{ + lua_pushinteger(L, numnodes); + return 1; +} +#endif + +////////////// +// ffloor_t // +////////////// + static int ffloor_get(lua_State *L) { ffloor_t *ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR)); @@ -1243,6 +1790,10 @@ static int ffloor_set(lua_State *L) } #ifdef ESLOPE +////////////// +// pslope_t // +////////////// + static int slope_get(lua_State *L) { pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); @@ -1379,6 +1930,10 @@ static int slope_set(lua_State *L) return 0; } +/////////////// +// vector*_t // +/////////////// + static int vector2_get(lua_State *L) { vector2_t *vec = *((vector2_t **)luaL_checkudata(L, 1, META_VECTOR2)); @@ -1417,6 +1972,10 @@ static int vector3_get(lua_State *L) } #endif +///////////////////// +// mapheaderinfo[] // +///////////////////// + static int lib_getMapheaderinfo(lua_State *L) { // i -> mapheaderinfo[i-1] @@ -1449,6 +2008,10 @@ static int lib_nummapheaders(lua_State *L) return 1; } +///////////////// +// mapheader_t // +///////////////// + static int mapheaderinfo_get(lua_State *L) { mapheader_t *header = *((mapheader_t **)luaL_checkudata(L, 1, META_MAPHEADER)); @@ -1511,12 +2074,14 @@ static int mapheaderinfo_get(lua_State *L) lua_pushinteger(L, header->levelselect); else if (fastcmp(field,"bonustype")) lua_pushinteger(L, header->bonustype); - else if (fastcmp(field,"saveoverride")) - lua_pushinteger(L, header->saveoverride); + else if (fastcmp(field,"maxbonuslives")) + lua_pushinteger(L, header->maxbonuslives); else if (fastcmp(field,"levelflags")) lua_pushinteger(L, header->levelflags); else if (fastcmp(field,"menuflags")) lua_pushinteger(L, header->menuflags); + else if (fastcmp(field,"startrings")) + lua_pushinteger(L, header->startrings); // TODO add support for reading numGradedMares and grades else { // Read custom vars now @@ -1601,6 +2166,41 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L, 1); +#ifdef HAVE_LUA_SEGS + luaL_newmetatable(L, META_SEG); + lua_pushcfunction(L, seg_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, seg_num); + lua_setfield(L, -2, "__len"); + lua_pop(L, 1); + + luaL_newmetatable(L, META_NODE); + lua_pushcfunction(L, node_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, node_num); + lua_setfield(L, -2, "__len"); + lua_pop(L, 1); + + luaL_newmetatable(L, META_NODEBBOX); + //lua_pushcfunction(L, nodebbox_get); + //lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, nodebbox_call); + lua_setfield(L, -2, "__call"); + lua_pop(L, 1); + + luaL_newmetatable(L, META_NODECHILDREN); + lua_pushcfunction(L, nodechildren_get); + lua_setfield(L, -2, "__index"); + lua_pop(L, 1); +#endif + + luaL_newmetatable(L, META_BBOX); + lua_pushcfunction(L, bbox_get); + lua_setfield(L, -2, "__index"); + lua_pop(L, 1); + #ifdef ESLOPE luaL_newmetatable(L, META_SLOPE); lua_pushcfunction(L, slope_get); @@ -1679,6 +2279,28 @@ int LUA_MapLib(lua_State *L) lua_setmetatable(L, -2); lua_setglobal(L, "vertexes"); +#ifdef HAVE_LUA_SEGS + lua_newuserdata(L, 0); + lua_createtable(L, 0, 2); + lua_pushcfunction(L, lib_getSeg); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, lib_numsegs); + lua_setfield(L, -2, "__len"); + lua_setmetatable(L, -2); + lua_setglobal(L, "segs"); + + lua_newuserdata(L, 0); + lua_createtable(L, 0, 2); + lua_pushcfunction(L, lib_getNode); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, lib_numnodes); + lua_setfield(L, -2, "__len"); + lua_setmetatable(L, -2); + lua_setglobal(L, "nodes"); +#endif + lua_newuserdata(L, 0); lua_createtable(L, 0, 2); lua_pushcfunction(L, lib_getMapheaderinfo); diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index 6cc8c0077a26f4973e53f8640f1c150d2b0e46ef..1f0d6e2872d99cbec85b8aebfa6dbf13f0848ad4 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -81,20 +81,9 @@ static int lib_finecosine(lua_State *L) static int lib_finetangent(lua_State *L) { - // 2.1.15 ONLY HACK: optional boolean argument, only add ANGLE_90 if true - boolean newtan = lua_optboolean(L, 2); - - if (newtan) - { - // HACK: add ANGLE_90 to make tan() in Lua start at 0 like it should - // use & 4095 instead of & FINEMASK (8191), so it doesn't go out of the array's bounds - lua_pushfixed(L, FINETANGENT(((luaL_checkangle(L, 1)+ANGLE_90)>>ANGLETOFINESHIFT) & 4095)); - } - else - { - LUA_Deprecated(L, "tan(angle)", "tan(angle, true)"); - lua_pushfixed(L, FINETANGENT((luaL_checkangle(L, 1)>>ANGLETOFINESHIFT) & 4095)); - } + // HACK: add ANGLE_90 to make tan() in Lua start at 0 like it should + // use & 4095 instead of & FINEMASK (8191), so it doesn't go out of the array's bounds + lua_pushfixed(L, FINETANGENT(((luaL_checkangle(L, 1)+ANGLE_90)>>ANGLETOFINESHIFT) & 4095)); return 1; } diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index aca50122102dbe85bc69944724fd9657cea2b79d..0835e5cc0114230c89f3dfdf11e7236be147021a 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -34,11 +34,14 @@ enum mobj_e { mobj_angle, mobj_sprite, mobj_frame, + mobj_sprite2, mobj_anim_duration, mobj_touching_sectorlist, mobj_subsector, mobj_floorz, mobj_ceilingz, + mobj_floorrover, + mobj_ceilingrover, mobj_radius, mobj_height, mobj_momx, @@ -98,11 +101,14 @@ static const char *const mobj_opt[] = { "angle", "sprite", "frame", + "sprite2", "anim_duration", "touching_sectorlist", "subsector", "floorz", "ceilingz", + "floorrover", + "ceilingrover", "radius", "height", "momx", @@ -197,6 +203,9 @@ static int mobj_get(lua_State *L) case mobj_frame: lua_pushinteger(L, mo->frame); break; + case mobj_sprite2: + lua_pushinteger(L, mo->sprite2); + break; case mobj_anim_duration: lua_pushinteger(L, mo->anim_duration); break; @@ -211,6 +220,12 @@ static int mobj_get(lua_State *L) case mobj_ceilingz: lua_pushfixed(L, mo->ceilingz); break; + case mobj_floorrover: + LUA_PushUserdata(L, mo->floorrover, META_FFLOOR); + break; + case mobj_ceilingrover: + LUA_PushUserdata(L, mo->ceilingrover, META_FFLOOR); + break; case mobj_radius: lua_pushfixed(L, mo->radius); break; @@ -404,6 +419,8 @@ static int mobj_set(lua_State *L) P_CheckPosition(mo, mo->x, mo->y); mo->floorz = tmfloorz; mo->ceilingz = tmceilingz; + mo->floorrover = tmfloorrover; + mo->ceilingrover = tmceilingrover; P_SetTarget(&tmthing, ptmthing); break; } @@ -424,6 +441,9 @@ static int mobj_set(lua_State *L) case mobj_frame: mo->frame = (UINT32)luaL_checkinteger(L, 3); break; + case mobj_sprite2: + mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), (UINT8)luaL_checkinteger(L, 3), mo->player); + break; case mobj_anim_duration: mo->anim_duration = (UINT16)luaL_checkinteger(L, 3); break; @@ -435,6 +455,10 @@ static int mobj_set(lua_State *L) return NOSETPOS; case mobj_ceilingz: return NOSETPOS; + case mobj_floorrover: + return NOSET; + case mobj_ceilingrover: + return NOSET; case mobj_radius: { mobj_t *ptmthing = tmthing; @@ -444,6 +468,8 @@ static int mobj_set(lua_State *L) P_CheckPosition(mo, mo->x, mo->y); mo->floorz = tmfloorz; mo->ceilingz = tmceilingz; + mo->floorrover = tmfloorrover; + mo->ceilingrover = tmceilingrover; P_SetTarget(&tmthing, ptmthing); break; } @@ -456,6 +482,8 @@ static int mobj_set(lua_State *L) P_CheckPosition(mo, mo->x, mo->y); mo->floorz = tmfloorz; mo->ceilingz = tmceilingz; + mo->floorrover = tmfloorrover; + mo->ceilingrover = tmceilingrover; P_SetTarget(&tmthing, ptmthing); break; } @@ -516,7 +544,8 @@ static int mobj_set(lua_State *L) for (i = 0; i < numskins; i++) if (fastcmp(skins[i].name, skin)) { - mo->skin = &skins[i]; + if (!mo->player || R_SkinUsable(mo->player-players, i)) + mo->skin = &skins[i]; return 0; } return luaL_error(L, "mobj.skin '%s' not found!", skin); @@ -534,10 +563,22 @@ static int mobj_set(lua_State *L) case mobj_bprev: return UNIMPLEMENTED; case mobj_hnext: - mo->hnext = luaL_checkudata(L, 3, META_MOBJ); + if (lua_isnil(L, 3)) + P_SetTarget(&mo->hnext, NULL); + else + { + mobj_t *hnext = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&mo->hnext, hnext); + } break; case mobj_hprev: - mo->hprev = luaL_checkudata(L, 3, META_MOBJ); + if (lua_isnil(L, 3)) + P_SetTarget(&mo->hprev, NULL); + else + { + mobj_t *hprev = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&mo->hprev, hprev); + } break; case mobj_type: // yeah sure, we'll let you change the mobj's type. { @@ -760,6 +801,8 @@ static int mapthing_set(lua_State *L) static int lib_iterateMapthings(lua_State *L) { size_t i = 0; + if (gamestate != GS_LEVEL) + return luaL_error(L, "This function can only be used in a level!"); if (lua_gettop(L) < 2) return luaL_error(L, "Don't call mapthings.iterate() directly, use it as 'for mapthing in mapthings.iterate do <block> end'."); lua_settop(L, 2); @@ -777,6 +820,8 @@ static int lib_iterateMapthings(lua_State *L) static int lib_getMapthing(lua_State *L) { int field; + if (gamestate != GS_LEVEL) + return luaL_error(L, "You cannot access this outside of a level!"); lua_settop(L, 2); lua_remove(L, 1); // dummy userdata table is unused. if (lua_isnumber(L, 1)) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index dd74393214592bd862a911d6a0ecf65963b03264..f3eb978f6163a1d7ef1ccd89c34a74e3f7199e4c 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -25,6 +25,8 @@ static int lib_iteratePlayers(lua_State *L) { INT32 i = -1; + if (gamestate != GS_LEVEL) + return luaL_error(L, "This function can only be used in a level!"); if (lua_gettop(L) < 2) { //return luaL_error(L, "Don't call players.iterate() directly, use it as 'for player in players.iterate do <block> end'."); @@ -51,6 +53,8 @@ static int lib_getPlayer(lua_State *L) { const char *field; // i -> players[i] + if (gamestate != GS_LEVEL) + return luaL_error(L, "You cannot access this outside of a level!"); if (lua_type(L, 2) == LUA_TNUMBER) { lua_Integer i = luaL_checkinteger(L, 2); @@ -108,6 +112,10 @@ static int player_get(lua_State *L) LUA_PushUserdata(L, &plr->cmd, META_TICCMD); else if (fastcmp(field,"playerstate")) lua_pushinteger(L, plr->playerstate); + else if (fastcmp(field,"camerascale")) + lua_pushfixed(L, plr->camerascale); + else if (fastcmp(field,"shieldscale")) + lua_pushfixed(L, plr->shieldscale); else if (fastcmp(field,"viewz")) lua_pushfixed(L, plr->viewz); else if (fastcmp(field,"viewheight")) @@ -118,8 +126,12 @@ static int player_get(lua_State *L) lua_pushfixed(L, plr->bob); else if (fastcmp(field,"aiming")) lua_pushangle(L, plr->aiming); - else if (fastcmp(field,"health")) - lua_pushinteger(L, plr->health); + else if (fastcmp(field,"drawangle")) + lua_pushangle(L, plr->drawangle); + else if (fastcmp(field,"rings")) + lua_pushinteger(L, plr->rings); + else if (fastcmp(field,"spheres")) + lua_pushinteger(L, plr->spheres); else if (fastcmp(field,"pity")) lua_pushinteger(L, plr->pity); else if (fastcmp(field,"currentweapon")) @@ -142,8 +154,6 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->score); else if (fastcmp(field,"dashspeed")) lua_pushfixed(L, plr->dashspeed); - else if (fastcmp(field,"dashtime")) - lua_pushinteger(L, plr->dashtime); else if (fastcmp(field,"normalspeed")) lua_pushfixed(L, plr->normalspeed); else if (fastcmp(field,"runspeed")) @@ -166,6 +176,10 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->spinitem); else if (fastcmp(field,"revitem")) lua_pushinteger(L, plr->revitem); + else if (fastcmp(field,"followitem")) + lua_pushinteger(L, plr->followitem); + else if (fastcmp(field,"followmobj")) + LUA_PushUserdata(L, plr->followmobj, META_MOBJ); else if (fastcmp(field,"actionspd")) lua_pushfixed(L, plr->actionspd); else if (fastcmp(field,"mindash")) @@ -174,6 +188,10 @@ static int player_get(lua_State *L) lua_pushfixed(L, plr->maxdash); else if (fastcmp(field,"jumpfactor")) lua_pushfixed(L, plr->jumpfactor); + else if (fastcmp(field,"height")) + lua_pushfixed(L, plr->height); + else if (fastcmp(field,"spinheight")) + lua_pushfixed(L, plr->spinheight); else if (fastcmp(field,"lives")) lua_pushinteger(L, plr->lives); else if (fastcmp(field,"continues")) @@ -184,8 +202,6 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->gotcontinue); else if (fastcmp(field,"speed")) lua_pushfixed(L, plr->speed); - else if (fastcmp(field,"jumping")) - lua_pushboolean(L, plr->jumping); else if (fastcmp(field,"secondjump")) lua_pushinteger(L, plr->secondjump); else if (fastcmp(field,"fly1")) @@ -202,6 +218,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->exiting); else if (fastcmp(field,"homing")) lua_pushinteger(L, plr->homing); + else if (fastcmp(field,"dashmode")) + lua_pushinteger(L, plr->dashmode); else if (fastcmp(field,"skidtime")) lua_pushinteger(L, plr->skidtime); else if (fastcmp(field,"cmomx")) @@ -270,22 +288,46 @@ static int player_get(lua_State *L) lua_pushboolean(L, plr->bonustime); else if (fastcmp(field,"capsule")) LUA_PushUserdata(L, plr->capsule, META_MOBJ); + else if (fastcmp(field,"drone")) + LUA_PushUserdata(L, plr->drone, META_MOBJ); + else if (fastcmp(field,"oldscale")) + lua_pushfixed(L, plr->oldscale); else if (fastcmp(field,"mare")) lua_pushinteger(L, plr->mare); + else if (fastcmp(field,"marelap")) + lua_pushinteger(L, plr->marelap); + else if (fastcmp(field,"marebonuslap")) + lua_pushinteger(L, plr->marebonuslap); else if (fastcmp(field,"marebegunat")) lua_pushinteger(L, plr->marebegunat); else if (fastcmp(field,"startedtime")) lua_pushinteger(L, plr->startedtime); else if (fastcmp(field,"finishedtime")) lua_pushinteger(L, plr->finishedtime); + else if (fastcmp(field,"lapbegunat")) + lua_pushinteger(L, plr->lapbegunat); + else if (fastcmp(field,"lapstartedtime")) + lua_pushinteger(L, plr->lapstartedtime); + else if (fastcmp(field,"finishedspheres")) + lua_pushinteger(L, plr->finishedspheres); else if (fastcmp(field,"finishedrings")) lua_pushinteger(L, plr->finishedrings); else if (fastcmp(field,"marescore")) lua_pushinteger(L, plr->marescore); else if (fastcmp(field,"lastmarescore")) lua_pushinteger(L, plr->lastmarescore); + else if (fastcmp(field,"totalmarescore")) + lua_pushinteger(L, plr->totalmarescore); else if (fastcmp(field,"lastmare")) lua_pushinteger(L, plr->lastmare); + else if (fastcmp(field,"lastmarelap")) + lua_pushinteger(L, plr->lastmarelap); + else if (fastcmp(field,"lastmarebonuslap")) + lua_pushinteger(L, plr->lastmarebonuslap); + else if (fastcmp(field,"totalmarelap")) + lua_pushinteger(L, plr->totalmarelap); + else if (fastcmp(field,"totalmarebonuslap")) + lua_pushinteger(L, plr->totalmarebonuslap); else if (fastcmp(field,"maxlink")) lua_pushinteger(L, plr->maxlink); else if (fastcmp(field,"texttimer")) @@ -310,6 +352,8 @@ static int player_get(lua_State *L) lua_pushangle(L, plr->awayviewaiming); else if (fastcmp(field,"spectator")) lua_pushboolean(L, plr->spectator); + else if (fastcmp(field,"outofcoop")) + lua_pushboolean(L, plr->outofcoop); else if (fastcmp(field,"bot")) lua_pushinteger(L, plr->bot); else if (fastcmp(field,"jointime")) @@ -355,6 +399,10 @@ static int player_set(lua_State *L) return NOSET; else if (fastcmp(field,"playerstate")) plr->playerstate = luaL_checkinteger(L, 3); + else if (fastcmp(field,"camerascale")) + plr->camerascale = luaL_checkfixed(L, 3); + else if (fastcmp(field,"shieldscale")) + plr->shieldscale = luaL_checkfixed(L, 3); else if (fastcmp(field,"viewz")) plr->viewz = luaL_checkfixed(L, 3); else if (fastcmp(field,"viewheight")) @@ -370,8 +418,12 @@ static int player_set(lua_State *L) else if (plr == &players[secondarydisplayplayer]) localaiming2 = plr->aiming; } - else if (fastcmp(field,"health")) - plr->health = (INT32)luaL_checkinteger(L, 3); + else if (fastcmp(field,"drawangle")) + plr->drawangle = luaL_checkangle(L, 3); + else if (fastcmp(field,"rings")) + plr->rings = (INT32)luaL_checkinteger(L, 3); + else if (fastcmp(field,"spheres")) + plr->spheres = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"pity")) plr->pity = (SINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"currentweapon")) @@ -399,8 +451,6 @@ static int player_set(lua_State *L) plr->score = (UINT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"dashspeed")) plr->dashspeed = luaL_checkfixed(L, 3); - else if (fastcmp(field,"dashtime")) - plr->dashtime = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"normalspeed")) plr->normalspeed = luaL_checkfixed(L, 3); else if (fastcmp(field,"runspeed")) @@ -423,6 +473,10 @@ static int player_set(lua_State *L) plr->spinitem = luaL_checkinteger(L, 3); else if (fastcmp(field,"revitem")) plr->revitem = luaL_checkinteger(L, 3); + else if (fastcmp(field,"followitem")) + plr->followitem = luaL_checkinteger(L, 3); + else if (fastcmp(field,"followmobj")) + P_SetTarget(&plr->followmobj, *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ))); else if (fastcmp(field,"actionspd")) plr->actionspd = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"mindash")) @@ -431,6 +485,10 @@ static int player_set(lua_State *L) plr->maxdash = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"jumpfactor")) plr->jumpfactor = (INT32)luaL_checkinteger(L, 3); + else if (fastcmp(field,"height")) + plr->height = luaL_checkfixed(L, 3); + else if (fastcmp(field,"spinheight")) + plr->spinheight = luaL_checkfixed(L, 3); else if (fastcmp(field,"lives")) plr->lives = (SINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"continues")) @@ -441,8 +499,6 @@ static int player_set(lua_State *L) plr->gotcontinue = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"speed")) plr->speed = luaL_checkfixed(L, 3); - else if (fastcmp(field,"jumping")) - plr->jumping = luaL_checkboolean(L, 3); else if (fastcmp(field,"secondjump")) plr->secondjump = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"fly1")) @@ -459,6 +515,8 @@ static int player_set(lua_State *L) plr->exiting = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"homing")) plr->homing = (UINT8)luaL_checkinteger(L, 3); + else if (fastcmp(field,"dashmode")) + plr->dashmode = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"skidtime")) plr->skidtime = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"cmomx")) @@ -532,22 +590,51 @@ static int player_set(lua_State *L) mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); P_SetTarget(&plr->capsule, mo); } + else if (fastcmp(field,"drone")) + { + mobj_t *mo = NULL; + if (!lua_isnil(L, 3)) + mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&plr->drone, mo); + } + else if (fastcmp(field,"oldscale")) + plr->oldscale = luaL_checkfixed(L, 3); else if (fastcmp(field,"mare")) plr->mare = (UINT8)luaL_checkinteger(L, 3); + else if (fastcmp(field,"marelap")) + plr->marelap = (UINT8)luaL_checkinteger(L, 3); + else if (fastcmp(field,"marebonuslap")) + plr->marebonuslap = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"marebegunat")) plr->marebegunat = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"startedtime")) plr->startedtime = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"finishedtime")) plr->finishedtime = (tic_t)luaL_checkinteger(L, 3); + else if (fastcmp(field,"lapbegunat")) + plr->lapbegunat = (tic_t)luaL_checkinteger(L, 3); + else if (fastcmp(field,"lapstartedtime")) + plr->lapstartedtime = (tic_t)luaL_checkinteger(L, 3); + else if (fastcmp(field,"finishedspheres")) + plr->finishedspheres = (INT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"finishedrings")) plr->finishedrings = (INT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"marescore")) plr->marescore = (UINT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"lastmarescore")) plr->lastmarescore = (UINT32)luaL_checkinteger(L, 3); + else if (fastcmp(field,"totalmarescore")) + plr->totalmarescore = (UINT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"lastmare")) plr->lastmare = (UINT8)luaL_checkinteger(L, 3); + else if (fastcmp(field,"lastmarelap")) + plr->lastmarelap = (UINT8)luaL_checkinteger(L, 3); + else if (fastcmp(field,"lastmarebonuslap")) + plr->lastmarebonuslap = (UINT8)luaL_checkinteger(L, 3); + else if (fastcmp(field,"totalmarelap")) + plr->totalmarelap = (UINT8)luaL_checkinteger(L, 3); + else if (fastcmp(field,"totalmarebonuslap")) + plr->totalmarebonuslap = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"maxlink")) plr->maxlink = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"texttimer")) @@ -581,6 +668,8 @@ static int player_set(lua_State *L) plr->awayviewaiming = luaL_checkangle(L, 3); else if (fastcmp(field,"spectator")) plr->spectator = lua_toboolean(L, 3); + else if (fastcmp(field,"outofcoop")) + plr->outofcoop = lua_toboolean(L, 3); else if (fastcmp(field,"bot")) return NOSET; else if (fastcmp(field,"jointime")) diff --git a/src/lua_script.c b/src/lua_script.c index edf8ac3c5da5b2e843101596eb2b8be14b28c204..04aa55cf07a9423cde72f9ea770273bc090e1cf6 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -164,6 +164,11 @@ void LUA_ClearExtVars(void) } #endif +// Use this variable to prevent certain functions from running +// if they were not called on lump load +// (i.e. they were called in hooks or coroutines etc) +boolean lua_lumploading = false; + // Load a script from a MYFILE static inline void LUA_LoadFile(MYFILE *f, char *name) { @@ -175,11 +180,15 @@ static inline void LUA_LoadFile(MYFILE *f, char *name) lua_pushinteger(gL, f->wad); lua_setfield(gL, LUA_REGISTRYINDEX, "WAD"); + lua_lumploading = true; // turn on loading flag + if (luaL_loadbuffer(gL, f->data, f->size, va("@%s",name)) || lua_pcall(gL, 0, 0, 0)) { CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); lua_pop(gL,1); } lua_gc(gL, LUA_GCCOLLECT, 0); + + lua_lumploading = false; // turn off again } // Load a script from a lump @@ -408,6 +417,7 @@ void LUA_InvalidateLevel(void) { thinker_t *th; size_t i; + ffloor_t *rover = NULL; if (!gL) return; @@ -419,7 +429,15 @@ void LUA_InvalidateLevel(void) for (i = 0; i < numsubsectors; i++) LUA_InvalidateUserdata(&subsectors[i]); for (i = 0; i < numsectors; i++) + { LUA_InvalidateUserdata(§ors[i]); + LUA_InvalidateUserdata(sectors[i].lines); + if (sectors[i].ffloors) + { + for (rover = sectors[i].ffloors; rover; rover = rover->next) + LUA_InvalidateUserdata(rover); + } + } for (i = 0; i < numlines; i++) { LUA_InvalidateUserdata(&lines[i]); @@ -429,6 +447,16 @@ void LUA_InvalidateLevel(void) LUA_InvalidateUserdata(&sides[i]); for (i = 0; i < numvertexes; i++) LUA_InvalidateUserdata(&vertexes[i]); +#ifdef HAVE_LUA_SEGS + for (i = 0; i < numsegs; i++) + LUA_InvalidateUserdata(&segs[i]); + for (i = 0; i < numnodes; i++) + { + LUA_InvalidateUserdata(&nodes[i]); + LUA_InvalidateUserdata(nodes[i].bbox); + LUA_InvalidateUserdata(nodes[i].children); + } +#endif } void LUA_InvalidateMapthings(void) @@ -468,6 +496,11 @@ enum ARCH_SIDE, ARCH_SUBSECTOR, ARCH_SECTOR, +#ifdef HAVE_LUA_SEGS + ARCH_SEG, + ARCH_NODE, +#endif + ARCH_FFLOOR, #ifdef ESLOPE ARCH_SLOPE, #endif @@ -490,6 +523,11 @@ static const struct { {META_SIDE, ARCH_SIDE}, {META_SUBSECTOR,ARCH_SUBSECTOR}, {META_SECTOR, ARCH_SECTOR}, +#ifdef HAVE_LUA_SEGS + {META_SEG, ARCH_SEG}, + {META_NODE, ARCH_NODE}, +#endif + {META_FFLOOR, ARCH_FFLOOR}, #ifdef ESLOPE {META_SLOPE, ARCH_SLOPE}, #endif @@ -697,6 +735,56 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) } break; } +#ifdef HAVE_LUA_SEGS + case ARCH_SEG: + { + seg_t *seg = *((seg_t **)lua_touserdata(gL, myindex)); + if (!seg) + WRITEUINT8(save_p, ARCH_NULL); + else { + WRITEUINT8(save_p, ARCH_SEG); + WRITEUINT16(save_p, seg - segs); + } + break; + } + case ARCH_NODE: + { + node_t *node = *((node_t **)lua_touserdata(gL, myindex)); + if (!node) + WRITEUINT8(save_p, ARCH_NULL); + else { + WRITEUINT8(save_p, ARCH_NODE); + WRITEUINT16(save_p, node - nodes); + } + break; + } +#endif + case ARCH_FFLOOR: + { + ffloor_t *rover = *((ffloor_t **)lua_touserdata(gL, myindex)); + if (!rover) + WRITEUINT8(save_p, ARCH_NULL); + else { + ffloor_t *r2; + UINT16 i = 0; + // search for id + for (r2 = rover->target->ffloors; r2; r2 = r2->next) + { + if (r2 == rover) + break; + i++; + } + if (!r2) + WRITEUINT8(save_p, ARCH_NULL); + else + { + WRITEUINT8(save_p, ARCH_FFLOOR); + WRITEUINT16(save_p, rover->target - sectors); + WRITEUINT16(save_p, i); + } + } + break; + } #ifdef ESLOPE case ARCH_SLOPE: { @@ -914,6 +1002,23 @@ static UINT8 UnArchiveValue(int TABLESINDEX) case ARCH_SECTOR: LUA_PushUserdata(gL, §ors[READUINT16(save_p)], META_SECTOR); break; +#ifdef HAVE_LUA_SEGS + case ARCH_SEG: + LUA_PushUserdata(gL, &segs[READUINT16(save_p)], META_SEG); + break; + case ARCH_NODE: + LUA_PushUserdata(gL, &nodes[READUINT16(save_p)], META_NODE); + break; +#endif + case ARCH_FFLOOR: + { + sector_t *sector = §ors[READUINT16(save_p)]; + UINT16 id = READUINT16(save_p); + ffloor_t *rover = P_GetFFloorByID(sector, id); + if (rover) + LUA_PushUserdata(gL, rover, META_FFLOOR); + break; + } #ifdef ESLOPE case ARCH_SLOPE: LUA_PushUserdata(gL, P_SlopeById(READUINT16(save_p)), META_SLOPE); diff --git a/src/lua_script.h b/src/lua_script.h index f944149d721e200c5ee9a8508de347aac6acbdee..b690e4fa7577e6f0076a7f6d7b878bde9d01581d 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -38,6 +38,8 @@ void LUA_ClearExtVars(void); #endif +extern boolean lua_lumploading; // is LUA_LoadLump being called? + void LUA_LoadLump(UINT16 wad, UINT16 lump); #ifdef LUA_ALLOW_BYTECODE void LUA_DumpFile(const char *filename); @@ -92,4 +94,7 @@ void COM_Lua_f(void); }\ } +// uncomment if you want seg_t/node_t in Lua +// #define HAVE_LUA_SEGS + #endif diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index 0fbcb2fd3c70cde9ac0d710d316a003414a39e64..a8f785c5aec9024f2b757e15c1b9e37194c87ee8 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -35,6 +35,7 @@ enum skin { skin_thokitem, skin_spinitem, skin_revitem, + skin_followitem, skin_actionspd, skin_mindash, skin_maxdash, @@ -44,10 +45,18 @@ enum skin { skin_accelstart, skin_acceleration, skin_jumpfactor, + skin_radius, + skin_height, + skin_spinheight, + skin_shieldscale, + skin_camerascale, skin_starttranscolor, skin_prefcolor, + skin_supercolor, + skin_prefoppositecolor, skin_highresscale, - skin_soundsid + skin_soundsid, + skin_availability }; static const char *const skin_opt[] = { "valid", @@ -65,6 +74,7 @@ static const char *const skin_opt[] = { "thokitem", "spinitem", "revitem", + "followitem", "actionspd", "mindash", "maxdash", @@ -74,10 +84,18 @@ static const char *const skin_opt[] = { "accelstart", "acceleration", "jumpfactor", + "radius", + "height", + "spinheight", + "shieldscale", + "camerascale", "starttranscolor", "prefcolor", + "supercolor", + "prefoppositecolor", "highresscale", "soundsid", + "availability", NULL}; #define UNIMPLEMENTED luaL_error(L, LUA_QL("skin_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", skin_opt[field]) @@ -146,6 +164,9 @@ static int skin_get(lua_State *L) case skin_revitem: lua_pushinteger(L, skin->revitem); break; + case skin_followitem: + lua_pushinteger(L, skin->followitem); + break; case skin_actionspd: lua_pushfixed(L, skin->actionspd); break; @@ -173,18 +194,42 @@ static int skin_get(lua_State *L) case skin_jumpfactor: lua_pushfixed(L, skin->jumpfactor); break; + case skin_radius: + lua_pushfixed(L, skin->radius); + break; + case skin_height: + lua_pushfixed(L, skin->height); + break; + case skin_spinheight: + lua_pushfixed(L, skin->spinheight); + break; + case skin_shieldscale: + lua_pushfixed(L, skin->shieldscale); + break; + case skin_camerascale: + lua_pushfixed(L, skin->camerascale); + break; case skin_starttranscolor: lua_pushinteger(L, skin->starttranscolor); break; case skin_prefcolor: lua_pushinteger(L, skin->prefcolor); break; + case skin_supercolor: + lua_pushinteger(L, skin->supercolor); + break; + case skin_prefoppositecolor: + lua_pushinteger(L, skin->prefoppositecolor); + break; case skin_highresscale: lua_pushinteger(L, skin->highresscale); break; case skin_soundsid: LUA_PushUserdata(L, skin->soundsid, META_SOUNDSID); break; + case skin_availability: + lua_pushinteger(L, skin->availability); + break; } return 1; } diff --git a/src/lua_thinkerlib.c b/src/lua_thinkerlib.c index ae859d46ee55a151f03510af477d2bb02033f6e5..ae648613a9ad77ec7b752a13e2ca0b092cfed61d 100644 --- a/src/lua_thinkerlib.c +++ b/src/lua_thinkerlib.c @@ -54,7 +54,13 @@ static int iterationState_gc(lua_State *L) static int lib_iterateThinkers(lua_State *L) { thinker_t *th = NULL, *next = NULL; - struct iterationState *it = luaL_checkudata(L, 1, META_ITERATIONSTATE); + struct iterationState *it; + + if (gamestate != GS_LEVEL) + return luaL_error(L, "This function can only be used in a level!"); + + it = luaL_checkudata(L, 1, META_ITERATIONSTATE); + lua_settop(L, 2); if (lua_isnil(L, 2)) @@ -106,6 +112,9 @@ static int lib_startIterate(lua_State *L) { struct iterationState *it; + if (gamestate != GS_LEVEL) + return luaL_error(L, "This function can only be used in a level!"); + lua_pushvalue(L, lua_upvalueindex(1)); it = lua_newuserdata(L, sizeof(struct iterationState)); luaL_getmetatable(L, META_ITERATIONSTATE); diff --git a/src/lzf.c b/src/lzf.c index 272174f30a54a6c04b64c864dff2304f57cad6cc..f81c3ee0a36321356a4eafff073d3177dd19fbd7 100644 --- a/src/lzf.c +++ b/src/lzf.c @@ -119,9 +119,7 @@ /*****************************************************************************/ /* nothing should be changed below */ -#ifndef _NDS typedef unsigned char u8; -#endif typedef const u8 *LZF_STATE[1 << (HLOG)]; @@ -159,7 +157,7 @@ typedef const u8 *LZF_STATE[1 << (HLOG)]; * lzfP.h ends here. lzf_d.c follows. */ -#if AVOID_ERRNO || defined(_WIN32_WCE) +#if AVOID_ERRNO # define SET_ERRNO(n) #else # include <errno.h> diff --git a/src/m_anigif.c b/src/m_anigif.c index 4e68819bc70313bc120366abd3ffeba13578f4fc..901927fa1bd2059660ac18f87451994347842a6a 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -18,6 +18,7 @@ #include "z_zone.h" #include "v_video.h" #include "i_video.h" +#include "m_misc.h" // GIFs are always little-endian #include "byteptr.h" @@ -396,7 +397,6 @@ static void GIF_headwrite(void) { UINT8 *gifhead = Z_Malloc(800, PU_STATIC, NULL); UINT8 *p = gifhead; - RGBA_t *c; INT32 i; UINT16 rwidth, rheight; @@ -427,12 +427,17 @@ static void GIF_headwrite(void) WRITEUINT8(p, 0x00); // write color table - for (i = 0; i < 256; ++i) { - c = &pLocalPalette[i]; - WRITEUINT8(p, c->s.red); - WRITEUINT8(p, c->s.green); - WRITEUINT8(p, c->s.blue); + RGBA_t *pal = ((cv_screenshot_colorprofile.value) + ? pLocalPalette + : pMasterPalette); + + for (i = 0; i < 256; i++) + { + WRITEUINT8(p, pal[i].s.red); + WRITEUINT8(p, pal[i].s.green); + WRITEUINT8(p, pal[i].s.blue); + } } // write extension block diff --git a/src/m_argv.c b/src/m_argv.c index e8bfdd3db237b762c5215e9a8728388d4bade9e2..117ec78339cf9768cab2110da40d00d619178c37 100644 --- a/src/m_argv.c +++ b/src/m_argv.c @@ -127,12 +127,7 @@ void M_PushSpecialParameters(void) } /// \brief max args - -#if defined (_arch_dreamcast) || defined (_XBOX) || defined (_WII) -#define MAXARGVS 1 -#else #define MAXARGVS 256 -#endif /** \brief the M_FindResponseFile function Find a response file diff --git a/src/m_cheat.c b/src/m_cheat.c index 6fa3ea113030dffde9e7260dcc611748a85e5b15..bee60087fec00c0d44beb4665779d907d4360d74 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -61,7 +61,7 @@ static UINT8 cheatf_ultimate(void) if (menuactive && (currentMenu != &MainDef && currentMenu != &SP_LoadDef)) return 0; // Only on the main menu, or the save select! - S_StartSound(0, sfx_itemup); + BwehHehHe(); ultimate_selectable = (!ultimate_selectable); // If on the save select, move to what is now Ultimate Mode! @@ -70,6 +70,7 @@ static UINT8 cheatf_ultimate(void) return 1; } +#ifdef REDXVI static UINT8 cheatf_warp(void) { if (modifiedgame) @@ -91,6 +92,7 @@ static UINT8 cheatf_warp(void) M_StartControlPanel(); return 1; } +#endif #ifdef DEVELOP static UINT8 cheatf_devmode(void) @@ -109,7 +111,7 @@ static UINT8 cheatf_devmode(void) G_SetGameModified(false); for (i = 0; i < MAXUNLOCKABLES; i++) unlockables[i].unlocked = true; - devparm = TRUE; + devparm = true; cv_debug |= 0x8000; // Refresh secrets menu existing. @@ -131,6 +133,7 @@ static cheatseq_t cheat_ultimate_joy = { SCRAMBLE(KEY_ENTER), 0xff } }; +#ifdef REDXVI static cheatseq_t cheat_warp = { 0, cheatf_warp, { SCRAMBLE('r'), SCRAMBLE('e'), SCRAMBLE('d'), SCRAMBLE('x'), SCRAMBLE('v'), SCRAMBLE('i'), 0xff } @@ -143,6 +146,7 @@ static cheatseq_t cheat_warp_joy = { SCRAMBLE(KEY_LEFTARROW), SCRAMBLE(KEY_UPARROW), SCRAMBLE(KEY_ENTER), 0xff } }; +#endif #ifdef DEVELOP static cheatseq_t cheat_devmode = { @@ -235,8 +239,10 @@ boolean cht_Responder(event_t *ev) ret += cht_CheckCheat(&cheat_ultimate, (char)ch); ret += cht_CheckCheat(&cheat_ultimate_joy, (char)ch); +#ifdef REDXVI ret += cht_CheckCheat(&cheat_warp, (char)ch); ret += cht_CheckCheat(&cheat_warp_joy, (char)ch); +#endif #ifdef DEVELOP ret += cht_CheckCheat(&cheat_devmode, (char)ch); #endif @@ -353,7 +359,7 @@ void Command_Hurtme_f(void) return; } - P_DamageMobj(players[consoleplayer].mo, NULL, NULL, atoi(COM_Argv(1))); + P_DamageMobj(players[consoleplayer].mo, NULL, NULL, atoi(COM_Argv(1)), 0); } // Moves the NiGHTS player to another axis within the current mare @@ -493,56 +499,211 @@ void Command_Teleport_f(void) REQUIRE_INLEVEL; REQUIRE_SINGLEPLAYER; - if (COM_Argc() < 3 || COM_Argc() > 7) + if (COM_Argc() < 3 || COM_Argc() > 11) { - CONS_Printf(M_GetText("teleport -x <value> -y <value> -z <value>: teleport to a location\n")); + CONS_Printf(M_GetText("teleport -x <value> -y <value> -z <value> -ang <value> -aim <value>: teleport to a location\nteleport -sp <sequence> <placement>: teleport to specified checkpoint\n")); return; } if (!p->mo) return; - i = COM_CheckParm("-x"); + i = COM_CheckParm("-sp"); if (i) - intx = atoi(COM_Argv(i + 1)); - else { - CONS_Alert(CONS_NOTICE, M_GetText("%s value not specified\n"), "X"); - return; - } + INT32 starpostnum = atoi(COM_Argv(i + 1)); // starpost number + INT32 starpostpath = atoi(COM_Argv(i + 2)); // quick, dirty way to distinguish between paths - i = COM_CheckParm("-y"); - if (i) - inty = atoi(COM_Argv(i + 1)); - else - { - CONS_Alert(CONS_NOTICE, M_GetText("%s value not specified\n"), "Y"); - return; - } + if (starpostnum < 0 || starpostpath < 0) + { + CONS_Alert(CONS_NOTICE, M_GetText("Negative starpost indexing is not valid.\n")); + return; + } - ss = R_PointInSubsector(intx*FRACUNIT, inty*FRACUNIT); - if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height) - { - CONS_Alert(CONS_NOTICE, M_GetText("Not a valid location.\n")); - return; - } - i = COM_CheckParm("-z"); - if (i) - { - intz = atoi(COM_Argv(i + 1)); - intz <<= FRACBITS; - if (intz < ss->sector->floorheight) - intz = ss->sector->floorheight; - if (intz > ss->sector->ceilingheight - p->mo->height) - intz = ss->sector->ceilingheight - p->mo->height; + if (!starpostnum) // spawnpoints... + { + mapthing_t *mt; + + if (starpostpath >= numcoopstarts) + { + CONS_Alert(CONS_NOTICE, M_GetText("Player %d spawnpoint not found (%d max).\n"), starpostpath+1, numcoopstarts-1); + return; + } + + mt = playerstarts[starpostpath]; // Given above check, should never be NULL. + intx = mt->x<<FRACBITS; + inty = mt->y<<FRACBITS; + + ss = R_IsPointInSubsector(intx, inty); + if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height) + { + CONS_Alert(CONS_NOTICE, M_GetText("Spawnpoint not in a valid location.\n")); + return; + } + + // Flagging a player's ambush will make them start on the ceiling + // Objectflip inverts + if (!!(mt->options & MTF_AMBUSH) ^ !!(mt->options & MTF_OBJECTFLIP)) + { + intz = ss->sector->ceilingheight - p->mo->height; + if (mt->options >> ZSHIFT) + intz -= ((mt->options >> ZSHIFT) << FRACBITS); + } + else + { + intz = ss->sector->floorheight; + if (mt->options >> ZSHIFT) + intz += ((mt->options >> ZSHIFT) << FRACBITS); + } + + if (mt->options & MTF_OBJECTFLIP) // flip the player! + { + p->mo->eflags |= MFE_VERTICALFLIP; + p->mo->flags2 |= MF2_OBJECTFLIP; + } + else + { + p->mo->eflags &= ~MFE_VERTICALFLIP; + p->mo->flags2 &= ~MF2_OBJECTFLIP; + } + + localangle = p->mo->angle = p->drawangle = FixedAngle(mt->angle<<FRACBITS); + } + else // scan the thinkers to find starposts... + { + mobj_t *mo2 = NULL; + thinker_t *th; + + INT32 starpostmax = 0; + intz = starpostpath; // variable reuse - counting down for selection purposes + + for (th = thinkercap.next; th != &thinkercap; th = th->next) + { + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; + + mo2 = (mobj_t *)th; + + if (mo2->type != MT_STARPOST) + continue; + + if (mo2->health != starpostnum) + { + if (mo2->health > starpostmax) + starpostmax = mo2->health; + continue; + } + + if (intz--) + continue; + + break; + } + + if (th == &thinkercap) + { + if (intz == starpostpath) + CONS_Alert(CONS_NOTICE, M_GetText("No starpost of position %d found (%d max).\n"), starpostnum, starpostmax); + else + CONS_Alert(CONS_NOTICE, M_GetText("Starpost of position %d, %d not found (%d, %d max).\n"), starpostnum, starpostpath, starpostmax, (starpostpath-intz)-1); + return; + } + + ss = R_IsPointInSubsector(mo2->x, mo2->y); + if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height) + { + CONS_Alert(CONS_NOTICE, M_GetText("Starpost not in a valid location.\n")); + return; + } + + intx = mo2->x; + inty = mo2->y; + intz = mo2->z; + + if (mo2->flags2 & MF2_OBJECTFLIP) // flip the player! + { + p->mo->eflags |= MFE_VERTICALFLIP; + p->mo->flags2 |= MF2_OBJECTFLIP; + } + else + { + p->mo->eflags &= ~MFE_VERTICALFLIP; + p->mo->flags2 &= ~MF2_OBJECTFLIP; + } + + localangle = p->mo->angle = p->drawangle = mo2->angle; + } + + CONS_Printf(M_GetText("Teleporting to checkpoint %d, %d...\n"), starpostnum, starpostpath); } else - intz = ss->sector->floorheight; + { + i = COM_CheckParm("-nop"); // undocumented stupid addition to allow pivoting on the spot with -ang and -aim + if (i) + { + intx = p->mo->x; + inty = p->mo->y; + } + else + { + i = COM_CheckParm("-x"); + if (i) + intx = atoi(COM_Argv(i + 1))<<FRACBITS; + else + { + CONS_Alert(CONS_NOTICE, M_GetText("%s value not specified.\n"), "X"); + return; + } + + i = COM_CheckParm("-y"); + if (i) + inty = atoi(COM_Argv(i + 1))<<FRACBITS; + else + { + CONS_Alert(CONS_NOTICE, M_GetText("%s value not specified.\n"), "Y"); + return; + } + } + + ss = R_IsPointInSubsector(intx, inty); + if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height) + { + CONS_Alert(CONS_NOTICE, M_GetText("Not a valid location.\n")); + return; + } + i = COM_CheckParm("-z"); + if (i) + { + intz = atoi(COM_Argv(i + 1))<<FRACBITS; + if (intz < ss->sector->floorheight) + intz = ss->sector->floorheight; + if (intz > ss->sector->ceilingheight - p->mo->height) + intz = ss->sector->ceilingheight - p->mo->height; + } + else + intz = ((p->mo->eflags & MFE_VERTICALFLIP) ? ss->sector->ceilingheight : ss->sector->floorheight); - CONS_Printf(M_GetText("Teleporting to %d, %d, %d...\n"), intx, inty, FixedInt(intz)); + i = COM_CheckParm("-ang"); + if (i) + localangle = p->drawangle = p->mo->angle = FixedAngle(atoi(COM_Argv(i + 1))<<FRACBITS); + + i = COM_CheckParm("-aim"); + if (i) + { + angle_t aim = FixedAngle(atoi(COM_Argv(i + 1))<<FRACBITS); + if (aim >= ANGLE_90 && aim <= ANGLE_270) + { + CONS_Alert(CONS_NOTICE, M_GetText("Not a valid aiming angle (between +/-90).\n")); + return; + } + localaiming = p->aiming = aim; + } + + CONS_Printf(M_GetText("Teleporting to %d, %d, %d...\n"), FixedInt(intx), FixedInt(inty), FixedInt(intz)); + } P_MapStart(); - if (!P_TeleportMove(p->mo, intx*FRACUNIT, inty*FRACUNIT, intz)) + if (!P_TeleportMove(p->mo, intx, inty, intz)) CONS_Alert(CONS_WARNING, M_GetText("Unable to teleport to that spot!\n")); else S_StartSound(p->mo, sfx_mixup); @@ -606,7 +767,7 @@ void Command_CauseCfail_f(void) players[consoleplayer].mo->y = 123311; //cfail cansuled kthxbye players[consoleplayer].mo->z = 123311; players[consoleplayer].score = 1337; - players[consoleplayer].health = 1337; + players[consoleplayer].rings = 1337; players[consoleplayer].mo->destscale = 25; P_SetThingPosition(players[consoleplayer].mo); @@ -719,11 +880,19 @@ void Command_Setrings_f(void) if (COM_Argc() > 1) { - // P_GivePlayerRings does value clamping - players[consoleplayer].health = players[consoleplayer].mo->health = 1; - P_GivePlayerRings(&players[consoleplayer], atoi(COM_Argv(1))); - if (!G_IsSpecialStage(gamemap) || !useNightsSS) + if (!(maptol & TOL_NIGHTS)) + { + // P_GivePlayerRings does value clamping + players[consoleplayer].rings = 0; + P_GivePlayerRings(&players[consoleplayer], atoi(COM_Argv(1))); players[consoleplayer].totalring -= atoi(COM_Argv(1)); //undo totalring addition done in P_GivePlayerRings + } + else + { + players[consoleplayer].spheres = 0; + P_GivePlayerSpheres(&players[consoleplayer], atoi(COM_Argv(1))); + // no totalsphere addition to revert + } G_SetGameModified(multiplayer); } @@ -738,9 +907,15 @@ void Command_Setlives_f(void) if (COM_Argc() > 1) { - // P_GivePlayerLives does value clamping - players[consoleplayer].lives = 0; - P_GivePlayerLives(&players[consoleplayer], atoi(COM_Argv(1))); + SINT8 lives = atoi(COM_Argv(1)); + if (lives == -1) + players[consoleplayer].lives = INFLIVES; // infinity! + else + { + // P_GivePlayerLives does value clamping + players[consoleplayer].lives = 0; + P_GivePlayerLives(&players[consoleplayer], atoi(COM_Argv(1))); + } G_SetGameModified(multiplayer); } @@ -773,10 +948,12 @@ void Command_Setcontinues_f(void) static CV_PossibleValue_t op_mapthing_t[] = {{0, "MIN"}, {4095, "MAX"}, {0, NULL}}; static CV_PossibleValue_t op_speed_t[] = {{1, "MIN"}, {128, "MAX"}, {0, NULL}}; static CV_PossibleValue_t op_flags_t[] = {{0, "MIN"}, {15, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t op_hoopflags_t[] = {{0, "MIN"}, {15, "MAX"}, {0, NULL}}; consvar_t cv_mapthingnum = {"op_mapthingnum", "0", CV_NOTINNET, op_mapthing_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_speed = {"op_speed", "16", CV_NOTINNET, op_speed_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_opflags = {"op_flags", "0", CV_NOTINNET, op_flags_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_ophoopflags = {"op_hoopflags", "4", CV_NOTINNET, op_hoopflags_t, NULL, 0, NULL, NULL, 0, 0, NULL}; boolean objectplacing = false; mobjtype_t op_currentthing = 0; // For the object placement mode @@ -942,7 +1119,7 @@ boolean OP_FreezeObjectplace(void) if (!objectplacing) return false; - if ((maptol & TOL_NIGHTS) && (players[consoleplayer].pflags & PF_NIGHTSMODE)) + if ((maptol & TOL_NIGHTS) && (players[consoleplayer].powers[pw_carry] == CR_NIGHTSMODE)) return false; return true; @@ -968,7 +1145,7 @@ void OP_NightsObjectplace(player_t *player) if (player->pflags & PF_ATTACKDOWN) { // Are ANY objectplace buttons pressed? If no, remove flag. - if (!(cmd->buttons & (BT_ATTACK|BT_TOSSFLAG|BT_USE|BT_CAMRIGHT|BT_CAMLEFT))) + if (!(cmd->buttons & (BT_ATTACK|BT_TOSSFLAG|BT_USE|BT_WEAPONNEXT|BT_WEAPONPREV))) player->pflags &= ~PF_ATTACKDOWN; // Do nothing. @@ -980,17 +1157,10 @@ void OP_NightsObjectplace(player_t *player) { UINT16 angle = (UINT16)(player->anotherflyangle % 360); INT16 temp = (INT16)FixedInt(AngleFixed(player->mo->angle)); // Traditional 2D Angle - sector_t *sec = player->mo->subsector->sector; -#ifdef ESLOPE - fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight; -#else - fixed_t fheight = sec->floorheight; -#endif - player->pflags |= PF_ATTACKDOWN; - mt = OP_CreateNewMapThing(player, 1705, false); + mt = OP_CreateNewMapThing(player, 1713, false); // Tilt mt->angle = (INT16)FixedInt(FixedDiv(angle*FRACUNIT, 360*(FRACUNIT/256))); @@ -1001,43 +1171,84 @@ void OP_NightsObjectplace(player_t *player) temp += 90; temp %= 360; - mt->options = (UINT16)((player->mo->z - fheight)>>FRACBITS); + mt->options = (mt->options & ~(UINT16)cv_opflags.value) | (UINT16)cv_ophoopflags.value; mt->angle = (INT16)(mt->angle+(INT16)((FixedInt(FixedDiv(temp*FRACUNIT, 360*(FRACUNIT/256))))<<8)); - P_SpawnHoopsAndRings(mt); + P_SpawnHoopsAndRings(mt, false); } // This places a bumper! if (cmd->buttons & BT_TOSSFLAG) { + UINT16 vertangle = (UINT16)(player->anotherflyangle % 360); + UINT16 newflags, newz; + player->pflags |= PF_ATTACKDOWN; if (!OP_HeightOkay(player, false)) return; mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_NIGHTSBUMPER].doomednum, false); + newz = min((mt->options >> ZSHIFT) - (mobjinfo[MT_NIGHTSBUMPER].height/4), 0); + // height offset: from P_TouchSpecialThing case MT_NIGHTSBUMPER + + // clockwise + if (vertangle >= 75 && vertangle < 105) // up + newflags = 3; + else if (vertangle >= 105 && vertangle < 135) // 60 upward tilt + newflags = 2; + else if (vertangle >= 135 && vertangle < 165) // 30 upward tilt + newflags = 1; + //else if (vertangle >= 165 && vertangle < 195) // forward, see else case + // newflags = 0; + else if (vertangle >= 195 && vertangle < 225) // 30 downward tilt + newflags = 11; + else if (vertangle >= 225 && vertangle < 255) // 60 downward tilt + newflags = 10; + else if (vertangle >= 255 && vertangle < 285) // down + newflags = 9; + else if (vertangle >= 285 && vertangle < 315) // 60 downward tilt backwards + newflags = 8; + else if (vertangle >= 315 && vertangle < 345) // 30 downward tilt backwards + newflags = 7; + else if (vertangle >= 345 || vertangle < 15) // backwards + newflags = 6; + else if (vertangle >= 15 && vertangle < 45) // 30 upward tilt backwards + newflags = 5; + else if (vertangle >= 45 && vertangle < 75) // 60 upward tilt backwards + newflags = 4; + else // forward + newflags = 0; + + mt->options = (newz << ZSHIFT) | newflags; + + // if NiGHTS is facing backwards, orient the Thing angle forwards so that the sprite angle + // displays correctly. Backwards movement via the Thing flags is unaffected. + if (vertangle < 90 || vertangle > 270) + mt->angle = (mt->angle + 180) % 360; + P_SpawnMapThing(mt); } - // This places a ring! - if (cmd->buttons & BT_CAMRIGHT) + // This places a sphere! + if (cmd->buttons & BT_WEAPONNEXT) { player->pflags |= PF_ATTACKDOWN; if (!OP_HeightOkay(player, false)) return; - mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_RING].doomednum, false); - P_SpawnHoopsAndRings(mt); + mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_BLUESPHERE].doomednum, false); + P_SpawnHoopsAndRings(mt, false); } - // This places a wing item! - if (cmd->buttons & BT_CAMLEFT) + // This places a ring! + if (cmd->buttons & BT_WEAPONPREV) { player->pflags |= PF_ATTACKDOWN; if (!OP_HeightOkay(player, false)) return; - mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_NIGHTSWING].doomednum, false); - P_SpawnHoopsAndRings(mt); + mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_RING].doomednum, false); + P_SpawnHoopsAndRings(mt, false); } // This places a custom object as defined in the console cv_mapthingnum. @@ -1054,7 +1265,7 @@ void OP_NightsObjectplace(player_t *player) if (!OP_HeightOkay(player, false)) return; - if (player->mo->target->flags & MF_AMBUSH) + if (player->mo->target->flags2 & MF2_AMBUSH) angle = (UINT16)player->anotherflyangle; else { @@ -1071,12 +1282,12 @@ void OP_NightsObjectplace(player_t *player) if (mt->type == 300 // Ring || mt->type == 308 || mt->type == 309 // Team Rings - || mt->type == 1706 // Nights Wing + || mt->type == 1706 // Sphere || (mt->type >= 600 && mt->type <= 609) // Placement patterns || mt->type == 1705 || mt->type == 1713 // NiGHTS Hoops || mt->type == 1800) // Mario Coin { - P_SpawnHoopsAndRings(mt); + P_SpawnHoopsAndRings(mt, false); } else P_SpawnMapThing(mt); @@ -1093,7 +1304,7 @@ void OP_ObjectplaceMovement(player_t *player) ticcmd_t *cmd = &player->cmd; if (!player->climbing && (netgame || !cv_analog.value || (player->pflags & PF_SPINNING))) - player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */); + player->drawangle = player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */); ticruned++; if (!(cmd->angleturn & TICCMD_RECEIVED)) @@ -1129,7 +1340,7 @@ void OP_ObjectplaceMovement(player_t *player) // make sure viewz follows player if in 1st person mode player->deltaviewheight = 0; - player->viewheight = FixedMul(cv_viewheight.value << FRACBITS, player->mo->scale); + player->viewheight = FixedMul(41*player->height/48, player->mo->scale); if (player->mo->eflags & MFE_VERTICALFLIP) player->viewz = player->mo->z + player->mo->height - player->viewheight; else @@ -1165,19 +1376,20 @@ void OP_ObjectplaceMovement(player_t *player) if (player->pflags & PF_ATTACKDOWN) { // Are ANY objectplace buttons pressed? If no, remove flag. - if (!(cmd->buttons & (BT_ATTACK|BT_TOSSFLAG|BT_CAMRIGHT|BT_CAMLEFT))) + if (!(cmd->buttons & (BT_ATTACK|BT_TOSSFLAG|BT_WEAPONNEXT|BT_WEAPONPREV))) player->pflags &= ~PF_ATTACKDOWN; // Do nothing. return; } - if (cmd->buttons & BT_CAMLEFT) + if (cmd->buttons & BT_WEAPONPREV) { OP_CycleThings(-1); player->pflags |= PF_ATTACKDOWN; } - else if (cmd->buttons & BT_CAMRIGHT) + + if (cmd->buttons & BT_WEAPONNEXT) { OP_CycleThings(1); player->pflags |= PF_ATTACKDOWN; @@ -1220,7 +1432,7 @@ void OP_ObjectplaceMovement(player_t *player) || mt->type == 1705 || mt->type == 1713 // NiGHTS Hoops || mt->type == 1800) // Mario Coin { - P_SpawnHoopsAndRings(mt); + P_SpawnHoopsAndRings(mt, false); } else P_SpawnMapThing(mt); @@ -1254,20 +1466,20 @@ void Command_ObjectPlace_f(void) { objectplacing = true; - if ((players[0].pflags & PF_NIGHTSMODE)) + if (players[0].powers[pw_carry] == CR_NIGHTSMODE) return; if (!COM_CheckParm("-silent")) { - HU_SetCEchoFlags(V_RETURN8|V_MONOSPACE); + HU_SetCEchoFlags(V_RETURN8|V_MONOSPACE|V_AUTOFADEOUT); HU_SetCEchoDuration(10); HU_DoCEcho(va(M_GetText( "\\\\\\\\\\\\\\\\\\\\\\\\\x82" " Objectplace Controls: \x80\\\\" - "Camera L/R: Cycle mapthings\\" - " Jump: Float up \\" - " Spin: Float down \\" - " Fire Ring: Place object \\"))); + "Weapon Next/Prev: Cycle mapthings\\" + " Jump: Float up \\" + " Spin: Float down \\" + " Fire Ring: Place object \\"))); } // Save all the player's data. @@ -1297,7 +1509,7 @@ void Command_ObjectPlace_f(void) // Like the classics, recover from death by entering objectplace if (players[0].mo->health <= 0) { - players[0].mo->health = players[0].health = 1; + players[0].mo->health = 1; players[0].deadtimer = 0; op_oldflags1 = mobjinfo[MT_PLAYER].flags; ++players[0].lives; @@ -1325,7 +1537,7 @@ void Command_ObjectPlace_f(void) // Don't touch the NiGHTS Objectplace stuff. // ... or if the mo mysteriously vanished. - if (!players[0].mo || (players[0].pflags & PF_NIGHTSMODE)) + if (!players[0].mo || (players[0].powers[pw_carry] == CR_NIGHTSMODE)) return; // If still in dummy state, get out of it. diff --git a/src/m_cheat.h b/src/m_cheat.h index bb901af74375312b5f9dc3a6e64a42ab2450570b..aa9b0bfebb9cea80853fd2a49b71c376bf5708a9 100644 --- a/src/m_cheat.h +++ b/src/m_cheat.h @@ -28,7 +28,7 @@ void cht_Init(void); void Command_ObjectPlace_f(void); void Command_Writethings_f(void); -extern consvar_t cv_opflags, cv_mapthingnum, cv_speed; +extern consvar_t cv_opflags, cv_ophoopflags, cv_mapthingnum, cv_speed; //extern consvar_t cv_snapto, cv_grid; extern boolean objectplacing; diff --git a/src/m_cond.c b/src/m_cond.c index 4c824b180ffa854df9a3fc00fcf04800b22ca333..e03542bf36c00beec606d0d340c10b690effb809 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -28,652 +28,18 @@ UINT32 unlocktriggers; // The meat of this system lies in condition sets conditionset_t conditionSets[MAXCONDITIONSETS]; -// Default Emblem locations -emblem_t emblemlocations[MAXEMBLEMS] = -{ - // GREEN FLOWER 1 - // --- - {0, 8156, 6936, 129, 1, 'A', SKINCOLOR_BLUE, 0, - "Go get your feet wet\n" - "to find this, the first emblem.\n" - "Yes, it's very deep.", 0}, - {0, 3184, 1812, 928, 1, 'B', SKINCOLOR_LAVENDER, 0, - "There are many rings,\n" - "but this one's not what you think.\n" - "There lies the emblem.", 0}, - {0, 9024, 6716, 769, 1, 'C', SKINCOLOR_RED, 0, - "Right next to a lake,\n" - "a ledge has been constructed.\n" - "Near there is the goal.", 0}, - {0, 2080, -384, 512, 1, 'D', SKINCOLOR_ORANGE, 0, - "Streams come to an end\n" - "where they can no longer fall.\n" - "But if you went up...", 0}, - {0, -336, 2064, 195, 1, 'E', SKINCOLOR_NEONGREEN, 0, - "This one's in plain sight.\n" - "Why haven't you claimed it?\n" - "Surely you saw it.", 0}, - - {ET_SCORE, 0,0,0, 1, 'S', SKINCOLOR_BROWN, 125000, "", 0}, - {ET_TIME, 0,0,0, 1, 'T', SKINCOLOR_GREY, 20*TICRATE, "", 0}, - {ET_RINGS, 0,0,0, 1, 'R', SKINCOLOR_GOLD, 200, "", 0}, - - - // GREEN FLOWER 2 - // --- - {0, 2624, -6816, 1332, 2, 'A', SKINCOLOR_BLUE, 0, - "Near the giant lake\n" - "lies a cave with a 1-Up.\n" - "An emblem's there, too!", 0}, - {0, -5728, -2848, 2848, 2, 'B', SKINCOLOR_LAVENDER, 0, - "Near the final lake,\n" - "a higher lake falls on in.\n" - "Three platforms await.", 0}, - {0, 3648, 6464, 2576, 2, 'C', SKINCOLOR_RED, 0, - "Near the level's start,\n" - "a bridge crosses a river.\n" - "What's that river's source?", 0}, - {0, -2032,-10048, 986, 2, 'D', SKINCOLOR_ORANGE, 0, - "Near the level's end,\n" - "another bridge spans a lake.\n" - "What could be under...?", 0}, - {0, -170, 491, 3821, 2, 'E', SKINCOLOR_NEONGREEN, 0, - "An ivied tunnel\n" - "has a corner that's sunlit.\n" - "Go reach for the sky!", 0}, - - {ET_SCORE, 0,0,0, 2, 'S', SKINCOLOR_BROWN, 150000, "", 0}, - {ET_TIME, 0,0,0, 2, 'T', SKINCOLOR_GREY, 40*TICRATE, "", 0}, - {ET_RINGS, 0,0,0, 2, 'R', SKINCOLOR_GOLD, 200, "", 0}, - - - // GREEN FLOWER 3 - // --- - {ET_TIME, 0,0,0, 3, 'T', SKINCOLOR_GREY, 30*TICRATE, "", 0}, - - - // TECHNO HILL 1 - // --- - {0, -5664, -5072, 2396, 4, 'A', SKINCOLOR_BLUE, 0, - "Three pipes reside near\n" - "where our heroes' paths split off.\n" - "You'll have to look up!", 0}, - {0, -784,-13968, 2888, 4, 'B', SKINCOLOR_LAVENDER, 0, - "Climbing yields great range.\n" - "Yet, on a path for climbers,\n" - "flying is the key.", 0}, - {0, 4160, -5824, 3776, 4, 'C', SKINCOLOR_RED, 0, - "That's sure lots of slime.\n" - "Say, do you ever wonder\n" - "what's dumping it all?", 0}, - {0, 6400, -8352, 1764, 4, 'D', SKINCOLOR_ORANGE, 0, - "Spinning through small gaps\n" - "can slip you into a cave.\n" - "In that cave's first stretch...", 0}, - {0, 2848, -9088, 488, 4, 'E', SKINCOLOR_NEONGREEN, 0, - "The slime lake is deep,\n" - "but reaching the floor takes height.\n" - "Scream \"Geronimo!\"...", 0}, - - {ET_SCORE, 0,0,0, 4, 'S', SKINCOLOR_BROWN, 75000, "", 0}, - {ET_TIME, 0,0,0, 4, 'T', SKINCOLOR_GREY, 75*TICRATE, "", 0}, - {ET_RINGS, 0,0,0, 4, 'R', SKINCOLOR_GOLD, 300, "", 0}, - - - // TECHNO HILL 2 - // --- - {0,-19138, -2692, 688, 5, 'A', SKINCOLOR_BLUE, 0, - "Near the first checkpoint,\n" - "a bridge crosses a slime pool.\n" - "(Sensing a pattern?)", 0}, - {0,-13120, 8062, 1248, 5, 'B', SKINCOLOR_LAVENDER, 0, - "Behind the windows,\n" - "near crushers, ever smashing\n" - "a conveyor belt.", 0}, - {0, 580, 4552, 1344, 5, 'C', SKINCOLOR_RED, 0, - "A pipe drops onto\n" - "a half-outdoors conveyor.\n" - "But is it empty?", 0}, - {0, 192, -8768, 24, 5, 'D', SKINCOLOR_ORANGE, 0, - "There is a hallway\n" - "that a button floods with slime.\n" - "Go through it again!", 0}, - {0, -2468,-12128, 1312, 5, 'E', SKINCOLOR_NEONGREEN, 0, - "Jumping on turtles\n" - "will send you springing skyward.\n" - "Now, do that six times...", 0}, - - {ET_SCORE, 0,0,0, 5, 'S', SKINCOLOR_BROWN, 100000, "", 0}, - {ET_TIME, 0,0,0, 5, 'T', SKINCOLOR_GREY, 120*TICRATE, "", 0}, - {ET_RINGS, 0,0,0, 5, 'R', SKINCOLOR_GOLD, 600, "", 0}, - - - // TECHNO HILL 3 - // --- - {ET_TIME, 0,0,0, 6, 'T', SKINCOLOR_GREY, 40*TICRATE, "", 0}, - - - // DEEP SEA 1 - // --- - {0,-16224, -2880, 3530, 7, 'A', SKINCOLOR_BLUE, 0, - "Climb up two maze walls.\n" - "Break the roof, then a corner.\n" - "There, glide, but stay dry.", 0}, - {0, -8224, 896, 1056, 7, 'B', SKINCOLOR_LAVENDER, 0, - "Follow the left path.\n" - "A square green button lurks deep.\n" - "Weight it down, somehow.", 0}, - {0, 4992, -5072, 4136, 7, 'C', SKINCOLOR_RED, 0, - "A certain path holds\n" - "many gargoyle puzzles.\n" - "Victors reach a \"V\".", 0}, - {0, 4576, 5168, 2660, 7, 'D', SKINCOLOR_ORANGE, 0, - "A caved-in hallway?\n" - "The floor falls; the path goes down.\n" - "But those rocks looked weak...", 0}, - {0, 12576, 16096, -992, 7, 'E', SKINCOLOR_NEONGREEN, 0, - "The end is quite dry.\n" - "Some rocks dam the water in.\n" - "Knuckles can fix that...", 0}, - - {ET_SCORE, 0,0,0, 7, 'S', SKINCOLOR_BROWN, 75000, "", 0}, - {ET_TIME, 0,0,0, 7, 'T', SKINCOLOR_GREY, 120*TICRATE, "", 0}, - {ET_RINGS, 0,0,0, 7, 'R', SKINCOLOR_GOLD, 400, "", 0}, - - - // DEEP SEA 2 - // --- - {0,-15040, 6976, 2016, 8, 'A', SKINCOLOR_BLUE, 0, - "A waterfall lands\n" - "near a starpost in a cave.\n" - "It's dark up there, but...", 0}, - {0, 4288, 2912, 544, 8, 'B', SKINCOLOR_LAVENDER, 0, - "So many blocks here!\n" - "Take five; bathe in the fountain.\n" - "Hmmm? A hidden path...?", 0}, - {0, -5696, 16992, 791, 8, 'C', SKINCOLOR_RED, 0, - "An ornate dragon\n" - "faces a secret passage.\n" - "Knuckles! Don't get crushed!", 0}, - {0,-13344, 18688, 1034, 8, 'D', SKINCOLOR_ORANGE, 0, - "In the current maze\n" - "hides a dark room of columns.\n" - "Find it, then look up.", 0}, - {0, 3104, 16192, 2408, 8, 'E', SKINCOLOR_NEONGREEN, 0, - "That same dragon's eye\n" - "hides another secret room.\n" - "There, solve its riddle.", 0}, - - {ET_SCORE, 0,0,0, 8, 'S', SKINCOLOR_BROWN, 50000, "", 0}, - {ET_TIME, 0,0,0, 8, 'T', SKINCOLOR_GREY, 150*TICRATE, "", 0}, - {ET_RINGS, 0,0,0, 8, 'R', SKINCOLOR_GOLD, 250, "", 0}, - - - // DEEP SEA 3 - // --- - {ET_TIME, 0,0,0, 9, 'T', SKINCOLOR_GREY, 90*TICRATE, "", 0}, - - - // CASTLE EGGMAN 1 - // --- - {0, -6176, -5184, -128, 10, 'A', SKINCOLOR_BLUE, 0, - "A drain feeds the lake.\n" - "Water rushes quickly through.\n" - "Go against the flow.", 0}, - {0, 3648,-15296, -992, 10, 'B', SKINCOLOR_LAVENDER, 0, - "The left starting path\n" - "goes atop a large wood deck.\n" - "Checked underneath yet?", 0}, - {0, 11712, 21312, 5472, 10, 'C', SKINCOLOR_RED, 0, - "At last, the castle!\n" - "Hold up! Don't just barge right in!\n" - "What's the facade hold...?", 0}, - {0, 20224, 13344, 3104, 10, 'D', SKINCOLOR_ORANGE, 0, - "The final approach!\n" - "A tower holds the emblem\n" - "near a ring arrow.", 0}, - {0, 9472, -5890, 710, 10, 'E', SKINCOLOR_NEONGREEN, 0, - "The right starting path\n" - "hides this near a canopy,\n" - "high, where two trees meet.", 0}, - - {ET_SCORE, 0,0,0, 10, 'S', SKINCOLOR_BROWN, 50000, "", 0}, - {ET_TIME, 0,0,0, 10, 'T', SKINCOLOR_GREY, 120*TICRATE, "", 0}, - {ET_RINGS, 0,0,0, 10, 'R', SKINCOLOR_GOLD, 200, "", 0}, - - - // CASTLE EGGMAN 2 - // --- - {0, 832,-15168, 7808, 11, 'A', SKINCOLOR_BLUE, 0, - "Find a trick bookcase\n" - "that hides a darkened hallway.\n" - "There, climb a tower.", 0}, - {0,-18460,-22180, 2416, 11, 'B', SKINCOLOR_LAVENDER, 0, - "Down in the dungeon,\n" - "a cracked wall hides secret paths.\n" - "Echidnas only!", 0}, - {0, -6144,-11792, 3232, 11, 'C', SKINCOLOR_RED, 0, - "A room you can flood!\n" - "A brown grate's near its exit.\n" - "Knuckles can break it...", 0}, - {0, 4608, -7024, 4256, 11, 'D', SKINCOLOR_ORANGE, 0, - "Some of these bookshelves\n" - "are not flush against the walls.\n" - "Wonder why that is?", 0}, - {0, 12708,-13536, 4768, 11, 'E', SKINCOLOR_NEONGREEN, 0, - "The ending's towers\n" - "are hiding a small alcove.\n" - "Check around outside.", 0}, - - {ET_SCORE, 0,0,0, 11, 'S', SKINCOLOR_BROWN, 400000, "", 0}, - {ET_TIME, 0,0,0, 11, 'T', SKINCOLOR_GREY, 210*TICRATE, "", 0}, - {ET_RINGS, 0,0,0, 11, 'R', SKINCOLOR_GOLD, 600, "", 0}, - - - // CASTLE EGGMAN 3 - // --- - {ET_TIME, 0,0,0, 12, 'T', SKINCOLOR_GREY, 120*TICRATE, "", 0}, - - - // ARID CANYON 1 - // --- - {0, 3488, 2208, 3072, 13, 'A', SKINCOLOR_BLUE, 0, - "A rather large gap\n" - "must be crossed by way of tram.\n" - "At its end, jump left.", 0}, - {0, -7552, 10464, 4094, 13, 'B', SKINCOLOR_LAVENDER, 0, - "Crushers that go up!\n" - "Mind your step; if they're triggered,\n" - "they'll block this emblem.", 0}, - {0,-12093, 14575, 5752, 13, 'C', SKINCOLOR_RED, 0, - "There's an oil lake\n" - "that you can sink deep into.\n" - "Drain it, and explore.", 0}, - {0, 512, -7136, 4640, 13, 'D', SKINCOLOR_ORANGE, 0, - "Not far from the start,\n" - "if you climb toward the sky,\n" - "the cliffs hide something.", 0}, - {0, 12504, 6848, 3424, 13, 'E', SKINCOLOR_NEONGREEN, 0, - "Right by the exit,\n" - "an emblem lies on a cliff.\n" - "Ride ropes to reach it.", 0}, - - {ET_SCORE, 0,0,0, 13, 'S', SKINCOLOR_BROWN, 50000, "", 0}, - {ET_TIME, 0,0,0, 13, 'T', SKINCOLOR_GREY, 120*TICRATE, "", 0}, - {ET_RINGS, 0,0,0, 13, 'R', SKINCOLOR_GOLD, 300, "", 0}, - - - // RED VOLCANO 1 - // --- - {0,-13184, 11424, 3080, 16, 'A', SKINCOLOR_BLUE, 0, - "Look around the room,\n" - "just before you clear the stage;\n" - "something's hidden there!", 0}, - {0, -2816, 3120, 3044, 16, 'B', SKINCOLOR_LAVENDER, 0, - "Ever look upwards\n" - "when you're traversing across\n" - "collapsing platforms?", 0}, - {0, 6720, 6784, 1452, 16, 'C', SKINCOLOR_RED, 0, - "Check out a corner\n" - "of a lake of magma near\n" - "spinning jets of flame.", 0}, - {0, -5504, 9824, 800, 16, 'D', SKINCOLOR_ORANGE, 0, - "Where once a bridge stood,\n" - "now magma falls from above.\n" - "The bridge dropped something...", 0}, - {0, 8287,-11043, 1328, 16, 'E', SKINCOLOR_NEONGREEN, 0, - "A lake of magma\n" - "ebbs and flows unendingly.\n" - "Wait for its nadir.", 0}, - - {ET_SCORE, 0,0,0, 16, 'S', SKINCOLOR_BROWN, 30000, "", 0}, - {ET_TIME, 0,0,0, 16, 'T', SKINCOLOR_GREY, 120*TICRATE, "", 0}, - {ET_RINGS, 0,0,0, 16, 'R', SKINCOLOR_GOLD, 100, "", 0}, - - - // EGG ROCK 1 - // --- - {0,-10976, -7328, 1584, 22, 'A', SKINCOLOR_BLUE, 0, - "Vanishing platforms,\n" - "then collapsing ones herald\n" - "a last-second jump.", 0}, - {0, -6592,-11200, 2208, 22, 'B', SKINCOLOR_LAVENDER, 0, - "What is this red stuff?\n" - "You can't breathe it in, but look!\n" - "It can't reach up there...", 0}, - {0, 6816, 832, 936, 22, 'C', SKINCOLOR_RED, 0, - "The team's paths diverge.\n" - "Should Tails run the crusher path?\n" - "No! Fly outside it!", 0}, - {0, 6942, -8902, 2080, 22, 'D', SKINCOLOR_ORANGE, 0, - "Don't jump too high here!\n" - "No conveyor will catch you;\n" - "you'd fall to your death.", 0}, - {0, -6432, -6192, 584, 22, 'E', SKINCOLOR_NEONGREEN, 0, - "Conveyors! Magma!\n" - "What an intense room this is!\n" - "But, what brought you here?", 0}, - - {ET_SCORE, 0,0,0, 22, 'S', SKINCOLOR_BROWN, 25000, "", 0}, - {ET_TIME, 0,0,0, 22, 'T', SKINCOLOR_GREY, 120*TICRATE, "", 0}, - {ET_RINGS, 0,0,0, 22, 'R', SKINCOLOR_GOLD, 150, "", 0}, - - - // EGG ROCK 2 - // --- - {0, -6672, 7792, 352, 23, 'A', SKINCOLOR_BLUE, 0, - "Walk on the ceiling;\n" - "resist the urge to flip back!\n" - "Find the cyan path...", 0}, - {0,-12256, 15136, -288, 23, 'B', SKINCOLOR_LAVENDER, 0, - "X marks the spot? Nope!\n" - "Try standing further away\n" - "when the timer flips.", 0}, - {0, 1536, 16224, 1144, 23, 'C', SKINCOLOR_RED, 0, - "There is more than one\n" - "elevator inside the\n" - "elevator shaft...", 0}, - {0,-15968, 14192, 3152, 23, 'D', SKINCOLOR_ORANGE, 0, - "Gears with missing teeth\n" - "can hide a clever secret!\n" - "Think Green Hill Zone boss.", 0}, - {0, 1920, 20608, 1064, 23, 'E', SKINCOLOR_NEONGREEN, 0, - "Just before you reach\n" - "the defective cargo bay,\n" - "fly under a bridge.", 0}, - - {ET_SCORE, 0,0,0, 23, 'S', SKINCOLOR_BROWN, 60000, "", 0}, - {ET_TIME, 0,0,0, 23, 'T', SKINCOLOR_GREY, 300*TICRATE, "", 0}, - {ET_RINGS, 0,0,0, 23, 'R', SKINCOLOR_GOLD, 250, "", 0}, - - - // EGG ROCK 3 - // --- -/* Just in case, I'll leave these here in the source. - {0, 848, -3584, 592, 24, 'A', SKINCOLOR_BLUE, 0, - "[PH] Hiding at the end of the first hallway.", 0}, - {0,-10368, -2816, 144, 24, 'B', SKINCOLOR_LAVENDER, 0, - "Directions are meaningless.", 0}, - {0, -8160, -5952, 560, 24, 'C', SKINCOLOR_RED, 0, - "[PH] In the ceiling of the conveyor belt + laser hallway.", 0}, - {0,-13728,-13728, 1552, 24, 'D', SKINCOLOR_ORANGE, 0, - "[PH] On top of the platform with rows of spikes in reverse gravity.", 0}, - {0,-14944, 768, 1232, 24, 'E', SKINCOLOR_NEONGREEN, 0, - "Follow the leader.", 0}, -*/ - - {ET_SCORE, 0,0,0, 24, 'S', SKINCOLOR_BROWN, 14000, "", 0}, - {ET_TIME, 0,0,0, 24, 'T', SKINCOLOR_GREY, 210*TICRATE, "", 0}, - {ET_RINGS, 0,0,0, 24, 'R', SKINCOLOR_GOLD, 100, "", 0}, - - - // EGG ROCK CORE - // --- - {ET_TIME, 0,0,0, 25, 'T', SKINCOLOR_GREY, 100*TICRATE, "", 0}, - - - // PIPE TOWERS - // --- - {0, 3182, 5040, 3008, 30, 'A', SKINCOLOR_BLUE, 0, - "A pipe in the roof\n" - "eternally drops water.\n" - "Something's stuck up there.", 0}, - {0, -2400, 5984, 2752, 30, 'B', SKINCOLOR_LAVENDER, 0, - "Pushing a red switch\n" - "raises the water level;\n" - "from there, can't miss it.", 0}, - {0, 6112, 7008, 4032, 30, 'C', SKINCOLOR_RED, 0, - "A high-up passage\n" - "hides near the second checkpoint.\n" - "Climb in; then, climb more.", 0}, - {0, 11424, -4832, 1376, 30, 'D', SKINCOLOR_ORANGE, 0, - "The underground room\n" - "with platforms that fall and rise\n" - "only LOOKS empty...", 0}, - {0 , 4960, -6112, 1312, 30, 'E', SKINCOLOR_NEONGREEN, 0, - "This one's straightforward.\n" - "What comes to mind when I say:\n" - "\"WELCOME TO WARP ZONE!\"?", 0}, - - {ET_SCORE, 0,0,0, 30, 'S', SKINCOLOR_BROWN, 75000, "", 0}, - {ET_TIME, 0,0,0, 30, 'T', SKINCOLOR_GREY, 100*TICRATE, "", 0}, - {ET_RINGS, 0,0,0, 30, 'R', SKINCOLOR_GOLD, 300, "", 0}, - - - // AERIAL GARDEN - // --- - {0, 10176,-14304, 1796, 40, 'A', SKINCOLOR_BLUE, 0, - "A central tower,\n" - "one with many waterfalls,\n" - "hides a secret room.", 0}, - {0, 480, 17696, 6496, 40, 'B', SKINCOLOR_LAVENDER, 0, - "Hidden off the path\n" - "lies a skyscraping tower.\n" - "A lake's at the top.", 0}, - {0, -8896, 13248, 3362, 40, 'C', SKINCOLOR_RED, 0, - "Find all four buttons\n" - "that sink when you stand on them.\n" - "They'll open a door...", 0}, - {0, -8896, -9952, 2480, 40, 'D', SKINCOLOR_ORANGE, 0, - "Much like the last one,\n" - "you need to find some switches.\n" - "Only two, this time.", 0}, - {0, 13184, 18880, 6672, 40, 'E', SKINCOLOR_NEONGREEN, 0, - "The inner sanctum!\n" - "Teleport to its switches;\n" - "then, check near the goal.", 0}, - - {ET_SCORE, 0,0,0, 40, 'S', SKINCOLOR_BROWN, 300000, "", 0}, - {ET_TIME, 0,0,0, 40, 'T', SKINCOLOR_GREY, 240*TICRATE, "", 0}, - {ET_RINGS, 0,0,0, 40, 'R', SKINCOLOR_GOLD, 1200, "", 0}, - - - // AZURE TEMPLE - // --- - {0, -2400, 7552, 1120, 41, 'A', SKINCOLOR_BLUE, 0, - "For those who can swim,\n" - "a long tunnel hides rewards.\n" - "Do mind the Buzzes!", 0}, - {0, -64, 14016, 2072, 41, 'B', SKINCOLOR_LAVENDER, 0, - "So many skylights!\n" - "A markedly large one hides\n" - "behind a starpost...", 0}, - {0, 2976, 13920, -32, 41, 'C', SKINCOLOR_RED, 0, - "When you reach gauntlets\n" - "of diagonal fire,\n" - "check out the corners.", 0}, - {0, 2176, 22592, 1376, 41, 'D', SKINCOLOR_ORANGE, 0, - "A room of currents;\n" - "most of them are marked by spikes.\n" - "This one? A corner.", 0}, - {0, -4128, 21344, 1120, 41, 'E', SKINCOLOR_NEONGREEN, 0, - "The only way to hit\n" - "all those gems at once is with\n" - "a radial blast.", 0}, - - {ET_SCORE, 0,0,0, 41, 'S', SKINCOLOR_BROWN, 425000, "", 0}, - {ET_TIME, 0,0,0, 41, 'T', SKINCOLOR_GREY, 240*TICRATE, "", 0}, - {ET_RINGS, 0,0,0, 41, 'R', SKINCOLOR_GOLD, 300, "", 0}, - - - // FLORAL FIELD - // --- - {0, 5394, -996, 160, 50, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, - {ET_NGRADE, 0,0,0, 50, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, - {ET_NTIME, 0,0,0, 50, 'T', SKINCOLOR_GREY, 40*TICRATE, "", 0}, - - - // TOXIC PLATEAU - // --- - {0, 780, -1664, 32, 51, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, - {ET_NGRADE, 0,0,0, 51, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, - {ET_NTIME, 0,0,0, 51, 'T', SKINCOLOR_GREY, 50*TICRATE, "", 0}, - - - // FLOODED COVE - // --- - {0, 1824, -1888, 2448, 52, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, - {ET_NGRADE, 0,0,0, 52, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, - {ET_NTIME, 0,0,0, 52, 'T', SKINCOLOR_GREY, 90*TICRATE, "", 0}, - - - // CAVERN FORTRESS - // --- - {0, -3089, -431, 1328, 53, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, - {ET_NGRADE, 0,0,0, 53, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, - {ET_NTIME, 0,0,0, 53, 'T', SKINCOLOR_GREY, 75*TICRATE, "", 0}, - - - // DUSTY WASTELAND - // --- - {0, 957, 924, 2956, 54, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, - {ET_NGRADE, 0,0,0, 54, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, - {ET_NTIME, 0,0,0, 54, 'T', SKINCOLOR_GREY, 65*TICRATE, "", 0}, - - - // MAGMA CAVES - // --- - {0, -2752, 3104, 1800, 55, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, - {ET_NGRADE, 0,0,0, 55, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, - {ET_NTIME, 0,0,0, 55, 'T', SKINCOLOR_GREY, 80*TICRATE, "", 0}, - - - // EGG SATELLITE - // --- - {0, 5334, -609, 3426, 56, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, - {ET_NGRADE, 0,0,0, 56, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, - {ET_NTIME, 0,0,0, 56, 'T', SKINCOLOR_GREY, 120*TICRATE, "", 0}, - - - // BLACK HOLE - // --- - {0, 2108, 3776, 32, 57, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, - {ET_NGRADE, 0,0,0, 57, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, - {ET_NTIME, 0,0,0, 57, 'T', SKINCOLOR_GREY, 150*TICRATE, "", 0}, - - - // SPRING HILL - // --- - {0, -1840, -1024, 1644, 58, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, - {ET_NGRADE, 0,0,0, 58, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, - {ET_NTIME, 0,0,0, 58, 'T', SKINCOLOR_GREY, 60*TICRATE, "", 0}, -}; - -// Default Extra Emblems -extraemblem_t extraemblems[MAXEXTRAEMBLEMS] = -{ - {"Game Complete", "Complete 1P Mode", 10, 'X', SKINCOLOR_BLUE, 0}, - {"All Emeralds", "Complete 1P Mode with all Emeralds", 11, 'V', SKINCOLOR_GREY, 0}, - {"Perfect Bonus", "Perfect Bonus on a non-secret stage", 30, 'P', SKINCOLOR_GOLD, 0}, - {"SRB1 Remake", "Complete SRB1 Remake", 21, 'O', SKINCOLOR_ROSEWOOD, 0}, - {"NiGHTS Mastery", "Show your mastery of NiGHTS!", 22, 'W', SKINCOLOR_TEAL, 0}, -}; - -// Default Unlockables -unlockable_t unlockables[MAXUNLOCKABLES] = -{ - // Name, Objective, Menu Height, ConditionSet, Unlock Type, Variable, NoCecho, NoChecklist - /* 01 */ {"Record Attack", "Complete Greenflower Zone, Act 1", 0, 1, SECRET_RECORDATTACK, 0, true, true, 0}, - /* 02 */ {"NiGHTS Mode", "Complete Floral Field", 0, 2, SECRET_NIGHTSMODE, 0, true, true, 0}, - - /* 03 */ {"Play Credits", "Complete 1P Mode", 30, 10, SECRET_CREDITS, 0, true, true, 0}, - /* 04 */ {"Sound Test", "Complete 1P Mode", 40, 10, SECRET_SOUNDTEST, 0, false, false, 0}, - - /* 05 */ {"EXTRA LEVELS", "", 60, 0, SECRET_HEADER, 0, true, true, 0}, - - /* 06 */ {"Aerial Garden Zone", "Complete 1P Mode w/ all emeralds", 70, 11, SECRET_WARP, 40, false, false, 0}, - /* 07 */ {"Azure Temple Zone", "Complete Aerial Garden Zone", 80, 20, SECRET_WARP, 41, false, false, 0}, - - /* 08 */ {"BONUS LEVELS", "", 100, 0, SECRET_HEADER, 0, true, true, 0}, - - /* 09 */ {"SRB1 Remake", "Collect 20 Emblems", 130, 40, SECRET_WARP, 101, false, false, 0}, - /* 10 */ {"Mario Koopa Blast", "Collect 60 Emblems", 110, 42, SECRET_WARP, 30, false, false, 0}, - /* 11 */ {"SRB1 Level Select", "Complete SRB1 Remake", 140, 21, SECRET_LEVELSELECT, 2, false, true, 0}, - - /* 12 */ {"Spring Hill Zone", "Collect 100 Emblems", 0, 44, SECRET_NONE, 0, false, false, 0}, - /* 13 */ {"Black Hole", "A Rank in all Special Stages", 0, 50, SECRET_NONE, 0, false, true, 0}, +// Emblem locations +emblem_t emblemlocations[MAXEMBLEMS]; - /* 14 */ {"Emblem Hints", "Collect 40 Emblems", 0, 41, SECRET_EMBLEMHINTS, 0, false, true, 0}, - /* 15 */ {"Emblem Radar", "Collect 80 Emblems", 0, 43, SECRET_ITEMFINDER, 0, false, true, 0}, +// Extra emblems +extraemblem_t extraemblems[MAXEXTRAEMBLEMS]; - /* 16 */ {"Pandora's Box", "Collect All Emblems", 0, 45, SECRET_PANDORA, 0, false, false, 0}, - /* 17 */ {"Level Select", "Collect All Emblems", 20, 45, SECRET_LEVELSELECT, 1, false, true, 0}, -}; +// Unlockables +unlockable_t unlockables[MAXUNLOCKABLES]; -// Default number of emblems and extra emblems -INT32 numemblems = 155; -INT32 numextraemblems = 5; - -// DEFAULT CONDITION SETS FOR SRB2 2.1: -void M_SetupDefaultConditionSets(void) -{ - memset(conditionSets, 0, sizeof(conditionSets)); - - // -- 1: Complete GFZ1 - M_AddRawCondition(1, 1, UC_MAPBEATEN, 1, 0, 0); - - // -- 2: Complete SS1 - M_AddRawCondition(2, 1, UC_MAPBEATEN, 50, 0, 0); - - // -- 10: Complete the game - M_AddRawCondition(10, 1, UC_GAMECLEAR, 1, 0, 0); - - // -- 11: Complete the game with all emeralds - M_AddRawCondition(11, 1, UC_ALLEMERALDS, 1, 0, 0); - - // -- 20: Beat AGZ - M_AddRawCondition(20, 1, UC_MAPBEATEN, 40, 0, 0); - - // -- 21: Beat SRB1 Remake - M_AddRawCondition(21, 1, UC_MAPBEATEN, 132, 0, 0); - - // -- 22: Beat Black Hole - M_AddRawCondition(22, 1, UC_MAPBEATEN, 57, 0, 0); - - // -- 30: Perfect Bonus - M_AddRawCondition(30, 1, UC_MAPPERFECT, 1, 0, 0); - M_AddRawCondition(30, 2, UC_MAPPERFECT, 2, 0, 0); - M_AddRawCondition(30, 3, UC_MAPPERFECT, 4, 0, 0); - M_AddRawCondition(30, 4, UC_MAPPERFECT, 5, 0, 0); - M_AddRawCondition(30, 5, UC_MAPPERFECT, 7, 0, 0); - M_AddRawCondition(30, 6, UC_MAPPERFECT, 8, 0, 0); - M_AddRawCondition(30, 7, UC_MAPPERFECT, 10, 0, 0); - M_AddRawCondition(30, 8, UC_MAPPERFECT, 11, 0, 0); - M_AddRawCondition(30, 9, UC_MAPPERFECT, 13, 0, 0); - M_AddRawCondition(30, 10, UC_MAPPERFECT, 16, 0, 0); - M_AddRawCondition(30, 11, UC_MAPPERFECT, 22, 0, 0); - M_AddRawCondition(30, 12, UC_MAPPERFECT, 23, 0, 0); - M_AddRawCondition(30, 13, UC_MAPPERFECT, 24, 0, 0); - M_AddRawCondition(30, 14, UC_MAPPERFECT, 40, 0, 0); - M_AddRawCondition(30, 15, UC_MAPPERFECT, 41, 0, 0); - - // -- 40: Find 20 emblems - M_AddRawCondition(40, 1, UC_TOTALEMBLEMS, 20, 0, 0); - - // -- 41: Find 40 emblems - M_AddRawCondition(41, 1, UC_TOTALEMBLEMS, 40, 0, 0); - - // -- 42: Find 60 emblems - M_AddRawCondition(42, 1, UC_TOTALEMBLEMS, 60, 0, 0); - - // -- 43: Find 80 emblems - M_AddRawCondition(43, 1, UC_TOTALEMBLEMS, 80, 0, 0); - - // -- 44: Find 100 emblems - M_AddRawCondition(44, 1, UC_TOTALEMBLEMS, 100, 0, 0); - - // -- 45: Find 160 (all) emblems - M_AddRawCondition(45, 1, UC_TOTALEMBLEMS, 160, 0, 0); - - // -- 50: A rank all NiGHTS special stages - M_AddRawCondition(50, 1, UC_NIGHTSGRADE, GRADE_A, 50, 0); - M_AddRawCondition(50, 1, UC_NIGHTSGRADE, GRADE_A, 51, 0); - M_AddRawCondition(50, 1, UC_NIGHTSGRADE, GRADE_A, 52, 0); - M_AddRawCondition(50, 1, UC_NIGHTSGRADE, GRADE_A, 53, 0); - M_AddRawCondition(50, 1, UC_NIGHTSGRADE, GRADE_A, 54, 0); - M_AddRawCondition(50, 1, UC_NIGHTSGRADE, GRADE_A, 55, 0); - M_AddRawCondition(50, 1, UC_NIGHTSGRADE, GRADE_A, 56, 0); -} +// Number of emblems and extra emblems +INT32 numemblems = 0; +INT32 numextraemblems = 0; void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2) { @@ -932,7 +298,7 @@ UINT8 M_CheckLevelEmblems(void) // Update Score, Time, Rings emblems for (i = 0; i < numemblems; ++i) { - if (emblemlocations[i].type <= ET_SKIN || emblemlocations[i].collected) + if (emblemlocations[i].type <= ET_SKIN || emblemlocations[i].type == ET_MAP || emblemlocations[i].collected) continue; levelnum = emblemlocations[i].level; @@ -966,6 +332,42 @@ UINT8 M_CheckLevelEmblems(void) return somethingUnlocked; } +UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separate print when awarding emblems and it's sorta different enough. +{ + INT32 i; + INT32 embtype; + INT16 levelnum; + UINT8 res; + UINT8 somethingUnlocked = 0; + UINT8 flags; + + for (i = 0; i < numemblems; ++i) + { + if (emblemlocations[i].type != ET_MAP || emblemlocations[i].collected) + continue; + + levelnum = emblemlocations[i].level; + embtype = emblemlocations[i].var; + flags = MV_BEATEN; + + if (embtype & ME_ALLEMERALDS) + flags |= MV_ALLEMERALDS; + + if (embtype & ME_ULTIMATE) + flags |= MV_ULTIMATE; + + if (embtype & ME_PERFECT) + flags |= MV_PERFECT; + + res = ((mapvisited[levelnum - 1] & flags) == flags); + + emblemlocations[i].collected = res; + if (res) + ++somethingUnlocked; + } + return somethingUnlocked; +} + // ------------------- // Quick unlock checks // ------------------- diff --git a/src/m_cond.h b/src/m_cond.h index 35170406479662dfc5d63b72e1c07593696e67fb..f82e49372ed0120da76cdd2bd8d8c0a7f2a128c5 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -66,20 +66,28 @@ typedef struct } conditionset_t; // Emblem information -#define ET_GLOBAL 0 // Global map emblem, var == color -#define ET_SKIN 1 // Skin specific emblem, var == skin -#define ET_SCORE 2 -#define ET_TIME 3 -#define ET_RINGS 4 -#define ET_NGRADE 5 -#define ET_NTIME 6 +#define ET_GLOBAL 0 // Emblem with a position in space +#define ET_SKIN 1 // Skin specific emblem with a position in space, var == skin +#define ET_MAP 2 // Beat the map +#define ET_SCORE 3 // Get the score +#define ET_TIME 4 // Get the time +#define ET_RINGS 5 // Get the rings +#define ET_NGRADE 6 // Get the grade +#define ET_NTIME 7 // Get the time (NiGHTS mode) + +// Global emblem flags +#define GE_NIGHTSPULL 1 // sun off the nights track - loop it +#define GE_NIGHTSITEM 2 // moon on the nights track - find it + +// Map emblem flags +#define ME_ALLEMERALDS 1 +#define ME_ULTIMATE 2 +#define ME_PERFECT 4 typedef struct { UINT8 type; ///< Emblem type - INT16 x; ///< X coordinate. - INT16 y; ///< Y coordinate. - INT16 z; ///< Z coordinate. + INT16 tag; ///< Tag of emblem mapthing INT16 level; ///< Level on which this emblem can be found. UINT8 sprite; ///< emblem sprite to use, 0 - 25 UINT8 color; ///< skincolor to use @@ -140,8 +148,7 @@ extern INT32 numextraemblems; extern UINT32 unlocktriggers; -// Condition Set Setup -void M_SetupDefaultConditionSets(void); +// Condition set setup void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2); // Clearing secrets @@ -153,6 +160,7 @@ void M_CheckUnlockConditions(void); UINT8 M_UpdateUnlockablesAndExtraEmblems(void); void M_SilentUpdateUnlockablesAndEmblems(void); UINT8 M_CheckLevelEmblems(void); +UINT8 M_CompletionEmblems(void); // Checking unlockable status UINT8 M_AnySecretUnlocked(void); diff --git a/src/m_fixed.h b/src/m_fixed.h index 8145a6917e7c6bf738d0e136bf7f4cb424f1c4c6..370633c1f6b0de4752f575bc3ab5929fd0a329cd 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -20,11 +20,6 @@ #include <stdlib.h> #endif -// Was this just for the #define USEASM? -//#ifdef _WIN32_WCE -//#include "sdl12/SRB2CE/cehelp.h" -//#endif - /*! \brief bits of the fraction */ diff --git a/src/m_menu.c b/src/m_menu.c index a833ace21a56d2286af516fef7b427644a6ba9f2..cebdd1bbd2376945f0bcb88d05ac4834fcbaaf17 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -56,6 +56,7 @@ #include "byteptr.h" #include "st_stuff.h" #include "i_sound.h" +#include "fastcmp.h" #include "i_joy.h" // for joystick menu controls @@ -71,13 +72,17 @@ int snprintf(char *str, size_t n, const char *fmt, ...); //int vsnprintf(char *str, size_t n, const char *fmt, va_list ap); #endif +#if defined (__GNUC__) && (__GNUC__ >= 4) +#define FIXUPO0 +#endif + #define SKULLXOFF -32 #define LINEHEIGHT 16 #define STRINGHEIGHT 8 #define FONTBHEIGHT 20 #define SMALLLINEHEIGHT 8 -#define SLIDER_RANGE 10 -#define SLIDER_WIDTH (8*SLIDER_RANGE+6) +#define SLIDER_RANGE 9 +#define SLIDER_WIDTH 78 #define SERVERS_PER_PAGE 11 typedef enum @@ -113,7 +118,7 @@ const char *quitmsg[NUM_QUITMESSAGES]; // Stuff for customizing the player select screen Tails 09-22-2003 description_t description[MAXSKINS]; - +INT16 char_on = -1, startchar = 1; static char *char_notes = NULL; static fixed_t char_scroll = 0; @@ -136,7 +141,9 @@ static char joystickInfo[8][29]; static UINT32 serverlistpage; #endif -static saveinfo_t savegameinfo[MAXSAVEGAMES]; // Extra info about the save games. +static UINT8 numsaves = 0; +static saveinfo_t* savegameinfo = NULL; // Extra info about the save games. +static patch_t *savselp[7]; INT16 startmap; // Mario, NiGHTS, or just a plain old normal game? @@ -157,6 +164,7 @@ static INT32 vidm_column_size; // PROTOTYPES // +static void M_GoBack(INT32 choice); static void M_StopMessage(INT32 choice); #ifndef NONET @@ -174,21 +182,43 @@ menu_t MessageDef; menu_t SPauseDef; +// Level Select +static levelselect_t levelselect = {0, NULL}; +static UINT8 levelselectselect[3]; +static patch_t *levselp[2][3]; +static INT32 lsoffs[2]; + +#define lsrow levelselectselect[0] +#define lscol levelselectselect[1] +#define lshli levelselectselect[2] + +#define lshseperation 101 +#define lsbasevseperation (62*vid.height)/(BASEVIDHEIGHT*vid.dupy) //62 #define lsheadingheight 16 +#define getheadingoffset(row) (levelselect.rows[row].header[0] ? lsheadingheight : 0) +#define lsvseperation(row) lsbasevseperation + getheadingoffset(row) +#define lswide(row) levelselect.rows[row].mapavailable[3] + +#define lsbasex 19 +#define lsbasey 59+lsheadingheight // Sky Room static void M_CustomLevelSelect(INT32 choice); static void M_CustomWarp(INT32 choice); FUNCNORETURN static ATTRNORETURN void M_UltimateCheat(INT32 choice); static void M_LoadGameLevelSelect(INT32 choice); +static void M_AllowSuper(INT32 choice); static void M_GetAllEmeralds(INT32 choice); static void M_DestroyRobots(INT32 choice); static void M_LevelSelectWarp(INT32 choice); static void M_Credits(INT32 choice); static void M_PandorasBox(INT32 choice); static void M_EmblemHints(INT32 choice); +static void M_HandleChecklist(INT32 choice); menu_t SR_MainDef, SR_UnlockChecklistDef; +static UINT8 check_on; + // Misc. Main Menu static void M_SinglePlayerMenu(INT32 choice); static void M_Options(INT32 choice); @@ -204,46 +234,48 @@ static void M_ConfirmTeamChange(INT32 choice); static void M_SecretsMenu(INT32 choice); static void M_SetupChoosePlayer(INT32 choice); static void M_QuitSRB2(INT32 choice); -menu_t SP_MainDef, MP_MainDef, OP_MainDef; +menu_t SP_MainDef, OP_MainDef; menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef; // Single Player +static void M_StartTutorial(INT32 choice); static void M_LoadGame(INT32 choice); +static void M_TimeAttackLevelSelect(INT32 choice); static void M_TimeAttack(INT32 choice); +static void M_NightsAttackLevelSelect(INT32 choice); static void M_NightsAttack(INT32 choice); static void M_Statistics(INT32 choice); static void M_ReplayTimeAttack(INT32 choice); static void M_ChooseTimeAttack(INT32 choice); static void M_ChooseNightsAttack(INT32 choice); -static void M_ModeAttackRetry(INT32 choice); static void M_ModeAttackEndGame(INT32 choice); static void M_SetGuestReplay(INT32 choice); +static void M_HandleChoosePlayerMenu(INT32 choice); static void M_ChoosePlayer(INT32 choice); -menu_t SP_GameStatsDef, SP_LevelStatsDef; +menu_t SP_LevelStatsDef; static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef; static menu_t SP_NightsAttackDef, SP_NightsReplayDef, SP_NightsGuestReplayDef, SP_NightsGhostDef; // Multiplayer -#ifndef NONET -static void M_StartServerMenu(INT32 choice); -static void M_ConnectMenu(INT32 choice); -static void M_ConnectIPMenu(INT32 choice); -#endif +static void M_SetupMultiPlayer(INT32 choice); +static void M_SetupMultiPlayer2(INT32 choice); static void M_StartSplitServerMenu(INT32 choice); static void M_StartServer(INT32 choice); +static void M_ServerOptions(INT32 choice); #ifndef NONET +static void M_StartServerMenu(INT32 choice); +static void M_ConnectMenu(INT32 choice); static void M_Refresh(INT32 choice); static void M_Connect(INT32 choice); static void M_ChooseRoom(INT32 choice); +menu_t MP_MainDef; #endif -static void M_SetupMultiPlayer(INT32 choice); -static void M_SetupMultiPlayer2(INT32 choice); // Options // Split into multiple parts due to size // Controls -menu_t OP_ControlsDef, OP_ControlListDef, OP_MoveControlsDef; -menu_t OP_MPControlsDef, OP_MiscControlsDef; +menu_t OP_ChangeControlsDef; +menu_t OP_MPControlsDef, OP_CameraControlsDef, OP_MiscControlsDef; menu_t OP_P1ControlsDef, OP_P2ControlsDef, OP_MouseOptionsDef; menu_t OP_Mouse2OptionsDef, OP_Joystick1Def, OP_Joystick2Def; static void M_VideoModeMenu(INT32 choice); @@ -255,7 +287,7 @@ static void M_AssignJoystick(INT32 choice); static void M_ChangeControl(INT32 choice); // Video & Sound -menu_t OP_VideoOptionsDef, OP_VideoModeDef; +menu_t OP_VideoOptionsDef, OP_VideoModeDef, OP_ColorOptionsDef; #ifdef HWRENDER menu_t OP_OpenGLOptionsDef, OP_OpenGLFogDef, OP_OpenGLColorDef; #endif @@ -263,8 +295,7 @@ menu_t OP_SoundOptionsDef; //Misc menu_t OP_DataOptionsDef, OP_ScreenshotOptionsDef, OP_EraseDataDef; -menu_t OP_GameOptionsDef, OP_ChatOptionsDef, OP_ServerOptionsDef; -menu_t OP_NetgameOptionsDef, OP_GametypeOptionsDef; +menu_t OP_ServerOptionsDef; menu_t OP_MonitorToggleDef; static void M_ScreenshotOptions(INT32 choice); static void M_EraseData(INT32 choice); @@ -275,8 +306,11 @@ static patch_t *addonsp[NUM_EXT+5]; #define numaddonsshown 4 +static void M_DrawLevelPlatterHeader(INT32 y, const char *header, boolean headerhighlight, boolean allowlowercase); + // Drawing functions static void M_DrawGenericMenu(void); +static void M_DrawGenericScrollMenu(void); static void M_DrawCenteredMenu(void); static void M_DrawAddons(void); static void M_DrawSkyRoom(void); @@ -284,42 +318,43 @@ static void M_DrawChecklist(void); static void M_DrawEmblemHints(void); static void M_DrawPauseMenu(void); static void M_DrawServerMenu(void); -static void M_DrawLevelSelectMenu(void); +static void M_DrawLevelPlatterMenu(void); static void M_DrawImageDef(void); static void M_DrawLoad(void); static void M_DrawLevelStats(void); -static void M_DrawGameStats(void); static void M_DrawTimeAttackMenu(void); static void M_DrawNightsAttackMenu(void); static void M_DrawSetupChoosePlayerMenu(void); static void M_DrawControl(void); +static void M_DrawMainVideoMenu(void); static void M_DrawVideoMode(void); +static void M_DrawColorMenu(void); +static void M_DrawScreenshotMenu(void); static void M_DrawMonitorToggles(void); #ifdef HWRENDER static void M_OGL_DrawFogMenu(void); static void M_OGL_DrawColorMenu(void); #endif #ifndef NONET +static void M_DrawScreenshotMenu(void); static void M_DrawConnectMenu(void); -static void M_DrawConnectIPMenu(void); +static void M_DrawMPMainMenu(void); static void M_DrawRoomMenu(void); #endif static void M_DrawJoystick(void); static void M_DrawSetupMultiPlayerMenu(void); // Handling functions -#ifndef NONET -static boolean M_CancelConnect(void); -#endif static boolean M_ExitPandorasBox(void); static boolean M_QuitMultiPlayerMenu(void); static void M_HandleAddons(INT32 choice); +static void M_HandleLevelPlatter(INT32 choice); static void M_HandleSoundTest(INT32 choice); static void M_HandleImageDef(INT32 choice); static void M_HandleLoadSave(INT32 choice); -static void M_HandleGameStats(INT32 choice); static void M_HandleLevelStats(INT32 choice); #ifndef NONET +static boolean M_CancelConnect(void); static void M_HandleConnectIP(INT32 choice); #endif static void M_HandleSetupMultiPlayer(INT32 choice); @@ -328,8 +363,9 @@ static void M_HandleFogColor(INT32 choice); #endif static void M_HandleVideoMode(INT32 choice); +static void M_ResetCvars(void); + // Consvar onchange functions -static void Nextmap_OnChange(void); static void Newgametype_OnChange(void); static void Dummymares_OnChange(void); @@ -363,6 +399,9 @@ static CV_PossibleValue_t serversort_cons_t[] = { }; consvar_t cv_serversort = {"serversort", "Ping", CV_HIDEN | CV_CALL, serversort_cons_t, M_SortServerList, 0, NULL, NULL, 0, 0, NULL}; +// first time memory +consvar_t cv_tutorialprompt = {"tutorialprompt", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + // autorecord demos for time attack static consvar_t cv_autorecord = {"autorecord", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -381,7 +420,7 @@ consvar_t cv_ghost_guest = {"ghost_guest", "Show", CV_SAVE, ghost2_cons_ static CV_PossibleValue_t dummyteam_cons_t[] = {{0, "Spectator"}, {1, "Red"}, {2, "Blue"}, {0, NULL}}; static CV_PossibleValue_t dummyscramble_cons_t[] = {{0, "Random"}, {1, "Points"}, {0, NULL}}; static CV_PossibleValue_t ringlimit_cons_t[] = {{0, "MIN"}, {9999, "MAX"}, {0, NULL}}; -static CV_PossibleValue_t liveslimit_cons_t[] = {{0, "MIN"}, {99, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t liveslimit_cons_t[] = {{-1, "MIN"}, {99, "MAX"}, {0, NULL}}; static CV_PossibleValue_t dummymares_cons_t[] = { {-1, "END"}, {0,"Overall"}, {1,"Mare 1"}, {2,"Mare 2"}, {3,"Mare 3"}, {4,"Mare 4"}, {5,"Mare 5"}, {6,"Mare 6"}, {7,"Mare 7"}, {8,"Mare 8"}, {0,NULL} }; @@ -407,12 +446,16 @@ static consvar_t cv_dummymares = {"dummymares", "Overall", CV_HIDEN|CV_CALL, dum // --------- static menuitem_t MainMenu[] = { - {IT_CALL |IT_STRING, NULL, "Secrets", M_SecretsMenu, 76}, - {IT_CALL |IT_STRING, NULL, "1 player", M_SinglePlayerMenu, 84}, - {IT_SUBMENU|IT_STRING, NULL, "multiplayer", &MP_MainDef, 92}, - {IT_CALL |IT_STRING, NULL, "options", M_Options, 100}, - {IT_CALL |IT_STRING, NULL, "Addons", M_Addons, 108}, - {IT_CALL |IT_STRING, NULL, "quit game", M_QuitSRB2, 116}, + {IT_STRING|IT_CALL, NULL, "Secrets", M_SecretsMenu, 76}, + {IT_STRING|IT_CALL, NULL, "1 player", M_SinglePlayerMenu, 84}, +#ifndef NONET + {IT_STRING|IT_SUBMENU, NULL, "multiplayer", &MP_MainDef, 92}, +#else + {IT_STRING|IT_CALL, NULL, "multiplayer", M_StartSplitServerMenu, 92}, +#endif + {IT_STRING|IT_CALL, NULL, "options", M_Options, 100}, + {IT_CALL |IT_STRING, NULL, "addons", M_Addons, 108}, + {IT_STRING|IT_CALL, NULL, "quit game", M_QuitSRB2, 116}, }; typedef enum @@ -452,22 +495,22 @@ typedef enum // --------------------- static menuitem_t MPauseMenu[] = { - {IT_STRING | IT_CALL, NULL, "Add-ons...", M_Addons, 8}, - {IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16}, - {IT_STRING | IT_CALL, NULL, "Switch Map..." , M_MapChange, 24}, + {IT_STRING | IT_CALL, NULL, "Add-ons...", M_Addons, 8}, + {IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16}, + {IT_STRING | IT_CALL, NULL, "Switch Gametype/Level...", M_MapChange, 24}, - {IT_CALL | IT_STRING, NULL, "Continue", M_SelectableClearMenus,40}, - {IT_CALL | IT_STRING, NULL, "Player 1 Setup", M_SetupMultiPlayer, 48}, // splitscreen - {IT_CALL | IT_STRING, NULL, "Player 2 Setup", M_SetupMultiPlayer2, 56}, // splitscreen + {IT_STRING | IT_CALL, NULL, "Continue", M_SelectableClearMenus,40}, + {IT_STRING | IT_CALL, NULL, "Player 1 Setup", M_SetupMultiPlayer, 48}, // splitscreen + {IT_STRING | IT_CALL, NULL, "Player 2 Setup", M_SetupMultiPlayer2, 56}, // splitscreen - {IT_STRING | IT_CALL, NULL, "Spectate", M_ConfirmSpectate, 48}, - {IT_STRING | IT_CALL, NULL, "Enter Game", M_ConfirmEnterGame, 48}, - {IT_STRING | IT_SUBMENU, NULL, "Switch Team...", &MISC_ChangeTeamDef, 48}, - {IT_CALL | IT_STRING, NULL, "Player Setup", M_SetupMultiPlayer, 56}, // alone - {IT_CALL | IT_STRING, NULL, "Options", M_Options, 64}, + {IT_STRING | IT_CALL, NULL, "Spectate", M_ConfirmSpectate, 48}, + {IT_STRING | IT_CALL, NULL, "Enter Game", M_ConfirmEnterGame, 48}, + {IT_STRING | IT_SUBMENU, NULL, "Switch Team...", &MISC_ChangeTeamDef, 48}, + {IT_STRING | IT_CALL, NULL, "Player Setup", M_SetupMultiPlayer, 56}, // alone + {IT_STRING | IT_CALL, NULL, "Options", M_Options, 64}, - {IT_CALL | IT_STRING, NULL, "Return to Title", M_EndGame, 80}, - {IT_CALL | IT_STRING, NULL, "Quit Game", M_QuitSRB2, 88}, + {IT_STRING | IT_CALL, NULL, "Return to Title", M_EndGame, 80}, + {IT_STRING | IT_CALL, NULL, "Quit Game", M_QuitSRB2, 88}, }; typedef enum @@ -516,6 +559,7 @@ typedef enum spause_continue, spause_retry, spause_options, + spause_title, spause_quit } spause_e; @@ -536,11 +580,21 @@ static menuitem_t MISC_ChangeTeamMenu[] = {IT_WHITESTRING|IT_CALL, NULL, "Confirm", M_ConfirmTeamChange, 90}, }; +static const gtdesc_t gametypedesc[] = +{ + {{ 54, 54}, "Play through the single-player campaign with your friends, teaming up to beat Dr Eggman's nefarious challenges!"}, + {{103, 103}, "Speed your way through the main acts, competing in several different categories to see who's the best."}, + {{190, 190}, "There's not much to it - zoom through the level faster than everyone else."}, + {{ 66, 66}, "Sling rings at your foes in a free-for-all battle. Use the special weapon rings to your advantage!"}, + {{153, 37}, "Sling rings at your foes in a color-coded battle. Use the special weapon rings to your advantage!"}, + {{123, 123}, "Whoever's IT has to hunt down everyone else. If you get caught, you have to turn on your former friends!"}, + {{150, 150}, "Try and find a good hiding place in these maps - we dare you."}, + {{ 37, 153}, "Steal the flag from the enemy's base and bring it back to your own, but watch out - they could just as easily steal yours!"}, +}; + static menuitem_t MISC_ChangeLevelMenu[] = { - {IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 30}, - {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 60}, - {IT_WHITESTRING|IT_CALL, NULL, "Change Level", M_ChangeLevel, 120}, + {IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleLevelPlatter, 0}, // dummy menuitem for the control func }; static menuitem_t MISC_HelpMenu[] = @@ -560,17 +614,20 @@ static menuitem_t MISC_HelpMenu[] = // Pause Menu Pandora's Box Options static menuitem_t SR_PandorasBox[] = { - {IT_STRING | IT_CVAR, NULL, "Rings", &cv_dummyrings, 20}, - {IT_STRING | IT_CVAR, NULL, "Lives", &cv_dummylives, 30}, - {IT_STRING | IT_CVAR, NULL, "Continues", &cv_dummycontinues, 40}, + {IT_STRING | IT_CALL, NULL, "Mid-game add-ons...", M_Addons, 0}, - {IT_STRING | IT_CVAR, NULL, "Gravity", &cv_gravity, 60}, - {IT_STRING | IT_CVAR, NULL, "Throw Rings", &cv_ringslinger, 70}, + {IT_STRING | IT_CVAR, NULL, "Rings", &cv_dummyrings, 20}, + {IT_STRING | IT_CVAR, NULL, "Lives", &cv_dummylives, 30}, + {IT_STRING | IT_CVAR, NULL, "Continues", &cv_dummycontinues, 40}, - {IT_STRING | IT_CALL, NULL, "Get All Emeralds", M_GetAllEmeralds, 90}, - {IT_STRING | IT_CALL, NULL, "Destroy All Robots", M_DestroyRobots, 100}, + {IT_STRING | IT_CVAR, NULL, "Gravity", &cv_gravity, 60}, + {IT_STRING | IT_CVAR, NULL, "Throw Rings", &cv_ringslinger, 70}, - {IT_STRING | IT_CALL, NULL, "Ultimate Cheat", M_UltimateCheat, 130}, + {IT_STRING | IT_CALL, NULL, "Enable Super form", M_AllowSuper, 90}, + {IT_STRING | IT_CALL, NULL, "Get All Emeralds", M_GetAllEmeralds, 100}, + {IT_STRING | IT_CALL, NULL, "Destroy All Robots", M_DestroyRobots, 110}, + + {IT_STRING | IT_CALL, NULL, "Ultimate Cheat", M_UltimateCheat, 130}, }; // Sky Room Custom Unlocks @@ -614,14 +671,12 @@ static menuitem_t SR_MainMenu[] = static menuitem_t SR_LevelSelectMenu[] = { - {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 60}, - - {IT_WHITESTRING|IT_CALL, NULL, "Start", M_LevelSelectWarp, 120}, + {IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleLevelPlatter, 0}, // dummy menuitem for the control func }; static menuitem_t SR_UnlockChecklistMenu[] = { - {IT_SUBMENU | IT_STRING, NULL, "NEXT", &SR_MainDef, 192}, + {IT_KEYHANDLER | IT_STRING, NULL, "", M_HandleChecklist, 0}, }; static menuitem_t SR_EmblemHintMenu[] = @@ -638,14 +693,16 @@ static menuitem_t SR_EmblemHintMenu[] = // Single Player Main static menuitem_t SP_MainMenu[] = { - {IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 92}, - {IT_SECRET, NULL, "Record Attack", M_TimeAttack, 100}, - {IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 108}, - {IT_CALL | IT_STRING | IT_CALL_NOTMODIFIED, NULL, "Statistics", M_Statistics, 116}, + {IT_CALL | IT_STRING, NULL, "Tutorial", M_StartTutorial, 84}, + {IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 92}, + {IT_SECRET, NULL, "Record Attack", M_TimeAttack, 100}, + {IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 108}, + {IT_CALL | IT_STRING | IT_CALL_NOTMODIFIED, NULL, "Statistics", M_Statistics, 116}, }; enum { + sptutorial, sploadgame, sprecordattack, spnightsmode, @@ -655,26 +712,30 @@ enum // Single Player Load Game static menuitem_t SP_LoadGameMenu[] = { - {IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleLoadSave, '\0'}, // dummy menuitem for the control func + {IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleLoadSave, 0}, // dummy menuitem for the control func }; // Single Player Level Select static menuitem_t SP_LevelSelectMenu[] = { - {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 60}, + {IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleLevelPlatter, 0}, // dummy menuitem for the control func +}; - {IT_WHITESTRING|IT_CALL, NULL, "Start", M_LevelSelectWarp, 120}, +// Single Player Time Attack Level Select +static menuitem_t SP_TimeAttackLevelSelectMenu[] = +{ + {IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleLevelPlatter, 0}, // dummy menuitem for the control func }; // Single Player Time Attack static menuitem_t SP_TimeAttackMenu[] = { - {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 52}, - {IT_STRING|IT_CVAR, NULL, "Player", &cv_chooseskin, 62}, + {IT_STRING|IT_CALL, NULL, "Level Select...", &M_TimeAttackLevelSelect, 52}, + {IT_STRING|IT_CVAR, NULL, "Character", &cv_chooseskin, 62}, {IT_DISABLED, NULL, "Guest Option...", &SP_GuestReplayDef, 100}, - {IT_DISABLED, NULL, "Replay...", &SP_ReplayDef, 110}, - {IT_DISABLED, NULL, "Ghosts...", &SP_GhostDef, 120}, + {IT_DISABLED, NULL, "Replay...", &SP_ReplayDef, 110}, + {IT_DISABLED, NULL, "Ghosts...", &SP_GhostDef, 120}, {IT_WHITESTRING|IT_CALL|IT_CALL_NOTMODIFIED, NULL, "Start", M_ChooseTimeAttack, 130}, }; @@ -758,16 +819,22 @@ static menuitem_t SP_NightsGhostMenu[] = {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_NightsAttackDef, 50} }; +// Single Player Nights Attack Level Select +static menuitem_t SP_NightsAttackLevelSelectMenu[] = +{ + {IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleLevelPlatter, 0}, // dummy menuitem for the control func +}; + // Single Player Nights Attack static menuitem_t SP_NightsAttackMenu[] = { - {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 44}, - {IT_STRING|IT_CVAR, NULL, "Show Records For", &cv_dummymares, 54}, + {IT_STRING|IT_CALL, NULL, "Level Select...", &M_NightsAttackLevelSelect, 52}, + {IT_STRING|IT_CVAR, NULL, "Show Records For", &cv_dummymares, 62}, - {IT_DISABLED, NULL, "Guest Option...", &SP_NightsGuestReplayDef, 108}, - {IT_DISABLED, NULL, "Replay...", &SP_NightsReplayDef, 118}, - {IT_DISABLED, NULL, "Ghosts...", &SP_NightsGhostDef, 128}, - {IT_WHITESTRING|IT_CALL|IT_CALL_NOTMODIFIED, NULL, "Start", M_ChooseNightsAttack, 138}, + {IT_DISABLED, NULL, "Guest Option...", &SP_NightsGuestReplayDef, 100}, + {IT_DISABLED, NULL, "Replay...", &SP_NightsReplayDef, 110}, + {IT_DISABLED, NULL, "Ghosts...", &SP_NightsGhostDef, 120}, + {IT_WHITESTRING|IT_CALL|IT_CALL_NOTMODIFIED, NULL, "Start", M_ChooseNightsAttack, 130}, }; enum @@ -782,63 +849,71 @@ enum }; // Statistics -static menuitem_t SP_GameStatsMenu[] = +static menuitem_t SP_LevelStatsMenu[] = { - {IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleGameStats, '\0'}, // dummy menuitem for the control func + {IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleLevelStats, 0}, // dummy menuitem for the control func }; -static menuitem_t SP_LevelStatsMenu[] = +// Player menu dummy +static menuitem_t SP_PlayerMenu[] = { - {IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleLevelStats, '\0'}, // dummy menuitem for the control func + {IT_NOTHING | IT_KEYHANDLER, NULL, "", M_HandleChoosePlayerMenu, 0}, // dummy menuitem for the control func }; -// A rare case. -// External files modify this menu, so we can't call it static. -// And I'm too lazy to go through and rename it everywhere. ARRGH! -menuitem_t PlayerMenu[MAXSKINS]; - // ----------------------------------- // Multiplayer and all of its submenus // ----------------------------------- // Prefix: MP_ -static menuitem_t MP_MainMenu[] = + +// Separated splitscreen and normal servers. +static menuitem_t MP_SplitServerMenu[] = { -#ifndef NONET - {IT_CALL | IT_STRING, NULL, "HOST GAME", M_StartServerMenu, 10}, - {IT_CALL | IT_STRING, NULL, "JOIN GAME (Search)", M_ConnectMenu, 30}, - {IT_CALL | IT_STRING, NULL, "JOIN GAME (Specify IP)", M_ConnectIPMenu, 40}, + {IT_STRING|IT_CALL, NULL, "Select Gametype/Level...", M_MapChange, 100}, +#ifdef NONET // In order to keep player setup accessible. + {IT_STRING|IT_CALL, NULL, "Player 1 setup...", M_SetupMultiPlayer, 110}, + {IT_STRING|IT_CALL, NULL, "Player 2 setup...", M_SetupMultiPlayer2, 120}, #endif - {IT_CALL | IT_STRING, NULL, "TWO PLAYER GAME", M_StartSplitServerMenu, 60}, - - {IT_CALL | IT_STRING, NULL, "SETUP PLAYER 1", M_SetupMultiPlayer, 80}, - {IT_CALL | IT_STRING, NULL, "SETUP PLAYER 2", M_SetupMultiPlayer2, 90}, + {IT_STRING|IT_CALL, NULL, "More Options...", M_ServerOptions, 130}, + {IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 140}, }; -static menuitem_t MP_ServerMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 10}, #ifndef NONET - {IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 20}, - {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 30}, -#endif - {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 80}, +static menuitem_t MP_MainMenu[] = +{ + {IT_HEADER, NULL, "Host a game", NULL, 0}, + {IT_STRING|IT_CALL, NULL, "Internet/LAN...", M_StartServerMenu, 12}, + {IT_STRING|IT_CALL, NULL, "Splitscreen...", M_StartSplitServerMenu, 22}, + {IT_HEADER, NULL, "Join a game", NULL, 40}, + {IT_STRING|IT_CALL, NULL, "Server browser...", M_ConnectMenu, 52}, + {IT_STRING|IT_KEYHANDLER, NULL, "Specify IPv4 address:", M_HandleConnectIP, 62}, + {IT_HEADER, NULL, "Player setup", NULL, 94}, + {IT_STRING|IT_CALL, NULL, "Player 1...", M_SetupMultiPlayer, 106}, + {IT_STRING|IT_CALL, NULL, "Player 2... ", M_SetupMultiPlayer2, 116}, +}; - {IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 130}, +static menuitem_t MP_ServerMenu[] = +{ + {IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 10}, + {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 20}, + {IT_STRING|IT_CVAR, NULL, "Max Players", &cv_maxplayers, 46}, + {IT_STRING|IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 56}, + {IT_STRING|IT_CALL, NULL, "Select Gametype/Level...", M_MapChange, 100}, + {IT_STRING|IT_CALL, NULL, "More Options...", M_ServerOptions, 130}, + {IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 140}, }; enum { - mp_server_gametype = 0, -#ifndef NONET - mp_server_room, + mp_server_room = 0, mp_server_name, -#endif - mp_server_level, + mp_server_maxpl, + mp_server_waddl, + mp_server_levelgt, + mp_server_options, mp_server_start }; -#ifndef NONET static menuitem_t MP_ConnectMenu[] = { {IT_STRING | IT_CALL, NULL, "Room...", M_RoomMenu, 4}, @@ -890,25 +965,14 @@ static menuitem_t MP_RoomMenu[] = {IT_DISABLED, NULL, "", M_ChooseRoom, 162}, }; -static menuitem_t MP_ConnectIPMenu[] = -{ - {IT_KEYHANDLER | IT_STRING, NULL, " IP Address:", M_HandleConnectIP, 0}, -}; #endif -// Separated splitscreen and normal servers. -static menuitem_t MP_SplitServerMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 10}, - {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 80}, - {IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 130}, -}; - static menuitem_t MP_PlayerSetupMenu[] = { - {IT_KEYHANDLER | IT_STRING, NULL, "Your name", M_HandleSetupMultiPlayer, 0}, - {IT_KEYHANDLER | IT_STRING, NULL, "Your color", M_HandleSetupMultiPlayer, 16}, - {IT_KEYHANDLER | IT_STRING, NULL, "Your player", M_HandleSetupMultiPlayer, 96}, // Tails 01-18-2001 + {IT_KEYHANDLER, NULL, "", M_HandleSetupMultiPlayer, 0}, // name + {IT_KEYHANDLER, NULL, "", M_HandleSetupMultiPlayer, 0}, // skin + {IT_KEYHANDLER, NULL, "", M_HandleSetupMultiPlayer, 0}, // colour + {IT_KEYHANDLER, NULL, "", M_HandleSetupMultiPlayer, 0}, // default }; // ------------------------------------ @@ -917,123 +981,114 @@ static menuitem_t MP_PlayerSetupMenu[] = // Prefix: OP_ static menuitem_t OP_MainMenu[] = { - {IT_SUBMENU | IT_STRING, NULL, "Setup Controls...", &OP_ControlsDef, 10}, + {IT_SUBMENU | IT_STRING, NULL, "Player 1 Controls...", &OP_P1ControlsDef, 10}, + {IT_SUBMENU | IT_STRING, NULL, "Player 2 Controls...", &OP_P2ControlsDef, 20}, + {IT_CVAR | IT_STRING, NULL, "Controls per key", &cv_controlperkey, 30}, - {IT_SUBMENU | IT_STRING, NULL, "Video Options...", &OP_VideoOptionsDef, 30}, - {IT_SUBMENU | IT_STRING, NULL, "Sound Options...", &OP_SoundOptionsDef, 40}, - {IT_SUBMENU | IT_STRING, NULL, "Data Options...", &OP_DataOptionsDef, 50}, - - {IT_SUBMENU | IT_STRING, NULL, "Game Options...", &OP_GameOptionsDef, 70}, - {IT_SUBMENU | IT_STRING, NULL, "Server Options...", &OP_ServerOptionsDef, 80}, - {IT_STRING | IT_CALL, NULL, "Add-on Options...", M_AddonsOptions, 90}, -}; + {IT_SUBMENU | IT_STRING, NULL, "Video Options...", &OP_VideoOptionsDef, 50}, + {IT_SUBMENU | IT_STRING, NULL, "Sound Options...", &OP_SoundOptionsDef, 60}, -static menuitem_t OP_ControlsMenu[] = -{ - {IT_SUBMENU | IT_STRING, NULL, "Player 1 Controls...", &OP_P1ControlsDef, 10}, - {IT_SUBMENU | IT_STRING, NULL, "Player 2 Controls...", &OP_P2ControlsDef, 20}, + {IT_CALL | IT_STRING, NULL, "Server Options...", M_ServerOptions, 80}, - {IT_STRING | IT_CVAR, NULL, "Controls per key", &cv_controlperkey, 40}, + {IT_SUBMENU | IT_STRING, NULL, "Data Options...", &OP_DataOptionsDef, 100}, }; static menuitem_t OP_P1ControlsMenu[] = { {IT_CALL | IT_STRING, NULL, "Control Configuration...", M_Setup1PControlsMenu, 10}, {IT_SUBMENU | IT_STRING, NULL, "Mouse Options...", &OP_MouseOptionsDef, 20}, - {IT_SUBMENU | IT_STRING, NULL, "Joystick Options...", &OP_Joystick1Def , 30}, + {IT_SUBMENU | IT_STRING, NULL, "Gamepad Options...", &OP_Joystick1Def , 30}, - {IT_STRING | IT_CVAR, NULL, "Camera" , &cv_chasecam , 50}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair , 60}, + {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam , 50}, + {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 60}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 70}, - {IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog, 80}, + //{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog, 90}, + {IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar, 90}, + {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake, 100}, }; static menuitem_t OP_P2ControlsMenu[] = { {IT_CALL | IT_STRING, NULL, "Control Configuration...", M_Setup2PControlsMenu, 10}, {IT_SUBMENU | IT_STRING, NULL, "Second Mouse Options...", &OP_Mouse2OptionsDef, 20}, - {IT_SUBMENU | IT_STRING, NULL, "Second Joystick Options...", &OP_Joystick2Def , 30}, - - {IT_STRING | IT_CVAR, NULL, "Camera" , &cv_chasecam2 , 50}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 60}, + {IT_SUBMENU | IT_STRING, NULL, "Second Gamepad Options...", &OP_Joystick2Def , 30}, - {IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog2, 80}, -}; + {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam2 , 50}, + {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 60}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 70}, -static menuitem_t OP_ControlListMenu[] = -{ - {IT_SUBMENU | IT_STRING, NULL, "Movement Controls...", &OP_MoveControlsDef, 10}, - {IT_SUBMENU | IT_STRING, NULL, "Multiplayer Controls...", &OP_MPControlsDef, 20}, - {IT_SUBMENU | IT_STRING, NULL, "Miscellaneous Controls...", &OP_MiscControlsDef, 30}, + //{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog2, 90}, + {IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar2, 90}, + {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake2, 100}, }; -static menuitem_t OP_MoveControlsMenu[] = +static menuitem_t OP_ChangeControlsMenu[] = { - {IT_HEADER, NULL, " Movement", NULL, 0}, + {IT_HEADER, NULL, "Movement", NULL, 0}, + {IT_SPACE, NULL, NULL, NULL, 0}, // padding {IT_CALL | IT_STRING2, NULL, "Move Forward", M_ChangeControl, gc_forward }, {IT_CALL | IT_STRING2, NULL, "Move Backward", M_ChangeControl, gc_backward }, {IT_CALL | IT_STRING2, NULL, "Move Left", M_ChangeControl, gc_strafeleft }, {IT_CALL | IT_STRING2, NULL, "Move Right", M_ChangeControl, gc_straferight }, {IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, gc_jump }, {IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, gc_use }, - {IT_HEADER, NULL, " Camera", NULL, 0}, + {IT_HEADER, NULL, "Camera", NULL, 0}, + {IT_SPACE, NULL, NULL, NULL, 0}, // padding {IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, gc_lookup }, {IT_CALL | IT_STRING2, NULL, "Look Down", M_ChangeControl, gc_lookdown }, - {IT_CALL | IT_STRING2, NULL, "Turn Left", M_ChangeControl, gc_turnleft }, - {IT_CALL | IT_STRING2, NULL, "Turn Right", M_ChangeControl, gc_turnright }, + {IT_CALL | IT_STRING2, NULL, "Look Left", M_ChangeControl, gc_turnleft }, + {IT_CALL | IT_STRING2, NULL, "Look Right", M_ChangeControl, gc_turnright }, {IT_CALL | IT_STRING2, NULL, "Center View", M_ChangeControl, gc_centerview }, {IT_CALL | IT_STRING2, NULL, "Toggle Mouselook", M_ChangeControl, gc_mouseaiming }, {IT_CALL | IT_STRING2, NULL, "Toggle Third-Person", M_ChangeControl, gc_camtoggle}, {IT_CALL | IT_STRING2, NULL, "Reset Camera", M_ChangeControl, gc_camreset }, - {IT_HEADER, NULL, " Advanced", NULL, 0}, - {IT_CALL | IT_STRING2, NULL, "Rotate Camera L", M_ChangeControl, gc_camleft }, - {IT_CALL | IT_STRING2, NULL, "Rotate Camera R", M_ChangeControl, gc_camright }, -}; - -static menuitem_t OP_MPControlsMenu[] = -{ - {IT_CALL | IT_STRING2, NULL, "Talk key", M_ChangeControl, gc_talkkey }, - {IT_CALL | IT_STRING2, NULL, "Team-Talk key", M_ChangeControl, gc_teamkey }, - {IT_CALL | IT_STRING2, NULL, "Rankings/Scores", M_ChangeControl, gc_scores }, - {IT_CALL | IT_STRING2, NULL, "Toss Flag", M_ChangeControl, gc_tossflag }, - {IT_CALL | IT_STRING2, NULL, "Next Weapon", M_ChangeControl, gc_weaponnext }, - {IT_CALL | IT_STRING2, NULL, "Prev Weapon", M_ChangeControl, gc_weaponprev }, - {IT_CALL | IT_STRING2, NULL, "Weapon Slot 1", M_ChangeControl, gc_wepslot1 }, - {IT_CALL | IT_STRING2, NULL, "Weapon Slot 2", M_ChangeControl, gc_wepslot2 }, - {IT_CALL | IT_STRING2, NULL, "Weapon Slot 3", M_ChangeControl, gc_wepslot3 }, - {IT_CALL | IT_STRING2, NULL, "Weapon Slot 4", M_ChangeControl, gc_wepslot4 }, - {IT_CALL | IT_STRING2, NULL, "Weapon Slot 5", M_ChangeControl, gc_wepslot5 }, - {IT_CALL | IT_STRING2, NULL, "Weapon Slot 6", M_ChangeControl, gc_wepslot6 }, - {IT_CALL | IT_STRING2, NULL, "Weapon Slot 7", M_ChangeControl, gc_wepslot7 }, - {IT_CALL | IT_STRING2, NULL, "Ring Toss", M_ChangeControl, gc_fire }, - {IT_CALL | IT_STRING2, NULL, "Ring Toss Normal", M_ChangeControl, gc_firenormal }, -}; - -static menuitem_t OP_MiscControlsMenu[] = -{ - {IT_CALL | IT_STRING2, NULL, "Custom Action 1", M_ChangeControl, gc_custom1 }, - {IT_CALL | IT_STRING2, NULL, "Custom Action 2", M_ChangeControl, gc_custom2 }, - {IT_CALL | IT_STRING2, NULL, "Custom Action 3", M_ChangeControl, gc_custom3 }, - - {IT_CALL | IT_STRING2, NULL, "Pause", M_ChangeControl, gc_pause }, + {IT_HEADER, NULL, "Meta", NULL, 0}, + {IT_SPACE, NULL, NULL, NULL, 0}, // padding + {IT_CALL | IT_STRING2, NULL, "Game Status", + M_ChangeControl, gc_scores }, + {IT_CALL | IT_STRING2, NULL, "Pause / Run Retry", M_ChangeControl, gc_pause }, {IT_CALL | IT_STRING2, NULL, "Screenshot", M_ChangeControl, gc_screenshot }, {IT_CALL | IT_STRING2, NULL, "Toggle GIF Recording", M_ChangeControl, gc_recordgif }, {IT_CALL | IT_STRING2, NULL, "Open/Close Menu (ESC)", M_ChangeControl, gc_systemmenu }, {IT_CALL | IT_STRING2, NULL, "Change Viewpoint", M_ChangeControl, gc_viewpoint }, - {IT_CALL | IT_STRING2, NULL, "Console", M_ChangeControl, gc_console }, + {IT_CALL | IT_STRING2, NULL, "Console", M_ChangeControl, gc_console }, + {IT_HEADER, NULL, "Multiplayer", NULL, 0}, + {IT_SPACE, NULL, NULL, NULL, 0}, // padding + {IT_CALL | IT_STRING2, NULL, "Talk", M_ChangeControl, gc_talkkey }, + {IT_CALL | IT_STRING2, NULL, "Talk (Team only)", M_ChangeControl, gc_teamkey }, + {IT_HEADER, NULL, "Ringslinger (Match, CTF, Tag, H&S)", NULL, 0}, + {IT_SPACE, NULL, NULL, NULL, 0}, // padding + {IT_CALL | IT_STRING2, NULL, "Fire", M_ChangeControl, gc_fire }, + {IT_CALL | IT_STRING2, NULL, "Fire Normal", M_ChangeControl, gc_firenormal }, + {IT_CALL | IT_STRING2, NULL, "Toss Flag", M_ChangeControl, gc_tossflag }, + {IT_CALL | IT_STRING2, NULL, "Next Weapon", M_ChangeControl, gc_weaponnext }, + {IT_CALL | IT_STRING2, NULL, "Prev Weapon", M_ChangeControl, gc_weaponprev }, + {IT_CALL | IT_STRING2, NULL, "Normal / Infinity", M_ChangeControl, gc_wepslot1 }, + {IT_CALL | IT_STRING2, NULL, "Automatic", M_ChangeControl, gc_wepslot2 }, + {IT_CALL | IT_STRING2, NULL, "Bounce", M_ChangeControl, gc_wepslot3 }, + {IT_CALL | IT_STRING2, NULL, "Scatter", M_ChangeControl, gc_wepslot4 }, + {IT_CALL | IT_STRING2, NULL, "Grenade", M_ChangeControl, gc_wepslot5 }, + {IT_CALL | IT_STRING2, NULL, "Explosion", M_ChangeControl, gc_wepslot6 }, + {IT_CALL | IT_STRING2, NULL, "Rail", M_ChangeControl, gc_wepslot7 }, + {IT_HEADER, NULL, "Add-ons", NULL, 0}, + {IT_SPACE, NULL, NULL, NULL, 0}, // padding + {IT_CALL | IT_STRING2, NULL, "Custom Action 1", M_ChangeControl, gc_custom1 }, + {IT_CALL | IT_STRING2, NULL, "Custom Action 2", M_ChangeControl, gc_custom2 }, + {IT_CALL | IT_STRING2, NULL, "Custom Action 3", M_ChangeControl, gc_custom3 }, }; static menuitem_t OP_Joystick1Menu[] = { - {IT_STRING | IT_CALL, NULL, "Select Joystick...", M_Setup1PJoystickMenu, 10}, - {IT_STRING | IT_CVAR, NULL, "Axis For Turning" , &cv_turnaxis , 30}, - {IT_STRING | IT_CVAR, NULL, "Axis For Moving" , &cv_moveaxis , 40}, - {IT_STRING | IT_CVAR, NULL, "Axis For Strafe" , &cv_sideaxis , 50}, - {IT_STRING | IT_CVAR, NULL, "Axis For Looking" , &cv_lookaxis , 60}, - {IT_STRING | IT_CVAR, NULL, "Axis For Jumping" , &cv_jumpaxis , 70}, - {IT_STRING | IT_CVAR, NULL, "Axis For Spinning" , &cv_spinaxis , 80}, - {IT_STRING | IT_CVAR, NULL, "Axis For Firing" , &cv_fireaxis , 90}, - {IT_STRING | IT_CVAR, NULL, "Axis For NFiring" , &cv_firenaxis , 100}, + {IT_STRING | IT_CALL, NULL, "Select Gamepad...", M_Setup1PJoystickMenu, 10}, + {IT_STRING | IT_CVAR, NULL, "Move \x17 Axis" , &cv_moveaxis , 30}, + {IT_STRING | IT_CVAR, NULL, "Move \x18 Axis" , &cv_sideaxis , 40}, + {IT_STRING | IT_CVAR, NULL, "Camera \x17 Axis" , &cv_lookaxis , 50}, + {IT_STRING | IT_CVAR, NULL, "Camera \x18 Axis" , &cv_turnaxis , 60}, + {IT_STRING | IT_CVAR, NULL, "Jump Axis" , &cv_jumpaxis , 70}, + {IT_STRING | IT_CVAR, NULL, "Spin Axis" , &cv_spinaxis , 80}, + {IT_STRING | IT_CVAR, NULL, "Fire Axis" , &cv_fireaxis , 90}, + {IT_STRING | IT_CVAR, NULL, "Fire Normal Axis" , &cv_firenaxis ,100}, {IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook, 120}, {IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook, 130}, @@ -1041,15 +1096,15 @@ static menuitem_t OP_Joystick1Menu[] = static menuitem_t OP_Joystick2Menu[] = { - {IT_STRING | IT_CALL, NULL, "Select Joystick...", M_Setup2PJoystickMenu, 10}, - {IT_STRING | IT_CVAR, NULL, "Axis For Turning" , &cv_turnaxis2 , 30}, - {IT_STRING | IT_CVAR, NULL, "Axis For Moving" , &cv_moveaxis2 , 40}, - {IT_STRING | IT_CVAR, NULL, "Axis For Strafe" , &cv_sideaxis2 , 50}, - {IT_STRING | IT_CVAR, NULL, "Axis For Looking" , &cv_lookaxis2 , 60}, - {IT_STRING | IT_CVAR, NULL, "Axis For Jumping" , &cv_jumpaxis2 , 70}, - {IT_STRING | IT_CVAR, NULL, "Axis For Spinning" , &cv_spinaxis2 , 80}, - {IT_STRING | IT_CVAR, NULL, "Axis For Firing" , &cv_fireaxis2 , 90}, - {IT_STRING | IT_CVAR, NULL, "Axis For NFiring" , &cv_firenaxis2 , 100}, + {IT_STRING | IT_CALL, NULL, "Select Gamepad...", M_Setup2PJoystickMenu, 10}, + {IT_STRING | IT_CVAR, NULL, "Move \x17 Axis" , &cv_moveaxis2 , 30}, + {IT_STRING | IT_CVAR, NULL, "Move \x18 Axis" , &cv_sideaxis2 , 40}, + {IT_STRING | IT_CVAR, NULL, "Camera \x17 Axis" , &cv_lookaxis2 , 50}, + {IT_STRING | IT_CVAR, NULL, "Camera \x18 Axis" , &cv_turnaxis2 , 60}, + {IT_STRING | IT_CVAR, NULL, "Jump Axis" , &cv_jumpaxis2 , 70}, + {IT_STRING | IT_CVAR, NULL, "Spin Axis" , &cv_spinaxis2 , 80}, + {IT_STRING | IT_CVAR, NULL, "Fire Axis" , &cv_fireaxis2 , 90}, + {IT_STRING | IT_CVAR, NULL, "Fire Normal Axis" , &cv_firenaxis2 ,100}, {IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook2,120}, {IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook2, 130}, @@ -1062,8 +1117,6 @@ static menuitem_t OP_JoystickSetMenu[] = {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, '2'}, {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, '3'}, {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, '4'}, - {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, '5'}, - {IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, '6'}, }; static menuitem_t OP_MouseOptionsMenu[] = @@ -1074,11 +1127,11 @@ static menuitem_t OP_MouseOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "First-Person MouseLook", &cv_alwaysfreelook, 30}, {IT_STRING | IT_CVAR, NULL, "Third-Person MouseLook", &cv_chasefreelook, 40}, {IT_STRING | IT_CVAR, NULL, "Mouse Move", &cv_mousemove, 50}, - {IT_STRING | IT_CVAR, NULL, "Invert Mouse", &cv_invertmouse, 60}, + {IT_STRING | IT_CVAR, NULL, "Invert Y Axis", &cv_invertmouse, 60}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Mouse X Speed", &cv_mousesens, 70}, + NULL, "Mouse X Sensitivity", &cv_mousesens, 70}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Mouse Y Speed", &cv_mouseysens, 80}, + NULL, "Mouse Y Sensitivity", &cv_mouseysens, 80}, }; static menuitem_t OP_Mouse2OptionsMenu[] = @@ -1089,40 +1142,109 @@ static menuitem_t OP_Mouse2OptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "First-Person MouseLook", &cv_alwaysfreelook2, 30}, {IT_STRING | IT_CVAR, NULL, "Third-Person MouseLook", &cv_chasefreelook2, 40}, {IT_STRING | IT_CVAR, NULL, "Mouse Move", &cv_mousemove2, 50}, - {IT_STRING | IT_CVAR, NULL, "Invert Mouse", &cv_invertmouse2, 60}, + {IT_STRING | IT_CVAR, NULL, "Invert Y Axis", &cv_invertmouse2, 60}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Mouse X Speed", &cv_mousesens2, 70}, + NULL, "Mouse X Sensitivity", &cv_mousesens2, 70}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Mouse Y Speed", &cv_mouseysens2, 80}, + NULL, "Mouse Y Sensitivity", &cv_mouseysens2, 80}, }; static menuitem_t OP_VideoOptionsMenu[] = { - {IT_STRING | IT_CALL, NULL, "Video Modes...", M_VideoModeMenu, 10}, + {IT_HEADER, NULL, "Screen", NULL, 0}, + {IT_STRING | IT_CALL, NULL, "Set Resolution...", M_VideoModeMenu, 6}, -#ifdef HWRENDER - {IT_SUBMENU|IT_STRING, NULL, "3D Card Options...", &OP_OpenGLOptionsDef, 20}, +#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) + {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 11}, #endif + {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 16}, -#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) - {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 30}, +#ifdef HWRENDER + {IT_SUBMENU|IT_STRING, NULL, "OpenGL Options...", &OP_OpenGLOptionsDef, 21}, #endif + {IT_HEADER, NULL, "Color Profile", NULL, 30}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness (F11)", &cv_globalgamma,36}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saturation", &cv_globalsaturation, 41}, + {IT_SUBMENU|IT_STRING, NULL, "Advanced Settings...", &OP_ColorOptionsDef, 46}, + + {IT_HEADER, NULL, "Heads-Up Display", NULL, 55}, + {IT_STRING | IT_CVAR, NULL, "Show HUD", &cv_showhud, 61}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Brightness", &cv_usegamma, 50}, - {IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 60}, - {IT_STRING | IT_CVAR, NULL, "NiGHTS Draw Dist", &cv_drawdist_nights, 70}, - {IT_STRING | IT_CVAR, NULL, "Precip Draw Dist", &cv_drawdist_precip, 80}, - {IT_STRING | IT_CVAR, NULL, "Precip Density", &cv_precipdensity, 90}, - - {IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 110}, - {IT_STRING | IT_CVAR, NULL, "Clear Before Redraw", &cv_homremoval, 120}, - {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 130}, + NULL, "HUD Transparency", &cv_translucenthud, 66}, + {IT_STRING | IT_CVAR, NULL, "Score/Time/Rings", &cv_timetic, 71}, + {IT_STRING | IT_CVAR, NULL, "Show Powerups", &cv_powerupdisplay, 76}, +#ifdef SEENAMES + {IT_STRING | IT_CVAR, NULL, "Show player names", &cv_seenames, 81}, +#endif + + {IT_HEADER, NULL, "Console", NULL, 90}, + {IT_STRING | IT_CVAR, NULL, "Background color", &cons_backcolor, 96}, + {IT_STRING | IT_CVAR, NULL, "Text Size", &cv_constextsize, 101}, + + {IT_HEADER, NULL, "Chat", NULL, 110}, + {IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 116}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Width", &cv_chatwidth, 121}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Height", &cv_chatheight, 126}, + {IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 131}, + {IT_STRING | IT_CVAR, NULL, "Chat Notifications", &cv_chatnotifications, 136}, + {IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 141}, + {IT_STRING | IT_CVAR, NULL, "Chat background tint", &cv_chatbacktint, 146}, + + {IT_HEADER, NULL, "Level", NULL, 155}, + {IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 161}, + {IT_STRING | IT_CVAR, NULL, "Weather Draw Dist.", &cv_drawdist_precip, 166}, + {IT_STRING | IT_CVAR, NULL, "NiGHTS mode Draw Dist.", &cv_drawdist_nights, 171}, + + {IT_HEADER, NULL, "Diagnostic", NULL, 180}, + {IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 186}, + {IT_STRING | IT_CVAR, NULL, "Clear Before Redraw", &cv_homremoval, 191}, }; static menuitem_t OP_VideoModeMenu[] = { - {IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleVideoMode, '\0'}, // dummy menuitem for the control func + {IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleVideoMode, 0}, // dummy menuitem for the control func +}; + +static menuitem_t OP_ColorOptionsMenu[] = +{ + {IT_STRING | IT_CALL, NULL, "Reset to defaults", M_ResetCvars, 0}, + + {IT_HEADER, NULL, "Red", NULL, 9}, + {IT_DISABLED, NULL, NULL, NULL, 35}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Hue", &cv_rhue, 15}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saturation", &cv_rsaturation, 20}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_rgamma, 25}, + + {IT_HEADER, NULL, "Yellow", NULL, 34}, + {IT_DISABLED, NULL, NULL, NULL, 73}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Hue", &cv_yhue, 40}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saturation", &cv_ysaturation, 45}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_ygamma, 50}, + + {IT_HEADER, NULL, "Green", NULL, 59}, + {IT_DISABLED, NULL, NULL, NULL, 112}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Hue", &cv_ghue, 65}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saturation", &cv_gsaturation, 70}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_ggamma, 75}, + + {IT_HEADER, NULL, "Cyan", NULL, 84}, + {IT_DISABLED, NULL, NULL, NULL, 255}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Hue", &cv_chue, 90}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saturation", &cv_csaturation, 95}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_cgamma, 100}, + + {IT_HEADER, NULL, "Blue", NULL, 109}, + {IT_DISABLED, NULL, NULL, NULL, 152}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Hue", &cv_bhue, 115}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saturation", &cv_bsaturation, 120}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_bgamma, 125}, + + {IT_HEADER, NULL, "Magenta", NULL, 134}, + {IT_DISABLED, NULL, NULL, NULL, 181}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Hue", &cv_mhue, 140}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saturation", &cv_msaturation, 145}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_mgamma, 150}, }; #ifdef HWRENDER @@ -1132,7 +1254,7 @@ static menuitem_t OP_OpenGLOptionsMenu[] = {IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 20}, {IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 30}, {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,40}, -#ifdef _WINDOWS +#if defined (_WINDOWS) && (!((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL))) {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 50}, #endif #ifdef ALAM_LIGHTING @@ -1170,60 +1292,67 @@ static menuitem_t OP_OpenGLColorMenu[] = static menuitem_t OP_SoundOptionsMenu[] = { - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Sound Volume" , &cv_soundvolume, 10}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Music Volume" , &cv_digmusicvolume, 20}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "MIDI Volume" , &cv_midimusicvolume, 30}, -#ifdef PC_DOS - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "CD Volume" , &cd_volume, 40}, -#endif + {IT_HEADER, NULL, "Game Audio", NULL, 0}, // 0 // ScrollMenu offsets + {IT_STRING | IT_CVAR, NULL, "Sound Effects", &cv_gamesounds, 13}, // 6 + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Sound Volume", &cv_soundvolume, 23}, // 11 + + {IT_STRING | IT_CVAR, NULL, "Digital Music", &cv_gamedigimusic, 43}, // 21 + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Digital Music Volume", &cv_digmusicvolume, 53}, // 26 - {IT_STRING | IT_CVAR, NULL, "SFX" , &cv_gamesounds, 50}, - {IT_STRING | IT_CVAR, NULL, "Digital Music", &cv_gamedigimusic, 60}, - {IT_STRING | IT_CVAR, NULL, "MIDI Music", &cv_gamemidimusic, 70}, + {IT_STRING | IT_CVAR, NULL, "MIDI Music", &cv_gamemidimusic, 73}, // 36 + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "MIDI Music Volume", &cv_midimusicvolume, 83}, // 41 + + {IT_HEADER, NULL, "Advanced", NULL, 103}, // 50 + {IT_STRING | IT_CVAR, NULL, "Closed Captioning", &cv_closedcaptioning, 115}, // 56 + +#ifdef HAVE_OPENMPT + {IT_HEADER, NULL, "OpenMPT Settings", NULL, 133}, + {IT_STRING | IT_CVAR, NULL, "Instrument Filter", &cv_modfilter, 145} +#endif }; static menuitem_t OP_DataOptionsMenu[] = { - {IT_STRING | IT_CALL, NULL, "Screenshot Options...", M_ScreenshotOptions, 10}, + {IT_STRING | IT_CALL, NULL, "Add-on Options...", M_AddonsOptions, 10}, + {IT_STRING | IT_CALL, NULL, "Screenshot Options...", M_ScreenshotOptions, 20}, - {IT_STRING | IT_SUBMENU, NULL, "Erase Data...", &OP_EraseDataDef, 30}, + {IT_STRING | IT_SUBMENU, NULL, "\x85" "Erase Data...", &OP_EraseDataDef, 40}, }; static menuitem_t OP_ScreenshotOptionsMenu[] = { - {IT_STRING|IT_CVAR, NULL, "Storage Location", &cv_screenshot_option, 10}, - {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_screenshot_folder, 20}, + {IT_HEADER, NULL, "General", NULL, 0}, + {IT_STRING|IT_CVAR, NULL, "Use color profile", &cv_screenshot_colorprofile, 6}, + {IT_STRING|IT_CVAR, NULL, "Storage Location", &cv_screenshot_option, 11}, + {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_screenshot_folder, 16}, - {IT_HEADER, NULL, "Screenshots (F8)", NULL, 50}, - {IT_STRING|IT_CVAR, NULL, "Memory Level", &cv_zlib_memory, 60}, - {IT_STRING|IT_CVAR, NULL, "Compression Level", &cv_zlib_level, 70}, - {IT_STRING|IT_CVAR, NULL, "Strategy", &cv_zlib_strategy, 80}, - {IT_STRING|IT_CVAR, NULL, "Window Size", &cv_zlib_window_bits, 90}, + {IT_HEADER, NULL, "Screenshots (F8)", NULL, 30}, + {IT_STRING|IT_CVAR, NULL, "Memory Level", &cv_zlib_memory, 36}, + {IT_STRING|IT_CVAR, NULL, "Compression Level", &cv_zlib_level, 41}, + {IT_STRING|IT_CVAR, NULL, "Strategy", &cv_zlib_strategy, 46}, + {IT_STRING|IT_CVAR, NULL, "Window Size", &cv_zlib_window_bits, 51}, - {IT_HEADER, NULL, "Movie Mode (F9)", NULL, 105}, - {IT_STRING|IT_CVAR, NULL, "Capture Mode", &cv_moviemode, 115}, + {IT_HEADER, NULL, "Movie Mode (F9)", NULL, 60}, + {IT_STRING|IT_CVAR, NULL, "Capture Mode", &cv_moviemode, 66}, - {IT_STRING|IT_CVAR, NULL, "Region Optimizing", &cv_gif_optimize, 125}, - {IT_STRING|IT_CVAR, NULL, "Downscaling", &cv_gif_downscale, 135}, + {IT_STRING|IT_CVAR, NULL, "Region Optimizing", &cv_gif_optimize, 71}, + {IT_STRING|IT_CVAR, NULL, "Downscaling", &cv_gif_downscale, 76}, - {IT_STRING|IT_CVAR, NULL, "Memory Level", &cv_zlib_memorya, 125}, - {IT_STRING|IT_CVAR, NULL, "Compression Level", &cv_zlib_levela, 135}, - {IT_STRING|IT_CVAR, NULL, "Strategy", &cv_zlib_strategya, 145}, - {IT_STRING|IT_CVAR, NULL, "Window Size", &cv_zlib_window_bitsa, 155}, + {IT_STRING|IT_CVAR, NULL, "Memory Level", &cv_zlib_memorya, 71}, + {IT_STRING|IT_CVAR, NULL, "Compression Level", &cv_zlib_levela, 76}, + {IT_STRING|IT_CVAR, NULL, "Strategy", &cv_zlib_strategya, 81}, + {IT_STRING|IT_CVAR, NULL, "Window Size", &cv_zlib_window_bitsa, 86}, }; enum { - op_screenshot_folder = 1, - op_screenshot_capture = 8, - op_screenshot_gif_start = 9, - op_screenshot_gif_end = 10, - op_screenshot_apng_start = 11, - op_screenshot_apng_end = 14, + op_screenshot_colorprofile = 1, + op_screenshot_folder = 3, + op_screenshot_capture = 10, + op_screenshot_gif_start = 11, + op_screenshot_gif_end = 12, + op_screenshot_apng_start = 13, + op_screenshot_apng_end = 16, }; static menuitem_t OP_EraseDataMenu[] = @@ -1236,15 +1365,15 @@ static menuitem_t OP_EraseDataMenu[] = static menuitem_t OP_AddonsOptionsMenu[] = { - {IT_HEADER, NULL, "Menu", NULL, 0}, - {IT_STRING|IT_CVAR, NULL, "Location", &cv_addons_option, 10}, - {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_addons_folder, 20}, - {IT_STRING|IT_CVAR, NULL, "Identify add-ons via", &cv_addons_md5, 48}, - {IT_STRING|IT_CVAR, NULL, "Show unsupported file types", &cv_addons_showall, 58}, + {IT_HEADER, NULL, "Menu", NULL, 0}, + {IT_STRING|IT_CVAR, NULL, "Location", &cv_addons_option, 12}, + {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_addons_folder, 22}, + {IT_STRING|IT_CVAR, NULL, "Identify add-ons via", &cv_addons_md5, 50}, + {IT_STRING|IT_CVAR, NULL, "Show unsupported file types", &cv_addons_showall, 60}, - {IT_HEADER, NULL, "Search", NULL, 76}, - {IT_STRING|IT_CVAR, NULL, "Matching", &cv_addons_search_type, 86}, - {IT_STRING|IT_CVAR, NULL, "Case-sensitive", &cv_addons_search_case, 96}, + {IT_HEADER, NULL, "Search", NULL, 78}, + {IT_STRING|IT_CVAR, NULL, "Matching", &cv_addons_search_type, 90}, + {IT_STRING|IT_CVAR, NULL, "Case-sensitive", &cv_addons_search_case, 100}, }; enum @@ -1252,125 +1381,76 @@ enum op_addons_folder = 2, }; -static menuitem_t OP_GameOptionsMenu[] = -{ -#ifndef NONET - {IT_STRING | IT_CVAR | IT_CV_STRING, - NULL, "Master server", &cv_masterserver, 10}, - {IT_STRING | IT_SUBMENU, NULL, "Chat Options...", &OP_ChatOptionsDef, 40}, -#endif - {IT_STRING | IT_CVAR, NULL, "Show HUD", &cv_showhud, 50}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "HUD Visibility", &cv_translucenthud, 60}, - {IT_STRING | IT_CVAR, NULL, "Timer Display", &cv_timetic, 70}, - {IT_STRING | IT_CVAR, NULL, "Always Compact Rankings", &cv_compactscoreboard, 80}, -#ifdef SEENAMES - {IT_STRING | IT_CVAR, NULL, "HUD Player Names", &cv_seenames, 90}, -#endif - {IT_STRING | IT_CVAR, NULL, "Log Hazard Damage", &cv_hazardlog, 100}, - - {IT_STRING | IT_CVAR, NULL, "Console Back Color", &cons_backcolor, 110}, - {IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize,120}, - {IT_STRING | IT_CVAR, NULL, "Uppercase Console", &cv_allcaps, 130}, - - {IT_STRING | IT_CVAR, NULL, "Title Screen Demos", &cv_rollingdemos, 140}, -}; - -static menuitem_t OP_ChatOptionsMenu[] = -{ - {IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 10}, - - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Width", &cv_chatwidth, 30}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Height", &cv_chatheight, 40}, - {IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 50}, - {IT_STRING | IT_CVAR, NULL, "Chat Notifications", &cv_chatnotifications, 60}, - {IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 70}, - {IT_STRING | IT_CVAR, NULL, "Chat background tint", &cv_chatbacktint, 80}, -}; - static menuitem_t OP_ServerOptionsMenu[] = { - {IT_STRING | IT_SUBMENU, NULL, "General netgame options...", &OP_NetgameOptionsDef, 10}, - {IT_STRING | IT_SUBMENU, NULL, "Gametype options...", &OP_GametypeOptionsDef, 20}, - {IT_STRING | IT_SUBMENU, NULL, "Random Monitor Toggles...", &OP_MonitorToggleDef, 30}, - + {IT_HEADER, NULL, "General", NULL, 0}, #ifndef NONET {IT_STRING | IT_CVAR | IT_CV_STRING, - NULL, "Server name", &cv_servername, 50}, -#endif - - {IT_STRING | IT_CVAR, NULL, "Intermission Timer", &cv_inttime, 80}, - {IT_STRING | IT_CVAR, NULL, "Advance to next map", &cv_advancemap, 90}, - -#ifndef NONET - {IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 110}, - {IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 120}, - {IT_STRING | IT_CVAR, NULL, "Allow WAD Downloading", &cv_downloading, 130}, - {IT_STRING | IT_CVAR, NULL, "Attempts to Resynch", &cv_resynchattempts, 140}, + NULL, "Server name", &cv_servername, 7}, + {IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 21}, + {IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26}, + {IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 31}, #endif -}; + {IT_STRING | IT_CVAR, NULL, "Map progression", &cv_advancemap, 36}, + {IT_STRING | IT_CVAR, NULL, "Intermission Timer", &cv_inttime, 41}, -static menuitem_t OP_NetgameOptionsMenu[] = -{ - {IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 10}, - {IT_STRING | IT_CVAR, NULL, "Point Limit", &cv_pointlimit, 18}, - {IT_STRING | IT_CVAR, NULL, "Overtime Tie-Breaker", &cv_overtime, 26}, - - {IT_STRING | IT_CVAR, NULL, "Special Ring Weapons", &cv_specialrings, 42}, - {IT_STRING | IT_CVAR, NULL, "Emeralds", &cv_powerstones, 50}, - {IT_STRING | IT_CVAR, NULL, "Item Boxes", &cv_matchboxes, 58}, - {IT_STRING | IT_CVAR, NULL, "Item Respawn", &cv_itemrespawn, 66}, - {IT_STRING | IT_CVAR, NULL, "Item Respawn time", &cv_itemrespawntime, 74}, + {IT_HEADER, NULL, "Characters", NULL, 50}, + {IT_STRING | IT_CVAR, NULL, "Force a character", &cv_forceskin, 56}, + {IT_STRING | IT_CVAR, NULL, "Restrict character changes", &cv_restrictskinchange, 61}, - {IT_STRING | IT_CVAR, NULL, "Sudden Death", &cv_suddendeath, 90}, - {IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 98}, + {IT_HEADER, NULL, "Items", NULL, 70}, + {IT_STRING | IT_CVAR, NULL, "Item respawn delay", &cv_itemrespawntime, 76}, + {IT_STRING | IT_SUBMENU, NULL, "Mystery Item Monitor Toggles...", &OP_MonitorToggleDef, 81}, - {IT_STRING | IT_CVAR, NULL, "Force Skin #", &cv_forceskin, 114}, - {IT_STRING | IT_CVAR, NULL, "Restrict skin changes", &cv_restrictskinchange, 122}, - - {IT_STRING | IT_CVAR, NULL, "Autobalance Teams", &cv_autobalance, 138}, - {IT_STRING | IT_CVAR, NULL, "Scramble Teams on Map Change", &cv_scrambleonchange, 146}, -}; + {IT_HEADER, NULL, "Cooperative", NULL, 90}, + {IT_STRING | IT_CVAR, NULL, "Players required for exit", &cv_playersforexit, 96}, + {IT_STRING | IT_CVAR, NULL, "Starposts", &cv_coopstarposts, 101}, + {IT_STRING | IT_CVAR, NULL, "Life sharing", &cv_cooplives, 106}, -static menuitem_t OP_GametypeOptionsMenu[] = -{ - {IT_HEADER, NULL, "CO-OP", NULL, 2}, - {IT_STRING | IT_CVAR, NULL, "Players for exit", &cv_playersforexit, 10}, - {IT_STRING | IT_CVAR, NULL, "Starting Lives", &cv_startinglives, 18}, + {IT_HEADER, NULL, "Race, Competition", NULL, 115}, + {IT_STRING | IT_CVAR, NULL, "Level completion countdown", &cv_countdowntime, 121}, + {IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_competitionboxes, 126}, - {IT_HEADER, NULL, "COMPETITION", NULL, 34}, - {IT_STRING | IT_CVAR, NULL, "Item Boxes", &cv_competitionboxes, 42}, - {IT_STRING | IT_CVAR, NULL, "Countdown Time", &cv_countdowntime, 50}, + {IT_HEADER, NULL, "Ringslinger (Match, CTF, Tag, H&S)", NULL, 135}, + {IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 141}, + {IT_STRING | IT_CVAR, NULL, "Score Limit", &cv_pointlimit, 146}, + {IT_STRING | IT_CVAR, NULL, "Overtime on Tie", &cv_overtime, 151}, + {IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 156}, - {IT_HEADER, NULL, "RACE", NULL, 66}, - {IT_STRING | IT_CVAR, NULL, "Number of Laps", &cv_numlaps, 74}, - {IT_STRING | IT_CVAR, NULL, "Use Map Lap Counts", &cv_usemapnumlaps, 82}, + {IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_matchboxes, 166}, + {IT_STRING | IT_CVAR, NULL, "Weapon Rings", &cv_specialrings, 171}, + {IT_STRING | IT_CVAR, NULL, "Power Stones", &cv_powerstones, 176}, - {IT_HEADER, NULL, "MATCH", NULL, 98}, - {IT_STRING | IT_CVAR, NULL, "Scoring Type", &cv_match_scoring, 106}, + {IT_STRING | IT_CVAR, NULL, "Flag respawn delay", &cv_flagtime, 186}, + {IT_STRING | IT_CVAR, NULL, "Hiding time", &cv_hidetime, 191}, - {IT_HEADER, NULL, "TAG", NULL, 122}, - {IT_STRING | IT_CVAR, NULL, "Hide Time", &cv_hidetime, 130}, + {IT_HEADER, NULL, "Teams", NULL, 200}, + {IT_STRING | IT_CVAR, NULL, "Autobalance sizes", &cv_autobalance, 206}, + {IT_STRING | IT_CVAR, NULL, "Scramble on Map Change", &cv_scrambleonchange, 211}, - {IT_HEADER, NULL, "CTF", NULL, 146}, - {IT_STRING | IT_CVAR, NULL, "Flag Respawn Time", &cv_flagtime, 154}, +#ifndef NONET + {IT_HEADER, NULL, "Advanced", NULL, 220}, + {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 226}, + {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 240}, +#endif }; static menuitem_t OP_MonitorToggleMenu[] = { // Printing handled by drawing function - {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Recycler", &cv_recycler, 20}, - {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Teleporters", &cv_teleporters, 30}, - {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Super Ring", &cv_superring, 40}, - {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Super Sneakers", &cv_supersneakers, 50}, - {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Invincibility", &cv_invincibility, 60}, - {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Jump Shield", &cv_jumpshield, 70}, - {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Elemental Shield", &cv_watershield, 80}, - {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Attraction Shield", &cv_ringshield, 90}, - {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Force Shield", &cv_forceshield, 100}, - {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Armageddon Shield", &cv_bombshield, 110}, - {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "1 Up", &cv_1up, 120}, - {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Eggman Box", &cv_eggmanbox, 130}, + {IT_STRING|IT_CALL, NULL, "Reset to defaults", M_ResetCvars, 15}, + {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Recycler", &cv_recycler, 30}, + {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Teleport", &cv_teleporters, 40}, + {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Super Ring", &cv_superring, 50}, + {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Super Sneakers", &cv_supersneakers, 60}, + {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Invincibility", &cv_invincibility, 70}, + {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Whirlwind Shield", &cv_jumpshield, 80}, + {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Elemental Shield", &cv_watershield, 90}, + {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Attraction Shield", &cv_ringshield, 100}, + {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Force Shield", &cv_forceshield, 110}, + {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Armageddon Shield", &cv_bombshield, 120}, + {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "1 Up", &cv_1up, 130}, + {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Eggman Box", &cv_eggmanbox, 140}, }; // ========================================================================== @@ -1378,10 +1458,11 @@ static menuitem_t OP_MonitorToggleMenu[] = // ========================================================================== // Main Menu and related -menu_t MainDef = CENTERMENUSTYLE(NULL, MainMenu, NULL, 72); +menu_t MainDef = CENTERMENUSTYLE(MN_MAIN, NULL, MainMenu, NULL, 72); menu_t MISC_AddonsDef = { + MN_AD_MAIN, NULL, sizeof (MISC_AddonsMenu)/sizeof (menuitem_t), &MainDef, @@ -1397,9 +1478,23 @@ menu_t SPauseDef = PAUSEMENUSTYLE(SPauseMenu, 40, 72); menu_t MPauseDef = PAUSEMENUSTYLE(MPauseMenu, 40, 72); // Misc Main Menu -menu_t MISC_ScrambleTeamDef = DEFAULTMENUSTYLE(NULL, MISC_ScrambleTeamMenu, &MPauseDef, 27, 40); -menu_t MISC_ChangeTeamDef = DEFAULTMENUSTYLE(NULL, MISC_ChangeTeamMenu, &MPauseDef, 27, 40); -menu_t MISC_ChangeLevelDef = MAPICONMENUSTYLE(NULL, MISC_ChangeLevelMenu, &MPauseDef); +menu_t MISC_ScrambleTeamDef = DEFAULTMENUSTYLE(MN_SPECIAL, NULL, MISC_ScrambleTeamMenu, &MPauseDef, 27, 40); +menu_t MISC_ChangeTeamDef = DEFAULTMENUSTYLE(MN_SPECIAL, NULL, MISC_ChangeTeamMenu, &MPauseDef, 27, 40); + +// MP Gametype and map change menu +menu_t MISC_ChangeLevelDef = +{ + MN_SPECIAL, + NULL, + sizeof (MISC_ChangeLevelMenu)/sizeof (menuitem_t), + &MainDef, // Doesn't matter. + MISC_ChangeLevelMenu, + M_DrawLevelPlatterMenu, + 0, 0, + 0, + NULL +}; + menu_t MISC_HelpDef = IMAGEDEF(MISC_HelpMenu); static INT32 highlightflags, recommendedflags, warningflags; @@ -1408,17 +1503,19 @@ static INT32 highlightflags, recommendedflags, warningflags; // Sky Room menu_t SR_PandoraDef = { + MN_SR_MAIN + (MN_SR_PANDORA << 6), "M_PANDRA", sizeof (SR_PandorasBox)/sizeof (menuitem_t), &SPauseDef, SR_PandorasBox, M_DrawGenericMenu, - 60, 40, + 60, 30, 0, M_ExitPandorasBox }; menu_t SR_MainDef = { + MN_SR_MAIN, "M_SECRET", sizeof (SR_MainMenu)/sizeof (menuitem_t), &MainDef, @@ -1428,30 +1525,26 @@ menu_t SR_MainDef = 0, NULL }; -menu_t SR_LevelSelectDef = -{ - 0, - sizeof (SR_LevelSelectMenu)/sizeof (menuitem_t), - &SR_MainDef, - SR_LevelSelectMenu, - M_DrawLevelSelectMenu, - 40, 40, - 0, - NULL -}; + +menu_t SR_LevelSelectDef = MAPPLATTERMENUSTYLE( + MN_SR_MAIN + (MN_SR_LEVELSELECT << 6), + NULL, SR_LevelSelectMenu); + menu_t SR_UnlockChecklistDef = { - NULL, + MN_SR_MAIN + (MN_SR_UNLOCKCHECKLIST << 6), + "M_SECRET", 1, &SR_MainDef, SR_UnlockChecklistMenu, M_DrawChecklist, - 280, 185, + 30, 30, 0, NULL }; menu_t SR_EmblemHintDef = { + MN_SR_MAIN + (MN_SR_EMBLEMHINT << 6), NULL, sizeof (SR_EmblemHintMenu)/sizeof (menuitem_t), &SPauseDef, @@ -1463,9 +1556,22 @@ menu_t SR_EmblemHintDef = }; // Single Player -menu_t SP_MainDef = CENTERMENUSTYLE(NULL, SP_MainMenu, &MainDef, 72); +menu_t SP_MainDef = //CENTERMENUSTYLE(NULL, SP_MainMenu, &MainDef, 72); +{ + MN_SP_MAIN, + NULL, + sizeof(SP_MainMenu)/sizeof(menuitem_t), + &MainDef, + SP_MainMenu, + M_DrawCenteredMenu, + BASEVIDWIDTH/2, 72, + 1, // start at "Start Game" on first entry + NULL +}; + menu_t SP_LoadDef = { + MN_SP_MAIN + (MN_SP_LOAD << 6), "M_PICKG", 1, &SP_MainDef, @@ -1475,21 +1581,14 @@ menu_t SP_LoadDef = 0, NULL }; -menu_t SP_LevelSelectDef = MAPICONMENUSTYLE(NULL, SP_LevelSelectMenu, &SP_LoadDef); -menu_t SP_GameStatsDef = -{ - "M_STATS", - 1, - &SP_MainDef, - SP_GameStatsMenu, - M_DrawGameStats, - 280, 185, - 0, - NULL -}; +menu_t SP_LevelSelectDef = MAPPLATTERMENUSTYLE( + MN_SP_MAIN + (MN_SP_LOAD << 6) + (MN_SP_PLAYER << 12) + (MN_SP_LEVELSELECT << 18), + NULL, SP_LevelSelectMenu); + menu_t SP_LevelStatsDef = { + MN_SP_MAIN + (MN_SP_LEVELSTATS << 6), "M_STATS", 1, &SP_MainDef, @@ -1500,8 +1599,13 @@ menu_t SP_LevelStatsDef = NULL }; +menu_t SP_TimeAttackLevelSelectDef = MAPPLATTERMENUSTYLE( + MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_TIMEATTACK_LEVELSELECT << 12), + "M_ATTACK", SP_TimeAttackLevelSelectMenu); + static menu_t SP_TimeAttackDef = { + MN_SP_MAIN + (MN_SP_TIMEATTACK << 6), "M_ATTACK", sizeof (SP_TimeAttackMenu)/sizeof (menuitem_t), &MainDef, // Doesn't matter. @@ -1513,6 +1617,7 @@ static menu_t SP_TimeAttackDef = }; static menu_t SP_ReplayDef = { + MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_REPLAY << 12), "M_ATTACK", sizeof(SP_ReplayMenu)/sizeof(menuitem_t), &SP_TimeAttackDef, @@ -1524,6 +1629,7 @@ static menu_t SP_ReplayDef = }; static menu_t SP_GuestReplayDef = { + MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_GUESTREPLAY << 12), "M_ATTACK", sizeof(SP_GuestReplayMenu)/sizeof(menuitem_t), &SP_TimeAttackDef, @@ -1535,6 +1641,7 @@ static menu_t SP_GuestReplayDef = }; static menu_t SP_GhostDef = { + MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_GHOST << 12), "M_ATTACK", sizeof(SP_GhostMenu)/sizeof(menuitem_t), &SP_TimeAttackDef, @@ -1545,8 +1652,13 @@ static menu_t SP_GhostDef = NULL }; +menu_t SP_NightsAttackLevelSelectDef = MAPPLATTERMENUSTYLE( + MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_LEVELSELECT << 12), + "M_NIGHTS", SP_NightsAttackLevelSelectMenu); + static menu_t SP_NightsAttackDef = { + MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6), "M_NIGHTS", sizeof (SP_NightsAttackMenu)/sizeof (menuitem_t), &MainDef, // Doesn't matter. @@ -1558,6 +1670,7 @@ static menu_t SP_NightsAttackDef = }; static menu_t SP_NightsReplayDef = { + MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_REPLAY << 12), "M_NIGHTS", sizeof(SP_NightsReplayMenu)/sizeof(menuitem_t), &SP_NightsAttackDef, @@ -1569,6 +1682,7 @@ static menu_t SP_NightsReplayDef = }; static menu_t SP_NightsGuestReplayDef = { + MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_GUESTREPLAY << 12), "M_NIGHTS", sizeof(SP_NightsGuestReplayMenu)/sizeof(menuitem_t), &SP_NightsAttackDef, @@ -1580,6 +1694,7 @@ static menu_t SP_NightsGuestReplayDef = }; static menu_t SP_NightsGhostDef = { + MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_GHOST << 12), "M_NIGHTS", sizeof(SP_NightsGhostMenu)/sizeof(menuitem_t), &SP_NightsAttackDef, @@ -1593,10 +1708,11 @@ static menu_t SP_NightsGhostDef = menu_t SP_PlayerDef = { + MN_SP_MAIN + (MN_SP_LOAD << 6) + (MN_SP_PLAYER << 12), "M_PICKP", - sizeof (PlayerMenu)/sizeof (menuitem_t),//player_end, + sizeof (SP_PlayerMenu)/sizeof (menuitem_t), &SP_MainDef, - PlayerMenu, + SP_PlayerMenu, M_DrawSetupChoosePlayerMenu, 24, 32, 0, @@ -1604,33 +1720,68 @@ menu_t SP_PlayerDef = }; // Multiplayer -menu_t MP_MainDef = DEFAULTMENUSTYLE("M_MULTI", MP_MainMenu, &MainDef, 60, 40); -menu_t MP_ServerDef = MAPICONMENUSTYLE("M_MULTI", MP_ServerMenu, &MP_MainDef); -#ifndef NONET -menu_t MP_ConnectDef = + +menu_t MP_SplitServerDef = { + MN_MP_MAIN + (MN_MP_SPLITSCREEN << 6), "M_MULTI", - sizeof (MP_ConnectMenu)/sizeof (menuitem_t), + sizeof (MP_SplitServerMenu)/sizeof (menuitem_t), +#ifndef NONET &MP_MainDef, - MP_ConnectMenu, - M_DrawConnectMenu, - 27,24, +#else + &MainDef, +#endif + MP_SplitServerMenu, + M_DrawServerMenu, + 27, 30 - 50, + 0, + NULL +}; + +#ifndef NONET + +menu_t MP_MainDef = +{ + MN_MP_MAIN, + "M_MULTI", + sizeof (MP_MainMenu)/sizeof (menuitem_t), + &MainDef, + MP_MainMenu, + M_DrawMPMainMenu, + 27, 40, 0, M_CancelConnect }; -menu_t MP_ConnectIPDef = + +menu_t MP_ServerDef = +{ + MN_MP_MAIN + (MN_MP_SERVER << 6), + "M_MULTI", + sizeof (MP_ServerMenu)/sizeof (menuitem_t), + &MP_MainDef, + MP_ServerMenu, + M_DrawServerMenu, + 27, 30, + 0, + NULL +}; + +menu_t MP_ConnectDef = { + MN_MP_MAIN + (MN_MP_CONNECT << 6), "M_MULTI", - sizeof (MP_ConnectIPMenu)/sizeof (menuitem_t), + sizeof (MP_ConnectMenu)/sizeof (menuitem_t), &MP_MainDef, - MP_ConnectIPMenu, - M_DrawConnectIPMenu, - 27,40, + MP_ConnectMenu, + M_DrawConnectMenu, + 27,24, 0, M_CancelConnect }; + menu_t MP_RoomDef = { + MN_MP_MAIN + (MN_MP_ROOM << 6), "M_MULTI", sizeof (MP_RoomMenu)/sizeof (menuitem_t), &MP_ConnectDef, @@ -1641,47 +1792,77 @@ menu_t MP_RoomDef = NULL }; #endif -menu_t MP_SplitServerDef = MAPICONMENUSTYLE("M_MULTI", MP_SplitServerMenu, &MP_MainDef); + menu_t MP_PlayerSetupDef = { +#ifdef NONET + MN_MP_MAIN + (MN_MP_PLAYERSETUP << 6), +#else + MN_MP_MAIN + (MN_MP_SPLITSCREEN << 6) + (MN_MP_PLAYERSETUP << 12), +#endif "M_SPLAYR", sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t), - &MP_MainDef, + &MainDef, // doesn't matter MP_PlayerSetupMenu, M_DrawSetupMultiPlayerMenu, - 27, 40, + 19, 22, 0, M_QuitMultiPlayerMenu }; // Options -menu_t OP_MainDef = DEFAULTMENUSTYLE("M_OPTTTL", OP_MainMenu, &MainDef, 60, 30); -menu_t OP_ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_ControlsMenu, &OP_MainDef, 60, 30); -menu_t OP_ControlListDef = DEFAULTMENUSTYLE("M_CONTRO", OP_ControlListMenu, &OP_ControlsDef, 60, 30); -menu_t OP_MoveControlsDef = CONTROLMENUSTYLE(OP_MoveControlsMenu, &OP_ControlListDef); -menu_t OP_MPControlsDef = CONTROLMENUSTYLE(OP_MPControlsMenu, &OP_ControlListDef); -menu_t OP_MiscControlsDef = CONTROLMENUSTYLE(OP_MiscControlsMenu, &OP_ControlListDef); -menu_t OP_P1ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P1ControlsMenu, &OP_ControlsDef, 60, 30); -menu_t OP_P2ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P2ControlsMenu, &OP_ControlsDef, 60, 30); -menu_t OP_MouseOptionsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_MouseOptionsMenu, &OP_P1ControlsDef, 60, 30); -menu_t OP_Mouse2OptionsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_Mouse2OptionsMenu, &OP_P2ControlsDef, 60, 30); -menu_t OP_Joystick1Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick1Menu, &OP_P1ControlsDef, 60, 30); -menu_t OP_Joystick2Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick2Menu, &OP_P2ControlsDef, 60, 30); +menu_t OP_MainDef = DEFAULTMENUSTYLE( + MN_OP_MAIN, + "M_OPTTTL", OP_MainMenu, &MainDef, 50, 30); +menu_t OP_ChangeControlsDef = CONTROLMENUSTYLE( + MN_OP_MAIN + (MN_OP_CHANGECONTROLS << 12), // second level (<<6) set on runtime + OP_ChangeControlsMenu, &OP_MainDef); +menu_t OP_P1ControlsDef = DEFAULTMENUSTYLE( + MN_OP_MAIN + (MN_OP_P1CONTROLS << 6), + "M_CONTRO", OP_P1ControlsMenu, &OP_MainDef, 50, 30); +menu_t OP_P2ControlsDef = DEFAULTMENUSTYLE( + MN_OP_MAIN + (MN_OP_P2CONTROLS << 6), + "M_CONTRO", OP_P2ControlsMenu, &OP_MainDef, 50, 30); +menu_t OP_MouseOptionsDef = DEFAULTMENUSTYLE( + MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1MOUSE << 12), + "M_CONTRO", OP_MouseOptionsMenu, &OP_P1ControlsDef, 35, 30); +menu_t OP_Mouse2OptionsDef = DEFAULTMENUSTYLE( + MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2MOUSE << 12), + "M_CONTRO", OP_Mouse2OptionsMenu, &OP_P2ControlsDef, 35, 30); +menu_t OP_Joystick1Def = DEFAULTMENUSTYLE( + MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1JOYSTICK << 12), + "M_CONTRO", OP_Joystick1Menu, &OP_P1ControlsDef, 50, 30); +menu_t OP_Joystick2Def = DEFAULTMENUSTYLE( + MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2JOYSTICK << 12), + "M_CONTRO", OP_Joystick2Menu, &OP_P2ControlsDef, 50, 30); menu_t OP_JoystickSetDef = { + MN_OP_MAIN + (MN_OP_JOYSTICKSET << MENUBITS*3), // second (<<6) and third level (<<12) set on runtime "M_CONTRO", sizeof (OP_JoystickSetMenu)/sizeof (menuitem_t), &OP_Joystick1Def, OP_JoystickSetMenu, M_DrawJoystick, - 50, 40, + 60, 40, 0, NULL }; -menu_t OP_VideoOptionsDef = DEFAULTMENUSTYLE("M_VIDEO", OP_VideoOptionsMenu, &OP_MainDef, 60, 30); +menu_t OP_VideoOptionsDef = +{ + MN_OP_MAIN + (MN_OP_VIDEO << 6), + "M_VIDEO", + sizeof (OP_VideoOptionsMenu)/sizeof (menuitem_t), + &OP_MainDef, + OP_VideoOptionsMenu, + M_DrawMainVideoMenu, + 30, 30, + 0, + NULL +}; menu_t OP_VideoModeDef = { + MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_VIDEOMODE << 12), "M_VIDEO", 1, &OP_VideoOptionsDef, @@ -1691,15 +1872,38 @@ menu_t OP_VideoModeDef = 0, NULL }; -menu_t OP_SoundOptionsDef = DEFAULTMENUSTYLE("M_SOUND", OP_SoundOptionsMenu, &OP_MainDef, 60, 30); -menu_t OP_GameOptionsDef = DEFAULTMENUSTYLE("M_GAME", OP_GameOptionsMenu, &OP_MainDef, 30, 30); -menu_t OP_ServerOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_ServerOptionsMenu, &OP_MainDef, 30, 30); +menu_t OP_ColorOptionsDef = +{ + MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_COLOR << 12), + "M_VIDEO", + sizeof (OP_ColorOptionsMenu)/sizeof (menuitem_t), + &OP_VideoOptionsDef, + OP_ColorOptionsMenu, + M_DrawColorMenu, + 30, 30, + 0, + NULL +}; +menu_t OP_SoundOptionsDef = +{ + MN_OP_MAIN + (MN_OP_SOUND << 6), + "M_SOUND", + sizeof (OP_SoundOptionsMenu)/sizeof (menuitem_t), + &OP_MainDef, + OP_SoundOptionsMenu, + M_DrawGenericMenu, + 30, 30, + 0, + NULL +}; + +menu_t OP_ServerOptionsDef = DEFAULTSCROLLMENUSTYLE( + MN_OP_MAIN + (MN_OP_SERVER << 6), + "M_SERVER", OP_ServerOptionsMenu, &OP_MainDef, 30, 30); -menu_t OP_NetgameOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_NetgameOptionsMenu, &OP_ServerOptionsDef, 30, 30); -menu_t OP_GametypeOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_GametypeOptionsMenu, &OP_ServerOptionsDef, 30, 30); -menu_t OP_ChatOptionsDef = DEFAULTMENUSTYLE("M_GAME", OP_ChatOptionsMenu, &OP_GameOptionsDef, 30, 30); menu_t OP_MonitorToggleDef = { + MN_OP_MAIN + (MN_OP_SERVER << 6) + (MN_OP_MONITORTOGGLE << 12), "M_SERVER", sizeof (OP_MonitorToggleMenu)/sizeof (menuitem_t), &OP_ServerOptionsDef, @@ -1711,12 +1915,17 @@ menu_t OP_MonitorToggleDef = }; #ifdef HWRENDER -menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE("M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30); +menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE( + MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12), + "M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30); #ifdef ALAM_LIGHTING -menu_t OP_OpenGLLightingDef = DEFAULTMENUSTYLE("M_VIDEO", OP_OpenGLLightingMenu, &OP_OpenGLOptionsDef, 60, 40); +menu_t OP_OpenGLLightingDef = DEFAULTMENUSTYLE( + MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12) + (MN_OP_OPENGL_LIGHTING << 18), + "M_VIDEO", OP_OpenGLLightingMenu, &OP_OpenGLOptionsDef, 60, 40); #endif menu_t OP_OpenGLFogDef = { + MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12) + (MN_OP_OPENGL_FOG << 18), "M_VIDEO", sizeof (OP_OpenGLFogMenu)/sizeof (menuitem_t), &OP_OpenGLOptionsDef, @@ -1728,6 +1937,7 @@ menu_t OP_OpenGLFogDef = }; menu_t OP_OpenGLColorDef = { + MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12) + (MN_OP_OPENGL_COLOR << 18), "M_VIDEO", sizeof (OP_OpenGLColorMenu)/sizeof (menuitem_t), &OP_OpenGLOptionsDef, @@ -1738,10 +1948,30 @@ menu_t OP_OpenGLColorDef = NULL }; #endif -menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30); -menu_t OP_ScreenshotOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_ScreenshotOptionsMenu, &OP_DataOptionsDef, 30, 30); -menu_t OP_AddonsOptionsDef = DEFAULTMENUSTYLE("M_ADDONS", OP_AddonsOptionsMenu, &OP_MainDef, 30, 30); -menu_t OP_EraseDataDef = DEFAULTMENUSTYLE("M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30); +menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE( + MN_OP_MAIN + (MN_OP_DATA << 6), + "M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30); + +menu_t OP_ScreenshotOptionsDef = +{ + MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_SCREENSHOTS << 12), + "M_DATA", + sizeof (OP_ScreenshotOptionsMenu)/sizeof (menuitem_t), + &OP_DataOptionsDef, + OP_ScreenshotOptionsMenu, + M_DrawScreenshotMenu, + 30, 30, + 0, + NULL +}; + +menu_t OP_AddonsOptionsDef = DEFAULTMENUSTYLE( + MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_ADDONS << 12), + "M_ADDONS", OP_AddonsOptionsMenu, &OP_DataOptionsDef, 30, 30); + +menu_t OP_EraseDataDef = DEFAULTMENUSTYLE( + MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_ERASEDATA << 12), + "M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30); // ========================================================================== // CVAR ONCHANGE EVENTS GO HERE @@ -1749,11 +1979,11 @@ menu_t OP_EraseDataDef = DEFAULTMENUSTYLE("M_DATA", OP_EraseDataMenu, &OP_DataOp // (there's only a couple anyway) // Prototypes -static INT32 M_FindFirstMap(INT32 gtype); -static INT32 M_GetFirstLevelInList(void); +static INT32 M_GetFirstLevelInList(INT32 gt); +static boolean M_CanShowLevelOnPlatter(INT32 mapnum, INT32 gt); -// Nextmap. Used for Time Attack. -static void Nextmap_OnChange(void) +// Nextmap. Used for Level select. +void Nextmap_OnChange(void) { char *leveltitle; char tabase[256]; @@ -1825,7 +2055,7 @@ static void Nextmap_OnChange(void) SP_TimeAttackMenu[taghost].status = IT_DISABLED; // Check if file exists, if not, disable REPLAY option - sprintf(tabase,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s",srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string); + sprintf(tabase,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s",srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name); for (i = 0; i < 5; i++) { SP_ReplayMenu[i].status = IT_DISABLED; SP_GuestReplayMenu[i].status = IT_DISABLED; @@ -1897,43 +2127,8 @@ static void Newgametype_OnChange(void) if(!mapheaderinfo[cv_nextmap.value-1]) P_AllocMapHeader((INT16)(cv_nextmap.value-1)); - if ((cv_newgametype.value == GT_COOP && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_COOP)) || - (cv_newgametype.value == GT_COMPETITION && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_COMPETITION)) || - (cv_newgametype.value == GT_RACE && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_RACE)) || - ((cv_newgametype.value == GT_MATCH || cv_newgametype.value == GT_TEAMMATCH) && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_MATCH)) || - ((cv_newgametype.value == GT_TAG || cv_newgametype.value == GT_HIDEANDSEEK) && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_TAG)) || - (cv_newgametype.value == GT_CTF && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_CTF))) - { - INT32 value = 0; - - switch (cv_newgametype.value) - { - case GT_COOP: - value = TOL_COOP; - break; - case GT_COMPETITION: - value = TOL_COMPETITION; - break; - case GT_RACE: - value = TOL_RACE; - break; - case GT_MATCH: - case GT_TEAMMATCH: - value = TOL_MATCH; - break; - case GT_TAG: - case GT_HIDEANDSEEK: - value = TOL_TAG; - break; - case GT_CTF: - value = TOL_CTF; - break; - } - - CV_SetValue(&cv_nextmap, M_FindFirstMap(value)); - CV_AddValue(&cv_nextmap, -1); - CV_AddValue(&cv_nextmap, 1); - } + if (!M_CanShowLevelOnPlatter(cv_nextmap.value-1, cv_newgametype.value)) + CV_SetValue(&cv_nextmap, M_GetFirstLevelInList(cv_newgametype.value)); } } @@ -1980,35 +2175,545 @@ void Addons_option_Onchange(void) menu_t *currentMenu = &MainDef; // ========================================================================= -// BASIC MENU HANDLING +// MENU PRESENTATION PARAMETER HANDLING (BACKGROUNDS) // ========================================================================= -static void M_ChangeCvar(INT32 choice) +// menu IDs are equal to current/prevMenu in most cases, except MN_SPECIAL when we don't want to operate on Message, Pause, etc. +UINT32 prevMenuId = 0; +UINT32 activeMenuId = 0; + +menupres_t menupres[NUMMENUTYPES]; + +void M_InitMenuPresTables(void) { - consvar_t *cv = (consvar_t *)currentMenu->menuitems[itemOn].itemaction; + INT32 i; - if (((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_SLIDER) - ||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_INVISSLIDER) - ||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_NOMOD)) - { - CV_SetValue(cv,cv->value+(choice*2-1)); + // Called in d_main before SOC can get to the tables + // Set menupres defaults + for (i = 0; i < NUMMENUTYPES; i++) + { + // so-called "undefined" + menupres[i].fadestrength = -1; + menupres[i].hidetitlepics = -1; // inherits global hidetitlepics + menupres[i].enterwipe = -1; + menupres[i].exitwipe = -1; + menupres[i].bgcolor = -1; + menupres[i].titlescrollxspeed = INT32_MAX; + menupres[i].titlescrollyspeed = INT32_MAX; + menupres[i].bghide = true; + // default true + menupres[i].enterbubble = true; + menupres[i].exitbubble = true; + + if (i != MN_MAIN) + { + menupres[i].muslooping = true; + } + if (i == MN_SP_TIMEATTACK || i == MN_SP_NIGHTSATTACK) + strncpy(menupres[i].musname, "_inter", 7); + else if (i == MN_SP_PLAYER) + strncpy(menupres[i].musname, "_chsel", 7); + } +} + +// ==================================== +// TREE ITERATION +// ==================================== + +// UINT32 menutype - current menutype_t +// INT32 level - current level up the tree, higher means younger +// INT32 *retval - Return value +// void *input - Pointer to input of any type +// +// return true - stop iterating +// return false - continue +typedef boolean (*menutree_iterator)(UINT32, INT32, INT32 *, void **, boolean fromoldest); + +// HACK: Used in the ChangeMusic iterator because we only allow +// a single input. Maybe someday use this struct program-wide. +typedef struct +{ + char musname[7]; + UINT16 mustrack; + boolean muslooping; +} menupresmusic_t; + +static INT32 M_IterateMenuTree(menutree_iterator itfunc, void *input) +{ + INT32 i, retval = 0; + UINT32 bitmask, menutype; + + for (i = NUMMENULEVELS; i >= 0; i--) + { + bitmask = ((1 << MENUBITS) - 1) << (MENUBITS*i); + menutype = (activeMenuId & bitmask) >> (MENUBITS*i); + if (itfunc(menutype, i, &retval, &input, false)) + break; + } + + return retval; +} + +// ==================================== +// ITERATORS +// ==================================== + +static boolean MIT_GetMenuAtLevel(UINT32 menutype, INT32 level, INT32 *retval, void **input, boolean fromoldest) +{ + INT32 *inputptr = (INT32*)*input; + INT32 targetlevel = *inputptr; + if (menutype) + { + if (level == targetlevel || targetlevel < 0) + { + *retval = menutype; + return true; + } + } + else if (targetlevel >= 0) + { + // offset targetlevel by failed attempts; this should only happen in beginning of iteration + if (fromoldest) + (*inputptr)++; + else + (*inputptr)--; // iterating backwards, so count from highest + } + return false; +} + +static boolean MIT_SetCurBackground(UINT32 menutype, INT32 level, INT32 *retval, void **input, boolean fromoldest) +{ + char *defaultname = (char*)*input; + + (void)retval; + (void)fromoldest; + + if (menupres[menutype].bgcolor >= 0) + { + curbgcolor = menupres[menutype].bgcolor; + return true; + } + else if (menupres[menutype].bgname[0] && (!menupres[menutype].bghide || !titlemapinaction)) + { + strncpy(curbgname, menupres[menutype].bgname, 8); + curbgxspeed = menupres[menutype].titlescrollxspeed != INT32_MAX ? menupres[menutype].titlescrollxspeed : titlescrollxspeed; + curbgyspeed = menupres[menutype].titlescrollyspeed != INT32_MAX ? menupres[menutype].titlescrollyspeed : titlescrollyspeed; + return true; + } + else if (menupres[menutype].bghide && titlemapinaction) // hide the background + { + curbghide = true; + return true; + } + else if (!level) + { + if (M_GetYoungestChildMenu() == MN_SP_PLAYER || !defaultname || !defaultname[0]) + curbgcolor = 31; + else if (titlemapinaction) // hide the background by default in titlemap + curbghide = true; + else + { + strncpy(curbgname, defaultname, 8); + curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed; + curbgyspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollyspeed; + } + } + return false; +} + +static boolean MIT_ChangeMusic(UINT32 menutype, INT32 level, INT32 *retval, void **input, boolean fromoldest) +{ + menupresmusic_t *defaultmusic = (menupresmusic_t*)*input; + + (void)retval; + (void)fromoldest; + + if (menupres[menutype].musname[0]) + { + S_ChangeMusic(menupres[menutype].musname, menupres[menutype].mustrack, menupres[menutype].muslooping); + return true; + } + else if (menupres[menutype].musstop) + { + S_StopMusic(); + return true; + } + else if (menupres[menutype].musignore) + return true; + else if (!level && defaultmusic && defaultmusic->musname[0]) + S_ChangeMusic(defaultmusic->musname, defaultmusic->mustrack, defaultmusic->muslooping); + return false; +} + +static boolean MIT_SetCurFadeValue(UINT32 menutype, INT32 level, INT32 *retval, void **input, boolean fromoldest) +{ + UINT8 defaultvalue = *(UINT8*)*input; + + (void)retval; + (void)fromoldest; + + if (menupres[menutype].fadestrength >= 0) + { + curfadevalue = (menupres[menutype].fadestrength % 32); + return true; + } + else if (!level) + curfadevalue = (gamestate == GS_TIMEATTACK) ? 0 : (defaultvalue % 32); + return false; +} + +static boolean MIT_SetCurHideTitlePics(UINT32 menutype, INT32 level, INT32 *retval, void **input, boolean fromoldest) +{ + (void)input; + (void)retval; + (void)fromoldest; + + if (menupres[menutype].hidetitlepics >= 0) + { + curhidepics = menupres[menutype].hidetitlepics; + return true; + } + else if (!level) + curhidepics = hidetitlepics; + return false; +} + +// ==================================== +// TREE RETRIEVAL +// ==================================== + +UINT8 M_GetYoungestChildMenu(void) // aka the active menu +{ + INT32 targetlevel = -1; + return M_IterateMenuTree(MIT_GetMenuAtLevel, &targetlevel); +} + +// ==================================== +// EFFECTS +// ==================================== + +void M_ChangeMenuMusic(const char *defaultmusname, boolean defaultmuslooping) +{ + menupresmusic_t defaultmusic; + + if (!defaultmusname) + defaultmusname = ""; + + strncpy(defaultmusic.musname, defaultmusname, 7); + defaultmusic.musname[6] = 0; + defaultmusic.mustrack = 0; + defaultmusic.muslooping = defaultmuslooping; + + M_IterateMenuTree(MIT_ChangeMusic, &defaultmusic); +} + +void M_SetMenuCurBackground(const char *defaultname) +{ + char name[8]; + strncpy(name, defaultname, 8); + M_IterateMenuTree(MIT_SetCurBackground, &name); +} + +void M_SetMenuCurFadeValue(UINT8 defaultvalue) +{ + M_IterateMenuTree(MIT_SetCurFadeValue, &defaultvalue); +} + +void M_SetMenuCurHideTitlePics(void) +{ + M_IterateMenuTree(MIT_SetCurHideTitlePics, NULL); +} + +// ==================================== +// MENU STATE +// ==================================== + +static INT32 exitlevel, enterlevel, anceslevel; +static INT16 exittype, entertype; +static INT16 exitwipe, enterwipe; +static boolean exitbubble, enterbubble; +static INT16 exittag, entertag; + +static void M_HandleMenuPresState(menu_t *newMenu) +{ + INT32 i; + UINT32 bitmask; + SINT8 prevtype, activetype, menutype; + + if (!newMenu) + return; + + // Look for MN_SPECIAL here, because our iterators can't look at new menu IDs + for (i = 0; i <= NUMMENULEVELS; i++) + { + bitmask = ((1 << MENUBITS) - 1) << (MENUBITS*i); + menutype = (newMenu->menuid & bitmask) >> (MENUBITS*i); + prevtype = (currentMenu->menuid & bitmask) >> (MENUBITS*i); + if (menutype == MN_SPECIAL || prevtype == MN_SPECIAL) + return; + } + + if (currentMenu && newMenu && currentMenu->menuid == newMenu->menuid) // same menu? + return; + + exittype = entertype = exitlevel = enterlevel = anceslevel = exitwipe = enterwipe = -1; + exitbubble = enterbubble = true; + + prevMenuId = currentMenu ? currentMenu->menuid : 0; + activeMenuId = newMenu ? newMenu->menuid : 0; + + // Set defaults for presentation values + strncpy(curbgname, "TITLESKY", 8); + curfadevalue = 16; + curhidepics = hidetitlepics; + curbgcolor = -1; + curbgxspeed = titlescrollxspeed; + curbgyspeed = titlescrollyspeed; + curbghide = true; + + // don't do the below during the in-game menus + if (gamestate != GS_TITLESCREEN && gamestate != GS_TIMEATTACK) + return; + + // Find current presentation values + M_SetMenuCurBackground((gamestate == GS_TIMEATTACK) ? "SRB2BACK" : "TITLESKY"); + M_SetMenuCurFadeValue(16); + M_SetMenuCurHideTitlePics(); + + // Loop through both menu IDs in parallel and look for type changes + // The youngest child in activeMenuId is the entered menu + // The youngest child in prevMenuId is the exited menu + + // 0. Get the type and level of each menu, and level of common ancestor + // 1. Get the wipes for both, then run the exit wipe + // 2. Change music (so that execs can change it again later) + // 3. Run each exit exec on the prevMenuId up to the common ancestor (UNLESS NoBubbleExecs) + // 4. Run each entrance exec on the activeMenuId down from the common ancestor (UNLESS NoBubbleExecs) + // 5. Run the entrance wipe + + // Get the parameters for each menu + for (i = NUMMENULEVELS; i >= 0; i--) + { + bitmask = ((1 << MENUBITS) - 1) << (MENUBITS*i); + prevtype = (prevMenuId & bitmask) >> (MENUBITS*i); + activetype = (activeMenuId & bitmask) >> (MENUBITS*i); + + if (prevtype && (exittype < 0)) + { + exittype = prevtype; + exitlevel = i; + exitwipe = menupres[exittype].exitwipe; + exitbubble = menupres[exittype].exitbubble; + exittag = menupres[exittype].exittag; + } + + if (activetype && (entertype < 0)) + { + entertype = activetype; + enterlevel = i; + enterwipe = menupres[entertype].enterwipe; + enterbubble = menupres[entertype].enterbubble; + entertag = menupres[entertype].entertag; + } + + if (prevtype && activetype && prevtype == activetype && anceslevel < 0) + { + anceslevel = i; + break; + } + } + + // if no common ancestor (top menu), force a wipe. Look for a specified wipe first. + // Don't force a wipe if you're actually going to/from the main menu + if (anceslevel < 0 && exitwipe < 0 && newMenu != &MainDef && currentMenu != &MainDef) + { + for (i = NUMMENULEVELS; i >= 0; i--) + { + bitmask = ((1 << MENUBITS) - 1) << (MENUBITS*i); + prevtype = (prevMenuId & bitmask) >> (MENUBITS*i); + + if (menupres[prevtype].exitwipe >= 0) + { + exitwipe = menupres[prevtype].exitwipe; + break; + } + } + + if (exitwipe < 0) + exitwipe = menupres[MN_MAIN].exitwipe; + } + + // do the same for enter wipe + if (anceslevel < 0 && enterwipe < 0 && newMenu != &MainDef && currentMenu != &MainDef) + { + for (i = NUMMENULEVELS; i >= 0; i--) + { + bitmask = ((1 << MENUBITS) - 1) << (MENUBITS*i); + activetype = (activeMenuId & bitmask) >> (MENUBITS*i); + + if (menupres[activetype].enterwipe >= 0) + { + exitwipe = menupres[activetype].enterwipe; + break; + } + } + + if (enterwipe < 0) + enterwipe = menupres[MN_MAIN].enterwipe; + } + + // Change the music + M_ChangeMenuMusic("_title", false); + + // Run the linedef execs + if (titlemapinaction) + { + // Run the exit tags + if (enterlevel <= exitlevel) // equals is an edge case + { + if (exitbubble) + { + for (i = exitlevel; i > anceslevel; i--) // don't run the common ancestor's exit tag + { + bitmask = ((1 << MENUBITS) - 1) << (MENUBITS*i); + menutype = (prevMenuId & bitmask) >> (MENUBITS*i); + if (menupres[menutype].exittag) + P_LinedefExecute(menupres[menutype].exittag, players[displayplayer].mo, NULL); + } + } + else if (exittag) + P_LinedefExecute(exittag, players[displayplayer].mo, NULL); + } + + // Run the enter tags + if (enterlevel >= exitlevel) // equals is an edge case + { + if (enterbubble) + { + for (i = anceslevel+1; i <= enterlevel; i++) // don't run the common ancestor's enter tag + { + bitmask = ((1 << MENUBITS) - 1) << (MENUBITS*i); + menutype = (activeMenuId & bitmask) >> (MENUBITS*i); + if (menupres[menutype].entertag) + P_LinedefExecute(menupres[menutype].entertag, players[displayplayer].mo, NULL); + } + } + else if (entertag) + P_LinedefExecute(entertag, players[displayplayer].mo, NULL); + } + } + + + // Set the wipes for next frame + if ( + (exitwipe >= 0 && enterlevel <= exitlevel) || + (enterwipe >= 0 && enterlevel >= exitlevel) || + (anceslevel < 0 && newMenu != &MainDef && currentMenu != &MainDef) + ) + { + if (gamestate == GS_TIMEATTACK) + wipetypepre = ((exitwipe && enterlevel <= exitlevel) || anceslevel < 0) ? exitwipe : -1; // force default + else + // HACK: INT16_MAX signals to not wipe + // because 0 is a valid index and -1 means default + wipetypepre = ((exitwipe && enterlevel <= exitlevel) || anceslevel < 0) ? exitwipe : INT16_MAX; + wipetypepost = ((enterwipe && enterlevel >= exitlevel) || anceslevel < 0) ? enterwipe : INT16_MAX; + wipegamestate = FORCEWIPE; + + // If just one of the above is a force not-wipe, + // mirror the other wipe. + if (wipetypepre != INT16_MAX && wipetypepost == INT16_MAX) + wipetypepost = wipetypepre; + else if (wipetypepost != INT16_MAX && wipetypepre == INT16_MAX) + wipetypepre = wipetypepost; + + // D_Display runs the next step of processing + } +} + +// ========================================================================= +// BASIC MENU HANDLING +// ========================================================================= + +static void M_GoBack(INT32 choice) +{ + (void)choice; + + if (currentMenu->prevMenu) + { + //If we entered the game search menu, but didn't enter a game, + //make sure the game doesn't still think we're in a netgame. + if (!Playing() && netgame && multiplayer) + { + MSCloseUDPSocket(); // Clean up so we can re-open the connection later. + netgame = multiplayer = false; + } + + if ((currentMenu->prevMenu == &MainDef) && (currentMenu == &SP_TimeAttackDef || currentMenu == &SP_NightsAttackDef)) + { + // D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate. + + if (levelselect.rows) + { + Z_Free(levelselect.rows); + levelselect.rows = NULL; + } + + menuactive = false; + wipetypepre = menupres[M_GetYoungestChildMenu()].exitwipe; + D_StartTitle(); + } + else + M_SetupNextMenu(currentMenu->prevMenu); + } + else + M_ClearMenus(true); +} + +static void M_ChangeCvar(INT32 choice) +{ + consvar_t *cv = (consvar_t *)currentMenu->menuitems[itemOn].itemaction; + + if (choice == -1) + { + if (cv == &cv_playercolor) + { + SINT8 skinno = R_SkinAvailable(cv_chooseskin.string); + if (skinno != -1) + CV_SetValue(cv,skins[skinno].prefcolor); + return; + } + CV_Set(cv,cv->defaultvalue); + return; + } + + choice = (choice<<1) - 1; + + if (((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_SLIDER) + ||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_INVISSLIDER) + ||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_NOMOD)) + { + CV_SetValue(cv,cv->value+(choice)); } else if (cv->flags & CV_FLOAT) { char s[20]; - sprintf(s,"%f",FIXED_TO_FLOAT(cv->value)+(choice*2-1)*(1.0f/16.0f)); + sprintf(s,"%f",FIXED_TO_FLOAT(cv->value)+(choice)*(1.0f/16.0f)); CV_Set(cv,s); } else - CV_AddValue(cv,choice*2-1); + CV_AddValue(cv,choice); } static boolean M_ChangeStringCvar(INT32 choice) { consvar_t *cv = (consvar_t *)currentMenu->menuitems[itemOn].itemaction; - char buf[255]; + char buf[MAXSTRINGLENGTH]; size_t len; + if (shiftdown && choice >= 32 && choice <= 127) + choice = shiftxform[choice]; + switch (choice) { case KEY_BACKSPACE: @@ -2038,10 +2743,22 @@ static boolean M_ChangeStringCvar(INT32 choice) return false; } +// resets all cvars on a menu - assumes that all that have itemactions are cvars +static void M_ResetCvars(void) +{ + INT32 i; + consvar_t *cv; + for (i = 0; i < currentMenu->numitems; i++) + { + if (!(currentMenu->menuitems[i].status & IT_CVAR) || !(cv = (consvar_t *)currentMenu->menuitems[i].itemaction)) + continue; + CV_SetValue(cv, atoi(cv->defaultvalue)); + } +} + static void M_NextOpt(void) { INT16 oldItemOn = itemOn; // prevent infinite loop - do { if (itemOn + 1 > currentMenu->numitems - 1) @@ -2054,7 +2771,6 @@ static void M_NextOpt(void) static void M_PrevOpt(void) { INT16 oldItemOn = itemOn; // prevent infinite loop - do { if (!itemOn) @@ -2241,7 +2957,6 @@ boolean M_Responder(event_t *ev) itemOn = 0; return true; -#ifndef DC case KEY_F5: // Video Mode if (modeattacking) return true; @@ -2249,7 +2964,6 @@ boolean M_Responder(event_t *ev) M_Options(0); M_VideoModeMenu(0); return true; -#endif case KEY_F6: // Empty return true; @@ -2270,7 +2984,7 @@ boolean M_Responder(event_t *ev) return true; case KEY_F11: // Gamma Level - CV_AddValue(&cv_usegamma, 1); + CV_AddValue(&cv_globalgamma, 1); return true; // Spymode on F12 handled in game logic @@ -2334,8 +3048,6 @@ boolean M_Responder(event_t *ev) { if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING) { - if (shiftdown && ch >= 32 && ch <= 127) - ch = shiftxform[ch]; if (M_ChangeStringCvar(ch)) return true; else @@ -2351,29 +3063,18 @@ boolean M_Responder(event_t *ev) case KEY_DOWNARROW: M_NextOpt(); S_StartSound(NULL, sfx_menu1); - if (currentMenu == &SP_PlayerDef) - { - Z_Free(char_notes); - char_notes = NULL; - } return true; case KEY_UPARROW: M_PrevOpt(); S_StartSound(NULL, sfx_menu1); - if (currentMenu == &SP_PlayerDef) - { - Z_Free(char_notes); - char_notes = NULL; - } return true; case KEY_LEFTARROW: if (routine && ((currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_ARROWS || (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)) { - if (currentMenu != &OP_SoundOptionsDef) - S_StartSound(NULL, sfx_menu1); + S_StartSound(NULL, sfx_menu1); routine(0); } return true; @@ -2382,8 +3083,7 @@ boolean M_Responder(event_t *ev) if (routine && ((currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_ARROWS || (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)) { - if (currentMenu != &OP_SoundOptionsDef) - S_StartSound(NULL, sfx_menu1); + S_StartSound(NULL, sfx_menu1); routine(1); } return true; @@ -2399,7 +3099,7 @@ boolean M_Responder(event_t *ev) { if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && modifiedgame && !savemoddata) { - S_StartSound(NULL, sfx_menu1); + 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); return true; } @@ -2425,28 +3125,8 @@ boolean M_Responder(event_t *ev) case KEY_ESCAPE: noFurtherInput = true; currentMenu->lastOn = itemOn; - if (currentMenu->prevMenu) - { - //If we entered the game search menu, but didn't enter a game, - //make sure the game doesn't still think we're in a netgame. - if (!Playing() && netgame && multiplayer) - { - MSCloseUDPSocket(); // Clean up so we can re-open the connection later. - netgame = false; - multiplayer = false; - } - if (currentMenu == &SP_TimeAttackDef || currentMenu == &SP_NightsAttackDef) - { - // D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate. - menuactive = false; - D_StartTitle(); - } - else - M_SetupNextMenu(currentMenu->prevMenu); - } - else - M_ClearMenus(true); + M_GoBack(0); return true; @@ -2455,9 +3135,27 @@ boolean M_Responder(event_t *ev) { // detach any keys associated with the game control G_ClearControlKeys(setupcontrols, currentMenu->menuitems[itemOn].alphaKey); + S_StartSound(NULL, sfx_shldls); return true; } - // Why _does_ backspace go back anyway? + + if (routine && ((currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_ARROWS + || (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)) + { + consvar_t *cv = (consvar_t *)currentMenu->menuitems[itemOn].itemaction; + + if (cv == &cv_chooseskin + || cv == &cv_nextmap + || cv == &cv_newgametype) + return true; + + if (currentMenu != &OP_SoundOptionsDef || itemOn > 3) + S_StartSound(NULL, sfx_menu1); + routine(-1); + return true; + } + + // Why _does_ backspace go back anyway? //currentMenu->lastOn = itemOn; //if (currentMenu->prevMenu) // M_SetupNextMenu(currentMenu->prevMenu); @@ -2483,8 +3181,8 @@ void M_Drawer(void) if (menuactive) { // now that's more readable with a faded background (yeah like Quake...) - if (!WipeInAction) - V_DrawFadeScreen(); + if (!WipeInAction && (curfadevalue || (gamestate != GS_TITLESCREEN && gamestate != GS_TIMEATTACK))) + V_DrawFadeScreen(0xFF00, (gamestate != GS_TITLESCREEN && gamestate != GS_TIMEATTACK) ? 16 : curfadevalue); if (currentMenu->drawroutine) currentMenu->drawroutine(); // call current menu Draw routine @@ -2620,10 +3318,14 @@ void M_StartControlPanel(void) } if (splitscreen) + { MPauseMenu[mpause_psetupsplit].status = MPauseMenu[mpause_psetupsplit2].status = IT_STRING | IT_CALL; + MPauseMenu[mpause_psetup].text = "Player 1 Setup"; + } else { MPauseMenu[mpause_psetup].status = IT_STRING | IT_CALL; + MPauseMenu[mpause_psetup].text = "Player Setup"; if (G_GametypeHasTeams()) MPauseMenu[mpause_switchteam].status = IT_STRING | IT_SUBMENU; @@ -2656,9 +3358,8 @@ void M_ClearMenus(boolean callexitmenufunc) if (currentMenu->quitroutine && callexitmenufunc && !currentMenu->quitroutine()) return; // we can't quit this menu (also used to set parameter from the menu) -#ifndef DC // Save the config file. I'm sick of crashing the game later and losing all my changes! + // Save the config file. I'm sick of crashing the game later and losing all my changes! COM_BufAddText(va("saveconfig \"%s\" -silent\n", configfile)); -#endif //Alam: But not on the Dreamcast's VMUs if (currentMenu == &MessageDef) // Oh sod off! currentMenu = &MainDef; // Not like it matters @@ -2678,6 +3379,9 @@ void M_SetupNextMenu(menu_t *menudef) if (currentMenu != menudef && !currentMenu->quitroutine()) return; // we can't quit this menu (also used to set parameter from the menu) } + + M_HandleMenuPresState(menudef); + currentMenu = menudef; itemOn = currentMenu->lastOn; @@ -2772,63 +3476,28 @@ void M_Init(void) #ifdef HWRENDER // Permanently hide some options based on render mode if (rendermode == render_soft) - OP_VideoOptionsMenu[1].status = IT_DISABLED; + OP_VideoOptionsMenu[4].status = IT_DISABLED; + else if (rendermode == render_opengl) + OP_ScreenshotOptionsMenu[op_screenshot_colorprofile].status = IT_GRAYEDOUT; #endif #ifndef NONET CV_RegisterVar(&cv_serversort); #endif - - //todo put this somewhere better... - CV_RegisterVar(&cv_allcaps); } void M_InitCharacterTables(void) { UINT8 i; - // Setup PlayerMenu table - for (i = 0; i < MAXSKINS; i++) - { - PlayerMenu[i].status = (i < 4 ? IT_CALL : IT_DISABLED); - PlayerMenu[i].patch = PlayerMenu[i].text = NULL; - PlayerMenu[i].itemaction = M_ChoosePlayer; - PlayerMenu[i].alphaKey = 0; - } - // Setup description table for (i = 0; i < MAXSKINS; i++) { - if (i == 0) - { - strcpy(description[i].notes, "\x82Sonic\x80 is the fastest of the three, but also the hardest to control. Beginners beware, but experts will find Sonic very powerful.\n\n\x82""Ability:\x80 Speed Thok\nDouble jump to zoom forward with a huge burst of speed.\n\n\x82Tip:\x80 Simply letting go of forward does not slow down in SRB2. To slow down, hold the opposite direction."); - strcpy(description[i].picname, ""); - strcpy(description[i].skinname, "sonic"); - } - else if (i == 1) - { - strcpy(description[i].notes, "\x82Tails\x80 is the most mobile of the three, but has the slowest speed. Because of his mobility, he's well-\nsuited to beginners.\n\n\x82""Ability:\x80 Fly\nDouble jump to start flying for a limited time. Repetitively hit the jump button to ascend.\n\n\x82Tip:\x80 To quickly descend while flying, hit the spin button."); - strcpy(description[i].picname, ""); - strcpy(description[i].skinname, "tails"); - } - else if (i == 2) - { - strcpy(description[i].notes, "\x82Knuckles\x80 is well-\nrounded and can destroy breakable walls simply by touching them, but he can't jump as high as the other two.\n\n\x82""Ability:\x80 Glide & Climb\nDouble jump to glide in the air as long as jump is held. Glide into a wall to climb it.\n\n\x82Tip:\x80 Press spin while climbing to jump off the wall; press jump instead to jump off\nand face away from\nthe wall."); - strcpy(description[i].picname, ""); - strcpy(description[i].skinname, "knuckles"); - } - else if (i == 3) - { - strcpy(description[i].notes, "\x82Sonic & Tails\x80 team up to take on Dr. Eggman!\nControl Sonic while Tails desperately struggles to keep up.\n\nPlayer 2 can control Tails directly by setting the controls in the options menu.\nTails's directional controls are relative to Player 1's camera.\n\nTails can pick up Sonic while flying and carry him around."); - strcpy(description[i].picname, "CHRS&T"); - strcpy(description[i].skinname, "sonic&tails"); - } - else - { - strcpy(description[i].notes, "???"); - strcpy(description[i].picname, ""); - strcpy(description[i].skinname, ""); - } + description[i].used = false; + strcpy(description[i].notes, "???"); + strcpy(description[i].picname, ""); + strcpy(description[i].skinname, ""); + description[i].prev = description[i].next = 0; } } @@ -2888,36 +3557,58 @@ static void M_DrawThermo(INT32 x, INT32 y, consvar_t *cv) } // A smaller 'Thermo', with range given as percents (0-100) -static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv) +static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv, boolean ontop) { INT32 i; INT32 range; patch_t *p; - for (i = 0; cv->PossibleValue[i+1].strvalue; i++); - - range = ((cv->value - cv->PossibleValue[0].value) * 100 / - (cv->PossibleValue[i].value - cv->PossibleValue[0].value)); - - if (range < 0) - range = 0; - if (range > 100) - range = 100; - x = BASEVIDWIDTH - x - SLIDER_WIDTH; - V_DrawScaledPatch(x - 8, y, 0, W_CachePatchName("M_SLIDEL", PU_CACHE)); + V_DrawScaledPatch(x, y, 0, W_CachePatchName("M_SLIDEL", PU_CACHE)); p = W_CachePatchName("M_SLIDEM", PU_CACHE); - for (i = 0; i < SLIDER_RANGE; i++) + for (i = 1; i < SLIDER_RANGE; i++) V_DrawScaledPatch (x+i*8, y, 0,p); + if (ontop) + { + V_DrawCharacter(x - 6 - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(x+i*8 + 8 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } + p = W_CachePatchName("M_SLIDER", PU_CACHE); - V_DrawScaledPatch(x+SLIDER_RANGE*8, y, 0, p); + V_DrawScaledPatch(x+i*8, y, 0, p); // draw the slider cursor p = W_CachePatchName("M_SLIDEC", PU_CACHE); - V_DrawMappedPatch(x + ((SLIDER_RANGE-1)*8*range)/100, y, 0, p, yellowmap); + + for (i = 0; cv->PossibleValue[i+1].strvalue; i++); + + if ((range = atoi(cv->defaultvalue)) != cv->value) + { + range = ((range - cv->PossibleValue[0].value) * 100 / + (cv->PossibleValue[i].value - cv->PossibleValue[0].value)); + + if (range < 0) + range = 0; + else if (range > 100) + range = 100; + + V_DrawMappedPatch(x + 2 + (SLIDER_RANGE*8*range)/100, y, V_TRANSLUCENT, p, yellowmap); + } + + range = ((cv->value - cv->PossibleValue[0].value) * 100 / + (cv->PossibleValue[i].value - cv->PossibleValue[0].value)); + + if (range < 0) + range = 0; + else if (range > 100) + range = 100; + + V_DrawMappedPatch(x + 2 + (SLIDER_RANGE*8*range)/100, y, 0, p, yellowmap); } // @@ -2927,7 +3618,7 @@ static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv) void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines) { // Solid color textbox. - V_DrawFill(x+5, y+5, width*8+6, boxlines*8+6, 239); + V_DrawFill(x+5, y+5, width*8+6, boxlines*8+6, 159); //V_DrawFill(x+8, y+8, width*8, boxlines*8, 31); /* patch_t *p; @@ -2977,9 +3668,38 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines) */ } +static fixed_t staticalong = 0; + +static void M_DrawStaticBox(fixed_t x, fixed_t y, INT32 flags, fixed_t w, fixed_t h) +{ + patch_t *patch; + fixed_t sw, pw; + + patch = W_CachePatchName("LSSTATIC", PU_CACHE); + pw = SHORT(patch->width) - (sw = w*2); //FixedDiv(w, scale); -- for scale FRACUNIT/2 + + /*if (pw > 0) -- model code for modders providing weird LSSTATIC + { + if (staticalong > pw) + staticalong -= pw; + } + else + staticalong = 0;*/ + + if (staticalong > pw) // simplified for base LSSTATIC + staticalong -= pw; + + V_DrawCroppedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT/2, flags, patch, staticalong, 0, sw, h*2); // FixedDiv(h, scale)); -- for scale FRACUNIT/2 + + staticalong += sw; //M_RandomRange(sw/2, 2*sw); -- turns out less randomisation looks better because immediately adjacent frames can't end up close to each other + + W_UnlockCachedPatch(patch); +} + // // Draw border for the savegame description // +#if 0 // once used for joysticks and savegames, now no longer static void M_DrawSaveLoadBorder(INT32 x,INT32 y) { INT32 i; @@ -2994,6 +3714,7 @@ static void M_DrawSaveLoadBorder(INT32 x,INT32 y) V_DrawScaledPatch (x,y+7,0,W_CachePatchName("M_LSRGHT",PU_CACHE)); } +#endif // horizontally centered text static void M_CentreText(INT32 y, const char *string) @@ -3022,6 +3743,8 @@ static void M_DrawMapEmblems(INT32 mapnum, INT32 x, INT32 y) curtype = 1; break; case ET_NGRADE: case ET_NTIME: curtype = 2; break; + case ET_MAP: + curtype = 3; break; default: curtype = 0; break; } @@ -3136,7 +3859,7 @@ static void M_DrawGenericMenu(void) switch (currentMenu->menuitems[i].status & IT_CVARTYPE) { case IT_CV_SLIDER: - M_DrawSlider(x, y, cv); + M_DrawSlider(x, y, cv, (i == itemOn)); case IT_CV_NOPRINT: // color use this case IT_CV_INVISSLIDER: // monitor toggles use this break; @@ -3149,8 +3872,15 @@ static void M_DrawGenericMenu(void) y += 16; break; default: - V_DrawString(BASEVIDWIDTH - x - V_StringWidth(cv->string, 0), y, + V_DrawRightAlignedString(BASEVIDWIDTH - x, y, ((cv->flags & CV_CHEAT) && !CV_IsSetToDefault(cv) ? V_REDMAP : V_YELLOWMAP), cv->string); + if (i == itemOn) + { + V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } break; } break; @@ -3188,7 +3918,8 @@ static void M_DrawGenericMenu(void) if (currentMenu->menuitems[i].alphaKey) y = currentMenu->y+currentMenu->menuitems[i].alphaKey; - V_DrawString(x-16, y, V_YELLOWMAP, currentMenu->menuitems[i].text); + //V_DrawString(x-16, y, V_YELLOWMAP, currentMenu->menuitems[i].text); + M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), currentMenu->menuitems[i].text, true, false); y += SMALLLINEHEIGHT; break; } @@ -3209,6 +3940,142 @@ static void M_DrawGenericMenu(void) } } +#define scrollareaheight 72 + +// note that alphakey is multiplied by 2 for scrolling menus to allow greater usage in UINT8 range. +static void M_DrawGenericScrollMenu(void) +{ + INT32 x, y, i, max, bottom, tempcentery, cursory = 0; + + // DRAW MENU + x = currentMenu->x; + y = currentMenu->y; + + if ((currentMenu->menuitems[itemOn].alphaKey*2 - currentMenu->menuitems[0].alphaKey*2) <= scrollareaheight) + tempcentery = currentMenu->y - currentMenu->menuitems[0].alphaKey*2; + else if ((currentMenu->menuitems[currentMenu->numitems-1].alphaKey*2 - currentMenu->menuitems[itemOn].alphaKey*2) <= scrollareaheight) + tempcentery = currentMenu->y - currentMenu->menuitems[currentMenu->numitems-1].alphaKey*2 + 2*scrollareaheight; + else + tempcentery = currentMenu->y - currentMenu->menuitems[itemOn].alphaKey*2 + scrollareaheight; + + for (i = 0; i < currentMenu->numitems; i++) + { + if (currentMenu->menuitems[i].status != IT_DISABLED && currentMenu->menuitems[i].alphaKey*2 + tempcentery >= currentMenu->y) + break; + } + + for (bottom = currentMenu->numitems; bottom > 0; bottom--) + { + if (currentMenu->menuitems[bottom-1].status != IT_DISABLED) + break; + } + + for (max = bottom; max > 0; max--) + { + if (currentMenu->menuitems[max-1].status != IT_DISABLED && currentMenu->menuitems[max-1].alphaKey*2 + tempcentery <= (currentMenu->y + 2*scrollareaheight)) + break; + } + + if (i) + V_DrawString(currentMenu->x - 20, currentMenu->y - (skullAnimCounter/5), V_YELLOWMAP, "\x1A"); // up arrow + if (max != bottom) + V_DrawString(currentMenu->x - 20, currentMenu->y + 2*scrollareaheight + (skullAnimCounter/5), V_YELLOWMAP, "\x1B"); // down arrow + + // draw title (or big pic) + M_DrawMenuTitle(); + + for (; i < max; i++) + { + y = currentMenu->menuitems[i].alphaKey*2 + tempcentery; + if (i == itemOn) + cursory = y; + switch (currentMenu->menuitems[i].status & IT_DISPLAY) + { + case IT_PATCH: + case IT_DYBIGSPACE: + case IT_BIGSLIDER: + case IT_STRING2: + case IT_DYLITLSPACE: + case IT_GRAYPATCH: + case IT_TRANSTEXT2: + // unsupported + break; + case IT_NOTHING: + break; + case IT_STRING: + case IT_WHITESTRING: + if (i != itemOn && (currentMenu->menuitems[i].status & IT_DISPLAY)==IT_STRING) + V_DrawString(x, y, 0, currentMenu->menuitems[i].text); + else + V_DrawString(x, y, V_YELLOWMAP, currentMenu->menuitems[i].text); + + // Cvar specific handling + switch (currentMenu->menuitems[i].status & IT_TYPE) + case IT_CVAR: + { + consvar_t *cv = (consvar_t *)currentMenu->menuitems[i].itemaction; + switch (currentMenu->menuitems[i].status & IT_CVARTYPE) + { + case IT_CV_SLIDER: + M_DrawSlider(x, y, cv, (i == itemOn)); + case IT_CV_NOPRINT: // color use this + case IT_CV_INVISSLIDER: // monitor toggles use this + break; + case IT_CV_STRING: +#if 1 + if (y + 12 > (currentMenu->y + 2*scrollareaheight)) + break; + M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1); + V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string); + if (skullAnimCounter < 4 && i == itemOn) + V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12, + '_' | 0x80, false); +#else // cool new string type stuff, not ready for limelight + if (i == itemOn) + { + V_DrawFill(x-2, y-1, MAXSTRINGLENGTH*8 + 4, 8+3, 159); + V_DrawString(x, y, V_ALLOWLOWERCASE, cv->string); + if (skullAnimCounter < 4) + V_DrawCharacter(x + V_StringWidth(cv->string, 0), y, '_' | 0x80, false); + } + else + V_DrawRightAlignedString(BASEVIDWIDTH - x, y, + V_YELLOWMAP|V_ALLOWLOWERCASE, cv->string); +#endif + break; + default: + V_DrawRightAlignedString(BASEVIDWIDTH - x, y, + ((cv->flags & CV_CHEAT) && !CV_IsSetToDefault(cv) ? V_REDMAP : V_YELLOWMAP), cv->string); + if (i == itemOn) + { + V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } + break; + } + break; + } + break; + case IT_TRANSTEXT: + V_DrawString(x, y, V_TRANSLUCENT, currentMenu->menuitems[i].text); + break; + case IT_QUESTIONMARKS: + V_DrawString(x, y, V_TRANSLUCENT|V_OLDSPACING, M_CreateSecretMenuOption(currentMenu->menuitems[i].text)); + break; + case IT_HEADERTEXT: + //V_DrawString(x-16, y, V_YELLOWMAP, currentMenu->menuitems[i].text); + M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), currentMenu->menuitems[i].text, true, false); + break; + } + } + + // DRAW THE SKULL CURSOR + V_DrawScaledPatch(currentMenu->x - 24, cursory, 0, + W_CachePatchName("M_CURSOR", PU_CACHE)); +} + static void M_DrawPauseMenu(void) { if (!netgame && !multiplayer && (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION)) @@ -3414,7 +4281,7 @@ static void M_DrawCenteredMenu(void) switch(currentMenu->menuitems[i].status & IT_CVARTYPE) { case IT_CV_SLIDER: - M_DrawSlider(x, y, cv); + M_DrawSlider(x, y, cv, (i == itemOn)); case IT_CV_NOPRINT: // color use this break; case IT_CV_STRING: @@ -3428,6 +4295,13 @@ static void M_DrawCenteredMenu(void) default: V_DrawString(BASEVIDWIDTH - x - V_StringWidth(cv->string, 0), y, ((cv->flags & CV_CHEAT) && !CV_IsSetToDefault(cv) ? V_REDMAP : V_YELLOWMAP), cv->string); + if (i == itemOn) + { + V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } break; } break; @@ -3504,9 +4378,9 @@ static void M_PatchSkinNameTable(void) for (j = 0; j < MAXSKINS; j++) { - if (skins[j].name[0] != '\0') + if (skins[j].name[0] != '\0' && R_SkinUsable(-1, j)) { - skins_cons_t[j].strvalue = skins[j].name; + skins_cons_t[j].strvalue = skins[j].realname; skins_cons_t[j].value = j+1; } else @@ -3516,31 +4390,60 @@ static void M_PatchSkinNameTable(void) } } - CV_SetValue(&cv_chooseskin, cv_chooseskin.value); // This causes crash sometimes?! - CV_SetValue(&cv_chooseskin, 1); - CV_AddValue(&cv_chooseskin, -1); - CV_AddValue(&cv_chooseskin, 1); + Nextmap_OnChange(); return; } -// Call before showing any level-select menus -static void M_PrepareLevelSelect(void) +// +// M_LevelAvailableOnPlatter +// +// Okay, you know that the level SHOULD show up on the platter already. +// The only question is whether it should be as a question mark, +// (hinting as to its existence), or as its pure, unfettered self. +// +static boolean M_LevelAvailableOnPlatter(INT32 mapnum) { - if (levellistmode != LLM_CREATESERVER) - CV_SetValue(&cv_nextmap, M_GetFirstLevelInList()); - else - Newgametype_OnChange(); // Make sure to start on an appropriate map if wads have been added + if (M_MapLocked(mapnum+1)) + return false; // not unlocked + + switch (levellistmode) + { + case LLM_CREATESERVER: + if (!(mapheaderinfo[mapnum]->typeoflevel & TOL_COOP)) + return true; + + if (mapvisited[mapnum]) // MV_MP + return true; + + if (mapnum+1 == spstage_start) + return true; + + /* FALLTHRU */ + case LLM_RECORDATTACK: + case LLM_NIGHTSATTACK: + if (mapvisited[mapnum] & MV_MAX) + return true; + + if (mapheaderinfo[mapnum]->menuflags & LF2_NOVISITNEEDED) + return true; + + return false; + case LLM_LEVELSELECT: + default: + return true; + } + return true; } // -// M_CanShowLevelInList +// M_CanShowLevelOnPlatter // // Determines whether to show a given map in the various level-select lists. // Set gt = -1 to ignore gametype. // -boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt) +static boolean M_CanShowLevelOnPlatter(INT32 mapnum, INT32 gt) { // Does the map exist? if (!mapheaderinfo[mapnum]) @@ -3550,6 +4453,9 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt) if (!mapheaderinfo[mapnum]->lvlttl[0]) return false; + /*if (M_MapLocked(mapnum+1)) + return false; // not unlocked*/ + switch (levellistmode) { case LLM_CREATESERVER: @@ -3557,9 +4463,6 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt) if (mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU) return false; - if (M_MapLocked(mapnum+1)) - return false; // not unlocked - if (gt == GT_COOP && (mapheaderinfo[mapnum]->typeoflevel & TOL_COOP)) return true; @@ -3581,40 +4484,19 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt) return false; case LLM_LEVELSELECT: - if (mapheaderinfo[mapnum]->levelselect != maplistoption) + if (!(mapheaderinfo[mapnum]->levelselect & maplistoption)) return false; - if (M_MapLocked(mapnum+1)) - return false; // not unlocked - return true; case LLM_RECORDATTACK: if (!(mapheaderinfo[mapnum]->menuflags & LF2_RECORDATTACK)) return false; - if (M_MapLocked(mapnum+1)) - return false; // not unlocked - - if (mapheaderinfo[mapnum]->menuflags & LF2_NOVISITNEEDED) - return true; - - if (!mapvisited[mapnum]) - return false; - return true; case LLM_NIGHTSATTACK: if (!(mapheaderinfo[mapnum]->menuflags & LF2_NIGHTSATTACK)) return false; - if (M_MapLocked(mapnum+1)) - return false; // not unlocked - - if (mapheaderinfo[mapnum]->menuflags & LF2_NOVISITNEEDED) - return true; - - if (!mapvisited[mapnum]) - return false; - return true; } @@ -3622,42 +4504,627 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt) return false; } -static INT32 M_CountLevelsToShowInList(void) +#if 0 +static INT32 M_CountLevelsToShowOnPlatter(INT32 gt) { INT32 mapnum, count = 0; for (mapnum = 0; mapnum < NUMMAPS; mapnum++) - if (M_CanShowLevelInList(mapnum, -1)) + if (M_CanShowLevelOnPlatter(mapnum, gt)) count++; return count; } +#endif -static INT32 M_GetFirstLevelInList(void) +#if 0 +static boolean M_SetNextMapOnPlatter(void) { - INT32 mapnum; + INT32 row, col = 0; + while (col < 3) + { + row = 0; + while (row < levelselect.numrows) + { + if (levelselect.rows[row].maplist[col] == cv_nextmap.value) + { + lsrow = row; + lscol = col; + return true; + } + row++; + } + col++; + } + return true; +} +#endif - for (mapnum = 0; mapnum < NUMMAPS; mapnum++) - if (M_CanShowLevelInList(mapnum, -1)) - return mapnum + 1; +static INT32 M_CountRowsToShowOnPlatter(INT32 gt) +{ + INT32 mapnum = 0, prevmapnum = 0, col = 0, rows = 0; - return 1; -} + while (mapnum < NUMMAPS) + { + if (M_CanShowLevelOnPlatter(mapnum, gt)) + { + if (rows == 0) + rows++; + else + { + if (col == 2 + || (mapheaderinfo[prevmapnum]->menuflags & LF2_WIDEICON) + || (mapheaderinfo[mapnum]->menuflags & LF2_WIDEICON) + || !(fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[prevmapnum]->selectheading))) + { + col = 0; + rows++; + } + else + col++; + } + prevmapnum = mapnum; + } + mapnum++; + } -// ================================================== -// MESSAGE BOX (aka: a hacked, cobbled together menu) -// ================================================== -static void M_DrawMessageMenu(void); + if (levellistmode == LLM_CREATESERVER) + rows++; -// Because this is just a hack-ish 'menu', I'm not putting this with the others -static menuitem_t MessageMenu[] = -{ - // TO HACK - {0,NULL, NULL, NULL,0} -}; + return rows; +} + +// +// M_PrepareLevelPlatter +// +// Prepares a tasty dish of zones and acts! +// Call before any attempt to access a level platter. +// +static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) +{ + INT32 numrows = M_CountRowsToShowOnPlatter(gt); + INT32 mapnum = 0, prevmapnum = 0, col = 0, row = 0, startrow = 0; + + if (!numrows) + return false; + + if (levelselect.rows) + Z_Free(levelselect.rows); + levelselect.rows = NULL; + + levelselect.numrows = numrows; + levelselect.rows = Z_Realloc(levelselect.rows, numrows*sizeof(levelselectrow_t), PU_STATIC, NULL); + if (!levelselect.rows) + I_Error("Insufficient memory to prepare level platter"); + + // done here so lsrow and lscol can be set if cv_nextmap is on the platter + lsrow = lscol = lshli = lsoffs[0] = lsoffs[1] = 0; + + if (levellistmode == LLM_CREATESERVER) + { + sprintf(levelselect.rows[0].header, "Gametype"); + lswide(0) = true; + levelselect.rows[row].mapavailable[2] = levelselect.rows[row].mapavailable[1] = levelselect.rows[row].mapavailable[0] = false; + startrow = row = 1; + + Z_Free(char_notes); + char_notes = NULL; + } + + while (mapnum < NUMMAPS) + { + if (M_CanShowLevelOnPlatter(mapnum, gt)) + { + const INT32 actnum = mapheaderinfo[mapnum]->actnum; + const boolean headingisname = (fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[mapnum]->lvlttl)); + const boolean wide = (mapheaderinfo[mapnum]->menuflags & LF2_WIDEICON); + + // preparing next position to drop mapnum into + if (levelselect.rows[startrow].maplist[0]) + { + if (col == 2 // no more space on the row? + || wide + || (mapheaderinfo[prevmapnum]->menuflags & LF2_WIDEICON) + || !(fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[prevmapnum]->selectheading))) // a new heading is starting? + { + col = 0; + row++; + } + else + col++; + } + + levelselect.rows[row].maplist[col] = mapnum+1; // putting the map on the platter + levelselect.rows[row].mapavailable[col] = M_LevelAvailableOnPlatter(mapnum); + + if ((lswide(row) = wide)) // intentionally assignment + { + levelselect.rows[row].maplist[2] = levelselect.rows[row].maplist[1] = levelselect.rows[row].maplist[0]; + levelselect.rows[row].mapavailable[2] = levelselect.rows[row].mapavailable[1] = levelselect.rows[row].mapavailable[0]; + } + + if (nextmappick && cv_nextmap.value == mapnum+1) // A little quality of life improvement. + { + lsrow = row; + lscol = col; + } + + // individual map name + if (levelselect.rows[row].mapavailable[col]) + { + if (headingisname) + { + if (actnum) + sprintf(levelselect.rows[row].mapnames[col], "ACT %d", actnum); + else + sprintf(levelselect.rows[row].mapnames[col], "THE ACT"); + } + else if (wide) + { + // Yes, with LF2_WIDEICON it'll continue on over into the next 17+1 char block. That's alright; col is always zero, the string is contiguous, and the maximum length is lvlttl[22] + ' ' + ZONE + ' ' + INT32, which is about 39 or so - barely crossing into the third column. + char* mapname = G_BuildMapTitle(mapnum+1); + strcpy(levelselect.rows[row].mapnames[col], (const char *)mapname); + Z_Free(mapname); + } + else + { + char mapname[22+1+11]; // lvlttl[22] + ' ' + INT32 + + if (actnum) + sprintf(mapname, "%s %d", mapheaderinfo[mapnum]->lvlttl, actnum); + else + strcpy(mapname, mapheaderinfo[mapnum]->lvlttl); + + if (strlen(mapname) >= 17) + strcpy(mapname+17-3, "..."); + + strcpy(levelselect.rows[row].mapnames[col], (const char *)mapname); + } + } + else + sprintf(levelselect.rows[row].mapnames[col], "???"); + + // creating header text + if (!col && ((row == startrow) || !(fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[levelselect.rows[row-1].maplist[0]-1]->selectheading)))) + { + if (!levelselect.rows[row].mapavailable[col]) + sprintf(levelselect.rows[row].header, "???"); + else + { + sprintf(levelselect.rows[row].header, "%s", mapheaderinfo[mapnum]->selectheading); + if (!(mapheaderinfo[mapnum]->levelflags & LF_NOZONE) && headingisname) + { + sprintf(levelselect.rows[row].header + strlen(levelselect.rows[row].header), " ZONE"); + } + } + } + + prevmapnum = mapnum; + } + + mapnum++; + } + +#ifdef SYMMETRICAL_PLATTER + // horizontally space out rows with missing right sides + for (; row >= 0; row--) + { + if (!levelselect.rows[row].maplist[2] // no right side + && levelselect.rows[row].maplist[0] && levelselect.rows[row].maplist[1]) // all the left filled in + { + levelselect.rows[row].maplist[2] = levelselect.rows[row].maplist[1]; + STRBUFCPY(levelselect.rows[row].mapnames[2], levelselect.rows[row].mapnames[1]); + levelselect.rows[row].mapavailable[2] = levelselect.rows[row].mapavailable[1]; + + levelselect.rows[row].maplist[1] = -1; // diamond + levelselect.rows[row].mapnames[1][0] = '\0'; + levelselect.rows[row].mapavailable[1] = false; + } + } +#endif + + if (levselp[0][0]) // never going to have some provided but not all, saves individually checking + { + W_UnlockCachedPatch(levselp[0][0]); + W_UnlockCachedPatch(levselp[0][1]); + W_UnlockCachedPatch(levselp[0][2]); + + W_UnlockCachedPatch(levselp[1][0]); + W_UnlockCachedPatch(levselp[1][1]); + W_UnlockCachedPatch(levselp[1][2]); + } + + levselp[0][0] = W_CachePatchName("SLCT1LVL", PU_STATIC); + levselp[0][1] = W_CachePatchName("SLCT2LVL", PU_STATIC); + levselp[0][2] = W_CachePatchName("BLANKLVL", PU_STATIC); + + levselp[1][0] = W_CachePatchName("SLCT1LVW", PU_STATIC); + levselp[1][1] = W_CachePatchName("SLCT2LVW", PU_STATIC); + levselp[1][2] = W_CachePatchName("BLANKLVW", PU_STATIC); + + return true; +} + +#define ifselectvalnextmapnobrace(column) if ((selectval = levelselect.rows[lsrow].maplist[column]) && levelselect.rows[lsrow].mapavailable[column])\ + {\ + CV_SetValue(&cv_nextmap, selectval); + +#define ifselectvalnextmap(column) ifselectvalnextmapnobrace(column)} + +// +// M_HandleLevelPlatter +// +// Reacts to your key inputs. Basically a mini menu thinker. +// +static void M_HandleLevelPlatter(INT32 choice) +{ + boolean exitmenu = false; // exit to previous menu + INT32 selectval; + + switch (choice) + { + case KEY_DOWNARROW: + lsrow++; + if (lsrow == levelselect.numrows) + lsrow = 0; + + lsoffs[0] = lsvseperation(lsrow); + + if (levelselect.rows[lsrow].header[0]) + lshli = lsrow; + // no else needed - headerless lines associate upwards, so moving down to a row without a header is identity + + S_StartSound(NULL,sfx_s3kb7); + + ifselectvalnextmap(lscol) else ifselectvalnextmap(0) + break; + + case KEY_UPARROW: + lsoffs[0] = -lsvseperation(lsrow); + + lsrow--; + if (lsrow == UINT8_MAX) + lsrow = levelselect.numrows-1; + + if (levelselect.rows[lsrow].header[0]) + lshli = lsrow; + else + { + UINT8 iter = lsrow; + do + iter = ((iter == 0) ? levelselect.numrows-1 : iter-1); + while ((iter != lsrow) && !(levelselect.rows[iter].header[0])); + lshli = iter; + } + + S_StartSound(NULL,sfx_s3kb7); + + ifselectvalnextmap(lscol) else ifselectvalnextmap(0) + break; + + case KEY_ENTER: + if (!(levellistmode == LLM_CREATESERVER && !lsrow)) + { + ifselectvalnextmapnobrace(lscol) + lsoffs[0] = lsoffs[1] = 0; + S_StartSound(NULL,sfx_menu1); + if (gamestate == GS_TIMEATTACK) + M_SetupNextMenu(currentMenu->prevMenu); + else if (currentMenu == &MISC_ChangeLevelDef) + { + if (currentMenu->prevMenu && currentMenu->prevMenu != &MPauseDef) + M_SetupNextMenu(currentMenu->prevMenu); + else + M_ChangeLevel(0); + Z_Free(levelselect.rows); + levelselect.rows = NULL; + } + else + M_LevelSelectWarp(0); + Nextmap_OnChange(); + } + else if (!lsoffs[0]) // prevent sound spam + { + lsoffs[0] = -8; + S_StartSound(NULL,sfx_s3kb2); + } + break; + } + /* FALLTHRU */ + case KEY_RIGHTARROW: + if (levellistmode == LLM_CREATESERVER && !lsrow) + { + CV_AddValue(&cv_newgametype, 1); + S_StartSound(NULL,sfx_menu1); + lscol = 0; + + Z_Free(char_notes); + char_notes = NULL; + + if (!M_PrepareLevelPlatter(cv_newgametype.value, false)) + I_Error("Unidentified level platter failure!"); + } + else if (lscol < 2) + { + lscol++; + + lsoffs[1] = (lswide(lsrow) ? 8 : -lshseperation); + S_StartSound(NULL,sfx_s3kb7); + + ifselectvalnextmap(lscol) else ifselectvalnextmap(0) + } + else if (!lsoffs[1]) // prevent sound spam + { + lsoffs[1] = 8; + S_StartSound(NULL,sfx_s3kb7); + } + break; + + case KEY_LEFTARROW: + if (levellistmode == LLM_CREATESERVER && !lsrow) + { + CV_AddValue(&cv_newgametype, -1); + S_StartSound(NULL,sfx_menu1); + lscol = 0; + + Z_Free(char_notes); + char_notes = NULL; + + if (!M_PrepareLevelPlatter(cv_newgametype.value, false)) + I_Error("Unidentified level platter failure!"); + } + else if (lscol > 0) + { + lscol--; + + lsoffs[1] = (lswide(lsrow) ? -8 : lshseperation); + S_StartSound(NULL,sfx_s3kb7); + + ifselectvalnextmap(lscol) else ifselectvalnextmap(0) + } + else if (!lsoffs[1]) // prevent sound spam + { + lsoffs[1] = -8; + S_StartSound(NULL,sfx_s3kb7); + } + break; + + case KEY_ESCAPE: + exitmenu = true; + break; + + default: + break; + } + + if (exitmenu) + { + if (gamestate != GS_TIMEATTACK) + { + Z_Free(levelselect.rows); + levelselect.rows = NULL; + } + + if (currentMenu->prevMenu) + { + M_SetupNextMenu(currentMenu->prevMenu); + Nextmap_OnChange(); + } + else + M_ClearMenus(true); + + Z_Free(char_notes); + char_notes = NULL; + } +} + +void M_DrawLevelPlatterHeader(INT32 y, const char *header, boolean headerhighlight, boolean allowlowercase) +{ + y += lsheadingheight - 12; + V_DrawString(19, y, (headerhighlight ? V_YELLOWMAP : 0)|(allowlowercase ? V_ALLOWLOWERCASE : 0), header); + y += 9; + V_DrawFill(19, y, 281, 1, (headerhighlight ? yellowmap[3] : 3)); + V_DrawFill(300, y, 1, 1, 26); + y++; + V_DrawFill(19, y, 282, 1, 26); +} + +static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolean highlight) +{ + patch_t *patch; + + INT32 map = levelselect.rows[row].maplist[col]; + if (map <= 0) + return; + + // A 564x100 image of the level as entry MAPxxW + if (!(levelselect.rows[row].mapavailable[col])) + { + V_DrawSmallScaledPatch(x, y, 0, levselp[1][2]); + M_DrawStaticBox(x, y, V_80TRANS, 282, 50); + } + else + { + if (W_CheckNumForName(va("%sW", G_BuildMapName(map))) != LUMPERROR) + patch = W_CachePatchName(va("%sW", G_BuildMapName(map)), PU_CACHE); + else + patch = levselp[1][2]; // don't static to indicate that it's just a normal level + + V_DrawSmallScaledPatch(x, y, 0, patch); + } + + V_DrawFill(x, y+50, 282, 8, + ((mapheaderinfo[map-1]->unlockrequired < 0) + ? 159 : 63)); + + V_DrawString(x, y+50, (highlight ? V_YELLOWMAP : 0), levelselect.rows[row].mapnames[col]); +} + +static void M_DrawLevelPlatterMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolean highlight) +{ + patch_t *patch; + + INT32 map = levelselect.rows[row].maplist[col]; + if (map <= 0) + return; + + // A 160x100 image of the level as entry MAPxxP + if (!(levelselect.rows[row].mapavailable[col])) + { + V_DrawSmallScaledPatch(x, y, 0, levselp[0][2]); + M_DrawStaticBox(x, y, V_80TRANS, 80, 50); + } + else + { + if (W_CheckNumForName(va("%sP", G_BuildMapName(map))) != LUMPERROR) + patch = W_CachePatchName(va("%sP", G_BuildMapName(map)), PU_CACHE); + else + patch = levselp[0][2]; // don't static to indicate that it's just a normal level + + V_DrawSmallScaledPatch(x, y, 0, patch); + } + + V_DrawFill(x, y+50, 80, 8, + ((mapheaderinfo[map-1]->unlockrequired < 0) + ? 159 : 63)); + + if (strlen(levelselect.rows[row].mapnames[col]) > 6) // "AERIAL GARDEN" vs "ACT 18" - "THE ACT" intentionally compressed + V_DrawThinString(x, y+50, (highlight ? V_YELLOWMAP : 0), levelselect.rows[row].mapnames[col]); + else + V_DrawString(x, y+50, (highlight ? V_YELLOWMAP : 0), levelselect.rows[row].mapnames[col]); +} + +static void M_DrawLevelPlatterRow(UINT8 row, INT32 y) +{ + UINT8 col; + const boolean rowhighlight = (row == lsrow); + if (levelselect.rows[row].header[0]) + { + M_DrawLevelPlatterHeader(y, levelselect.rows[row].header, (rowhighlight || (row == lshli)), false); + y += lsheadingheight; + } + + if (levellistmode == LLM_CREATESERVER && !row) + { + if (!char_notes) + char_notes = V_WordWrap(0, 282 - 8, V_ALLOWLOWERCASE, gametypedesc[cv_newgametype.value].notes); + + V_DrawFill(lsbasex, y, 282, 50, 27); + V_DrawString(lsbasex + 4, y + 4, V_RETURN8|V_ALLOWLOWERCASE, char_notes); + + V_DrawFill(lsbasex, y+50, 141, 8, gametypedesc[cv_newgametype.value].col[0]); + V_DrawFill(lsbasex+141, y+50, 141, 8, gametypedesc[cv_newgametype.value].col[1]); + + V_DrawString(lsbasex, y+50, 0, gametype_cons_t[cv_newgametype.value].strvalue); + + if (!lsrow) + { + V_DrawCharacter(lsbasex - 10 - (skullAnimCounter/5), y+25, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(lsbasex+282 + 2 + (skullAnimCounter/5), y+25, + '\x1D' | V_YELLOWMAP, false); + } + } + else if (lswide(row)) + M_DrawLevelPlatterWideMap(row, 0, lsbasex, y, rowhighlight); + else + { + for (col = 0; col < 3; col++) + M_DrawLevelPlatterMap(row, col, lsbasex+(col*lshseperation), y, (rowhighlight && (col == lscol))); + } +} + +static void M_DrawLevelPlatterMenu(void) +{ + UINT8 iter = lsrow, sizeselect = (lswide(lsrow) ? 1 : 0); + INT32 y = lsbasey + lsoffs[0] - getheadingoffset(lsrow); + const INT32 cursorx = (sizeselect ? 0 : (lscol*lshseperation)); + + if (gamestate == GS_TIMEATTACK) + { + if (curbgcolor >= 0) + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); + else if (!curbghide || !titlemapinaction) + F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + if (curfadevalue) + V_DrawFadeScreen(0xFF00, curfadevalue); + } + + // finds row at top of the screen + while (y > -8) + { + iter = ((iter == 0) ? levelselect.numrows-1 : iter-1); + y -= lsvseperation(iter); + } + + // draw from top to bottom + while (y < (vid.height/vid.dupy)) + { + M_DrawLevelPlatterRow(iter, y); + y += lsvseperation(iter); + iter = ((iter == levelselect.numrows-1) ? 0 : iter+1); + } + + // draw cursor box + if (levellistmode != LLM_CREATESERVER || lsrow) + V_DrawSmallScaledPatch(lsbasex + cursorx + lsoffs[1], lsbasey+lsoffs[0], 0, (levselp[sizeselect][((skullAnimCounter/4) ? 1 : 0)])); + +#if 0 + if (levelselect.rows[lsrow].maplist[lscol] > 0) + V_DrawScaledPatch(lsbasex + cursorx-17, lsbasey+50+lsoffs[0], 0, W_CachePatchName("M_CURSOR", PU_CACHE)); +#endif + + // handle movement of cursor box + if (lsoffs[0] > 1 || lsoffs[0] < -1) + lsoffs[0] = 2*lsoffs[0]/3; + else + lsoffs[0] = 0; + + if (lsoffs[1] > 1 || lsoffs[1] < -1) + lsoffs[1] = 2*lsoffs[1]/3; + else + lsoffs[1] = 0; + + M_DrawMenuTitle(); +} + +// +// M_CanShowLevelInList +// +// Determines whether to show a given map in level-select lists where you don't want to see locked levels. +// Set gt = -1 to ignore gametype. +// +boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt) +{ + return (M_CanShowLevelOnPlatter(mapnum, gt) && M_LevelAvailableOnPlatter(mapnum)); +} + +static INT32 M_GetFirstLevelInList(INT32 gt) +{ + INT32 mapnum; + + for (mapnum = 0; mapnum < NUMMAPS; mapnum++) + if (M_CanShowLevelInList(mapnum, gt)) + return mapnum + 1; + + return 1; +} + +// ================================================== +// MESSAGE BOX (aka: a hacked, cobbled together menu) +// ================================================== +static void M_DrawMessageMenu(void); + +// Because this is just a hack-ish 'menu', I'm not putting this with the others +static menuitem_t MessageMenu[] = +{ + // TO HACK + {0,NULL, NULL, NULL,0} +}; menu_t MessageDef = { + MN_SPECIAL, NULL, // title 1, // # of menu items NULL, // previous menu (TO HACK) @@ -3783,7 +5250,14 @@ static void M_DrawMessageMenu(void) // hack: draw RA background in RA menus if (gamestate == GS_TIMEATTACK) - V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); + { + if (curbgcolor >= 0) + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); + else if (!curbghide || !titlemapinaction) + F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + if (curfadevalue) + V_DrawFadeScreen(0xFF00, curfadevalue); + } M_DrawTextBox(currentMenu->x, y - 8, (max+7)>>3, mlines); @@ -4005,21 +5479,21 @@ static void M_DrawTemperature(INT32 x, fixed_t t) t = (FixedMul(h<<FRACBITS, t)>>FRACBITS); // border - V_DrawFill(x - 1, vpadding, 1, h, 120); - V_DrawFill(x + width, vpadding, 1, h, 120); - V_DrawFill(x - 1, vpadding-1, width+2, 1, 120); - V_DrawFill(x - 1, vpadding+h, width+2, 1, 120); + V_DrawFill(x - 1, vpadding, 1, h, 3); + V_DrawFill(x + width, vpadding, 1, h, 3); + V_DrawFill(x - 1, vpadding-1, width+2, 1, 3); + V_DrawFill(x - 1, vpadding+h, width+2, 1, 3); // bar itself y = h; if (t) for (t = h - t; y > 0; y--) { - UINT8 colours[NUMCOLOURS] = {135, 133, 92, 77, 114, 178, 161, 162}; + UINT8 colours[NUMCOLOURS] = {42, 40, 58, 222, 65, 90, 97, 98}; UINT8 c; if (y <= t) break; if (y+vpadding >= BASEVIDHEIGHT/2) - c = 185; + c = 113; else c = colours[(NUMCOLOURS*(y-1))/(h/2)]; V_DrawFill(x, y-1 + vpadding, width, 1, c); @@ -4027,7 +5501,7 @@ static void M_DrawTemperature(INT32 x, fixed_t t) // fill the rest of the backing if (y) - V_DrawFill(x, vpadding, width, y, 30); + V_DrawFill(x, vpadding, width, y, 27); } #undef width #undef vpadding @@ -4145,14 +5619,15 @@ static void M_DrawAddons(void) x = currentMenu->x; y = currentMenu->y + 1; - hilicol = V_GetStringColormap(highlightflags)[120]; + hilicol = 0; // white V_DrawString(x-21, (y - 16) + (lsheadingheight - 12), highlightflags|V_ALLOWLOWERCASE, M_AddonsHeaderPath()); V_DrawFill(x-21, (y - 16) + (lsheadingheight - 3), MAXSTRINGLENGTH*8+6, 1, hilicol); V_DrawFill(x-21, (y - 16) + (lsheadingheight - 2), MAXSTRINGLENGTH*8+6, 1, 30); m = (BASEVIDHEIGHT - currentMenu->y + 2) - (y - 1); - V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, m, 239); + // addons menu back color + V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, m, 159); // scrollbar! if (sizedirmenu <= (2*numaddonsshown + 1)) @@ -4406,7 +5881,7 @@ static void M_HandleAddons(INT32 choice) M_StartMessage(va("%c%s\x80\nThis copy of SRB2 was compiled\nwithout support for .lua files.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING); break; #endif - // else intentional fallthrough + /* FALLTHRU */ case EXT_SOC: case EXT_WAD: #ifdef USE_KART @@ -4435,7 +5910,7 @@ static void M_HandleAddons(INT32 choice) { closefilemenu(true); - // Secret menu! + // secrets disabled by addfile... MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED); if (currentMenu->prevMenu) @@ -4448,16 +5923,33 @@ static void M_HandleAddons(INT32 choice) static void M_PandorasBox(INT32 choice) { (void)choice; - CV_StealthSetValue(&cv_dummyrings, max(players[consoleplayer].health - 1, 0)); - CV_StealthSetValue(&cv_dummylives, players[consoleplayer].lives); + if (maptol & TOL_NIGHTS) + CV_StealthSetValue(&cv_dummyrings, max(players[consoleplayer].spheres, 0)); + else + CV_StealthSetValue(&cv_dummyrings, max(players[consoleplayer].rings, 0)); + if (players[consoleplayer].lives == INFLIVES) + CV_StealthSetValue(&cv_dummylives, -1); + else + CV_StealthSetValue(&cv_dummylives, players[consoleplayer].lives); CV_StealthSetValue(&cv_dummycontinues, players[consoleplayer].continues); + SR_PandorasBox[6].status = ((players[consoleplayer].charflags & SF_SUPER) +#ifndef DEVELOP + || cv_skin.value == 1 +#endif + ) ? (IT_GRAYEDOUT) : (IT_STRING | IT_CALL); + SR_PandorasBox[7].status = (emeralds == ((EMERALD7)*2)-1) ? (IT_GRAYEDOUT) : (IT_STRING | IT_CALL); M_SetupNextMenu(&SR_PandoraDef); } static boolean M_ExitPandorasBox(void) { - if (cv_dummyrings.value != max(players[consoleplayer].health - 1, 0)) - COM_ImmedExecute(va("setrings %d", cv_dummyrings.value)); + if (cv_dummyrings.value != max(players[consoleplayer].rings, 0)) + { + if (maptol & TOL_NIGHTS) + COM_ImmedExecute(va("setspheres %d", cv_dummyrings.value)); + else + COM_ImmedExecute(va("setrings %d", cv_dummyrings.value)); + } if (cv_dummylives.value != players[consoleplayer].lives) COM_ImmedExecute(va("setlives %d", cv_dummylives.value)); if (cv_dummycontinues.value != players[consoleplayer].continues) @@ -4544,10 +6036,10 @@ static void M_Options(INT32 choice) (void)choice; // if the player is not admin or server, disable server options - OP_MainMenu[5].status = (Playing() && !(server || IsPlayerAdmin(consoleplayer))) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); + OP_MainMenu[5].status = (Playing() && !(server || IsPlayerAdmin(consoleplayer))) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL); // if the player is playing _at all_, disable the erase data options - OP_DataOptionsMenu[1].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); + OP_DataOptionsMenu[2].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); OP_MainDef.prevMenu = currentMenu; M_SetupNextMenu(&OP_MainDef); @@ -4587,12 +6079,24 @@ static void M_UltimateCheat(INT32 choice) I_Quit(); } +static void M_AllowSuper(INT32 choice) +{ + (void)choice; + + players[consoleplayer].charflags |= SF_SUPER; + M_StartMessage(M_GetText("You are now capable of turning super.\nRemember to get all the emeralds!\n"),NULL,MM_NOTHING); + SR_PandorasBox[6].status = IT_GRAYEDOUT; + + G_SetGameModified(multiplayer); +} + static void M_GetAllEmeralds(INT32 choice) { (void)choice; emeralds = ((EMERALD7)*2)-1; M_StartMessage(M_GetText("You now have all 7 emeralds.\nUse them wisely.\nWith great power comes great ring drain.\n"),NULL,MM_NOTHING); + SR_PandorasBox[7].status = IT_GRAYEDOUT; G_SetGameModified(multiplayer); } @@ -4635,7 +6139,7 @@ static void M_LevelSelectWarp(INT32 choice) G_LoadGame((UINT32)cursaveslot, startmap); else { - cursaveslot = -1; + cursaveslot = 0; M_SetupChoosePlayer(0); } } @@ -4646,28 +6150,341 @@ static void M_LevelSelectWarp(INT32 choice) UINT8 skyRoomMenuTranslations[MAXUNLOCKABLES]; -#define NUMCHECKLIST 8 +static boolean checklist_cangodown; // uuuueeerggghhhh HACK + +static void M_HandleChecklist(INT32 choice) +{ + INT32 j; + switch (choice) + { + case KEY_DOWNARROW: + S_StartSound(NULL, sfx_menu1); + if ((check_on != MAXUNLOCKABLES) && checklist_cangodown) + { + for (j = check_on+1; j < MAXUNLOCKABLES; j++) + { + if (!unlockables[j].name[0]) + continue; + // if (unlockables[j].nochecklist) + // continue; + if (!unlockables[j].conditionset) + continue; + if (unlockables[j].conditionset > MAXCONDITIONSETS) + continue; + if (unlockables[j].conditionset == unlockables[check_on].conditionset) + continue; + break; + } + if (j != MAXUNLOCKABLES) + check_on = j; + } + return; + + case KEY_UPARROW: + S_StartSound(NULL, sfx_menu1); + if (check_on) + { + for (j = check_on-1; j > -1; j--) + { + if (!unlockables[j].name[0]) + continue; + // if (unlockables[j].nochecklist) + // continue; + if (!unlockables[j].conditionset) + continue; + if (unlockables[j].conditionset > MAXCONDITIONSETS) + continue; + if (j && unlockables[j].conditionset == unlockables[j-1].conditionset) + continue; + break; + } + if (j != -1) + check_on = j; + } + return; + + case KEY_ESCAPE: + if (currentMenu->prevMenu) + M_SetupNextMenu(currentMenu->prevMenu); + else + M_ClearMenus(true); + return; + default: + break; + } +} + +#define addy(add) { y += add; if ((y - currentMenu->y) > (scrollareaheight*2)) goto finishchecklist; } + static void M_DrawChecklist(void) { - INT32 i, j = 0; + INT32 i = check_on, j = 0, y = currentMenu->y; + UINT32 condnum, previd, maxcond; + condition_t *cond; + + // draw title (or big pic) + M_DrawMenuTitle(); - for (i = 0; i < MAXUNLOCKABLES; i++) + if (check_on) + V_DrawString(10, y-(skullAnimCounter/5), V_YELLOWMAP, "\x1A"); + + while (i < MAXUNLOCKABLES) { - if (unlockables[i].name[0] == 0 || unlockables[i].nochecklist + if (unlockables[i].name[0] == 0 //|| unlockables[i].nochecklist || !unlockables[i].conditionset || unlockables[i].conditionset > MAXCONDITIONSETS) continue; - V_DrawString(8, 8+(24*j), V_RETURN8, unlockables[i].name); - V_DrawString(160, 8+(24*j), V_RETURN8, V_WordWrap(160, 292, 0, unlockables[i].objective)); + V_DrawString(currentMenu->x, y, ((unlockables[i].unlocked) ? V_GREENMAP : V_TRANSLUCENT), ((unlockables[i].unlocked || !unlockables[i].nochecklist) ? unlockables[i].name : M_CreateSecretMenuOption(unlockables[i].name))); + + for (j = i+1; j < MAXUNLOCKABLES; j++) + { + if (!(unlockables[j].name[0] == 0 //|| unlockables[j].nochecklist + || !unlockables[j].conditionset || unlockables[j].conditionset > MAXCONDITIONSETS)) + break; + } + if ((j != MAXUNLOCKABLES) && (unlockables[i].conditionset == unlockables[j].conditionset)) + addy(8) + else + { + if ((maxcond = conditionSets[unlockables[i].conditionset-1].numconditions)) + { + cond = conditionSets[unlockables[i].conditionset-1].condition; + previd = cond[0].id; + addy(2); + + if (unlockables[i].objective[0] != '/') + { + addy(8); + V_DrawString(currentMenu->x, y, + V_ALLOWLOWERCASE, + va("\x1E %s", unlockables[i].objective)); + } + else + { + for (condnum = 0; condnum < maxcond; condnum++) + { + const char *beat = "!"; + + if (cond[condnum].id != previd) + { + addy(8); + V_DrawString(currentMenu->x + 4, y, V_YELLOWMAP, "OR"); + } + + addy(8); + + switch (cond[condnum].type) + { + case UC_PLAYTIME: + { + UINT32 hours = G_TicsToHours(cond[condnum].requirement); + UINT32 minutes = G_TicsToMinutes(cond[condnum].requirement, false); + UINT32 seconds = G_TicsToSeconds(cond[condnum].requirement); + +#define getplural(field) ((field == 1) ? "" : "s") + if (hours) + { + if (minutes) + beat = va("Play the game for %d hour%s %d minute%s", hours, getplural(hours), minutes, getplural(minutes)); + else + beat = va("Play the game for %d hour%s", hours, getplural(hours)); + } + else + { + if (minutes && seconds) + beat = va("Play the game for %d minute%s %d second%s", minutes, getplural(minutes), seconds, getplural(seconds)); + else if (minutes) + beat = va("Play the game for %d minute%s", minutes, getplural(minutes)); + else + beat = va("Play the game for %d second%s", seconds, getplural(seconds)); + } +#undef getplural + } + break; + case UC_MAPVISITED: + case UC_MAPBEATEN: + case UC_MAPALLEMERALDS: + case UC_MAPULTIMATE: + case UC_MAPPERFECT: + { + char *title = G_BuildMapTitle(cond[condnum].requirement); + + if (title) + { + const char *level = ((M_MapLocked(cond[condnum].requirement) || !((mapheaderinfo[cond[condnum].requirement-1]->menuflags & LF2_NOVISITNEEDED) || (mapvisited[cond[condnum].requirement-1] & MV_MAX))) ? M_CreateSecretMenuOption(title) : title); + + switch (cond[condnum].type) + { + case UC_MAPVISITED: + beat = va("Visit %s", level); + break; + case UC_MAPALLEMERALDS: + beat = va("Beat %s with all emeralds", level); + break; + case UC_MAPULTIMATE: + beat = va("Beat %s in Ultimate mode", level); + break; + case UC_MAPPERFECT: + beat = va("Get all rings in %s", level); + break; + case UC_MAPBEATEN: + default: + beat = va("Beat %s", level); + break; + } + Z_Free(title); + } + } + break; + case UC_MAPSCORE: + case UC_MAPTIME: + case UC_MAPRINGS: + { + char *title = G_BuildMapTitle(cond[condnum].extrainfo1); + + if (title) + { + const char *level = ((M_MapLocked(cond[condnum].extrainfo1) || !((mapheaderinfo[cond[condnum].extrainfo1-1]->menuflags & LF2_NOVISITNEEDED) || (mapvisited[cond[condnum].extrainfo1-1] & MV_MAX))) ? M_CreateSecretMenuOption(title) : title); + + switch (cond[condnum].type) + { + case UC_MAPSCORE: + beat = va("Get %d points in %s", cond[condnum].requirement, level); + break; + case UC_MAPTIME: + beat = va("Beat %s in %d:%02d.%02d", level, + G_TicsToMinutes(cond[condnum].requirement, true), + G_TicsToSeconds(cond[condnum].requirement), + G_TicsToCentiseconds(cond[condnum].requirement)); + break; + case UC_MAPRINGS: + beat = va("Get %d rings in %s", cond[condnum].requirement, level); + break; + default: + break; + } + Z_Free(title); + } + } + break; + case UC_OVERALLSCORE: + case UC_OVERALLTIME: + case UC_OVERALLRINGS: + { + switch (cond[condnum].type) + { + case UC_OVERALLSCORE: + beat = va("Get %d points over all maps", cond[condnum].requirement); + break; + case UC_OVERALLTIME: + beat = va("Get a total time of less than %d:%02d.%02d", + G_TicsToMinutes(cond[condnum].requirement, true), + G_TicsToSeconds(cond[condnum].requirement), + G_TicsToCentiseconds(cond[condnum].requirement)); + break; + case UC_OVERALLRINGS: + beat = va("Get %d rings over all maps", cond[condnum].requirement); + break; + default: + break; + } + } + break; + case UC_GAMECLEAR: + case UC_ALLEMERALDS: + { + const char *emeraldtext = ((cond[condnum].type == UC_ALLEMERALDS) ? " with all emeralds" : ""); + if (cond[condnum].requirement != 1) + beat = va("Beat the game %d times%s", + cond[condnum].requirement, emeraldtext); + else + beat = va("Beat the game%s", + emeraldtext); + } + break; + case UC_TOTALEMBLEMS: + beat = va("Collect %s%d emblems", ((numemblems+numextraemblems == cond[condnum].requirement) ? "all " : ""), cond[condnum].requirement); + break; + case UC_NIGHTSTIME: + case UC_NIGHTSSCORE: + case UC_NIGHTSGRADE: + { + char *title = G_BuildMapTitle(cond[condnum].extrainfo1); + + if (title) + { + const char *level = ((M_MapLocked(cond[condnum].extrainfo1) || !((mapheaderinfo[cond[condnum].extrainfo1-1]->menuflags & LF2_NOVISITNEEDED) || (mapvisited[cond[condnum].extrainfo1-1] & MV_MAX))) ? M_CreateSecretMenuOption(title) : title); + + switch (cond[condnum].type) + { + case UC_NIGHTSSCORE: + if (cond[condnum].extrainfo2) + beat = va("Get %d points in %s, mare %d", cond[condnum].requirement, level, cond[condnum].extrainfo2); + else + beat = va("Get %d points in %s", cond[condnum].requirement, level); + break; + case UC_NIGHTSTIME: + if (cond[condnum].extrainfo2) + beat = va("Beat %s, mare %d in %d:%02d.%02d", level, cond[condnum].extrainfo2, + G_TicsToMinutes(cond[condnum].requirement, true), + G_TicsToSeconds(cond[condnum].requirement), + G_TicsToCentiseconds(cond[condnum].requirement)); + else + beat = va("Beat %s in %d:%02d.%02d", + level, + G_TicsToMinutes(cond[condnum].requirement, true), + G_TicsToSeconds(cond[condnum].requirement), + G_TicsToCentiseconds(cond[condnum].requirement)); + break; + case UC_NIGHTSGRADE: + { + char grade = ('F' - (char)cond[condnum].requirement); + if (grade < 'A') + grade = 'A'; + if (cond[condnum].extrainfo2) + beat = va("Get grade %c in %s, mare %d", grade, level, cond[condnum].extrainfo2); + else + beat = va("Get grade %c in %s", grade, level); + } + break; + default: + break; + } + Z_Free(title); + } + } + break; + case UC_TRIGGER: + case UC_EMBLEM: + case UC_CONDITIONSET: + default: + y -= 8; // Nope, not showing this. + break; + } + if (beat[0] != '!') + { + V_DrawString(currentMenu->x, y, 0, "\x1E"); + V_DrawString(currentMenu->x+12, y, V_ALLOWLOWERCASE, beat); + } + previd = cond[condnum].id; + } + } + } + addy(12); + } + i = j; + + /*V_DrawString(160, 8+(24*j), V_RETURN8, V_WordWrap(160, 292, 0, unlockables[i].objective)); if (unlockables[i].unlocked) V_DrawString(308, 8+(24*j), V_YELLOWMAP, "Y"); else - V_DrawString(308, 8+(24*j), V_YELLOWMAP, "N"); - - if (++j >= NUMCHECKLIST) - break; + V_DrawString(308, 8+(24*j), V_YELLOWMAP, "N");*/ } + +finishchecklist: + if ((checklist_cangodown = ((y - currentMenu->y) > (scrollareaheight*2)))) // haaaaaaacks. + V_DrawString(10, currentMenu->y+(scrollareaheight*2)+(skullAnimCounter/5), V_YELLOWMAP, "\x1B"); } #define NUMHINTS 5 @@ -4720,27 +6537,6 @@ static void M_DrawEmblemHints(void) M_DrawGenericMenu(); } -static void M_DrawLevelSelectMenu(void) -{ - M_DrawGenericMenu(); - - if (cv_nextmap.value) - { - lumpnum_t lumpnum; - patch_t *PictureOfLevel; - - // A 160x100 image of the level as entry MAPxxP - lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value))); - - if (lumpnum != LUMPERROR) - PictureOfLevel = W_CachePatchName(va("%sP", G_BuildMapName(cv_nextmap.value)), PU_CACHE); - else - PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); - - V_DrawSmallScaledPatch(200, 110, 0, PictureOfLevel); - } -} - static void M_DrawSkyRoom(void) { INT32 i, y = 0; @@ -4759,6 +6555,13 @@ static void M_DrawSkyRoom(void) return; V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + y, V_YELLOWMAP, cv_soundtest.string); + if (i == itemOn) + { + V_DrawCharacter(BASEVIDWIDTH - currentMenu->x - 10 - V_StringWidth(cv_soundtest.string, 0) - (skullAnimCounter/5), currentMenu->y + y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - currentMenu->x + 2 + (skullAnimCounter/5), currentMenu->y + y, + '\x1D' | V_YELLOWMAP, false); + } if (cv_soundtest.value) V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + y + 8, V_YELLOWMAP, S_sfx[cv_soundtest.value].name); } @@ -4911,7 +6714,7 @@ static void M_CustomWarp(INT32 choice) static void M_Credits(INT32 choice) { (void)choice; - cursaveslot = -2; + cursaveslot = -1; M_ClearMenus(true); F_StartCredits(); } @@ -4923,13 +6726,13 @@ static void M_CustomLevelSelect(INT32 choice) SR_LevelSelectDef.prevMenu = currentMenu; levellistmode = LLM_LEVELSELECT; maplistoption = (UINT8)(unlockables[ul].variable); - if (M_CountLevelsToShowInList() == 0) + + if (!M_PrepareLevelPlatter(-1, true)) { M_StartMessage(M_GetText("No selectable levels found.\n"),NULL,MM_NOTHING); return; } - M_PrepareLevelSelect(); M_SetupNextMenu(&SR_LevelSelectDef); } @@ -4940,6 +6743,8 @@ static void M_CustomLevelSelect(INT32 choice) static void M_SinglePlayerMenu(INT32 choice) { (void)choice; + SP_MainMenu[sptutorial].status = + tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED; SP_MainMenu[sprecordattack].status = (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET; SP_MainMenu[spnightsmode].status = @@ -4951,167 +6756,379 @@ static void M_SinglePlayerMenu(INT32 choice) static void M_LoadGameLevelSelect(INT32 choice) { (void)choice; + + SP_LevelSelectDef.prevMenu = currentMenu; levellistmode = LLM_LEVELSELECT; - maplistoption = 1; - if (M_CountLevelsToShowInList() == 0) + maplistoption = 1+2; + + if (!M_PrepareLevelPlatter(-1, true)) { M_StartMessage(M_GetText("No selectable levels found.\n"),NULL,MM_NOTHING); return; } - SP_LevelSelectDef.prevMenu = currentMenu; - - M_PrepareLevelSelect(); M_SetupNextMenu(&SP_LevelSelectDef); } -// ============== -// LOAD GAME MENU -// ============== - -static INT32 saveSlotSelected = 0; -static short menumovedir = 0; - -static void M_DrawLoadGameData(void) +void M_TutorialSaveControlResponse(INT32 ch) { - INT32 ecks; - INT32 i; - - ecks = SP_LoadDef.x + 24; - M_DrawTextBox(SP_LoadDef.x-12,144, 24, 4); + if (ch == 'y' || ch == KEY_ENTER) + { + G_CopyControls(gamecontrol, gamecontroldefault[tutorialgcs], gcl_tutorial_full, num_gcl_tutorial_full); + CV_Set(&cv_usemouse, cv_usemouse.defaultvalue); + CV_Set(&cv_alwaysfreelook, cv_alwaysfreelook.defaultvalue); + CV_Set(&cv_mousemove, cv_mousemove.defaultvalue); + CV_Set(&cv_analog, cv_analog.defaultvalue); + S_StartSound(NULL, sfx_itemup); + } + else + S_StartSound(NULL, sfx_menu1); +} - if (saveSlotSelected == NOSAVESLOT) // last slot is play without saving +static void M_TutorialControlResponse(INT32 ch) +{ + if (ch != KEY_ESCAPE) { - if (ultimate_selectable) + G_CopyControls(gamecontroldefault[gcs_custom], gamecontrol, NULL, 0); // using gcs_custom as temp storage for old controls + if (ch == 'y' || ch == KEY_ENTER) { - V_DrawCenteredString(ecks + 68, 144, V_ORANGEMAP, "ULTIMATE MODE"); - V_DrawCenteredString(ecks + 68, 156, 0, "NO RINGS, NO ONE-UPS,"); - V_DrawCenteredString(ecks + 68, 164, 0, "NO CONTINUES, ONE LIFE,"); - V_DrawCenteredString(ecks + 68, 172, 0, "FINAL DESTINATION."); + tutorialgcs = gcs_fps; + tutorialusemouse = cv_usemouse.value; + tutorialfreelook = cv_alwaysfreelook.value; + tutorialmousemove = cv_mousemove.value; + tutorialanalog = cv_analog.value; + + G_CopyControls(gamecontrol, gamecontroldefault[tutorialgcs], gcl_tutorial_full, num_gcl_tutorial_full); + CV_Set(&cv_usemouse, cv_usemouse.defaultvalue); + CV_Set(&cv_alwaysfreelook, cv_alwaysfreelook.defaultvalue); + CV_Set(&cv_mousemove, cv_mousemove.defaultvalue); + CV_Set(&cv_analog, cv_analog.defaultvalue); + + //S_StartSound(NULL, sfx_itemup); } else { - V_DrawCenteredString(ecks + 68, 144, V_ORANGEMAP, "PLAY WITHOUT SAVING"); - V_DrawCenteredString(ecks + 68, 156, 0, "THIS GAME WILL NOT BE"); - V_DrawCenteredString(ecks + 68, 164, 0, "SAVED, BUT YOU CAN STILL"); - V_DrawCenteredString(ecks + 68, 172, 0, "GET EMBLEMS AND SECRETS."); + tutorialgcs = gcs_custom; + S_StartSound(NULL, sfx_menu1); } - return; + M_StartTutorial(INT32_MAX); } + else + S_StartSound(NULL, sfx_menu1); - if (savegameinfo[saveSlotSelected].lives == -42) // Empty - { - V_DrawCenteredString(ecks + 68, 160, 0, "NO DATA"); - return; - } + MessageDef.prevMenu = &SP_MainDef; // if FirstPrompt -> ControlsPrompt -> ESC, we would go to the main menu unless we force this +} + +// Starts up the tutorial immediately (tbh I wasn't sure where else to put this) +static void M_StartTutorial(INT32 choice) +{ + if (!tutorialmap) + return; // no map to go to, don't bother - if (savegameinfo[saveSlotSelected].lives == -666) // savegame is bad + if (choice != INT32_MAX && G_GetControlScheme(gamecontrol, gcl_tutorial_check, num_gcl_tutorial_check) != gcs_fps) { - V_DrawCenteredString(ecks + 68, 144, V_REDMAP, "CORRUPT SAVE FILE"); - V_DrawCenteredString(ecks + 68, 156, 0, "THIS SAVE FILE"); - V_DrawCenteredString(ecks + 68, 164, 0, "CAN NOT BE LOADED."); - V_DrawCenteredString(ecks + 68, 172, 0, "DELETE USING BACKSPACE."); + M_StartMessage("Do you want to try the \202recommended \202movement controls\x80?\n\nWe will set them just for this tutorial.\n\nPress 'Y' or 'Enter' to confirm\nPress 'N' or any key to keep \nyour current controls.\n",M_TutorialControlResponse,MM_YESNO); return; } + else if (choice != INT32_MAX) + tutorialgcs = gcs_custom; - // Draw the back sprite, it looks ugly if we don't - V_DrawScaledPatch(SP_LoadDef.x, 144+8, 0, livesback); - if (savegameinfo[saveSlotSelected].skincolor == 0) - V_DrawScaledPatch(SP_LoadDef.x,144+8,0,W_CachePatchName(skins[savegameinfo[saveSlotSelected].skinnum].face, PU_CACHE)); - else - { - UINT8 *colormap = R_GetTranslationColormap(savegameinfo[saveSlotSelected].skinnum, savegameinfo[saveSlotSelected].skincolor, 0); - V_DrawMappedPatch(SP_LoadDef.x,144+8,0,W_CachePatchName(skins[savegameinfo[saveSlotSelected].skinnum].face, PU_CACHE), colormap); - } + CV_SetValue(&cv_tutorialprompt, 0); // first-time prompt - V_DrawString(ecks + 12, 152, 0, savegameinfo[saveSlotSelected].playername); + tutorialmode = true; // turn on tutorial mode -#ifdef SAVEGAMES_OTHERVERSIONS - if (savegameinfo[saveSlotSelected].gamemap & 16384) - V_DrawCenteredString(ecks + 68, 144, V_REDMAP, "OUTDATED SAVE FILE!"); -#endif + emeralds = 0; + M_ClearMenus(true); + gamecomplete = false; + cursaveslot = 0; + G_DeferedInitNew(false, G_BuildMapName(tutorialmap), 0, false, false); +} - if (savegameinfo[saveSlotSelected].gamemap & 8192) - V_DrawString(ecks + 12, 160, V_GREENMAP, "CLEAR!"); - else - V_DrawString(ecks + 12, 160, 0, va("%s", savegameinfo[saveSlotSelected].levelname)); +// ============== +// LOAD GAME MENU +// ============== + +static INT32 saveSlotSelected = 1; +static INT32 loadgamescroll = 0; +static UINT8 loadgameoffset = 0; - // Use the big face pic for lives, duh. :3 - V_DrawScaledPatch(ecks + 12, 175, 0, W_CachePatchName("STLIVEX", PU_HUDGFX)); - V_DrawTallNum(ecks + 40, 172, 0, savegameinfo[saveSlotSelected].lives); +static void M_DrawLoadGameData(void) +{ + INT32 i, savetodraw, x, y, hsep = 90; + skin_t *charskin = NULL; - // Absolute ridiculousness, condensed into another function. - V_DrawContinueIcon(ecks + 58, 182, 0, savegameinfo[saveSlotSelected].skinnum, savegameinfo[saveSlotSelected].skincolor); - V_DrawScaledPatch(ecks + 68, 175, 0, W_CachePatchName("STLIVEX", PU_HUDGFX)); - V_DrawTallNum(ecks + 96, 172, 0, savegameinfo[saveSlotSelected].continues); + if (vid.width != BASEVIDWIDTH*vid.dupx) + hsep = (hsep*vid.width)/(BASEVIDWIDTH*vid.dupx); - for (i = 0; i < 7; ++i) + for (i = -2; i <= 2; i++) { - if (savegameinfo[saveSlotSelected].numemeralds & (1 << i)) - V_DrawScaledPatch(ecks + 104 + (i * 8), 172, 0, tinyemeraldpics[i]); - } -} + savetodraw = (saveSlotSelected + i + numsaves)%numsaves; + x = (BASEVIDWIDTH/2 - 42 + loadgamescroll) + (i*hsep); + y = 33 + 9; -#define LOADBARHEIGHT SP_LoadDef.y + (LINEHEIGHT * (j+1)) + ymod -#define CURSORHEIGHT SP_LoadDef.y + (LINEHEIGHT*3) - 1 -static void M_DrawLoad(void) -{ - INT32 i, j; - INT32 ymod = 0, offset = 0; + { + INT32 diff = x - (BASEVIDWIDTH/2 - 42); + if (diff < 0) + diff = -diff; + diff = (42 - diff)/3 - loadgameoffset; + if (diff < 0) + diff = 0; + y -= diff; + } - M_DrawMenuTitle(); + if (savetodraw == 0) + { + V_DrawSmallScaledPatch(x, y, 0, + savselp[((ultimate_selectable) ? 2 : 1)]); + x += 2; + y += 1; + V_DrawString(x, y, + ((savetodraw == saveSlotSelected) ? V_YELLOWMAP : 0), + "NO FILE"); + if (savetodraw == saveSlotSelected) + V_DrawFill(x, y+9, 80, 1, yellowmap[3]); + y += 11; + V_DrawSmallScaledPatch(x, y, 0, savselp[4]); + M_DrawStaticBox(x, y, V_80TRANS, 80, 50); + y += 41; + if (ultimate_selectable) + V_DrawRightAlignedThinString(x + 79, y, V_REDMAP, "ULTIMATE."); + else + V_DrawRightAlignedThinString(x + 79, y, V_GRAYMAP, "DON'T SAVE!"); - if (menumovedir != 0) //movement illusion - { - ymod = (-(LINEHEIGHT/4))*menumovedir; - offset = ((menumovedir > 0) ? -1 : 1); - } + continue; + } - V_DrawCenteredString(BASEVIDWIDTH/2, 40, 0, "Press backspace to delete a save."); + savetodraw--; - for (i = MAXSAVEGAMES + saveSlotSelected - 2 + offset, j = 0;i <= MAXSAVEGAMES + saveSlotSelected + 2 + offset; i++, j++) - { - if ((menumovedir < 0 && j == 4) || (menumovedir > 0 && j == 0)) - continue; //this helps give the illusion of movement + if (savegameinfo[savetodraw].lives > 0) + charskin = &skins[savegameinfo[savetodraw].skinnum]; + + // signpost background + { + UINT8 col; + if (savegameinfo[savetodraw].lives == -666) + { + V_DrawSmallScaledPatch(x+2, y+64, 0, savselp[5]); + } +#ifdef PERFECTSAVE // disabled on request + else if ((savegameinfo[savetodraw].skinnum == 1) + && (savegameinfo[savetodraw].lives == 99) + && (savegameinfo[savetodraw].gamemap & 8192) + && (savegameinfo[savetodraw].numgameovers == 0) + && (savegameinfo[savetodraw].numemeralds == ((1<<7) - 1))) // perfect save + { + V_DrawFill(x+6, y+64, 72, 50, 134); + V_DrawFill(x+6, y+74, 72, 30, 201); + V_DrawFill(x+6, y+84, 72, 10, 1); + } +#endif + else + { + if (savegameinfo[savetodraw].lives == -42) + col = 26; + else if (savegameinfo[savetodraw].botskin == 3) // & knuckles + col = 105; + else if (savegameinfo[savetodraw].botskin) // tailsbot or custom + col = 134; + else + { + col = (charskin->prefcolor - 1)*2; + col = Color_Index[Color_Opposite[col]-1][Color_Opposite[col+1]]; + } - M_DrawSaveLoadBorder(SP_LoadDef.x, LOADBARHEIGHT); + V_DrawFill(x+6, y+64, 72, 50, col); + } + } - if ((i%MAXSAVEGAMES) == NOSAVESLOT) // play without saving + V_DrawSmallScaledPatch(x, y, 0, savselp[0]); + x += 2; + y += 1; + V_DrawString(x, y, + ((savetodraw == saveSlotSelected-1) ? V_YELLOWMAP : 0), + va("FILE %d", savetodraw+1)); + if (savetodraw == saveSlotSelected-1) + V_DrawFill(x, y+9, 80, 1, yellowmap[3]); + y += 11; + + // level image area { - if (ultimate_selectable) - V_DrawCenteredString(SP_LoadDef.x+92, LOADBARHEIGHT - 1, V_ORANGEMAP, "ULTIMATE MODE"); + if ((savegameinfo[savetodraw].lives == -42) + || (savegameinfo[savetodraw].lives == -666)) + { + V_DrawFill(x, y, 80, 50, 31); + M_DrawStaticBox(x, y, V_80TRANS, 80, 50); + } + else + { + patch_t *patch; + if (savegameinfo[savetodraw].gamemap & 8192) + patch = savselp[3]; + else + { + lumpnum_t lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName((savegameinfo[savetodraw].gamemap) & 8191))); + if (lumpnum != LUMPERROR) + patch = W_CachePatchNum(lumpnum, PU_CACHE); + else + patch = savselp[5]; + } + V_DrawSmallScaledPatch(x, y, 0, patch); + } + + y += 41; + + if (savegameinfo[savetodraw].lives == -42) + V_DrawRightAlignedThinString(x + 79, y, V_GRAYMAP, "NEW GAME"); + else if (savegameinfo[savetodraw].lives == -666) + V_DrawRightAlignedThinString(x + 79, y, V_REDMAP, "CAN'T LOAD!"); + else if (savegameinfo[savetodraw].gamemap & 8192) + V_DrawRightAlignedThinString(x + 79, y, V_GREENMAP, "CLEAR!"); else - V_DrawCenteredString(SP_LoadDef.x+92, LOADBARHEIGHT - 1, V_ORANGEMAP, "PLAY WITHOUT SAVING"); + V_DrawRightAlignedThinString(x + 79, y, V_YELLOWMAP, savegameinfo[savetodraw].levelname); + } + + if ((savegameinfo[savetodraw].lives == -42) + || (savegameinfo[savetodraw].lives == -666)) continue; + + y += 64; + + // tiny emeralds + { + INT32 j, workx = x + 6; + for (j = 0; j < 7; ++j) + { + if (savegameinfo[savetodraw].numemeralds & (1 << j)) + V_DrawScaledPatch(workx, y, 0, emeraldpics[1][j]); + workx += 10; + } } - if (savegameinfo[i%MAXSAVEGAMES].lives == -42) - V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, V_TRANSLUCENT, "NO DATA"); - else if (savegameinfo[i%MAXSAVEGAMES].lives == -666) - V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, V_REDMAP, "CORRUPT SAVE FILE"); - else if (savegameinfo[i%MAXSAVEGAMES].gamemap & 8192) - V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, V_GREENMAP, "CLEAR!"); - else - V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, 0, va("%s", savegameinfo[i%MAXSAVEGAMES].levelname)); + y -= 13; + + // character heads, lives, and continues + { + spritedef_t *sprdef; + spriteframe_t *sprframe; + patch_t *patch; + UINT8 *colormap = NULL; + + INT32 tempx = (x+40)<<FRACBITS, tempy = y<<FRACBITS, flip = 0, calc; + + // botskin first + if (savegameinfo[savetodraw].botskin) + { + skin_t *charbotskin = &skins[savegameinfo[savetodraw].botskin-1]; + sprdef = &charbotskin->sprites[SPR2_SIGN]; + if (!sprdef->numframes) + goto skipbot; + colormap = R_GetTranslationColormap(savegameinfo[savetodraw].botskin, charbotskin->prefcolor, 0); + sprframe = &sprdef->spriteframes[0]; + patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + + V_DrawFixedPatch( + tempx + (18<<FRACBITS), + tempy - (4<<FRACBITS), + charbotskin->highresscale, + 0, patch, colormap); + + Z_Free(colormap); + + tempx -= (15<<FRACBITS); + flip = V_FLIP; + } +skipbot: + // signpost image + if (!charskin) // shut up compiler + goto skipsign; + sprdef = &charskin->sprites[SPR2_SIGN]; + colormap = R_GetTranslationColormap(savegameinfo[savetodraw].skinnum, charskin->prefcolor, 0); + if (!sprdef->numframes) + goto skipsign; + sprframe = &sprdef->spriteframes[0]; + patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + if ((calc = SHORT(patch->topoffset) - 42) > 0) + tempy += ((4+calc)<<FRACBITS); + + V_DrawFixedPatch( + tempx, + tempy, + charskin->highresscale, + flip, patch, colormap); + +skipsign: + y += 25; + + tempx = x + 10; + if (savegameinfo[savetodraw].lives != INFLIVES + && savegameinfo[savetodraw].lives > 9) + tempx -= 4; + + if (!charskin) // shut up compiler + goto skiplife; + + // lives + sprdef = &charskin->sprites[SPR2_LIFE]; + if (!sprdef->numframes) + goto skiplife; + sprframe = &sprdef->spriteframes[0]; + patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + + V_DrawFixedPatch( + (tempx + 4)<<FRACBITS, + (y + 6)<<FRACBITS, + charskin->highresscale/2, + 0, patch, colormap); +skiplife: + if (colormap) + Z_Free(colormap); + + patch = W_CachePatchName("STLIVEX", PU_CACHE); + + V_DrawScaledPatch(tempx + 9, y + 2, 0, patch); + tempx += 16; + if (savegameinfo[savetodraw].lives == INFLIVES) + V_DrawCharacter(tempx, y + 1, '\x16', false); + else + V_DrawString(tempx, y, 0, va("%d", savegameinfo[savetodraw].lives)); - //Draw the save slot number on the right side - V_DrawRightAlignedString(SP_LoadDef.x+192, LOADBARHEIGHT - 1, 0, va("%d",(i%MAXSAVEGAMES) + 1)); + tempx = x + 47; + if (savegameinfo[savetodraw].continues > 9) + tempx -= 4; + + // continues + if (savegameinfo[savetodraw].continues > 0) + { + V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTSAVE", PU_CACHE)); + V_DrawScaledPatch(tempx + 9, y + 2, 0, patch); + V_DrawString(tempx + 16, y, 0, va("%d", savegameinfo[savetodraw].continues)); + } + else + { + V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTNONE", PU_CACHE)); + V_DrawScaledPatch(tempx + 9, y + 2, 0, W_CachePatchName("STNONEX", PU_CACHE)); + V_DrawString(tempx + 16, y, V_GRAYMAP, "0"); + } + } } +} + +static void M_DrawLoad(void) +{ + M_DrawMenuTitle(); + + if (loadgamescroll > 1 || loadgamescroll < -1) + loadgamescroll = 2*loadgamescroll/3; + else + loadgamescroll = 0; - //Draw cursors on both sides. - V_DrawScaledPatch( 32, CURSORHEIGHT, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); - V_DrawScaledPatch(274, CURSORHEIGHT, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); + if (loadgameoffset > 1) + loadgameoffset = 2*loadgameoffset/3; + else + loadgameoffset = 0; M_DrawLoadGameData(); - - //finishing the movement illusion - if (menumovedir) - menumovedir += ((menumovedir > 0) ? 1 : -1); - if (abs(menumovedir) > 3) - menumovedir = 0; } -#undef LOADBARHEIGHT -#undef CURSORHEIGHT // // User wants to load this game @@ -5123,7 +7140,7 @@ static void M_LoadSelect(INT32 choice) if (saveSlotSelected == NOSAVESLOT) //last slot is play without saving { M_NewGame(); - cursaveslot = -1; + cursaveslot = 0; return; } @@ -5132,8 +7149,8 @@ static void M_LoadSelect(INT32 choice) // This slot is empty, so start a new game here. M_NewGame(); } - else if (savegameinfo[saveSlotSelected].gamemap & 8192) // Completed - M_LoadGameLevelSelect(saveSlotSelected + 1); + else if (savegameinfo[saveSlotSelected-1].gamemap & 8192) // Completed + M_LoadGameLevelSelect(0); else G_LoadGame((UINT32)saveSlotSelected, 0); @@ -5155,12 +7172,11 @@ static void M_ReadSavegameInfo(UINT32 slot) INT32 fake; // Dummy variable char temp[sizeof(timeattackfolder)]; char vcheck[VERSIONSIZE]; -#ifdef SAVEGAMES_OTHERVERSIONS - boolean oldversion = false; -#endif sprintf(savename, savegamename, slot); + slot--; + length = FIL_ReadFile(savename, &savebuffer); if (length == 0) { @@ -5176,14 +7192,7 @@ static void M_ReadSavegameInfo(UINT32 slot) // Version check memset(vcheck, 0, sizeof (vcheck)); sprintf(vcheck, "version %d", VERSION); - if (strcmp((const char *)save_p, (const char *)vcheck)) - { -#ifdef SAVEGAMES_OTHERVERSIONS - oldversion = true; -#else - BADSAVE // Incompatible versions? -#endif - } + if (strcmp((const char *)save_p, (const char *)vcheck)) BADSAVE save_p += VERSIONSIZE; // dearchive all the modifications @@ -5195,30 +7204,19 @@ static void M_ReadSavegameInfo(UINT32 slot) if (((fake-1) & 8191) >= NUMMAPS) BADSAVE if(!mapheaderinfo[(fake-1) & 8191]) - { savegameinfo[slot].levelname[0] = '\0'; - savegameinfo[slot].actnum = 0; - } else { - strcpy(savegameinfo[slot].levelname, mapheaderinfo[(fake-1) & 8191]->lvlttl); - savegameinfo[slot].actnum = mapheaderinfo[(fake-1) & 8191]->actnum; - } + strlcpy(savegameinfo[slot].levelname, mapheaderinfo[(fake-1) & 8191]->lvlttl, 17+1); -#ifdef SAVEGAMES_OTHERVERSIONS - if (oldversion) - { - if (fake == 24) //meh, let's count old Clear! saves too - fake |= 8192; - fake |= 16384; // marker for outdated version + if (strlen(mapheaderinfo[(fake-1) & 8191]->lvlttl) >= 17) + strcpy(savegameinfo[slot].levelname+17-3, "..."); } -#endif + savegameinfo[slot].gamemap = fake; CHECKPOS - fake = READUINT16(save_p)-357; // emeralds - - savegameinfo[slot].numemeralds = (UINT8)fake; + savegameinfo[slot].numemeralds = READUINT16(save_p)-357; // emeralds CHECKPOS READSTRINGN(save_p, temp, sizeof(temp)); // mod it belongs to @@ -5227,39 +7225,25 @@ static void M_ReadSavegameInfo(UINT32 slot) // P_UnArchivePlayer() CHECKPOS - savegameinfo[slot].skincolor = READUINT8(save_p); - CHECKPOS - savegameinfo[slot].skinnum = READUINT8(save_p); + fake = READUINT16(save_p); + savegameinfo[slot].skinnum = fake & ((1<<5) - 1); + if (savegameinfo[slot].skinnum >= numskins + || !R_SkinUsable(-1, savegameinfo[slot].skinnum)) + BADSAVE + savegameinfo[slot].botskin = fake >> 5; + if (savegameinfo[slot].botskin-1 >= numskins + || !R_SkinUsable(-1, savegameinfo[slot].botskin-1)) + BADSAVE CHECKPOS - (void)READINT32(save_p); // Score - + savegameinfo[slot].numgameovers = READUINT8(save_p); // numgameovers CHECKPOS - savegameinfo[slot].lives = READINT32(save_p); // lives + savegameinfo[slot].lives = READSINT8(save_p); // lives + CHECKPOS + (void)READINT32(save_p); // Score CHECKPOS savegameinfo[slot].continues = READINT32(save_p); // continues - if (fake & (1<<10)) - { - CHECKPOS - savegameinfo[slot].botskin = READUINT8(save_p); - if (savegameinfo[slot].botskin-1 >= numskins) - savegameinfo[slot].botskin = 0; - CHECKPOS - savegameinfo[slot].botcolor = READUINT8(save_p); // because why not. - } - else - savegameinfo[slot].botskin = 0; - - if (savegameinfo[slot].botskin) - snprintf(savegameinfo[slot].playername, 36, "%s & %s", - skins[savegameinfo[slot].skinnum].realname, - skins[savegameinfo[slot].botskin-1].realname); - else - strcpy(savegameinfo[slot].playername, skins[savegameinfo[slot].skinnum].realname); - - savegameinfo[slot].playername[31] = 0; - // File end marker check CHECKPOS if (READUINT8(save_p) != 0x1d) BADSAVE; @@ -5278,23 +7262,78 @@ static void M_ReadSavegameInfo(UINT32 slot) static void M_ReadSaveStrings(void) { FILE *handle; - UINT32 i; + SINT8 i; char name[256]; + boolean nofile[MAXSAVEGAMES-1]; + SINT8 tolerance = 3; // empty slots at any time + UINT8 lastseen = 0; + + loadgamescroll = 0; + loadgameoffset = 14; - for (i = 0; i < MAXSAVEGAMES; i++) + for (i = 1; (i < MAXSAVEGAMES); i++) // slot 0 is no save { snprintf(name, sizeof name, savegamename, i); name[sizeof name - 1] = '\0'; handle = fopen(name, "rb"); - if (handle == NULL) + if ((nofile[i-1] = (handle == NULL))) + continue; + fclose(handle); + lastseen = i; + } + + if (savegameinfo) + Z_Free(savegameinfo); + savegameinfo = NULL; + + if (lastseen < saveSlotSelected) + lastseen = saveSlotSelected; + + i = lastseen; + + for (; (lastseen > 0 && tolerance); lastseen--) + { + if (nofile[lastseen-1]) + tolerance--; + } + + if ((i += tolerance+1) > MAXSAVEGAMES) // show 3 empty slots at minimum + i = MAXSAVEGAMES; + + numsaves = i; + savegameinfo = Z_Realloc(savegameinfo, numsaves*sizeof(saveinfo_t), PU_STATIC, NULL); + if (!savegameinfo) + I_Error("Insufficient memory to prepare save platter"); + + for (; i > 0; i--) + { + if (nofile[i-1] == true) { - savegameinfo[i].lives = -42; + savegameinfo[i-1].lives = -42; continue; } - fclose(handle); M_ReadSavegameInfo(i); } + + if (savselp[0]) // never going to have some provided but not all, saves individually checking + { + W_UnlockCachedPatch(savselp[0]); + W_UnlockCachedPatch(savselp[1]); + W_UnlockCachedPatch(savselp[2]); + + W_UnlockCachedPatch(savselp[3]); + W_UnlockCachedPatch(savselp[4]); + W_UnlockCachedPatch(savselp[5]); + } + + savselp[0] = W_CachePatchName("SAVEBACK", PU_STATIC); + savselp[1] = W_CachePatchName("SAVENONE", PU_STATIC); + savselp[2] = W_CachePatchName("ULTIMATE", PU_STATIC); + + savselp[3] = W_CachePatchName("GAMEDONE", PU_STATIC); + savselp[4] = W_CachePatchName("BLACXLVL", PU_STATIC); + savselp[5] = W_CachePatchName("BLANKLVL", PU_STATIC); } // @@ -5312,8 +7351,19 @@ static void M_SaveGameDeleteResponse(INT32 ch) name[sizeof name - 1] = '\0'; remove(name); - // Refresh savegame menu info - M_ReadSaveStrings(); + BwehHehHe(); + M_ReadSaveStrings(); // reload the menu +} + +static void M_SaveGameUltimateResponse(INT32 ch) +{ + if (ch != 'y' && ch != KEY_ENTER) + return; + + S_StartSound(NULL, sfx_menu1); + M_LoadSelect(saveSlotSelected); + SP_PlayerDef.prevMenu = MessageDef.prevMenu; + MessageDef.prevMenu = &SP_PlayerDef; } static void M_HandleLoadSave(INT32 choice) @@ -5322,26 +7372,46 @@ static void M_HandleLoadSave(INT32 choice) switch (choice) { - case KEY_DOWNARROW: - S_StartSound(NULL, sfx_menu1); + case KEY_RIGHTARROW: + S_StartSound(NULL, sfx_s3kb7); ++saveSlotSelected; - if (saveSlotSelected >= MAXSAVEGAMES) - saveSlotSelected -= MAXSAVEGAMES; - menumovedir = 1; + if (saveSlotSelected >= numsaves) + saveSlotSelected -= numsaves; + loadgamescroll = 90; break; - case KEY_UPARROW: - S_StartSound(NULL, sfx_menu1); + case KEY_LEFTARROW: + S_StartSound(NULL, sfx_s3kb7); --saveSlotSelected; if (saveSlotSelected < 0) - saveSlotSelected += MAXSAVEGAMES; - menumovedir = -1; + saveSlotSelected += numsaves; + loadgamescroll = -90; break; case KEY_ENTER: - S_StartSound(NULL, sfx_menu1); - if (savegameinfo[saveSlotSelected].lives != -666) // don't allow loading of "bad saves" + if (ultimate_selectable && saveSlotSelected == NOSAVESLOT) + { + loadgamescroll = 0; + S_StartSound(NULL, sfx_skid); + M_StartMessage("Are you sure you want to play\n\x85ultimate mode\x80? It isn't remotely fair,\nand you don't even get an emblem for it.\n\n(Press 'Y' to confirm)\n",M_SaveGameUltimateResponse,MM_YESNO); + } + else if (saveSlotSelected != NOSAVESLOT && savegameinfo[saveSlotSelected-1].lives == -42 && !(!modifiedgame || savemoddata)) + { + loadgamescroll = 0; + 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); + } + else if (saveSlotSelected == NOSAVESLOT || savegameinfo[saveSlotSelected-1].lives != -666) // don't allow loading of "bad saves" + { + loadgamescroll = 0; + S_StartSound(NULL, sfx_menu1); M_LoadSelect(saveSlotSelected); + } + else if (!loadgameoffset) + { + S_StartSound(NULL, sfx_lose); + loadgameoffset = 14; + } break; case KEY_ESCAPE: @@ -5349,11 +7419,25 @@ static void M_HandleLoadSave(INT32 choice) break; case KEY_BACKSPACE: - S_StartSound(NULL, sfx_menu1); // Don't allow people to 'delete' "Play without Saving." // Nor allow people to 'delete' slots with no saves in them. - if (saveSlotSelected != NOSAVESLOT && savegameinfo[saveSlotSelected].lives != -42) - M_StartMessage(M_GetText("Are you sure you want to delete\nthis save game?\n\n(Press 'Y' to confirm)\n"),M_SaveGameDeleteResponse,MM_YESNO); + if (saveSlotSelected != NOSAVESLOT && savegameinfo[saveSlotSelected-1].lives != -42) + { + loadgamescroll = 0; + S_StartSound(NULL, sfx_skid); + M_StartMessage(va("Are you sure you want to delete\nsave file %d?\n\n(Press 'Y' to confirm)\n", saveSlotSelected),M_SaveGameDeleteResponse,MM_YESNO); + } + else if (!loadgameoffset) + { + if (saveSlotSelected == NOSAVESLOT && ultimate_selectable) + { + ultimate_selectable = false; + S_StartSound(NULL, sfx_strpst); + } + else + S_StartSound(NULL, sfx_lose); + loadgameoffset = 14; + } break; } if (exitmenu) @@ -5362,6 +7446,28 @@ static void M_HandleLoadSave(INT32 choice) M_SetupNextMenu(currentMenu->prevMenu); else M_ClearMenus(true); + Z_Free(savegameinfo); + savegameinfo = NULL; + } +} + +static void M_FirstTimeResponse(INT32 ch) +{ + S_StartSound(NULL, sfx_menu1); + + if (ch == KEY_ESCAPE) + return; + + if (ch != 'y' && ch != KEY_ENTER) + { + CV_SetValue(&cv_tutorialprompt, 0); + M_ReadSaveStrings(); + MessageDef.prevMenu = &SP_LoadDef; // calls M_SetupNextMenu + } + else + { + M_StartTutorial(0); + MessageDef.prevMenu = &MessageDef; // otherwise, the controls prompt won't fire } } @@ -5372,6 +7478,13 @@ static void M_LoadGame(INT32 choice) { (void)choice; + if (tutorialmap && cv_tutorialprompt.value) + { + M_StartMessage("Do you want to \x82play a brief Tutorial\x80?\n\nWe highly recommend this because \nthe controls are slightly different \nfrom other games.\n\nPress 'Y' or 'Enter' to go\nPress 'N' or any key to skip\n", + M_FirstTimeResponse, MM_YESNO); + return; + } + M_ReadSaveStrings(); M_SetupNextMenu(&SP_LoadDef); } @@ -5381,14 +7494,15 @@ static void M_LoadGame(INT32 choice) // void M_ForceSaveSlotSelected(INT32 sslot) { - // Already there? Out of bounds? Whatever, then! - if (sslot == saveSlotSelected || sslot >= MAXSAVEGAMES) + loadgameoffset = 14; + + // Already there? Whatever, then! + if (sslot == saveSlotSelected) return; - // Figure out whether to display up movement or down movement - menumovedir = (saveSlotSelected - sslot) > 0 ? -1 : 1; - if (abs(saveSlotSelected - sslot) > (MAXSAVEGAMES>>1)) - menumovedir *= -1; + loadgamescroll = 90; + if (saveSlotSelected <= numsaves/2) + loadgamescroll = -loadgamescroll; saveSlotSelected = sslot; } @@ -5399,25 +7513,145 @@ void M_ForceSaveSlotSelected(INT32 sslot) static void M_SetupChoosePlayer(INT32 choice) { + INT32 skinnum; + UINT8 i; + UINT8 firstvalid = 255; + UINT8 lastvalid = 0; + boolean allowed = false; + char *name; (void)choice; - if (mapheaderinfo[startmap-1] && mapheaderinfo[startmap-1]->forcecharacter[0] != '\0') + SP_PlayerMenu[0].status &= ~IT_DYBIGSPACE; // Correcting a hack that may be made below. + + for (i = 0; i < 32; i++) // Handle charsels, availability, and unlocks. { - M_ChoosePlayer(0); //oh for crying out loud just get STARTED, it doesn't matter! - return; + if (description[i].used) // If the character's disabled through SOC, there's nothing we can do for it. + { + name = strtok(Z_StrDup(description[i].skinname), "&"); + skinnum = R_SkinAvailable(name); + if ((skinnum != -1) && (R_SkinUsable(-1, skinnum))) + { + // Handling order. + if (firstvalid == 255) + firstvalid = i; + else + { + description[i].prev = lastvalid; + description[lastvalid].next = i; + } + lastvalid = i; + + if (i == char_on) + allowed = true; + + if (description[i].picname[0] == '\0') + strncpy(description[i].picname, skins[skinnum].charsel, 8); + } + // else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them. + Z_Free(name); + } } - if (Playing() == false) + if ((firstvalid != 255) + && !(mapheaderinfo[startmap-1] + && (mapheaderinfo[startmap-1]->forcecharacter[0] != '\0') + ) + ) + { // One last bit of order we can't do in the iteration above. + description[firstvalid].prev = lastvalid; + description[lastvalid].next = firstvalid; + } + else // We're being forced into a specific character, so might as well. { - S_StopMusic(); - S_ChangeMusicInternal("chrsel", true); + SP_PlayerMenu[0].status |= IT_DYBIGSPACE; // This is a dummy flag hack to make a non-IT_CALL character in slot 0 not softlock the game. + M_ChoosePlayer(0); + return; } + if (Playing() == false) + M_ChangeMenuMusic("_chsel", true); + SP_PlayerDef.prevMenu = currentMenu; M_SetupNextMenu(&SP_PlayerDef); - char_scroll = itemOn*128*FRACUNIT; // finish scrolling the menu + if (!allowed) + { + char_on = firstvalid; + if (startchar > 0 && startchar < 32) + { + INT16 workchar = startchar; + while (workchar--) + char_on = description[char_on].next; + } + } + char_scroll = 0; // finish scrolling the menu Z_Free(char_notes); - char_notes = NULL; + char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[char_on].notes); +} + +// +// M_HandleChoosePlayerMenu +// +// Reacts to your key inputs. Basically a mini menu thinker. +// +static void M_HandleChoosePlayerMenu(INT32 choice) +{ + boolean exitmenu = false; // exit to previous menu + INT32 selectval; + + switch (choice) + { + case KEY_DOWNARROW: + if ((selectval = description[char_on].next) != char_on) + { + S_StartSound(NULL,sfx_s3kb7); + char_on = selectval; + char_scroll = -128*FRACUNIT; + Z_Free(char_notes); + char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[char_on].notes); + } + else if (!char_scroll) + { + S_StartSound(NULL,sfx_s3kb7); + char_scroll = 16*FRACUNIT; + } + break; + + case KEY_UPARROW: + if ((selectval = description[char_on].prev) != char_on) + { + S_StartSound(NULL,sfx_s3kb7); + char_on = selectval; + char_scroll = 128*FRACUNIT; + Z_Free(char_notes); + char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[char_on].notes); + } + else if (!char_scroll) + { + S_StartSound(NULL,sfx_s3kb7); + char_scroll = -16*FRACUNIT; + } + break; + + case KEY_ENTER: + S_StartSound(NULL, sfx_menu1); + M_ChoosePlayer(char_on); + break; + + case KEY_ESCAPE: + exitmenu = true; + break; + + default: + break; + } + + if (exitmenu) + { + if (currentMenu->prevMenu) + M_SetupNextMenu(currentMenu->prevMenu); + else + M_ClearMenus(true); + } } // Draw the choose player setup menu, had some fun with player anim @@ -5425,125 +7659,88 @@ static void M_DrawSetupChoosePlayerMenu(void) { const INT32 my = 24; patch_t *patch; - INT32 i, o, j; - char *picname; + INT32 i, o; + UINT8 prev, next; // Black BG - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); - //V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); + if (curbgcolor >= 0) + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); + else if (!curbghide || !titlemapinaction) + F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + if (curfadevalue) + V_DrawFadeScreen(0xFF00, curfadevalue); // Character select profile images!1 M_DrawTextBox(0, my, 16, 20); - if (abs(itemOn*128*FRACUNIT - char_scroll) > 256*FRACUNIT) - char_scroll = itemOn*128*FRACUNIT; - else if (itemOn*128*FRACUNIT - char_scroll > 128*FRACUNIT) - char_scroll += 48*FRACUNIT; - else if (itemOn*128*FRACUNIT - char_scroll < -128*FRACUNIT) - char_scroll -= 48*FRACUNIT; - else if (itemOn*128*FRACUNIT > char_scroll+16*FRACUNIT) - char_scroll += 16*FRACUNIT; - else if (itemOn*128*FRACUNIT < char_scroll-16*FRACUNIT) - char_scroll -= 16*FRACUNIT; + if (abs(char_scroll) > FRACUNIT) + char_scroll -= (char_scroll>>2); else // close enough. - char_scroll = itemOn*128*FRACUNIT; // just be exact now. - i = (char_scroll+16*FRACUNIT)/(128*FRACUNIT); - o = ((char_scroll/FRACUNIT)+16)%128; + char_scroll = 0; // just be exact now. - // prev character - if (i-1 >= 0 && PlayerMenu[i-1].status != IT_DISABLED - && o < 32) - { - picname = description[i-1].picname; - if (picname[0] == '\0') - { - picname = strtok(Z_StrDup(description[i-1].skinname), "&"); - for (j = 0; j < numskins; j++) - if (stricmp(skins[j].name, picname) == 0) - { - Z_Free(picname); - picname = skins[j].charsel; - break; - } - if (j == numskins) // AAAAAAAAAA - picname = skins[0].charsel; - } - patch = W_CachePatchName(picname, PU_CACHE); - if (SHORT(patch->width) >= 256) - V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT/2, 0, patch, 0, SHORT(patch->height) - 64 + o*2, SHORT(patch->width), SHORT(patch->height)); - else - V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT, 0, patch, 0, SHORT(patch->height) - 32 + o, SHORT(patch->width), SHORT(patch->height)); - W_UnlockCachedPatch(patch); - } + o = (char_scroll >> FRACBITS) + 16; - // next character - if (i+1 < currentMenu->numitems && PlayerMenu[i+1].status != IT_DISABLED - && o < 128) + if (o < 0) // A little hacky... { - picname = description[i+1].picname; - if (picname[0] == '\0') - { - picname = strtok(Z_StrDup(description[i+1].skinname), "&"); - for (j = 0; j < numskins; j++) - if (stricmp(skins[j].name, picname) == 0) - { - Z_Free(picname); - picname = skins[j].charsel; - break; - } - if (j == numskins) // AAAAAAAAAA - picname = skins[0].charsel; - } - patch = W_CachePatchName(picname, PU_CACHE); - if (SHORT(patch->width) >= 256) - V_DrawCroppedPatch(8<<FRACBITS, (my + 168 - o)<<FRACBITS, FRACUNIT/2, 0, patch, 0, 0, SHORT(patch->width), o*2); - else - V_DrawCroppedPatch(8<<FRACBITS, (my + 168 - o)<<FRACBITS, FRACUNIT, 0, patch, 0, 0, SHORT(patch->width), o); - W_UnlockCachedPatch(patch); + i = description[char_on].prev; + o += 128; } + else + i = char_on; + + // Get prev character... + prev = description[i].prev; - // current character - if (i < currentMenu->numitems && PlayerMenu[i].status != IT_DISABLED) + if (prev != i) // If there's more than one character available... { - picname = description[i].picname; - if (picname[0] == '\0') - { - picname = strtok(Z_StrDup(description[i].skinname), "&"); - for (j = 0; j < numskins; j++) - if (stricmp(skins[j].name, picname) == 0) - { - Z_Free(picname); - picname = skins[j].charsel; - break; - } - if (j == numskins) // AAAAAAAAAA - picname = skins[0].charsel; - } - patch = W_CachePatchName(picname, PU_CACHE); - if (o >= 0 && o <= 32) + // Let's get the next character now. + next = description[i].next; + + // Draw prev character if it's visible and its number isn't greater than the current one or there's more than two + if (o < 32) { + patch = W_CachePatchName(description[prev].picname, PU_CACHE); if (SHORT(patch->width) >= 256) - V_DrawSmallScaledPatch(8, my + 40 - o, 0, patch); + V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT/2, 0, patch, 0, SHORT(patch->height) + 2*(o-32), SHORT(patch->width), 64 - 2*o); else - V_DrawScaledPatch(8, my + 40 - o, 0, patch); + V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT, 0, patch, 0, SHORT(patch->height) + o - 32, SHORT(patch->width), 32 - o); + W_UnlockCachedPatch(patch); } - else + + // Draw next character if it's visible and its number isn't less than the current one or there's more than two + if (o < 128) // (next != i) was previously a part of this, but it's implicitly true if (prev != i) is true. { + patch = W_CachePatchName(description[next].picname, PU_CACHE); if (SHORT(patch->width) >= 256) - V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT/2, 0, patch, 0, (o - 32)*2, SHORT(patch->width), SHORT(patch->height)); + V_DrawCroppedPatch(8<<FRACBITS, (my + 168 - o)<<FRACBITS, FRACUNIT/2, 0, patch, 0, 0, SHORT(patch->width), 2*o); else - V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT, 0, patch, 0, o - 32, SHORT(patch->width), SHORT(patch->height)); + V_DrawCroppedPatch(8<<FRACBITS, (my + 168 - o)<<FRACBITS, FRACUNIT, 0, patch, 0, 0, SHORT(patch->width), o); + W_UnlockCachedPatch(patch); } - W_UnlockCachedPatch(patch); } + patch = W_CachePatchName(description[i].picname, PU_CACHE); + if (o >= 0 && o <= 32) + { + if (SHORT(patch->width) >= 256) + V_DrawSmallScaledPatch(8, my + 40 - o, 0, patch); + else + V_DrawScaledPatch(8, my + 40 - o, 0, patch); + } + else + { + if (SHORT(patch->width) >= 256) + V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT/2, 0, patch, 0, (o-32)*2, SHORT(patch->width), SHORT(patch->height) - 2*(o-32)); + else + V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT, 0, patch, 0, (o-32), SHORT(patch->width), SHORT(patch->height) - (o-32)); + } + W_UnlockCachedPatch(patch); + // draw title (or big pic) M_DrawMenuTitle(); // Character description M_DrawTextBox(136, my, 21, 20); - if (!char_notes) - char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[itemOn].notes); V_DrawString(146, my + 9, V_RETURN8|V_ALLOWLOWERCASE, char_notes); } @@ -5554,11 +7751,11 @@ static void M_ChoosePlayer(INT32 choice) INT32 skinnum; boolean ultmode = (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT); - // skip this if forcecharacter - if (mapheaderinfo[startmap-1] && mapheaderinfo[startmap-1]->forcecharacter[0] == '\0') + // skip this if forcecharacter or no characters available + if (!(SP_PlayerMenu[0].status & IT_DYBIGSPACE)) { // M_SetupChoosePlayer didn't call us directly, that means we've been properly set up. - char_scroll = itemOn*128*FRACUNIT; // finish scrolling the menu + char_scroll = 0; // finish scrolling the menu M_DrawSetupChoosePlayerMenu(); // draw the finally selected character one last time for the fadeout } M_ClearMenus(true); @@ -5584,13 +7781,21 @@ static void M_ChoosePlayer(INT32 choice) } if (startmap != spstage_start) - cursaveslot = -1; + cursaveslot = 0; - lastmapsaved = 0; + //lastmapsaved = 0; gamecomplete = false; G_DeferedInitNew(ultmode, G_BuildMapName(startmap), (UINT8)skinnum, false, fromlevelselect); COM_BufAddText("dummyconsvar 1\n"); // G_DeferedInitNew doesn't do this + + if (levelselect.rows) + Z_Free(levelselect.rows); + levelselect.rows = NULL; + + if (savegameinfo) + Z_Free(savegameinfo); + savegameinfo = NULL; } // =============== @@ -5617,29 +7822,30 @@ static void M_Statistics(INT32 choice) if (!(mapheaderinfo[i]->typeoflevel & TOL_SP) || (mapheaderinfo[i]->menuflags & LF2_HIDEINSTATS)) continue; - if (!mapvisited[i]) + if (!(mapvisited[i] & MV_MAX)) continue; statsMapList[j++] = i; } statsMapList[j] = -1; - statsMax = j - 13 + numextraemblems; + statsMax = j - 11 + numextraemblems; statsLocation = 0; if (statsMax < 0) statsMax = 0; - M_SetupNextMenu(&SP_GameStatsDef); + M_SetupNextMenu(&SP_LevelStatsDef); } static void M_DrawStatsMaps(int location) { - INT32 y = 76, i = -1; + INT32 y = 80, i = -1; INT16 mnum; extraemblem_t *exemblem; + boolean dotopname = true, dobottomarrow = (location < statsMax); - V_DrawString(20, y-12, 0, "LEVEL NAME"); - V_DrawString(248, y-12, 0, "EMBLEMS"); + if (location) + V_DrawString(10, y-(skullAnimCounter/5), V_YELLOWMAP, "\x1A"); while (statsMapList[++i] != -1) { @@ -5648,6 +7854,13 @@ static void M_DrawStatsMaps(int location) --location; continue; } + else if (dotopname) + { + V_DrawString(20, y, V_GREENMAP, "LEVEL NAME"); + V_DrawString(248, y, V_GREENMAP, "EMBLEMS"); + y += 8; + dotopname = false; + } mnum = statsMapList[i]; M_DrawMapEmblems(mnum+1, 292, y); @@ -5660,100 +7873,59 @@ static void M_DrawStatsMaps(int location) y += 8; if (y >= BASEVIDHEIGHT-8) - return; + goto bottomarrow; + } + if (dotopname && !location) + { + V_DrawString(20, y, V_GREENMAP, "LEVEL NAME"); + V_DrawString(248, y, V_GREENMAP, "EMBLEMS"); + y += 8; } + else if (location) + --location; // Extra Emblems for (i = -2; i < numextraemblems; ++i) { - if (location) - { - --location; - continue; - } - if (i == -1) - V_DrawString(20, y, V_GREENMAP, "EXTRA EMBLEMS"); - else if (i >= 0) { - exemblem = &extraemblems[i]; - - if (exemblem->collected) - V_DrawSmallMappedPatch(292, y, 0, W_CachePatchName(M_GetExtraEmblemPatch(exemblem), PU_CACHE), - R_GetTranslationColormap(TC_DEFAULT, M_GetExtraEmblemColor(exemblem), GTC_CACHE)); - else - V_DrawSmallScaledPatch(292, y, 0, W_CachePatchName("NEEDIT", PU_CACHE)); - - V_DrawString(20, y, V_YELLOWMAP, va("%s", exemblem->description)); - } - - y += 8; - - if (y >= BASEVIDHEIGHT-8) - return; - } -} - -static void M_DrawLevelStats(void) -{ - M_DrawMenuTitle(); - V_DrawCenteredString(BASEVIDWIDTH/2, 24, V_YELLOWMAP, "PAGE 2 OF 2"); - - V_DrawString(72, 48, 0, va("x %d/%d", M_CountEmblems(), numemblems+numextraemblems)); - V_DrawScaledPatch(40, 48-4, 0, W_CachePatchName("EMBLICON", PU_STATIC)); - - M_DrawStatsMaps(statsLocation); -} - -// Handle statistics. -static void M_HandleLevelStats(INT32 choice) -{ - boolean exitmenu = false; // exit to previous menu - - switch (choice) - { - case KEY_DOWNARROW: - S_StartSound(NULL, sfx_menu1); - if (statsLocation < statsMax) - ++statsLocation; - break; + V_DrawString(20, y, V_GREENMAP, "EXTRA EMBLEMS"); + if (location) + { + y += 8; + location++; + } + } + if (location) + { + --location; + continue; + } - case KEY_UPARROW: - S_StartSound(NULL, sfx_menu1); - if (statsLocation) - --statsLocation; - break; + if (i >= 0) + { + exemblem = &extraemblems[i]; - case KEY_RIGHTARROW: - S_StartSound(NULL, sfx_menu1); - statsLocation += (statsLocation+15 >= statsMax) ? statsMax-statsLocation : 15; - break; + if (exemblem->collected) + V_DrawSmallMappedPatch(292, y, 0, W_CachePatchName(M_GetExtraEmblemPatch(exemblem), PU_CACHE), + R_GetTranslationColormap(TC_DEFAULT, M_GetExtraEmblemColor(exemblem), GTC_CACHE)); + else + V_DrawSmallScaledPatch(292, y, 0, W_CachePatchName("NEEDIT", PU_CACHE)); - case KEY_LEFTARROW: - S_StartSound(NULL, sfx_menu1); - statsLocation -= (statsLocation < 15) ? statsLocation : 15; - break; + V_DrawString(20, y, V_YELLOWMAP, va("%s", exemblem->description)); + } - case KEY_ESCAPE: - exitmenu = true; - break; + y += 8; - case KEY_ENTER: - S_StartSound(NULL, sfx_menu1); - M_SetupNextMenu(&SP_GameStatsDef); - break; - } - if (exitmenu) - { - if (currentMenu->prevMenu) - M_SetupNextMenu(currentMenu->prevMenu); - else - M_ClearMenus(true); + if (y >= BASEVIDHEIGHT-8) + goto bottomarrow; } +bottomarrow: + if (dobottomarrow) + V_DrawString(10, y-8 + (skullAnimCounter/5), V_YELLOWMAP, "\x1B"); } -// Handle GAME statistics. -static void M_DrawGameStats(void) +static void M_DrawLevelStats(void) { char beststr[40]; @@ -5762,81 +7934,106 @@ static void M_DrawGameStats(void) UINT32 bestrings = 0; INT32 i; - INT32 mapsunfinished[3] = {0, 0, 0}; + INT32 mapsunfinished = 0; + boolean bestunfinished[3] = {false, false, false}; M_DrawMenuTitle(); - V_DrawCenteredString(BASEVIDWIDTH/2, 24, V_YELLOWMAP, "PAGE 1 OF 2"); - V_DrawString(32, 60, V_YELLOWMAP, "Total Play Time:"); - V_DrawRightAlignedString(BASEVIDWIDTH-32, 70, 0, va("%i hours, %i minutes, %i seconds", + V_DrawString(20, 24, V_YELLOWMAP, "Total Play Time:"); + V_DrawCenteredString(BASEVIDWIDTH/2, 32, 0, va("%i hours, %i minutes, %i seconds", G_TicsToHours(totalplaytime), G_TicsToMinutes(totalplaytime, false), G_TicsToSeconds(totalplaytime))); for (i = 0; i < NUMMAPS; i++) { + boolean mapunfinished = false; + if (!mapheaderinfo[i] || !(mapheaderinfo[i]->menuflags & LF2_RECORDATTACK)) continue; if (!mainrecords[i]) { - mapsunfinished[0]++; - mapsunfinished[1]++; - mapsunfinished[2]++; + mapsunfinished++; + bestunfinished[0] = bestunfinished[1] = bestunfinished[2] = true; continue; } if (mainrecords[i]->score > 0) bestscore += mainrecords[i]->score; else - mapsunfinished[0]++; + mapunfinished = bestunfinished[0] = true; if (mainrecords[i]->time > 0) besttime += mainrecords[i]->time; else - mapsunfinished[1]++; + mapunfinished = bestunfinished[1] = true; if (mainrecords[i]->rings > 0) bestrings += mainrecords[i]->rings; else - mapsunfinished[2]++; + mapunfinished = bestunfinished[2] = true; + if (mapunfinished) + mapsunfinished++; } - V_DrawCenteredString(BASEVIDWIDTH/2, 90, 0, "* COMBINED RECORDS *"); + V_DrawString(20, 48, 0, "Combined records:"); + + if (mapsunfinished) + V_DrawString(20, 56, V_REDMAP, va("(%d unfinished)", mapsunfinished)); + else + V_DrawString(20, 56, V_GREENMAP, "(complete)"); + + V_DrawString(36, 64, 0, va("x %d/%d", M_CountEmblems(), numemblems+numextraemblems)); + V_DrawSmallScaledPatch(20, 64, 0, W_CachePatchName("EMBLICON", PU_STATIC)); sprintf(beststr, "%u", bestscore); - V_DrawString(32, 100, V_YELLOWMAP, "SCORE:"); - V_DrawRightAlignedString(BASEVIDWIDTH-32, 100, 0, beststr); - if (mapsunfinished[0]) - V_DrawRightAlignedString(BASEVIDWIDTH-32, 108, V_REDMAP, va("(%d unfinished)", mapsunfinished[0])); + V_DrawString(BASEVIDWIDTH/2, 48, V_YELLOWMAP, "SCORE:"); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 48, (bestunfinished[0] ? V_REDMAP : 0), beststr); sprintf(beststr, "%i:%02i:%02i.%02i", G_TicsToHours(besttime), G_TicsToMinutes(besttime, false), G_TicsToSeconds(besttime), G_TicsToCentiseconds(besttime)); - V_DrawString(32, 120, V_YELLOWMAP, "TIME:"); - V_DrawRightAlignedString(BASEVIDWIDTH-32, 120, 0, beststr); - if (mapsunfinished[1]) - V_DrawRightAlignedString(BASEVIDWIDTH-32, 128, V_REDMAP, va("(%d unfinished)", mapsunfinished[1])); + V_DrawString(BASEVIDWIDTH/2, 56, V_YELLOWMAP, "TIME:"); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 56, (bestunfinished[1] ? V_REDMAP : 0), beststr); sprintf(beststr, "%u", bestrings); - V_DrawString(32, 140, V_YELLOWMAP, "RINGS:"); - V_DrawRightAlignedString(BASEVIDWIDTH-32, 140, 0, beststr); - if (mapsunfinished[2]) - V_DrawRightAlignedString(BASEVIDWIDTH-32, 148, V_REDMAP, va("(%d unfinished)", mapsunfinished[2])); + V_DrawString(BASEVIDWIDTH/2, 64, V_YELLOWMAP, "RINGS:"); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 64, (bestunfinished[2] ? V_REDMAP : 0), beststr); + + M_DrawStatsMaps(statsLocation); } -static void M_HandleGameStats(INT32 choice) +// Handle statistics. +static void M_HandleLevelStats(INT32 choice) { boolean exitmenu = false; // exit to previous menu switch (choice) { - case KEY_ESCAPE: - exitmenu = true; + case KEY_DOWNARROW: + S_StartSound(NULL, sfx_menu1); + if (statsLocation < statsMax) + ++statsLocation; break; - case KEY_ENTER: + case KEY_UPARROW: + S_StartSound(NULL, sfx_menu1); + if (statsLocation) + --statsLocation; + break; + + case KEY_PGDN: S_StartSound(NULL, sfx_menu1); - M_SetupNextMenu(&SP_LevelStatsDef); + statsLocation += (statsLocation+13 >= statsMax) ? statsMax-statsLocation : 13; + break; + + case KEY_PGUP: + S_StartSound(NULL, sfx_menu1); + statsLocation -= (statsLocation < 13) ? statsLocation : 13; + break; + + case KEY_ESCAPE: + exitmenu = true; break; } if (exitmenu) @@ -5857,13 +8054,16 @@ void M_DrawTimeAttackMenu(void) { INT32 i, x, y, cursory = 0; UINT16 dispstatus; - patch_t *PictureOfLevel, *PictureOfUrFace; - lumpnum_t lumpnum; - char beststr[40]; + patch_t *PictureOfUrFace; - S_ChangeMusicInternal("racent", true); // Eww, but needed for when user hits escape during demo playback + M_ChangeMenuMusic("_inter", true); // Eww, but needed for when user hits escape during demo playback - V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); + if (curbgcolor >= 0) + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); + else if (!curbghide || !titlemapinaction) + F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + if (curfadevalue) + V_DrawFadeScreen(0xFF00, curfadevalue); M_DrawMenuTitle(); @@ -5896,6 +8096,13 @@ void M_DrawTimeAttackMenu(void) // Should see nothing but strings V_DrawString(BASEVIDWIDTH - x - soffset - V_StringWidth(cv->string, 0), y, V_YELLOWMAP, cv->string); + if (i == itemOn) + { + V_DrawCharacter(BASEVIDWIDTH - x - soffset - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - x - soffset + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } } } @@ -5903,16 +8110,6 @@ void M_DrawTimeAttackMenu(void) V_DrawScaledPatch(currentMenu->x - 24, cursory, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); V_DrawString(currentMenu->x, cursory, V_YELLOWMAP, currentMenu->menuitems[itemOn].text); - // A 160x100 image of the level as entry MAPxxP - lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value))); - - if (lumpnum != LUMPERROR) - PictureOfLevel = W_CachePatchName(va("%sP", G_BuildMapName(cv_nextmap.value)), PU_CACHE); - else - PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); - - V_DrawSmallScaledPatch(208, 32, 0, PictureOfLevel); - // Character face! if (W_CheckNumForName(skins[cv_chooseskin.value-1].charsel) != LUMPERROR) { @@ -5928,16 +8125,31 @@ void M_DrawTimeAttackMenu(void) { emblem_t *em; INT32 yHeight; + patch_t *PictureOfLevel; + lumpnum_t lumpnum; + char beststr[40]; + + M_DrawLevelPlatterHeader(32-lsheadingheight/2, cv_nextmap.string, true, false); + + // A 160x100 image of the level as entry MAPxxP + lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value))); + + if (lumpnum != LUMPERROR) + PictureOfLevel = W_CachePatchName(va("%sP", G_BuildMapName(cv_nextmap.value)), PU_CACHE); + else + PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); + + V_DrawSmallScaledPatch(208, 32+lsheadingheight, 0, PictureOfLevel); - V_DrawCenteredString(104, 32, 0, "* LEVEL RECORDS *"); + V_DrawString(104 - 72, 32+lsheadingheight/2, 0, "* LEVEL RECORDS *"); if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->score) sprintf(beststr, "(none)"); else sprintf(beststr, "%u", mainrecords[cv_nextmap.value-1]->score); - V_DrawString(104-72, 48, V_YELLOWMAP, "SCORE:"); - V_DrawRightAlignedString(104+72, 48, V_ALLOWLOWERCASE, beststr); + V_DrawString(104-72, 48+lsheadingheight/2, V_YELLOWMAP, "SCORE:"); + V_DrawRightAlignedString(104+72, 48+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->time) sprintf(beststr, "(none)"); @@ -5946,16 +8158,16 @@ void M_DrawTimeAttackMenu(void) G_TicsToSeconds(mainrecords[cv_nextmap.value-1]->time), G_TicsToCentiseconds(mainrecords[cv_nextmap.value-1]->time)); - V_DrawString(104-72, 58, V_YELLOWMAP, "TIME:"); - V_DrawRightAlignedString(104+72, 58, V_ALLOWLOWERCASE, beststr); + V_DrawString(104-72, 58+lsheadingheight/2, V_YELLOWMAP, "TIME:"); + V_DrawRightAlignedString(104+72, 58+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->rings) sprintf(beststr, "(none)"); else sprintf(beststr, "%hu", mainrecords[cv_nextmap.value-1]->rings); - V_DrawString(104-72, 68, V_YELLOWMAP, "RINGS:"); - V_DrawRightAlignedString(104+72, 68, V_ALLOWLOWERCASE, beststr); + V_DrawString(104-72, 68+lsheadingheight/2, V_YELLOWMAP, "RINGS:"); + V_DrawRightAlignedString(104+72, 68+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); // Draw record emblems. em = M_GetLevelEmblems(cv_nextmap.value); @@ -5971,17 +8183,17 @@ void M_DrawTimeAttackMenu(void) } if (em->collected) - V_DrawSmallMappedPatch(104+76, yHeight, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE), + V_DrawSmallMappedPatch(104+76, yHeight+lsheadingheight/2, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE), R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE)); else - V_DrawSmallScaledPatch(104+76, yHeight, 0, W_CachePatchName("NEEDIT", PU_CACHE)); + V_DrawSmallScaledPatch(104+76, yHeight+lsheadingheight/2, 0, W_CachePatchName("NEEDIT", PU_CACHE)); skipThisOne: em = M_GetLevelEmblems(-1); } } - // ALWAYS DRAW level name and skin even when not on this menu! + // ALWAYS DRAW level and skin even when not on this menu! if (currentMenu != &SP_TimeAttackDef) { consvar_t *ncv; @@ -5989,27 +8201,30 @@ void M_DrawTimeAttackMenu(void) x = SP_TimeAttackDef.x; y = SP_TimeAttackDef.y; - for (i = 0; i < 2; ++i) - { - ncv = (consvar_t *)SP_TimeAttackMenu[i].itemaction; + V_DrawString(x, y + SP_TimeAttackMenu[talevel].alphaKey, V_TRANSLUCENT, SP_TimeAttackMenu[talevel].text); - V_DrawString(x, y + SP_TimeAttackMenu[i].alphaKey, V_TRANSLUCENT, SP_TimeAttackMenu[i].text); - V_DrawString(BASEVIDWIDTH - x - V_StringWidth(ncv->string, 0), - y + SP_TimeAttackMenu[i].alphaKey, V_YELLOWMAP|V_TRANSLUCENT, ncv->string); - } + ncv = (consvar_t *)SP_TimeAttackMenu[taplayer].itemaction; + V_DrawString(x, y + SP_TimeAttackMenu[taplayer].alphaKey, V_TRANSLUCENT, SP_TimeAttackMenu[taplayer].text); + V_DrawString(BASEVIDWIDTH - x - V_StringWidth(ncv->string, 0), y + SP_TimeAttackMenu[taplayer].alphaKey, V_YELLOWMAP|V_TRANSLUCENT, ncv->string); } } +static void M_TimeAttackLevelSelect(INT32 choice) +{ + (void)choice; + SP_TimeAttackLevelSelectDef.prevMenu = currentMenu; + M_SetupNextMenu(&SP_TimeAttackLevelSelectDef); +} + // Going to Time Attack menu... static void M_TimeAttack(INT32 choice) { (void)choice; - memset(skins_cons_t, 0, sizeof (skins_cons_t)); - + SP_TimeAttackDef.prevMenu = &MainDef; levellistmode = LLM_RECORDATTACK; // Don't be dependent on cv_newgametype - if (M_CountLevelsToShowInList() == 0) + if (!M_PrepareLevelPlatter(-1, true)) { M_StartMessage(M_GetText("No record-attackable levels found.\n"),NULL,MM_NOTHING); return; @@ -6017,119 +8232,168 @@ static void M_TimeAttack(INT32 choice) M_PatchSkinNameTable(); - M_PrepareLevelSelect(); + G_SetGamestate(GS_TIMEATTACK); // do this before M_SetupNextMenu so that menu meta state knows that we're switching M_SetupNextMenu(&SP_TimeAttackDef); - Nextmap_OnChange(); + if (!M_CanShowLevelInList(cv_nextmap.value-1, -1) && levelselect.rows[0].maplist[0]) + CV_SetValue(&cv_nextmap, levelselect.rows[0].maplist[0]); + else + Nextmap_OnChange(); itemOn = tastart; // "Start" is selected. - - G_SetGamestate(GS_TIMEATTACK); - S_ChangeMusicInternal("racent", true); } // Drawing function for Nights Attack void M_DrawNightsAttackMenu(void) { - patch_t *PictureOfLevel; - lumpnum_t lumpnum; - char beststr[40]; + INT32 i, x, y, cursory = 0; + UINT16 dispstatus; + + M_ChangeMenuMusic("_inter", true); // Eww, but needed for when user hits escape during demo playback - S_ChangeMusicInternal("racent", true); // Eww, but needed for when user hits escape during demo playback + if (curbgcolor >= 0) + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); + else if (!curbghide || !titlemapinaction) + F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + if (curfadevalue) + V_DrawFadeScreen(0xFF00, curfadevalue); - V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); + M_DrawMenuTitle(); // draw menu (everything else goes on top of it) - M_DrawGenericMenu(); + // Sadly we can't just use generic mode menus because we need some extra hacks + x = currentMenu->x; + y = currentMenu->y; - // A 160x100 image of the level as entry MAPxxP - lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value))); + for (i = 0; i < currentMenu->numitems; ++i) + { + dispstatus = (currentMenu->menuitems[i].status & IT_DISPLAY); + if (dispstatus != IT_STRING && dispstatus != IT_WHITESTRING) + continue; - if (lumpnum != LUMPERROR) - PictureOfLevel = W_CachePatchName(va("%sP", G_BuildMapName(cv_nextmap.value)), PU_CACHE); - else - PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); + y = currentMenu->y+currentMenu->menuitems[i].alphaKey; + if (i == itemOn) + cursory = y; + + V_DrawString(x, y, (dispstatus == IT_WHITESTRING) ? V_YELLOWMAP : 0 , currentMenu->menuitems[i].text); + + // Cvar specific handling + if ((currentMenu->menuitems[i].status & IT_TYPE) == IT_CVAR) + { + consvar_t *cv = (consvar_t *)currentMenu->menuitems[i].itemaction; + INT32 soffset = 0; + + // hack to keep the menu from overlapping the overall grade icon + if (currentMenu != &SP_NightsAttackDef) + soffset = 80; + + // Should see nothing but strings + V_DrawString(BASEVIDWIDTH - x - soffset - V_StringWidth(cv->string, 0), y, V_YELLOWMAP, cv->string); + if (i == itemOn) + { + V_DrawCharacter(BASEVIDWIDTH - x - soffset - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - x - soffset + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } + } + } - V_DrawSmallScaledPatch(90, 28, 0, PictureOfLevel); + // DRAW THE SKULL CURSOR + V_DrawScaledPatch(currentMenu->x - 24, cursory, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); + V_DrawString(currentMenu->x, cursory, V_YELLOWMAP, currentMenu->menuitems[itemOn].text); // Level record list if (cv_nextmap.value) { emblem_t *em; INT32 yHeight; + patch_t *PictureOfLevel; + lumpnum_t lumpnum; + char beststr[40]; UINT8 bestoverall = G_GetBestNightsGrade(cv_nextmap.value, 0); UINT8 bestgrade = G_GetBestNightsGrade(cv_nextmap.value, cv_dummymares.value); UINT32 bestscore = G_GetBestNightsScore(cv_nextmap.value, cv_dummymares.value); tic_t besttime = G_GetBestNightsTime(cv_nextmap.value, cv_dummymares.value); - if (P_HasGrades(cv_nextmap.value, 0)) - V_DrawScaledPatch(200, 28 + 8, 0, ngradeletters[bestoverall]); + M_DrawLevelPlatterHeader(32-lsheadingheight/2, cv_nextmap.string, true, false); - if (currentMenu == &SP_NightsAttackDef) - { - if (P_HasGrades(cv_nextmap.value, cv_dummymares.value)) - { - V_DrawString(160-88, 112, V_YELLOWMAP, "BEST GRADE:"); - V_DrawSmallScaledPatch(160 + 86 - (ngradeletters[bestgrade]->width/2), - 112 + 8 - (ngradeletters[bestgrade]->height/2), - 0, ngradeletters[bestgrade]); - } + // A 160x100 image of the level as entry MAPxxP + lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value))); - if (!bestscore) - sprintf(beststr, "(none)"); - else - sprintf(beststr, "%u", bestscore); + if (lumpnum != LUMPERROR) + PictureOfLevel = W_CachePatchName(va("%sP", G_BuildMapName(cv_nextmap.value)), PU_CACHE); + else + PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); - V_DrawString(160 - 88, 122, V_YELLOWMAP, "BEST SCORE:"); - V_DrawRightAlignedString(160 + 88, 122, V_ALLOWLOWERCASE, beststr); + V_DrawSmallScaledPatch(208, 32+lsheadingheight, 0, PictureOfLevel); - if (besttime == UINT32_MAX) - sprintf(beststr, "(none)"); - else - sprintf(beststr, "%i:%02i.%02i", G_TicsToMinutes(besttime, true), - G_TicsToSeconds(besttime), - G_TicsToCentiseconds(besttime)); + V_DrawString(104 - 72, 32+lsheadingheight/2, 0, "* LEVEL RECORDS *"); - V_DrawString(160-88, 132, V_YELLOWMAP, "BEST TIME:"); - V_DrawRightAlignedString(160+88, 132, V_ALLOWLOWERCASE, beststr); + if (P_HasGrades(cv_nextmap.value, 0)) + V_DrawScaledPatch(235, 135, 0, ngradeletters[bestoverall]); + + if (P_HasGrades(cv_nextmap.value, cv_dummymares.value)) + {//make bigger again + V_DrawString(104 - 72, 48+lsheadingheight/2, V_YELLOWMAP, "BEST GRADE:"); + V_DrawSmallScaledPatch(104 + 72 - (ngradeletters[bestgrade]->width/2), + 48+lsheadingheight/2 + 8 - (ngradeletters[bestgrade]->height/2), + 0, ngradeletters[bestgrade]); + } - if (cv_dummymares.value == 0) { - // Draw record emblems. - em = M_GetLevelEmblems(cv_nextmap.value); - while (em) - { - switch (em->type) - { - case ET_NGRADE: yHeight = 112; break; - case ET_NTIME: yHeight = 132; break; - default: - goto skipThisOne; - } + if (!bestscore) + sprintf(beststr, "(none)"); + else + sprintf(beststr, "%u", bestscore); - if (em->collected) - V_DrawSmallMappedPatch(160+88, yHeight, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE), - R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE)); - else - V_DrawSmallScaledPatch(160+88, yHeight, 0, W_CachePatchName("NEEDIT", PU_CACHE)); + V_DrawString(104 - 72, 58+lsheadingheight/2, V_YELLOWMAP, "BEST SCORE:"); + V_DrawRightAlignedString(104 + 72, 58+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); + + if (besttime == UINT32_MAX) + sprintf(beststr, "(none)"); + else + sprintf(beststr, "%i:%02i.%02i", G_TicsToMinutes(besttime, true), + G_TicsToSeconds(besttime), + G_TicsToCentiseconds(besttime)); + + V_DrawString(104 - 72, 68+lsheadingheight/2, V_YELLOWMAP, "BEST TIME:"); + V_DrawRightAlignedString(104 + 72, 68+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); - skipThisOne: - em = M_GetLevelEmblems(-1); + if (cv_dummymares.value == 0) { + // Draw record emblems. + em = M_GetLevelEmblems(cv_nextmap.value); + while (em) + { + switch (em->type) + { + case ET_NGRADE: yHeight = 48; break; + case ET_NTIME: yHeight = 68; break; + default: + goto skipThisOne; } + + if (em->collected) + V_DrawSmallMappedPatch(104+76, yHeight+lsheadingheight/2, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE), + R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE)); + else + V_DrawSmallScaledPatch(104+76, yHeight+lsheadingheight/2, 0, W_CachePatchName("NEEDIT", PU_CACHE)); + + skipThisOne: + em = M_GetLevelEmblems(-1); } } - // ALWAYS DRAW level name even when not on this menu! - else - { - consvar_t *ncv; - INT32 x = SP_NightsAttackDef.x; - INT32 y = SP_NightsAttackDef.y; - - ncv = (consvar_t *)SP_NightsAttackMenu[0].itemaction; - V_DrawString(x, y + SP_NightsAttackMenu[0].alphaKey, V_TRANSLUCENT, SP_NightsAttackMenu[0].text); - V_DrawString(BASEVIDWIDTH - x - V_StringWidth(ncv->string, 0), - y + SP_NightsAttackMenu[0].alphaKey, V_YELLOWMAP|V_TRANSLUCENT, ncv->string); - } } + + // ALWAYS DRAW level even when not on this menu! + if (currentMenu != &SP_NightsAttackDef) + V_DrawString(SP_NightsAttackDef.x, SP_NightsAttackDef.y + SP_TimeAttackMenu[nalevel].alphaKey, V_TRANSLUCENT, SP_NightsAttackMenu[nalevel].text); +} + +static void M_NightsAttackLevelSelect(INT32 choice) +{ + (void)choice; + SP_NightsAttackLevelSelectDef.prevMenu = currentMenu; + M_SetupNextMenu(&SP_NightsAttackLevelSelectDef); } // Going to Nights Attack menu... @@ -6137,27 +8401,25 @@ static void M_NightsAttack(INT32 choice) { (void)choice; - memset(skins_cons_t, 0, sizeof (skins_cons_t)); - + SP_NightsAttackDef.prevMenu = &MainDef; levellistmode = LLM_NIGHTSATTACK; // Don't be dependent on cv_newgametype - if (M_CountLevelsToShowInList() == 0) + if (!M_PrepareLevelPlatter(-1, true)) { M_StartMessage(M_GetText("No NiGHTS-attackable levels found.\n"),NULL,MM_NOTHING); return; } - // This is really just to make sure Sonic is the played character, just in case M_PatchSkinNameTable(); - M_PrepareLevelSelect(); + G_SetGamestate(GS_TIMEATTACK); // do this before M_SetupNextMenu so that menu meta state knows that we're switching M_SetupNextMenu(&SP_NightsAttackDef); - Nextmap_OnChange(); + if (!M_CanShowLevelInList(cv_nextmap.value-1, -1) && levelselect.rows[0].maplist[0]) + CV_SetValue(&cv_nextmap, levelselect.rows[0].maplist[0]); + else + Nextmap_OnChange(); itemOn = nastart; // "Start" is selected. - - G_SetGamestate(GS_TIMEATTACK); - S_ChangeMusicInternal("racent", true); } // Player has selected the "START" from the nights attack screen @@ -6200,7 +8462,7 @@ static void M_ChooseTimeAttack(INT32 choice) I_Error("Out of memory for replay filepath\n"); sprintf(gpath,"replay"PATHSEP"%s"PATHSEP"%s", timeattackfolder, G_BuildMapName(cv_nextmap.value)); - snprintf(nameofdemo, sizeof nameofdemo, "%s-%s-last", gpath, cv_chooseskin.string); + snprintf(nameofdemo, sizeof nameofdemo, "%s-%s-last", gpath, skins[cv_chooseskin.value-1].name); if (!cv_autorecord.value) remove(va("%s"PATHSEP"%s.lmp", srb2home, nameofdemo)); @@ -6239,7 +8501,7 @@ static void M_ReplayTimeAttack(INT32 choice) return; } // 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), cv_chooseskin.string, which)); + 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) { @@ -6273,8 +8535,7 @@ static void M_EraseGuest(INT32 choice) M_SetupNextMenu(&SP_NightsAttackDef); else M_SetupNextMenu(&SP_TimeAttackDef); - CV_AddValue(&cv_nextmap, -1); - CV_AddValue(&cv_nextmap, 1); + Nextmap_OnChange(); M_StartMessage(M_GetText("Guest replay data erased.\n"),NULL,MM_NOTHING); } @@ -6284,7 +8545,7 @@ static void M_OverwriteGuest(const char *which, boolean nights) UINT8 *buf; size_t len; if (!nights) - len = FIL_ReadFile(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which), &buf); + len = FIL_ReadFile(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), &buf); else len = FIL_ReadFile(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which), &buf); if (!len) { @@ -6300,8 +8561,7 @@ static void M_OverwriteGuest(const char *which, boolean nights) M_SetupNextMenu(&SP_NightsAttackDef); else M_SetupNextMenu(&SP_TimeAttackDef); - CV_AddValue(&cv_nextmap, -1); - CV_AddValue(&cv_nextmap, 1); + Nextmap_OnChange(); M_StartMessage(M_GetText("Guest replay data saved.\n"),NULL,MM_NOTHING); } @@ -6359,9 +8619,10 @@ static void M_SetGuestReplay(INT32 choice) which(0); } -static void M_ModeAttackRetry(INT32 choice) +void M_ModeAttackRetry(INT32 choice) { (void)choice; + // todo -- maybe seperate this out and G_SetRetryFlag() here instead? is just calling this from the menu 100% safe? G_CheckDemoStatus(); // Cancel recording if (modeattacking == ATTACKING_RECORD) M_ChooseTimeAttack(0); @@ -6383,18 +8644,18 @@ static void M_ModeAttackEndGame(INT32 choice) default: case ATTACKING_RECORD: currentMenu = &SP_TimeAttackDef; + wipetypepost = menupres[MN_SP_TIMEATTACK].enterwipe; break; case ATTACKING_NIGHTS: currentMenu = &SP_NightsAttackDef; + wipetypepost = menupres[MN_SP_NIGHTSATTACK].enterwipe; break; } itemOn = currentMenu->lastOn; G_SetGamestate(GS_TIMEATTACK); modeattacking = ATTACKING_NONE; - S_ChangeMusicInternal("racent", true); - // Update replay availability. - CV_AddValue(&cv_nextmap, 1); - CV_AddValue(&cv_nextmap, -1); + M_ChangeMenuMusic("_title", true); + Nextmap_OnChange(); } // ======== @@ -6763,25 +9024,6 @@ static void M_ChooseRoom(INT32 choice) // Start Server Menu //=========================================================================== -// -// FindFirstMap -// -// Finds the first map of a particular gametype -// Defaults to 1 if nothing found. -// -static INT32 M_FindFirstMap(INT32 gtype) -{ - INT32 i; - - for (i = 0; i < NUMMAPS; i++) - { - if (mapheaderinfo[i] && (mapheaderinfo[i]->typeoflevel & gtype)) - return i + 1; - } - - return 1; -} - static void M_StartServer(INT32 choice) { boolean StartSplitScreenGame = (currentMenu == &MP_SplitServerDef); @@ -6822,15 +9064,13 @@ static void M_StartServer(INT32 choice) static void M_DrawServerMenu(void) { - lumpnum_t lumpnum; - patch_t *PictureOfLevel; - M_DrawGenericMenu(); #ifndef NONET // Room name if (currentMenu == &MP_ServerDef) { + M_DrawLevelPlatterHeader(currentMenu->y - lsheadingheight/2, "Server settings", true, false); if (ms_RoomId < 0) V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey, V_YELLOWMAP, (itemOn == mp_server_room) ? "<Select to change>" : "<Offline Mode>"); @@ -6840,27 +9080,49 @@ static void M_DrawServerMenu(void) } #endif - // A 160x100 image of the level as entry MAPxxP - lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value))); + if (cv_nextmap.value) + { +#ifndef NONET +#define imgheight MP_ServerMenu[mp_server_levelgt].alphaKey +#else +#define imgheight 100 +#endif + patch_t *PictureOfLevel; + lumpnum_t lumpnum; + char headerstr[40]; - if (lumpnum != LUMPERROR) - PictureOfLevel = W_CachePatchName(va("%sP", G_BuildMapName(cv_nextmap.value)), PU_CACHE); - else - PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); + sprintf(headerstr, "%s - %s", cv_newgametype.string, cv_nextmap.string); + + M_DrawLevelPlatterHeader(currentMenu->y + imgheight - 10 - lsheadingheight/2, (const char *)headerstr, true, false); + + // A 160x100 image of the level as entry MAPxxP + lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value))); + + if (lumpnum != LUMPERROR) + PictureOfLevel = W_CachePatchName(va("%sP", G_BuildMapName(cv_nextmap.value)), PU_CACHE); + else + PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); - V_DrawSmallScaledPatch((BASEVIDWIDTH*3/4)-(SHORT(PictureOfLevel->width)/4), ((BASEVIDHEIGHT*3/4)-(SHORT(PictureOfLevel->height)/4)+10), 0, PictureOfLevel); + V_DrawSmallScaledPatch(319 - (currentMenu->x + (SHORT(PictureOfLevel->width)/2)), currentMenu->y + imgheight, 0, PictureOfLevel); + } } static void M_MapChange(INT32 choice) { (void)choice; + MISC_ChangeLevelDef.prevMenu = currentMenu; levellistmode = LLM_CREATESERVER; - CV_SetValue(&cv_newgametype, gametype); - CV_SetValue(&cv_nextmap, gamemap); + if (Playing() && !(M_CanShowLevelOnPlatter(cv_nextmap.value-1, cv_newgametype.value)) && (M_CanShowLevelOnPlatter(gamemap-1, cv_newgametype.value))) + CV_SetValue(&cv_nextmap, gamemap); + + if (!M_PrepareLevelPlatter(cv_newgametype.value, (currentMenu == &MPauseDef))) + { + M_StartMessage(M_GetText("No selectable levels found.\n"),NULL,MM_NOTHING); + return; + } - M_PrepareLevelSelect(); M_SetupNextMenu(&MISC_ChangeLevelDef); } @@ -6868,51 +9130,92 @@ static void M_StartSplitServerMenu(INT32 choice) { (void)choice; levellistmode = LLM_CREATESERVER; - M_PrepareLevelSelect(); + Newgametype_OnChange(); M_SetupNextMenu(&MP_SplitServerDef); } +static void M_ServerOptions(INT32 choice) +{ + (void)choice; + +#ifndef NONET + if ((splitscreen && !netgame) || currentMenu == &MP_SplitServerDef) + { + OP_ServerOptionsMenu[ 1].status = IT_GRAYEDOUT; // Server name + OP_ServerOptionsMenu[ 2].status = IT_GRAYEDOUT; // Max players + OP_ServerOptionsMenu[ 3].status = IT_GRAYEDOUT; // Allow add-on downloading + OP_ServerOptionsMenu[ 4].status = IT_GRAYEDOUT; // Allow players to join + OP_ServerOptionsMenu[34].status = IT_GRAYEDOUT; // Master server + OP_ServerOptionsMenu[35].status = IT_GRAYEDOUT; // Attempts to resynchronise + } + else + { + OP_ServerOptionsMenu[ 1].status = IT_STRING | IT_CVAR | IT_CV_STRING; + OP_ServerOptionsMenu[ 2].status = IT_STRING | IT_CVAR; + OP_ServerOptionsMenu[ 3].status = IT_STRING | IT_CVAR; + OP_ServerOptionsMenu[ 4].status = IT_STRING | IT_CVAR; + OP_ServerOptionsMenu[34].status = (netgame + ? IT_GRAYEDOUT + : (IT_STRING | IT_CVAR | IT_CV_STRING)); + OP_ServerOptionsMenu[35].status = IT_STRING | IT_CVAR; + } +#endif + + OP_ServerOptionsDef.prevMenu = currentMenu; + M_SetupNextMenu(&OP_ServerOptionsDef); +} + #ifndef NONET static void M_StartServerMenu(INT32 choice) { (void)choice; - levellistmode = LLM_CREATESERVER; - M_PrepareLevelSelect(); ms_RoomId = -1; + levellistmode = LLM_CREATESERVER; + Newgametype_OnChange(); M_SetupNextMenu(&MP_ServerDef); - + itemOn = 1; } // ============== // CONNECT VIA IP // ============== -static char setupm_ip[16]; - -// Connect using IP address Tails 11-19-2002 -static void M_ConnectIPMenu(INT32 choice) -{ - (void)choice; - // modified game check: no longer handled - // we don't request a restart unless the filelist differs - - M_SetupNextMenu(&MP_ConnectIPDef); -} +static char setupm_ip[16]; // Draw the funky Connect IP menu. Tails 11-19-2002 // So much work for such a little thing! -static void M_DrawConnectIPMenu(void) +static void M_DrawMPMainMenu(void) { + INT32 x = currentMenu->x; + INT32 y = currentMenu->y; + // use generic drawer for cursor, items and title M_DrawGenericMenu(); +#if MAXPLAYERS == 32 + V_DrawRightAlignedString(BASEVIDWIDTH-x, y+12, + ((itemOn == 1) ? V_YELLOWMAP : 0), "(2-32 players)"); +#else +Update the maxplayers label... +#endif + + V_DrawRightAlignedString(BASEVIDWIDTH-x, y+22, + ((itemOn == 2) ? V_YELLOWMAP : 0), "(2 players)"); + + V_DrawRightAlignedString(BASEVIDWIDTH-x, y+116, + ((itemOn == 8) ? V_YELLOWMAP : 0), "(splitscreen)"); + + y += 62; + + V_DrawFill(x+5, y+4+5, /*16*8 + 6,*/ BASEVIDWIDTH - 2*(x+5), 8+6, 159); + // draw name string - V_DrawString(128,40, V_MONOSPACE, setupm_ip); + V_DrawString(x+8,y+12, V_MONOSPACE, setupm_ip); // draw text cursor for name - if (itemOn == 0 && - skullAnimCounter < 4) //blink cursor - V_DrawCharacter(128+V_StringWidth(setupm_ip, V_MONOSPACE),40,'_',false); + if (itemOn == 5 //0 + && skullAnimCounter < 4) //blink cursor + V_DrawCharacter(x+8+V_StringWidth(setupm_ip, V_MONOSPACE),y+12,'_',false); } // Tails 11-19-2002 @@ -6940,11 +9243,21 @@ static void M_ConnectIP(INT32 choice) // Tails 11-19-2002 static void M_HandleConnectIP(INT32 choice) { - size_t l; - boolean exitmenu = false; // exit to previous menu and send name change + size_t l; + boolean exitmenu = false; // exit to previous menu and send name change switch (choice) { + case KEY_DOWNARROW: + M_NextOpt(); + S_StartSound(NULL,sfx_menu1); // Tails + break; + + case KEY_UPARROW: + M_PrevOpt(); + S_StartSound(NULL,sfx_menu1); // Tails + break; + case KEY_ENTER: S_StartSound(NULL,sfx_menu1); // Tails M_ClearMenus(true); @@ -6956,29 +9269,41 @@ static void M_HandleConnectIP(INT32 choice) break; case KEY_BACKSPACE: - if ((l = strlen(setupm_ip))!=0 && itemOn == 0) + if ((l = strlen(setupm_ip)) != 0) + { + S_StartSound(NULL,sfx_menu1); // Tails + setupm_ip[l-1] = 0; + } + break; + + case KEY_DEL: + if (setupm_ip[0]) { S_StartSound(NULL,sfx_menu1); // Tails - setupm_ip[l-1] =0; + setupm_ip[0] = 0; } break; default: l = strlen(setupm_ip); - if (l < 16-1 && (choice == 46 || (choice >= 48 && choice <= 57))) // Rudimentary number and period enforcing + if (l >= 16-1) + break; + + if (choice == 46 || (choice >= 48 && choice <= 57)) // Rudimentary number and period enforcing { S_StartSound(NULL,sfx_menu1); // Tails - setupm_ip[l] =(char)choice; - setupm_ip[l+1] =0; + setupm_ip[l] = (char)choice; + setupm_ip[l+1] = 0; } - else if (l < 16-1 && choice >= 199 && choice <= 211 && choice != 202 && choice != 206) //numpad too! + else if (choice >= 199 && choice <= 211 && choice != 202 && choice != 206) //numpad too! { - XBOXSTATIC char keypad_translation[] = {'7','8','9','-','4','5','6','+','1','2','3','0','.'}; + char keypad_translation[] = {'7','8','9','-','4','5','6','+','1','2','3','0','.'}; choice = keypad_translation[choice - 199]; S_StartSound(NULL,sfx_menu1); // Tails - setupm_ip[l] =(char)choice; - setupm_ip[l+1] =0; + setupm_ip[l] = (char)choice; + setupm_ip[l+1] = 0; } + break; } @@ -6997,11 +9322,9 @@ static void M_HandleConnectIP(INT32 choice) // ======================== // Tails 03-02-2002 -#define PLBOXW 8 -#define PLBOXH 9 - -static INT32 multi_tics; -static state_t *multi_state; +static UINT8 multi_tics; +static UINT8 multi_frame; +static UINT8 multi_spr2; // this is set before entering the MultiPlayer setup menu, // for either player 1 or 2 @@ -7010,107 +9333,188 @@ static player_t *setupm_player; static consvar_t *setupm_cvskin; static consvar_t *setupm_cvcolor; static consvar_t *setupm_cvname; +static consvar_t *setupm_cvdefaultskin; +static consvar_t *setupm_cvdefaultcolor; +static consvar_t *setupm_cvdefaultname; static INT32 setupm_fakeskin; static INT32 setupm_fakecolor; static void M_DrawSetupMultiPlayerMenu(void) { - INT32 mx, my, st, flags = 0; + INT32 x, y, cursory = 0, flags = 0; spritedef_t *sprdef; spriteframe_t *sprframe; patch_t *patch; - UINT8 frame; + UINT8 *colormap; - mx = MP_PlayerSetupDef.x; - my = MP_PlayerSetupDef.y; + x = MP_PlayerSetupDef.x; + y = MP_PlayerSetupDef.y; // use generic drawer for cursor, items and title - M_DrawGenericMenu(); + //M_DrawGenericMenu(); + + // draw title (or big pic) + M_DrawMenuTitle(); + + M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), "Name", true, false); + if (itemOn == 0) + cursory = y; + y += 11; // draw name string - M_DrawTextBox(mx + 90, my - 8, MAXPLAYERNAME, 1); - V_DrawString(mx + 98, my, V_ALLOWLOWERCASE, setupm_name); + V_DrawFill(x, y, 282/*(MAXPLAYERNAME+1)*8+6*/, 14, 159); + V_DrawString(x + 8, y + 3, V_ALLOWLOWERCASE, setupm_name); + if (skullAnimCounter < 4 && itemOn == 0) + V_DrawCharacter(x + 8 + V_StringWidth(setupm_name, V_ALLOWLOWERCASE), y + 3, + '_' | 0x80, false); + + y += 20; + + M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), "Character", true, false); + if (itemOn == 1) + cursory = y; // draw skin string - V_DrawString(mx + 90, my + 96, - ((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|V_YELLOWMAP|V_ALLOWLOWERCASE, + V_DrawRightAlignedString(BASEVIDWIDTH - x, y, + ((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|(itemOn == 1 ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE, skins[setupm_fakeskin].realname); - // draw the name of the color you have chosen - // Just so people don't go thinking that "Default" is Green. - V_DrawString(208, 72, V_YELLOWMAP|V_ALLOWLOWERCASE, Color_Names[setupm_fakecolor]); + if (itemOn == 1 && (MP_PlayerSetupMenu[2].status & IT_TYPE) != IT_SPACE) + { + V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(skins[setupm_fakeskin].realname, V_ALLOWLOWERCASE) - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } - // draw text cursor for name - if (!itemOn && skullAnimCounter < 4) // blink cursor - V_DrawCharacter(mx + 98 + V_StringWidth(setupm_name, 0), my, '_',false); + x = BASEVIDWIDTH/2; + y += 11; // anim the player in the box if (--multi_tics <= 0) { - st = multi_state->nextstate; - if (st != S_NULL) - multi_state = &states[st]; - multi_tics = multi_state->tics; - if (multi_tics == -1) - multi_tics = 15; + multi_frame++; + multi_tics = 4; } - // skin 0 is default player sprite - if (R_SkinAvailable(skins[setupm_fakeskin].name) != -1) - sprdef = &skins[R_SkinAvailable(skins[setupm_fakeskin].name)].spritedef; - else - sprdef = &skins[0].spritedef; +#define charw 74 + + // draw box around character + V_DrawFill(x-(charw/2), y, charw, 84, 159); + + sprdef = &skins[setupm_fakeskin].sprites[multi_spr2]; + if (!setupm_fakecolor || !sprdef->numframes) // should never happen but hey, who knows + goto faildraw; + + // ok, draw player sprite for sure now + colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor, 0); + + if (multi_frame >= sprdef->numframes) + multi_frame = 0; + + sprframe = &sprdef->spriteframes[multi_frame]; + patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + if (sprframe->flip & 1) // Only for first sprite + flags |= V_FLIP; // This sprite is left/right flipped! + +#define chary (y+64) + + V_DrawFixedPatch( + x<<FRACBITS, + chary<<FRACBITS, + FixedDiv(skins[setupm_fakeskin].highresscale, skins[setupm_fakeskin].shieldscale), + flags, patch, colormap); + + Z_Free(colormap); + goto colordraw; + +faildraw: + sprdef = &sprites[SPR_UNKN]; if (!sprdef->numframes) // No frames ?? return; // Can't render! - frame = multi_state->frame & FF_FRAMEMASK; - if (frame >= sprdef->numframes) // Walking animation missing - frame = 0; // Try to use standing frame - - sprframe = &sprdef->spriteframes[frame]; + sprframe = &sprdef->spriteframes[0]; patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); if (sprframe->flip & 1) // Only for first sprite flags |= V_FLIP; // This sprite is left/right flipped! - // draw box around guy - M_DrawTextBox(mx + 90, my + 8, PLBOXW, PLBOXH); + V_DrawScaledPatch(x, chary, flags, patch); + +#undef chary - // draw player sprite - if (!setupm_fakecolor) // should never happen but hey, who knows +colordraw: + x = MP_PlayerSetupDef.x; + y += 75; + + M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), "Color", true, false); + if (itemOn == 2) + cursory = y; + + // draw color string + V_DrawRightAlignedString(BASEVIDWIDTH - x, y, + (itemOn == 2 ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE, + Color_Names[setupm_fakecolor]); + + if (itemOn == 2 && (MP_PlayerSetupMenu[2].status & IT_TYPE) != IT_SPACE) { - if (skins[setupm_fakeskin].flags & SF_HIRES) - { - V_DrawSciencePatch((mx+98+(PLBOXW*8/2))<<FRACBITS, - (my+16+(PLBOXH*8)-12)<<FRACBITS, - flags, patch, - skins[setupm_fakeskin].highresscale); - } - else - V_DrawScaledPatch(mx + 98 + (PLBOXW*8/2), my + 16 + (PLBOXH*8) - 12, flags, patch); + V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(Color_Names[setupm_fakecolor], V_ALLOWLOWERCASE) - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); } - else + + y += 11; + +#define indexwidth 8 { - UINT8 *colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor, 0); + const INT32 colwidth = (282-charw)/(2*indexwidth); + INT32 i = -colwidth; + INT16 col = setupm_fakecolor - colwidth; + INT32 w = indexwidth; + UINT8 h; - if (skins[setupm_fakeskin].flags & SF_HIRES) + while (col < 1) + col += MAXSKINCOLORS-1; + while (i <= colwidth) { - V_DrawFixedPatch((mx+98+(PLBOXW*8/2))<<FRACBITS, - (my+16+(PLBOXH*8)-12)<<FRACBITS, - skins[setupm_fakeskin].highresscale, - flags, patch, colormap); + if (!(i++)) + w = charw; + else + w = indexwidth; + for (h = 0; h < 16; h++) + V_DrawFill(x, y+h, w, 1, Color_Index[col-1][h]); + if (++col >= MAXSKINCOLORS) + col -= MAXSKINCOLORS-1; + x += w; } - else - V_DrawMappedPatch(mx + 98 + (PLBOXW*8/2), my + 16 + (PLBOXH*8) - 12, flags, patch, colormap); - - Z_Free(colormap); } +#undef charw +#undef indexwidth + + x = MP_PlayerSetupDef.x; + y += 20; + + V_DrawString(x, y, + ((R_SkinAvailable(setupm_cvdefaultskin->string) != setupm_fakeskin + || setupm_cvdefaultcolor->value != setupm_fakecolor + || strcmp(setupm_name, setupm_cvdefaultname->string)) + ? 0 + : V_TRANSLUCENT) + | ((itemOn == 3) ? V_YELLOWMAP : 0), + "Save as default"); + if (itemOn == 3) + cursory = y; + + V_DrawScaledPatch(x - 17, cursory, 0, + W_CachePatchName("M_CURSOR", PU_CACHE)); } // Handle 1P/2P MP Setup static void M_HandleSetupMultiPlayer(INT32 choice) { size_t l; + INT32 prev_setupm_fakeskin; boolean exitmenu = false; // exit to previous menu and send name change switch (choice) @@ -7126,25 +9530,55 @@ static void M_HandleSetupMultiPlayer(INT32 choice) break; case KEY_LEFTARROW: - if (itemOn == 2) //player skin + if (itemOn == 1) //player skin { S_StartSound(NULL,sfx_menu1); // Tails - setupm_fakeskin--; + prev_setupm_fakeskin = setupm_fakeskin; + do + { + setupm_fakeskin--; + if (setupm_fakeskin < 0) + setupm_fakeskin = numskins-1; + } + while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUsable(-1, setupm_fakeskin))); + multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL); } - else if (itemOn == 1) // player color + else if (itemOn == 2) // player color { S_StartSound(NULL,sfx_menu1); // Tails setupm_fakecolor--; } break; + case KEY_ENTER: + if (itemOn == 3 + && (R_SkinAvailable(setupm_cvdefaultskin->string) != setupm_fakeskin + || setupm_cvdefaultcolor->value != setupm_fakecolor + || strcmp(setupm_name, setupm_cvdefaultname->string))) + { + S_StartSound(NULL,sfx_strpst); + // you know what? always putting these in the buffer won't hurt anything. + COM_BufAddText (va("%s \"%s\"\n",setupm_cvdefaultskin->name,skins[setupm_fakeskin].name)); + COM_BufAddText (va("%s %d\n",setupm_cvdefaultcolor->name,setupm_fakecolor)); + COM_BufAddText (va("%s %s\n",setupm_cvdefaultname->name,setupm_name)); + break; + } + /* FALLTHRU */ case KEY_RIGHTARROW: - if (itemOn == 2) //player skin + if (itemOn == 1) //player skin { S_StartSound(NULL,sfx_menu1); // Tails - setupm_fakeskin++; + prev_setupm_fakeskin = setupm_fakeskin; + do + { + setupm_fakeskin++; + if (setupm_fakeskin > numskins-1) + setupm_fakeskin = 0; + } + while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUsable(-1, setupm_fakeskin))); + multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL); } - else if (itemOn == 1) // player color + else if (itemOn == 2) // player color { S_StartSound(NULL,sfx_menu1); // Tails setupm_fakecolor++; @@ -7156,32 +9590,44 @@ static void M_HandleSetupMultiPlayer(INT32 choice) break; case KEY_BACKSPACE: - if ((l = strlen(setupm_name))!=0 && itemOn == 0) + if (itemOn == 0 && (l = strlen(setupm_name))!=0) + { + S_StartSound(NULL,sfx_menu1); // Tails + setupm_name[l-1] = 0; + } + else if (itemOn == 2) + { + UINT8 col = skins[setupm_fakeskin].prefcolor; + if (setupm_fakecolor != col) + { + S_StartSound(NULL,sfx_menu1); // Tails + setupm_fakecolor = col; + } + } + break; + break; + + case KEY_DEL: + if (itemOn == 0 && (l = strlen(setupm_name))!=0) { S_StartSound(NULL,sfx_menu1); // Tails - setupm_name[l-1] =0; + setupm_name[0] = 0; } break; default: - if (choice < 32 || choice > 127 || itemOn != 0) + if (itemOn != 0 || choice < 32 || choice > 127) break; + S_StartSound(NULL,sfx_menu1); // Tails l = strlen(setupm_name); if (l < MAXPLAYERNAME) { - S_StartSound(NULL,sfx_menu1); // Tails - setupm_name[l] =(char)choice; - setupm_name[l+1] =0; + setupm_name[l] = (char)choice; + setupm_name[l+1] = 0; } break; } - // check skin - if (setupm_fakeskin < 0) - setupm_fakeskin = numskins-1; - if (setupm_fakeskin > numskins-1) - setupm_fakeskin = 0; - // check color if (setupm_fakecolor < 1) setupm_fakecolor = MAXSKINCOLORS-1; @@ -7202,8 +9648,8 @@ static void M_SetupMultiPlayer(INT32 choice) { (void)choice; - multi_state = &states[mobjinfo[MT_PLAYER].seestate]; - multi_tics = multi_state->tics; + multi_frame = 0; + multi_tics = 4; strcpy(setupm_name, cv_playername.string); // set for player 1 @@ -7211,6 +9657,9 @@ static void M_SetupMultiPlayer(INT32 choice) setupm_cvskin = &cv_skin; setupm_cvcolor = &cv_playercolor; setupm_cvname = &cv_playername; + setupm_cvdefaultskin = &cv_defaultskin; + setupm_cvdefaultcolor = &cv_defaultplayercolor; + setupm_cvdefaultname = &cv_defaultplayername; // For whatever reason this doesn't work right if you just use ->value setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string); @@ -7220,9 +9669,11 @@ static void M_SetupMultiPlayer(INT32 choice) // disable skin changes if we can't actually change skins if (!CanChangeSkin(consoleplayer)) - MP_PlayerSetupMenu[2].status = (IT_GRAYEDOUT); + MP_PlayerSetupMenu[1].status = (IT_GRAYEDOUT); else - MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER|IT_STRING); + MP_PlayerSetupMenu[1].status = (IT_KEYHANDLER|IT_STRING); + + multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL); MP_PlayerSetupDef.prevMenu = currentMenu; M_SetupNextMenu(&MP_PlayerSetupDef); @@ -7233,8 +9684,8 @@ static void M_SetupMultiPlayer2(INT32 choice) { (void)choice; - multi_state = &states[mobjinfo[MT_PLAYER].seestate]; - multi_tics = multi_state->tics; + multi_frame = 0; + multi_tics = 4; strcpy (setupm_name, cv_playername2.string); // set for splitscreen secondary player @@ -7242,6 +9693,9 @@ static void M_SetupMultiPlayer2(INT32 choice) setupm_cvskin = &cv_skin2; setupm_cvcolor = &cv_playercolor2; setupm_cvname = &cv_playername2; + setupm_cvdefaultskin = &cv_defaultskin2; + setupm_cvdefaultcolor = &cv_defaultplayercolor2; + setupm_cvdefaultname = &cv_defaultplayername2; // For whatever reason this doesn't work right if you just use ->value setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string); @@ -7251,9 +9705,11 @@ static void M_SetupMultiPlayer2(INT32 choice) // disable skin changes if we can't actually change skins if (splitscreen && !CanChangeSkin(secondarydisplayplayer)) - MP_PlayerSetupMenu[2].status = (IT_GRAYEDOUT); + MP_PlayerSetupMenu[1].status = (IT_GRAYEDOUT); else - MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER | IT_STRING); + MP_PlayerSetupMenu[1].status = (IT_KEYHANDLER | IT_STRING); + + multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL); MP_PlayerSetupDef.prevMenu = currentMenu; M_SetupNextMenu(&MP_PlayerSetupDef); @@ -7297,6 +9753,7 @@ static void M_EraseDataResponse(INT32 ch) totalplaytime = 0; F_StartIntro(); } + BwehHehHe(); M_ClearMenus(true); } @@ -7336,18 +9793,25 @@ static void M_DrawJoystick(void) { INT32 i; - M_DrawGenericMenu(); + // draw title (or big pic) + M_DrawMenuTitle(); - for (i = 0;i < 7; i++) + for (i = 0; i <= 4; i++) // See MAX_JOYSTICKS { M_DrawTextBox(OP_JoystickSetDef.x-8, OP_JoystickSetDef.y+LINEHEIGHT*i-12, 28, 1); - //M_DrawSaveLoadBorder(OP_JoystickSetDef.x, OP_JoystickSetDef.y+LINEHEIGHT*i); + //M_DrawSaveLoadBorder(OP_JoystickSetDef.x+4, OP_JoystickSetDef.y+1+LINEHEIGHT*i); if ((setupcontrols_secondaryplayer && (i == cv_usejoystick2.value)) || (!setupcontrols_secondaryplayer && (i == cv_usejoystick.value))) V_DrawString(OP_JoystickSetDef.x, OP_JoystickSetDef.y+LINEHEIGHT*i-4,V_GREENMAP,joystickInfo[i]); else V_DrawString(OP_JoystickSetDef.x, OP_JoystickSetDef.y+LINEHEIGHT*i-4,0,joystickInfo[i]); + + if (i == itemOn) + { + V_DrawScaledPatch(currentMenu->x - 24, OP_JoystickSetDef.y+LINEHEIGHT*i-4, 0, + W_CachePatchName("M_CURSOR", PU_CACHE)); + } } } @@ -7375,6 +9839,10 @@ static void M_Setup1PJoystickMenu(INT32 choice) { setupcontrols_secondaryplayer = false; OP_JoystickSetDef.prevMenu = &OP_Joystick1Def; + OP_JoystickSetDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); + OP_JoystickSetDef.menuid &= ~(((1 << MENUBITS) - 1) << (MENUBITS*2)); + OP_JoystickSetDef.menuid |= MN_OP_P1CONTROLS << MENUBITS; + OP_JoystickSetDef.menuid |= MN_OP_P1JOYSTICK << (MENUBITS*2); M_SetupJoystickMenu(choice); } @@ -7382,6 +9850,10 @@ static void M_Setup2PJoystickMenu(INT32 choice) { setupcontrols_secondaryplayer = true; OP_JoystickSetDef.prevMenu = &OP_Joystick2Def; + OP_JoystickSetDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); + OP_JoystickSetDef.menuid &= ~(((1 << MENUBITS) - 1) << (MENUBITS*2)); + OP_JoystickSetDef.menuid |= MN_OP_P2CONTROLS << MENUBITS; + OP_JoystickSetDef.menuid |= MN_OP_P2JOYSTICK << (MENUBITS*2); M_SetupJoystickMenu(choice); } @@ -7404,16 +9876,28 @@ static void M_Setup1PControlsMenu(INT32 choice) setupcontrols = gamecontrol; // was called from main Options (for console player, then) currentMenu->lastOn = itemOn; - // Unhide the three non-P2 controls - OP_MPControlsMenu[0].status = IT_CALL|IT_STRING2; - OP_MPControlsMenu[1].status = IT_CALL|IT_STRING2; - OP_MPControlsMenu[2].status = IT_CALL|IT_STRING2; - // Unide the pause/console controls too - OP_MiscControlsMenu[3].status = IT_CALL|IT_STRING2; - OP_MiscControlsMenu[4].status = IT_CALL|IT_STRING2; - - OP_ControlListDef.prevMenu = &OP_P1ControlsDef; - M_SetupNextMenu(&OP_ControlListDef); + // Unhide the nine non-P2 controls and their headers + //OP_ChangeControlsMenu[18+0].status = IT_HEADER; + //OP_ChangeControlsMenu[18+1].status = IT_SPACE; + // ... + OP_ChangeControlsMenu[18+2].status = IT_CALL|IT_STRING2; + OP_ChangeControlsMenu[18+3].status = IT_CALL|IT_STRING2; + OP_ChangeControlsMenu[18+4].status = IT_CALL|IT_STRING2; + OP_ChangeControlsMenu[18+5].status = IT_CALL|IT_STRING2; + OP_ChangeControlsMenu[18+6].status = IT_CALL|IT_STRING2; + //OP_ChangeControlsMenu[18+7].status = IT_CALL|IT_STRING2; + OP_ChangeControlsMenu[18+8].status = IT_CALL|IT_STRING2; + // ... + OP_ChangeControlsMenu[27+0].status = IT_HEADER; + OP_ChangeControlsMenu[27+1].status = IT_SPACE; + // ... + OP_ChangeControlsMenu[27+2].status = IT_CALL|IT_STRING2; + OP_ChangeControlsMenu[27+3].status = IT_CALL|IT_STRING2; + + OP_ChangeControlsDef.prevMenu = &OP_P1ControlsDef; + OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove first level (<< 6) + OP_ChangeControlsDef.menuid |= MN_OP_P1CONTROLS << MENUBITS; // combine first level (<< 6) + M_SetupNextMenu(&OP_ChangeControlsDef); } static void M_Setup2PControlsMenu(INT32 choice) @@ -7423,63 +9907,151 @@ static void M_Setup2PControlsMenu(INT32 choice) setupcontrols = gamecontrolbis; currentMenu->lastOn = itemOn; - // Hide the three non-P2 controls - OP_MPControlsMenu[0].status = IT_GRAYEDOUT2; - OP_MPControlsMenu[1].status = IT_GRAYEDOUT2; - OP_MPControlsMenu[2].status = IT_GRAYEDOUT2; - // Hide the pause/console and system menu controls too - OP_MiscControlsMenu[3].status = IT_GRAYEDOUT2; - OP_MiscControlsMenu[6].status = IT_GRAYEDOUT2; - OP_MiscControlsMenu[8].status = IT_GRAYEDOUT2; - - OP_ControlListDef.prevMenu = &OP_P2ControlsDef; - M_SetupNextMenu(&OP_ControlListDef); -} + // Hide the nine non-P2 controls and their headers + //OP_ChangeControlsMenu[18+0].status = IT_GRAYEDOUT2; + //OP_ChangeControlsMenu[18+1].status = IT_GRAYEDOUT2; + // ... + OP_ChangeControlsMenu[18+2].status = IT_GRAYEDOUT2; + OP_ChangeControlsMenu[18+3].status = IT_GRAYEDOUT2; + OP_ChangeControlsMenu[18+4].status = IT_GRAYEDOUT2; + OP_ChangeControlsMenu[18+5].status = IT_GRAYEDOUT2; + OP_ChangeControlsMenu[18+6].status = IT_GRAYEDOUT2; + //OP_ChangeControlsMenu[18+7].status = IT_GRAYEDOUT2; + OP_ChangeControlsMenu[18+8].status = IT_GRAYEDOUT2; + // ... + OP_ChangeControlsMenu[27+0].status = IT_GRAYEDOUT2; + OP_ChangeControlsMenu[27+1].status = IT_GRAYEDOUT2; + // ... + OP_ChangeControlsMenu[27+2].status = IT_GRAYEDOUT2; + OP_ChangeControlsMenu[27+3].status = IT_GRAYEDOUT2; + + OP_ChangeControlsDef.prevMenu = &OP_P2ControlsDef; + OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove first level (<< 6) + OP_ChangeControlsDef.menuid |= MN_OP_P2CONTROLS << MENUBITS; // combine first level (<< 6) + M_SetupNextMenu(&OP_ChangeControlsDef); +} + +#define controlheight 18 // Draws the Customise Controls menu static void M_DrawControl(void) { char tmp[50]; - INT32 i; + INT32 x, y, i, max, cursory = 0, iter; INT32 keys[2]; - // draw title, strings and submenu - M_DrawGenericMenu(); + x = currentMenu->x; + y = currentMenu->y; - M_CentreText(30, - (setupcontrols_secondaryplayer ? "SET CONTROLS FOR SECONDARY PLAYER" : - "PRESS ENTER TO CHANGE, BACKSPACE TO CLEAR")); + /*i = itemOn - (controlheight/2); + if (i < 0) + i = 0; + */ - for (i = 0;i < currentMenu->numitems;i++) + iter = (controlheight/2); + for (i = itemOn; ((iter || currentMenu->menuitems[i].status == IT_GRAYEDOUT2) && i > 0); i--) { - if (currentMenu->menuitems[i].status != IT_CONTROL) - continue; + if (currentMenu->menuitems[i].status != IT_GRAYEDOUT2) + iter--; + } + if (currentMenu->menuitems[i].status == IT_GRAYEDOUT2) + i--; - keys[0] = setupcontrols[currentMenu->menuitems[i].alphaKey][0]; - keys[1] = setupcontrols[currentMenu->menuitems[i].alphaKey][1]; + iter += (controlheight/2); + for (max = itemOn; (iter && max < currentMenu->numitems); max++) + { + if (currentMenu->menuitems[max].status != IT_GRAYEDOUT2) + iter--; + } - tmp[0] ='\0'; - if (keys[0] == KEY_NULL && keys[1] == KEY_NULL) + if (iter) + { + iter += (controlheight/2); + for (i = itemOn; ((iter || currentMenu->menuitems[i].status == IT_GRAYEDOUT2) && i > 0); i--) { - strcpy(tmp, "---"); + if (currentMenu->menuitems[i].status != IT_GRAYEDOUT2) + iter--; } + } + + /*max = i + controlheight; + if (max > currentMenu->numitems) + { + max = currentMenu->numitems; + if (max < controlheight) + i = 0; + else + i = max - controlheight; + }*/ + + // draw title (or big pic) + M_DrawMenuTitle(); + + if (tutorialmode && tutorialgcs) + { + if ((gametic / TICRATE) % 2) + M_CentreText(30, "\202EXIT THE TUTORIAL TO CHANGE THE CONTROLS"); else + M_CentreText(30, "EXIT THE TUTORIAL TO CHANGE THE CONTROLS"); + } + else + M_CentreText(30, + (setupcontrols_secondaryplayer ? "SET CONTROLS FOR SECONDARY PLAYER" : + "PRESS ENTER TO CHANGE, BACKSPACE TO CLEAR")); + + if (i) + V_DrawString(currentMenu->x - 16, y-(skullAnimCounter/5), V_YELLOWMAP, "\x1A"); // up arrow + if (max != currentMenu->numitems) + V_DrawString(currentMenu->x - 16, y+(SMALLLINEHEIGHT*(controlheight-1))+(skullAnimCounter/5), V_YELLOWMAP, "\x1B"); // down arrow + + for (; i < max; i++) + { + if (currentMenu->menuitems[i].status == IT_GRAYEDOUT2) + continue; + + if (i == itemOn) + cursory = y; + + if (currentMenu->menuitems[i].status == IT_CONTROL) { - if (keys[0] != KEY_NULL) - strcat (tmp, G_KeynumToString (keys[0])); + V_DrawString(x, y, ((i == itemOn) ? V_YELLOWMAP : 0), currentMenu->menuitems[i].text); + keys[0] = setupcontrols[currentMenu->menuitems[i].alphaKey][0]; + keys[1] = setupcontrols[currentMenu->menuitems[i].alphaKey][1]; + + tmp[0] ='\0'; + if (keys[0] == KEY_NULL && keys[1] == KEY_NULL) + { + strcpy(tmp, "---"); + } + else + { + if (keys[0] != KEY_NULL) + strcat (tmp, G_KeynumToString (keys[0])); - if (keys[0] != KEY_NULL && keys[1] != KEY_NULL) - strcat(tmp," or "); + if (keys[0] != KEY_NULL && keys[1] != KEY_NULL) + strcat(tmp," or "); - if (keys[1] != KEY_NULL) - strcat (tmp, G_KeynumToString (keys[1])); + if (keys[1] != KEY_NULL) + strcat (tmp, G_KeynumToString (keys[1])); + } + V_DrawRightAlignedString(BASEVIDWIDTH-currentMenu->x, y, V_YELLOWMAP, tmp); } - V_DrawRightAlignedString(BASEVIDWIDTH-currentMenu->x, currentMenu->y + i*8, V_YELLOWMAP, tmp); + /*else if (currentMenu->menuitems[i].status == IT_GRAYEDOUT2) + V_DrawString(x, y, V_TRANSLUCENT, currentMenu->menuitems[i].text);*/ + else if ((currentMenu->menuitems[i].status == IT_HEADER) && (i != max-1)) + M_DrawLevelPlatterHeader(y, currentMenu->menuitems[i].text, true, false); + + y += SMALLLINEHEIGHT; } + + V_DrawScaledPatch(currentMenu->x - 20, cursory, 0, + W_CachePatchName("M_CURSOR", PU_CACHE)); } +#undef controlbuffer + static INT32 controltochange; static char controltochangetext[33]; @@ -7558,7 +10130,7 @@ static void M_ChangecontrolResponse(event_t *ev) menu_t *prev = currentMenu->prevMenu; if (controltochange == gc_pause) - sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nyou may select another key. \n\nHit another key for\n%s\nESC for Cancel"), + sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nit cannot be used to retry runs \nduring Record Attack. \n\nHit another key for\n%s\nESC for Cancel"), controltochangetext); else sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nit is not configurable. \n\nHit another key for\n%s\nESC for Cancel"), @@ -7582,6 +10154,9 @@ static void M_ChangeControl(INT32 choice) // If you change the below message, then change the size of this buffer! static char tmp[68]; + if (tutorialmode && tutorialgcs) // don't allow control changes if temp control override is active + return; + controltochange = currentMenu->menuitems[choice].alphaKey; sprintf(tmp, M_GetText("Hit the new key for\n%s\nESC for Cancel"), currentMenu->menuitems[choice].text); @@ -7680,6 +10255,21 @@ static void M_VideoModeMenu(INT32 choice) M_SetupNextMenu(&OP_VideoModeDef); } +static void M_DrawMainVideoMenu(void) +{ + + M_DrawGenericScrollMenu(); + if (itemOn < 8) // where it starts to go offscreen; change this number if you change the layout of the video menu + { + INT32 y = currentMenu->y+currentMenu->menuitems[1].alphaKey*2; + if (itemOn == 7) + y -= 10; + V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, y, + (SCR_IsAspectCorrect(vid.width, vid.height) ? V_GREENMAP : V_YELLOWMAP), + va("%dx%d", vid.width, vid.height)); + } +} + // Draw the video modes list, a-la-Quake static void M_DrawVideoMode(void) { @@ -7738,10 +10328,10 @@ static void M_DrawVideoMode(void) V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 138, V_GREENMAP, "Green modes are recommended."); - V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 150, + V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 146, V_YELLOWMAP, "Other modes may have visual errors."); V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 158, - V_YELLOWMAP, "Use at own risk."); + V_YELLOWMAP, "Larger modes may have performance issues."); } // Draw the cursor for the VidMode menu @@ -7752,6 +10342,134 @@ static void M_DrawVideoMode(void) W_CachePatchName("M_CURSOR", PU_CACHE)); } +// Just M_DrawGenericScrollMenu but showing a backing behind the headers. +static void M_DrawColorMenu(void) +{ + INT32 x, y, i, max, tempcentery, cursory = 0; + + // DRAW MENU + x = currentMenu->x; + y = currentMenu->y; + + V_DrawFill(19 , y-4, 47, 1, 35); + V_DrawFill(19+( 47), y-4, 47, 1, 73); + V_DrawFill(19+(2*47), y-4, 47, 1, 112); + V_DrawFill(19+(3*47), y-4, 47, 1, 255); + V_DrawFill(19+(4*47), y-4, 47, 1, 152); + V_DrawFill(19+(5*47), y-4, 46, 1, 181); + + V_DrawFill(300, y-4, 1, 1, 26); + V_DrawFill( 19, y-3, 282, 1, 26); + + if ((currentMenu->menuitems[itemOn].alphaKey*2 - currentMenu->menuitems[0].alphaKey*2) <= scrollareaheight) + tempcentery = currentMenu->y - currentMenu->menuitems[0].alphaKey*2; + else if ((currentMenu->menuitems[currentMenu->numitems-1].alphaKey*2 - currentMenu->menuitems[itemOn].alphaKey*2) <= scrollareaheight) + tempcentery = currentMenu->y - currentMenu->menuitems[currentMenu->numitems-1].alphaKey*2 + 2*scrollareaheight; + else + tempcentery = currentMenu->y - currentMenu->menuitems[itemOn].alphaKey*2 + scrollareaheight; + + for (i = 0; i < currentMenu->numitems; i++) + { + if (currentMenu->menuitems[i].status != IT_DISABLED && currentMenu->menuitems[i].alphaKey*2 + tempcentery >= currentMenu->y) + break; + } + + for (max = currentMenu->numitems; max > 0; max--) + { + if (currentMenu->menuitems[max].status != IT_DISABLED && currentMenu->menuitems[max-1].alphaKey*2 + tempcentery <= (currentMenu->y + 2*scrollareaheight)) + break; + } + + if (i) + V_DrawString(currentMenu->x - 20, currentMenu->y - (skullAnimCounter/5), V_YELLOWMAP, "\x1A"); // up arrow + if (max != currentMenu->numitems) + V_DrawString(currentMenu->x - 20, currentMenu->y + 2*scrollareaheight + (skullAnimCounter/5), V_YELLOWMAP, "\x1B"); // down arrow + + // draw title (or big pic) + M_DrawMenuTitle(); + + for (; i < max; i++) + { + y = currentMenu->menuitems[i].alphaKey*2 + tempcentery; + if (i == itemOn) + cursory = y; + switch (currentMenu->menuitems[i].status & IT_DISPLAY) + { + case IT_PATCH: + case IT_DYBIGSPACE: + case IT_BIGSLIDER: + case IT_STRING2: + case IT_DYLITLSPACE: + case IT_GRAYPATCH: + case IT_TRANSTEXT2: + // unsupported + break; + case IT_NOTHING: + break; + case IT_STRING: + case IT_WHITESTRING: + if (i != itemOn && (currentMenu->menuitems[i].status & IT_DISPLAY)==IT_STRING) + V_DrawString(x, y, 0, currentMenu->menuitems[i].text); + else + V_DrawString(x, y, V_YELLOWMAP, currentMenu->menuitems[i].text); + + // Cvar specific handling + switch (currentMenu->menuitems[i].status & IT_TYPE) + case IT_CVAR: + { + consvar_t *cv = (consvar_t *)currentMenu->menuitems[i].itemaction; + switch (currentMenu->menuitems[i].status & IT_CVARTYPE) + { + case IT_CV_SLIDER: + M_DrawSlider(x, y, cv, (i == itemOn)); + case IT_CV_NOPRINT: // color use this + case IT_CV_INVISSLIDER: // monitor toggles use this + break; + case IT_CV_STRING: + if (y + 12 > (currentMenu->y + 2*scrollareaheight)) + break; + M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1); + V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string); + if (skullAnimCounter < 4 && i == itemOn) + V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12, + '_' | 0x80, false); + y += 16; + break; + default: + V_DrawRightAlignedString(BASEVIDWIDTH - x, y, + ((cv->flags & CV_CHEAT) && !CV_IsSetToDefault(cv) ? V_REDMAP : V_YELLOWMAP), cv->string); + if (i == itemOn) + { + V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } + break; + } + break; + } + break; + case IT_TRANSTEXT: + V_DrawString(x, y, V_TRANSLUCENT, currentMenu->menuitems[i].text); + break; + case IT_QUESTIONMARKS: + V_DrawString(x, y, V_TRANSLUCENT|V_OLDSPACING, M_CreateSecretMenuOption(currentMenu->menuitems[i].text)); + break; + case IT_HEADERTEXT: + //V_DrawString(x-16, y, V_YELLOWMAP, currentMenu->menuitems[i].text); + V_DrawFill(19, y, 281, 9, currentMenu->menuitems[i+1].alphaKey); + V_DrawFill(300, y, 1, 9, 26); + M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), currentMenu->menuitems[i].text, false, false); + break; + } + } + + // DRAW THE SKULL CURSOR + V_DrawScaledPatch(currentMenu->x - 24, cursory, 0, + W_CachePatchName("M_CURSOR", PU_CACHE)); +} + // special menuitem key handler for video mode list static void M_HandleVideoMode(INT32 ch) { @@ -7825,6 +10543,21 @@ static void M_HandleVideoMode(INT32 ch) } } +static void M_DrawScreenshotMenu(void) +{ + + M_DrawGenericScrollMenu(); +#ifdef HWRENDER + if ((rendermode == render_opengl) && (itemOn < 7)) // where it starts to go offscreen; change this number if you change the layout of the screenshot menu + { + INT32 y = currentMenu->y+currentMenu->menuitems[op_screenshot_colorprofile].alphaKey*2; + if (itemOn == 6) + y -= 10; + V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, y, V_REDMAP, "ON"); + } +#endif +} + // =============== // Monitor Toggles // =============== @@ -7840,7 +10573,8 @@ static void M_DrawMonitorToggles(void) // Assumes all are cvar type. for (i = 0; i < currentMenu->numitems; ++i) { - cv = (consvar_t *)currentMenu->menuitems[i].itemaction; + if (!(currentMenu->menuitems[i].status & IT_CVAR) || !(cv = (consvar_t *)currentMenu->menuitems[i].itemaction)) + continue; sum += cv->value; if (!CV_IsSetToDefault(cv)) @@ -7849,10 +10583,11 @@ static void M_DrawMonitorToggles(void) for (i = 0; i < currentMenu->numitems; ++i) { - cv = (consvar_t *)currentMenu->menuitems[i].itemaction; + if (!(currentMenu->menuitems[i].status & IT_CVAR) || !(cv = (consvar_t *)currentMenu->menuitems[i].itemaction)) + continue; y = currentMenu->y + currentMenu->menuitems[i].alphaKey; - M_DrawSlider(currentMenu->x + 20, y, cv); + M_DrawSlider(currentMenu->x + 20, y, cv, (i == itemOn)); if (!cv->value) V_DrawRightAlignedString(312, y, V_OLDSPACING|((i == itemOn) ? V_YELLOWMAP : 0), "None"); @@ -7896,6 +10631,8 @@ void M_QuitResponse(INT32 ch) return; if (!(netgame || cv_debug)) { + S_ResetCaptions(); + mrand = M_RandomKey(sizeof(quitsounds)/sizeof(INT32)); if (quitsounds[mrand]) S_StartSound(NULL, quitsounds[mrand]); @@ -7979,7 +10716,6 @@ static void M_HandleFogColor(INT32 choice) break; case KEY_ESCAPE: - S_StartSound(NULL, sfx_menu1); exitmenu = true; break; diff --git a/src/m_menu.h b/src/m_menu.h index fcde5b7dbb9204ec60fa591f2c0a49f23f6f2bd6..04146ebdc7ccc97cc9bf8c68f78abed928eaf290 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -22,6 +22,140 @@ // // MENUS // + +// If menu hierarchies go deeper, change this up to 5. +// Zero-based, inclusive. +#define NUMMENULEVELS 3 +#define MENUBITS 6 + +// Menu IDs sectioned by numeric places to signify hierarchy +typedef enum +{ + MN_NONE, + + MN_MAIN, + + // Single Player + MN_SP_MAIN, + + MN_SP_LOAD, + MN_SP_PLAYER, + + MN_SP_LEVELSELECT, + MN_SP_LEVELSTATS, + + MN_SP_TIMEATTACK, + MN_SP_TIMEATTACK_LEVELSELECT, + MN_SP_GUESTREPLAY, + MN_SP_REPLAY, + MN_SP_GHOST, + + MN_SP_NIGHTSATTACK, + MN_SP_NIGHTS_LEVELSELECT, + MN_SP_NIGHTS_GUESTREPLAY, + MN_SP_NIGHTS_REPLAY, + MN_SP_NIGHTS_GHOST, + + // Multiplayer + MN_MP_MAIN, + MN_MP_SPLITSCREEN, // SplitServer + MN_MP_SERVER, + MN_MP_CONNECT, + MN_MP_ROOM, + MN_MP_PLAYERSETUP, // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET + + // Options + MN_OP_MAIN, + + MN_OP_P1CONTROLS, + MN_OP_CHANGECONTROLS, // OP_ChangeControlsDef shared with P2 + MN_OP_P1MOUSE, + MN_OP_P1JOYSTICK, + MN_OP_JOYSTICKSET, // OP_JoystickSetDef shared with P2 + + MN_OP_P2CONTROLS, + MN_OP_P2MOUSE, + MN_OP_P2JOYSTICK, + + MN_OP_VIDEO, + MN_OP_VIDEOMODE, + MN_OP_COLOR, + MN_OP_OPENGL, + MN_OP_OPENGL_LIGHTING, + MN_OP_OPENGL_FOG, + MN_OP_OPENGL_COLOR, + + MN_OP_SOUND, + + MN_OP_SERVER, + MN_OP_MONITORTOGGLE, + + MN_OP_DATA, + MN_OP_ADDONS, + MN_OP_SCREENSHOTS, + MN_OP_ERASEDATA, + + // Secrets + MN_SR_MAIN, + MN_SR_PANDORA, + MN_SR_LEVELSELECT, + MN_SR_UNLOCKCHECKLIST, + MN_SR_EMBLEMHINT, + + // Addons (Part of MISC, but let's make it our own) + MN_AD_MAIN, + + // MISC + // MN_MESSAGE, + // MN_SPAUSE, + + // MN_MPAUSE, + // MN_SCRAMBLETEAM, + // MN_CHANGETEAM, + // MN_CHANGELEVEL, + + // MN_MAPAUSE, + // MN_HELP, + + MN_SPECIAL, + NUMMENUTYPES, +} menutype_t; // up to 63; MN_SPECIAL = 53 + +typedef struct +{ + char bgname[8]; // name for background gfx lump; lays over titlemap if this is set + SINT8 hidetitlepics; // hide title gfx per menu; -1 means undefined, inherits global setting + INT32 titlescrollxspeed; // background gfx scroll per menu; inherits global setting + INT32 titlescrollyspeed; // y scroll + INT32 bgcolor; // fill color, overrides bg name. -1 means follow bg name rules. + boolean bghide; // for titlemaps, hide the background. + + char musname[7]; ///< Music track to play. "" for no music. + UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. + boolean muslooping; ///< Loop the music + boolean musstop; ///< Don't play any music + boolean musignore; ///< Let the current music keep playing + + SINT8 fadestrength; // darken background when displaying this menu, strength 0-31 or -1 for undefined + boolean enterbubble; // run all entrance line execs after common ancestor and up to child. If false, only run the child's exec + boolean exitbubble; // run all exit line execs from child and up to before common ancestor. If false, only run the child's exec + INT32 entertag; // line exec to run on menu enter, if titlemap + INT32 exittag; // line exec to run on menu exit, if titlemap + INT16 enterwipe; // wipe type to run on menu enter, -1 means default + INT16 exitwipe; // wipe type to run on menu exit, -1 means default +} menupres_t; + +extern menupres_t menupres[NUMMENUTYPES]; +extern UINT32 prevMenuId; +extern UINT32 activeMenuId; + +void M_InitMenuPresTables(void); +UINT8 M_GetYoungestChildMenu(void); +void M_ChangeMenuMusic(const char *defaultmusname, boolean defaultmuslooping); +void M_SetMenuCurBackground(const char *defaultname); +void M_SetMenuCurFadeValue(UINT8 defaultvalue); +void M_SetMenuCurHideTitlePics(void); + // Called by main loop, // saves config file and calls I_Quit when user exits. // Even when the menu is not displayed, @@ -69,7 +203,7 @@ void M_StartMessage(const char *string, void *routine, menumessagetype_t itemtyp // Called by linux_x/i_video_xshm.c void M_QuitResponse(INT32 ch); -// Determines whether to show a level in the list +// Determines whether to show a level in the list (platter version does not need to be exposed) boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt); @@ -82,7 +216,7 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt); #define IT_SUBMENU 6 // go to sub menu #define IT_CVAR 8 // handle as a cvar #define IT_SPACE 10 // no handling -#define IT_MSGHANDLER 12 // same as key but with event and sometime can handle y/n key (special for message +#define IT_MSGHANDLER 12 // same as key but with event and sometime can handle y/n key (special for message) #define IT_DISPLAY (48+64+128) // 16+32+64+128 #define IT_NOTHING 0 // space @@ -154,10 +288,9 @@ typedef struct menuitem_s UINT8 alphaKey; } menuitem_t; -extern menuitem_t PlayerMenu[MAXSKINS]; - typedef struct menu_s { + UINT32 menuid; // ID to encode menu type and hierarchy const char *menutitlepic; INT16 numitems; // # of menu items struct menu_s *prevMenu; // previous menu @@ -179,11 +312,37 @@ extern menu_t SP_LoadDef; // Stuff for customizing the player select screen typedef struct { + boolean used; char notes[441]; char picname[8]; char skinname[SKINNAMESIZE*2+2]; // skin&skin\0 + UINT8 prev; + UINT8 next; } description_t; +// level select platter +typedef struct +{ + char header[22+5]; // mapheader_t lvltttl max length + " ZONE" + INT32 maplist[3]; + char mapnames[3][17+1]; + boolean mapavailable[4]; // mapavailable[3] == wide or not +} levelselectrow_t; + +typedef struct +{ + UINT8 numrows; + levelselectrow_t *rows; +} levelselect_t; +// experimental level select end + +// descriptions for gametype select screen +typedef struct +{ + UINT8 col[2]; + char notes[441]; +} gtdesc_t; + // mode descriptions for video mode menu typedef struct { @@ -195,18 +354,14 @@ typedef struct // savegame struct for save game menu typedef struct { - char playername[37]; char levelname[32]; - UINT8 actnum; - UINT8 skincolor; UINT8 skinnum; UINT8 botskin; - UINT8 botcolor; UINT8 numemeralds; + UINT8 numgameovers; INT32 lives; INT32 continues; INT32 gamemap; - UINT8 netgame; } saveinfo_t; extern description_t description[MAXSKINS]; @@ -216,14 +371,24 @@ extern CV_PossibleValue_t gametype_cons_t[]; extern INT16 startmap; extern INT32 ultimate_selectable; +extern INT16 char_on, startchar; + +#define MAXSAVEGAMES 31 +#define NOSAVESLOT 0 //slot where Play Without Saving appears -#define MAXSAVEGAMES 31 //note: last save game is "no save" -#define NOSAVESLOT MAXSAVEGAMES-1 //slot where Play Without Saving appears +#define BwehHehHe() S_StartSound(NULL, sfx_bewar1+M_RandomKey(4)) // Bweh heh he + +void M_TutorialSaveControlResponse(INT32 ch); void M_ForceSaveSlotSelected(INT32 sslot); void M_CheatActivationResponder(INT32 ch); +void M_ModeAttackRetry(INT32 choice); + +// Level select updating +void Nextmap_OnChange(void); + // Screenshot menu updating void Moviemode_mode_Onchange(void); void Screenshot_option_Onchange(void); @@ -232,8 +397,9 @@ void Screenshot_option_Onchange(void); void Addons_option_Onchange(void); // These defines make it a little easier to make menus -#define DEFAULTMENUSTYLE(header, source, prev, x, y)\ +#define DEFAULTMENUSTYLE(id, header, source, prev, x, y)\ {\ + id,\ header,\ sizeof(source)/sizeof(menuitem_t),\ prev,\ @@ -244,8 +410,22 @@ void Addons_option_Onchange(void); NULL\ } +#define DEFAULTSCROLLMENUSTYLE(id, header, source, prev, x, y)\ +{\ + id,\ + header,\ + sizeof(source)/sizeof(menuitem_t),\ + prev,\ + source,\ + M_DrawGenericScrollMenu,\ + x, y,\ + 0,\ + NULL\ +} + #define PAUSEMENUSTYLE(source, x, y)\ {\ + MN_SPECIAL,\ NULL,\ sizeof(source)/sizeof(menuitem_t),\ NULL,\ @@ -256,8 +436,9 @@ void Addons_option_Onchange(void); NULL\ } -#define CENTERMENUSTYLE(header, source, prev, y)\ +#define CENTERMENUSTYLE(id, header, source, prev, y)\ {\ + id,\ header,\ sizeof(source)/sizeof(menuitem_t),\ prev,\ @@ -268,20 +449,22 @@ void Addons_option_Onchange(void); NULL\ } -#define MAPICONMENUSTYLE(header, source, prev)\ +#define MAPPLATTERMENUSTYLE(id, header, source)\ {\ + id,\ header,\ sizeof (source)/sizeof (menuitem_t),\ - prev,\ + &MainDef,\ source,\ - M_DrawServerMenu,\ - 27,40,\ + M_DrawLevelPlatterMenu,\ + 0,0,\ 0,\ NULL\ } -#define CONTROLMENUSTYLE(source, prev)\ +#define CONTROLMENUSTYLE(id, source, prev)\ {\ + id,\ "M_CONTRO",\ sizeof (source)/sizeof (menuitem_t),\ prev,\ @@ -294,6 +477,7 @@ void Addons_option_Onchange(void); #define IMAGEDEF(source)\ {\ + MN_SPECIAL,\ NULL,\ sizeof (source)/sizeof (menuitem_t),\ NULL,\ diff --git a/src/m_misc.c b/src/m_misc.c index 0445136fe06d5facd7c064d2f05c5ae5ab3af3cc..6fdae94115905ce3cdf4b62d8f5aa13c112268b9 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -62,7 +62,7 @@ typedef off_t off64_t; #define PRIdS "u" #elif defined (_WIN32) #define PRIdS "Iu" -#elif defined (_PSP) || defined (_arch_dreamcast) || defined (DJGPP) || defined (_WII) || defined (_NDS) || defined (_PS3) +#elif defined (DJGPP) #define PRIdS "u" #else #define PRIdS "zu" @@ -71,12 +71,10 @@ typedef off_t off64_t; #ifdef HAVE_PNG #ifndef _MSC_VER -#ifndef _WII #ifndef _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE #endif #endif -#endif #ifndef _LFS64_LARGEFILE #define _LFS64_LARGEFILE @@ -105,6 +103,8 @@ static CV_PossibleValue_t screenshot_cons_t[] = {{0, "Default"}, {1, "HOME"}, {2 consvar_t cv_screenshot_option = {"screenshot_option", "Default", CV_SAVE|CV_CALL, screenshot_cons_t, Screenshot_option_Onchange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_screenshot_folder = {"screenshot_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_screenshot_colorprofile = {"screenshot_colorprofile", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; + static CV_PossibleValue_t moviemode_cons_t[] = {{MM_GIF, "GIF"}, {MM_APNG, "aPNG"}, {MM_SCREENSHOT, "Screenshots"}, {0, NULL}}; consvar_t cv_moviemode = {"moviemode_mode", "GIF", CV_SAVE|CV_CALL, moviemode_cons_t, Moviemode_mode_Onchange, 0, NULL, NULL, 0, 0, NULL}; @@ -194,7 +194,7 @@ INT32 M_MapNumber(char first, char second) // ========================================================================== // some libcs has no access function, make our own -#if defined (_WIN32_WCE) || defined (_XBOX) || defined (_WII) || defined (_PS3) +#if defined (_WIN32_WCE) int access(const char *path, int amode) { int accesshandle = -1; @@ -446,7 +446,8 @@ void Command_LoadConfig_f(void) // load default control G_ClearAllControlKeys(); - G_Controldefault(); + G_CopyControls(gamecontrol, gamecontroldefault[gcs_fps], NULL, 0); + G_CopyControls(gamecontrolbis, gamecontrolbisdefault[gcs_fps], NULL, 0); // temporarily reset execversion to default CV_ToggleExecVersion(true); @@ -493,7 +494,9 @@ void M_FirstLoadConfig(void) } // load default control - G_Controldefault(); + G_DefineDefaultControls(); + G_CopyControls(gamecontrol, gamecontroldefault[gcs_fps], NULL, 0); + G_CopyControls(gamecontrolbis, gamecontrolbisdefault[gcs_fps], NULL, 0); // register execversion here before we load any configs CV_RegisterVar(&cv_execversion); @@ -581,8 +584,28 @@ void M_SaveConfig(const char *filename) // FIXME: save key aliases if ever implemented.. - CV_SaveVariables(f); - if (!dedicated) G_SaveKeySetting(f); + if (tutorialmode && tutorialgcs) + { + CV_SetValue(&cv_usemouse, tutorialusemouse); + CV_SetValue(&cv_alwaysfreelook, tutorialfreelook); + CV_SetValue(&cv_mousemove, tutorialmousemove); + CV_SetValue(&cv_analog, tutorialanalog); + CV_SaveVariables(f); + CV_Set(&cv_usemouse, cv_usemouse.defaultvalue); + CV_Set(&cv_alwaysfreelook, cv_alwaysfreelook.defaultvalue); + CV_Set(&cv_mousemove, cv_mousemove.defaultvalue); + CV_Set(&cv_analog, cv_analog.defaultvalue); + } + else + CV_SaveVariables(f); + + if (!dedicated) + { + if (tutorialmode && tutorialgcs) + G_SaveKeySetting(f, gamecontroldefault[gcs_custom], gamecontrolbis); // using gcs_custom as temp storage + else + G_SaveKeySetting(f, gamecontrol, gamecontrolbis); + } fclose(f); } @@ -596,7 +619,9 @@ static void M_CreateScreenShotPalette(void) size_t i, j; for (i = 0, j = 0; i < 768; i += 3, j++) { - RGBA_t locpal = pLocalPalette[(max(st_palette,0)*256)+j]; + RGBA_t locpal = ((cv_screenshot_colorprofile.value) + ? pLocalPalette[(max(st_palette,0)*256)+j] + : pMasterPalette[(max(st_palette,0)*256)+j]); screenshot_palette[i] = locpal.s.red; screenshot_palette[i+1] = locpal.s.green; screenshot_palette[i+2] = locpal.s.blue; @@ -1373,7 +1398,7 @@ typedef struct * \param palette Palette of image data */ #if NUMSCREENS > 2 -static boolean WritePCXfile(const char *filename, const UINT8 *data, int width, int height, const UINT8 *palette) +static boolean WritePCXfile(const char *filename, const UINT8 *data, int width, int height, const UINT8 *pal) { int i; size_t length; @@ -1414,8 +1439,16 @@ static boolean WritePCXfile(const char *filename, const UINT8 *data, int width, // write the palette *pack++ = 0x0c; // palette ID byte - for (i = 0; i < 768; i++) - *pack++ = *palette++; + + // write color table + { + for (i = 0; i < 256; i++) + { + *pack++ = *pal; pal++; + *pack++ = *pal; pal++; + *pack++ = *pal; pal++; + } + } // write output file length = pack - (UINT8 *)pcx; @@ -1663,6 +1696,11 @@ INT32 axtoi(const char *hexStg) return intValue; } +// Token parser variables + +static UINT32 oldendPos = 0; // old value of endPos, used by M_UnGetToken +static UINT32 endPos = 0; // now external to M_GetToken, but still static + /** Token parser for TEXTURES, ANIMDEFS, and potentially other lumps later down the line. * Was originally R_GetTexturesToken when I was coding up the TEXTURES parser, until I realized I needed it for ANIMDEFS too. * Parses up to the next whitespace character or comma. When finding the start of the next token, whitespace is skipped. @@ -1677,7 +1715,7 @@ char *M_GetToken(const char *inputString) { static const char *stringToUse = NULL; // Populated if inputString != NULL; used otherwise static UINT32 startPos = 0; - static UINT32 endPos = 0; +// static UINT32 endPos = 0; static UINT32 stringLength = 0; static UINT8 inComment = 0; // 0 = not in comment, 1 = // Single-line, 2 = /* Multi-line */ char *texturesToken = NULL; @@ -1687,12 +1725,12 @@ char *M_GetToken(const char *inputString) { stringToUse = inputString; startPos = 0; - endPos = 0; + oldendPos = endPos = 0; stringLength = strlen(inputString); } else { - startPos = endPos; + startPos = oldendPos = endPos; } if (stringToUse == NULL) return NULL; @@ -1823,6 +1861,16 @@ char *M_GetToken(const char *inputString) return texturesToken; } +/** Undoes the last M_GetToken call + * The current position along the string being parsed is reset to the last saved position. + * This exists mostly because of R_ParseTexture/R_ParsePatch honestly, but could be useful elsewhere? + * -Monster Iestyn (22/10/16) + */ +void M_UnGetToken(void) +{ + endPos = oldendPos; +} + /** Count bits in a number. */ UINT8 M_CountBits(UINT32 num, UINT8 size) diff --git a/src/m_misc.h b/src/m_misc.h index 7dd8baabf2d82713178c3c49f5f0329ecd909eb4..6ac92dbcc085324c5c5bcba48c8f22fd2824c85f 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -29,7 +29,7 @@ typedef enum { } moviemode_t; extern moviemode_t moviemode; -extern consvar_t cv_screenshot_option, cv_screenshot_folder; +extern consvar_t cv_screenshot_option, cv_screenshot_folder, cv_screenshot_colorprofile; extern consvar_t cv_moviemode; extern consvar_t cv_zlib_memory, cv_zlib_level, cv_zlib_strategy, cv_zlib_window_bits; extern consvar_t cv_zlib_memorya, cv_zlib_levela, cv_zlib_strategya, cv_zlib_window_bitsa; @@ -40,13 +40,7 @@ void M_SaveFrame(void); void M_StopMovie(void); // the file where game vars and settings are saved -#ifdef DC -#define CONFIGFILENAME "srb2dc.cfg" -#elif defined (PSP) -#define CONFIGFILENAME "srb2psp.cfg" -#else #define CONFIGFILENAME "config.cfg" -#endif INT32 M_MapNumber(char first, char second); diff --git a/src/md5.c b/src/md5.c index 8031650e60666109fb8562af0ff25b94f4304ec4..66d563666059a292cc836771d793fcbc529a49c4 100644 --- a/src/md5.c +++ b/src/md5.c @@ -19,9 +19,7 @@ #endif #include <string.h> -#ifndef _WIN32_WCE #include <sys/types.h> -#endif #ifdef _MSC_VER #pragma warning(disable : 4127) #endif @@ -30,7 +28,7 @@ #include <stdlib.h> #else #ifndef HAVE_MEMCPY - #if !((defined (_WIN32) || defined (_WIN32_WCE)) && !defined (__CYGWIN__)) && !defined (__APPLE__) + #if !(defined (_WIN32) && !defined (__CYGWIN__)) && !defined (__APPLE__) #define memcpy(d, s, n) bcopy ((s), (d), (n)) #endif #endif diff --git a/src/mserv.c b/src/mserv.c index 3fbb637601f1bbd27add6ef6d85fd028ba8551ca..cf636dfdfb74082fc219d312819a686fc8d6bb0f 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -16,9 +16,7 @@ #include <errno.h> #endif -#if !defined (UNDER_CE) #include <time.h> -#endif #if (defined (NOMD5) || defined (NOMSERV)) && !defined (NONET) #define NONET @@ -30,7 +28,7 @@ #define HAVE_IPV6 #endif -#if (defined (_WIN32) || defined (_WIN32_WCE)) && !defined (_XBOX) +#ifdef _WIN32 #define RPC_NO_WINDOWS_H #ifdef HAVE_IPV6 #include <ws2tcpip.h> @@ -38,16 +36,6 @@ #include <winsock.h> // socket(),... #endif //!HAVE_IPV6 #else -#ifdef __OS2__ -#include <sys/types.h> -#endif // __OS2__ - -#ifdef HAVE_LWIP -#include <lwip/inet.h> -#include <kos/net.h> -#include <lwip/lwip.h> -#define ioctl lwip_ioctl -#else #include <arpa/inet.h> #ifdef __APPLE_CC__ #ifndef _BSD_SOCKLEN_T_ @@ -56,25 +44,12 @@ #endif #include <sys/socket.h> // socket(),... #include <netinet/in.h> // sockaddr_in -#ifdef _PS3 -#include <net/select.h> -#elif !defined(_arch_dreamcast) #include <netdb.h> // getaddrinfo(),... #include <sys/ioctl.h> -#endif -#endif - -#ifdef _arch_dreamcast -#include "sdl12/SRB2DC/dchelp.h" -#endif #include <sys/time.h> // timeval,... (TIMEOUT) #include <errno.h> -#endif // _WIN32/_WIN32_WCE - -#ifdef __OS2__ -#include <errno.h> -#endif // __OS2__ +#endif // _WIN32 #endif // !NONET #include "doomstat.h" @@ -91,10 +66,6 @@ #include "m_argv.h" // Alam is going to kill me <3 #include "m_misc.h" // GetRevisionString() -#ifdef _WIN32_WCE -#include "sdl12/SRB2CE/cehelp.h" -#endif - #include "i_addrinfo.h" // ================================ DEFINITIONS =============================== @@ -183,13 +154,13 @@ typedef struct #endif // win32 or djgpp -#if defined (_WIN32) || defined (_WIN32_WCE) || defined (__DJGPP__) +#if defined (_WIN32) || defined (__DJGPP__) #define ioctl ioctlsocket #define close closesocket #ifdef WATTCP #define strerror strerror_s #endif -#if defined (_WIN32) || defined (_WIN32_WCE) +#ifdef _WIN32 #undef errno #define errno h_errno // some very strange things happen when not using h_error #endif @@ -215,11 +186,11 @@ static enum { MSCS_NONE, MSCS_WAITING, MSCS_REGISTERED, MSCS_FAILED } con_state static INT32 msnode = -1; UINT16 current_port = 0; -#if (defined (_WIN32) || defined (_WIN32_WCE) || defined (_WIN32)) && !defined (NONET) +#if defined (_WIN32) && !defined (NONET) typedef SOCKET SOCKET_TYPE; #define ERRSOCKET (SOCKET_ERROR) #else -#if (defined (__unix__) && !defined (MSDOS)) || defined (__APPLE__) || defined (__HAIKU__) || defined (_PS3) +#if (defined (__unix__) && !defined (MSDOS)) || defined (__APPLE__) || defined (__HAIKU__) typedef int SOCKET_TYPE; #else typedef unsigned long SOCKET_TYPE; diff --git a/src/nds/Makefile.cfg b/src/nds/Makefile.cfg deleted file mode 100644 index c2d915924ab55692039d67eaed070578a815f0eb..0000000000000000000000000000000000000000 --- a/src/nds/Makefile.cfg +++ /dev/null @@ -1,31 +0,0 @@ -# Adapted in part from devkitPRO makefiles. - -NOMD5=1 - -# Check if DEVKITARM is set in the environment. If so, continue with compilation. -.SUFFIXES: - -ifeq ($(strip $(DEVKITARM)),) -$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM") -endif - -# use absolute paths because changing PATH variable breaks distcc -PREFIX := $(DEVKITARM)/bin/arm-eabi -NDSTOOL := $(DEVKITARM)/bin/ndstool - -# Disable same warning flags -WFLAGS+=-Wno-inline -Wno-cast-align -WFLAGS+=-Wno-shadow -Wno-char-subscripts -WFLAGS+=-Wno-declaration-after-statement -WFLAGS+=-Wno-old-style-definition -WFLAGS+=-Wno-undef -WFLAGS+=-Wno-unsuffixed-float-constants - -ifndef NOHW - OBJS+=$(OBJDIR)/r_nds3d.o -endif - -ARCH = -mthumb -mthumb-interwork -LDFLAGS += -L$(DEVKITPRO)/libnds/lib -specs=ds_arm9.specs -g $(ARCH) -mno-fpu -LIBS += -lfat -lnds9 -CFLAGS += -D_NDS -DARM9 -I$(DEVKITPRO)/libnds/include $(ARCH) -march=armv5te -mtune=arm946e-s -fomit-frame-pointer -ffast-math diff --git a/src/nds/i_cdmus.c b/src/nds/i_cdmus.c deleted file mode 100644 index f3f7036677dfb1092dc23170e64bd60cd7287619..0000000000000000000000000000000000000000 --- a/src/nds/i_cdmus.c +++ /dev/null @@ -1,37 +0,0 @@ -#include "../command.h" -#include "../s_sound.h" -#include "../i_sound.h" - -// -// CD MUSIC I/O -// - -UINT8 cdaudio_started = 0; - -consvar_t cd_volume = {"cd_volume","31",CV_SAVE,soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cdUpdate = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; - - -void I_InitCD(void){} - -void I_StopCD(void){} - -void I_PauseCD(void){} - -void I_ResumeCD(void){} - -void I_ShutdownCD(void){} - -void I_UpdateCD(void){} - -void I_PlayCD(UINT8 track, UINT8 looping) -{ - (void)track; - (void)looping; -} - -boolean I_SetVolumeCD(int volume) -{ - (void)volume; - return false; -} diff --git a/src/nds/i_main.c b/src/nds/i_main.c deleted file mode 100644 index 292a5f91dfc1ce77a52597ee5458d6548d831e92..0000000000000000000000000000000000000000 --- a/src/nds/i_main.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "../doomdef.h" -#include "../d_main.h" -#include "../m_argv.h" -#include "../i_system.h" - -int main(int argc, char **argv) -{ - myargc = argc; - myargv = argv; /// \todo pull out path to exe from this string - - CONS_Printf("I_StartupSystem..."); - I_StartupSystem(); - - // startup SRB2 - CONS_Printf("Setting up SRB2...\n"); - D_SRB2Main(); - CONS_Printf("Entering main game loop...\n"); - // never return - D_SRB2Loop(); - - // return to OS -#ifndef __GNUC__ - return 0; -#endif -} diff --git a/src/nds/i_net.c b/src/nds/i_net.c deleted file mode 100644 index f6e642022e4a54360d68004f69d61eaa5e3acb19..0000000000000000000000000000000000000000 --- a/src/nds/i_net.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "../i_net.h" - -boolean I_InitNetwork(void) -{ - return false; -} diff --git a/src/nds/i_sound.c b/src/nds/i_sound.c deleted file mode 100644 index a17c7f66a24a746e68e78147dc943fd0892c093b..0000000000000000000000000000000000000000 --- a/src/nds/i_sound.c +++ /dev/null @@ -1,151 +0,0 @@ -#include "../i_sound.h" - -UINT8 sound_started = 0; - -void *I_GetSfx(sfxinfo_t *sfx) -{ - (void)sfx; - return NULL; -} - -void I_FreeSfx(sfxinfo_t *sfx) -{ - (void)sfx; -} - -void I_StartupSound(void){} - -void I_ShutdownSound(void){} - -// -// SFX I/O -// - -INT32 I_StartSound(sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, INT32 priority, INT32 channel) -{ - (void)id; - (void)vol; - (void)sep; - (void)pitch; - (void)priority; - (void)channel; - return -1; -} - -void I_StopSound(INT32 handle) -{ - (void)handle; -} - -INT32 I_SoundIsPlaying(INT32 handle) -{ - (void)handle; - return false; -} - -void I_UpdateSoundParams(INT32 handle, INT32 vol, INT32 sep, INT32 pitch) -{ - (void)handle; - (void)vol; - (void)sep; - (void)pitch; -} - -void I_SetSfxVolume(INT32 volume) -{ - (void)volume; -} - -// -// MUSIC I/O -// -UINT8 music_started = 0; - -void I_InitMusic(void){} - -void I_ShutdownMusic(void){} - -void I_PauseSong(INT32 handle) -{ - (void)handle; -} - -void I_ResumeSong(INT32 handle) -{ - (void)handle; -} - -// -// MIDI I/O -// - -UINT8 midimusic_started = 0; - -void I_InitMIDIMusic(void){} - -void I_ShutdownMIDIMusic(void){} - -void I_SetMIDIMusicVolume(INT32 volume) -{ - (void)volume; -} - -INT32 I_RegisterSong(void *data, size_t len) -{ - (void)data; - (void)len; - return -1; -} - -boolean I_PlaySong(INT32 handle, INT32 looping) -{ - (void)handle; - (void)looping; - return false; -} - -void I_StopSong(INT32 handle) -{ - (void)handle; -} - -void I_UnRegisterSong(INT32 handle) -{ - (void)handle; -} - -// -// DIGMUSIC I/O -// - -UINT8 digmusic_started = 0; - -void I_InitDigMusic(void){} - -void I_ShutdownDigMusic(void){} - -boolean I_StartDigSong(const char *musicname, INT32 looping) -{ - (void)musicname; - (void)looping; - return false; -} - -void I_StopDigSong(void){} - -void I_SetDigMusicVolume(INT32 volume) -{ - (void)volume; -} - -boolean I_SetSongSpeed(float speed) -{ - (void)speed; - return false; -} - -boolean I_SetSongTrack(int track) -{ - (void)track; - return false; -} diff --git a/src/nds/i_system.c b/src/nds/i_system.c deleted file mode 100644 index 3e5c4b8c6d33fb6d266d12aad24e3d50748a9769..0000000000000000000000000000000000000000 --- a/src/nds/i_system.c +++ /dev/null @@ -1,286 +0,0 @@ -#include <nds.h> -#include <fat.h> - -#include "../doomdef.h" -#include "../d_main.h" -#include "../i_system.h" -#include "../i_joy.h" - -UINT8 graphics_started = 0; - -UINT8 keyboard_started = 0; - -static volatile tic_t ticcount; - - -UINT32 I_GetFreeMem(UINT32 *total) -{ - *total = 0; - return 0; -} - -tic_t I_GetTime(void) -{ - return ticcount; -} - -void I_Sleep(void){} - -void I_GetEvent(void) -{ - // Mappings of DS keys to SRB2 keys - UINT32 dskeys[] = - { - KEY_A, - KEY_B, - KEY_X, - KEY_Y, - KEY_L, - KEY_R, - KEY_START, - KEY_SELECT - }; - - event_t event; - UINT32 held, up, down; - UINT32 i; - - // Check how the state has changed since last time - scanKeys(); - - // For the d-pad, we only care about the current state - held = keysHeld(); - event.type = ev_joystick; - event.data1 = 0; // First (and only) axis set - - if (held & KEY_LEFT) event.data2 = -1; - else if (held & KEY_RIGHT) event.data2 = 1; - else event.data2 = 0; - - if (held & KEY_UP) event.data3 = -1; - else if (held & KEY_DOWN) event.data3 = 1; - else event.data3 = 0; - - D_PostEvent(&event); - - // For the buttons, we need to report changes in state - up = keysUp(); - down = keysDown(); - for (i = 0; i < sizeof(dskeys)/sizeof(dskeys[0]); i++) - { - // Has this button's state changed? - if ((up | down) & dskeys[i]) - { - event.type = (up & dskeys[i]) ? ev_keyup : ev_keydown; - event.data1 = KEY_JOY1 + i; - D_PostEvent(&event); - } - } -} - -void I_OsPolling(void) -{ - I_GetEvent(); -} - -ticcmd_t *I_BaseTiccmd(void) -{ - static ticcmd_t emptyticcmd; - return &emptyticcmd; -} - -ticcmd_t *I_BaseTiccmd2(void) -{ - static ticcmd_t emptyticcmd2; - return &emptyticcmd2; -} - -void I_Quit(void) -{ - exit(0); -} - -void I_Error(const char *error, ...) -{ - va_list argptr; - - va_start(argptr, error); - viprintf(error, argptr); - va_end(argptr); - - for(;;); -} - -void I_Tactile(FFType Type, const JoyFF_t *Effect) -{ - (void)Type; - (void)Effect; -} - -void I_Tactile2(FFType Type, const JoyFF_t *Effect) -{ - (void)Type; - (void)Effect; -} - -void I_JoyScale(void){} - -void I_JoyScale2(void){} - -void I_InitJoystick(void) -{ - Joystick.bGamepadStyle = true; -} - -void I_InitJoystick2(void){} - -INT32 I_NumJoys(void) -{ - return 0; -} - -const char *I_GetJoyName(INT32 joyindex) -{ - (void)joyindex; - return NULL; -} - -void I_SetupMumble(void) -{ -} - -#ifndef NOMUMBLE -void I_UpdateMumble(const mobj_t *mobj, const listener_t listener) -{ - (void)mobj; - (void)listener; -} -#endif - -void I_OutputMsg(const char *error, ...) -{ - va_list argptr; - - va_start(argptr, error); - viprintf(error, argptr); - va_end(argptr); -} - -void I_StartupMouse(void){} - -void I_StartupMouse2(void){} - -void I_StartupKeyboard(void){} - -INT32 I_GetKey(void) -{ - return 0; -} - -static void NDS_VBlankHandler(void) -{ - ticcount++; -} - -void I_StartupTimer(void) -{ - irqSet(IRQ_VBLANK, NDS_VBlankHandler); -} - -void I_AddExitFunc(void (*func)()) -{ - (void)func; -} - -void I_RemoveExitFunc(void (*func)()) -{ - (void)func; -} - -// Adapted in part from the devkitPro examples. -INT32 I_StartupSystem(void) -{ - lcdMainOnTop(); - - videoSetModeSub(MODE_0_2D); - vramSetBankC(VRAM_C_MAIN_BG); // Get this mapped *out* of the sub BG - vramSetBankI(VRAM_I_SUB_BG_0x06208000); - - // The background VRAM that's mapped starts at 0x06208000. - // The map base is specified in an offset of multiples of 2 KB - // from 0x06200000, and the tile base in multiples of 16 KB. - // We put the tiles at the start and the map 2 KB from the end - // (i.e. 14 KB from the start). - // The map base is then at 0x0620B800 = 0x06200000 + 16 * 0x800 + 7 * 0x800, - // and the tile base is at 0x06208000 = 0x06200000 + 2 * 0x4000. - consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 16+7, 2, false, true); - - // start FAT filesystem code, required for reading SD card - if(!fatInitDefault()) - I_Error("Couldn't init FAT."); - - return 0; -} - -void I_ShutdownSystem(void){} - -void I_GetDiskFreeSpace(INT64* freespace) -{ - *freespace = 0; -} - -char *I_GetUserName(void) -{ - return NULL; -} - -INT32 I_mkdir(const char *dirname, INT32 unixright) -{ - (void)dirname; - (void)unixright; - return -1; -} - -const CPUInfoFlags *I_CPUInfo(void) -{ - return NULL; -} - -const char *I_LocateWad(void) -{ - return NULL; -} - -void I_GetJoystickEvents(void){} - -void I_GetJoystick2Events(void){} - -void I_GetMouseEvents(void){} - -char *I_GetEnv(const char *name) -{ - (void)name; - return NULL; -} - -INT32 I_PutEnv(char *variable) -{ - (void)variable; - return -1; -} - -INT32 I_ClipboardCopy(const char *data, size_t size) -{ - (void)data; - (void)size; - return -1; -} - -char *I_ClipboardPaste(void) -{ - return NULL; -} - -void I_RegisterSysCommands(void) {} - -#include "../sdl/dosstr.c" diff --git a/src/nds/i_video.c b/src/nds/i_video.c deleted file mode 100644 index 3dfb995574b1804ff0be222f8d771e888b3d1047..0000000000000000000000000000000000000000 --- a/src/nds/i_video.c +++ /dev/null @@ -1,148 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1993-1996 by id Software, Inc. -// Portions Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief SRB2 graphics stuff for NDS - - -#include "../doomdef.h" -#include "../command.h" -#include "../i_video.h" - -#include "../hardware/hw_drv.h" -#include "../hardware/hw_main.h" -#include "r_nds3d.h" - -rendermode_t rendermode = render_opengl; - -boolean highcolor = false; - -boolean allow_fullscreen = false; - -consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - -void I_StartupGraphics(void) -{ - vid.width = 256; - vid.height = 192; - vid.bpp = 1; - vid.rowbytes = vid.width * vid.bpp; - vid.recalc = true; - - HWD.pfnInit = NDS3D_Init; - HWD.pfnShutdown = NDS3D_Shutdown; - HWD.pfnFinishUpdate = NDS3D_FinishUpdate; - HWD.pfnDraw2DLine = NDS3D_Draw2DLine; - HWD.pfnDrawPolygon = NDS3D_DrawPolygon; - HWD.pfnSetBlend = NDS3D_SetBlend; - HWD.pfnClearBuffer = NDS3D_ClearBuffer; - HWD.pfnSetTexture = NDS3D_SetTexture; - HWD.pfnReadRect = NDS3D_ReadRect; - HWD.pfnGClipRect = NDS3D_GClipRect; - HWD.pfnClearMipMapCache = NDS3D_ClearMipMapCache; - HWD.pfnSetSpecialState = NDS3D_SetSpecialState; - HWD.pfnSetPalette = NDS3D_SetPalette; - HWD.pfnGetTextureUsed = NDS3D_GetTextureUsed; - HWD.pfnDrawMD2 = NDS3D_DrawMD2; - HWD.pfnDrawMD2i = NDS3D_DrawMD2i; - HWD.pfnSetTransform = NDS3D_SetTransform; - HWD.pfnGetRenderVersion = NDS3D_GetRenderVersion; - - videoSetMode(MODE_0_3D); - vramSetBankA(VRAM_A_TEXTURE); - vramSetBankB(VRAM_B_TEXTURE); - vramSetBankC(VRAM_C_TEXTURE); - vramSetBankD(VRAM_D_TEXTURE); - vramSetBankE(VRAM_E_TEX_PALETTE); - - glInit(); - - glEnable(GL_TEXTURE_2D); - - glClearColor(16,16,16,31); - glClearPolyID(63); - glClearDepth(0x7FFF); - - glViewport(0, 0, vid.width - 1, vid.height - 1); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - gluPerspective(fov, ASPECT_RATIO, NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glScalef(1.0f, 1.0f, -1.0f); - - HWD.pfnInit(I_Error); - HWR_Startup(); -} - -void I_ShutdownGraphics(void){} - -void I_SetPalette(RGBA_t *palette) -{ - (void)palette; -} - -INT32 VID_NumModes(void) -{ - return 0; -} - -INT32 VID_GetModeForSize(INT32 w, INT32 h) -{ - (void)w; - (void)h; - return 0; -} - -void VID_PrepareModeList(void){} - -INT32 VID_SetMode(INT32 modenum) -{ - (void)modenum; - return 0; -} - -const char *VID_GetModeName(INT32 modenum) -{ - (void)modenum; - return NULL; -} - -void I_UpdateNoBlit(void){} - -void I_FinishUpdate(void) -{ - HWD.pfnFinishUpdate(true); -} - -void I_UpdateNoVsync(void) {} - -void I_WaitVBL(INT32 count) -{ - (void)count; -} - -void I_ReadScreen(UINT8 *scr) -{ - (void)scr; -} - -void I_BeginRead(void){} - -void I_EndRead(void){} diff --git a/src/nds/r_nds3d.c b/src/nds/r_nds3d.c deleted file mode 100644 index dbdcec158c1d64ac2da05b4a4b52fb0535d4d40a..0000000000000000000000000000000000000000 --- a/src/nds/r_nds3d.c +++ /dev/null @@ -1,389 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1993-1996 by id Software, Inc. -// Portions Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief NDS 3D API for SRB2. -// -// In an ideal world, we would share as much code as possible with r_opengl.c, -// but this will do for now. - -#include "../doomtype.h" -#include "../hardware/hw_defs.h" -#include "../hardware/hw_dll.h" -#include "../hardware/hw_md2.h" -#include "r_nds3d.h" - -static I_Error_t I_Error_GL = NULL; - -#define NOTEXTURE_NUM 0 // small white texture -#define FIRST_TEX_AVAIL (NOTEXTURE_NUM + 1) -#define MAX_SRB2_TEXTURES 256 - -FCOORD NEAR_CLIPPING_PLANE = 0.9f; -float fov = 90.0f; - -static FBITFIELD CurrentPolyFlags = 0xFFFFFFFF; -static UINT32 CurrentGLPolyFmt = POLY_CULL_NONE; -static UINT8 CurrentPolyAlpha = 31; -static UINT16 myPaletteData[256]; -static FTextureInfo* gr_cachetail = NULL; -static FTextureInfo* gr_cachehead = NULL; -static INT32 NextTexAvail = FIRST_TEX_AVAIL; -static UINT32 tex_downloaded = 0; -static INT32 texids[MAX_SRB2_TEXTURES]; -static boolean scalehack = false; - - -static void GenerateTextureNames(void) -{ - glGenTextures(MAX_SRB2_TEXTURES - 1, texids + 1); - texids[NOTEXTURE_NUM] = 0; -} - -static void Flush(void) -{ - // Delete all textures at once, since libnds's glDeleteTextures seems to be buggy. - glResetTextures(); - GenerateTextureNames(); - while (gr_cachehead) - { - gr_cachehead->downloaded = 0; - gr_cachehead = gr_cachehead->nextmipmap; - } - gr_cachetail = gr_cachehead = NULL; - NextTexAvail = FIRST_TEX_AVAIL; - tex_downloaded = 0; -} - -static void SetNoTexture(void) -{ - // Set small white texture. - if (tex_downloaded != NOTEXTURE_NUM) - { - glBindTexture(GL_TEXTURE_2D, texids[NOTEXTURE_NUM]); - tex_downloaded = NOTEXTURE_NUM; - } -} - - -static void SetAlpha(UINT8 alpha) -{ - CurrentPolyAlpha = alpha >> 3; - glPolyFmt(CurrentGLPolyFmt | POLY_ALPHA(CurrentPolyAlpha)); -} - - - -boolean NDS3D_Init(I_Error_t ErrorFunction) -{ - I_Error_GL = ErrorFunction; - glPolyFmt(CurrentGLPolyFmt | POLY_ALPHA(CurrentPolyAlpha)); - GenerateTextureNames(); - return true; -} - -void NDS3D_Shutdown(void) {} - -void NDS3D_SetPalette(RGBA_t *ppal, RGBA_t *pgamma) -{ - INT32 i; - - for (i = 0; i < 256; i++) - { - UINT8 red = (UINT8)min((ppal[i].s.red*pgamma->s.red)/127, 255) >> 3; - UINT8 green = (UINT8)min((ppal[i].s.green*pgamma->s.green)/127, 255) >> 3; - UINT8 blue = (UINT8)min((ppal[i].s.blue*pgamma->s.blue)/127, 255) >> 3; - - myPaletteData[i] = ARGB16(ppal[i].s.alpha ? 1 : 0, red, green, blue); - } - - Flush(); -} - -void NDS3D_FinishUpdate(INT32 waitvbl) -{ - (void)waitvbl; - - glFlush(0); -} - -void NDS3D_Draw2DLine(F2DCoord *v1, F2DCoord *v2, RGBA_t Color) -{ - (void)v1; - (void)v2; - (void)Color; -} - -void NDS3D_DrawPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags) -{ - FUINT i; - - NDS3D_SetBlend(PolyFlags); - - // If Modulated, mix the surface colour to the texture - if ((CurrentPolyFlags & PF_Modulated) && pSurf) - { - glColor3b(pSurf->FlatColor.s.red, pSurf->FlatColor.s.green, pSurf->FlatColor.s.blue); - SetAlpha(pSurf->FlatColor.s.alpha); - } - - // libnds doesn't have GL_TRIANGLE_FAN, so use GL_TRIANGLE_STRIP instead - glBegin(GL_TRIANGLE_STRIP); - for (i = 0; i < iNumPts; i++) - { - FUINT index = (i & 1) ? (i >> 1) : (iNumPts - 1 - (i >> 1)); - FLOAT x, y, z; - - if (scalehack) - { - x = pOutVerts[index].x/4096.0f; - y = pOutVerts[index].y/4096.0f; - z = pOutVerts[index].z/4096.0f; - } - else - { - x = pOutVerts[index].x; - y = pOutVerts[index].y; - z = pOutVerts[index].z; - } - - glTexCoord2f(pOutVerts[index].sow, pOutVerts[index].tow); - glVertex3f(x,y,z); - } - glEnd(); -} - -void NDS3D_SetBlend(FBITFIELD PolyFlags) -{ - FBITFIELD Xor = PolyFlags ^ CurrentPolyFlags; - - if (Xor & (PF_NoTexture|PF_Modulated)) - { - if (Xor&PF_Modulated) - { - if(!(PolyFlags & PF_Modulated)) - { - glColor3b(255, 255, 255); - CurrentPolyAlpha = 31; - } - } - - if (PolyFlags & PF_NoTexture) - { - SetNoTexture(); - } - } - - CurrentPolyFlags = PolyFlags; - glPolyFmt(CurrentGLPolyFmt | POLY_ALPHA(CurrentPolyAlpha)); -} - -void NDS3D_ClearBuffer(FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor) -{ - (void)ClearColor; - - if (ColorMask && ClearColor) - { - // TODO: Fixed-ify - glClearColor((uint8)(ClearColor->red*31), - (uint8)(ClearColor->green*31), - (uint8)(ClearColor->blue*31), - (uint8)(ClearColor->alpha*31)); - } - - if (DepthMask) - glClearDepth(GL_MAX_DEPTH); - - NDS3D_SetBlend(DepthMask ? PF_Occlude | CurrentPolyFlags : CurrentPolyFlags&~PF_Occlude); -} - -void NDS3D_SetTexture(FTextureInfo *TexInfo) -{ - if (!TexInfo) - { - SetNoTexture(); - return; - } - else if (TexInfo->downloaded) - { - if (TexInfo->downloaded != tex_downloaded) - { - glBindTexture(GL_TEXTURE_2D, texids[TexInfo->downloaded]); - tex_downloaded = TexInfo->downloaded; - } - } - else if (TexInfo->grInfo.data) - { - UINT8 wtype, htype; - INT32 texparam = GL_TEXTURE_COLOR0_TRANSPARENT; - - // We rely on the numerical values of GL_TEXTURE_SIZE_ENUM here. - wtype = TEXTURE_SIZE_8; - while(TexInfo->width > 1 << (wtype + 3)) wtype++; - - htype = TEXTURE_SIZE_8; - while(TexInfo->height > 1 << (htype + 3)) htype++; - - TexInfo->downloaded = NextTexAvail++; - tex_downloaded = TexInfo->downloaded; - glBindTexture(GL_TEXTURE_2D, texids[TexInfo->downloaded]); - - if(!glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB256, wtype, htype, 0, TEXGEN_TEXCOORD, TexInfo->grInfo.data)) - { - // HACK: If we're out of memory, flush and try again. - // This will result in artefacts for one frame. - Flush(); - TexInfo->downloaded = 0; - NDS3D_SetTexture(TexInfo); - return; - } - - if (TexInfo->downloaded > FIRST_TEX_AVAIL) - { - // We already have a texture using the palette, so it's already in VRAM - glAssignColorTable(GL_TEXTURE_2D, texids[FIRST_TEX_AVAIL]); - } - else - { - // Generate the palette in hardware - glColorTableEXT(0, 0, 256, 0, 0, myPaletteData); - } - - if (TexInfo->flags & TF_WRAPX) - texparam |= GL_TEXTURE_WRAP_S; - - if (TexInfo->flags & TF_WRAPY) - texparam |= GL_TEXTURE_WRAP_T; - - glTexParameter(0, texparam); - - TexInfo->nextmipmap = NULL; - if (gr_cachetail) - { - gr_cachetail->nextmipmap = TexInfo; - gr_cachetail = TexInfo; - } - else - gr_cachetail = gr_cachehead = TexInfo; - } -} - -void NDS3D_ReadRect(INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data) -{ - (void)x; - (void)y; - (void)width; - (void)height; - (void)dst_stride; - (void)dst_data; -} - -void NDS3D_GClipRect(INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip) -{ - (void)minx; - (void)miny; - (void)maxx; - (void)maxy; - //glViewport(minx, vid.height-maxy, maxx-minx, maxy-miny); - NEAR_CLIPPING_PLANE = nearclip; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(fov, ASPECT_RATIO, NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE); - glMatrixMode(GL_MODELVIEW); -} - -void NDS3D_ClearMipMapCache(void) {} - -void NDS3D_SetSpecialState(hwdspecialstate_t IdState, INT32 Value) -{ - (void)IdState; - (void)Value; -} - -void NDS3D_DrawMD2(INT32 *gl_cmd_buffer, md2_frame_t *frame, FTransform *pos, float scale) -{ - (void)gl_cmd_buffer; - (void)frame; - (void)pos; - (void)scale; -} - -void NDS3D_DrawMD2i(INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 duration, UINT32 tics, md2_frame_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) -{ - (void)gl_cmd_buffer; - (void)frame; - (void)duration; - (void)tics; - (void)nextframe; - (void)pos; - (void)scale; - (void)flipped; - (void)color; -} - -void NDS3D_SetTransform(FTransform *ptransform) -{ - static INT32 special_splitscreen; - glLoadIdentity(); - if (ptransform) - { - scalehack = true; - - glScalef(ptransform->scalex*4096.0f, ptransform->scaley*4096.0f, -ptransform->scalez*4096.0f); - glRotatef(ptransform->anglex , 1.0f, 0.0f, 0.0f); - glRotatef(ptransform->angley+270.0f, 0.0f, 1.0f, 0.0f); - glTranslatef(-ptransform->x/4096.0f, -ptransform->z/4096.0f, -ptransform->y/4096.0f); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - special_splitscreen = (ptransform->splitscreen && ptransform->fovxangle == 90.0f); - if (special_splitscreen) - gluPerspective(53.13l, 2*ASPECT_RATIO, // 53.13 = 2*atan(0.5) - NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE); - else - gluPerspective(ptransform->fovxangle, ASPECT_RATIO, NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE); - - glMatrixMode(GL_MODELVIEW); - } - else - { - scalehack = false; - - glScalef(1.0f, 1.0f, -1.0f); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - if (special_splitscreen) - gluPerspective(53.13l, 2*ASPECT_RATIO, // 53.13 = 2*atan(0.5) - NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE); - else - //Hurdler: is "fov" correct? - gluPerspective(fov, ASPECT_RATIO, NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE); - - glMatrixMode(GL_MODELVIEW); - } -} - -INT32 NDS3D_GetTextureUsed(void) -{ - return 0; -} - -INT32 NDS3D_GetRenderVersion(void) -{ - return 0; -} diff --git a/src/nds/r_nds3d.h b/src/nds/r_nds3d.h deleted file mode 100644 index 3a7075bcded94fe550a12f54c2fe952d61a5bb7d..0000000000000000000000000000000000000000 --- a/src/nds/r_nds3d.h +++ /dev/null @@ -1,55 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1993-1996 by id Software, Inc. -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief NDS 3D API for SRB2. - -#ifndef __R_NDS3D__ -#define __R_NDS3D__ - -#include "../doomtype.h" -#include "../hardware/hw_defs.h" -#include "../hardware/hw_dll.h" -#include "../hardware/hw_md2.h" - -#define FAR_CLIPPING_PLANE 150000.0f -#define ASPECT_RATIO 1.0f - -typedef float FCOORD; - -extern FCOORD NEAR_CLIPPING_PLANE; -extern float fov; - -boolean NDS3D_Init(I_Error_t ErrorFunction); -void NDS3D_Shutdown(void); -void NDS3D_SetPalette(RGBA_t *ppal, RGBA_t *pgamma); -void NDS3D_FinishUpdate(INT32 waitvbl); -void NDS3D_Draw2DLine(F2DCoord *v1, F2DCoord *v2, RGBA_t Color); -void NDS3D_DrawPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags); -void NDS3D_SetBlend(FBITFIELD PolyFlags); -void NDS3D_ClearBuffer(FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor); -void NDS3D_SetTexture(FTextureInfo *TexInfo); -void NDS3D_ReadRect(INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data); -void NDS3D_GClipRect(INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip); -void NDS3D_ClearMipMapCache(void); -void NDS3D_SetSpecialState(hwdspecialstate_t IdState, INT32 Value); -void NDS3D_DrawMD2(INT32 *gl_cmd_buffer, md2_frame_t *frame, FTransform *pos, float scale); -void NDS3D_DrawMD2i(INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 duration, UINT32 tics, md2_frame_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color); -void NDS3D_SetTransform(FTransform *ptransform); -INT32 NDS3D_GetTextureUsed(void); -INT32 NDS3D_GetRenderVersion(void); - -#endif diff --git a/src/p_enemy.c b/src/p_enemy.c index 7c28854eaad6fad51ff56f0383ab93da5344e281..2861f448020da629178503808189aff4185c02e3 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -15,6 +15,7 @@ #include "doomdef.h" #include "g_game.h" #include "p_local.h" +#include "p_setup.h" #include "r_main.h" #include "r_state.h" #include "s_sound.h" @@ -22,6 +23,7 @@ #include "m_misc.h" #include "r_things.h" #include "i_video.h" +#include "z_zone.h" #include "lua_hook.h" #ifdef HW3SOUND @@ -55,17 +57,31 @@ void A_Fall(mobj_t *actor); void A_Look(mobj_t *actor); void A_Chase(mobj_t *actor); void A_FaceStabChase(mobj_t *actor); +void A_FaceStabRev(mobj_t *actor); +void A_FaceStabHurl(mobj_t *actor); +void A_FaceStabMiss(mobj_t *actor); +void A_StatueBurst(mobj_t *actor); void A_JetJawRoam(mobj_t *actor); void A_JetJawChomp(mobj_t *actor); void A_PointyThink(mobj_t *actor); void A_CheckBuddy(mobj_t *actor); +void A_HoodFire(mobj_t *actor); void A_HoodThink(mobj_t *actor); -void A_ArrowCheck(mobj_t *actor); +void A_HoodFall(mobj_t *actor); +void A_ArrowBonks(mobj_t *actor); void A_SnailerThink(mobj_t *actor); void A_SharpChase(mobj_t *actor); void A_SharpSpin(mobj_t *actor); +void A_SharpDecel(mobj_t *actor); +void A_CrushstaceanWalk(mobj_t *actor); +void A_CrushstaceanPunch(mobj_t *actor); +void A_CrushclawAim(mobj_t *actor); +void A_CrushclawLaunch(mobj_t *actor); void A_VultureVtol(mobj_t *actor); void A_VultureCheck(mobj_t *actor); +void A_VultureHover(mobj_t *actor); +void A_VultureBlast(mobj_t *actor); +void A_VultureFly(mobj_t *actor); void A_SkimChase(mobj_t *actor); void A_FaceTarget(mobj_t *actor); void A_FaceTracer(mobj_t *actor); @@ -86,24 +102,21 @@ void A_Scream(mobj_t *actor); void A_Pain(mobj_t *actor); void A_1upThinker(mobj_t *actor); void A_MonitorPop(mobj_t *actor); +void A_GoldMonitorPop(mobj_t *actor); +void A_GoldMonitorRestore(mobj_t *actor); +void A_GoldMonitorSparkle(mobj_t *actor); void A_Explode(mobj_t *actor); void A_BossDeath(mobj_t *actor); void A_CustomPower(mobj_t *actor); void A_GiveWeapon(mobj_t *actor); -void A_JumpShield(mobj_t *actor); -void A_RingShield(mobj_t *actor); void A_RingBox(mobj_t *actor); void A_Invincibility(mobj_t *actor); void A_SuperSneakers(mobj_t *actor); void A_AwardScore(mobj_t *actor); void A_ExtraLife(mobj_t *actor); -void A_BombShield(mobj_t *actor); -void A_WaterShield(mobj_t *actor); -void A_ForceShield(mobj_t *actor); -void A_PityShield(mobj_t *actor); +void A_GiveShield(mobj_t *actor); void A_GravityBox(mobj_t *actor); void A_ScoreRise(mobj_t *actor); -void A_ParticleSpawn(mobj_t *actor); void A_BunnyHop(mobj_t *actor); void A_BubbleSpawn(mobj_t *actor); void A_FanBubbleSpawn(mobj_t *actor); @@ -131,7 +144,6 @@ void A_DetonChase(mobj_t *actor); void A_CapeChase(mobj_t *actor); void A_RotateSpikeBall(mobj_t *actor); void A_SlingAppear(mobj_t *actor); -void A_MaceRotate(mobj_t *actor); void A_UnidusBall(mobj_t *actor); void A_RockSpawn(mobj_t *actor); void A_SetFuse(mobj_t *actor); @@ -223,7 +235,6 @@ void A_SetScale(mobj_t *actor); void A_RemoteDamage(mobj_t *actor); void A_HomingChase(mobj_t *actor); void A_TrapShot(mobj_t *actor); -//for p_enemy.c void A_Boss1Chase(mobj_t *actor); void A_Boss2Chase(mobj_t *actor); void A_Boss2Pogo(mobj_t *actor); @@ -236,6 +247,54 @@ void A_BrakFireShot(mobj_t *actor); void A_BrakLobShot(mobj_t *actor); void A_NapalmScatter(mobj_t *actor); void A_SpawnFreshCopy(mobj_t *actor); +void A_FlickySpawn(mobj_t *actor); +void A_FlickyCenter(mobj_t *actor); +void A_FlickyAim(mobj_t *actor); +void A_FlickyFly(mobj_t *actor); +void A_FlickySoar(mobj_t *actor); +void A_FlickyCoast(mobj_t *actor); +void A_FlickyHop(mobj_t *actor); +void A_FlickyFlounder(mobj_t *actor); +void A_FlickyCheck(mobj_t *actor); +void A_FlickyHeightCheck(mobj_t *actor); +void A_FlickyFlutter(mobj_t *actor); +void A_FlameParticle(mobj_t *actor); +void A_FadeOverlay(mobj_t *actor); +void A_Boss5Jump(mobj_t *actor); +void A_LightBeamReset(mobj_t *actor); +void A_MineExplode(mobj_t *actor); +void A_MineRange(mobj_t *actor); +void A_ConnectToGround(mobj_t *actor); +void A_SpawnParticleRelative(mobj_t *actor); +void A_MultiShotDist(mobj_t *actor); +void A_WhoCaresIfYourSonIsABee(mobj_t *actor); +void A_ParentTriesToSleep(mobj_t *actor); +void A_CryingToMomma(mobj_t *actor); +void A_CheckFlags2(mobj_t *actor); +void A_Boss5FindWaypoint(mobj_t *actor); +void A_DoNPCSkid(mobj_t *actor); +void A_DoNPCPain(mobj_t *actor); +void A_PrepareRepeat(mobj_t *actor); +void A_Boss5ExtraRepeat(mobj_t *actor); +void A_Boss5Calm(mobj_t *actor); +void A_Boss5CheckOnGround(mobj_t *actor); +void A_Boss5CheckFalling(mobj_t *actor); +void A_Boss5PinchShot(mobj_t *actor); +void A_Boss5MakeItRain(mobj_t *actor); +void A_LookForBetter(mobj_t *actor); +void A_Boss5BombExplode(mobj_t *actor); +void A_DustDevilThink(mobj_t *actor); +void A_TNTExplode(mobj_t *actor); +void A_DebrisRandom(mobj_t *actor); +void A_TrainCameo(mobj_t *actor); +void A_TrainCameo2(mobj_t *actor); +void A_CanarivoreGas(mobj_t *actor); +void A_KillSegments(mobj_t *actor); +void A_SnapperSpawn(mobj_t *actor); +void A_SnapperThinker(mobj_t *actor); +void A_SaloonDoorSpawn(mobj_t *actor); +void A_MinecartSparkThink(mobj_t *actor); +//for p_enemy.c // // ENEMY THINKING @@ -655,15 +714,15 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed if ((netgame || multiplayer) && player->spectator) continue; - if (player->health <= 0) - continue; // dead - if (player->pflags & PF_INVIS) continue; // ignore notarget if (!player->mo || P_MobjWasRemoved(player->mo)) continue; + if (player->mo->health <= 0) + continue; // dead + if (dist > 0 && P_AproxDistance(P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist) continue; // Too far away @@ -727,7 +786,7 @@ static boolean P_LookForShield(mobj_t *actor) player = &players[actor->lastlook]; - if (player->health <= 0 || !player->mo) + if (!player->mo || player->mo->health <= 0) continue; // dead //When in CTF, don't pull rings that you cannot pick up. @@ -735,10 +794,16 @@ static boolean P_LookForShield(mobj_t *actor) (actor->type == MT_BLUETEAMRING && player->ctfteam != 2)) continue; - if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT + 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))) { P_SetTarget(&actor->tracer, player->mo); + + if (actor->hnext) + P_SetTarget(&actor->hnext->hprev, actor->hprev); + if (actor->hprev) + P_SetTarget(&actor->hprev->hnext, actor->hnext); + return true; } } @@ -818,6 +883,60 @@ static int P_RecycleCompare(const void *p1, const void *p2) } #endif +// Handles random monitor weights via console. +static mobjtype_t P_DoRandomBoxChances(void) +{ + mobjtype_t spawnchance[256]; + INT32 numchoices = 0, i = 0; + + if (!(netgame || multiplayer)) + { + switch (P_RandomKey(10)) + { + case 0: + return MT_RING_ICON; + case 1: + return MT_SNEAKERS_ICON; + case 2: + return MT_INVULN_ICON; + case 3: + return MT_WHIRLWIND_ICON; + case 4: + return MT_ELEMENTAL_ICON; + case 5: + return MT_ATTRACT_ICON; + case 6: + return MT_FORCE_ICON; + case 7: + return MT_ARMAGEDDON_ICON; + case 8: + return MT_1UP_ICON; + case 9: + return MT_EGGMAN_ICON; + } + return MT_NULL; + } + +#define QUESTIONBOXCHANCES(type, cvar) \ +for (i = cvar.value; i; --i) spawnchance[numchoices++] = type + QUESTIONBOXCHANCES(MT_RING_ICON, cv_superring); + QUESTIONBOXCHANCES(MT_SNEAKERS_ICON, cv_supersneakers); + QUESTIONBOXCHANCES(MT_INVULN_ICON, cv_invincibility); + QUESTIONBOXCHANCES(MT_WHIRLWIND_ICON, cv_jumpshield); + QUESTIONBOXCHANCES(MT_ELEMENTAL_ICON, cv_watershield); + QUESTIONBOXCHANCES(MT_ATTRACT_ICON, cv_ringshield); + QUESTIONBOXCHANCES(MT_FORCE_ICON, cv_forceshield); + QUESTIONBOXCHANCES(MT_ARMAGEDDON_ICON, cv_bombshield); + QUESTIONBOXCHANCES(MT_1UP_ICON, cv_1up); + QUESTIONBOXCHANCES(MT_EGGMAN_ICON, cv_eggmanbox); + QUESTIONBOXCHANCES(MT_MIXUP_ICON, cv_teleporters); + QUESTIONBOXCHANCES(MT_RECYCLER_ICON, cv_recycler); +#undef QUESTIONBOXCHANCES + + if (numchoices == 0) return MT_NULL; + return spawnchance[P_RandomKey(numchoices)]; +} + // // ACTION ROUTINES // @@ -955,7 +1074,7 @@ nomissile: // Function: A_FaceStabChase // -// Description: A_Chase for CastleBot FaceStabber. +// Description: Unused variant of A_Chase for Castlebot Facestabber. // // var1 = unused // var2 = unused @@ -1043,6 +1162,269 @@ nomissile: P_NewChaseDir(actor); } +static void P_SharpDust(mobj_t *actor, mobjtype_t type, angle_t ang) +{ + mobj_t *dust; + + if (!type || !P_IsObjectOnGround(actor)) + return; + + dust = P_SpawnMobjFromMobj(actor, + -P_ReturnThrustX(actor, ang, 16<<FRACBITS), + -P_ReturnThrustY(actor, ang, 16<<FRACBITS), + 0, type); + P_SetObjectMomZ(dust, P_RandomRange(1, 4)<<FRACBITS, false); +} + +static void P_FaceStabFlume(mobj_t *actor) +{ + mobj_t *flume; + if (leveltime & 1) + return; + + flume = P_SpawnMobjFromMobj(actor, + -P_ReturnThrustX(actor, actor->angle, actor->radius), + -P_ReturnThrustY(actor, actor->angle, actor->radius), + actor->height/3, + MT_PARTICLE); + flume->destscale = actor->scale*3; + P_SetScale(flume, flume->destscale); + P_SetTarget(&flume->target, actor); + flume->sprite = SPR_JETF; + flume->frame = FF_FULLBRIGHT; + flume->tics = 2; +} + +// Function: A_FaceStabRev +// +// Description: Facestabber rev action +// +// var1 = effective duration +// var2 = effective nextstate +// +void A_FaceStabRev(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_FaceStabRev", actor)) + return; +#endif + + if (!actor->target) + { + P_SetMobjState(actor, actor->info->spawnstate); + return; + } + + actor->extravalue1 = 0; + + if (!actor->reactiontime) + { + actor->reactiontime = locvar1; + S_StartSound(actor, actor->info->activesound); + } + else + { + if ((--actor->reactiontime) == 0) + { + S_StartSound(actor, actor->info->attacksound); + P_SetMobjState(actor, locvar2); + } + else + { + P_TryMove(actor, actor->x - P_ReturnThrustX(actor, actor->angle, 2<<FRACBITS), actor->y - P_ReturnThrustY(actor, actor->angle, 2<<FRACBITS), false); + P_FaceStabFlume(actor); + } + } +} + +// Function: A_FaceStabHurl +// +// Description: Facestabber hurl action +// +// var1 = homing strength (recommended strength between 0-8) +// var2 = effective nextstate +// +void A_FaceStabHurl(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_FaceStabHurl", actor)) + return; +#endif + + if (actor->target) + { + angle_t visang = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); + // Calculate new direction. + angle_t dirang = actor->angle; + angle_t diffang = visang - dirang; + + if (locvar1) // Allow homing? + { + if (diffang > ANGLE_180) + { + angle_t workang = locvar1*(InvAngle(diffang)>>5); + diffang += InvAngle(workang); + } + else + diffang += (locvar1*(diffang>>5)); + } + diffang += ANGLE_45; + + // Check the sight cone. + if (diffang < ANGLE_90) + { + actor->angle = dirang; + if (++actor->extravalue2 < 4) + actor->extravalue2 = 4; + else if (actor->extravalue2 > 26) + actor->extravalue2 = 26; + + if (P_TryMove(actor, + actor->x + P_ReturnThrustX(actor, dirang, actor->extravalue2<<FRACBITS), + actor->y + P_ReturnThrustY(actor, dirang, actor->extravalue2<<FRACBITS), + false)) + { + // Do the spear damage. +#define NUMSTEPS 3 +#define NUMGRADS 5 +#define MAXVAL (NUMSTEPS*NUMGRADS) + SINT8 step = (++actor->extravalue1); + fixed_t basesize = FRACUNIT/MAXVAL; + mobj_t *hwork = actor; + INT32 dist = 113; + fixed_t xo = P_ReturnThrustX(actor, actor->angle, dist*basesize); + fixed_t yo = P_ReturnThrustY(actor, actor->angle, dist*basesize); + + while (step > 0) + { + if (!hwork->hnext) + P_SetTarget(&hwork->hnext, P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_FACESTABBERSPEAR)); + hwork = hwork->hnext; + hwork->angle = actor->angle + ANGLE_90; + hwork->destscale = FixedSqrt(step*basesize); + P_SetScale(hwork, hwork->destscale); + hwork->fuse = 2; + P_TeleportMove(hwork, actor->x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<<FRACBITS))); + step -= NUMGRADS; + } + + if (actor->extravalue1 >= MAXVAL) + actor->extravalue1 -= NUMGRADS; + + if ((step % 5) == 0) + P_SharpDust(actor, MT_SPINDUST, actor->angle); + + P_FaceStabFlume(actor); + return; +#undef MAXVAL +#undef NUMGRADS +#undef NUMSTEPS + } + } + } + + P_SetMobjState(actor, locvar2); + actor->reactiontime = actor->info->reactiontime; +} + +// Function: A_FaceStabMiss +// +// Description: Facestabber miss action +// +// var1 = unused +// var2 = effective nextstate +// +void A_FaceStabMiss(mobj_t *actor) +{ + //INT32 locvar1 = var1; + INT32 locvar2 = var2; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_FaceStabMiss", actor)) + return; +#endif + + if (++actor->extravalue1 >= 3) + { + actor->extravalue2 -= 2; + actor->extravalue1 = 0; + S_StartSound(actor, sfx_s3k47); + P_SharpDust(actor, MT_SPINDUST, actor->angle); + } + + if (actor->extravalue2 <= 0 || !P_TryMove(actor, + actor->x + P_ReturnThrustX(actor, actor->angle, actor->extravalue2<<FRACBITS), + actor->y + P_ReturnThrustY(actor, actor->angle, actor->extravalue2<<FRACBITS), + false)) + { + actor->extravalue2 = 0; + P_SetMobjState(actor, locvar2); + } +} + +// Function: A_StatueBurst +// +// Description: For suspicious statues only... +// +// var1 = object to create +// var2 = effective nextstate for created object +// +void A_StatueBurst(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + mobjtype_t chunktype = (mobjtype_t)actor->info->raisestate; + mobj_t *new; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_StatueBurst", actor)) + return; +#endif + + if (!locvar1 || !(new = P_SpawnMobjFromMobj(actor, 0, 0, 0, locvar1))) + return; + + new->angle = actor->angle; + new->target = actor->target; + if (locvar2) + P_SetMobjState(new, (statenum_t)locvar2); + S_StartSound(new, new->info->attacksound); + S_StopSound(actor); + S_StartSound(actor, sfx_s3k96); + + { + fixed_t a, b; + fixed_t c = (actor->height>>2) - FixedMul(actor->scale, mobjinfo[chunktype].height>>1); + fixed_t v = 4<<FRACBITS; + const fixed_t r = (actor->radius>>1); + mobj_t *spawned; + UINT8 i; + for (i = 0; i < 8; i++) + { + a = ((i & 1) ? r : (-r)); + b = ((i & 2) ? r : (-r)); + if (i == 4) + { + c += (actor->height>>1); + v = 8<<FRACBITS; + } + + spawned = P_SpawnMobjFromMobj(actor, a, b, c, chunktype); + + P_InstaThrust(spawned, R_PointToAngle2(0, 0, a, b), 8<<FRACBITS); + P_SetObjectMomZ(spawned, v, false); + + spawned->fuse = 3*TICRATE; + } + } +} + // Function: A_JetJawRoam // // Description: Roaming routine for JetJaw @@ -1239,6 +1621,62 @@ void A_CheckBuddy(mobj_t *actor) P_RemoveMobj(actor); } +// Helper function for the Robo Hood. +// Don't ask me how it works. Nev3r made it with dark majyks. +static void P_ParabolicMove(mobj_t *actor, fixed_t x, fixed_t y, fixed_t z, fixed_t speed) +{ + fixed_t dh; + + x -= actor->x; + y -= actor->y; + z -= actor->z; + + dh = P_AproxDistance(x, y); + + actor->momx = FixedMul(FixedDiv(x, dh), speed); + actor->momy = FixedMul(FixedDiv(y, dh), speed); + + if (!gravity) + return; + + dh = FixedDiv(FixedMul(dh, gravity), speed); + actor->momz = (dh>>1) + FixedDiv(z, dh<<1); +} + +// Function: A_HoodFire +// +// Description: Firing Robo-Hood +// +// var1 = object type to fire +// var2 = unused +// +void A_HoodFire(mobj_t *actor) +{ + mobj_t *arrow; + INT32 locvar1 = var1; + //INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_HoodFire", actor)) + return; +#endif + + // Check target first. + if (!actor->target) + { + actor->reactiontime = actor->info->reactiontime; + P_SetMobjState(actor, actor->info->spawnstate); + return; + } + + A_FaceTarget(actor); + + if (!(arrow = P_SpawnMissile(actor, actor->target, (mobjtype_t)locvar1))) + return; + + // Set a parabolic trajectory for the arrow. + P_ParabolicMove(arrow, actor->target->x, actor->target->y, actor->target->z, arrow->info->speed); +} + // Function: A_HoodThink // // Description: Thinker for Robo-Hood @@ -1248,97 +1686,112 @@ void A_CheckBuddy(mobj_t *actor) // void A_HoodThink(mobj_t *actor) { + fixed_t dx, dy, dz, dm; + boolean checksight; #ifdef HAVE_BLUA if (LUA_CallAction("A_HoodThink", actor)) return; #endif - // Currently in the air... - if (!(actor->eflags & MFE_VERTICALFLIP) && actor->z > actor->floorz) + + // Check target first. + if (!actor->target) { - if (actor->momz > 0) - P_SetMobjStateNF(actor, actor->info->xdeathstate); // Rising - else - P_SetMobjStateNF(actor, actor->info->raisestate); // Falling + actor->reactiontime = actor->info->reactiontime; + P_SetMobjState(actor, actor->info->spawnstate); + return; + } + dx = (actor->target->x - actor->x), dy = (actor->target->y - actor->y), dz = (actor->target->z - actor->z); + dm = P_AproxDistance(dx, dy); + // Target dangerously close to robohood, retreat then. + if ((dm < 256<<FRACBITS) && (abs(dz) < 128<<FRACBITS)) + { + P_SetMobjState(actor, actor->info->raisestate); return; } - else if ((actor->eflags & MFE_VERTICALFLIP) && actor->z + actor->height < actor->ceilingz) + + // If target on sight, look at it. + if ((checksight = P_CheckSight(actor, actor->target))) { - if (actor->momz < 0) - P_SetMobjStateNF(actor, actor->info->xdeathstate); // Rising + angle_t dang = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); + if (actor->angle >= ANGLE_180) + { + actor->angle = InvAngle(actor->angle)>>1; + actor->angle = InvAngle(actor->angle); + } else - P_SetMobjStateNF(actor, actor->info->raisestate); // Falling + actor->angle >>= 1; - return; - } + if (dang >= ANGLE_180) + { + dang = InvAngle(dang)>>1; + dang = InvAngle(dang); + } + else + dang >>= 1; - if (actor->state == &states[actor->info->xdeathstate] - || actor->state == &states[actor->info->raisestate]) - P_SetMobjStateNF(actor, actor->info->seestate); + actor->angle += dang; + } - if (!actor->target) + // Check whether to do anything. + if ((--actor->reactiontime) <= 0) { - P_SetMobjState(actor, actor->info->spawnstate); - return; - } + actor->reactiontime = actor->info->reactiontime; - A_FaceTarget(actor); // Aiming... aiming... + // If way too far, don't shoot. + if ((dm < (3072<<FRACBITS)) && checksight) + { + P_SetMobjState(actor, actor->info->missilestate); + return; + } + } +} - if (--actor->reactiontime > 0) +// Function: A_HoodFall +// +// Description: Falling Robo-Hood +// +// var1 = unused +// var2 = unused +// +void A_HoodFall(mobj_t *actor) +{ +#ifdef HAVE_BLUA + if (LUA_CallAction("A_HoodFall", actor)) return; +#endif - // Shoot, if not too close (cheap shots are lame) - if ((P_AproxDistance(actor->x-actor->target->x, actor->y-actor->target->y) > FixedMul(192*FRACUNIT, actor->scale)) - || (actor->spawnpoint && (actor->spawnpoint->options & MTF_AMBUSH))) // If you can't jump, might as well shoot regardless of distance! - P_SetMobjState(actor, actor->info->missilestate); - else if (!(actor->spawnpoint && (actor->spawnpoint->options & MTF_AMBUSH)))// But we WILL jump! - P_SetMobjState(actor, actor->info->painstate); + if (!P_IsObjectOnGround(actor)) + return; + actor->momx = actor->momy = 0; actor->reactiontime = actor->info->reactiontime; + P_SetMobjState(actor, actor->info->seestate); } -// Function: A_ArrowCheck +// Function: A_ArrowBonks // -// Description: Checks arrow direction and adjusts sprite accordingly +// Description: Arrow momentum setting on collision // // var1 = unused // var2 = unused // -void A_ArrowCheck(mobj_t *actor) +void A_ArrowBonks(mobj_t *actor) { - fixed_t x,y,z; - angle_t angle; - fixed_t dist; - #ifdef HAVE_BLUA - if (LUA_CallAction("A_ArrowCheck", actor)) + if (LUA_CallAction("A_ArrowBonks", actor)) return; #endif - // Movement vector - x = actor->momx; - y = actor->momy; - z = actor->momz; - - // Calculate the angle of movement. - /* - Z - / | - / | - / | - 0------dist(X,Y) - */ - - dist = P_AproxDistance(x, y); + if (((actor->eflags & MFE_VERTICALFLIP) && actor->z + actor->height >= actor->ceilingz) + || (!(actor->eflags & MFE_VERTICALFLIP) && actor->z <= actor->floorz)) + actor->angle += ANGLE_180; - angle = R_PointToAngle2(0, 0, dist, z); + P_SetObjectMomZ(actor, 8*actor->scale, false); + P_InstaThrust(actor, actor->angle, -6*actor->scale); - if (angle > ANG20 && angle <= ANGLE_180) - P_SetMobjStateNF(actor, actor->info->raisestate); - else if (angle < ANG340 && angle > ANGLE_180) - P_SetMobjStateNF(actor, actor->info->xdeathstate); - else - P_SetMobjStateNF(actor, actor->info->spawnstate); + actor->flags = (actor->flags|MF_NOCLIPHEIGHT) & ~MF_NOGRAVITY; + actor->z += P_MobjFlip(actor); } // Function: A_SnailerThink @@ -1418,7 +1871,7 @@ void A_SnailerThink(mobj_t *actor) // Function: A_SharpChase // -// Description: Thinker/Chase routine for Sharps +// Description: Thinker/Chase routine for Spincushions // // var1 = unused // var2 = unused @@ -1430,12 +1883,6 @@ void A_SharpChase(mobj_t *actor) return; #endif - if (!actor->health) - { - P_SetMobjState(actor, actor->info->deathstate); - return; - } - if (actor->reactiontime) { INT32 delta; @@ -1478,50 +1925,335 @@ void A_SharpChase(mobj_t *actor) // Function: A_SharpSpin // -// Description: Spin chase routine for Sharps +// Description: Spin chase routine for Spincushions // -// var1 = unused -// var2 = unused +// var1 = object # to spawn as dust (if not provided not done) +// var2 = if nonzero, do the old-style spinning using this as the angle difference // void A_SharpSpin(mobj_t *actor) { + INT32 locvar1 = var1; + INT32 locvar2 = var2; + angle_t oldang = actor->angle; + #ifdef HAVE_BLUA if (LUA_CallAction("A_SharpSpin", actor)) return; #endif - if (!actor->health) - { - P_SetMobjState(actor, actor->info->deathstate); - return; - } - if (actor->threshold && actor->target) { - actor->angle += ANGLE_22h; - P_Thrust(actor, R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y), FixedMul(actor->info->speed*FRACUNIT, actor->scale)); + angle_t ang = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); + P_Thrust(actor, ang, actor->info->speed*actor->scale); + if (locvar2) + actor->angle += locvar2; // ANGLE_22h; + else + actor->angle = ang; actor->threshold--; + if (leveltime & 1) + S_StartSound(actor, actor->info->painsound); } else { actor->reactiontime = actor->info->reactiontime; - P_SetMobjState(actor, actor->info->spawnstate); - - var1 = 1; - A_Look(actor); - if (actor->target) - actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); + P_SetMobjState(actor, actor->info->meleestate); } + + P_SharpDust(actor, locvar1, oldang); } -// Function: A_VultureVtol +// Function: A_SharpDecel // -// Description: Vulture rising up to match target's height +// Description: Slow down the Spincushion // // var1 = unused // var2 = unused // -void A_VultureVtol(mobj_t *actor) +void A_SharpDecel(mobj_t *actor) +{ +#ifdef HAVE_BLUA + if (LUA_CallAction("A_SharpDecel", actor)) + return; +#endif + + if (actor->momx > 2 || actor->momy > 2) + { + actor->momx >>= 1; + actor->momy >>= 1; + } + else + P_SetMobjState(actor, actor->info->xdeathstate); +} + +// Function: A_CrushstaceanWalk +// +// Description: Crushstacean movement +// +// var1 = speed (actor info's speed if 0) +// var2 = state to switch to when blocked (spawnstate if 0) +// +void A_CrushstaceanWalk(mobj_t *actor) +{ + INT32 locvar1 = (var1 ? var1 : (INT32)actor->info->speed); + INT32 locvar2 = (var2 ? var2 : (INT32)actor->info->spawnstate); + angle_t ang = actor->angle + ((actor->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270); +#ifdef HAVE_BLUA + if (LUA_CallAction("A_CrushstaceanWalk", actor)) + return; +#endif + + actor->reactiontime--; + + if (!P_TryMove(actor, + actor->x + P_ReturnThrustX(actor, ang, locvar1*actor->scale), + actor->y + P_ReturnThrustY(actor, ang, locvar1*actor->scale), + false) + || (actor->reactiontime-- <= 0)) + { + actor->flags2 ^= MF2_AMBUSH; + P_SetMobjState(actor, locvar2); + actor->reactiontime = actor->info->reactiontime; + } +} + +// Function: A_CrushstaceanPunch +// +// Description: Crushstacean attack +// +// var1 = unused +// var2 = state to go to if unsuccessful (spawnstate if 0) +// +void A_CrushstaceanPunch(mobj_t *actor) +{ + //INT32 locvar1 = var1; + INT32 locvar2 = (var2 ? var2 : (INT32)actor->info->spawnstate); +#ifdef HAVE_BLUA + if (LUA_CallAction("A_CrushstaceanPunch", actor)) + return; +#endif + + if (!actor->tracer) + return; + + if (!actor->target) + { + P_SetMobjState(actor, locvar2); + return; + } + + actor->tracer->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); + P_SetMobjState(actor->tracer, actor->tracer->info->missilestate); + actor->tracer->extravalue1 = actor->tracer->extravalue2 = 0; + S_StartSound(actor, actor->info->attacksound); +} + +// Function: A_CrushclawAim +// +// Description: Crushstacean claw aiming +// +// var1 = sideways offset +// var2 = vertical offset +// +void A_CrushclawAim(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + mobj_t *crab = actor->tracer; + angle_t ang; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_CrushclawAim", actor)) + return; +#endif + + if (!crab) + { + P_RemoveMobj(actor); + return; // there is only one step and it is crab + } + + if (crab->target || P_LookForPlayers(crab, true, false, 600*crab->scale)) + ang = R_PointToAngle2(crab->x, crab->y, crab->target->x, crab->target->y); + else + ang = crab->angle + ((crab->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270); + ang -= actor->angle; + +#define anglimit ANGLE_22h +#define angfactor 5 + if (ang < ANGLE_180) + { + if (ang > anglimit) + ang = anglimit; + ang /= angfactor; + } + else + { + ang = InvAngle(ang); + if (ang > anglimit) + ang = anglimit; + ang = InvAngle(ang/angfactor); + } + actor->angle += ang; +#undef anglimit +#undef angfactor + + P_TeleportMove(actor, + crab->x + P_ReturnThrustX(actor, actor->angle, locvar1*crab->scale), + crab->y + P_ReturnThrustY(actor, actor->angle, locvar1*crab->scale), + crab->z + locvar2*crab->scale); + + if (!crab->target || !crab->info->missilestate || (statenum_t)(crab->state-states) == crab->info->missilestate) + return; + + if (((ang + ANG1) < ANG2) || P_AproxDistance(crab->x - crab->target->x, crab->y - crab->target->y) < 333*crab->scale) + P_SetMobjState(crab, crab->info->missilestate); +} + +// Function: A_CrushclawLaunch +// +// Description: Crushstacean claw launching +// +// var1: +// 0 - forwards +// anything else - backwards +// var2 = state to change to when done +// +void A_CrushclawLaunch(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + mobj_t *crab = actor->tracer; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_CrushclawLaunch", actor)) + return; +#endif + + if (!crab) + { + mobj_t *chainnext; + while (actor) + { + chainnext = actor->target; + P_RemoveMobj(actor); + actor = chainnext; + } + return; // there is only one step and it is crab + } + + if (!actor->extravalue1) + { + S_StartSound(actor, actor->info->activesound); + actor->extravalue1 = ((locvar1) ? -1 : 32); + } + else if (actor->extravalue1 != 1) + actor->extravalue1 -= 1; + +#define CSEGS 5 + if (!actor->target) + { + mobj_t *prevchain = actor; + UINT8 i = 0; + for (i = 0; (i < CSEGS); i++) + { + mobj_t *newchain = P_SpawnMobjFromMobj(actor, 0, 0, 0, actor->info->raisestate); + prevchain->target = newchain; + prevchain = newchain; + } + actor->target->angle = R_PointToAngle2(actor->target->x, actor->target->y, crab->target->x, crab->target->y); + } + + if ((!locvar1) && crab->target) + { +#define anglimit ANGLE_22h +#define angfactor 7 + angle_t ang = R_PointToAngle2(actor->target->x, actor->target->y, crab->target->x, crab->target->y) - actor->target->angle; + if (ang < ANGLE_180) + { + if (ang > anglimit) + ang = anglimit; + ang /= angfactor; + } + else + { + ang = InvAngle(ang); + if (ang > anglimit) + ang = anglimit; + ang /= angfactor; + ang = InvAngle(ang); + } + actor->target->angle += ang; + actor->angle = actor->target->angle; + } + + actor->extravalue2 += actor->extravalue1; + + if (!P_TryMove(actor, + actor->target->x + P_ReturnThrustX(actor, actor->target->angle, actor->extravalue2*actor->scale), + actor->target->y + P_ReturnThrustY(actor, actor->target->angle, actor->extravalue2*actor->scale), + true) + && !locvar1) + { + actor->extravalue1 = 0; + actor->extravalue2 = FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y)>>FRACBITS; + P_SetMobjState(actor, locvar2); + S_StopSound(actor); + S_StartSound(actor, sfx_s3k49); + } + else + { + actor->z = actor->target->z; + if ((!locvar1 && (actor->extravalue2 > 256)) || (locvar1 && (actor->extravalue2 < 16))) + { + if (locvar1) // In case of retracting, resume crab and remove the chain. + { + mobj_t *chain = actor->target, *chainnext; + while (chain) + { + chainnext = chain->target; + P_RemoveMobj(chain); + chain = chainnext; + } + actor->extravalue2 = 0; + actor->angle = R_PointToAngle2(crab->x, crab->y, actor->x, actor->y); + P_SetTarget(&actor->target, NULL); + P_SetTarget(&crab->target, NULL); + P_SetMobjState(crab, crab->state->nextstate); + } + actor->extravalue1 = 0; + P_SetMobjState(actor, locvar2); + S_StopSound(actor); + if (!locvar1) + S_StartSound(actor, sfx_s3k64); + } + } + + if (!actor->target) + return; + + { + mobj_t *chain = actor->target->target; + fixed_t dx = (actor->x - actor->target->x)/CSEGS, dy = (actor->y - actor->target->y)/CSEGS, dz = (actor->z - actor->target->z)/CSEGS; + fixed_t idx = dx, idy = dy, idz = dz; + while (chain) + { + P_TeleportMove(chain, actor->target->x + idx, actor->target->y + idy, actor->target->z + idz); + chain->watertop = chain->z; + idx += dx; + idy += dy; + idz += dz; + chain = chain->target; + } + } +#undef CSEGS +} + +// Function: A_VultureVtol +// +// Description: Vulture rising up to match target's height +// +// var1 = unused +// var2 = unused +// +void A_VultureVtol(mobj_t *actor) { #ifdef HAVE_BLUA if (LUA_CallAction("A_VultureVtol", actor)) @@ -1577,6 +2309,222 @@ void A_VultureCheck(mobj_t *actor) } } +static void P_VultureHoverParticle(mobj_t *actor) +{ + fixed_t fdist = actor->z - P_FloorzAtPos(actor->x, actor->y, actor->z, actor->height); + + if (fdist < 128*FRACUNIT) + { + mobj_t *dust; + UINT8 i; + angle_t angle = (leveltime % 2)*ANGLE_45/2; + + for (i = 0; i <= 7; i++) + { + angle_t fa = (angle >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t px = actor->x + FixedMul(fdist + 64*FRACUNIT, FINECOSINE(fa)); + fixed_t py = actor->y + FixedMul(fdist + 64*FRACUNIT, FINESINE(fa)); + fixed_t pz = P_FloorzAtPos(px, py, actor->z, actor->height); + + dust = P_SpawnMobj(px, py, pz, MT_ARIDDUST); + P_SetMobjState(dust, (statenum_t)(dust->state - states + P_RandomRange(0, 2))); + P_Thrust(dust, angle, FixedDiv(12*FRACUNIT, max(FRACUNIT, fdist/2))); + dust->momx += actor->momx; + dust->momy += actor->momy; + angle += ANGLE_45; + } + } +} + +// Function: A_VultureHover +// +// Description: Vulture hovering and checking whether to attack. +// +// var1 = unused +// var2 = unused +// +void A_VultureHover(mobj_t *actor) +{ + fixed_t targetz; + fixed_t distdif; + fixed_t memz = actor->z; + INT8 i; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_VultureHover", actor)) + return; +#endif + + if (!actor->target || P_MobjWasRemoved(actor->target)) + { + P_SetMobjState(actor, actor->info->spawnstate); + return; + } + + actor->flags |= MF_NOGRAVITY; + + actor->momx -= actor->momx/24; + actor->momy -= actor->momy/24; + + P_VultureHoverParticle(actor); + + A_FaceTarget(actor); + targetz = actor->target->z + actor->target->height / 2; + for (i = -1; i <= 1; i++) + { + actor->z = targetz - i * 128 * FRACUNIT; + if (P_CheckSight(actor, actor->target)) + { + targetz -= i * 128 * FRACUNIT; + break; + } + } + actor->z = memz; + + distdif = (actor->z + actor->height/2) - targetz; + + if (abs(actor->momz*16) > abs(distdif)) + actor->momz -= actor->momz/16; + else if (distdif < 0) + actor->momz = min(actor->momz+FRACUNIT/8, actor->info->speed*FRACUNIT); + else + actor->momz = max(actor->momz-FRACUNIT/8, -actor->info->speed*FRACUNIT); + + if (abs(distdif) < 128*FRACUNIT && abs(actor->momz) < FRACUNIT && P_CheckSight(actor, actor->target)) + { + P_SetMobjState(actor, actor->info->missilestate); + actor->momx = 0; + actor->momy = 0; + actor->momz = 0; + actor->extravalue1 = 0; + } +} + +// Function: A_VultureBlast +// +// Description: Vulture spawning a dust cloud. +// +// var1 = unused +// var2 = unused +// +void A_VultureBlast(mobj_t *actor) +{ + mobj_t *dust; + UINT8 i; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_VultureBlast", actor)) + return; +#endif + + S_StartSound(actor, actor->info->attacksound); + + for (i = 0; i <= 7; i++) + { + angle_t fa = ((i*(angle_t)ANGLE_45) >> ANGLETOFINESHIFT) & FINEMASK; + angle_t faa = (actor->angle >> ANGLETOFINESHIFT) & FINEMASK; + dust = P_SpawnMobj(actor->x + 48*FixedMul(FINECOSINE(fa), -FINESINE(faa)), actor->y + 48*FixedMul(FINECOSINE(fa), FINECOSINE(faa)), actor->z + actor->height/2 + 48*FINESINE(fa), MT_PARTICLE); + + P_SetScale(dust, 4*FRACUNIT); + dust->destscale = FRACUNIT; + dust->scalespeed = 4*FRACUNIT/TICRATE; + dust->fuse = TICRATE; + dust->momx = FixedMul(FINECOSINE(fa), -FINESINE(faa))*3; + dust->momy = FixedMul(FINECOSINE(fa), FINECOSINE(faa))*3; + dust->momz = FINESINE(fa)*6; + } +} + +// Function: A_VultureFly +// +// Description: Vulture charging towards target. +// +// var1 = unused +// var2 = unused +// +void A_VultureFly(mobj_t *actor) +{ + fixed_t speedmax = 18*FRACUNIT; + angle_t angledif = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) - actor->angle; + fixed_t dx = actor->target->x - actor->x; + fixed_t dy = actor->target->y - actor->y; + fixed_t dz = actor->target->z - actor->z; + fixed_t dxy = FixedHypot(dx, dy); + fixed_t dm; + mobj_t *dust; + fixed_t momm; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_VultureFly", actor)) + return; +#endif + + if (leveltime % 4 == 0) + S_StartSound(actor, actor->info->activesound); + + if (angledif > ANGLE_180) + angledif = InvAngle(angledif); + + // Tweak the target height according to the position. + if (angledif < ANGLE_45) // Centered? + { + actor->reactiontime = actor->info->reactiontime; + if (dxy > 768*FRACUNIT) + dz = max(P_FloorzAtPos(actor->target->x, actor->target->y, actor->target->z, 0) - actor->z + min(dxy/8, 128*FRACUNIT), dz); + } + else + { + actor->reactiontime--; + + if (angledif < ANGLE_90) + dz = max(P_FloorzAtPos(actor->target->x, actor->target->y, actor->target->z, 0) - actor->z + min(dxy/2, 192*FRACUNIT), dz); + else + dz = max(P_FloorzAtPos(actor->target->x, actor->target->y, actor->target->z, 0) - actor->z + 232*FRACUNIT, dz); + } + + dm = FixedHypot(dz, dxy); + + P_VultureHoverParticle(actor); + + dust = P_SpawnMobj(actor->x + P_RandomFixed() - FRACUNIT/2, actor->y + P_RandomFixed() - FRACUNIT/2, actor->z + actor->height/2 + P_RandomFixed() - FRACUNIT/2, MT_PARTICLE); + P_SetScale(dust, 2*FRACUNIT); + dust->destscale = FRACUNIT/3; + dust->scalespeed = FRACUNIT/40; + dust->fuse = TICRATE*2; + + actor->momx += FixedDiv(dx, dm)*2; + actor->momy += FixedDiv(dy, dm)*2; + actor->momz += FixedDiv(dz, dm)*2; + + momm = FixedHypot(actor->momz, FixedHypot(actor->momx, actor->momy)); + + if (momm > speedmax/2 && actor->reactiontime == 0) + { + P_SetMobjState(actor, actor->info->seestate); + return; + } + + //Hits a wall hard? + if (actor->extravalue1 - momm > 15*FRACUNIT) + { + actor->flags &= ~MF_NOGRAVITY; + P_SetMobjState(actor, actor->info->painstate); + S_StopSound(actor); + S_StartSound(actor, actor->info->painsound); + return; + } + actor->extravalue1 = momm; + + if (momm > speedmax) + { + actor->momx = FixedMul(FixedDiv(actor->momx, momm), speedmax); + actor->momy = FixedMul(FixedDiv(actor->momy, momm), speedmax); + actor->momz = FixedMul(FixedDiv(actor->momz, momm), speedmax); + } + + actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy); +} + // Function: A_SkimChase // // Description: Thinker/Chase routine for Skims @@ -2092,13 +3040,15 @@ void A_Boss1Laser(mobj_t *actor) if (!(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH)) { point = P_SpawnMobj(x + P_ReturnThrustX(actor, actor->angle, actor->radius), y + P_ReturnThrustY(actor, actor->angle, actor->radius), actor->z - actor->height / 2, MT_EGGMOBILE_TARGET); + point->angle = actor->angle; point->fuse = actor->tics+1; P_SetTarget(&point->target, actor->target); P_SetTarget(&actor->target, point); } } + /* -- the following was relevant when the MT_EGGMOBILE_TARGET was allowed to move left and right from its path else if (actor->target && !(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH)) - actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y); + actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y);*/ if (actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH) angle = FixedAngle(FixedDiv(actor->tics*160*FRACUNIT, actor->state->tics*FRACUNIT) + 10*FRACUNIT); @@ -2148,11 +3098,16 @@ void A_Boss1Laser(mobj_t *actor) // var1: // 0 - accelerative focus with friction // 1 - steady focus with fixed movement speed -// var2 = unused +// anything else - don't move +// var2: +// 0 - don't trace target, just move forwards +// & 1 - change horizontal angle +// & 2 - change vertical angle // void A_FocusTarget(mobj_t *actor) { INT32 locvar1 = var1; + INT32 locvar2 = var2; #ifdef HAVE_BLUA if (LUA_CallAction("A_FocusTarget", actor)) return; @@ -2161,9 +3116,9 @@ void A_FocusTarget(mobj_t *actor) if (actor->target) { fixed_t speed = FixedMul(actor->info->speed, actor->scale); - fixed_t dist = R_PointToDist2(actor->x, actor->y, actor->target->x, actor->target->y); - angle_t vangle = R_PointToAngle2(actor->z , 0, actor->target->z + (actor->target->height>>1), dist); - angle_t hangle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); + fixed_t dist = (locvar2 ? R_PointToDist2(actor->x, actor->y, actor->target->x, actor->target->y) : speed+1); + angle_t hangle = ((locvar2 & 1) ? R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) : actor->angle); + angle_t vangle = ((locvar2 & 2) ? R_PointToAngle2(actor->z , 0, actor->target->z + (actor->target->height>>1), dist) : ANGLE_90); switch(locvar1) { case 0: @@ -2508,9 +3463,8 @@ void A_1upThinker(mobj_t *actor) } } - if (closestplayer == -1 || skins[players[closestplayer].skin].spritedef.numframes <= states[S_PLAY_BOX1].frame) + if (closestplayer == -1 || skins[players[closestplayer].skin].sprites[SPR2_LIFE].numframes == 0) { // Closest player not found (no players in game?? may be empty dedicated server!), or does not have correct sprite. - actor->frame = 0; if (actor->tracer) { P_RemoveMobj(actor->tracer); actor->tracer = NULL; @@ -2518,11 +3472,20 @@ void A_1upThinker(mobj_t *actor) return; } + // We're using the overlay, so use the overlay 1up box (no text) + actor->sprite = SPR_TV1P; + if (!actor->tracer) { P_SetTarget(&actor->tracer, P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY)); P_SetTarget(&actor->tracer->target, actor); + actor->tracer->skin = &skins[players[closestplayer].skin]; // required here to prevent spr2 default showing stand for a single frame P_SetMobjState(actor->tracer, actor->info->seestate); + + // The overlay is going to be one tic early turning off and on + // because it's going to get its thinker run the frame we spawned it. + // So make it take one tic longer if it just spawned. + ++actor->tracer->tics; } actor->tracer->color = players[closestplayer].mo->color; @@ -2538,155 +3501,225 @@ void A_1upThinker(mobj_t *actor) // void A_MonitorPop(mobj_t *actor) { - mobj_t *remains; - mobjtype_t explode; mobjtype_t item = 0; - mobjtype_t newbox; + mobj_t *newmobj; #ifdef HAVE_BLUA if (LUA_CallAction("A_MonitorPop", actor)) return; #endif - // de-solidify + // Spawn the "pop" explosion. + if (actor->info->deathsound) + S_StartSound(actor, actor->info->deathsound); + P_SpawnMobjFromMobj(actor, 0, 0, actor->height/4, MT_EXPLODE); + + // We're dead now. De-solidify. actor->health = 0; P_UnsetThingPosition(actor); actor->flags &= ~MF_SOLID; actor->flags |= MF_NOCLIP; P_SetThingPosition(actor); - // Monitor explosion - explode = mobjinfo[actor->info->speed].mass; - remains = P_SpawnMobj(actor->x, actor->y, - ((actor->eflags & MFE_VERTICALFLIP) ? (actor->z + 3*(actor->height/4) - FixedMul(mobjinfo[explode].height, actor->scale)) : (actor->z + actor->height/4)), explode); - if (actor->eflags & MFE_VERTICALFLIP) + if (actor->info->damage == MT_UNKNOWN) { - remains->eflags |= MFE_VERTICALFLIP; - remains->flags2 |= MF2_OBJECTFLIP; + // MT_UNKNOWN is random. Because it's unknown to us... get it? + item = P_DoRandomBoxChances(); + + if (item == MT_NULL) + { + CONS_Alert(CONS_WARNING, M_GetText("All monitors turned off.\n")); + return; + } } - remains->destscale = actor->destscale; - P_SetScale(remains, actor->scale); + else + item = actor->info->damage; - remains = P_SpawnMobj(actor->x, actor->y, - ((actor->eflags & MFE_VERTICALFLIP) ? (actor->z + actor->height - FixedMul(mobjinfo[actor->info->speed].height, actor->scale)) : actor->z), - actor->info->speed); - remains->type = actor->type; // Transfer type information - P_UnsetThingPosition(remains); - if (sector_list) + if (item == 0) { - P_DelSeclist(sector_list); - sector_list = NULL; + CONS_Debug(DBG_GAMELOGIC, "Powerup item not defined in 'damage' field for A_MonitorPop\n"); + return; } - P_SetThingPosition(remains); - remains->destscale = actor->destscale; - P_SetScale(remains, actor->scale); - remains->flags = actor->flags; // Transfer flags - remains->flags2 = actor->flags2; // Transfer flags2 - remains->fuse = actor->fuse; // Transfer respawn timer - remains->threshold = 68; - remains->skin = NULL; - - P_SetTarget(&tmthing, remains); - if (actor->info->deathsound) - S_StartSound(remains, actor->info->deathsound); + newmobj = P_SpawnMobjFromMobj(actor, 0, 0, 13*FRACUNIT, item); + P_SetTarget(&newmobj->target, actor->target); // Transfer target - switch (actor->type) + if (item == MT_1UP_ICON) { - case MT_QUESTIONBOX: // Random! - { - mobjtype_t spawnchance[256]; - INT32 numchoices = 0, i = 0; + if (actor->tracer) // Remove the old lives icon. + P_RemoveMobj(actor->tracer); -#define QUESTIONBOXCHANCES(type, cvar) \ -for (i = cvar.value; i; --i) spawnchance[numchoices++] = type + if (!newmobj->target + || !newmobj->target->player + || !newmobj->target->skin + || ((skin_t *)newmobj->target->skin)->sprites[SPR2_LIFE].numframes == 0) + {} // No lives icon for this player, use the default. + else + { // Spawn the lives icon. + mobj_t *livesico = P_SpawnMobjFromMobj(newmobj, 0, 0, 0, MT_OVERLAY); + P_SetTarget(&livesico->target, newmobj); + P_SetTarget(&newmobj->tracer, livesico); - QUESTIONBOXCHANCES(MT_SUPERRINGBOX, cv_superring); - QUESTIONBOXCHANCES(MT_SNEAKERTV, cv_supersneakers); - QUESTIONBOXCHANCES(MT_INV, cv_invincibility); - QUESTIONBOXCHANCES(MT_WHITETV, cv_jumpshield); - QUESTIONBOXCHANCES(MT_GREENTV, cv_watershield); - QUESTIONBOXCHANCES(MT_YELLOWTV, cv_ringshield); - QUESTIONBOXCHANCES(MT_BLUETV, cv_forceshield); - QUESTIONBOXCHANCES(MT_BLACKTV, cv_bombshield); - QUESTIONBOXCHANCES(MT_PRUP, cv_1up); - QUESTIONBOXCHANCES(MT_EGGMANBOX, cv_eggmanbox); - QUESTIONBOXCHANCES(MT_MIXUPBOX, cv_teleporters); - QUESTIONBOXCHANCES(MT_RECYCLETV, cv_recycler); + livesico->color = newmobj->target->player->mo->color; + livesico->skin = &skins[newmobj->target->player->skin]; + P_SetMobjState(livesico, newmobj->info->seestate); -#undef QUESTIONBOXCHANCES + // We're using the overlay, so use the overlay 1up sprite (no text) + newmobj->sprite = SPR_TV1P; + } + } - if (numchoices == 0) - { - CONS_Alert(CONS_WARNING, M_GetText("All monitors turned off.\n")); - return; - } + // Run a linedef executor immediately upon popping + // You may want to delay your effects by 18 tics to sync with the reward giving + if (actor->spawnpoint && actor->lastlook) + P_LinedefExecute(actor->lastlook, actor->target, NULL); +} + +// Function: A_GoldMonitorPop +// +// Description: Used by repeating monitors when they turn off. They don't really pop, but, you know... +// +// var1 = unused +// var2 = unused +// +void A_GoldMonitorPop(mobj_t *actor) +{ + mobjtype_t item = 0; + mobj_t *newmobj; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_GoldMonitorPop", actor)) + return; +#endif - newbox = spawnchance[P_RandomKey(numchoices)]; - item = mobjinfo[newbox].damage; + // Don't spawn the "pop" explosion, because the monitor isn't broken. + if (actor->info->deathsound) + S_StartSound(actor, actor->info->deathsound); + //P_SpawnMobjFromMobj(actor, 0, 0, actor.height/4, MT_EXPLODE); - remains->flags &= ~MF_AMBUSH; - break; - } - default: - item = actor->info->damage; - break; - } + // Remove our flags for a bit. + // Players can now stand on top of us. + P_UnsetThingPosition(actor); + actor->flags &= ~(MF_MONITOR|MF_SHOOTABLE); + P_SetThingPosition(actor); + + // Don't count this box in statistics. Sorry. + if (actor->target && actor->target->player) + --actor->target->player->numboxes; + actor->fuse = 0; // Don't let the monitor code screw us up. - if (item != 0) + if (actor->info->damage == MT_UNKNOWN) { - mobj_t *newmobj; + // MT_UNKNOWN is random. Because it's unknown to us... get it? + item = P_DoRandomBoxChances(); - if (actor->eflags & MFE_VERTICALFLIP) + if (item == MT_NULL) { - newmobj = P_SpawnMobj(actor->x, actor->y, actor->z + actor->height - FixedMul(13*FRACUNIT + mobjinfo[item].height, actor->scale), item); - newmobj->eflags |= MFE_VERTICALFLIP; + CONS_Alert(CONS_WARNING, M_GetText("All monitors turned off.\n")); + return; } + } + else + item = actor->info->damage; + + if (item == 0) + { + CONS_Debug(DBG_GAMELOGIC, "Powerup item not defined in 'damage' field for A_GoldMonitorPop\n"); + return; + } + + // Note: the icon spawns 1 fracunit higher + newmobj = P_SpawnMobjFromMobj(actor, 0, 0, 14*FRACUNIT, item); + P_SetTarget(&newmobj->target, actor->target); // Transfer target + + if (item == MT_1UP_ICON) + { + if (actor->tracer) // Remove the old lives icon. + P_RemoveMobj(actor->tracer); + + if (!newmobj->target + || !newmobj->target->player + || !newmobj->target->skin + || ((skin_t *)newmobj->target->skin)->sprites[SPR2_LIFE].numframes == 0) + {} // No lives icon for this player, use the default. else - newmobj = P_SpawnMobj(actor->x, actor->y, actor->z + FixedMul(13*FRACUNIT, actor->scale), item); + { // Spawn the lives icon. + mobj_t *livesico = P_SpawnMobjFromMobj(newmobj, 0, 0, 0, MT_OVERLAY); + P_SetTarget(&livesico->target, newmobj); + P_SetTarget(&newmobj->tracer, livesico); - newmobj->destscale = actor->destscale; - P_SetScale(newmobj, actor->scale); - P_SetTarget(&newmobj->target, actor->target); // Transfer target - if (item == MT_1UPICO && newmobj->target->player) - { - if (actor->tracer) // Remove the old lives icon. - P_RemoveMobj(actor->tracer); + livesico->color = newmobj->target->player->mo->color; + livesico->skin = &skins[newmobj->target->player->skin]; + P_SetMobjState(livesico, newmobj->info->seestate); - if (!newmobj->target->skin || ((skin_t *)newmobj->target->skin)->spritedef.numframes <= states[S_PLAY_BOX1].frame) - newmobj->frame -= 2; // No lives icon for this player, use the default. - else - { // Spawn the lives icon. - remains = P_SpawnMobj(newmobj->x, newmobj->y, newmobj->z, MT_OVERLAY); - P_SetTarget(&remains->target, newmobj); - P_SetTarget(&newmobj->tracer, remains); - - remains->color = newmobj->target->player->mo->color; - remains->skin = &skins[newmobj->target->player->skin]; - P_SetMobjState(remains, newmobj->info->seestate); - } + // We're using the overlay, so use the overlay 1up sprite (no text) + newmobj->sprite = SPR_TV1P; } } - else - CONS_Debug(DBG_GAMELOGIC, "Powerup item not defined in 'damage' field for A_MonitorPop\n"); - P_RemoveMobj(actor); + // Run a linedef executor immediately upon popping + // You may want to delay your effects by 18 tics to sync with the reward giving + if (actor->spawnpoint && actor->lastlook) + P_LinedefExecute(actor->lastlook, actor->target, NULL); +} + +// Function: A_GoldMonitorRestore +// +// Description: A repeating monitor is coming back to life. Reset monitor flags, etc. +// +// var1 = unused +// var2 = unused +// +void A_GoldMonitorRestore(mobj_t *actor) +{ +#ifdef HAVE_BLUA + if (LUA_CallAction("A_GoldMonitorRestore", actor)) + return; +#endif + + actor->flags |= MF_MONITOR|MF_SHOOTABLE; + actor->health = 1; // Just in case. +} + +// Function: A_GoldMonitorSparkle +// +// Description: Spawns the little sparkly effect around big monitors. Looks pretty, doesn't it? +// +// var1 = unused +// var2 = unused +// +void A_GoldMonitorSparkle(mobj_t *actor) +{ + fixed_t i, ngangle, xofs, yofs; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_GoldMonitorSparkle", actor)) + return; +#endif + + ngangle = FixedAngle(((leveltime * 21) % 360) << FRACBITS); + xofs = FINESINE((ngangle>>ANGLETOFINESHIFT) & FINEMASK) * (actor->radius>>FRACBITS); + yofs = FINECOSINE((ngangle>>ANGLETOFINESHIFT) & FINEMASK) * (actor->radius>>FRACBITS); + + for (i = FRACUNIT*2; i <= FRACUNIT*3; i += FRACUNIT/2) + P_SetObjectMomZ(P_SpawnMobjFromMobj(actor, xofs, yofs, 0, MT_BOXSPARKLE), i, false); } // Function: A_Explode // // Description: Explodes an object, doing damage to any objects nearby. The target is used as the cause of the explosion. Damage value is used as explosion range. // -// var1 = unused +// var1 = damagetype // var2 = unused // void A_Explode(mobj_t *actor) { + INT32 locvar1 = var1; #ifdef HAVE_BLUA if (LUA_CallAction("A_Explode", actor)) return; #endif - P_RadiusAttack(actor, actor->target, actor->info->damage); + P_RadiusAttack(actor, actor->target, actor->info->damage, locvar1); } // Function: A_BossDeath @@ -2707,7 +3740,10 @@ void A_BossDeath(mobj_t *mo) return; #endif - P_LinedefExecute(LE_BOSSDEAD, mo, NULL); + if (mo->spawnpoint && mo->spawnpoint->extrainfo) + P_LinedefExecute(LE_BOSSDEAD+(mo->spawnpoint->extrainfo*LE_PARAMWIDTH), mo, NULL); + else + P_LinedefExecute(LE_BOSSDEAD, mo, NULL); mo->health = 0; // Boss is dead (but not necessarily fleeing...) @@ -2716,8 +3752,8 @@ void A_BossDeath(mobj_t *mo) // make sure there is a player alive for victory for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && (players[i].health > 0 - || ((netgame || multiplayer) && (players[i].lives > 0 || players[i].continues > 0)))) + if (playeringame[i] && ((players[i].mo && players[i].mo->health) + || ((netgame || multiplayer) && (players[i].lives || players[i].continues)))) break; if (i == MAXPLAYERS) @@ -2745,11 +3781,11 @@ void A_BossDeath(mobj_t *mo) else { // Bring the egg trap up to the surface - junk.tag = 680; + junk.tag = LE_CAPSULE0; EV_DoElevator(&junk, elevateHighest, false); - junk.tag = 681; + junk.tag = LE_CAPSULE1; EV_DoElevator(&junk, elevateUp, false); - junk.tag = 682; + junk.tag = LE_CAPSULE2; EV_DoElevator(&junk, elevateHighest, false); } @@ -2760,59 +3796,105 @@ bossjustdie: else if (P_MobjWasRemoved(mo)) return; #endif - if (mo->type == MT_BLACKEGGMAN || mo->type == MT_CYBRAKDEMON) + switch (mo->type) { - mo->flags |= MF_NOCLIP; - mo->flags &= ~MF_SPECIAL; + case MT_BLACKEGGMAN: + case MT_CYBRAKDEMON: + { + mo->flags |= MF_NOCLIP; + mo->flags &= ~MF_SPECIAL; - S_StartSound(NULL, sfx_befall); - } - else if (mo->type == MT_KOOPA) - { - junk.tag = 650; - EV_DoCeiling(&junk, raiseToHighest); - return; - } - else // eggmobiles - { - // Stop exploding and prepare to run. - P_SetMobjState(mo, mo->info->xdeathstate); - if (P_MobjWasRemoved(mo)) + S_StartSound(NULL, sfx_befall); + break; + } + case MT_KOOPA: + { + junk.tag = LE_KOOPA; + EV_DoCeiling(&junk, raiseToHighest); return; - - P_SetTarget(&mo->target, NULL); - - // Flee! Flee! Find a point to escape to! If none, just shoot upward! - // scan the thinkers to find the runaway point - for (th = thinkercap.next; th != &thinkercap; th = th->next) + } + case MT_FANG: { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; + if (mo->tracer) + { + var1 = var2 = 0; + A_Boss5Jump(mo); + mo->momx = ((16 - 1)*mo->momx)/16; + mo->momy = ((16 - 1)*mo->momy)/16; + if (!(mo->flags2 & MF2_AMBUSH)) + { + const fixed_t time = FixedHypot(mo->tracer->x - mo->x, mo->tracer->y - mo->y)/FixedHypot(mo->momx, mo->momy); + const fixed_t speed = 64*FRACUNIT; + mobj_t *pole = P_SpawnMobj( + mo->tracer->x - P_ReturnThrustX(mo->tracer, mo->tracer->angle, speed*time), + mo->tracer->y - P_ReturnThrustY(mo->tracer, mo->tracer->angle, speed*time), + mo->tracer->floorz + 4*FRACUNIT, + MT_FSGNB); + P_SetTarget(&pole->tracer, P_SpawnMobj( + pole->x + P_ReturnThrustX(pole, mo->tracer->angle, FRACUNIT), + pole->y + P_ReturnThrustY(pole, mo->tracer->angle, FRACUNIT), + pole->z + 256*FRACUNIT, + MT_FSGNA)); + pole->angle = mo->tracer->angle; + pole->tracer->angle = pole->angle - ANGLE_90; + pole->momx = P_ReturnThrustX(pole, pole->angle, speed); + pole->momy = P_ReturnThrustY(pole, pole->angle, speed); + pole->tracer->momx = pole->momx; + pole->tracer->momy = pole->momy; + } + } + else + { + P_SetObjectMomZ(mo, 10*FRACUNIT, false); + mo->flags |= MF_NOGRAVITY; + } + mo->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT; + return; + } + default: //eggmobiles + { + // Stop exploding and prepare to run. + P_SetMobjState(mo, mo->info->xdeathstate); + if (P_MobjWasRemoved(mo)) + return; - mo2 = (mobj_t *)th; + P_SetTarget(&mo->target, NULL); - if (mo2->type == MT_BOSSFLYPOINT) + // Flee! Flee! Find a point to escape to! If none, just shoot upward! + // scan the thinkers to find the runaway point + for (th = thinkercap.next; th != &thinkercap; th = th->next) { - // If this one's closer then the last one, go for it. - if (!mo->target || - P_AproxDistance(P_AproxDistance(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z) < + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; + + mo2 = (mobj_t *)th; + + if (mo2->type != MT_BOSSFLYPOINT) + continue; + + // If this one's further then the last one, don't go for it. + if (mo->target && + P_AproxDistance(P_AproxDistance(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z) > P_AproxDistance(P_AproxDistance(mo->x - mo->target->x, mo->y - mo->target->y), mo->z - mo->target->z)) - P_SetTarget(&mo->target, mo2); - // Otherwise... Don't! + continue; + + // Otherwise... Do! + P_SetTarget(&mo->target, mo2); } - } - mo->flags |= MF_NOGRAVITY|MF_NOCLIP; - mo->flags |= MF_NOCLIPHEIGHT; + mo->flags |= MF_NOGRAVITY|MF_NOCLIP; + mo->flags |= MF_NOCLIPHEIGHT; - if (mo->target) - { - mo->angle = R_PointToAngle2(mo->x, mo->y, mo->target->x, mo->target->y); - mo->flags2 |= MF2_BOSSFLEE; - mo->momz = FixedMul(FixedDiv(mo->target->z - mo->z, P_AproxDistance(mo->x-mo->target->x,mo->y-mo->target->y)), FixedMul(2*FRACUNIT, mo->scale)); + if (mo->target) + { + mo->angle = R_PointToAngle2(mo->x, mo->y, mo->target->x, mo->target->y); + mo->flags2 |= MF2_BOSSFLEE; + mo->momz = FixedMul(FixedDiv(mo->target->z - mo->z, P_AproxDistance(mo->x-mo->target->x,mo->y-mo->target->y)), FixedMul(2*FRACUNIT, mo->scale)); + } + else + mo->momz = FixedMul(2*FRACUNIT, mo->scale); + break; } - else - mo->momz = FixedMul(2*FRACUNIT, mo->scale); } if (mo->type == MT_EGGMOBILE2) @@ -2938,70 +4020,6 @@ void A_GiveWeapon(mobj_t *actor) S_StartSound(player->mo, actor->info->seesound); } -// Function: A_JumpShield -// -// Description: Awards the player a jump shield. -// -// var1 = unused -// var2 = unused -// -void A_JumpShield(mobj_t *actor) -{ - player_t *player; - -#ifdef HAVE_BLUA - if (LUA_CallAction("A_JumpShield", actor)) - return; -#endif - if (!actor->target || !actor->target->player) - { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; - } - - player = actor->target->player; - - if ((player->powers[pw_shield] & SH_NOSTACK) != SH_JUMP) - { - player->powers[pw_shield] = SH_JUMP|(player->powers[pw_shield] & SH_STACK); - P_SpawnShieldOrb(player); - } - - S_StartSound(player->mo, actor->info->seesound); -} - -// Function: A_RingShield -// -// Description: Awards the player a ring shield. -// -// var1 = unused -// var2 = unused -// -void A_RingShield(mobj_t *actor) -{ - player_t *player; - -#ifdef HAVE_BLUA - if (LUA_CallAction("A_RingShield", actor)) - return; -#endif - if (!actor->target || !actor->target->player) - { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; - } - - player = actor->target->player; - - if ((player->powers[pw_shield] & SH_NOSTACK) != SH_ATTRACT) - { - player->powers[pw_shield] = SH_ATTRACT|(player->powers[pw_shield] & SH_STACK); - P_SpawnShieldOrb(player); - } - - S_StartSound(player->mo, actor->info->seesound); -} - // Function: A_RingBox // // Description: Awards the player 10 rings. @@ -3059,7 +4077,9 @@ void A_Invincibility(mobj_t *actor) S_StopMusic(); if (mariomode) G_GhostAddColor(GHC_INVINCIBLE); - S_ChangeMusicInternal((mariomode) ? "minvnc" : "invinc", false); + strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14); + S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]); + S_ChangeMusicInternal((mariomode) ? "_minv" : "_inv", false); } } @@ -3095,8 +4115,10 @@ void A_SuperSneakers(mobj_t *actor) else { S_StopMusic(); - S_ChangeMusicInternal("shoes", false); + S_ChangeMusicInternal("_shoes", false); } + strlcpy(S_sfx[sfx_None].caption, "Speed shoes", 12); + S_StartCaption(sfx_None, -1, player->powers[pw_sneakers]); } } @@ -3151,8 +4173,11 @@ void A_ExtraLife(mobj_t *actor) player = actor->target->player; - if (actor->type == MT_1UPICO && !actor->tracer) - actor->frame -= 2; // No lives icon for this player, use the default. + if (actor->type == MT_1UP_ICON && actor->tracer) + { + // We're using the overlay, so use the overlay 1up sprite (no text) + actor->sprite = SPR_TV1P; + } if (ultimatemode) //I don't THINK so! { @@ -3160,27 +4185,23 @@ void A_ExtraLife(mobj_t *actor) return; } - // In shooter gametypes, give the player 100 rings instead of an extra life. - if (gametype != GT_COOP && gametype != GT_COMPETITION) - P_GivePlayerRings(player, 100); - else - P_GivePlayerLives(player, 1); - P_PlayLivesJingle(player); + P_GiveCoopLives(player, 1, true); } -// Function: A_BombShield +// Function: A_GiveShield // -// Description: Awards the player a bomb shield. +// Description: Awards the player a specified shield. // -// var1 = unused +// var1 = Shield type (make with SH_ constants) // var2 = unused // -void A_BombShield(mobj_t *actor) +void A_GiveShield(mobj_t *actor) { player_t *player; + UINT16 locvar1 = var1; #ifdef HAVE_BLUA - if (LUA_CallAction("A_BombShield", actor)) + if (LUA_CallAction("A_GiveShield", actor)) return; #endif if (!actor->target || !actor->target->player) @@ -3191,28 +4212,23 @@ void A_BombShield(mobj_t *actor) player = actor->target->player; - if ((player->powers[pw_shield] & SH_NOSTACK) != SH_BOMB) - { - player->powers[pw_shield] = SH_BOMB|(player->powers[pw_shield] & SH_STACK); - P_SpawnShieldOrb(player); - } - + P_SwitchShield(player, locvar1); S_StartSound(player->mo, actor->info->seesound); } -// Function: A_WaterShield +// Function: A_GravityBox // -// Description: Awards the player a water shield. +// Description: Awards the player gravity boots. // // var1 = unused // var2 = unused // -void A_WaterShield(mobj_t *actor) +void A_GravityBox(mobj_t *actor) { player_t *player; #ifdef HAVE_BLUA - if (LUA_CallAction("A_WaterShield", actor)) + if (LUA_CallAction("A_GravityBox", actor)) return; #endif if (!actor->target || !actor->target->player) @@ -3223,202 +4239,51 @@ void A_WaterShield(mobj_t *actor) player = actor->target->player; - if ((player->powers[pw_shield] & SH_NOSTACK) != SH_ELEMENTAL) - { - player->powers[pw_shield] = SH_ELEMENTAL|(player->powers[pw_shield] & SH_STACK); - P_SpawnShieldOrb(player); - } - - if (player->powers[pw_underwater] && player->powers[pw_underwater] <= 12*TICRATE + 1) - P_RestoreMusic(player); - - player->powers[pw_underwater] = 0; + S_StartSound(player, actor->info->activesound); - if (player->powers[pw_spacetime] > 1) - { - player->powers[pw_spacetime] = 0; - P_RestoreMusic(player); - } - S_StartSound(player->mo, actor->info->seesound); + player->powers[pw_gravityboots] = (UINT16)(actor->info->reactiontime + 1); } -// Function: A_ForceShield +// Function: A_ScoreRise // -// Description: Awards the player a force shield. +// Description: Makes the little score logos rise. Speed value sets speed. // // var1 = unused // var2 = unused // -void A_ForceShield(mobj_t *actor) +void A_ScoreRise(mobj_t *actor) { - player_t *player; - #ifdef HAVE_BLUA - if (LUA_CallAction("A_ForceShield", actor)) + if (LUA_CallAction("A_ScoreRise", actor)) return; #endif - if (!actor->target || !actor->target->player) - { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; - } - - player = actor->target->player; - - if (!(player->powers[pw_shield] & SH_FORCE)) - { - player->powers[pw_shield] = SH_FORCE|(player->powers[pw_shield] & SH_STACK)|0x01; - P_SpawnShieldOrb(player); - } - else - player->powers[pw_shield] = SH_FORCE|(player->powers[pw_shield] & SH_STACK)|0x01; - - S_StartSound(player->mo, actor->info->seesound); + // make logo rise! + P_SetObjectMomZ(actor, actor->info->speed, false); } -// Function: A_PityShield +// Function: A_BunnyHop // -// Description: Awards the player a pity shield. -// Because you fail it. -// Your skill is not enough. -// See you next time. -// Bye-bye. +// Description: Makes object hop like a bunny. // -// var1 = unused -// var2 = unused +// var1 = jump strength +// var2 = horizontal movement // -void A_PityShield(mobj_t *actor) +void A_BunnyHop(mobj_t *actor) { - player_t *player; + INT32 locvar1 = var1; + INT32 locvar2 = var2; #ifdef HAVE_BLUA - if (LUA_CallAction("A_PityShield", actor)) + if (LUA_CallAction("A_BunnyHop", actor)) return; #endif - if (!actor->target || !actor->target->player) + if (((actor->eflags & MFE_VERTICALFLIP) && actor->z + actor->height >= actor->ceilingz) + || (!(actor->eflags & MFE_VERTICALFLIP) && actor->z <= actor->floorz)) { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; + P_SetObjectMomZ(actor, locvar1*FRACUNIT, false); + P_InstaThrust(actor, actor->angle, FixedMul(locvar2*FRACUNIT, actor->scale)); // Launch the hopping action! PHOOM!! } - - player = actor->target->player; - - if ((player->powers[pw_shield] & SH_NOSTACK) != SH_PITY) - { - player->powers[pw_shield] = SH_PITY+(player->powers[pw_shield] & SH_STACK); - P_SpawnShieldOrb(player); - } - - S_StartSound(player->mo, actor->info->seesound); -} - - -// Function: A_GravityBox -// -// Description: Awards the player gravity boots. -// -// var1 = unused -// var2 = unused -// -void A_GravityBox(mobj_t *actor) -{ - player_t *player; - -#ifdef HAVE_BLUA - if (LUA_CallAction("A_GravityBox", actor)) - return; -#endif - if (!actor->target || !actor->target->player) - { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; - } - - player = actor->target->player; - player->powers[pw_gravityboots] = (UINT16)(actor->info->reactiontime + 1); - - S_StartSound(player, actor->info->activesound); -} - -// Function: A_ScoreRise -// -// Description: Makes the little score logos rise. Speed value sets speed. -// -// var1 = unused -// var2 = unused -// -void A_ScoreRise(mobj_t *actor) -{ -#ifdef HAVE_BLUA - if (LUA_CallAction("A_ScoreRise", actor)) - return; -#endif - // make logo rise! - P_SetObjectMomZ(actor, actor->info->speed, false); -} - -// Function: A_ParticleSpawn -// -// Description: Spawns a particle at a specified interval -// -// var1 = type (if 0, defaults to MT_PARTICLE) -// var2 = unused -// -void A_ParticleSpawn(mobj_t *actor) -{ - INT32 locvar1 = var1; - fixed_t speed; - mobjtype_t type; - mobj_t *spawn; - -#ifdef HAVE_BLUA - if (LUA_CallAction("A_ParticleSpawn", actor)) - return; -#endif - if (!actor->spawnpoint) - { - P_RemoveMobj(actor); - return; - } - - if (locvar1) - type = (mobjtype_t)locvar1; - else - type = MT_PARTICLE; - - speed = FixedMul((actor->spawnpoint->angle >> 12)<<FRACBITS, actor->scale); - - spawn = P_SpawnMobj(actor->x, actor->y, actor->z, type); - P_SetScale(spawn, actor->scale); - spawn->momz = speed; - spawn->destscale = FixedDiv(spawn->scale<<FRACBITS, 100<<FRACBITS); - spawn->scalespeed = FixedDiv(((actor->spawnpoint->angle >> 8) & 63) << FRACBITS, 100<<FRACBITS); - actor->tics = actor->spawnpoint->extrainfo + 1; -} - -// Function: A_BunnyHop -// -// Description: Makes object hop like a bunny. -// -// var1 = jump strength -// var2 = horizontal movement -// -void A_BunnyHop(mobj_t *actor) -{ - INT32 locvar1 = var1; - INT32 locvar2 = var2; - -#ifdef HAVE_BLUA - if (LUA_CallAction("A_BunnyHop", actor)) - return; -#endif - if (((actor->eflags & MFE_VERTICALFLIP) && actor->z + actor->height >= actor->ceilingz) - || (!(actor->eflags & MFE_VERTICALFLIP) && actor->z <= actor->floorz)) - { - P_SetObjectMomZ(actor, locvar1*FRACUNIT, false); - P_InstaThrust(actor, actor->angle, FixedMul(locvar2*FRACUNIT, actor->scale)); // Launch the hopping action! PHOOM!! - } -} +} // Function: A_BubbleSpawn // @@ -3444,10 +4309,10 @@ void A_BubbleSpawn(mobj_t *actor) } actor->flags2 &= ~MF2_DONTDRAW; - if (!(actor->flags & MF_AMBUSH)) + if (!(actor->flags2 & MF2_AMBUSH)) { // Quick! Look through players! - // Don't spawn bubbles unless a player is relatively close by (var2). + // Don't spawn bubbles unless a player is relatively close by (var1). for (i = 0; i < MAXPLAYERS; ++i) if (playeringame[i] && players[i].mo && P_AproxDistance(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (locvar1<<FRACBITS)) @@ -3492,7 +4357,7 @@ void A_FanBubbleSpawn(mobj_t *actor) if (!(actor->eflags & MFE_UNDERWATER)) return; - if (!(actor->flags & MF_AMBUSH)) + if (!(actor->flags2 & MF2_AMBUSH)) { // Quick! Look through players! // Don't spawn bubbles unless a player is relatively close by (var2). @@ -3603,7 +4468,7 @@ void A_AttractChase(mobj_t *actor) // Turn flingrings back into regular rings if attracted. if (actor->tracer && actor->tracer->player - && (actor->tracer->player->powers[pw_shield] & SH_NOSTACK) != SH_ATTRACT && actor->info->reactiontime && actor->type != (mobjtype_t)actor->info->reactiontime) + && !(actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRIC) && actor->info->reactiontime && actor->type != (mobjtype_t)actor->info->reactiontime) { mobj_t *newring; newring = P_SpawnMobj(actor->x, actor->y, actor->z, actor->info->reactiontime); @@ -3707,11 +4572,18 @@ void A_DropMine(mobj_t *actor) void A_FishJump(mobj_t *actor) { INT32 locvar1 = var1; + INT32 locvar2 = var2; #ifdef HAVE_BLUA if (LUA_CallAction("A_FishJump", actor)) return; #endif + if (locvar2) + { + fixed_t rad = actor->radius>>FRACBITS; + P_SpawnMobjFromMobj(actor, P_RandomRange(rad, -rad)<<FRACBITS, P_RandomRange(rad, -rad)<<FRACBITS, 0, (mobjtype_t)locvar2); + } + if ((actor->z <= actor->floorz) || (actor->z <= actor->watertop - FixedMul((64 << FRACBITS), actor->scale))) { fixed_t jumpval; @@ -3808,7 +4680,7 @@ void A_ThrownRing(mobj_t *actor) // A non-homing ring getting attracted by a // magnetic player. If he gets too far away, make // sure to stop the attraction! - if ((!actor->tracer->health) || (actor->tracer->player && (actor->tracer->player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT + if ((!actor->tracer->health) || (actor->tracer->player && (actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRIC) && P_AproxDistance(P_AproxDistance(actor->tracer->x-actor->x, actor->tracer->y-actor->y), actor->tracer->z-actor->z) > FixedMul(RING_DIST/4, actor->tracer->scale))) { @@ -3816,7 +4688,7 @@ void A_ThrownRing(mobj_t *actor) } if (actor->tracer && (actor->tracer->health) - && (actor->tracer->player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT)// Already found someone to follow. + && (actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRIC))// Already found someone to follow. { const INT32 temp = actor->threshold; actor->threshold = 32000; @@ -3884,7 +4756,7 @@ void A_ThrownRing(mobj_t *actor) if (!P_CheckSight(actor, player->mo)) continue; // out of sight - if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT + if ((player->powers[pw_shield] & SH_PROTECTELECTRIC) && dist < FixedMul(RING_DIST/4, player->mo->scale)) P_SetTarget(&actor->tracer, player->mo); return; @@ -3908,15 +4780,18 @@ void A_SetSolidSteam(mobj_t *actor) #endif actor->flags &= ~MF_NOCLIP; actor->flags |= MF_SOLID; - if (P_RandomChance(FRACUNIT/8)) - { - if (actor->info->deathsound) - S_StartSound(actor, actor->info->deathsound); // Hiss! - } - else + if (!(actor->flags2 & MF2_AMBUSH)) { - if (actor->info->painsound) - S_StartSound(actor, actor->info->painsound); + if (P_RandomChance(FRACUNIT/8)) + { + if (actor->info->deathsound) + S_StartSound(actor, actor->info->deathsound); // Hiss! + } + else + { + if (actor->info->painsound) + S_StartSound(actor, actor->info->painsound); + } } P_SetObjectMomZ (actor, 1, true); @@ -3949,6 +4824,7 @@ void A_UnsetSolidSteam(mobj_t *actor) void A_SignPlayer(mobj_t *actor) { mobj_t *ov; + skin_t *skin; #ifdef HAVE_BLUA if (LUA_CallAction("A_SignPlayer", actor)) return; @@ -3959,16 +4835,39 @@ void A_SignPlayer(mobj_t *actor) if (!actor->target->player) return; - // Set the sign to be an appropriate background color for this player's skincolor. - actor->color = Color_Opposite[actor->target->player->skincolor*2]; - actor->frame += Color_Opposite[actor->target->player->skincolor*2+1]; + skin = &skins[actor->target->player->skin]; + + if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor? + { + actor->color = skin->prefoppositecolor; + /* + If you're here from the comment above Color_Opposite, + the following line is the one which is dependent on the + array being symmetrical. It gets the opposite of the + opposite of your desired colour just so it can get the + brightness frame for the End Sign. It's not a great + design choice, but it's constant time array access and + the idea that the colours should be OPPOSITES is kind + of in the name. If you have a better idea, feel free + to let me know. ~toast 2016/07/20 + */ + actor->frame += (15 - Color_Opposite[(Color_Opposite[(skin->prefoppositecolor - 1)*2] - 1)*2 + 1]); + } + else if (actor->target->player->skincolor) // Set the sign to be an appropriate background color for this player's skincolor. + { + actor->color = Color_Opposite[(actor->target->player->skincolor - 1)*2]; + actor->frame += (15 - Color_Opposite[(actor->target->player->skincolor - 1)*2 + 1]); + } - // spawn an overlay of the player's face. - ov = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY); - P_SetTarget(&ov->target, actor); - ov->color = actor->target->player->skincolor; - ov->skin = &skins[actor->target->player->skin]; - P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN + if (skin->sprites[SPR2_SIGN].numframes) + { + // spawn an overlay of the player's face. + ov = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY); + P_SetTarget(&ov->target, actor); + ov->color = actor->target->player->skincolor; + ov->skin = skin; + P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN + } } // Function: A_OverlayThink @@ -4038,7 +4937,7 @@ void A_JetChase(mobj_t *actor) return; #endif - if (actor->flags & MF_AMBUSH) + if (actor->flags2 & MF2_AMBUSH) return; if (actor->z >= actor->waterbottom && actor->watertop > actor->floorz @@ -4145,7 +5044,8 @@ void A_JetbThink(mobj_t *actor) { A_JetChase(actor); // check for melee attack - if ((actor->z > (actor->floorz + FixedMul((32<<FRACBITS), actor->scale))) + if (actor->info->raisestate + && (actor->z > (actor->floorz + FixedMul((32<<FRACBITS), actor->scale))) && P_JetbCheckMeleeRange(actor) && !actor->reactiontime && (actor->target->z >= actor->floorz)) { @@ -4256,56 +5156,111 @@ void A_ShootBullet(mobj_t *actor) S_StartSound(actor, actor->info->attacksound); } +static mobj_t *minus; + +static boolean PIT_MinusCarry(mobj_t *thing) +{ + if (minus->type == thing->type) + return true; + + if (!(thing->flags & MF_SHOOTABLE) || !(thing->flags & MF_ENEMY)) + return true; + + if (P_AproxDistance(minus->x - thing->x, minus->y - thing->y) >= minus->radius * 3) + return true; + + if (abs(thing->z - minus->z) > minus->height) + return true; + + P_SetTarget(&minus->tracer, thing); + minus->tracer->flags &= ~MF_PUSHABLE; + + return true; +} + // Function: A_MinusDigging // // Description: Minus digging in the ground. // -// var1 = unused +// var1 = If 1, play digging sound. // var2 = unused // void A_MinusDigging(mobj_t *actor) { + INT32 locvar1 = var1; + INT32 rad = 32; + angle_t fa = (actor->angle >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t dis = actor->info->speed*4; + fixed_t x = FINECOSINE(fa)*dis + actor->x + FRACUNIT*P_RandomRange(-rad, rad); + fixed_t y = FINESINE(fa)*dis + actor->y + FRACUNIT*P_RandomRange(-rad, rad); + fixed_t mz = (actor->eflags & MFE_VERTICALFLIP) ? actor->ceilingz : actor->floorz; + mobj_t *par; + #ifdef HAVE_BLUA if (LUA_CallAction("A_MinusDigging", actor)) return; #endif - actor->flags &= ~MF_SPECIAL; - actor->flags &= ~MF_SHOOTABLE; if (!actor->target) { - A_Look(actor); + P_SetMobjState(actor, actor->info->spawnstate); return; } - if (actor->reactiontime) + par = P_SpawnMobj(actor->x, actor->y, mz, MT_MINUSDIRT); + if (actor->eflags & MFE_VERTICALFLIP) + par->eflags |= MFE_VERTICALFLIP; + P_TryMove(par, x, y, false); + + // If close enough, prepare to attack + if (P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) < actor->radius*2) { - actor->reactiontime--; + P_SetMobjState(actor, actor->info->meleestate); + P_TryMove(actor, actor->target->x, actor->target->y, false); + S_StartSound(actor, actor->info->attacksound); + + // Spawn growing dirt pile. + par = P_SpawnMobj(actor->x, actor->y, mz, MT_MINUSDIRT); + P_SetMobjState(par, actor->info->raisestate); + P_SetScale(par, actor->scale*2); + if (actor->eflags & MFE_VERTICALFLIP) + par->eflags |= MFE_VERTICALFLIP; return; } - // Dirt trail - P_SpawnGhostMobj(actor); + // Play digging sound + if (locvar1 == 1) + A_PlayActiveSound(actor); - actor->flags |= MF_NOCLIPTHING; + // Move var1 = 3; A_Chase(actor); - actor->flags &= ~MF_NOCLIPTHING; - // Play digging sound - if (!(leveltime & 15)) - S_StartSound(actor, actor->info->activesound); + // Carry over shit, maybe + if (!actor->tracer) + { + fixed_t radius = 3*actor->radius; + fixed_t yh = (unsigned)(actor->y + radius - bmaporgy) >> MAPBLOCKSHIFT; + fixed_t yl = (unsigned)(actor->y - radius - bmaporgy) >> MAPBLOCKSHIFT; + fixed_t xh = (unsigned)(actor->x + radius - bmaporgx) >> MAPBLOCKSHIFT; + fixed_t xl = (unsigned)(actor->x - radius - bmaporgx) >> MAPBLOCKSHIFT; + fixed_t bx, by; - // If we're close enough to our target, pop out of the ground - if (P_AproxDistance(actor->target->x-actor->x, actor->target->y-actor->y) < actor->radius - && abs(actor->target->z - actor->z) < actor->height) - P_SetMobjState(actor, actor->info->missilestate); + BMBOUNDFIX(xl, xh, yl, yh); - // Snap to ground - if (actor->eflags & MFE_VERTICALFLIP) - actor->z = actor->ceilingz - actor->height; + minus = actor; + + for (bx = xl; bx <= xh; bx++) + for (by = yl; by <= yh; by++) + P_BlockThingsIterator(bx, by, PIT_MinusCarry); + } else - actor->z = actor->floorz; + { + if (P_TryMove(actor->tracer, actor->x, actor->y, false)) + actor->tracer->z = mz; + else + P_SetTarget(&actor->tracer, NULL); + } } // Function: A_MinusPopup @@ -4317,45 +5272,56 @@ void A_MinusDigging(mobj_t *actor) // void A_MinusPopup(mobj_t *actor) { + INT32 num = 6; + angle_t ani = FixedAngle(FRACUNIT*360/num); + INT32 i; + #ifdef HAVE_BLUA if (LUA_CallAction("A_MinusPopup", actor)) return; #endif - P_SetObjectMomZ(actor, 10*FRACUNIT, false); - actor->flags |= MF_SPECIAL; - actor->flags |= MF_SHOOTABLE; + if (actor->eflags & MFE_VERTICALFLIP) + actor->momz = -10*FRACUNIT; + else + actor->momz = 10*FRACUNIT; + + actor->flags |= MF_SPECIAL|MF_SHOOTABLE; + S_StartSound(actor, sfx_s3k82); + for (i = 1; i <= num; i++) + { + mobj_t *rock = P_SpawnMobj(actor->x, actor->y, actor->z + actor->height/4, MT_ROCKCRUMBLE1); + P_Thrust(rock, ani*i, FRACUNIT); + rock->momz = 3*FRACUNIT; + P_SetScale(rock, FRACUNIT/3); + } + P_RadiusAttack(actor, actor, 2*actor->radius, 0); + if (actor->tracer) + P_DamageMobj(actor->tracer, actor, actor, 1, 0); - // Sound for busting out of the ground. - S_StartSound(actor, actor->info->attacksound); } // Function: A_MinusCheck // // Description: If the minus hits the floor, dig back into the ground. // -// var1 = unused +// var1 = State to switch to (if 0, use seestate). // var2 = unused // void A_MinusCheck(mobj_t *actor) { + INT32 locvar1 = var1; + #ifdef HAVE_BLUA if (LUA_CallAction("A_MinusCheck", actor)) return; #endif - if ((!(actor->eflags & MFE_VERTICALFLIP) && actor->z <= actor->floorz) - || ((actor->eflags & MFE_VERTICALFLIP) && actor->z + actor->height >= actor->ceilingz)) + + if (((actor->eflags & MFE_VERTICALFLIP) && actor->z + actor->height >= actor->ceilingz) || (!(actor->eflags & MFE_VERTICALFLIP) && actor->z <= actor->floorz)) { - actor->flags &= ~MF_SPECIAL; - actor->flags &= ~MF_SHOOTABLE; - actor->reactiontime = TICRATE; - P_SetMobjState(actor, actor->info->seestate); - return; + P_SetMobjState(actor, locvar1 ? (statenum_t)locvar1 : actor->info->seestate); + actor->flags = actor->info->flags; } - - // 'Falling' animation - if (P_MobjFlip(actor)*actor->momz < 0 && actor->state < &states[actor->info->meleestate]) - P_SetMobjState(actor, actor->info->meleestate); } // Function: A_ChickenCheck @@ -4635,6 +5601,7 @@ void A_CapeChase(mobj_t *actor) fixed_t foffsetx, foffsety, boffsetx, boffsety; INT32 locvar1 = var1; INT32 locvar2 = var2; + angle_t angle; #ifdef HAVE_BLUA if (LUA_CallAction("A_CapeChase", actor)) return; @@ -4656,11 +5623,13 @@ void A_CapeChase(mobj_t *actor) return; } - foffsetx = P_ReturnThrustX(chaser, chaser->angle, FixedMul((locvar2 >> 16)*FRACUNIT, actor->scale)); - foffsety = P_ReturnThrustY(chaser, chaser->angle, FixedMul((locvar2 >> 16)*FRACUNIT, actor->scale)); + angle = (chaser->player ? chaser->player->drawangle : chaser->angle); + + foffsetx = P_ReturnThrustX(chaser, angle, FixedMul((locvar2 >> 16)*FRACUNIT, actor->scale)); + foffsety = P_ReturnThrustY(chaser, angle, FixedMul((locvar2 >> 16)*FRACUNIT, actor->scale)); - boffsetx = P_ReturnThrustX(chaser, chaser->angle-ANGLE_90, FixedMul((locvar2 & 65535)*FRACUNIT, actor->scale)); - boffsety = P_ReturnThrustY(chaser, chaser->angle-ANGLE_90, FixedMul((locvar2 & 65535)*FRACUNIT, actor->scale)); + boffsetx = P_ReturnThrustX(chaser, angle-ANGLE_90, FixedMul((locvar2 & 65535)*FRACUNIT, actor->scale)); + boffsety = P_ReturnThrustY(chaser, angle-ANGLE_90, FixedMul((locvar2 & 65535)*FRACUNIT, actor->scale)); P_UnsetThingPosition(actor); actor->x = chaser->x + foffsetx + boffsetx; @@ -4677,7 +5646,7 @@ void A_CapeChase(mobj_t *actor) actor->flags2 &= ~MF2_OBJECTFLIP; actor->z = chaser->z + FixedMul((locvar1 >> 16)*FRACUNIT, actor->scale); } - actor->angle = chaser->angle; + actor->angle = angle; P_SetThingPosition(actor); } @@ -4699,9 +5668,6 @@ void A_RotateSpikeBall(mobj_t *actor) return; #endif - if (actor->type == MT_SPECIALSPIKEBALL) // don't remove this, these spikeballs share the same states as the rotating spikeballs - return; - if (!((!locvar1 && (actor->target)) || (locvar1 && (actor->tracer))))// This should NEVER happen. { CONS_Debug(DBG_GAMELOGIC, "A_RotateSpikeBall: Spikeball has no target\n"); @@ -4804,7 +5770,7 @@ void A_UnidusBall(mobj_t *actor) boolean skull = (actor->target->flags2 & MF2_SKULLFLY) == MF2_SKULLFLY; if (actor->target->state == &states[actor->target->info->painstate]) { - P_KillMobj(actor, NULL, NULL); + P_KillMobj(actor, NULL, NULL, 0); return; } switch(actor->extravalue2) @@ -4900,9 +5866,8 @@ void A_RockSpawn(mobj_t *actor) // void A_SlingAppear(mobj_t *actor) { - boolean firsttime = true; UINT8 mlength = 4; - mobj_t *spawnee; + mobj_t *spawnee, *hprev; #ifdef HAVE_BLUA if (LUA_CallAction("A_SlingAppear", actor)) return; @@ -4913,157 +5878,34 @@ void A_SlingAppear(mobj_t *actor) P_SetThingPosition(actor); actor->lastlook = 128; actor->movecount = actor->lastlook; - actor->health = actor->angle>>ANGLETOFINESHIFT; actor->threshold = 0; actor->movefactor = actor->threshold; actor->friction = 128; - actor->flags |= MF_SLIDEME; + hprev = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SMALLGRABCHAIN); + P_SetTarget(&hprev->tracer, actor); + P_SetTarget(&hprev->hprev, actor); + P_SetTarget(&actor->hnext, hprev); + hprev->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT; + hprev->movecount = mlength; + + mlength--; while (mlength > 0) { spawnee = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SMALLMACECHAIN); + P_SetTarget(&spawnee->tracer, actor); + P_SetTarget(&spawnee->hprev, hprev); + P_SetTarget(&hprev->hnext, spawnee); + hprev = spawnee; - P_SetTarget(&spawnee->target, actor); - - spawnee->movecount = 0; - spawnee->threshold = 0; - spawnee->reactiontime = mlength; - - if (firsttime) - { - // This is the outermost link in the chain - spawnee->flags |= MF_AMBUSH; - firsttime = false; - } + spawnee->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT; + spawnee->movecount = mlength; mlength--; } } -// -// Function: A_MaceRotate -// -// Spins an object around its target, or, swings it from side to side. -// -// var1 = unused -// var2 = unused -// -// So NOBODY forgets: -// actor-> -// threshold - X tilt -// movecount - Z tilt -// reactiontime - link # in the chain (1 is closest) -// lastlook - speed -// friction - top speed -// movedir - current angle holder -// extravalue1 - smoothly move link into place -// -void A_MaceRotate(mobj_t *actor) -{ - TVector v; - TVector *res; - fixed_t radius; -#ifdef HAVE_BLUA - if (LUA_CallAction("A_MaceRotate", actor)) - return; -#endif - - // Target was removed. - if (!actor->target) - { - P_RemoveMobj(actor); - return; - } - - P_UnsetThingPosition(actor); - - // Radius of the link's rotation. - radius = FixedMul(actor->info->speed * actor->reactiontime, actor->target->scale); - - // Double the radius if the chain links are made up of maces. - if (actor->target->type == MT_AXIS && (actor->type == MT_SMALLMACE || actor->type == MT_BIGMACE)) - radius *= 2; - - // Axis offset for the axis. - radius += actor->target->extravalue1; - - // Smoothly move the link into position. - if (actor->extravalue1) - { - radius = FixedMul(radius, FixedDiv(actor->extravalue1, 100)); - actor->extravalue1 += 1; - if (actor->extravalue1 >= 100) - actor->extravalue1 = 0; - } - - actor->x = actor->target->x; - actor->y = actor->target->y; - actor->z = actor->target->z; - - // Cut the height to align the link with the axis. - if (actor->type == MT_SMALLMACECHAIN || actor->type == MT_BIGMACECHAIN) - actor->z -= actor->height/4; - else - actor->z -= actor->height/2; - - // Set the top speed for the link if it happens to be over that speed. - if (actor->target->lastlook > actor->target->friction) - actor->target->lastlook = actor->target->friction; - - // Swinging Chain. - if (actor->target->type == MT_HANGMACEPOINT || actor->target->type == MT_SWINGMACEPOINT) - { - actor->movecount += actor->target->lastlook; - actor->movecount &= FINEMASK; - - actor->threshold = FixedMul(FINECOSINE(actor->movecount), actor->target->lastlook << FRACBITS); - - v[0] = FRACUNIT; - v[1] = 0; - v[2] = -radius; - v[3] = FRACUNIT; - - // Calculate the angle matrixes for the link. - res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(actor->threshold))); - M_Memcpy(&v, res, sizeof(v)); - res = VectorMatrixMultiply(v, *RotateZMatrix(actor->target->health << ANGLETOFINESHIFT)); - M_Memcpy(&v, res, sizeof(v)); - } - // Rotating Chain. - else - { - angle_t fa; - - actor->threshold += actor->target->lastlook; - actor->threshold &= FINEMASK; - actor->target->health &= FINEMASK; - - fa = actor->threshold; - v[0] = FixedMul(FINECOSINE(fa), radius); - v[1] = 0; - v[2] = FixedMul(FINESINE(fa), radius); - v[3] = FRACUNIT; - - // Calculate the angle matrixes for the link. - res = VectorMatrixMultiply(v, *RotateXMatrix(actor->target->threshold << ANGLETOFINESHIFT)); - M_Memcpy(&v, res, sizeof(v)); - res = VectorMatrixMultiply(v, *RotateZMatrix(actor->target->health << ANGLETOFINESHIFT)); - M_Memcpy(&v, res, sizeof(v)); - } - - // Add on the appropriate distances to the actor's co-ordinates. - actor->x += v[0]; - actor->y += v[1]; - actor->z += v[2]; - - P_SetThingPosition(actor); - - if (!(actor->target->flags2 & MF2_BOSSNOTRAP) // flag that makes maces shut up on request - && !(leveltime & 63) && (actor->type == MT_BIGMACE || actor->type == MT_SMALLMACE) && actor->target->type == MT_MACEPOINT) - S_StartSound(actor, actor->info->activesound); -} - // Function: A_SetFuse // // Description: Sets the actor's fuse timer if not set already. May also change state when fuse reaches the last tic, otherwise by default the actor will die or disappear. (Replaces A_SnowBall) @@ -5106,6 +5948,7 @@ void A_CrawlaCommanderThink(mobj_t *actor) fixed_t thefloor; INT32 locvar1 = var1; INT32 locvar2 = var2; + boolean hovermode = (actor->health > 1 || actor->fuse); #ifdef HAVE_BLUA if (LUA_CallAction("A_CrawlaCommanderThink", actor)) return; @@ -5117,10 +5960,16 @@ void A_CrawlaCommanderThink(mobj_t *actor) else thefloor = actor->floorz; - if (actor->fuse & 1) - actor->flags2 |= MF2_DONTDRAW; - else - actor->flags2 &= ~MF2_DONTDRAW; + if (!actor->fuse && actor->flags2 & MF2_FRET) + { + if (actor->info->painsound) + S_StartSound(actor, actor->info->painsound); + + actor->fuse = TICRATE/2; + actor->momz = 0; + + P_InstaThrust(actor, actor->angle-ANGLE_180, FixedMul(5*FRACUNIT, actor->scale)); + } if (actor->reactiontime > 0) actor->reactiontime--; @@ -5132,7 +5981,7 @@ void A_CrawlaCommanderThink(mobj_t *actor) } // Hover mode - if (actor->health > 1 || actor->fuse) + if (hovermode) { if (actor->z < thefloor + FixedMul(16*FRACUNIT, actor->scale)) actor->momz += FixedMul(FRACUNIT, actor->scale); @@ -5142,7 +5991,7 @@ void A_CrawlaCommanderThink(mobj_t *actor) actor->momz += FixedMul(16, actor->scale); } - if (!actor->target || !(actor->target->flags & MF_SHOOTABLE)) + if (!actor->target) { // look for a new target if (P_LookForPlayers(actor, true, false, 0)) @@ -5155,14 +6004,13 @@ void A_CrawlaCommanderThink(mobj_t *actor) dist = P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y); - if (actor->target->player && actor->health > 1) + if (actor->target->player && (!hovermode || actor->reactiontime <= 2*TICRATE)) { - if (dist < FixedMul(128*FRACUNIT, actor->scale) + if (dist < FixedMul(64<<(FRACBITS+(hovermode ? 1 : 0)), actor->scale) && ((actor->target->player->pflags & PF_JUMPED) || (actor->target->player->pflags & PF_SPINNING))) { - // Auugh! He's trying to kill you! Strafe! STRAAAAFFEEE!! - if (actor->target->momx || actor->target->momy) - P_InstaThrust(actor, actor->angle - ANGLE_180, FixedMul(20*FRACUNIT, actor->scale)); + // Auugh! She's trying to kill you! Strafe! STRAAAAFFEEE!! + P_InstaThrust(actor, actor->angle - ANGLE_180, FixedMul(20*FRACUNIT, actor->scale)); return; } } @@ -5187,29 +6035,44 @@ void A_CrawlaCommanderThink(mobj_t *actor) actor->angle += (P_RandomByte()<<10); actor->angle -= (P_RandomByte()<<10); - if (actor->health > 1) - P_InstaThrust(actor, actor->angle, FixedMul(10*FRACUNIT, actor->scale)); + if (hovermode) + { + fixed_t mom; + P_Thrust(actor, actor->angle, 2*actor->scale); + mom = P_AproxDistance(actor->momx, actor->momy); + if (mom > 20*actor->scale) + { + mom += 20*actor->scale; + mom >>= 1; + P_InstaThrust(actor, R_PointToAngle2(0, 0, actor->momx, actor->momy), mom); + } + } } else if (!actor->reactiontime) { - if (actor->health > 1) // Hover Mode + if (hovermode && !(actor->flags2 & MF2_FRET)) // Hover Mode { if (dist < FixedMul(512*FRACUNIT, actor->scale)) { actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); - P_InstaThrust(actor, actor->angle, FixedMul(60*FRACUNIT, actor->scale)); + P_InstaThrust(actor, actor->angle, FixedMul(40*FRACUNIT, actor->scale)); actor->threshold = 1; + if (actor->info->attacksound) + S_StartSound(actor, actor->info->attacksound); } } - actor->reactiontime = 2*TICRATE + P_RandomByte()/2; + actor->reactiontime = 3*TICRATE + (P_RandomByte()>>2); } if (actor->health == 1) P_Thrust(actor, actor->angle, 1); // Pogo Mode - if (!actor->fuse && actor->health == 1 && actor->z <= actor->floorz) + if (!hovermode && actor->z <= actor->floorz) { + if (actor->info->activesound) + S_StartSound(actor, actor->info->activesound); + if (dist < FixedMul(256*FRACUNIT, actor->scale)) { actor->momz = FixedMul(locvar2, actor->scale); @@ -5271,7 +6134,7 @@ void A_RingExplode(mobj_t *actor) if (mo2->flags & MF_SHOOTABLE) { actor->flags2 |= MF2_DEBRIS; - P_DamageMobj(mo2, actor, actor->target, 1); + P_DamageMobj(mo2, actor, actor->target, 1, 0); continue; } } @@ -5382,7 +6245,10 @@ void A_MixUp(mobj_t *actor) // No mix-up monitors in hide and seek or time only race. // The random factor is okay for other game modes, but in these, it is cripplingly unfair. if (gametype == GT_HIDEANDSEEK || gametype == GT_RACE) + { + S_StartSound(actor, sfx_lose); return; + } numplayers = 0; memset(teleported, 0, sizeof (teleported)); @@ -5391,7 +6257,7 @@ void A_MixUp(mobj_t *actor) // and grab their xyz coords for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && players[i].mo->health > 0 && players[i].playerstate == PST_LIVE - && !players[i].exiting && !players[i].powers[pw_super]) + && !players[i].exiting && !players[i].powers[pw_super] && players[i].powers[pw_carry] != CR_NIGHTSMODE) { if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators continue; @@ -5400,17 +6266,20 @@ void A_MixUp(mobj_t *actor) } if (numplayers <= 1) // Not enough players to mix up. + { + S_StartSound(actor, sfx_lose); return; + } else if (numplayers == 2) // Special case -- simple swap { fixed_t x, y, z; - angle_t angle; + angle_t angle, drawangle; INT32 one = -1, two = 0; // default value 0 to make the compiler shut up // Zoom tube stuff mobj_t *tempthing = NULL; //tracer - pflags_t flags1,flags2; //player pflags - INT32 transspeed; //player speed + UINT16 carry1,carry2; //carry + INT32 transspeed; //player speed // Starpost stuff INT16 starpostx, starposty, starpostz; @@ -5437,6 +6306,10 @@ void A_MixUp(mobj_t *actor) } //get this done first! + if (players[one].powers[pw_carry] == CR_MINECART && players[one].mo->tracer && !(P_MobjWasRemoved(players[one].mo->tracer))) + P_SetTarget(&players[one].mo->tracer->target, players[two].mo); + if (players[two].powers[pw_carry] == CR_MINECART && players[two].mo->tracer && !(P_MobjWasRemoved(players[two].mo->tracer))) + P_SetTarget(&players[two].mo->tracer->target, players[one].mo); tempthing = players[one].mo->tracer; P_SetTarget(&players[one].mo->tracer, players[two].mo->tracer); P_SetTarget(&players[two].mo->tracer, tempthing); @@ -5447,13 +6320,14 @@ void A_MixUp(mobj_t *actor) players[two].speed = transspeed; //set flags variables now but DON'T set them. - flags1 = (players[one].pflags & (PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG)); - flags2 = (players[two].pflags & (PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG)); + carry1 = (players[one].powers[pw_carry] == CR_PLAYER ? CR_NONE : players[one].powers[pw_carry]); + carry2 = (players[two].powers[pw_carry] == CR_PLAYER ? CR_NONE : players[two].powers[pw_carry]); x = players[one].mo->x; y = players[one].mo->y; z = players[one].mo->z; angle = players[one].mo->angle; + drawangle = players[one].drawangle; starpostx = players[one].starpostx; starposty = players[one].starposty; @@ -5469,16 +6343,18 @@ void A_MixUp(mobj_t *actor) players[two].starpostnum, players[two].starposttime, players[two].starpostangle, players[two].mo->flags2); + players[one].drawangle = players[two].drawangle; + P_MixUp(players[two].mo, x, y, z, angle, starpostx, starposty, starpostz, starpostnum, starposttime, starpostangle, mflags2); - //flags set after mixup. Stupid P_ResetPlayer() takes away some of the flags we look for... - //but not all of them! So we need to make sure they aren't set wrong or anything. - players[one].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG); - players[one].pflags |= flags2; - players[two].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG); - players[two].pflags |= flags1; + players[two].drawangle = drawangle; + + //carry set after mixup. Stupid P_ResetPlayer() takes away some of the stuff we look for... + //but not all of it! So we need to make sure they aren't set wrong or anything. + players[one].powers[pw_carry] = carry2; + players[two].powers[pw_carry] = carry1; teleported[one] = true; teleported[two] = true; @@ -5486,12 +6362,13 @@ void A_MixUp(mobj_t *actor) else { fixed_t position[MAXPLAYERS][3]; - angle_t anglepos[MAXPLAYERS]; + angle_t anglepos[MAXPLAYERS][2]; INT32 pindex[MAXPLAYERS], counter = 0, teleportfrom = 0; // Zoom tube stuff - mobj_t *transtracer[MAXPLAYERS]; //tracer - pflags_t transflag[MAXPLAYERS]; //player pflags + mobj_t *transtracer[MAXPLAYERS]; //tracer + //pflags_t transflag[MAXPLAYERS]; //cyan pink white pink cyan + UINT16 transcarry[MAXPLAYERS]; //player carry INT32 transspeed[MAXPLAYERS]; //player speed // Star post stuff @@ -5504,14 +6381,14 @@ void A_MixUp(mobj_t *actor) for (i = 0; i < MAXPLAYERS; i++) { - position[i][0] = position[i][1] = position[i][2] = anglepos[i] = pindex[i] = -1; + position[i][0] = position[i][1] = position[i][2] = anglepos[i][0] = anglepos[i][1] = pindex[i] = -1; teleported[i] = false; } for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i] && players[i].playerstate == PST_LIVE - && players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super]) + && players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super] && players[i].powers[pw_carry] != CR_NIGHTSMODE) { if ((netgame || multiplayer) && players[i].spectator)// Ignore spectators continue; @@ -5520,12 +6397,13 @@ void A_MixUp(mobj_t *actor) position[counter][1] = players[i].mo->y; position[counter][2] = players[i].mo->z; pindex[counter] = i; - anglepos[counter] = players[i].mo->angle; + anglepos[counter][0] = players[i].mo->angle; + anglepos[counter][1] = players[i].drawangle; players[i].mo->momx = players[i].mo->momy = players[i].mo->momz = players[i].rmomx = players[i].rmomy = 1; players[i].cmomx = players[i].cmomy = 0; - transflag[counter] = (players[i].pflags & (PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG)); + transcarry[counter] = (players[i].powers[pw_carry] == CR_PLAYER ? CR_NONE : players[i].powers[pw_carry]); transspeed[counter] = players[i].speed; transtracer[counter] = players[i].mo->tracer; @@ -5561,7 +6439,7 @@ void A_MixUp(mobj_t *actor) for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i] && players[i].playerstate == PST_LIVE - && players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super]) + && players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super] && players[i].powers[pw_carry] != CR_NIGHTSMODE) { if ((netgame || multiplayer) && players[i].spectator)// Ignore spectators continue; @@ -5572,14 +6450,17 @@ void A_MixUp(mobj_t *actor) players[i].speed = transspeed[teleportfrom]; P_SetTarget(&players[i].mo->tracer, transtracer[teleportfrom]); - P_MixUp(players[i].mo, position[teleportfrom][0], position[teleportfrom][1], position[teleportfrom][2], anglepos[teleportfrom], + P_MixUp(players[i].mo, position[teleportfrom][0], position[teleportfrom][1], position[teleportfrom][2], anglepos[teleportfrom][0], spposition[teleportfrom][0], spposition[teleportfrom][1], spposition[teleportfrom][2], starpostnum[teleportfrom], starposttime[teleportfrom], starpostangle[teleportfrom], flags2[teleportfrom]); - //...flags after. same reasoning. - players[i].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG); - players[i].pflags |= transflag[teleportfrom]; + players[i].drawangle = anglepos[teleportfrom][1]; + + //...carry after. same reasoning. + players[i].powers[pw_carry] = transcarry[teleportfrom]; + if (transcarry[teleportfrom] == CR_MINECART && transtracer[teleportfrom] && !(P_MobjWasRemoved(transtracer[teleportfrom]))) + P_SetTarget(&transtracer[teleportfrom]->target, players[i].mo); teleported[i] = true; counter++; @@ -5592,7 +6473,7 @@ void A_MixUp(mobj_t *actor) if (teleported[i]) { if (playeringame[i] && players[i].playerstate == PST_LIVE - && players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super]) + && players[i].mo && players[i].mo->health > 0 && !players[i].exiting && !players[i].powers[pw_super] && players[i].powers[pw_carry] != CR_NIGHTSMODE) { if ((netgame || multiplayer) && players[i].spectator)// Ignore spectators continue; @@ -5648,7 +6529,10 @@ void A_RecyclePowers(mobj_t *actor) #endif if (!multiplayer) + { + S_StartSound(actor, sfx_lose); return; + } numplayers = 0; @@ -5684,7 +6568,10 @@ void A_RecyclePowers(mobj_t *actor) } if (numplayers <= 1) + { + S_StartSound(actor, sfx_lose); return; //nobody to touch! + } //shuffle the post scramble list, whee! // hardcoded 0-1 to 1-0 for two players @@ -5734,7 +6621,7 @@ void A_RecyclePowers(mobj_t *actor) for (j = 0; j < NUMPOWERS; j++) { - if (j == pw_flashing || j == pw_underwater || j == pw_spacetime + if (j == pw_flashing || j == pw_underwater || j == pw_spacetime || j == pw_carry || j == pw_tailsfly || j == pw_extralife || j == pw_nocontrol || j == pw_super) continue; players[recv_pl].powers[j] = powers[send_pl][j]; @@ -5818,7 +6705,10 @@ void A_Boss1Chase(mobj_t *actor) } else { - P_LinedefExecute(LE_PINCHPHASE, actor, NULL); + if (actor->spawnpoint && actor->spawnpoint->extrainfo) + P_LinedefExecute(LE_PINCHPHASE+(actor->spawnpoint->extrainfo*LE_PARAMWIDTH), actor, NULL); + else + P_LinedefExecute(LE_PINCHPHASE, actor, NULL); P_SetMobjState(actor, actor->info->raisestate); } @@ -5918,7 +6808,7 @@ void A_Boss2Chase(mobj_t *actor) { actor->watertop = -actor->watertop; actor->extravalue1 = 18; - if (actor->flags & MF_AMBUSH) + if (actor->flags2 & MF2_AMBUSH) actor->extravalue1 -= (actor->info->spawnhealth - actor->health)*2; actor->extravalue2 = actor->extravalue1; } @@ -5944,7 +6834,7 @@ void A_Boss2Chase(mobj_t *actor) else { // Only speed up if you have the 'Deaf' flag. - if (actor->flags & MF_AMBUSH) + if (actor->flags2 & MF2_AMBUSH) speedvar = actor->health; else speedvar = actor->info->spawnhealth; @@ -6146,7 +7036,7 @@ void A_Boss7Chase(mobj_t *actor) if (actor->health <= actor->info->damage && actor->target && actor->target->player - && (actor->target->player->pflags & PF_ITEMHANG)) + && (actor->target->player->powers[pw_carry] == CR_GENERIC)) { A_FaceTarget(actor); P_SetMobjState(actor, S_BLACKEGG_SHOOT1); @@ -6381,7 +7271,7 @@ void A_EggmanBox(mobj_t *actor) return; } - P_DamageMobj(actor->target, actor, actor, 1); // Ow! + P_DamageMobj(actor->target, actor, actor, 1, 0); // Ow! } // Function: A_TurretFire @@ -6535,7 +7425,7 @@ void A_BuzzFly(mobj_t *actor) if (LUA_CallAction("A_BuzzFly", actor)) return; #endif - if (actor->flags & MF_AMBUSH) + if (actor->flags2 & MF2_AMBUSH) return; if (actor->reactiontime) @@ -6638,47 +7528,77 @@ void A_GuardChase(mobj_t *actor) if (actor->reactiontime) actor->reactiontime--; - if ((!actor->tracer || !actor->tracer->health) && actor->threshold != 42) + if (actor->threshold != 42) // In formation... { - P_SetTarget(&actor->tracer, NULL); - actor->threshold = 42; - P_SetMobjState(actor, actor->info->painstate); - actor->flags |= MF_SPECIAL|MF_SHOOTABLE; - return; - } + fixed_t speed; - // turn towards movement direction if not there yet - if (actor->movedir < NUMDIRS) - { - actor->angle &= (7<<29); - delta = actor->angle - (actor->movedir << 29); + if (!actor->tracer || !actor->tracer->health) + { + P_SetTarget(&actor->tracer, NULL); + actor->threshold = 42; + P_SetMobjState(actor, actor->info->painstate); + actor->flags |= MF_SPECIAL|MF_SHOOTABLE; + return; + } - if (delta > 0) - actor->angle -= ANGLE_45; - else if (delta < 0) - actor->angle += ANGLE_45; - } + speed = actor->extravalue1*actor->scale; - if (!actor->target || !(actor->target->flags & MF_SHOOTABLE)) - { - // look for a new target - if (P_LookForPlayers(actor, true, false, 0)) - return; // got a new target + if (actor->flags2 & MF2_AMBUSH) + speed <<= 1; - P_SetMobjStateNF(actor, actor->info->spawnstate); - return; + if (speed + && !P_TryMove(actor, + actor->x + P_ReturnThrustX(actor, actor->angle, speed), + actor->y + P_ReturnThrustY(actor, actor->angle, speed), + false) + && speed > 0) // can't be the same check as previous so that P_TryMove gets to happen. + { + if (actor->spawnpoint && ((actor->spawnpoint->options & (MTF_EXTRA|MTF_OBJECTSPECIAL)) == MTF_OBJECTSPECIAL)) + actor->angle += ANGLE_90; + else if (actor->spawnpoint && ((actor->spawnpoint->options & (MTF_EXTRA|MTF_OBJECTSPECIAL)) == MTF_EXTRA)) + actor->angle -= ANGLE_90; + else + actor->angle += ANGLE_180; + } + + if (actor->extravalue1 < actor->info->speed) + actor->extravalue1++; } + else // Break ranks! + { + // turn towards movement direction if not there yet + if (actor->movedir < NUMDIRS) + { + actor->angle &= (7<<29); + delta = actor->angle - (actor->movedir << 29); - // possibly choose another target - if (multiplayer && (actor->target->health <= 0 || !P_CheckSight(actor, actor->target)) - && P_LookForPlayers(actor, true, false, 0)) - return; // got a new target + if (delta > 0) + actor->angle -= ANGLE_45; + else if (delta < 0) + actor->angle += ANGLE_45; + } - // chase towards player - if (--actor->movecount < 0 || !P_Move(actor, (actor->flags & MF_AMBUSH) ? actor->info->speed * 2 : actor->info->speed)) - { - P_NewChaseDir(actor); - actor->movecount += 5; // Increase tics before change in direction allowed. + if (!actor->target || !(actor->target->flags & MF_SHOOTABLE)) + { + // look for a new target + if (P_LookForPlayers(actor, true, false, 0)) + return; // got a new target + + P_SetMobjStateNF(actor, actor->info->spawnstate); + return; + } + + // possibly choose another target + if (multiplayer && (actor->target->health <= 0 || !P_CheckSight(actor, actor->target)) + && P_LookForPlayers(actor, true, false, 0)) + return; // got a new target + + // chase towards player + if (--actor->movecount < 0 || !P_Move(actor, (actor->flags2 & MF2_AMBUSH) ? actor->info->speed * 2 : actor->info->speed)) + { + P_NewChaseDir(actor); + actor->movecount += 5; // Increase tics before change in direction allowed. + } } // Now that we've moved, its time for our shield to move! @@ -6993,6 +7913,8 @@ void A_LinedefExecute(mobj_t *actor) if (locvar2) tagnum += locvar2*(AngleFixed(actor->angle)>>FRACBITS); + else if (actor->spawnpoint && actor->spawnpoint->extrainfo) + tagnum += (actor->spawnpoint->extrainfo*LE_PARAMWIDTH); CONS_Debug(DBG_GAMELOGIC, "A_LinedefExecute: Running mobjtype %d's sector with tag %d\n", actor->type, tagnum); @@ -7164,6 +8086,7 @@ void A_SpawnObjectRelative(mobj_t *actor) if (actor->eflags & MFE_VERTICALFLIP) mo->flags2 |= MF2_OBJECTFLIP; + } // Function: A_ChangeAngleRelative @@ -8008,21 +8931,49 @@ void A_ToggleFlameJet(mobj_t* actor) // Description: Used by Chaos Emeralds to orbit around Nights (aka Super Sonic.) // // var1 = Angle adjustment (aka orbit speed) -// var2 = Lower four bits: height offset, Upper 4 bits = set if object is Nightopian Helper -// +// var2: +// Bits 1-10: height offset, max 1023 +// Bits 11-16: X radius factor (max 63, default 20) +// Bit 17: set if object is Nightopian Helper +// Bit 18: set to define X/Y/Z rotation factor +// Bits 19-20: Unused +// Bits 21-26: Y radius factor (max 63, default 32) +// Bits 27-32: Z radius factor (max 63, default 32) +// +// If MF_GRENADEBOUNCE is flagged on mobj, use actor->threshold to define X/Y/Z radius factor, max 1023 each: +// Bits 1-10: X factor +// Bits 11-20: Y factor +// Bits 21-30: Z factor void A_OrbitNights(mobj_t* actor) { - INT32 ofs = (var2 & 0xFFFF); - boolean ishelper = (var2 & 0xFFFF0000); + INT32 ofs = (var2 & 0x3FF); + boolean ishelper = (var2 & 0x10000); + boolean donotrescale = (var2 & 0x40000); + INT32 xfactor = 32, yfactor = 32, zfactor = 20; #ifdef HAVE_BLUA if (LUA_CallAction("A_OrbitNights", actor)) return; #endif - if (!actor->target || !actor->target->player || - !actor->target->tracer || !actor->target->player->nightstime + if (actor->flags & MF_GRENADEBOUNCE) + { + xfactor = (actor->threshold & 0x3FF); + yfactor = (actor->threshold & 0xFFC00) >> 10; + zfactor = (actor->threshold & 0x3FF00000) >> 20; + } + else if (var2 & 0x20000) + { + xfactor = (var2 & 0xFC00) >> 10; + yfactor = (var2 & 0x3F00000) >> 20; + zfactor = (var2 & 0xFC000000) >> 26; + } + + if (!actor->target + || (actor->target->player && + // if NiGHTS special stage and not NiGHTSmode. + (((maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap) && !(actor->target->player->powers[pw_carry] == CR_NIGHTSMODE)) // Also remove this object if they no longer have a NiGHTS helper - || (ishelper && !actor->target->player->powers[pw_nights_helper])) + || (ishelper && !actor->target->player->powers[pw_nights_helper])))) { P_RemoveMobj(actor); return; @@ -8035,18 +8986,30 @@ void A_OrbitNights(mobj_t* actor) const angle_t fa = (angle_t)actor->extravalue1 >> ANGLETOFINESHIFT; const angle_t ofa = ((angle_t)actor->extravalue1 + (ofs*ANG1)) >> ANGLETOFINESHIFT; - const fixed_t fc = FixedMul(FINECOSINE(fa),FixedMul(32*FRACUNIT, actor->scale)); - const fixed_t fh = FixedMul(FINECOSINE(ofa),FixedMul(20*FRACUNIT, actor->scale)); - const fixed_t fs = FixedMul(FINESINE(fa),FixedMul(32*FRACUNIT, actor->scale)); + const fixed_t fc = FixedMul(FINECOSINE(fa),FixedMul(xfactor*FRACUNIT, actor->scale)); + const fixed_t fh = FixedMul(FINECOSINE(ofa),FixedMul(zfactor*FRACUNIT, actor->scale)); + const fixed_t fs = FixedMul(FINESINE(fa),FixedMul(yfactor*FRACUNIT, actor->scale)); - actor->x = actor->target->tracer->x + fc; - actor->y = actor->target->tracer->y + fs; - actor->z = actor->target->tracer->z + fh + FixedMul(16*FRACUNIT, actor->scale); + actor->x = actor->target->x + fc; + actor->y = actor->target->y + fs; + actor->z = actor->target->z + fh + FixedMul(16*FRACUNIT, actor->scale); // Semi-lazy hack actor->angle = (angle_t)actor->extravalue1 + ANGLE_90; } P_SetThingPosition(actor); + + if (ishelper && actor->target->player) // Flash a helper that's about to be removed. + { + if ((actor->target->player->powers[pw_nights_helper] < TICRATE) + && (actor->target->player->powers[pw_nights_helper] & 1)) + actor->flags2 |= MF2_DONTDRAW; + else + actor->flags2 &= ~MF2_DONTDRAW; + } + + if (!donotrescale && actor->destscale != actor->target->destscale) + actor->destscale = actor->target->destscale; } } @@ -8054,16 +9017,20 @@ void A_OrbitNights(mobj_t* actor) // // Description: Spawns a "ghost" mobj of this actor, ala spindash trails and the minus's digging "trails" // -// var1 = unused +// var1 = duration in tics // var2 = unused // void A_GhostMe(mobj_t *actor) { + INT32 locvar1 = var1; + mobj_t *ghost; #ifdef HAVE_BLUA if (LUA_CallAction("A_GhostMe", actor)) return; #endif - P_SpawnGhostMobj(actor); + ghost = P_SpawnGhostMobj(actor); + if (ghost && locvar1 > 0) + ghost->fuse = locvar1; } // Function: A_SetObjectState @@ -8253,7 +9220,7 @@ void A_RingDrain(mobj_t *actor) } player = actor->target->player; - P_GivePlayerRings(player, -min(locvar1, player->mo->health-1)); + P_GivePlayerRings(player, -min(locvar1, player->rings)); } // Function: A_SplitShot @@ -8561,7 +9528,7 @@ void A_CheckTargetRings(mobj_t *actor) if (!(actor->target) || !(actor->target->player)) return; - if (actor->target->player->health >= locvar1) + if (actor->target->player->rings >= locvar1) P_SetMobjState(actor, locvar2); } @@ -8583,7 +9550,7 @@ void A_CheckRings(mobj_t *actor) #endif for (i = 0; i < MAXPLAYERS; i++) - cntr += players[i].health-1; + cntr += players[i].rings; if (cntr >= locvar1) P_SetMobjState(actor, locvar2); @@ -9155,8 +10122,8 @@ void A_ForceWin(mobj_t *actor) for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && (players[i].health > 0 - || ((netgame || multiplayer) && (players[i].lives > 0 || players[i].continues > 0)))) + if (playeringame[i] && ((players[i].mo && players[i].mo->health) + || ((netgame || multiplayer) && (players[i].lives || players[i].continues)))) break; } @@ -9269,7 +10236,7 @@ void A_Repeat(mobj_t *actor) return; #endif - if ((!(actor->extravalue2)) || actor->extravalue2 > locvar1) + if (locvar1 && (!actor->extravalue2 || actor->extravalue2 > locvar1)) actor->extravalue2 = locvar1; if (--actor->extravalue2 > 0) @@ -9358,9 +10325,9 @@ void A_RemoteDamage(mobj_t *actor) if (locvar2 == 1) // Kill mobj! { if (target->player) // players die using P_DamageMobj instead for some reason - P_DamageMobj(target, source, source, 10000); + P_DamageMobj(target, source, source, 1, DMG_INSTAKILL); else - P_KillMobj(target, source, source); + P_KillMobj(target, source, source, 0); } else if (locvar2 == 2) // Remove mobj! { @@ -9370,7 +10337,7 @@ void A_RemoteDamage(mobj_t *actor) P_RemoveMobj(target); } else // default: Damage mobj! - P_DamageMobj(target, source, source, 1); + P_DamageMobj(target, source, source, 1, 0); } // Function: A_HomingChase @@ -9422,14 +10389,19 @@ void A_HomingChase(mobj_t *actor) // lower 16 bits = object # to fire // upper 16 bits = front offset // var2: -// lower 16 bits = vertical angle +// lower 15 bits = vertical angle variable +// 16th bit: +// - 0: use vertical angle variable as vertical angle in degrees +// - 1: mimic P_SpawnXYZMissile +// use z of actor minus z of missile as vertical distance to cover during momz calculation +// use vertical angle variable as horizontal distance to cover during momz calculation // upper 16 bits = height offset // void A_TrapShot(mobj_t *actor) { INT32 locvar1 = var1; INT32 locvar2 = var2; - angle_t vertang = FixedAngle(((INT16)(locvar2 & 65535))*FRACUNIT); + boolean oldstyle = (locvar2 & 32768) ? true : false; mobjtype_t type = (mobjtype_t)(locvar1 & 65535); mobj_t *missile; INT16 frontoff = (INT16)(locvar1 >> 16); @@ -9445,10 +10417,7 @@ void A_TrapShot(mobj_t *actor) y = actor->y + P_ReturnThrustY(actor, actor->angle, FixedMul(frontoff*FRACUNIT, actor->scale)); if (actor->eflags & MFE_VERTICALFLIP) - { z = actor->z + actor->height - FixedMul(vertoff*FRACUNIT, actor->scale) - FixedMul(mobjinfo[type].height, actor->scale); - vertang = InvAngle(vertang); // flip firing angle - } else z = actor->z + FixedMul(vertoff*FRACUNIT, actor->scale); @@ -9459,20 +10428,35 @@ void A_TrapShot(mobj_t *actor) if (actor->eflags & MFE_VERTICALFLIP) missile->flags2 |= MF2_OBJECTFLIP; - missile->destscale = actor->destscale; - P_SetScale(missile, missile->destscale); + + missile->destscale = actor->scale; + P_SetScale(missile, actor->scale); if (missile->info->seesound) - S_StartSound(actor, missile->info->seesound); + S_StartSound(missile, missile->info->seesound); P_SetTarget(&missile->target, actor); missile->angle = actor->angle; speed = FixedMul(missile->info->speed, missile->scale); - missile->momx = FixedMul(FINECOSINE(vertang>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(missile->angle>>ANGLETOFINESHIFT), speed)); - missile->momy = FixedMul(FINECOSINE(vertang>>ANGLETOFINESHIFT), FixedMul(FINESINE(missile->angle>>ANGLETOFINESHIFT), speed)); - missile->momz = FixedMul(FINESINE(vertang>>ANGLETOFINESHIFT), speed); + if (oldstyle) + { + missile->momx = FixedMul(FINECOSINE(missile->angle>>ANGLETOFINESHIFT), speed); + missile->momy = FixedMul(FINESINE(missile->angle>>ANGLETOFINESHIFT), speed); + // The below line basically mimics P_SpawnXYZMissile's momz calculation. + missile->momz = (actor->z + ((actor->eflags & MFE_VERTICALFLIP) ? actor->height : 0) - z) / ((fixed_t)(locvar2 & 32767)*FRACUNIT / speed); + P_CheckMissileSpawn(missile); + } + else + { + angle_t vertang = FixedAngle(((INT16)(locvar2 & 32767))*FRACUNIT); + if (actor->eflags & MFE_VERTICALFLIP) + vertang = InvAngle(vertang); // flip firing angle + missile->momx = FixedMul(FINECOSINE(vertang>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(missile->angle>>ANGLETOFINESHIFT), speed)); + missile->momy = FixedMul(FINECOSINE(vertang>>ANGLETOFINESHIFT), FixedMul(FINESINE(missile->angle>>ANGLETOFINESHIFT), speed)); + missile->momz = FixedMul(FINESINE(vertang>>ANGLETOFINESHIFT), speed); + } } // Function: A_VileTarget @@ -9605,7 +10589,7 @@ void A_VileAttack(mobj_t *actor) return; S_StartSound(actor, soundtoplay); - P_DamageMobj(actor->target, actor, actor, 1); + P_DamageMobj(actor->target, actor, actor, 1, 0); //actor->target->momz = 1000*FRACUNIT/actor->target->info->mass; // How id did it actor->target->momz += FixedMul(10*FRACUNIT, actor->scale)*P_MobjFlip(actor->target); // How we're doing it if (explosionType != MT_NULL) @@ -9626,7 +10610,7 @@ void A_VileAttack(mobj_t *actor) actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)), actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)), fire->z); - P_RadiusAttack(fire, actor, 70*FRACUNIT); + P_RadiusAttack(fire, actor, 70*FRACUNIT, 0); } else { @@ -9646,7 +10630,7 @@ void A_VileAttack(mobj_t *actor) continue; S_StartSound(actor, soundtoplay); - P_DamageMobj(players[i].mo, actor, actor, 1); + P_DamageMobj(players[i].mo, actor, actor, 1, 0); //actor->target->momz = 1000*FRACUNIT/actor->target->info->mass; // How id did it players[i].mo->momz += FixedMul(10*FRACUNIT, actor->scale)*P_MobjFlip(players[i].mo); // How we're doing it if (explosionType != MT_NULL) @@ -9671,7 +10655,7 @@ void A_VileAttack(mobj_t *actor) actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)), actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)), fire->z); - P_RadiusAttack(fire, actor, 70*FRACUNIT); + P_RadiusAttack(fire, actor, 70*FRACUNIT, 0); } } @@ -10135,13 +11119,2459 @@ void A_SpawnFreshCopy(mobj_t *actor) return; #endif - newObject = P_SpawnMobj(actor->x, actor->y, actor->z, actor->type); + newObject = P_SpawnMobjFromMobj(actor, 0, 0, 0, actor->type); + newObject->flags2 = actor->flags2 & MF2_AMBUSH; newObject->angle = actor->angle; - P_SetScale(newObject, actor->scale); - newObject->destscale = actor->destscale; + newObject->color = actor->color; P_SetTarget(&newObject->target, actor->target); P_SetTarget(&newObject->tracer, actor->tracer); if (newObject->info->seesound) S_StartSound(newObject, newObject->info->seesound); } + +// Internal Flicky spawning function. +mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers) +{ + mobj_t *flicky; + + if (!flickytype) + { + if (!mapheaderinfo[gamemap-1] || !mapheaderinfo[gamemap-1]->numFlickies) // No mapheader, no shoes, no service. + return NULL; + else + { + INT32 prandom = P_RandomKey(mapheaderinfo[gamemap-1]->numFlickies); + flickytype = mapheaderinfo[gamemap-1]->flickies[prandom]; + } + } + + flicky = P_SpawnMobjFromMobj(actor, 0, 0, 0, flickytype); + flicky->angle = actor->angle; + + if (flickytype == MT_SEED) + flicky->z += P_MobjFlip(actor)*(actor->height - flicky->height)/2; + + if (actor->eflags & MFE_UNDERWATER) + momz = FixedDiv(momz, FixedSqrt(3*FRACUNIT)); + + P_SetObjectMomZ(flicky, momz, false); + flicky->movedir = (P_RandomChance(FRACUNIT/2) ? -1 : 1); + flicky->fuse = P_RandomRange(595, 700); // originally 300, 350 + flicky->threshold = 0; + + if (lookforplayers) + P_LookForPlayers(flicky, true, false, 0); + + return flicky; +} + +// Function: A_FlickySpawn +// +// Description: Flicky spawning function. +// +// var1: +// lower 16 bits: if 0, spawns random flicky based on level header. Else, spawns the designated thing type. +// upper 16 bits: if 0, no sound is played. Else, A_Scream is called. +// var2 = upwards thrust for spawned flicky. If zero, default value is provided. +// +void A_FlickySpawn(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_FlickySpawn", actor)) + return; +#endif + + if (locvar1 >> 16) { + A_Scream(actor); // A shortcut for the truly lazy. + locvar1 &= 65535; + } + + P_InternalFlickySpawn(actor, locvar1, ((locvar2) ? locvar2 : 8*FRACUNIT), true); +} + +// Internal Flicky color setting +void P_InternalFlickySetColor(mobj_t *actor, UINT8 extrainfo) +{ + UINT8 flickycolors[] = { + SKINCOLOR_RED, + SKINCOLOR_CYAN, + SKINCOLOR_BLUE, + SKINCOLOR_VAPOR, + SKINCOLOR_PURPLE, + SKINCOLOR_BUBBLEGUM, + SKINCOLOR_NEON, + SKINCOLOR_BLACK, + SKINCOLOR_BEIGE, + SKINCOLOR_LAVENDER, + SKINCOLOR_RUBY, + SKINCOLOR_SALMON, + SKINCOLOR_SUNSET, + SKINCOLOR_ORANGE, + SKINCOLOR_YELLOW, + }; + + if (extrainfo == 0) + // until we can customize flicky colors by level header, just stick to SRB2's defaults + actor->color = flickycolors[P_RandomKey(2)]; //flickycolors[P_RandomKey(sizeof(flickycolors))]; + else + actor->color = flickycolors[min(extrainfo-1, 14)]; // sizeof(flickycolors)-1 +} + +// Function: A_FlickyCenter +// +// Description: Place flickies in-level. +// +// var1: +// Lower 16 bits = if 0, spawns random flicky based on level header. Else, spawns the designated thing type. +// Bits 17-20 = Flicky color, up to 15. Applies to fish. +// Bit 21 = Flag MF_SLIDEME (see below) +// Bit 22 = Flag MF_GRENADEBOUNCE (see below) +// Bit 23 = Flag MF_NOCLIPTHING (see below) +// +// If actor is placed from a spawnpoint (map Thing), the Thing's properties take precedence. +// +// var2 = maximum default distance away from spawn the flickies are allowed to travel. If angle != 0, then that's the radius. +// +// If MTF_EXTRA (MF_SLIDEME): is flagged, Flickies move aimlessly. Else, orbit around the target. +// If MTF_OBJECTSPECIAL (MF_GRENADEBOUNCE): Flickies stand in-place without gravity (unless they hop, then gravity is applied.) +// If MTF_AMBUSH (MF_NOCLIPTHING): is flagged, Flickies hop. +// +void A_FlickyCenter(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + UINT16 flickytype = (locvar1 & 0xFFFF); + UINT8 flickycolor = ((locvar1 >> 16) & 0xFF); + UINT8 flickyflags = ((locvar1 >> 20) & 0xF); +#ifdef HAVE_BLUA + if (LUA_CallAction("A_FlickyCenter", actor)) + return; +#endif + + if (!actor->tracer) + { + mobj_t *flicky = P_InternalFlickySpawn(actor, locvar1, 1, false); + P_SetTarget(&flicky->target, actor); + P_SetTarget(&actor->tracer, flicky); + + if (actor->spawnpoint) + { + actor->flags &= ~(MF_SLIDEME|MF_GRENADEBOUNCE|MF_NOCLIPTHING); + actor->flags |= ( + ((actor->spawnpoint->options & MTF_EXTRA) ? MF_SLIDEME : 0) + | ((actor->spawnpoint->options & MTF_OBJECTSPECIAL) ? MF_GRENADEBOUNCE : 0) + | ((actor->spawnpoint->options & MTF_AMBUSH) ? MF_NOCLIPTHING : 0) + ); + actor->extravalue1 = actor->spawnpoint->angle ? abs(actor->spawnpoint->angle) * FRACUNIT + : locvar2 ? abs(locvar2) : 384 * FRACUNIT; + actor->extravalue2 = actor->spawnpoint->extrainfo; + actor->friction = actor->spawnpoint->x*FRACUNIT; + actor->movefactor = actor->spawnpoint->y*FRACUNIT; + actor->watertop = actor->spawnpoint->z*FRACUNIT; + } + else + { + actor->flags &= ~(MF_SLIDEME|MF_GRENADEBOUNCE|MF_NOCLIPTHING); + actor->flags |= ( + ((flickyflags & 1) ? MF_SLIDEME : 0) + | ((flickyflags & 2) ? MF_GRENADEBOUNCE : 0) + | ((flickyflags & 4) ? MF_NOCLIPTHING : 0) + ); + actor->extravalue1 = abs(locvar2); + actor->extravalue2 = flickycolor; + actor->friction = actor->x; + actor->movefactor = actor->y; + actor->watertop = actor->z; + locvar1 = flickytype; + } + + if (actor->flags & MF_GRENADEBOUNCE) // in-place + actor->tracer->fuse = 0; + else if (actor->flags & MF_SLIDEME) // aimless + { + actor->tracer->fuse = 0; // less than 2*TICRATE means move aimlessly. + actor->tracer->angle = P_RandomKey(180)*ANG2; + } + else //orbit + actor->tracer->fuse = FRACUNIT; + + if (locvar1 == MT_FLICKY_08) + P_InternalFlickySetColor(actor->tracer, actor->extravalue2); + + actor->extravalue2 = 0; + } + + if (!(actor->flags & MF_SLIDEME) && !(actor->flags & MF_GRENADEBOUNCE)) + { + fixed_t originx = actor->friction; + fixed_t originy = actor->movefactor; + fixed_t originz = actor->watertop; + + actor->tracer->fuse = FRACUNIT; + + // Impose default home radius if flicky orbits around player + if (!actor->extravalue1) + actor->extravalue1 = locvar2 ? abs(locvar2) : 384 * FRACUNIT; + + P_LookForPlayers(actor, true, false, actor->extravalue1); + + if (actor->target && P_AproxDistance(actor->target->x - originx, actor->target->y - originy) < actor->extravalue1) + { + actor->extravalue2 = 1; + P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z); + } + else if(actor->extravalue2) + { + actor->extravalue2 = 0; + P_TeleportMove(actor, originx, originy, originz); + } + } +} + +// Internal Flicky bubbling function. +void P_InternalFlickyBubble(mobj_t *actor) +{ + if (actor->eflags & MFE_UNDERWATER) + { + mobj_t *overlay; + + if (!((actor->z + 3*actor->height/2) < actor->watertop) || !mobjinfo[actor->type].raisestate || actor->tracer) + return; + + overlay = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY); + P_SetMobjStateNF(overlay, mobjinfo[actor->type].raisestate); + P_SetTarget(&actor->tracer, overlay); + P_SetTarget(&overlay->target, actor); + return; + } + + if (!actor->tracer || P_MobjWasRemoved(actor->tracer)) + return; + + P_RemoveMobj(actor->tracer); + P_SetTarget(&actor->tracer, NULL); +} + +// Function: A_FlickyAim +// +// Description: Flicky aiming function. +// +// var1 = how far around the target (in angle constants) the flicky should look +// var2 = distance from target to aim for +// +void A_FlickyAim(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + boolean flickyhitwall = false; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_FlickyAim", actor)) + return; +#endif + + if ((actor->momx == actor->momy && actor->momy == 0) + || (actor->target && P_IsFlickyCenter(actor->target->type) + && actor->target->extravalue1 && (actor->target->flags & MF_SLIDEME) + && P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) >= actor->target->extravalue1)) + flickyhitwall = true; + + P_InternalFlickyBubble(actor); + P_InstaThrust(actor, 0, 0); + + if (!actor->target) + { + P_LookForPlayers(actor, true, false, 0); + actor->angle = P_RandomKey(36)*ANG10; + return; + } + + if (actor->fuse > 2*TICRATE) + { + angle_t posvar; + fixed_t chasevar, chasex, chasey; + + if (flickyhitwall) + actor->movedir *= -1; + + posvar = ((R_PointToAngle2(actor->target->x, actor->target->y, actor->x, actor->y) + actor->movedir*locvar1) >> ANGLETOFINESHIFT) & FINEMASK; + chasevar = FixedSqrt(max(FRACUNIT, P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y) - locvar2)) + locvar2; + + chasex = actor->target->x + FixedMul(FINECOSINE(posvar), chasevar); + chasey = actor->target->y + FixedMul(FINESINE(posvar), chasevar); + + if (P_AproxDistance(chasex - actor->x, chasey - actor->y)) + actor->angle = R_PointToAngle2(actor->x, actor->y, chasex, chasey); + } + else if (flickyhitwall) + { + if (actor->target && P_IsFlickyCenter(actor->target->type)) + actor->angle = R_PointToAngle2(actor->target->x, actor->target->y, actor->x, actor->y) + P_RandomRange(112, 248) * ANG1; + else + actor->angle += P_RandomRange(112, 248)*ANG1; + actor->threshold = 0; + } +} + +//Internal Flicky flying function. Also usuable as an underwater swim thrust. +void P_InternalFlickyFly(mobj_t *actor, fixed_t flyspeed, fixed_t targetdist, fixed_t chasez) +{ + angle_t vertangle; + + flyspeed = FixedMul(flyspeed, actor->scale); + actor->flags |= MF_NOGRAVITY; + + var1 = ANG30; + var2 = 32*FRACUNIT; + A_FlickyAim(actor); + + chasez *= 8; + if (!actor->target || !(actor->fuse > 2*TICRATE)) + chasez += ((actor->eflags & MFE_VERTICALFLIP) ? actor->ceilingz - 24*FRACUNIT : actor->floorz + 24*FRACUNIT); + else + { + fixed_t add = actor->target->z + (actor->target->height - actor->height)/2; + if (add > (actor->ceilingz - 24*actor->scale - actor->height)) + add = actor->ceilingz - 24*actor->scale - actor->height; + else if (add < (actor->floorz + 24*actor->scale)) + add = actor->floorz + 24*actor->scale; + chasez += add; + } + + if (!targetdist) + targetdist = 16*FRACUNIT; //Default! + + if (actor->target && abs(chasez - actor->z) > targetdist) + targetdist = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y); + + if (actor->target + && P_IsFlickyCenter(actor->target->type) + && (actor->target->flags & MF_SLIDEME)) + vertangle = 0; + else + vertangle = (R_PointToAngle2(0, actor->z, targetdist, chasez) >> ANGLETOFINESHIFT) & FINEMASK; + + P_InstaThrust(actor, actor->angle, FixedMul(FINECOSINE(vertangle), flyspeed)); + actor->momz = FixedMul(FINESINE(vertangle), flyspeed); +} + +// Function: A_FlickyFly +// +// Description: Flicky flying function. +// +// var1 = how fast to fly +// var2 = how far ahead the target should be considered +// +void A_FlickyFly(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_FlickyFly", actor)) + return; +#endif + P_InternalFlickyFly(actor, locvar1, locvar2, + FINECOSINE((((actor->fuse % 36) * ANG10) >> ANGLETOFINESHIFT) & FINEMASK) + ); +} + +// Function: A_FlickySoar +// +// Description: Flicky soaring function - specific to puffin. +// +// var1 = how fast to fly +// var2 = how far ahead the target should be considered +// +void A_FlickySoar(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_FlickySoar", actor)) + return; +#endif + P_InternalFlickyFly(actor, locvar1, locvar2, + 2*(FRACUNIT/2 - abs(FINECOSINE((((actor->fuse % 144) * 5*ANG1/2) >> ANGLETOFINESHIFT) & FINEMASK))) + ); + + if (P_MobjFlip(actor)*actor->momz > 0 && actor->frame == 1 && actor->sprite == SPR_FL10) + actor->frame = 3; +} + +//Function: A_FlickyCoast +// +// Description: Flicky swim-coasting function. +// +// var1 = speed to change state upon reaching +// var2 = state to change to upon slowing down +// the spawnstate of the mobj = state to change to when above water +// +void A_FlickyCoast(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_FlickyCoast", actor)) + return; +#endif + if (actor->eflags & MFE_UNDERWATER) + { + actor->momx = (11*actor->momx)/12; + actor->momy = (11*actor->momy)/12; + actor->momz = (11*actor->momz)/12; + + if (P_AproxDistance(P_AproxDistance(actor->momx, actor->momy), actor->momz) < locvar1) + P_SetMobjState(actor, locvar2); + + return; + } + + actor->flags &= ~MF_NOGRAVITY; + P_SetMobjState(actor, mobjinfo[actor->type].spawnstate); +} + +// Internal Flicky hopping function. +void P_InternalFlickyHop(mobj_t *actor, fixed_t momz, fixed_t momh, angle_t angle) +{ + if (((!(actor->eflags & MFE_VERTICALFLIP) && actor->z <= actor->floorz) + || ((actor->eflags & MFE_VERTICALFLIP) && actor->z + actor->height >= actor->ceilingz))) + { + if (momz) + { + if (actor->eflags & MFE_UNDERWATER) + momz = FixedDiv(momz, FixedSqrt(3*FRACUNIT)); + P_SetObjectMomZ(actor, momz, false); + } + P_InstaThrust(actor, angle, FixedMul(momh, actor->scale)); + } +} + +// Function: A_FlickyHop +// +// Description: Flicky hopping function. +// +// var1 = vertical thrust +// var2 = horizontal thrust +// +void A_FlickyHop(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_FlickyHop", actor)) + return; +#endif + P_InternalFlickyHop(actor, locvar1, locvar2, actor->angle); +} + +// Function: A_FlickyFlounder +// +// Description: Flicky floundering function. +// +// var1 = intended vertical thrust +// var2 = intended horizontal thrust +// +void A_FlickyFlounder(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + angle_t hopangle; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_FlickyFlounder", actor)) + return; +#endif + locvar1 *= (P_RandomKey(2) + 1); + locvar2 *= (P_RandomKey(2) + 1); + hopangle = (actor->angle + (P_RandomKey(9) - 4)*ANG2); + P_InternalFlickyHop(actor, locvar1, locvar2, hopangle); +} + +// Function: A_FlickyCheck +// +// Description: Flicky airtime check function. +// +// var1 = state to change to upon touching the floor +// var2 = state to change to upon falling +// the meleestate of the mobj = state to change to when underwater +// +void A_FlickyCheck(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_FlickyCheck", actor)) + return; +#endif + if (actor->target + && P_IsFlickyCenter(actor->target->type) + && (actor->target->flags & MF_GRENADEBOUNCE)) + { + if (!(actor->target->flags & MF_NOCLIPTHING)) // no hopping + { + actor->momz = 0; + actor->flags |= MF_NOGRAVITY; + } + actor->flags |= MF_NOCLIP | MF_NOBLOCKMAP | MF_SCENERY; + P_SetMobjState(actor, mobjinfo[actor->type].seestate); + } + else if (locvar2 && P_MobjFlip(actor)*actor->momz < 1) + P_SetMobjState(actor, locvar2); + else if (locvar1 && ((!(actor->eflags & MFE_VERTICALFLIP) && actor->z <= actor->floorz) + || ((actor->eflags & MFE_VERTICALFLIP) && actor->z + actor->height >= actor->ceilingz))) + P_SetMobjState(actor, locvar1); + else if (mobjinfo[actor->type].meleestate && (actor->eflags & MFE_UNDERWATER)) + P_SetMobjState(actor, mobjinfo[actor->type].meleestate); + P_InternalFlickyBubble(actor); +} + +// Function: A_FlickyHeightCheck +// +// Description: Flicky height check function. +// +// var1 = state to change to when falling below height relative to target +// var2 = height relative to target to change state at +// +void A_FlickyHeightCheck(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_FlickyHeightCheck", actor)) + return; +#endif + if (actor->target + && P_IsFlickyCenter(actor->target->type) + && (actor->target->flags & MF_GRENADEBOUNCE)) + { + if (!(actor->target->flags & MF_NOCLIPTHING)) // no hopping + { + actor->momz = 0; + actor->flags |= MF_NOGRAVITY; + } + actor->flags |= MF_NOCLIP | MF_NOBLOCKMAP | MF_SCENERY; + P_SetMobjState(actor, mobjinfo[actor->type].seestate); + } + else if (locvar1 && actor->target && P_MobjFlip(actor)*actor->momz < 1 + && ((P_MobjFlip(actor)*((actor->z + actor->height/2) - (actor->target->z + actor->target->height/2)) < locvar2) + || (actor->z - actor->height < actor->floorz) || (actor->z + 2*actor->height > actor->ceilingz))) + P_SetMobjState(actor, locvar1); + P_InternalFlickyBubble(actor); +} + +// Function: A_FlickyFlutter +// +// Description: Flicky fluttering function - specific to chicken. +// +// var1 = state to change to upon touching the floor +// var2 = state to change to upon falling +// the meleestate of the mobj = state to change to when underwater +// +void A_FlickyFlutter(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_FlickyFlutter", actor)) + return; +#endif + var1 = locvar1; + var2 = locvar2; + A_FlickyCheck(actor); + + var1 = ANG30; + var2 = 32*FRACUNIT; + A_FlickyAim(actor); + + P_InstaThrust(actor, actor->angle, 2*actor->scale); + if (P_MobjFlip(actor)*actor->momz < -FRACUNIT/2) + actor->momz = -P_MobjFlip(actor)*actor->scale/2; +} + +#undef FLICKYHITWALL + +// Function: A_FlameParticle +// +// Description: Creates the mobj's painchance at a random position around the object's radius. +// +// var1 = unused +// var2 = unused +// +void A_FlameParticle(mobj_t *actor) +{ + mobjtype_t type = (mobjtype_t)(mobjinfo[actor->type].painchance); + fixed_t rad, hei; + mobj_t *particle; + //INT32 locvar1 = var1; + //INT32 locvar2 = var2; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_FlameParticle", actor)) + return; +#endif + + if (!type) + return; + + rad = actor->radius>>FRACBITS; + hei = actor->height>>FRACBITS; + particle = P_SpawnMobjFromMobj(actor, + P_RandomRange(rad, -rad)<<FRACBITS, + P_RandomRange(rad, -rad)<<FRACBITS, + P_RandomRange(hei/2, hei)<<FRACBITS, + type); + P_SetObjectMomZ(particle, 2<<FRACBITS, false); +} + +// Function: A_FadeOverlay +// +// Description: Makes a pretty overlay (primarily for super/NiGHTS transformation). +// +// var1 = bit 1 = bit 1 = don't make fast, bit 2 = don't set tracer +// var2 = unused +// +void A_FadeOverlay(mobj_t *actor) +{ + mobj_t *fade; + INT32 locvar1 = var1; + //INT32 locvar2 = var2; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_FadeOverlay", actor)) + return; +#endif + + fade = P_SpawnGhostMobj(actor); + fade->frame = actor->frame; + + if (!(locvar1 & 1)) + { + fade->fuse = 15; + fade->flags2 |= MF2_BOSSNOTRAP; + } + else + fade->fuse = 20; + + if (!(locvar1 & 2)) + P_SetTarget(&actor->tracer, fade); +} + +// Function: A_Boss5Jump +// +// Description: Makes an object jump in an arc to land on their tracer precicely. +// Adapted from A_BrakLobShot, see there for explanation. +// +// var1 = unused +// var2 = unused +// +void A_Boss5Jump(mobj_t *actor) +{ + fixed_t v; // Velocity to jump at + fixed_t a1, a2, aToUse; // Velocity squared + fixed_t g; // Gravity + fixed_t x; // Horizontal difference + INT32 x_int; // x! But in integer form! + fixed_t y; // Vertical difference (yes that's normally z in SRB2 shut up) + INT32 y_int; // y! But in integer form! + INT32 intHypotenuse; // x^2 + y^2. Frequently overflows fixed point, hence why we need integers proper. + fixed_t fixedHypotenuse; // However, we can work around that and still get a fixed-point number. + angle_t theta; // Angle of attack + // INT32 locvar1 = var1; + // INT32 locvar2 = var2; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Boss5Jump", actor)) + return; +#endif + + if (!actor->tracer) + return; // Don't even bother if we've got nothing to aim at. + + // Look up actor's current gravity situation + if (actor->subsector->sector->gravity) + g = FixedMul(gravity,(FixedDiv(*actor->subsector->sector->gravity>>FRACBITS, 1000))); + else + g = gravity; + + // Look up distance between actor and its tracer + x = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y); + // Look up height difference between actor and its tracer + y = actor->tracer->z - actor->z; + + // Get x^2 + y^2. Have to do it in a roundabout manner, because this overflows fixed_t way too easily otherwise. + x_int = x>>FRACBITS; + y_int = y>>FRACBITS; + intHypotenuse = (x_int*x_int) + (y_int*y_int); + fixedHypotenuse = FixedSqrt(intHypotenuse) *256; + + // a = g(y+/-sqrt(x^2+y^2)). a1 can be +, a2 can be -. + a1 = FixedMul(g,y+fixedHypotenuse); + a2 = FixedMul(g,y-fixedHypotenuse); + + // Determine which one isn't actually an imaginary number (or the smaller of the two, if both are real), and use that for v. + if (a1 < 0 || a2 < 0) + { + if (a1 < 0 && a2 < 0) + { + //Somehow, v^2 is negative in both cases. v is therefore imaginary and something is horribly wrong. Abort! + return; + } + // Just find which one's NOT negative, and use that + aToUse = max(a1,a2); + } + else + { + // Both are positive; use whichever's smaller so it can decay faster + aToUse = min(a1,a2); + } + v = FixedSqrt(aToUse); + // Okay, so we know the velocity. Let's actually find theta. + // We can cut the "+/- sqrt" part out entirely, since v was calculated specifically for it to equal zero. So: + //theta = tantoangle[FixedDiv(aToUse,FixedMul(g,x)) >> DBITS]; + theta = tantoangle[SlopeDiv(aToUse,FixedMul(g,x))]; + + // Okay, complicated math done. Let's make this object jump already. + A_FaceTracer(actor); + + if (actor->eflags & MFE_VERTICALFLIP) + actor->z--; + else + actor->z++; + + // Horizontal axes first. First parameter is initial horizontal impulse, second is to correct its angle. + fixedHypotenuse = FixedMul(v, FINECOSINE(theta >> ANGLETOFINESHIFT)); // variable reuse + actor->momx = FixedMul(fixedHypotenuse, FINECOSINE(actor->angle >> ANGLETOFINESHIFT)); + actor->momy = FixedMul(fixedHypotenuse, FINESINE(actor->angle >> ANGLETOFINESHIFT)); + // Then the vertical axis. No angle-correction needed here. + actor->momz = FixedMul(v, FINESINE(theta >> ANGLETOFINESHIFT)); + // I hope that's all that's needed, ugh +} + +// Function: A_LightBeamReset +// Description: Resets momentum and position for DSZ's projecting light beams +// +// var1 = unused +// var2 = unused +// +void A_LightBeamReset(mobj_t *actor) +{ + // INT32 locvar1 = var1; + // INT32 locvar2 = var2; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_LightBeamReset", actor)) + return; +#endif + + actor->destscale = FRACUNIT + P_SignedRandom()*FRACUNIT/256; + P_SetScale(actor, actor->destscale); + + if (!actor->spawnpoint) + return; // this can't work properly welp + + actor->momx = -(P_SignedRandom()*FINESINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/128; + actor->momy = (P_SignedRandom()*FINECOSINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/128; + actor->momz = (P_SignedRandom()*FRACUNIT)/128; + + P_TeleportMove(actor, + actor->spawnpoint->x*FRACUNIT - (P_SignedRandom()*FINESINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/2, + actor->spawnpoint->y*FRACUNIT + (P_SignedRandom()*FINECOSINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/2, + actor->spawnpoint->z*FRACUNIT + (P_SignedRandom()*FRACUNIT)/2); +} + +// Function: A_MineExplode +// Description: Handles the explosion of a DSZ mine. +// +// var1 = unused +// var2 = unused +// +void A_MineExplode(mobj_t *actor) +{ + // INT32 locvar1 = var1; + // INT32 locvar2 = var2; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_MineExplode", actor)) + return; +#endif + + A_Scream(actor); + actor->flags = MF_NOGRAVITY|MF_NOCLIP; + + quake.epicenter = NULL; + quake.radius = 512*FRACUNIT; + quake.intensity = 8*FRACUNIT; + quake.time = TICRATE/3; + + P_RadiusAttack(actor, actor->tracer, 192*FRACUNIT, DMG_CANHURTSELF); + P_MobjCheckWater(actor); + + { +#define dist 64 + UINT8 i; + mobjtype_t type = ((actor->eflags & MFE_UNDERWATER) ? MT_UWEXPLODE : MT_BOSSEXPLODE); + S_StartSound(actor, ((actor->eflags & MFE_UNDERWATER) ? sfx_s3k57 : sfx_s3k4e)); + P_SpawnMobj(actor->x, actor->y, actor->z, type); + for (i = 0; i < 16; i++) + { + mobj_t *b = P_SpawnMobj(actor->x+P_RandomRange(-dist, dist)*FRACUNIT, + actor->y+P_RandomRange(-dist, dist)*FRACUNIT, + actor->z+P_RandomRange(((actor->eflags & MFE_UNDERWATER) ? -dist : 0), dist)*FRACUNIT, + type); + fixed_t dx = b->x - actor->x, dy = b->y - actor->y, dz = b->z - actor->z; + fixed_t dm = P_AproxDistance(dz, P_AproxDistance(dy, dx)); + b->momx = FixedDiv(dx, dm)*3; + b->momy = FixedDiv(dy, dm)*3; + b->momz = FixedDiv(dz, dm)*3; + if ((actor->watertop == INT32_MAX) || (b->z + b->height > actor->watertop)) + b->flags &= ~MF_NOGRAVITY; + } +#undef dist + + if (actor->watertop != INT32_MAX) + P_SpawnMobj(actor->x, actor->y, actor->watertop, MT_SPLISH); + } +} + +// Function: A_MineRange +// Description: If the target gets too close, change the state to meleestate. +// +// var1 = Distance to alert at +// var2 = unused +// +void A_MineRange(mobj_t *actor) +{ + fixed_t dm; + INT32 locvar1 = var1; + // INT32 locvar2 = var2; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_MineRange", actor)) + return; +#endif + + if (!actor->target) + return; + + dm = P_AproxDistance(actor->z - actor->target->z, P_AproxDistance(actor->y - actor->target->y, actor->x - actor->target->x)); + if ((dm>>FRACBITS) < locvar1) + P_SetMobjState(actor, actor->info->meleestate); +} + +// Function: A_ConnectToGround +// Description: Create a palm tree trunk/mine chain. +// +// var1 = Object type to connect to ground +// var2 = Object type to place on ground +// +void A_ConnectToGround(mobj_t *actor) +{ + mobj_t *work; + fixed_t workz; + fixed_t workh; + SINT8 dir; + angle_t ang; + INT32 locvar1 = var1; + INT32 locvar2 = var2; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_ConnectToGround", actor)) + return; +#endif + + if (actor->subsector->sector->ffloors) + P_AdjustMobjFloorZ_FFloors(actor, actor->subsector->sector, 2); + + if (actor->flags2 & MF2_OBJECTFLIP) + { + workz = actor->ceilingz - (actor->z + actor->height); + dir = -1; + } + else + { + workz = actor->floorz - actor->z; + dir = 1; + } + + 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 += dir*workh; + } + + if (!locvar1) + return; + + if (!(workh = FixedMul(mobjinfo[locvar1].height, actor->scale))) + return; + + if (actor->flags2 & MF2_OBJECTFLIP) + workz -= workh; + + ang = actor->angle + ANGLE_45; + while (dir*workz < 0) + { + work = P_SpawnMobjFromMobj(actor, 0, 0, workz, locvar1); + if (work) + work->angle = ang; + ang += ANGLE_90; + workz += dir*workh; + } + + if (workz != 0) + actor->z += workz; +} + +// Function: A_SpawnParticleRelative +// +// Description: Spawns a particle effect relative to the location of the actor +// +// var1: +// var1 >> 16 = x +// var1 & 65535 = y +// var2: +// var2 >> 16 = z +// var2 & 65535 = state +// +void A_SpawnParticleRelative(mobj_t *actor) +{ + INT16 x, y, z; // Want to be sure we can use negative values + statenum_t state; + mobj_t *mo; + INT32 locvar1 = var1; + INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_SpawnParticleRelative", actor)) + return; +#endif + + CONS_Debug(DBG_GAMELOGIC, "A_SpawnParticleRelative called from object type %d, var1: %d, var2: %d\n", actor->type, locvar1, locvar2); + + x = (INT16)(locvar1>>16); + y = (INT16)(locvar1&65535); + z = (INT16)(locvar2>>16); + state = (statenum_t)(locvar2&65535); + + // Spawn objects correctly in reverse gravity. + // NOTE: Doing actor->z + actor->height is the bottom of the object while the object has reverse gravity. - Flame + mo = P_SpawnMobj(actor->x + FixedMul(x<<FRACBITS, actor->scale), + actor->y + FixedMul(y<<FRACBITS, actor->scale), + (actor->eflags & MFE_VERTICALFLIP) ? ((actor->z + actor->height - mobjinfo[MT_PARTICLE].height) - FixedMul(z<<FRACBITS, actor->scale)) : (actor->z + FixedMul(z<<FRACBITS, actor->scale)), MT_PARTICLE); + + // Spawn objects with an angle matching the spawner's, rather than spawning Eastwards - Monster Iestyn + mo->angle = actor->angle; + + if (actor->eflags & MFE_VERTICALFLIP) + mo->flags2 |= MF2_OBJECTFLIP; + + P_SetMobjState(mo, state); +} + +// Function: A_MultiShotDist +// +// Description: Spawns multiple shots based on player proximity +// +// var1 = same as A_MultiShot +// var2 = same as A_MultiShot +// +void A_MultiShotDist(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_MultiShotDist", actor)) + return; +#endif + + { + UINT8 i; + // Quick! Look through players! + // Don't spawn dust unless a player is relatively close by (var1). + for (i = 0; i < MAXPLAYERS; ++i) + if (playeringame[i] && players[i].mo + && P_AproxDistance(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (1600<<FRACBITS)) + break; // Stop looking. + if (i == MAXPLAYERS) + return; // don't make bubble! + } + + var1 = locvar1; + var2 = locvar2; + A_MultiShot(actor); +} + +// Function: A_WhoCaresIfYourSonIsABee +// +// Description: Makes a child object, storing the number of created children in the parent's extravalue1. +// +// var1 = mobjtype of child +// var2 >> 16 = mobjtype of child +// var2 & 65535 = vertical momentum +// var2: +// var2 >> 16 = forward offset +// var2 & 65535 = vertical offset +// +void A_WhoCaresIfYourSonIsABee(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + fixed_t foffsetx; + fixed_t foffsety; + mobj_t *son; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_WhoCaresIfYourSonIsABee", actor)) + return; +#endif + + A_FaceTarget(actor); + + if (actor->extravalue1) + actor->extravalue1--; + + if (actor->info->attacksound) + S_StartSound(actor, actor->info->attacksound); + + foffsetx = P_ReturnThrustX(actor, actor->angle, FixedMul((locvar2 >> 16)*FRACUNIT, actor->scale)); + foffsety = P_ReturnThrustY(actor, actor->angle, FixedMul((locvar2 >> 16)*FRACUNIT, actor->scale)); + + if (!(son = P_SpawnMobjFromMobj(actor, foffsetx, foffsety, (locvar2&65535)*FRACUNIT, (mobjtype_t)(locvar1 >> 16)))) + return; + + P_SetObjectMomZ(son, (locvar1 & 65535)<<FRACBITS, true); + + P_SetTarget(&son->tracer, actor); + P_SetTarget(&son->target, actor->target); +} + +// Function: A_ParentTriesToSleep +// +// Description: If extravalue1 is less than or equal to var1, go to var2. +// +// var1 = state to go to when extravalue1 +// var2 = unused +// +void A_ParentTriesToSleep(mobj_t *actor) +{ + INT32 locvar1 = var1; + //INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_ParentTriesToSleep", actor)) + return; +#endif + + if (actor->extravalue1) + { + if (actor->info->seesound) + S_StartSound(actor, actor->info->seesound); + actor->reactiontime = 0; + P_SetMobjState(actor, locvar1); + } + else if (!actor->reactiontime) + { + actor->reactiontime = 1; + if (actor->info->activesound) // more like INactivesound doy hoy hoy + S_StartSound(actor, actor->info->activesound); + } +} + + +// Function: A_CryingToMomma +// +// Description: If you're a child, let your parent know something's happened to you through extravalue1. Also, prepare to die. +// +// var1 = unused +// var2 = unused +// +void A_CryingToMomma(mobj_t *actor) +{ + //INT32 locvar1 = var1; + //INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_CryingToMomma", actor)) + return; +#endif + + if (actor->tracer) + actor->tracer->extravalue1++; + + actor->momx = actor->momy = actor->momz = 0; + + P_UnsetThingPosition(actor); + if (sector_list) + { + P_DelSeclist(sector_list); + sector_list = NULL; + } + actor->flags = MF_NOBLOCKMAP|MF_NOCLIPTHING; + P_SetThingPosition(actor); +} + +// Function: A_CheckFlags2 +// +// Description: If actor->flags2 & var1, goto var2. +// +// var1 = mask +// var2 = state to go +// +void A_CheckFlags2(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_CheckFlags2", actor)) + return; +#endif + + if (actor->flags2 & locvar1) + P_SetMobjState(actor, (statenum_t)locvar2); +} + +// Function: A_Boss5FindWaypoint +// +// Description: Finds the next waypoint in sequence and sets it as its tracer. +// +// var1 = if 1, always go to ambush-marked waypoint. if 2, go to MT_BOSSFLYPOINT. +// var2 = unused +// +void A_Boss5FindWaypoint(mobj_t *actor) +{ + INT32 locvar1 = var1; + //INT32 locvar2 = var2; + boolean avoidcenter; + UINT32 i; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Boss5FindWaypoint", actor)) + return; +#endif + + avoidcenter = !actor->tracer || (actor->health == actor->info->damage+1); + + if (locvar1 == 2) // look for the boss waypoint + { + for (i = 0; i < nummapthings; i++) + { + if (!mapthings[i].mobj) + continue; + if (mapthings[i].mobj->type != MT_BOSSFLYPOINT) + continue; + P_SetTarget(&actor->tracer, mapthings[i].mobj); + break; + } + if (i == nummapthings) + return; // no boss flypoints found + } + else if (locvar1 == 1) // always go to ambush-marked waypoint + { + if (avoidcenter) + goto nowaypoints; // if we can't go the center, why on earth are we doing this? + + for (i = 0; i < nummapthings; i++) + { + if (!mapthings[i].mobj) + continue; + if (mapthings[i].mobj->type != MT_FANGWAYPOINT) + continue; + if (mapthings[i].options & MTF_AMBUSH) + { + P_SetTarget(&actor->tracer, mapthings[i].mobj); + break; + } + } + + if (i == nummapthings) + goto nowaypoints; + } + else // locvar1 == 0 + { + fixed_t hackoffset = P_MobjFlip(actor)*56*FRACUNIT; + INT32 numwaypoints = 0; + mobj_t **waypoints; + INT32 key; + + actor->z += hackoffset; + + // first, count how many waypoints we have + for (i = 0; i < nummapthings; i++) + { + if (!mapthings[i].mobj) + continue; + if (mapthings[i].mobj->type != MT_FANGWAYPOINT) + continue; + if (actor->tracer == mapthings[i].mobj) // this was your tracer last time + continue; + if (mapthings[i].options & MTF_AMBUSH) + { + if (avoidcenter) + continue; + } + else if (mapthings[i].mobj->reactiontime > 0) + continue; + if (!P_CheckSight(actor, mapthings[i].mobj)) + continue; + numwaypoints++; + } + + // players also count as waypoints apparently + if (actor->extravalue2 > 1) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + if (!players[i].mo) + continue; + if (players[i].spectator) + continue; + if (players[i].mo->health <= 0) + continue; + if (players[i].powers[pw_flashing]) + continue; + if (actor->tracer == players[i].mo) // this was your tracer last time + continue; + if (!P_CheckSight(actor, players[i].mo)) + continue; + numwaypoints++; + } + } + + if (!numwaypoints) + { + // restore z position + actor->z -= hackoffset; + goto nowaypoints; // no waypoints :( + } + + // allocate the table and reset count to zero + waypoints = Z_Calloc(sizeof(*waypoints)*numwaypoints, PU_STATIC, NULL); + numwaypoints = 0; + + // now find them again and add them to the table! + for (i = 0; i < nummapthings; i++) + { + if (!mapthings[i].mobj) + continue; + if (mapthings[i].mobj->type != MT_FANGWAYPOINT) + continue; + if (actor->tracer == mapthings[i].mobj) // this was your tracer last time + continue; + if (mapthings[i].options & MTF_AMBUSH) + { + if (avoidcenter) + continue; + } + else if (mapthings[i].mobj->reactiontime > 0) + { + mapthings[i].mobj->reactiontime--; + continue; + } + if (!P_CheckSight(actor, mapthings[i].mobj)) + continue; + waypoints[numwaypoints++] = mapthings[i].mobj; + } + + if (actor->extravalue2 > 1) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + if (!players[i].mo) + continue; + if (players[i].spectator) + continue; + if (players[i].mo->health <= 0) + continue; + if (players[i].powers[pw_flashing]) + continue; + if (actor->tracer == players[i].mo) // this was your tracer last time + continue; + if (!P_CheckSight(actor, players[i].mo)) + continue; + waypoints[numwaypoints++] = players[i].mo; + } + } + + // restore z position + actor->z -= hackoffset; + + if (!numwaypoints) + { + Z_Free(waypoints); // free table + goto nowaypoints; // ??? + } + + key = P_RandomKey(numwaypoints); + + P_SetTarget(&actor->tracer, waypoints[key]); + if (actor->tracer->type == MT_FANGWAYPOINT) + actor->tracer->reactiontime = numwaypoints/4; // Monster Iestyn: is this how it should be? I count center waypoints as waypoints unlike the original Lua script + Z_Free(waypoints); // free table + } + + // now face the tracer you just set! + A_FaceTracer(actor); + return; + +nowaypoints: + // no waypoints at all, guess the mobj has to disappear + if (actor->health) + P_KillMobj(actor, NULL, NULL, 0); + else + P_RemoveMobj(actor); + return; +} + +// Function: A_DoNPCSkid +// +// Description: Something that looks like a player is skidding. +// +// var1 = state to change to upon being slow enough +// var2 = minimum speed +// +void A_DoNPCSkid(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + fixed_t x, y, z; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_DoNPCSkid", actor)) + return; +#endif + + x = actor->x; + y = actor->y; + z = actor->z; + + if (!locvar2) + locvar2 = FRACUNIT/2; + + if ((FixedHypot(actor->momx, actor->momy) < locvar2) + || !P_TryMove(actor, actor->x + actor->momx, actor->y + actor->momy, false)) + { + actor->momx = actor->momy = 0; + P_SetMobjState(actor, locvar1); + return; + } + else + { + actor->momx = (2*actor->momx)/3; + actor->momy = (2*actor->momy)/3; + } + + P_TeleportMove(actor, x, y, z); + + // Spawn a particle every 3 tics. + if (!(leveltime % 3)) + { + mobj_t *particle = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_SPINDUST); + particle->tics = 10; + + P_SetScale(particle, 2*actor->scale/3); + particle->destscale = actor->scale; + P_SetObjectMomZ(particle, FRACUNIT, false); + } +} + +// Function: A_DoNPCPain +// +// Description: Something that looks like a player was hit, put them in pain. +// +// var1 = If zero, always fling the same amount. +// Otherwise, slowly reduce the vertical +// and horizontal speed to the base value +// multiplied by this the more damage is done. +// var2 = If zero, use default fling values. +// Otherwise, vertical and horizontal speed +// will be multiplied by this. +// +void A_DoNPCPain(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + fixed_t vspeed = 0; + fixed_t hspeed = FixedMul(4*FRACUNIT, actor->scale); +#ifdef HAVE_BLUA + if (LUA_CallAction("A_DoNPCPain", actor)) + return; +#endif + + actor->flags &= ~(MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT); + + var1 = var2 = 0; + A_Pain(actor); + + actor->z += P_MobjFlip(actor); + + if (actor->eflags & MFE_UNDERWATER) + vspeed = FixedDiv(10511*FRACUNIT,2600*FRACUNIT); + else + vspeed = FixedDiv(69*FRACUNIT,10*FRACUNIT); + + if (actor->target) + actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x + actor->target->momx, actor->target->y + actor->target->momy); + + if (locvar1) + { + if (!actor->info->spawnhealth) + return; // there's something very wrong here if you're using this action on something with no starting health + locvar1 += ((FRACUNIT - locvar1)/actor->info->spawnhealth)*actor->health; + hspeed = FixedMul(hspeed, locvar1); + vspeed = FixedMul(vspeed, locvar1); + } + + if (locvar2) + { + hspeed = FixedMul(hspeed, locvar2); + vspeed = FixedMul(vspeed, locvar2); + } + + P_SetObjectMomZ(actor, vspeed, false); + P_InstaThrust(actor, actor->angle, -hspeed); +} + +// Function: A_PrepareRepeat +// +// Description: Simple way to prepare A_Repeat. +// +// var1 = value to set extravalue2 to +// var2 = unused +// +void A_PrepareRepeat(mobj_t *actor) +{ + INT32 locvar1 = var1; + //INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_PrepareRepeat", actor)) + return; +#endif + + actor->extravalue2 = locvar1; +} + +// Function: A_Boss5ExtraRepeat +// +// Description: Simple way to prepare A_Repeat. +// +// var1 = maximum value to setextravalue2 to (normally) +// var2 = pinch annoyance +// +void A_Boss5ExtraRepeat(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + INT32 calc; + INT32 locspawn; + INT32 lochealth; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Boss5ExtraRepeat", actor)) + return; +#endif + + if (actor->extravalue2 > 0 && !(actor->flags2 & MF2_FRET)) + return; + + locspawn = actor->info->spawnhealth - actor->info->damage; + lochealth = actor->health - actor->info->damage; + + if (locspawn <= 0 || lochealth <= 0) + calc = locvar1; + else + calc = (locvar1*(locspawn - lochealth))/locspawn; + + if (calc > 2) + actor->extravalue2 = 1 + calc/2 + P_RandomKey(calc/2); + else + actor->extravalue2 = 1 + calc; + + if (lochealth <= 0) + actor->extravalue2 += locvar2; +} + +// Function: A_Boss5Calm +// +// Description: Simple way to disable MF2_FRET (and enable MF_SHOOTABLE the first time it's called) +// +// var1 = unused +// var2 = unused +// +void A_Boss5Calm(mobj_t *actor) +{ +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Boss5Calm", actor)) + return; +#endif + actor->flags |= MF_SHOOTABLE; + actor->flags2 &= ~MF2_FRET; +} + +// Function: A_Boss5CheckOnGround +// +// Description: Ground checker. +// +// var1 = state to change to upon hitting ground. +// var2 = state to change to upon hitting ground if health == pinchhealth, assuming it exists +// +void A_Boss5CheckOnGround(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Boss5CheckOnGround", actor)) + return; +#endif + + if ((!(actor->eflags & MFE_VERTICALFLIP) && actor->z <= actor->floorz) + || (actor->eflags & MFE_VERTICALFLIP && actor->z + actor->height >= actor->ceilingz)) + { + if (locvar2 && (!actor->health || (actor->health == actor->info->damage && !(actor->flags2 & MF2_STRONGBOX)))) + P_SetMobjState(actor, locvar2); + else + P_SetMobjState(actor, locvar1); + } + + if (actor->tracer && P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y) < 2*actor->radius) + { + actor->momx = (4*actor->momx)/5; + actor->momy = (4*actor->momy)/5; + } +} + +// Function: A_Boss5CheckFalling +// +// Description: Falling checker. +// +// var1 = state to change to when hitting ground. +// var2 = state to change to when falling. +// +void A_Boss5CheckFalling(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Boss5CheckFalling", actor)) + return; +#endif + + if (actor->health && actor->extravalue2 > 1) + { + var1 = locvar1; + var2 = 0; + A_Boss5CheckOnGround(actor); + return; + } + + if (P_MobjFlip(actor)*actor->momz <= 0) + P_SetMobjState(actor, locvar2); +} + +// Function: A_Boss5PinchShot +// +// Description: Fires a missile directly upwards if in pinch. +// +// var1 = object # to shoot +// var2 = height offset (from default of +48 FU) +// +void A_Boss5PinchShot(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + fixed_t zoffset; + mobj_t *missile; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Boss5PinchShot", actor)) + return; +#endif + + if (actor->health > actor->info->damage) + return; + + if (actor->eflags & MFE_VERTICALFLIP) + zoffset = actor->z + actor->height - FixedMul((48 + locvar2)*FRACUNIT, actor->scale); + else + zoffset = actor->z + FixedMul((48 + locvar2)*FRACUNIT, actor->scale); + + missile = P_SpawnPointMissile(actor, actor->x, actor->y, zoffset, locvar1, + actor->x, actor->y, zoffset); + + if (!missile) + return; + + missile->momx = missile->momy = 0; + missile->momz = P_MobjFlip(actor)*missile->info->speed/2; +} + +// Function: A_Boss5MakeItRain +// +// Description: Pinch crisis. +// +// var1 = object # to shoot +// var2 = height offset (from default of +48 FU) +// +void A_Boss5MakeItRain(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + INT32 offset = (48 + locvar2)<<16; // upper 16 bits, not fixed_t! + INT32 i; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Boss5MakeItRain", actor)) + return; +#endif + + actor->flags2 |= MF2_STRONGBOX; + + var1 = locvar1; + var2 = offset + 90; + A_TrapShot(actor); + + for (i = 0; i < 8; i++) + { + actor->angle += ANGLE_45; + + var1 = locvar1; + var2 = offset + (i & 1) ? 80 : 85; + A_TrapShot(actor); + } + + actor->extravalue2 = 0; +} + +// Function: A_LookForBetter +// +// Description: A_Look, except it finds a better target in multiplayer, and doesn't lose the target in singleplayer. +// +// var1 lower 16 bits = 0 - looks only in front, 1 - looks all around +// var1 upper 16 bits = distance limit +// var2 = unused +// +void A_LookForBetter(mobj_t *actor) +{ + INT32 locvar1 = var1; + //INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_LookForBetter", actor)) + return; +#endif + + P_LookForPlayers(actor, (locvar1 & 65535), false, FixedMul((locvar1 >> 16)*FRACUNIT, actor->scale)); + A_FaceTarget(actor); +} + +/* * Spawns a dust ring. + * The dust ring behaves slightly randomly so it doesn't look too uniform. + * + * \param mobjtype Thing type to make a ring of. + * \param div Amount of things to spawn on the ring. + * \param x Center X coordinates. + * \param y Center Y coordinates. + * \param z Center Z coordinates. + * \param radius Radius. + * \param speed Additional thrust on particles. + * \param initscale Initial scale when spawning. + * \param scale "Default" scale. + */ +static void P_DustRing(mobjtype_t mobjtype, UINT32 div, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t speed, fixed_t initscale, fixed_t scale) +{ + angle_t ang = FixedAngle(FixedDiv(360*FRACUNIT, div*FRACUNIT)); //(ANGLE_180/div)*2; + UINT32 i; + + // it turned out the radius was effectively nullified thanks to errors in the original script + // BUT people preferred how it looked before I "fixed" it, so I got rid of the radius calculations altogether + // this was a bit of a mess to sort out, but at least it's probably somewhat fine now? + // -- Monster Iestyn (21/05/19) + (void)radius; + + for (i = 0; i < div; i++) + { + mobj_t *dust = P_SpawnMobj( + x, //+ FixedMul(radius, FINECOSINE((ang*i) >> ANGLETOFINESHIFT)), + y, //+ FixedMul(radius, FINESINE((ang*i) >> ANGLETOFINESHIFT)), + z, + mobjtype + ); + + dust->angle = ang*i + ANGLE_90; + P_SetScale(dust, FixedMul(initscale, scale)); + dust->destscale = FixedMul(4*FRACUNIT + P_RandomFixed(), scale); + dust->scalespeed = scale/24; + P_Thrust(dust, ang*i, speed + FixedMul(P_RandomFixed(), scale)); + dust->momz = P_SignedRandom()*scale/64; + } +} + +// Function: A_Boss5BombExplode +// +// Description: Boss 5's bomb exploding. +// +// var1 = Thing type to spawn as dust +// var2 = unused +// +void A_Boss5BombExplode(mobj_t *actor) +{ + INT32 locvar1 = var1; + //INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Boss5BombExplode", actor)) + return; +#endif + + // The original Lua script did not use |= to add flags but just set these flags exactly apparently? + // (I may modify this later) + // -- Monster Iestyn (21/05/19) + actor->flags = MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP; + actor->flags2 = MF2_EXPLOSION; + + if (actor->target) + P_RadiusAttack(actor, actor->target, 7*actor->radius, 0); + + P_DustRing(locvar1, 4, actor->x, actor->y, actor->z+actor->height, 2*actor->radius, 0, FRACUNIT, actor->scale); + P_DustRing(locvar1, 6, actor->x, actor->y, actor->z+actor->height/2, 3*actor->radius, FRACUNIT, FRACUNIT, actor->scale); + //P_StartQuake(9*actor->scale, TICRATE/6, {actor->x, actor->y, actor->z}, 20*actor->radius); + // the above does not exist, so we set the quake values directly instead + quake.intensity = 9*actor->scale; + quake.time = TICRATE/6; + // the following quake values have no effect atm? ah well, may as well set them anyway + { + mappoint_t q_epicenter = {actor->x, actor->y, actor->z}; + quake.epicenter = &q_epicenter; + } + quake.radius = 20*actor->radius; +} + +static mobj_t *dustdevil; + +static boolean PIT_DustDevilLaunch(mobj_t *thing) +{ + player_t *player = thing->player; + + if (!player) + return true; + + if (abs(thing->x - dustdevil->x) > dustdevil->radius || abs(thing->y - dustdevil->y) > dustdevil->radius) + return true; + + if (thing->z + thing->height >= dustdevil->z && dustdevil->z + dustdevil->height >= thing->z) { + fixed_t pos = thing->z - dustdevil->z; + fixed_t thrust = max(FixedDiv(pos, dustdevil->height) * 20, 8 * FRACUNIT); + angle_t fa = R_PointToAngle2(thing->x, thing->y, dustdevil->x, dustdevil->y) >> ANGLETOFINESHIFT; + fixed_t c = FINECOSINE(fa); + fixed_t s = FINESINE(fa); + fixed_t thresh = dustdevil->scale * 20; + + //Player in the swirl part. + if (dustdevil->height - pos > thresh) + { + fixed_t dist = FixedHypot(thing->x - dustdevil->x, thing->y - dustdevil->y); + fixed_t dragamount = 6 * FRACUNIT; + fixed_t x, y; + + if (player->powers[pw_nocontrol] == 0) + A_PlayActiveSound(dustdevil); + player->powers[pw_nocontrol] = 2; + player->drawangle += ANG20; + P_SetPlayerMobjState(thing, S_PLAY_PAIN); + + if (dist > dragamount) + { + x = thing->x + FixedMul(c, dragamount); + y = thing->y + FixedMul(s, dragamount); + } + else + { + x = dustdevil->x; + y = dustdevil->y; + } + P_TryMove(thing, x - thing->momx, y - thing->momy, true); + } + else + { //Player on the top of the tornado. + thing->z = dustdevil->z + dustdevil->height; + thrust = 20 * FRACUNIT; + player->powers[pw_nocontrol] = 0; + S_StartSound(thing, sfx_wdjump); + P_SetPlayerMobjState(thing, S_PLAY_FALL); + player->pflags &= ~PF_JUMPED; + } + + thing->momz = thrust; + } + + return true; +} + +// Function: A_DustDevilThink +// +// Description: Thinker for the dust devil. +// +// var1 = unused +// var2 = unused +// +void A_DustDevilThink(mobj_t *actor) +{ + fixed_t scale = actor->scale; + mobj_t *layer = actor->tracer; + INT32 bx, by, xl, xh, yl, yh; + fixed_t radius = actor->radius; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_DustDevilThink", actor)) + return; +#endif + + //Chained thinker for the spiralling dust column. + while (layer && !P_MobjWasRemoved(layer)) { + angle_t fa = layer->angle >> ANGLETOFINESHIFT; + P_TeleportMove(layer, layer->x + 5 * FixedMul(scale, FINECOSINE(fa)), layer->y + 5 * FixedMul(scale, FINESINE(fa)), layer->z); + layer->scale = scale; + layer->angle += ANG10 / 2; + layer->momx = actor->momx; + layer->momy = actor->momy; + layer = layer->tracer; + } + + //Spawn random dust around the column on the base. + if (P_IsObjectOnGround(actor)) { + angle_t dustang = ((P_RandomRange(0, 7)*ANGLE_45)>>ANGLETOFINESHIFT) & FINEMASK; + mobj_t *dust = P_SpawnMobj(actor->x + 96 * FixedMul(scale, FINECOSINE(dustang)), actor->y + 96 * FixedMul(scale, FINESINE(dustang)), actor->z, MT_ARIDDUST); + P_SetMobjState(dust, dust->info->spawnstate + P_RandomRange(0, 2)); + dust->destscale = scale * 3; + P_SetScale(dust, dust->destscale); + } + + actor->extravalue1++; + if (actor->extravalue1 == 12) { + size_t i = 0; + actor->extravalue1 = 0; + + //Create a set of items for the rising dust column + for (; i <= 3; i++) { + fixed_t fa = (ANGLE_90*i) >> ANGLETOFINESHIFT; + fixed_t px = actor->x + 70 * FixedMul(scale, FINECOSINE(fa)); + fixed_t py = actor->y + 70 * FixedMul(scale, FINESINE(fa)); + fixed_t pz = actor->z; + + layer = P_SpawnMobj(px, py, pz, MT_DUSTLAYER); + layer->momz = 5 * scale; + layer->angle = ANGLE_90 + ANGLE_90*i; + layer->extravalue1 = TICRATE * 3; + + //Chain them + P_SetTarget(&layer->tracer, actor->tracer); + P_SetTarget(&actor->tracer, layer); + } + } + + //The physics are handled here. + yh = (unsigned)(actor->y + radius - bmaporgy) >> MAPBLOCKSHIFT; + yl = (unsigned)(actor->y - radius - bmaporgy) >> MAPBLOCKSHIFT; + xh = (unsigned)(actor->x + radius - bmaporgx) >> MAPBLOCKSHIFT; + xl = (unsigned)(actor->x - radius - bmaporgx) >> MAPBLOCKSHIFT; + + BMBOUNDFIX(xl, xh, yl, yh); + + dustdevil = actor; + + for (bx = xl; bx <= xh; bx++) + for (by = yl; by <= yh; by++) + P_BlockThingsIterator(bx, by, PIT_DustDevilLaunch); + + //Whirlwind sound effect. + if (leveltime % 70 == 0) + S_StartSound(actor, sfx_s3kcel); +} + +// stuff used by A_TNTExplode +static mobj_t *barrel; +static fixed_t exploderadius; +static fixed_t explodethrust; + +static boolean PIT_TNTExplode(mobj_t *nearby) +{ + fixed_t dx, dy, dz; + fixed_t dm; + + if (nearby == barrel) + return true; + + dx = nearby->x - barrel->x; + dy = nearby->y - barrel->y; + dz = nearby->z - barrel->z + (nearby->height - barrel->height/2)/2; + dm = P_AproxDistance(P_AproxDistance(dx, dy), dz); + + if (dm >= exploderadius || !P_CheckSight(barrel, nearby)) // out of range or not visible + return true; + + if (barrel->type == nearby->type) // nearby is also a barrel + { + if (nearby->state == &states[nearby->info->spawnstate]) + { + if (barrel->info->attacksound) + S_StartSound(nearby, barrel->info->attacksound); + nearby->momx = FixedMul(FixedDiv(dx, dm), explodethrust); + nearby->momy = FixedMul(FixedDiv(dy, dm), explodethrust); + nearby->momz = FixedMul(FixedDiv(dz, dm), explodethrust); + nearby->flags = MF_NOBLOCKMAP|MF_MISSILE; + P_SetMobjState(nearby, nearby->info->missilestate); + } + } + else + { + if (barrel->target == nearby) + { + mobj_t *tar = barrel->target; // temporarily store barrel's target + barrel->target = NULL; + P_DamageMobj(nearby, barrel, NULL, 1, 0); + barrel->target = tar; + } + else + { + P_DamageMobj(nearby, + (barrel->target) ? barrel->target : barrel, + (barrel->target) ? barrel->target : barrel, + 1, 0); + } + } + + return true; +} + +// Function: A_TNTExplode +// +// Description: Creates a TNT explosion. Used by TNT barrels and the like. +// +// var1 = Thing type to spawn as dust. +// var2 = unused +// +void A_TNTExplode(mobj_t *actor) +{ + INT32 locvar1 = var1; + //INT32 locvar2 = var2; + INT32 x, y; + INT32 xl, xh, yl, yh; + static mappoint_t epicenter = {0,0,0}; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_TNTExplode", actor)) + return; +#endif + + actor->flags = MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP; + actor->flags2 = MF2_EXPLOSION; + if (actor->info->deathsound) + S_StartSound(actor, actor->info->deathsound); + + explodethrust = 32*FRACUNIT; + exploderadius = 256*FRACUNIT; + + xl = (unsigned)(actor->x - exploderadius - bmaporgx)>>MAPBLOCKSHIFT; + xh = (unsigned)(actor->x + exploderadius - bmaporgx)>>MAPBLOCKSHIFT; + yl = (unsigned)(actor->y - exploderadius - bmaporgy)>>MAPBLOCKSHIFT; + yh = (unsigned)(actor->y + exploderadius - bmaporgy)>>MAPBLOCKSHIFT; + + BMBOUNDFIX(xl, xh, yl, yh); + + barrel = actor; + + for (x = xl; x <= xh; x++) + for (y = yl; y <= yh; y++) + P_BlockThingsIterator(x, y, PIT_TNTExplode); + + // cause a quake -- P_StartQuake does not exist yet + epicenter.x = actor->x; + epicenter.y = actor->y; + epicenter.z = actor->z; + quake.intensity = 9*FRACUNIT; + quake.time = TICRATE/6; + quake.epicenter = &epicenter; + quake.radius = 512*FRACUNIT; + + if (locvar1) + { + P_DustRing(locvar1, 4, actor->x, actor->y, actor->z+actor->height, 64, 0, FRACUNIT, actor->scale); + P_DustRing(locvar1, 6, actor->x, actor->y, actor->z+actor->height/2, 96, FRACUNIT, FRACUNIT, actor->scale); + } + + actor->destscale *= 4; +} + +// Function: A_DebrisRandom +// +// Description: Randomizes debris frame and movement. +// +// var1 = Frame range. +// var2 = unused +// +void A_DebrisRandom(mobj_t *actor) +{ + INT32 locvar1 = var1; + //INT32 locvar2 = var2; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_DebrisRandom", actor)) + return; +#endif + + actor->frame |= P_RandomRange(0, locvar1); + var1 = 0; + var2 = 359; + A_ChangeAngleAbsolute(actor); + P_Thrust(actor, actor->angle, FRACUNIT * 2); +} + +static mobj_t *P_TrainSeg(mobj_t *src, fixed_t x, fixed_t y, fixed_t z, angle_t ang, spritenum_t spr, UINT32 frame) +{ + mobj_t *s = P_SpawnMobj(x, y, z, MT_TRAINSEG); + s->fuse = 16*TICRATE; + s->sprite = spr; + s->frame = frame|FF_PAPERSPRITE; + s->angle = ang; + P_Thrust(s, src->angle, 7*FRACUNIT); + return s; +} + +// Function: A_TrainCameo +// +// Description: Sets up train cameo locomotive. +// +// var1 = Train width. +// var2 = Train length. +// +void A_TrainCameo(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + fixed_t x = actor->x; + fixed_t y = actor->y; + fixed_t z = actor->z; + angle_t ang = actor->angle; + mobj_t *m; + spritenum_t spr = SPR_TRAE; + fixed_t span = locvar1*FRACUNIT; + fixed_t len = locvar2*FRACUNIT; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_TrainCameo", actor)) + return; +#endif + + //Spawn sides. + P_TrainSeg(actor, x, y + span, z, ang, spr, 0); + P_TrainSeg(actor, x, y - span, z, ang, spr, 0); + + //Center. + P_TrainSeg(actor, x, y, z, ang, spr, 1); + + //Front and back. + P_TrainSeg(actor, x + len, y, z, ang + ANGLE_90, spr, 2); + P_TrainSeg(actor, x - len, y, z, ang + ANGLE_90, spr, 2); + + //Smoke spawner. + m = P_TrainSeg(actor, x - (20 * FRACUNIT), y, z + (30 * FRACUNIT), ang + ANGLE_90, spr, 0); + P_SetMobjState(m, S_TRAINPUFFMAKER); +} + +// Function: A_TrainCameo2 +// +// Description: Sets up train cameo wagon. +// +// var1 = Train width. +// var2 = Train length. +// +void A_TrainCameo2(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + fixed_t x = actor->x; + fixed_t y = actor->y; + fixed_t z = actor->z; + angle_t ang = actor->angle; + spritenum_t spr = SPR_TRAI; + fixed_t span = locvar1*FRACUNIT; + fixed_t len = locvar2*FRACUNIT; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_TrainCameo2", actor)) + return; +#endif + + //Spawn sides. + P_TrainSeg(actor, x, y + span, z, ang, spr, 0); + P_TrainSeg(actor, x, y - span, z, ang, spr, 0); + + //Center. + P_TrainSeg(actor, x, y, z, ang, spr, 1); + + //Front and back. + P_TrainSeg(actor, x + len, y, z, ang + ANGLE_90, spr, 2); + P_TrainSeg(actor, x - len, y, z, ang + ANGLE_90, spr, 2); +} + +// Function: A_CanarivoreGas +// +// Description: Releases gas clouds. Used by the Canarivore. +// +// var1 = Mobj type. +// var2 = Unused +// +void A_CanarivoreGas(mobj_t *actor) +{ + INT32 locvar1 = var1; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_CanarivoreGas", actor)) + return; +#endif + + P_DustRing(locvar1, 4, actor->x, actor->y, actor->z + actor->height / 5, 18, 0, FRACUNIT/10, actor->scale); + P_DustRing(locvar1, 6, actor->x, actor->y, actor->z + actor->height / 5, 28, FRACUNIT, FRACUNIT/10, actor->scale); +} + +// +// Function: A_KillSegments +// +// Description: Causes segments attached via tracer chain to be killed. +// +// var1 = Fuse (if 0, default to TICRATE/2). +// var2 = Unused +// +void A_KillSegments(mobj_t *actor) +{ + INT32 locvar1 = var1; + mobj_t *seg = actor->tracer; + INT32 fuse = locvar1 ? locvar1 : TICRATE/2; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_KillSegments", actor)) + return; +#endif + + while (seg) + { + mobj_t *kseg = seg; + seg = seg->tracer; + + kseg->flags = MF_NOBLOCKMAP|MF_BOUNCE; + kseg->flags2 = 0; + kseg->fuse = fuse; + P_Thrust(kseg, R_PointToAngle2(actor->x, actor->y, kseg->x, kseg->y), 3*actor->scale); + kseg->momz = 3*actor->scale; + } +} + +static void P_SnapperLegPlace(mobj_t *mo) +{ + mobj_t *seg = mo->tracer; + fixed_t x0 = mo->x; + fixed_t y0 = mo->y; + angle_t a = mo->angle; + angle_t fa = (a >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t c = FINECOSINE(fa); + fixed_t s = FINESINE(fa); + fixed_t x, y; + INT32 o1, o2; + INT32 woffset = mo->extravalue1; + INT32 side = mo->extravalue2; + INT32 alt; + + // Move head first. + fixed_t rad = mo->radius; + INT32 necklen = (32*(mo->info->reactiontime - mo->reactiontime))/mo->info->reactiontime; // Not in FU + + P_TeleportMove(seg, mo->x + FixedMul(c, rad) + necklen*c, mo->y + FixedMul(s, rad) + necklen*s, mo->z + mo->height/3); + seg->angle = a; + + // Move as many legs as available. + seg = seg->tracer; + do + { + o1 = seg->extravalue1; + o2 = seg->extravalue2; + alt = seg->cusval; + + if (alt == 1) + o2 += woffset; + else + o2 -= woffset; + + if (alt != side) + { + x = c*o2 + s*o1; + y = s*o2 - c*o1; + P_TryMove(seg, x0 + x, y0 + y, true); + P_SetMobjState(seg, seg->info->raisestate); + } + else + P_SetMobjState(seg, seg->info->spawnstate); + + seg->angle = R_PointToAngle2(x0, y0, seg->x, seg->y); + + seg = seg->tracer; + } while (seg); +} + +// +// Function: A_SnapperSpawn +// +// Description: Sets up Green Snapper legs and head. +// +// var1 = Leg mobj type. +// var2 = Head mobj type. +// +void A_SnapperSpawn(mobj_t *actor) +{ + mobjtype_t legtype = (mobjtype_t)var1; + mobjtype_t headtype = (mobjtype_t)var2; + mobj_t *ptr = actor; + INT32 i; + mobj_t *seg; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_SnapperSpawn", actor)) + return; +#endif + + // It spawns 1 head. + seg = P_SpawnMobj(actor->x, actor->y, actor->z, headtype); + P_SetTarget(&ptr->tracer, seg); + ptr = seg; + + // It spawns 4 legs which will be handled in the thinker function. + for (i = 1; i <= 4; i++) + { + seg = P_SpawnMobj(actor->x, actor->y, actor->z, legtype); + P_SetTarget(&ptr->tracer, seg); + ptr = seg; + + // The legs' base offsets are stored as extravalues, as relative coordinates in xy space. + seg->extravalue1 = 28; + seg->extravalue2 = 28; + if (i % 2) + seg->extravalue1 = -seg->extravalue1; + + if ((i/2) % 2) + seg->extravalue2 = -seg->extravalue2; + + // Alternating motion stuff. + seg->cusval = ((i + 1)/2) % 2; + } + + actor->extravalue1 = 0; + actor->extravalue2 = 0; + P_SnapperLegPlace(actor); +} + +// +// Function: A_SnapperThinker +// +// Description: Thinker for Green Snapper. +// +// var1 = Unused +// var2 = Unused +// +void A_SnapperThinker(mobj_t *actor) +{ + fixed_t x0 = actor->x; + fixed_t y0 = actor->y; + fixed_t xs, ys; + fixed_t x1, y1; + fixed_t dist; + boolean chasing; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_SnapperThinker", actor)) + return; +#endif + + // We make a check just in case there's no spawnpoint. + if (actor->spawnpoint) + { + xs = actor->spawnpoint->x*FRACUNIT; + ys = actor->spawnpoint->y*FRACUNIT; + } + else + { + xs = x0; + ys = y0; + } + + // Look for nearby, valid players to chase angrily at. + if ((actor->target || P_LookForPlayers(actor, true, false, 1024*FRACUNIT)) + && P_AproxDistance(actor->target->x - xs, actor->target->y - ys) < 2048*FRACUNIT + && abs(actor->target->z - actor->z) < 80*FRACUNIT + && P_CheckSight(actor, actor->target)) + { + chasing = true; + x1 = actor->target->x; + y1 = actor->target->y; + } + else + { + chasing = false; + x1 = xs; + y1 = ys; + } + + dist = P_AproxDistance(x1 - x0, y1 - y0); + + // The snapper either chases what it considers to be a nearby player, or instead decides to go back to its spawnpoint. + if (chasing || dist > 32*FRACUNIT) + { + INT32 speed = actor->info->speed + actor->info->reactiontime - actor->reactiontime; + + angle_t maxang = FixedAngle(speed*FRACUNIT/2); + angle_t ang = actor->angle; + angle_t realang = R_PointToAngle2(x0, y0, x1, y1); + angle_t dif = realang - ang; + angle_t fa; + fixed_t c, s; + + if (dif < ANGLE_180 && dif > maxang) + actor->angle += maxang; + else if (dif >= ANGLE_180 && dif < InvAngle(maxang)) + actor->angle -= maxang; + else + actor->angle = realang; + + fa = (actor->angle >> ANGLETOFINESHIFT) & FINEMASK; + c = FINECOSINE(fa); + s = FINESINE(fa); + + P_TryMove(actor, actor->x + c*speed, actor->y + s*speed, false); + + // The snapper spawns dust if going fast! + if (actor->reactiontime < 4) + { + mobj_t *dust = P_SpawnMobj(x0, y0, actor->z, MT_SPINDUST); + P_Thrust(dust, ang + ANGLE_180 + FixedAngle(P_RandomRange(-20, 20)*FRACUNIT), speed*FRACUNIT); + } + + if (actor->extravalue2 == 0) + { + if (actor->extravalue1 > 16) + { + A_PlayActiveSound(actor); + actor->extravalue2 = 1; + + // If the snapper is chasing, accelerate; otherwise, decelerate. + if (chasing) + actor->reactiontime = max(0, actor->reactiontime - 1); + else + actor->reactiontime = min(actor->info->reactiontime, actor->reactiontime + 1); + } + else + actor->extravalue1 += speed; + } + else + { + if (actor->extravalue1 < -16) + { + A_PlayActiveSound(actor); + actor->extravalue2 = 0; + + // If the snapper is chasing, accelerate; otherwise, decelerate. + if (chasing) + actor->reactiontime = max(0, actor->reactiontime - 1); + else + actor->reactiontime = min(actor->info->reactiontime, actor->reactiontime + 1); + } + else + actor->extravalue1 -= speed; + } + } + + P_SnapperLegPlace(actor); +} + +// Function: A_SaloonDoorSpawn +// +// Description: Spawns a saloon door. +// +// var1 = unused +// var2 = unused +// +void A_SaloonDoorSpawn(mobj_t *actor) +{ + angle_t ang = actor->angle; + angle_t fa = (ang >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t c = FINECOSINE(fa); + fixed_t s = FINESINE(fa); + INT32 d = 48; + fixed_t x = actor->x; + fixed_t y = actor->y; + fixed_t z = actor->z; + mobj_t *door; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_SaloonDoorSpawn", actor)) + return; +#endif + + //Front + door = P_SpawnMobj(x + c*d, y + s*d, z, MT_SALOONDOOR); + door->angle = ang + ANGLE_180; + + // Origin angle + door->extravalue1 = AngleFixed(door->angle); + + // Angular speed + door->extravalue2 = 0; + + // Origin door + door->tracer = actor; + + //Back + door = P_SpawnMobj(x - c*d, y - s*d, z, MT_SALOONDOOR); + door->angle = ang; + + // Origin angle + door->extravalue1 = AngleFixed(door->angle); + + // Angular speed + door->extravalue2 = 0; + + // Origin door + door->tracer = actor; +} + +// Function: A_MinecartSparkThink +// +// Description: Thinker for the minecart spark. +// +// var1 = unused +// var2 = unused +// +void A_MinecartSparkThink(mobj_t *actor) +{ + fixed_t dx = actor->momx; + fixed_t dy = actor->momy; + fixed_t dz, dm; + UINT8 i; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_MinecartSparkThink", actor)) + return; +#endif + + if (actor->momz == 0 && P_IsObjectOnGround(actor)) + actor->momz = P_RandomRange(2, 4)*FRACUNIT; + + dz = actor->momz; + dm = FixedHypot(FixedHypot(dx, dy), dz); + dx = FixedDiv(dx, dm); + dy = FixedDiv(dy, dm); + dz = FixedDiv(dz, dm); + + for (i = 1; i <= 8; i++) + { + mobj_t *trail = P_SpawnMobj(actor->x - dx*i, actor->y - dy*i, actor->z - dz*i, MT_PARTICLE); + trail->tics = 2; + trail->sprite = actor->sprite; + P_SetScale(trail, trail->scale/4); + trail->destscale = trail->scale; + } +} \ No newline at end of file diff --git a/src/p_floor.c b/src/p_floor.c index 6db4310ace93c0fce3c4022af9c205f4c7a43299..a1b1c45fc08dc51ab30eab179bf740290713bdbf 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -13,7 +13,11 @@ #include "doomdef.h" #include "doomstat.h" +#include "m_random.h" #include "p_local.h" +#ifdef ESLOPE +#include "p_slopes.h" +#endif #include "r_state.h" #include "s_sound.h" #include "z_zone.h" @@ -1149,6 +1153,7 @@ void T_MarioBlock(levelspecthink_t *block) block->sector->ceilingdata = NULL; block->sector->floorspeed = 0; block->sector->ceilspeed = 0; + block->direction = 0; } for (i = -1; (i = P_FindSectorFromTag((INT16)block->vars[0], i)) >= 0 ;) @@ -1228,9 +1233,7 @@ void T_SpikeSector(levelspecthink_t *spikes) if (dothepain) { - mobj_t *killer = P_SpawnMobj(thing->x, thing->y, thing->z, MT_NULL); - killer->threshold = 43; // Special flag that it was spikes which hurt you. - P_DamageMobj(thing, killer, killer, 1); + P_DamageMobj(thing, NULL, NULL, 1, DMG_SPIKE); break; } } @@ -1754,16 +1757,20 @@ static mobj_t *SearchMarioNode(msecnode_t *node) { case MT_NULL: case MT_UNKNOWN: + case MT_TAILSOVERLAY: case MT_THOK: case MT_GHOST: case MT_OVERLAY: case MT_EMERALDSPAWN: - case MT_GREENORB: - case MT_YELLOWORB: - case MT_BLUEORB: - case MT_BLACKORB: - case MT_WHITEORB: - case MT_PITYORB: + case MT_ELEMENTAL_ORB: + case MT_ATTRACT_ORB: + case MT_FORCE_ORB: + case MT_ARMAGEDDON_ORB: + case MT_WHIRLWIND_ORB: + case MT_PITY_ORB: + case MT_FLAMEAURA_ORB: + case MT_BUBBLEWRAP_ORB: + case MT_THUNDERCOIN_ORB: case MT_IVSP: case MT_SUPERSPARK: case MT_RAIN: @@ -1778,9 +1785,9 @@ static mobj_t *SearchMarioNode(msecnode_t *node) case MT_SCORE: case MT_DROWNNUMBERS: case MT_GOTEMERALD: + case MT_LOCKON: case MT_TAG: case MT_GOTFLAG: - case MT_GOTFLAG2: case MT_HOOP: case MT_HOOPCOLLIDE: case MT_NIGHTSCORE: @@ -1792,8 +1799,8 @@ static mobj_t *SearchMarioNode(msecnode_t *node) break; } // Ignore popped monitors, too. - if (node->m_thing->flags & MF_MONITOR - && node->m_thing->threshold == 68) + if (node->m_thing->health == 0 // this only really applies for monitors + || (!(node->m_thing->flags & MF_MONITOR) && (mobjinfo[node->m_thing->type].flags & MF_MONITOR))) // gold monitor support continue; // Okay, we found something valid. if (!thing // take either the first thing @@ -1807,10 +1814,24 @@ static mobj_t *SearchMarioNode(msecnode_t *node) void T_MarioBlockChecker(levelspecthink_t *block) { line_t *masterline = block->sourceline; + if (block->vars[2] == 1) // Don't update the textures when the block's being bumped upwards. + return; if (SearchMarioNode(block->sector->touching_thinglist)) - sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].bottomtexture; + { + sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].bottomtexture; // Update textures + if (masterline->backsector) + { + block->sector->ceilingpic = block->sector->floorpic = masterline->backsector->ceilingpic; // Update flats to be backside's ceiling + } + } else + { sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].toptexture; + if (masterline->backsector) + { + block->sector->ceilingpic = block->sector->floorpic = masterline->backsector->floorpic; // Update flats to be backside's floor + } + } } // This is the Thwomp's 'brain'. It looks around for players nearby, and if @@ -1998,51 +2019,71 @@ void T_NoEnemiesSector(levelspecthink_t *nobaddies) { size_t i; fixed_t upperbound, lowerbound; - INT32 s; - sector_t *checksector; + sector_t *sec = NULL; + sector_t *targetsec = NULL; + INT32 secnum = -1; msecnode_t *node; mobj_t *thing; - boolean exists = false; + boolean FOFsector = false; - for (i = 0; i < nobaddies->sector->linecount; i++) + while ((secnum = P_FindSectorFromLineTag(nobaddies->sourceline, secnum)) >= 0) { - if (nobaddies->sector->lines[i]->special == 223) + sec = §ors[secnum]; + + FOFsector = false; + + // Check the lines of this sector, to see if it is a FOF control sector. + for (i = 0; i < sec->linecount; i++) { + INT32 targetsecnum = -1; + + if (sec->lines[i]->special < 100 || sec->lines[i]->special >= 300) + continue; - upperbound = nobaddies->sector->ceilingheight; - lowerbound = nobaddies->sector->floorheight; + FOFsector = true; - for (s = -1; (s = P_FindSectorFromLineTag(nobaddies->sector->lines[i], s)) >= 0 ;) + while ((targetsecnum = P_FindSectorFromLineTag(sec->lines[i], targetsecnum)) >= 0) { - checksector = §ors[s]; + targetsec = §ors[targetsecnum]; - node = checksector->touching_thinglist; // things touching this sector + upperbound = targetsec->ceilingheight; + lowerbound = targetsec->floorheight; + node = targetsec->touching_thinglist; // things touching this sector while (node) { thing = node->m_thing; if ((thing->flags & (MF_ENEMY|MF_BOSS)) && thing->health > 0 - && thing->z < upperbound && thing->z+thing->height > lowerbound) - { - exists = true; - goto foundenemy; - } + && thing->z < upperbound && thing->z+thing->height > lowerbound) + return; node = node->m_thinglist_next; } } } - } -foundenemy: - if (exists) - return; - s = P_AproxDistance(nobaddies->sourceline->dx, nobaddies->sourceline->dy)>>FRACBITS; + if (!FOFsector) + { + upperbound = sec->ceilingheight; + lowerbound = sec->floorheight; + node = sec->touching_thinglist; // things touching this sector + while (node) + { + thing = node->m_thing; + + if ((thing->flags & (MF_ENEMY|MF_BOSS)) && thing->health > 0 + && thing->z < upperbound && thing->z+thing->height > lowerbound) + return; + + node = node->m_thinglist_next; + } + } + } - CONS_Debug(DBG_GAMELOGIC, "Running no-more-enemies exec with tag of %d\n", s); + CONS_Debug(DBG_GAMELOGIC, "Running no-more-enemies exec with tag of %d\n", nobaddies->sourceline->tag); - // Otherwise, run the linedef exec and terminate this thinker - P_LinedefExecute((INT16)s, NULL, NULL); + // No enemies found, run the linedef exec and terminate this thinker + P_RunTriggerLinedef(nobaddies->sourceline, NULL, NULL); P_RemoveThinker(&nobaddies->thinker); } @@ -2605,6 +2646,35 @@ void T_CameraScanner(elevator_t *elevator) } } +void T_PlaneDisplace(planedisplace_t *pd) +{ + sector_t *control, *target; + INT32 direction; + fixed_t diff; + + control = §ors[pd->control]; + target = §ors[pd->affectee]; + + if (control->floorheight == pd->last_height) + return; // no change, no movement + + direction = (control->floorheight > pd->last_height) ? 1 : -1; + diff = FixedMul(control->floorheight-pd->last_height, pd->speed); + + if (pd->reverse) // reverse direction? + { + direction *= -1; + diff *= -1; + } + + if (pd->type == pd_floor || pd->type == pd_both) + T_MovePlane(target, INT32_MAX/2, target->floorheight+diff, 0, 0, direction); // move floor + if (pd->type == pd_ceiling || pd->type == pd_both) + T_MovePlane(target, INT32_MAX/2, target->ceilingheight+diff, 0, 1, direction); // move ceiling + + pd->last_height = control->floorheight; +} + // // EV_DoFloor // @@ -2962,18 +3032,41 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) size_t topmostvertex = 0, bottommostvertex = 0; fixed_t leftx, rightx; fixed_t topy, bottomy; - fixed_t topz; + fixed_t topz, bottomz; + fixed_t widthfactor = FRACUNIT, heightfactor = FRACUNIT; fixed_t a, b, c; mobjtype_t type = MT_ROCKCRUMBLE1; + fixed_t spacing = (32<<FRACBITS); + tic_t lifetime = 3*TICRATE; + INT16 flags = 0; + +#define controlsec rover->master->frontsector + + if (controlsec->tag != 0) + { + INT32 tagline = P_FindSpecialLineFromTag(14, controlsec->tag, -1); + if (tagline != -1) + { + if (sides[lines[tagline].sidenum[0]].toptexture) + type = (mobjtype_t)sides[lines[tagline].sidenum[0]].toptexture; // Set as object type in p_setup.c... + if (sides[lines[tagline].sidenum[0]].textureoffset) + spacing = sides[lines[tagline].sidenum[0]].textureoffset; + if (sides[lines[tagline].sidenum[0]].rowoffset) + { + if (sides[lines[tagline].sidenum[0]].rowoffset>>FRACBITS != -1) + lifetime = (sides[lines[tagline].sidenum[0]].rowoffset>>FRACBITS); + else + lifetime = 0; + } + flags = lines[tagline].flags; + } + } - // If the control sector has a special - // of Section3:7-15, use the custom debris. - if (GETSECSPECIAL(rover->master->frontsector->special, 3) >= 8) - type = MT_ROCKCRUMBLE1+(GETSECSPECIAL(rover->master->frontsector->special, 3)-7); +#undef controlsec // soundorg z height never gets set normally, so MEH. sec->soundorg.z = sec->floorheight; - S_StartSound(&sec->soundorg, sfx_crumbl); + S_StartSound(&sec->soundorg, mobjinfo[type].activesound); // Find the outermost vertexes in the subsector for (i = 0; i < sec->linecount; i++) @@ -2992,23 +3085,46 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) bottommostvertex = i; } - leftx = sec->lines[leftmostvertex]->v1->x+(16<<FRACBITS); + leftx = sec->lines[leftmostvertex]->v1->x+(spacing>>1); rightx = sec->lines[rightmostvertex]->v1->x; - topy = sec->lines[topmostvertex]->v1->y-(16<<FRACBITS); + topy = sec->lines[topmostvertex]->v1->y-(spacing>>1); bottomy = sec->lines[bottommostvertex]->v1->y; - topz = *rover->topheight-(16<<FRACBITS); - for (a = leftx; a < rightx; a += (32<<FRACBITS)) + topz = *rover->topheight-(spacing>>1); + bottomz = *rover->bottomheight; + + if (flags & ML_EFFECT1) { - for (b = topy; b > bottomy; b -= (32<<FRACBITS)) + widthfactor = (rightx + topy - leftx - bottomy)>>3; + heightfactor = (topz - *rover->bottomheight)>>2; + } + + for (a = leftx; a < rightx; a += spacing) + { + for (b = topy; b > bottomy; b -= spacing) { if (R_PointInSubsector(a, b)->sector == sec) { mobj_t *spawned = NULL; - for (c = topz; c > *rover->bottomheight; c -= (32<<FRACBITS)) +#ifdef ESLOPE + if (*rover->t_slope) + topz = P_GetZAt(*rover->t_slope, a, b) - (spacing>>1); + if (*rover->b_slope) + bottomz = P_GetZAt(*rover->b_slope, a, b); +#endif + + for (c = topz; c > bottomz; c -= spacing) { spawned = P_SpawnMobj(a, b, c, type); - spawned->fuse = 3*TICRATE; + spawned->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones + + if (flags & ML_EFFECT1) + { + P_InstaThrust(spawned, R_PointToAngle2(sec->soundorg.x, sec->soundorg.y, a, b), FixedDiv(P_AproxDistance(a - sec->soundorg.x, b - sec->soundorg.y), widthfactor)); + P_SetObjectMomZ(spawned, FixedDiv((c - bottomz), heightfactor), false); + } + + spawned->fuse = lifetime; } } } @@ -3168,8 +3284,10 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, return 1; } -INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mobj_t *puncher) +INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher) { + sector_t *roversec = rover->master->frontsector; + fixed_t topheight = *rover->topheight; levelspecthink_t *block; mobj_t *thing; fixed_t oldx = 0, oldy = 0, oldz = 0; @@ -3177,11 +3295,14 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob I_Assert(puncher != NULL); I_Assert(puncher->player != NULL); - if (sec->floordata || sec->ceilingdata) + if (roversec->floordata || roversec->ceilingdata) return 0; + if (!(rover->flags & FF_SOLID)) + rover->flags |= (FF_SOLID|FF_RENDERALL|FF_CUTLEVEL); + // Find an item to pop out! - thing = SearchMarioNode(sec->touching_thinglist); + thing = SearchMarioNode(roversec->touching_thinglist); // Found something! if (thing) @@ -3191,13 +3312,13 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob block = Z_Calloc(sizeof (*block), PU_LEVSPEC, NULL); P_AddThinker(&block->thinker); - sec->floordata = block; - sec->ceilingdata = block; + roversec->floordata = block; + roversec->ceilingdata = block; block->thinker.function.acp1 = (actionf_p1)T_MarioBlock; // Set up the fields - block->sector = sec; - block->vars[0] = roversector->tag; // actionsector + block->sector = roversec; + block->vars[0] = sector->tag; // actionsector block->vars[1] = 4*FRACUNIT; // speed block->vars[2] = 1; // Up // direction block->vars[3] = block->sector->floorheight; // floorwasheight @@ -3213,14 +3334,14 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob } P_UnsetThingPosition(thing); - thing->x = roversector->soundorg.x; - thing->y = roversector->soundorg.y; + thing->x = sector->soundorg.x; + thing->y = sector->soundorg.y; thing->z = topheight; thing->momz = FixedMul(6*FRACUNIT, thing->scale); P_SetThingPosition(thing); if (thing->flags & MF_SHOOTABLE) - P_DamageMobj(thing, puncher, puncher, 1); - else if (thing->type == MT_RING || thing->type == MT_COIN) + P_DamageMobj(thing, puncher, puncher, 1, 0); + else if (thing->type == MT_RING || thing->type == MT_COIN || thing->type == MT_TOKEN) { thing->momz = FixedMul(3*FRACUNIT, thing->scale); P_TouchSpecialThing(thing, puncher, false); @@ -3229,27 +3350,19 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob } else { - if (thing->type == MT_EMMY && thing->spawnpoint && (thing->spawnpoint->options & MTF_OBJECTSPECIAL)) - { - mobj_t *tokenobj = P_SpawnMobj(roversector->soundorg.x, roversector->soundorg.y, topheight, MT_TOKEN); - P_SetTarget(&thing->tracer, tokenobj); - P_SetTarget(&tokenobj->target, thing); - P_SetMobjState(tokenobj, mobjinfo[MT_TOKEN].seestate); - } - // "Powerup rise" sound S_StartSound(puncher, sfx_mario9); // Puncher is "close enough" } - if (itsamonitor) + if (itsamonitor && thing) { - P_UnsetThingPosition(tmthing); - tmthing->x = oldx; - tmthing->y = oldy; - tmthing->z = oldz; - tmthing->momx = 1; - tmthing->momy = 1; - P_SetThingPosition(tmthing); + P_UnsetThingPosition(thing); + thing->x = oldx; + thing->y = oldy; + thing->z = oldz; + thing->momx = 1; + thing->momy = 1; + P_SetThingPosition(thing); } } else diff --git a/src/p_inter.c b/src/p_inter.c index 29450f6e1d075833d10b199faf87e128b8c040cc..cd1e80de2dbbb1a231c3558c1b0e293812d84a33 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -23,6 +23,7 @@ #include "hu_stuff.h" #include "lua_hook.h" #include "m_cond.h" // unlockables, emblems, etc +#include "p_setup.h" #include "m_cheat.h" // objectplace #include "m_misc.h" #include "v_video.h" // video flags for CEchos @@ -103,8 +104,13 @@ void P_ClearStarPost(INT32 postnum) mo2 = (mobj_t *)th; - if (mo2->type == MT_STARPOST && mo2->health <= postnum) - P_SetMobjState(mo2, mo2->info->seestate); + if (mo2->type != MT_STARPOST) + continue; + + if (mo2->health > postnum) + continue; + + P_SetMobjState(mo2, mo2->info->seestate); } return; } @@ -142,7 +148,10 @@ boolean P_CanPickupItem(player_t *player, boolean weapon) if (player->bot && weapon) return false; - if (player->powers[pw_flashing] > (flashingtics/4)*3 && player->powers[pw_flashing] <= flashingtics) + if (player->powers[pw_flashing] > (flashingtics/4)*3 && player->powers[pw_flashing] < UINT16_MAX) + return false; + + if (player->mo && player->mo->health <= 0) return false; return true; @@ -173,14 +182,14 @@ void P_DoNightsScore(player_t *player) { if (++players[i].linkcount > players[i].maxlink) players[i].maxlink = players[i].linkcount; - players[i].linktimer = 2*TICRATE; + players[i].linktimer = nightslinktics; } } else // Individual link counts { if (++player->linkcount > player->maxlink) player->maxlink = player->linkcount; - player->linktimer = 2*TICRATE; + player->linktimer = nightslinktics; } if (player->linkcount < 10) @@ -221,6 +230,69 @@ void P_DoNightsScore(player_t *player) dummymo->destscale = 2*FRACUNIT; } +// +// P_DoMatchSuper +// +// Checks if you have all 7 pw_emeralds, then turns you "super". =P +// +void P_DoMatchSuper(player_t *player) +{ + UINT16 match_emeralds = player->powers[pw_emeralds]; + boolean doteams = false; + int i; + + // If this gametype has teams, check every player on your team for emeralds. + if (G_GametypeHasTeams()) + { + doteams = true; + for (i = 0; i < MAXPLAYERS; i++) + if (players[i].ctfteam == player->ctfteam) + match_emeralds |= players[i].powers[pw_emeralds]; + } + + if (!ALL7EMERALDS(match_emeralds)) + return; + + // Got 'em all? Turn "super"! + emeraldspawndelay = invulntics + 1; + player->powers[pw_emeralds] = 0; + player->powers[pw_invulnerability] = emeraldspawndelay; + player->powers[pw_sneakers] = emeraldspawndelay; + if (P_IsLocalPlayer(player) && !player->powers[pw_super]) + { + S_StopMusic(); + if (mariomode) + G_GhostAddColor(GHC_INVINCIBLE); + strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14); + S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]); + S_ChangeMusicInternal((mariomode) ? "_minv" : "_inv", false); + } + + // Also steal 50 points from every enemy, sealing your victory. + P_StealPlayerScore(player, 50); + + // In a team game? + // Check everyone else on your team for emeralds, and turn those helpful assisting players invincible too. + if (doteams) + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].ctfteam == player->ctfteam + && players[i].powers[pw_emeralds] != 0) + { + players[i].powers[pw_emeralds] = 0; + player->powers[pw_invulnerability] = invulntics + 1; + player->powers[pw_sneakers] = player->powers[pw_invulnerability]; + if (P_IsLocalPlayer(player) && !player->powers[pw_super]) + { + S_StopMusic(); + if (mariomode) + G_GhostAddColor(GHC_INVINCIBLE); + strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14); + S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]); + S_ChangeMusicInternal((mariomode) ? "_minv" : "_inv", false); + } + } +} + /** Takes action based on a ::MF_SPECIAL thing touched by a player. * Actually, this just checks a few things (heights, toucher->player, no * objectplace, no dead or disappearing things) @@ -237,6 +309,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { player_t *player; INT32 i; + UINT8 elementalpierce; if (objectplacing) return; @@ -282,8 +355,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->spectator) return; - // Ignore eggman in "ouchie" mode - if (special->flags & MF_BOSS && special->flags2 & MF2_FRET) + // Ignore multihits in "ouchie" mode + if (special->flags & (MF_ENEMY|MF_BOSS) && special->flags2 & MF2_FRET) return; #ifdef HAVE_BLUA @@ -291,85 +364,137 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; #endif - if (special->flags & MF_BOSS) - { - if (special->type == MT_BLACKEGGMAN) - { - P_DamageMobj(toucher, special, special, 1); // ouch - return; - } - - if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) - || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)) - || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? - { - if (P_MobjFlip(toucher)*toucher->momz < 0) - toucher->momz = -toucher->momz; - toucher->momx = -toucher->momx; - toucher->momy = -toucher->momy; - P_DamageMobj(special, toucher, toucher, 1); - } - else if (((toucher->z < special->z && !(toucher->eflags & MFE_VERTICALFLIP)) - || (toucher->z + toucher->height > special->z + special->height && (toucher->eflags & MFE_VERTICALFLIP))) - && player->charability == CA_FLY - && (player->powers[pw_tailsfly] - || (toucher->state >= &states[S_PLAY_SPC1] && toucher->state <= &states[S_PLAY_SPC4]))) // Tails can shred stuff with his propeller. - { - toucher->momz = -toucher->momz/2; - - P_DamageMobj(special, toucher, toucher, 1); - } - else - P_DamageMobj(toucher, special, special, 1); + // 0 = none, 1 = elemental pierce, 2 = bubble bounce + elementalpierce = (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (player->pflags & PF_SHIELDABILITY) + ? (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) ? 1 : 2) + : 0); - return; - } - else if ((special->flags & MF_ENEMY) && !(special->flags & MF_MISSILE)) + if ((special->flags & (MF_ENEMY|MF_BOSS)) && !(special->flags & MF_MISSILE)) { //////////////////////////////////////////////////////// - /////ENEMIES!!////////////////////////////////////////// + /////ENEMIES & BOSSES!!///////////////////////////////// //////////////////////////////////////////////////////// - if (special->type == MT_GSNAPPER && !(((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) - || player->powers[pw_invulnerability] || player->powers[pw_super]) - && toucher->z < special->z + special->height && toucher->z + toucher->height > special->z) - { - // Can only hit snapper from above - P_DamageMobj(toucher, special, special, 1); - } - else if (special->type == MT_SHARP - && ((special->state == &states[special->info->xdeathstate]) || (toucher->z > special->z + special->height/2))) + + switch (special->type) { - // Cannot hit sharp from above or when red and angry - P_DamageMobj(toucher, special, special, 1); + case MT_BLACKEGGMAN: + { + P_DamageMobj(toucher, special, special, 1, 0); // ouch + return; + } + case MT_BIGMINE: + { + special->momx = toucher->momx/3; + special->momy = toucher->momy/3; + special->momz = toucher->momz/3; + toucher->momx /= -8; + toucher->momy /= -8; + toucher->momz /= -8; + special->flags &= ~MF_SPECIAL; + if (special->info->activesound) + S_StartSound(special, special->info->activesound); + P_SetTarget(&special->tracer, toucher); + player->homing = 0; + return; + } + case MT_GSNAPPER: + if (!elementalpierce + && toucher->z < special->z + special->height + && toucher->z + toucher->height > special->z + && P_DamageMobj(toucher, special, special, 1, DMG_SPIKE)) + return; // Can only hit snapper from above + break; + + case MT_SPINCUSHION: + if (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) + { + if (player->pflags & PF_BOUNCING) + { + toucher->momz = -toucher->momz; + P_DoAbilityBounce(player, false); + return; + } + else if (P_DamageMobj(toucher, special, special, 1, DMG_SPIKE)) + return; // Cannot hit sharp from above + } + break; + case MT_FANG: + if (!player->powers[pw_flashing] + && !(player->charability == CA_TWINSPIN && player->panim == PA_ABILITY) + && !(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) + { + if ((special->state == &states[S_FANG_BOUNCE3] + || special->state == &states[S_FANG_BOUNCE4] + || special->state == &states[S_FANG_PINCHBOUNCE3] + || special->state == &states[S_FANG_PINCHBOUNCE4]) + && P_MobjFlip(special)*((special->z + special->height/2) - (toucher->z - toucher->height/2)) > 0) + { + P_DamageMobj(toucher, special, special, 1, 0); + P_SetTarget(&special->tracer, toucher); + + if (special->state == &states[S_FANG_PINCHBOUNCE3] + || special->state == &states[S_FANG_PINCHBOUNCE4]) + P_SetMobjState(special, S_FANG_PINCHPATHINGSTART2); + else + { + var1 = var2 = 4; + A_Boss5ExtraRepeat(special); + P_SetMobjState(special, S_FANG_PATHINGCONT2); //S_FANG_PATHINGCONT1 if you want him to drop a bomb on the player + } + if (special->eflags & MFE_VERTICALFLIP) + special->z = toucher->z - special->height; + else + special->z = toucher->z + toucher->height; + return; + } + } + break; + default: + break; } - else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) - || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)) - || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? - { - if (P_MobjFlip(toucher)*toucher->momz < 0) - toucher->momz = -toucher->momz; - P_DamageMobj(special, toucher, toucher, 1); + if (((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING)) + || ((player->pflags & PF_JUMPED) && (!(player->pflags & PF_NOJUMPDAMAGE) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY))) + || (player->pflags & (PF_SPINNING|PF_GLIDING)) + || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2) + || ((player->charflags & SF_STOMPDAMAGE || player->pflags & PF_BOUNCING) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)) + || player->powers[pw_invulnerability] || player->powers[pw_super] + || elementalpierce) // Do you possess the ability to subdue the object? + { + if ((P_MobjFlip(toucher)*toucher->momz < 0) && (elementalpierce != 1)) + { + if (elementalpierce == 2) + P_DoBubbleBounce(player); + else if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) + toucher->momz = -toucher->momz; + } + if (player->pflags & PF_BOUNCING) + P_DoAbilityBounce(player, false); + if (special->info->spawnhealth > 1) // Multi-hit? Bounce back! + { + toucher->momx = -toucher->momx; + toucher->momy = -toucher->momy; + } + P_DamageMobj(special, toucher, toucher, 1, 0); } else if (((toucher->z < special->z && !(toucher->eflags & MFE_VERTICALFLIP)) - || (toucher->z + toucher->height > special->z + special->height && (toucher->eflags & MFE_VERTICALFLIP))) // Flame is bad at logic - JTE + || (toucher->z + toucher->height > special->z + special->height && (toucher->eflags & MFE_VERTICALFLIP))) && player->charability == CA_FLY && (player->powers[pw_tailsfly] - || (toucher->state >= &states[S_PLAY_SPC1] && toucher->state <= &states[S_PLAY_SPC4]))) // Tails can shred stuff with his propeller. + || toucher->state-states == S_PLAY_FLY_TIRED)) // Tails can shred stuff with her propeller. { - if (P_MobjFlip(toucher)*toucher->momz < 0) - toucher->momz = -toucher->momz/2; + toucher->momz = -toucher->momz/2; - P_DamageMobj(special, toucher, toucher, 1); + P_DamageMobj(special, toucher, toucher, 1, 0); } else - P_DamageMobj(toucher, special, special, 1); + P_DamageMobj(toucher, special, special, 1, 0); return; } else if (special->flags & MF_FIRE) { - P_DamageMobj(toucher, special, special, 1); + P_DamageMobj(toucher, special, special, 1, DMG_FIRE); return; } else @@ -390,42 +515,46 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) /* FALLTHRU */ case MT_RING: case MT_FLINGRING: - if (!(P_CanPickupItem(player, false))) + case MT_COIN: + case MT_FLINGCOIN: + case MT_NIGHTSSTAR: + if (!(P_CanPickupItem(player, false)) && !(special->flags2 & MF2_NIGHTSPULL)) return; special->momx = special->momy = special->momz = 0; P_GivePlayerRings(player, 1); - if ((maptol & TOL_NIGHTS) && special->type != MT_FLINGRING) + if ((maptol & TOL_NIGHTS) && special->type != MT_FLINGRING && special->type != MT_FLINGCOIN) P_DoNightsScore(player); break; - - case MT_COIN: - case MT_FLINGCOIN: - if (!(P_CanPickupItem(player, false))) + case MT_BLUESPHERE: + case MT_FLINGBLUESPHERE: + case MT_NIGHTSCHIP: + case MT_FLINGNIGHTSCHIP: + if (!(P_CanPickupItem(player, false)) && !(special->flags2 & MF2_NIGHTSPULL)) return; - special->momx = special->momy = 0; - P_GivePlayerRings(player, 1); + special->momx = special->momy = special->momz = 0; + P_GivePlayerSpheres(player, 1); - if ((maptol & TOL_NIGHTS) && special->type != MT_FLINGCOIN) + if (special->type == MT_BLUESPHERE) + { + special->destscale = ((player->powers[pw_carry] == CR_NIGHTSMODE) ? 4 : 2)*special->scale; + if (states[special->info->deathstate].tics > 0) + special->scalespeed = FixedDiv(FixedDiv(special->destscale, special->scale), states[special->info->deathstate].tics<<FRACBITS); + else + special->scalespeed = 4*FRACUNIT/5; + } + + if (maptol & TOL_NIGHTS) P_DoNightsScore(player); break; - case MT_BLUEBALL: - if (!(P_CanPickupItem(player, false))) + case MT_BOMBSPHERE: + if (!(P_CanPickupItem(player, false)) && !(special->flags2 & MF2_NIGHTSPULL)) return; - P_GivePlayerRings(player, 1); - special->momx = special->momy = special->momz = 0; - special->destscale = FixedMul(8*FRACUNIT, special->scale); - if (states[special->info->deathstate].tics > 0) - special->scalespeed = FixedDiv(FixedDiv(special->destscale, special->scale), states[special->info->deathstate].tics<<FRACBITS); - else - special->scalespeed = 4*FRACUNIT/5; - - if (maptol & TOL_NIGHTS) - P_DoNightsScore(player); + P_DamageMobj(toucher, special, special, 1, 0); break; case MT_AUTOPICKUP: case MT_BOUNCEPICKUP: @@ -441,7 +570,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { INT32 pindex = special->info->mass - (INT32)pw_infinityring; - player->powers[special->info->mass] += (UINT16)special->info->reactiontime; + player->powers[special->info->mass] += (UINT16)special->reactiontime; player->ringweapons |= 1 << (pindex-1); if (player->powers[special->info->mass] > rw_maximums[pindex]) @@ -474,21 +603,40 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Gameplay related collectibles // // ***************************** // // Special Stage Token - case MT_EMMY: + case MT_TOKEN: if (player->bot) return; + + P_AddPlayerScore(player, 1000); + + if (gametype != GT_COOP || modeattacking) // score only? + { + S_StartSound(toucher, sfx_chchng); + break; + } + tokenlist += special->health; if (ALL7EMERALDS(emeralds)) // Got all 7 { - P_GivePlayerRings(player, 50); - nummaprings += 50; // no cheating towards Perfect! + if (!(netgame || multiplayer)) + { + player->continues += 1; + players->gotcontinue = true; + if (P_IsLocalPlayer(player)) + S_StartSound(NULL, sfx_s3kac); + else + S_StartSound(toucher, sfx_chchng); + } + else + S_StartSound(toucher, sfx_chchng); } else + { token++; + S_StartSound(toucher, sfx_token); + } - if (special->tracer) // token BG - P_RemoveMobj(special->tracer); break; // Emerald Hunt @@ -512,7 +660,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) players[i].exiting = (14*TICRATE)/5 + 1; } - S_StartSound(NULL, sfx_lvpass); + //S_StartSound(NULL, sfx_lvpass); } break; @@ -528,7 +676,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; if (special->threshold) + { player->powers[pw_emeralds] |= special->info->speed; + P_DoMatchSuper(player); + } else emeralds |= special->info->speed; @@ -549,6 +700,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; player->powers[pw_emeralds] |= special->threshold; + P_DoMatchSuper(player); break; // Secret emblem thingy @@ -639,45 +791,134 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // NiGHTS gameplay items and powerups // // ********************************** // case MT_NIGHTSDRONE: - if (player->bot) - return; - if (player->exiting) - return; - if (player->bonustime) { - if (G_IsSpecialStage(gamemap)) //After-mare bonus time/emerald reward in special stages. + boolean spec = G_IsSpecialStage(gamemap); + boolean cangiveemmy = false; + if (player->bot) + return; + if (player->exiting) + return; + if (player->bonustime) { - // only allow the player with the emerald in-hand to leave. - if (toucher->tracer && toucher->tracer->target - && toucher->tracer->target->type == MT_GOTEMERALD) + if (spec) //After-mare bonus time/emerald reward in special stages. { + // only allow the player with the emerald in-hand to leave. + if (toucher->tracer + && toucher->tracer->type == MT_GOTEMERALD) + {} + else // Make sure that SOMEONE has the emerald, at least! + { + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].playerstate == PST_LIVE + && players[i].mo->tracer + && players[i].mo->tracer->type == MT_GOTEMERALD) + return; + // Well no one has an emerald, so exit anyway! + } + cangiveemmy = true; + // Don't play Ideya sound in special stage mode + } + else + S_StartSound(toucher, special->info->activesound); + } + else //Initial transformation. Don't allow second chances in special stages! + { + if (player->powers[pw_carry] == CR_NIGHTSMODE) + return; + + S_StartSound(toucher, sfx_supert); + } + P_SwitchSpheresBonusMode(false); + if (!(netgame || multiplayer) && !(player->powers[pw_carry] == CR_NIGHTSMODE)) + P_SetTarget(&special->tracer, toucher); + P_SetTarget(&player->drone, special); // Mark the player as 'center into the drone' + P_NightserizePlayer(player, special->health); // Transform! + if (!spec) + { + if (toucher->tracer) // Move the Ideya to an anchor! + { + mobj_t *orbittarget = special->target ? special->target : special; + mobj_t *hnext = orbittarget->hnext, *anchorpoint = NULL, *anchorpoint2 = NULL; + mobj_t *mo2; + thinker_t *th; + + // The player might have two Ideyas: toucher->tracer and toucher->tracer->hnext + // so handle their anchorpoints accordingly. + // scan the thinkers to find the corresponding anchorpoint + for (th = thinkercap.next; th != &thinkercap; th = th->next) + { + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; + + mo2 = (mobj_t *)th; + + if (mo2->type == MT_IDEYAANCHOR) + { + if (mo2->health == toucher->tracer->health) // do ideya numberes match? + anchorpoint = mo2; + else if (toucher->tracer->hnext && mo2->health == toucher->tracer->hnext->health) + anchorpoint2 = mo2; + + if ((!toucher->tracer->hnext && anchorpoint) + || (toucher->tracer->hnext && anchorpoint && anchorpoint2)) + break; + } + } + + if (anchorpoint) + { + toucher->tracer->flags |= MF_GRENADEBOUNCE; // custom radius factors + toucher->tracer->threshold = 8 << 20; // X factor 0, Y factor 0, Z factor 8 + } + + if (anchorpoint2) + { + toucher->tracer->hnext->flags |= MF_GRENADEBOUNCE; // custom radius factors + toucher->tracer->hnext->threshold = 8 << 20; // X factor 0, Y factor 0, Z factor 8 + } + + P_SetTarget(&orbittarget->hnext, toucher->tracer); + if (!orbittarget->hnext->hnext) + P_SetTarget(&orbittarget->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. + else + P_SetTarget(&orbittarget->hnext->hnext->target, anchorpoint2 ? anchorpoint2 : orbittarget); + P_SetTarget(&orbittarget->hnext->target, anchorpoint ? anchorpoint : orbittarget); + P_SetTarget(&toucher->tracer, NULL); + + if (hnext) + { + orbittarget->hnext->extravalue1 = (angle_t)(hnext->extravalue1 - 72*ANG1); + if (orbittarget->hnext->extravalue1 > hnext->extravalue1) + orbittarget->hnext->extravalue1 -= (72*ANG1)/orbittarget->hnext->extravalue1; + } } - else // Make sure that SOMEONE has the emerald, at least! + if (player->exiting) // ...then move it back? { - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].playerstate == PST_LIVE - && players[i].mo->tracer && players[i].mo->tracer->target - && players[i].mo->tracer->target->type == MT_GOTEMERALD) - return; - // Well no one has an emerald, so exit anyway! + mobj_t *hnext = special->target ? special->target : special; // goalpost + while ((hnext = hnext->hnext)) + { + hnext->flags &= ~MF_GRENADEBOUNCE; + hnext->threshold = 0; + P_SetTarget(&hnext->target, toucher); + } } - P_GiveEmerald(false); - // Don't play Ideya sound in special stage mode + return; } - else - S_StartSound(toucher, special->info->activesound); - } - else //Initial transformation. Don't allow second chances in special stages! - { - if (player->pflags & PF_NIGHTSMODE) + + if (!cangiveemmy) return; - S_StartSound(toucher, sfx_supert); + if (player->exiting) + P_GiveEmerald(false); + else if (player->mo->tracer && player->mare) + { + P_KillMobj(toucher->tracer, NULL, NULL, 0); // No emerald for you just yet! + S_StartSound(NULL, sfx_ghosty); + special->flags2 |= MF2_DONTDRAW; + } + + return; } - if (!(netgame || multiplayer) && !(player->pflags & PF_NIGHTSMODE)) - P_SetTarget(&special->tracer, toucher); - P_NightserizePlayer(player, special->health); // Transform! - return; case MT_NIGHTSLOOPHELPER: // One second delay if (special->fuse < toucher->fuse - TICRATE) @@ -760,7 +1001,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (mo2->flags & MF_SHOOTABLE) { - P_DamageMobj(mo2, toucher, toucher, 1); + P_DamageMobj(mo2, toucher, toucher, 1, 0); continue; } @@ -774,7 +1015,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!(mo2->flags & MF_SPECIAL) && mo2->health) { - P_SetMobjState(mo2, mo2->info->seestate); + mo2->flags2 &= ~MF2_DONTDRAW; mo2->flags |= MF_SPECIAL; mo2->flags &= ~MF_NIGHTSITEM; S_StartSound(toucher, sfx_hidden); @@ -782,13 +1023,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } } - if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN - || mo2->type == MT_BLUEBALL)) + 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)))) continue; // Yay! The thing's in reach! Pull it in! mo2->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT; mo2->flags2 |= MF2_NIGHTSPULL; + // New NiGHTS attract speed dummied out because the older behavior + // is exploited as a mechanic. Uncomment to enable. + mo2->movefactor = 0; // 32*FRACUNIT; // initialize the NightsItemChase timer P_SetTarget(&mo2->tracer, toucher); } } @@ -798,9 +1044,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; // make sure everything is as it should be, THEN take rings from players in special stages - if (player->pflags & PF_NIGHTSMODE && !toucher->target) + if (player->powers[pw_carry] == CR_NIGHTSMODE && !toucher->target) return; + if (toucher->tracer && toucher->tracer->health > 0) + return; // Don't have multiple ideya, unless it's the first one given (health = 0) + if (player->mare != special->threshold) // wrong mare return; @@ -808,18 +1057,16 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; if (G_IsSpecialStage(gamemap) && !player->exiting) - { // In special stages, share rings. Everyone gives up theirs to the player who touched the capsule + { // In special stages, share spheres. Everyone gives up theirs to the player who touched the capsule for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && (&players[i] != player) && players[i].mo->health > 1) + if (playeringame[i] && (&players[i] != player) && players[i].spheres > 0) { - toucher->health += players[i].mo->health-1; - player->health = toucher->health; - players[i].mo->health = 1; - players[i].health = players[i].mo->health; + player->spheres += players[i].spheres; + players[i].spheres = 0; } } - if (!(player->health > 1) || player->exiting) + if (player->spheres <= 0 || player->exiting) return; // Mark the player as 'pull into the capsule' @@ -838,7 +1085,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->bumpertime < TICRATE/4) { S_StartSound(toucher, special->info->seesound); - if (player->pflags & PF_NIGHTSMODE) + if (player->powers[pw_carry] == CR_NIGHTSMODE) { player->bumpertime = TICRATE/2; if (special->threshold > 0) @@ -847,13 +1094,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) player->flyangle = special->threshold; player->speed = FixedMul(special->info->speed, special->scale); - // Potentially causes axis transfer failures. - // Also rarely worked properly anyway. - //P_UnsetThingPosition(player->mo); - //player->mo->x = special->x; - //player->mo->y = special->y; - //P_SetThingPosition(player->mo); - toucher->z = special->z+(special->height/4); + P_SetTarget(&player->mo->hnext, special); // Reference bumper for position correction on next tic } else // More like a spring { @@ -889,19 +1130,19 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_ResetPlayer(player); - P_SetPlayerMobjState(toucher, S_PLAY_FALL1); + P_SetPlayerMobjState(toucher, S_PLAY_FALL); } } return; case MT_NIGHTSSUPERLOOP: - if (player->bot || !(player->pflags & PF_NIGHTSMODE)) + if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE)) return; if (!G_IsSpecialStage(gamemap)) player->powers[pw_nights_superloop] = (UINT16)special->info->speed; else { for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE) + if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE) players[i].powers[pw_nights_superloop] = (UINT16)special->info->speed; if (special->info->deathsound != sfx_None) S_StartSound(NULL, special->info->deathsound); @@ -916,14 +1157,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } break; case MT_NIGHTSDRILLREFILL: - if (player->bot || !(player->pflags & PF_NIGHTSMODE)) + if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE)) return; if (!G_IsSpecialStage(gamemap)) player->drillmeter = special->info->speed; else { for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE) + if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE) players[i].drillmeter = special->info->speed; if (special->info->deathsound != sfx_None) S_StartSound(NULL, special->info->deathsound); @@ -938,7 +1179,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } break; case MT_NIGHTSHELPER: - if (player->bot || !(player->pflags & PF_NIGHTSMODE)) + if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE)) return; if (!G_IsSpecialStage(gamemap)) { @@ -952,7 +1193,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { mobj_t *flickyobj; for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].mo && players[i].pflags & PF_NIGHTSMODE) { + if (playeringame[i] && players[i].mo && players[i].powers[pw_carry] == CR_NIGHTSMODE) { players[i].powers[pw_nights_helper] = (UINT16)special->info->speed; flickyobj = P_SpawnMobj(players[i].mo->x, players[i].mo->y, players[i].mo->z + players[i].mo->info->height, MT_NIGHTOPIANHELPER); P_SetTarget(&flickyobj->target, players[i].mo); @@ -970,21 +1211,23 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } break; case MT_NIGHTSEXTRATIME: - if (player->bot || !(player->pflags & PF_NIGHTSMODE)) + if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE)) return; if (!G_IsSpecialStage(gamemap)) { player->nightstime += special->info->speed; player->startedtime += special->info->speed; + player->lapstartedtime += special->info->speed; P_RestoreMusic(player); } else { for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE) + if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE) { players[i].nightstime += special->info->speed; players[i].startedtime += special->info->speed; + players[i].lapstartedtime += special->info->speed; P_RestoreMusic(&players[i]); } if (special->info->deathsound != sfx_None) @@ -1000,20 +1243,20 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } break; case MT_NIGHTSLINKFREEZE: - if (player->bot || !(player->pflags & PF_NIGHTSMODE)) + if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE)) return; if (!G_IsSpecialStage(gamemap)) { player->powers[pw_nights_linkfreeze] = (UINT16)special->info->speed; - player->linktimer = 2*TICRATE; + player->linktimer = nightslinktics; } else { for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE) + if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE) { players[i].powers[pw_nights_linkfreeze] += (UINT16)special->info->speed; - players[i].linktimer = 2*TICRATE; + players[i].linktimer = nightslinktics; } if (special->info->deathsound != sfx_None) S_StartSound(NULL, special->info->deathsound); @@ -1027,17 +1270,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Link Freeze")); } break; - case MT_NIGHTSWING: - if (G_IsSpecialStage(gamemap) && useNightsSS) - { // Pseudo-ring. - S_StartSound(toucher, special->info->painsound); - player->totalring++; - } - else - S_StartSound(toucher, special->info->activesound); - - P_DoNightsScore(player); - break; case MT_HOOPCOLLIDE: // This produces a kind of 'domino effect' with the hoop's pieces. for (; special->hprev != NULL; special = special->hprev); // Move to the first sprite in the hoop @@ -1068,7 +1300,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (G_IsSpecialStage(gamemap)) { for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE) + if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE) players[i].drillmeter += TICRATE/2; } else if (player->bot) @@ -1089,15 +1321,33 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Mario // // ***** // case MT_SHELL: - if (special->state == &states[S_SHELL]) // Resting anim { - // Kick that sucker around! - special->angle = toucher->angle; - P_InstaThrust(special, special->angle, FixedMul(special->info->speed, special->scale)); - S_StartSound(toucher, sfx_mario2); - P_SetMobjState(special, S_SHELL1); - P_SetTarget(&special->target, toucher); - special->threshold = (3*TICRATE)/2; + boolean bounceon = ((P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)); + if (special->threshold == TICRATE) // it's moving + { + if (bounceon) + { + // Stop it! + special->momx = special->momy = 0; + S_StartSound(toucher, sfx_mario2); + P_SetTarget(&special->target, NULL); + special->threshold = TICRATE - 1; + toucher->momz = -toucher->momz; + } + else // can't handle in PIT_CheckThing because of landing-on causing it to stop + P_DamageMobj(toucher, special, special->target, 1, 0); + } + else if (special->threshold == 0) + { + // Kick that sucker around! + special->movedir = ((special->movedir == 1) ? -1 : 1); + P_InstaThrust(special, toucher->angle, (special->info->speed*special->scale)); + S_StartSound(toucher, sfx_mario2); + P_SetTarget(&special->target, toucher); + special->threshold = (3*TICRATE)/2; + if (bounceon) + toucher->momz = -toucher->momz; + } } return; case MT_AXE: @@ -1109,7 +1359,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->bot) return; - junk.tag = 649; + junk.tag = LE_AXE; EV_DoElevator(&junk, bridgeFall, false); // scan the remaining thinkers to find koopa @@ -1119,20 +1369,29 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) continue; mo2 = (mobj_t *)th; - if (mo2->type == MT_KOOPA) - { - mo2->momz = 5*FRACUNIT; - break; - } + + if (mo2->type != MT_KOOPA) + continue; + + mo2->momz = 5*FRACUNIT; + break; } } break; case MT_FIREFLOWER: if (player->bot) return; - player->powers[pw_shield] |= SH_FIREFLOWER; - toucher->color = SKINCOLOR_WHITE; - G_GhostAddColor(GHC_FIREFLOWER); + + S_StartSound(toucher, sfx_mario3); + + player->powers[pw_shield] = (player->powers[pw_shield] & SH_NOSTACK)|SH_FIREFLOWER; + + if (!(player->powers[pw_super] || (mariomode && player->powers[pw_invulnerability]))) + { + player->mo->color = SKINCOLOR_WHITE; + G_GhostAddColor(GHC_FIREFLOWER); + } + break; // *************** // @@ -1162,16 +1421,44 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->starpostnum >= special->health) return; // Already hit this post - // Save the player's time and position. - player->starposttime = leveltime; - player->starpostx = toucher->x>>FRACBITS; - player->starposty = toucher->y>>FRACBITS; - player->starpostz = special->z>>FRACBITS; - player->starpostangle = special->angle; - player->starpostnum = special->health; + if (cv_coopstarposts.value && gametype == GT_COOP && (netgame || multiplayer)) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i]) + { + if (players[i].bot) // ignore dumb, stupid tails + continue; + + players[i].starposttime = leveltime; + players[i].starpostx = player->mo->x>>FRACBITS; + players[i].starposty = player->mo->y>>FRACBITS; + players[i].starpostz = special->z>>FRACBITS; + players[i].starpostangle = special->angle; + players[i].starpostnum = special->health; + + if (cv_coopstarposts.value == 2 && (players[i].playerstate == PST_DEAD || players[i].spectator) && P_GetLives(&players[i])) + P_SpectatorJoinGame(&players[i]); //players[i].playerstate = PST_REBORN; + } + } + S_StartSound(NULL, special->info->painsound); + } + else + { + // Save the player's time and position. + player->starposttime = leveltime; + player->starpostx = toucher->x>>FRACBITS; + player->starposty = toucher->y>>FRACBITS; + player->starpostz = special->z>>FRACBITS; + player->starpostangle = special->angle; + player->starpostnum = special->health; + S_StartSound(toucher, special->info->painsound); + } + P_ClearStarPost(special->health); - // Find all starposts in the level with this value. + // Find all starposts in the level with this value - INCLUDING this one! + if (!(netgame && circuitmap && player != &players[consoleplayer])) { thinker_t *th; mobj_t *mo2; @@ -1183,21 +1470,16 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) mo2 = (mobj_t *)th; - if (mo2 == special) + if (mo2->type != MT_STARPOST) + continue; + if (mo2->health != special->health) continue; - if (mo2->type == MT_STARPOST && mo2->health == special->health) - { - if (!(netgame && circuitmap && player != &players[consoleplayer])) - P_SetMobjState(mo2, mo2->info->painstate); - } + P_SetMobjState(mo2, mo2->info->painstate); } } S_StartSound(toucher, special->info->painsound); - - if (!(netgame && circuitmap && player != &players[consoleplayer])) - P_SetMobjState(special, special->info->painstate); return; case MT_FAKEMOBILE: @@ -1225,9 +1507,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) toucher->momz = -toucher->momz; if (player->pflags & PF_GLIDING) { - player->pflags &= ~(PF_GLIDING|PF_JUMPED); - P_SetPlayerMobjState(toucher, S_PLAY_FALL1); + player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); + P_SetPlayerMobjState(toucher, S_PLAY_FALL); } + player->homing = 0; // Play a bounce sound? S_StartSound(toucher, special->info->painsound); @@ -1235,7 +1518,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; case MT_BLACKEGGMAN_GOOPFIRE: - if (toucher->state != &states[S_PLAY_PAIN] && !player->powers[pw_flashing]) + if (!player->powers[pw_flashing]) { toucher->momx = 0; toucher->momy = 0; @@ -1243,13 +1526,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (toucher->momz != 0) special->momz = toucher->momz; - player->powers[pw_ingoop] = 2; - - if (player->pflags & PF_ITEMHANG) - { - P_SetTarget(&toucher->tracer, NULL); - player->pflags &= ~PF_ITEMHANG; - } + player->powers[pw_carry] = CR_BRAKGOOP; + P_SetTarget(&toucher->tracer, special); P_ResetPlayer(player); @@ -1261,28 +1539,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SetMobjState(special->target, special->target->info->raisestate); } } - else - player->powers[pw_ingoop] = 0; return; case MT_EGGSHIELD: { - fixed_t touchx, touchy, touchspeed; - angle_t angle; - - if (P_AproxDistance(toucher->x-special->x, toucher->y-special->y) > - P_AproxDistance((toucher->x-toucher->momx)-special->x, (toucher->y-toucher->momy)-special->y)) - { - touchx = toucher->x + toucher->momx; - touchy = toucher->y + toucher->momy; - } - else - { - touchx = toucher->x; - touchy = toucher->y; - } - - angle = R_PointToAngle2(special->x, special->y, touchx, touchy) - special->angle; - touchspeed = P_AproxDistance(toucher->momx, toucher->momy); + angle_t angle = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->angle; + fixed_t touchspeed = P_AproxDistance(toucher->momx, toucher->momy); + if (touchspeed < special->scale) + touchspeed = special->scale; // Blocked by the shield? if (!(angle > ANGLE_90 && angle < ANGLE_270)) @@ -1292,16 +1555,19 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) toucher->momz = -toucher->momz; if (player->pflags & PF_GLIDING) { - player->pflags &= ~(PF_GLIDING|PF_JUMPED); - P_SetPlayerMobjState(toucher, S_PLAY_FALL1); + player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); + P_SetPlayerMobjState(toucher, S_PLAY_FALL); } + player->homing = 0; // Play a bounce sound? S_StartSound(toucher, special->info->painsound); - return; + + // experimental bounce + if (special->target) + special->target->extravalue1 = -special->target->info->speed; } - else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)) - || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? + else { // Shatter the shield! toucher->momx = -toucher->momx/2; @@ -1326,11 +1592,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SetMobjState(special, special->info->seestate); } return; - case MT_SMALLMACECHAIN: - case MT_BIGMACECHAIN: - // Is this the last link in the chain? - if (toucher->momz > 0 || !(special->flags & MF_AMBUSH) - || (player->pflags & PF_ITEMHANG) || (player->pflags & PF_MACESPIN)) + case MT_SMALLGRABCHAIN: + case MT_BIGGRABCHAIN: + if (P_MobjFlip(toucher)*toucher->momz > 0 + || (player->powers[pw_carry])) return; if (toucher->z > special->z + special->height/2) @@ -1342,64 +1607,39 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->powers[pw_flashing]) return; + if (special->movefactor && special->tracer && special->tracer->angle != ANGLE_90 && special->tracer->angle != ANGLE_270) + { // I don't expect you to understand this, Mr Bond... + angle_t ang = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->tracer->angle; + if ((special->movefactor > 0) == (special->tracer->angle > ANGLE_90 && special->tracer->angle < ANGLE_270)) + ang += ANGLE_180; + if (ang < ANGLE_180) + return; // I expect you to die. + } + P_ResetPlayer(player); P_SetTarget(&toucher->tracer, special); - if (special->target && (special->target->type == MT_SPINMACEPOINT || special->target->type == MT_HIDDEN_SLING)) + if (special->tracer && !(special->tracer->flags2 & MF2_STRONGBOX)) { - player->pflags |= PF_MACESPIN; + player->powers[pw_carry] = CR_MACESPIN; S_StartSound(toucher, sfx_spin); - P_SetPlayerMobjState(toucher, S_PLAY_ATK1); + P_SetPlayerMobjState(toucher, S_PLAY_ROLL); } else - player->pflags |= PF_ITEMHANG; + player->powers[pw_carry] = CR_GENERIC; // Can't jump first frame player->pflags |= PF_JUMPSTASIS; - return; - case MT_BIGMINE: - case MT_BIGAIRMINE: - // Spawn explosion! - P_SpawnMobj(special->x, special->y, special->z, special->info->mass); - P_RadiusAttack(special, special, special->info->damage); - S_StartSound(special, special->info->deathsound); - P_SetMobjState(special, special->info->deathstate); - return; - case MT_SPECIALSPIKEBALL: - if (!(!useNightsSS && G_IsSpecialStage(gamemap))) // Only for old special stages - { - P_DamageMobj(toucher, special, special, 1); - return; - } - if (player->powers[pw_invulnerability] || player->powers[pw_flashing] - || (player->powers[pw_super] && !(ALL7EMERALDS(player->powers[pw_emeralds])))) + return; + case MT_EGGMOBILE2_POGO: + // sanity checks + if (!special->target || !special->target->health) return; - if (player->powers[pw_shield] || player->bot) //If One-Hit Shield + // Goomba Stomp'd! + if (special->target->momz < 0) { - P_RemoveShield(player); - S_StartSound(toucher, sfx_shldls); // Ba-Dum! Shield loss. - } - else - { - P_PlayRinglossSound(toucher); - if (toucher->health > 10) - toucher->health -= 10; - else - toucher->health = 1; - player->health = toucher->health; - } - - P_DoPlayerPain(player, special, NULL); - return; - case MT_EGGMOBILE2_POGO: - // sanity checks - if (!special->target || !special->target->health) - return; - // Goomba Stomp'd! - if (special->target->momz < 0) - { - P_DamageMobj(toucher, special, special->target, 1); + P_DamageMobj(toucher, special, special->target, 1, 0); //special->target->momz = -special->target->momz; special->target->momx = special->target->momy = 0; special->target->momz = 0; @@ -1411,7 +1651,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; case MT_EXTRALARGEBUBBLE: - if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) + if (player->powers[pw_shield] & SH_PROTECTWATER) return; if (maptol & TOL_NIGHTS) return; @@ -1428,7 +1668,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; // Only go in the mouth // Eaten by player! - if (player->powers[pw_underwater] && player->powers[pw_underwater] <= 12*TICRATE + 1) + if ((!player->bot) && (player->powers[pw_underwater] && player->powers[pw_underwater] <= 12*TICRATE + 1)) P_RestoreMusic(player); if (player->powers[pw_underwater] < underwatertics + 1) @@ -1436,12 +1676,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!player->climbing) { + if (player->bot && toucher->state-states != S_PLAY_GASP) + S_StartSound(toucher, special->info->deathsound); // Force it to play a sound for bots P_SetPlayerMobjState(toucher, S_PLAY_GASP); P_ResetPlayer(player); } toucher->momx = toucher->momy = toucher->momz = 0; - break; + + if (player->bot) + return; + else + break; case MT_WATERDROP: if (special->state == &states[special->info->spawnstate]) @@ -1454,6 +1700,74 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } return; + case MT_CANARIVORE_GAS: + // if player and gas touch, attach gas to player (overriding any gas that already attached) and apply slowdown effect + special->flags |= MF_NOGRAVITY|MF_NOCLIPHEIGHT; + P_UnsetThingPosition(special); + special->x = toucher->x - toucher->momx/2; + special->y = toucher->y - toucher->momy/2; + special->z = toucher->z - toucher->momz/2; + P_SetThingPosition(special); + toucher->momx = FixedMul(toucher->momx, 50*FRACUNIT/51); + toucher->momy = FixedMul(toucher->momy, 50*FRACUNIT/51); + special->momx = toucher->momx; + special->momy = toucher->momy; + special->momz = toucher->momz; + return; + + case MT_MINECARTSPAWNER: + if (!special->fuse || player->powers[pw_carry] != CR_MINECART) + { + mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); + P_SetTarget(&mcart->target, toucher); + mcart->angle = toucher->angle = player->drawangle = special->angle; + mcart->friction = FRACUNIT; + + P_ResetPlayer(player); + player->pflags |= PF_JUMPDOWN; + player->powers[pw_carry] = CR_MINECART; + toucher->player->pflags &= ~PF_APPLYAUTOBRAKE; + P_SetTarget(&toucher->tracer, mcart); + toucher->momx = toucher->momy = toucher->momz = 0; + + special->fuse = 3*TICRATE; + special->flags2 |= MF2_DONTDRAW; + } + return; + + case MT_MINECARTEND: + if (player->powers[pw_carry] == CR_MINECART && toucher->tracer && !P_MobjWasRemoved(toucher->tracer) && toucher->tracer->health) + { + fixed_t maxz = max(toucher->z, special->z + 35*special->scale); + + toucher->momx = toucher->tracer->momx/2; + toucher->momy = toucher->tracer->momy/2; + toucher->momz = toucher->tracer->momz + P_AproxDistance(toucher->tracer->momx, toucher->tracer->momy)/2; + P_ResetPlayer(player); + player->pflags &= ~PF_APPLYAUTOBRAKE; + P_SetPlayerMobjState(toucher, S_PLAY_FALL); + P_SetTarget(&toucher->tracer->target, NULL); + P_KillMobj(toucher->tracer, toucher, special, 0); + P_SetTarget(&toucher->tracer, NULL); + player->powers[pw_carry] = CR_NONE; + P_UnsetThingPosition(toucher); + toucher->x = special->x; + toucher->y = special->y; + toucher->z = maxz; + P_SetThingPosition(toucher); + } + return; + + case MT_MINECARTSWITCHPOINT: + if (player->powers[pw_carry] == CR_MINECART && toucher->tracer && !P_MobjWasRemoved(toucher->tracer) && toucher->tracer->health) + { + mobjflag2_t destambush = special->flags2 & MF2_AMBUSH; + angle_t angdiff = toucher->tracer->angle - special->angle; + if (angdiff > ANGLE_90 && angdiff < ANGLE_270) + destambush ^= MF2_AMBUSH; + toucher->tracer->flags2 = (toucher->tracer->flags2 & ~MF2_AMBUSH) | destambush; + } + return; default: // SOC or script pickup if (player->bot) return; @@ -1463,7 +1777,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } S_StartSound(toucher, special->info->deathsound); // was NULL, but changed to player so you could hear others pick up rings - P_KillMobj(special, NULL, toucher); + P_KillMobj(special, NULL, toucher, 0); } /** Prints death messages relating to a dying or hit player. @@ -1471,8 +1785,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) * \param player Affected player. * \param inflictor The attack weapon used, can be NULL. * \param source The attacker, can be NULL. + * \param damagetype The type of damage dealt to the player. If bit 7 (0x80) is set, this was an instant-kill. */ -static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *source) +static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype) { const char *str = NULL; boolean deathonly = false; @@ -1488,6 +1803,9 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour if (!player) return; // Impossible! + if (!player->mo) + return; // Also impossible! + if (player->spectator) return; // No messages for dying (crushed) spectators. @@ -1495,11 +1813,11 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour return; // Presumably it's obvious what's happening in splitscreen. #ifdef HAVE_BLUA - if (LUAh_HurtMsg(player, inflictor, source)) + if (LUAh_HurtMsg(player, inflictor, source, damagetype)) return; #endif - deadtarget = (player->health <= 0); + deadtarget = (player->mo->health <= 0); // Target's name snprintf(targetname, sizeof(targetname), "%s%s%s", @@ -1533,8 +1851,10 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour else switch (inflictor->type) { case MT_PLAYER: - if ((inflictor->player->powers[pw_shield] & SH_NOSTACK) == SH_BOMB) + if (damagetype == DMG_NUKE) // SH_ARMAGEDDON, armageddon shield str = M_GetText("%s%s's armageddon blast %s %s.\n"); + else if ((inflictor->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && (inflictor->player->pflags & PF_SHIELDABILITY)) + str = M_GetText("%s%s's elemental stomp %s %s.\n"); else if (inflictor->player->powers[pw_invulnerability]) str = M_GetText("%s%s's invincibility aura %s %s.\n"); else if (inflictor->player->powers[pw_super]) @@ -1584,27 +1904,11 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour } else switch (source->type) { - case MT_NULL: - switch(source->threshold) - { - case 42: - deathonly = true; - str = M_GetText("%s drowned.\n"); - break; - case 43: - str = M_GetText("%s was %s by spikes.\n"); - break; - case 44: - deathonly = true; - str = M_GetText("%s was crushed.\n"); - break; - } - break; - case MT_EGGMANICO: - case MT_EGGMANBOX: + case MT_EGGMAN_ICON: str = M_GetText("%s was %s by Eggman's nefarious TV magic.\n"); break; case MT_SPIKE: + case MT_WALLSPIKE: str = M_GetText("%s was %s by spikes.\n"); break; default: @@ -1615,30 +1919,52 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour else { // null source, environment kills - // TERRIBLE HACK for hit damage because P_DoPlayerPain moves the player... - // I'll put it back, I promise! - player->mo->z -= player->mo->momz+1; - if (P_PlayerTouchingSectorSpecial(player, 1, 2)) - str = M_GetText("%s was %s by chemical water.\n"); - else if (P_PlayerTouchingSectorSpecial(player, 1, 3)) - str = M_GetText("%s was %s by molten lava.\n"); - else if (P_PlayerTouchingSectorSpecial(player, 1, 4)) - str = M_GetText("%s was %s by electricity.\n"); - else if (deadtarget) - { - deathonly = true; - if (P_PlayerTouchingSectorSpecial(player, 1, 6) - || P_PlayerTouchingSectorSpecial(player, 1, 7)) - str = M_GetText("%s fell into a bottomless pit.\n"); - else if (P_PlayerTouchingSectorSpecial(player, 1, 12)) - str = M_GetText("%s asphyxiated in space.\n"); - else - str = M_GetText("%s died.\n"); + switch (damagetype) + { + case DMG_WATER: + str = M_GetText("%s was %s by chemical water.\n"); + break; + case DMG_FIRE: + str = M_GetText("%s was %s by molten lava.\n"); + break; + case DMG_ELECTRIC: + str = M_GetText("%s was %s by electricity.\n"); + break; + case DMG_SPIKE: + str = M_GetText("%s was %s by spikes.\n"); + break; + case DMG_DROWNED: + deathonly = true; + str = M_GetText("%s drowned.\n"); + break; + case DMG_CRUSHED: + deathonly = true; + str = M_GetText("%s was crushed.\n"); + break; + case DMG_DEATHPIT: + if (deadtarget) + { + deathonly = true; + str = M_GetText("%s fell into a bottomless pit.\n"); + } + break; + case DMG_SPACEDROWN: + if (deadtarget) + { + deathonly = true; + str = M_GetText("%s asphyxiated in space.\n"); + } + break; + default: + if (deadtarget) + { + deathonly = true; + str = M_GetText("%s died.\n"); + } + break; } if (!str) str = M_GetText("%s was %s by an environmental hazard.\n"); - - player->mo->z += player->mo->momz+1; } if (!str) // Should not happen! Unless we missed catching something above. @@ -1694,7 +2020,7 @@ void P_CheckTimeLimit(void) for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].spectator - || (players[i].pflags & PF_TAGGED) || (players[i].pflags & PF_TAGIT)) + || (players[i].pflags & PF_GAMETYPEOVER) || (players[i].pflags & PF_TAGIT)) continue; CONS_Printf(M_GetText("%s received double points for surviving the round.\n"), player_names[i]); @@ -1841,7 +2167,7 @@ void P_CheckSurvivors(void) spectators++; else if (players[i].pflags & PF_TAGIT) taggers++; - else if (!(players[i].pflags & PF_TAGGED)) + else if (!(players[i].pflags & PF_GAMETYPEOVER)) { survivorarray[survivors] = i; survivors++; @@ -1931,19 +2257,19 @@ boolean P_CheckRacers(void) * \param target The victim. * \param inflictor The attack weapon. May be NULL (environmental damage). * \param source The attacker. May be NULL. + * \param damagetype The type of damage dealt that killed the target. If bit 7 (0x80) was set, this was an instant-death. * \todo Cleanup, refactor, split up. * \sa P_DamageMobj */ -void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) +void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype) { - mobjtype_t item; mobj_t *mo; if (inflictor && (inflictor->type == MT_SHELL || inflictor->type == MT_FIREBALL)) P_SetTarget(&target->tracer, inflictor); - if (!useNightsSS && G_IsSpecialStage(gamemap) && target->player && sstimer > 6) - sstimer = 6; // Just let P_Ticker take care of the rest. + if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap) && target->player && target->player->nightstime > 6) + target->player->nightstime = 6; // Just let P_Ticker take care of the rest. if (target->flags & (MF_ENEMY|MF_BOSS)) target->momx = target->momy = target->momz = 0; @@ -1952,7 +2278,10 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) target->flags |= MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT; // Don't drop Tails 03-08-2000 if (target->flags2 & MF2_NIGHTSPULL) + { P_SetTarget(&target->tracer, NULL); + target->movefactor = 0; // reset NightsItemChase timer + } // dead target is no more shootable target->flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SPECIAL); @@ -1960,7 +2289,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) target->health = 0; // This makes it easy to check if something's dead elsewhere. #ifdef HAVE_BLUA - if (LUAh_MobjDeath(target, inflictor, source) || P_MobjWasRemoved(target)) + if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target)) return; #endif @@ -1969,7 +2298,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) { if (metalrecording) // Ack! Metal Sonic shouldn't die! Cut the tape, end recording! G_StopMetalRecording(); - if (gametype == GT_MATCH && cv_match_scoring.value == 0 // note, no team match suicide penalty + if (gametype == GT_MATCH // note, no team match suicide penalty && ((target == source) || (source == NULL && inflictor == NULL) || (source && !source->player))) { // Suicide penalty if (target->player->score >= 50) @@ -2011,28 +2340,34 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) // to make people want to actually dash towards/paraloop enemies if (++source->player->linkcount > source->player->maxlink) source->player->maxlink = source->player->linkcount; - source->player->linktimer = 2*TICRATE; + source->player->linktimer = nightslinktics; } } else { if (target->flags & MF_BOSS) score = 1000; - else if ((target->flags & MF_ENEMY) && !(target->flags & MF_MISSILE)) + else if ((target->flags & MF_ENEMY) && !(target->flags & MF_MISSILE) && target->info->spawnhealth) { + UINT8 locscoreadd = source->player->scoreadd + target->info->spawnhealth; mobj_t *scoremobj; UINT32 scorestate = mobjinfo[MT_SCORE].spawnstate; scoremobj = P_SpawnMobj(target->x, target->y, target->z + (target->height / 2), MT_SCORE); - // On ground? No chain starts. - if (!source->player->powers[pw_invulnerability] && P_IsObjectOnGround(source)) + // More Sonic-like point system + if (!mariomode) switch (locscoreadd) { - source->player->scoreadd = 0; - score = 100; + case 1: score = 100; break; + case 2: score = 200; scorestate += 1; break; + case 3: score = 500; scorestate += 2; break; + case 4: case 5: case 6: case 7: case 8: case 9: + case 10: case 11: case 12: case 13: case 14: + score = 1000; scorestate += 3; break; + default: score = 10000; scorestate += 4; break; } // Mario Mode has Mario-like chain point values - else if (mariomode) switch (++source->player->scoreadd) + else switch (locscoreadd) { case 1: score = 100; break; case 2: score = 200; scorestate += 1; break; @@ -2052,19 +2387,12 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) scorestate += 10; break; } - // More Sonic-like point system - else switch (++source->player->scoreadd) - { - case 1: score = 100; break; - case 2: score = 200; scorestate += 1; break; - case 3: score = 500; scorestate += 2; break; - case 4: case 5: case 6: case 7: case 8: case 9: - case 10: case 11: case 12: case 13: case 14: - score = 1000; scorestate += 3; break; - default: score = 10000; scorestate += 4; break; - } P_SetMobjState(scoremobj, scorestate); + + // On ground? No chain starts. + if (source->player->powers[pw_invulnerability] || !P_IsObjectOnGround(source)) + source->player->scoreadd = locscoreadd; } } @@ -2077,20 +2405,47 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) { target->flags &= ~(MF_SOLID|MF_SHOOTABLE); // does not block P_UnsetThingPosition(target); - target->flags |= MF_NOBLOCKMAP; + target->flags |= MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; P_SetThingPosition(target); - if (!target->player->bot && !G_IsSpecialStage(gamemap) + if ((target->player->lives <= 1) && (netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value == 0)) + ; + else if (!target->player->bot && !target->player->spectator && !G_IsSpecialStage(gamemap) && (target->player->lives != INFLIVES) && G_GametypeUsesLives()) { target->player->lives -= 1; // Lose a life Tails 03-11-2000 if (target->player->lives <= 0) // Tails 03-14-2000 { - if (P_IsLocalPlayer(target->player)/* && target->player == &players[consoleplayer] */) + boolean gameovermus = false; + if ((netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value != 1)) + { + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].lives > 0) + break; + } + if (i == MAXPLAYERS) + gameovermus = true; + } + else if (P_IsLocalPlayer(target->player)) + gameovermus = true; + + if (gameovermus) { S_StopMusic(); // Stop the Music! Tails 03-14-2000 - S_ChangeMusicInternal("gmover", false); // Yousa dead now, Okieday? Tails 03-14-2000 + S_ChangeMusicInternal("_gover", false); // Yousa dead now, Okieday? Tails 03-14-2000 + } + + if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) && numgameovers < maxgameovers) + { + numgameovers++; + if ((!modifiedgame || savemoddata) && cursaveslot > 0) + G_SaveGameOver((UINT32)cursaveslot, (target->player->continues <= 0)); } } } @@ -2128,7 +2483,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) } else { - if (!(target->player->pflags & PF_TAGGED)) + if (!(target->player->pflags & PF_GAMETYPEOVER)) { //otherwise, increment the tagger's score. //in hide and seek, suiciding players are counted as found. @@ -2140,7 +2495,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) P_AddPlayerScore(&players[w], 100); } - target->player->pflags |= PF_TAGGED; + target->player->pflags |= PF_GAMETYPEOVER; CONS_Printf(M_GetText("%s was found!\n"), player_names[target->player-players]); P_CheckSurvivors(); } @@ -2152,90 +2507,107 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) if (source && target && target->player && source->player) P_PlayVictorySound(source); // Killer laughs at you. LAUGHS! BWAHAHAHA! - // Drop stuff. - // This determines the kind of object spawned - // during the death frame of a thing. - if (!mariomode // Don't show birds, etc. in Mario Mode Tails 12-23-2001 - && target->flags & MF_ENEMY) + // Other death animation effects + switch(target->type) { - if (cv_soniccd.value) - item = MT_SEED; - else - { - INT32 prandom; + case MT_BOUNCEPICKUP: + case MT_RAILPICKUP: + case MT_AUTOPICKUP: + case MT_EXPLODEPICKUP: + case MT_SCATTERPICKUP: + case MT_GRENADEPICKUP: + P_SetObjectMomZ(target, FRACUNIT, false); + target->fuse = target->info->damage; + break; - switch (target->type) - { - case MT_REDCRAWLA: - case MT_GOLDBUZZ: - case MT_SKIM: - case MT_UNIDUS: - item = MT_BUNNY; - break; + case MT_BUBBLEBUZZ: + if (inflictor && inflictor->player // did a player kill you? Spawn relative to the player so they're bound to get it + && P_AproxDistance(inflictor->x - target->x, inflictor->y - target->y) <= inflictor->radius + target->radius + FixedMul(8*FRACUNIT, inflictor->scale) // close enough? + && inflictor->z <= target->z + target->height + FixedMul(8*FRACUNIT, inflictor->scale) + && inflictor->z + inflictor->height >= target->z - FixedMul(8*FRACUNIT, inflictor->scale)) + mo = P_SpawnMobj(inflictor->x + inflictor->momx, inflictor->y + inflictor->momy, inflictor->z + (inflictor->height / 2) + inflictor->momz, MT_EXTRALARGEBUBBLE); + else + mo = P_SpawnMobj(target->x, target->y, target->z, MT_EXTRALARGEBUBBLE); + mo->destscale = target->scale; + P_SetScale(mo, mo->destscale); + break; - case MT_BLUECRAWLA: - case MT_JETTBOMBER: - case MT_GFZFISH: - item = MT_BIRD; - break; + case MT_YELLOWSHELL: + P_SpawnMobjFromMobj(target, 0, 0, 0, MT_YELLOWSPRING); + break; - case MT_JETTGUNNER: - case MT_CRAWLACOMMANDER: - case MT_REDBUZZ: - case MT_DETON: - item = MT_MOUSE; - break; + case MT_CRAWLACOMMANDER: + target->momx = target->momy = target->momz = 0; + break; - case MT_GSNAPPER: - case MT_EGGGUARD: - case MT_SPRINGSHELL: - item = MT_COW; - break; + case MT_CRUSHSTACEAN: + if (target->tracer) + { + mobj_t *chain = target->tracer->target, *chainnext; + while (chain) + { + chainnext = chain->target; + P_RemoveMobj(chain); + chain = chainnext; + } + S_StopSound(target->tracer); + P_KillMobj(target->tracer, inflictor, source, damagetype); + } + break; - case MT_MINUS: - case MT_VULTURE: - case MT_POINTY: - case MT_YELLOWSHELL: - item = MT_CHICKEN; - break; + case MT_EGGSHIELD: + P_SetObjectMomZ(target, 4*target->scale, false); + P_InstaThrust(target, target->angle, 3*target->scale); + target->flags = (target->flags|MF_NOCLIPHEIGHT) & ~MF_NOGRAVITY; + break; - case MT_AQUABUZZ: - item = MT_REDBIRD; - break; + case MT_EGGMOBILE3: + { + thinker_t *th; + UINT32 i = 0; // to check how many clones we've removed - default: - if (target->info->doomednum) - prandom = target->info->doomednum%5; // "Random" animal for new enemies. - else - prandom = P_RandomKey(5); // No placable object, just use a random number. + // scan the thinkers to make sure all the old pinch dummies are gone on death + // this can happen if the boss was hurt earlier than expected + for (th = thinkercap.next; th != &thinkercap; th = th->next) + { + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; - switch(prandom) + mo = (mobj_t *)th; + if (mo->type == (mobjtype_t)target->info->mass && mo->tracer == target) { - default: item = MT_BUNNY; break; - case 1: item = MT_BIRD; break; - case 2: item = MT_MOUSE; break; - case 3: item = MT_COW; break; - case 4: item = MT_CHICKEN; break; + P_RemoveMobj(mo); + i++; } - break; + if (i == 2) // we've already removed 2 of these, let's stop now + break; + } } - } + break; - mo = P_SpawnMobj(target->x, target->y, target->z + (target->height / 2) - FixedMul(mobjinfo[item].height / 2, target->scale), item); - mo->destscale = target->scale; - P_SetScale(mo, mo->destscale); - } - // Other death animation effects - else switch(target->type) - { - case MT_BOUNCEPICKUP: - case MT_RAILPICKUP: - case MT_AUTOPICKUP: - case MT_EXPLODEPICKUP: - case MT_SCATTERPICKUP: - case MT_GRENADEPICKUP: - P_SetObjectMomZ(target, FRACUNIT, false); - target->fuse = target->info->damage; + case MT_BIGMINE: + if (inflictor) + { + fixed_t dx = target->x - inflictor->x, dy = target->y - inflictor->y, dz = target->z - inflictor->z; + fixed_t dm = FixedHypot(dz, FixedHypot(dy, dx)); + target->momx = FixedDiv(FixedDiv(dx, dm), dm)*512; + target->momy = FixedDiv(FixedDiv(dy, dm), dm)*512; + target->momz = FixedDiv(FixedDiv(dz, dm), dm)*512; + } + if (source) + P_SetTarget(&target->tracer, source); + break; + + case MT_BLASTEXECUTOR: + if (target->spawnpoint) + P_LinedefExecute(target->spawnpoint->angle, (source ? source : inflictor), target->subsector->sector); + break; + + case MT_SPINBOBERT: + if (target->hnext) + P_KillMobj(target->hnext, inflictor, source, damagetype); + if (target->hprev) + P_KillMobj(target->hprev, inflictor, source, damagetype); break; case MT_EGGTRAP: @@ -2243,161 +2615,203 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) target->fuse = TICRATE*2; break; - case MT_PLAYER: - target->fuse = TICRATE*3; // timer before mobj disappears from view (even if not an actual player) + case MT_MINECART: + A_Scream(target); target->momx = target->momy = target->momz = 0; - if (!(source && source->type == MT_NULL && source->threshold == 42)) // Don't jump up when drowning - P_SetObjectMomZ(target, 14*FRACUNIT, false); + if (target->target && target->target->health) + P_KillMobj(target->target, target, source, 0); + break; - if (source && source->type == MT_NULL && source->threshold == 42) // drowned - S_StartSound(target, sfx_drown); - else if (source && (source->type == MT_SPIKE || (source->type == MT_NULL && source->threshold == 43))) // Spikes - S_StartSound(target, sfx_spkdth); - else - P_PlayDeathSound(target); + case MT_PLAYER: + { + target->fuse = TICRATE*3; // timer before mobj disappears from view (even if not an actual player) + target->momx = target->momy = target->momz = 0; + + if (damagetype == DMG_DROWNED) // drowned + { + target->movedir = damagetype; // we're MOVING the Damage Into anotheR function... Okay, this is a bit of a hack. + if (target->player->charflags & SF_MACHINE) + S_StartSound(target, sfx_fizzle); + else + S_StartSound(target, sfx_drown); + // Don't jump up when drowning + } + else + { + P_SetObjectMomZ(target, 14*FRACUNIT, false); + if (damagetype == DMG_SPIKE) // Spikes + S_StartSound(target, sfx_spkdth); + else + P_PlayDeathSound(target); + } + } break; default: break; } - // Enemy drops that ALWAYS occur regardless of mode - if (target->type == MT_AQUABUZZ) // Additionally spawns breathable bubble for players to get + // Final state setting - do something instead of P_SetMobjState; + if (target->type == MT_SPIKE && target->info->deathstate != S_NULL) { - if (inflictor && inflictor->player // did a player kill you? Spawn relative to the player so he's bound to get it - && P_AproxDistance(inflictor->x - target->x, inflictor->y - target->y) <= inflictor->radius + target->radius + FixedMul(8*FRACUNIT, inflictor->scale) // close enough? - && inflictor->z <= target->z + target->height + FixedMul(8*FRACUNIT, inflictor->scale) - && inflictor->z + inflictor->height >= target->z - FixedMul(8*FRACUNIT, inflictor->scale)) - mo = P_SpawnMobj(inflictor->x + inflictor->momx, inflictor->y + inflictor->momy, inflictor->z + (inflictor->height / 2) + inflictor->momz, MT_EXTRALARGEBUBBLE); - else - mo = P_SpawnMobj(target->x, target->y, target->z, MT_EXTRALARGEBUBBLE); - mo->destscale = target->scale; - P_SetScale(mo, mo->destscale); - } - else if (target->type == MT_YELLOWSHELL) // Spawns a spring that falls to the ground - { - mobjtype_t spawnspring = MT_YELLOWSPRING; - fixed_t spawnheight = target->z; - if (!(target->eflags & MFE_VERTICALFLIP)) - spawnheight += target->height; + const angle_t ang = ((inflictor) ? inflictor->angle : 0) + ANGLE_90; + const fixed_t scale = target->scale; + const fixed_t xoffs = P_ReturnThrustX(target, ang, 8*scale), yoffs = P_ReturnThrustY(target, ang, 8*scale); + const UINT16 flip = (target->eflags & MFE_VERTICALFLIP); + mobj_t *chunk; + fixed_t momz; - mo = P_SpawnMobj(target->x, target->y, spawnheight, spawnspring); - mo->destscale = target->scale; - P_SetScale(mo, mo->destscale); - - if (target->flags2 & MF2_OBJECTFLIP) - mo->flags2 |= MF2_OBJECTFLIP; - } + S_StartSound(target, target->info->deathsound); - if (target->type == MT_EGGMOBILE3) - { - thinker_t *th; - UINT32 i = 0; // to check how many clones we've removed - - // scan the thinkers to make sure all the old pinch dummies are gone on death - // this can happen if the boss was hurt earlier than expected - for (th = thinkercap.next; th != &thinkercap; th = th->next) + if (target->info->xdeathstate != S_NULL) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - - mo = (mobj_t *)th; - if (mo->type == (mobjtype_t)target->info->mass && mo->tracer == target) - { - P_RemoveMobj(mo); - i++; - } - if (i == 2) // we've already removed 2 of these, let's stop now - break; + momz = 6*scale; + if (flip) + momz *= -1; +#define makechunk(angtweak, xmov, ymov) \ + chunk = P_SpawnMobj(target->x, target->y, target->z, MT_SPIKE);\ + chunk->eflags |= flip;\ + P_SetMobjState(chunk, target->info->xdeathstate);\ + chunk->health = 0;\ + chunk->angle = angtweak;\ + chunk->destscale = scale;\ + P_SetScale(chunk, scale);\ + P_UnsetThingPosition(chunk);\ + chunk->flags = MF_NOCLIP;\ + chunk->x += xmov;\ + chunk->y += ymov;\ + P_SetThingPosition(chunk);\ + P_InstaThrust(chunk,chunk->angle, 4*scale);\ + chunk->momz = momz + + makechunk(ang + ANGLE_180, -xoffs, -yoffs); + makechunk(ang, xoffs, yoffs); + +#undef makechunk } - } - if (target->type == MT_SPIKE && inflictor && target->info->deathstate != S_NULL) - { - const fixed_t x=target->x,y=target->y,z=target->z; - const fixed_t scale=target->scale; - const boolean flip=(target->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP; - S_StartSound(target,target->info->deathsound); + momz = 7*scale; + if (flip) + momz *= -1; + + chunk = P_SpawnMobj(target->x, target->y, target->z, MT_SPIKE); + chunk->eflags |= flip; + + P_SetMobjState(chunk, target->info->deathstate); + chunk->health = 0; + chunk->angle = ang + ANGLE_180; + chunk->destscale = scale; + P_SetScale(chunk, scale); + P_UnsetThingPosition(chunk); + chunk->flags = MF_NOCLIP; + chunk->x -= xoffs; + chunk->y -= yoffs; + if (flip) + chunk->z -= 12*scale; + else + chunk->z += 12*scale; + P_SetThingPosition(chunk); + P_InstaThrust(chunk, chunk->angle, 2*scale); + chunk->momz = momz; P_SetMobjState(target, target->info->deathstate); target->health = 0; - target->angle = inflictor->angle + ANGLE_90; + target->angle = ang; P_UnsetThingPosition(target); target->flags = MF_NOCLIP; - target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - if (flip) - target->z -= FixedMul(12*FRACUNIT, target->scale); - else - target->z += FixedMul(12*FRACUNIT, target->scale); + target->x += xoffs; + target->y += yoffs; + target->z = chunk->z; P_SetThingPosition(target); - P_InstaThrust(target,target->angle,FixedMul(2*FRACUNIT, target->scale)); - target->momz = FixedMul(7*FRACUNIT, target->scale); - if (flip) - target->momz = -target->momz; + P_InstaThrust(target, target->angle, 2*scale); + target->momz = momz; + } + else if (target->type == MT_WALLSPIKE && target->info->deathstate != S_NULL) + { + const angle_t ang = (/*(inflictor) ? inflictor->angle : */target->angle) + ANGLE_90; + const fixed_t scale = target->scale; + const fixed_t xoffs = P_ReturnThrustX(target, ang, 8*scale), yoffs = P_ReturnThrustY(target, ang, 8*scale), forwardxoffs = P_ReturnThrustX(target, target->angle, 7*scale), forwardyoffs = P_ReturnThrustY(target, target->angle, 7*scale); + const UINT16 flip = (target->eflags & MFE_VERTICALFLIP); + mobj_t *chunk; + boolean sprflip; - if (flip) + S_StartSound(target, target->info->deathsound); + if (!P_MobjWasRemoved(target->tracer)) + P_RemoveMobj(target->tracer); + + if (target->info->xdeathstate != S_NULL) { - target = P_SpawnMobj(x,y,z-FixedMul(12*FRACUNIT, target->scale),MT_SPIKE); - target->eflags |= MFE_VERTICALFLIP; + sprflip = P_RandomChance(FRACUNIT/2); + +#define makechunk(angtweak, xmov, ymov) \ + chunk = P_SpawnMobj(target->x, target->y, target->z, MT_WALLSPIKE);\ + chunk->eflags |= flip;\ + P_SetMobjState(chunk, target->info->xdeathstate);\ + chunk->health = 0;\ + chunk->angle = target->angle;\ + chunk->destscale = scale;\ + P_SetScale(chunk, scale);\ + P_UnsetThingPosition(chunk);\ + chunk->flags = MF_NOCLIP;\ + chunk->x += xmov - forwardxoffs;\ + chunk->y += ymov - forwardyoffs;\ + P_SetThingPosition(chunk);\ + P_InstaThrust(chunk, angtweak, 4*scale);\ + chunk->momz = P_RandomRange(5, 7)*scale;\ + if (flip)\ + chunk->momz *= -1;\ + if (sprflip)\ + chunk->frame |= FF_VERTICALFLIP + + makechunk(ang + ANGLE_180, -xoffs, -yoffs); + sprflip = !sprflip; + makechunk(ang, xoffs, yoffs); + +#undef makechunk } - else - target = P_SpawnMobj(x,y,z+FixedMul(12*FRACUNIT, target->scale),MT_SPIKE); + + sprflip = P_RandomChance(FRACUNIT/2); + + chunk = P_SpawnMobj(target->x, target->y, target->z, MT_WALLSPIKE); + chunk->eflags |= flip; + + P_SetMobjState(chunk, target->info->deathstate); + chunk->health = 0; + chunk->angle = target->angle; + chunk->destscale = scale; + P_SetScale(chunk, scale); + P_UnsetThingPosition(chunk); + chunk->flags = MF_NOCLIP; + chunk->x += forwardxoffs - xoffs; + chunk->y += forwardyoffs - yoffs; + P_SetThingPosition(chunk); + P_InstaThrust(chunk, ang + ANGLE_180, 2*scale); + chunk->momz = P_RandomRange(5, 7)*scale; + if (flip) + chunk->momz *= -1; + if (sprflip) + chunk->frame |= FF_VERTICALFLIP; + P_SetMobjState(target, target->info->deathstate); target->health = 0; - target->angle = inflictor->angle - ANGLE_90; - target->destscale = scale; - P_SetScale(target, scale); P_UnsetThingPosition(target); target->flags = MF_NOCLIP; - target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); + target->x += forwardxoffs + xoffs; + target->y += forwardyoffs + yoffs; P_SetThingPosition(target); - P_InstaThrust(target,target->angle,FixedMul(2*FRACUNIT, target->scale)); - target->momz = FixedMul(7*FRACUNIT, target->scale); + P_InstaThrust(target, ang, 2*scale); + target->momz = P_RandomRange(5, 7)*scale; if (flip) - target->momz = -target->momz; - - if (target->info->xdeathstate != S_NULL) - { - target = P_SpawnMobj(x,y,z,MT_SPIKE); - if (flip) - target->eflags |= MFE_VERTICALFLIP; - P_SetMobjState(target, target->info->xdeathstate); - target->health = 0; - target->angle = inflictor->angle + ANGLE_90; - target->destscale = scale; - P_SetScale(target, scale); - P_UnsetThingPosition(target); - target->flags = MF_NOCLIP; - target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - P_SetThingPosition(target); - P_InstaThrust(target,target->angle,FixedMul(4*FRACUNIT, target->scale)); - target->momz = FixedMul(6*FRACUNIT, target->scale); - if (flip) - target->momz = -target->momz; - - target = P_SpawnMobj(x,y,z,MT_SPIKE); - if (flip) - target->eflags |= MFE_VERTICALFLIP; - P_SetMobjState(target, target->info->xdeathstate); - target->health = 0; - target->angle = inflictor->angle - ANGLE_90; - target->destscale = scale; - P_SetScale(target, scale); - P_UnsetThingPosition(target); - target->flags = MF_NOCLIP; - target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - P_SetThingPosition(target); - P_InstaThrust(target,target->angle,FixedMul(4*FRACUNIT, target->scale)); - target->momz = FixedMul(6*FRACUNIT, target->scale); - if (flip) - target->momz = -target->momz; - } + target->momz *= -1; + if (!sprflip) + target->frame |= FF_VERTICALFLIP; } else if (target->player) - P_SetPlayerMobjState(target, target->info->deathstate); + { + if (damagetype == DMG_DROWNED || damagetype == DMG_SPACEDROWN) + P_SetPlayerMobjState(target, target->info->xdeathstate); + else + P_SetPlayerMobjState(target, target->info->deathstate); + } else #ifdef DEBUG_NULL_DEATHSTATE P_SetMobjState(target, S_NULL); @@ -2415,8 +2829,9 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source) player_t *player = target->player; tic_t oldnightstime = player->nightstime; - if (!player->powers[pw_flashing] - && !(player->pflags & PF_GODMODE)) + (void)source; // unused + + if (!player->powers[pw_flashing]) { angle_t fa; @@ -2429,20 +2844,10 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source) player->drillmeter -= 5*20; else { - if (source && source->player) - { - if (player->nightstime > 20*TICRATE) - player->nightstime -= 20*TICRATE; - else - player->nightstime = 1; - } + if (player->nightstime > 5*TICRATE) + player->nightstime -= 5*TICRATE; else - { - if (player->nightstime > 5*TICRATE) - player->nightstime -= 5*TICRATE; - else - player->nightstime = 1; - } + player->nightstime = 1; } if (player->pflags & PF_TRANSFERTOCLOSEST) @@ -2459,19 +2864,29 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source) } player->powers[pw_flashing] = flashingtics; - P_SetMobjState(target->tracer, S_NIGHTSHURT1); + P_SetPlayerMobjState(target, S_PLAY_NIGHTS_STUN); S_StartSound(target, sfx_nghurt); if (oldnightstime > 10*TICRATE && player->nightstime < 10*TICRATE) { - //S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH - S_ChangeMusicInternal("drown",false); + if ((mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN) +#ifdef _WIN32 + // win32 MIDI volume hack means we cannot fade down the music + && S_MusicType() != MU_MID +#endif + ) + { + S_FadeMusic(0, 10*MUSICRATE); + S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. + } + else + S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false); } } } -static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage) +static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { player_t *player = target->player; (void)damage; //unused parm @@ -2481,7 +2896,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou return false; // Ignore IT players shooting each other, unless friendlyfire is on. - if ((player->pflags & PF_TAGIT && !(cv_friendlyfire.value && + if ((player->pflags & PF_TAGIT && !((cv_friendlyfire.value || (damagetype & DMG_CANHURTSELF)) && source && source->player && source->player->pflags & PF_TAGIT))) return false; @@ -2491,7 +2906,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou // Don't allow players on the same team to hurt one another, // unless cv_friendlyfire is on. - if (!cv_friendlyfire.value && (player->pflags & PF_TAGIT) == (source->player->pflags & PF_TAGIT)) + if (!(cv_friendlyfire.value || (damagetype & DMG_CANHURTSELF)) && (player->pflags & PF_TAGIT) == (source->player->pflags & PF_TAGIT)) { if (!(inflictor->flags & MF_FIRE)) P_GivePlayerRings(player, 1); @@ -2504,7 +2919,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou if (source->player->pflags & PF_TAGIT && !(player->pflags & PF_TAGIT)) { P_AddPlayerScore(source->player, 100); //award points to tagger. - P_HitDeathMessages(player, inflictor, source); + P_HitDeathMessages(player, inflictor, source, 0); if (gametype == GT_TAG) //survivor { @@ -2513,7 +2928,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou } else { - player->pflags |= PF_TAGGED; //in hide and seek, the player is tagged and stays stationary. + player->pflags |= PF_GAMETYPEOVER; //in hide and seek, the player is tagged and stays stationary. CONS_Printf(M_GetText("%s was found!\n"), player_names[player-players]); // Tell everyone who is it! } @@ -2531,45 +2946,49 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou return true; } - if (target->health <= 1) // Death + if (player->powers[pw_carry] == CR_NIGHTSFALL) { - P_PlayDeathSound(target); - P_PlayVictorySound(source); // Killer laughs at you! LAUGHS! BWAHAHAHHAHAA!! + if (player->spheres > 0) + { + P_PlayRinglossSound(target); + P_PlayerRingBurst(player, player->spheres); + player->spheres = 0; + } } - else if (target->health > 1) // Ring loss + else if (player->rings > 0) // Ring loss { P_PlayRinglossSound(target); - P_PlayerRingBurst(player, player->mo->health - 1); + P_PlayerRingBurst(player, player->rings); + player->rings = 0; } - - if (inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) + else // Death { - player->health -= 10; - if (player->health < 2) - player->health = 2; - target->health = player->health; + P_PlayDeathSound(target); + P_PlayVictorySound(source); // Killer laughs at you! LAUGHS! BWAHAHAHHAHAA!! } - else - player->health = target->health = 1; - return true; } -static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage) +static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { player_t *player = target->player; - // You can't kill yourself, idiot... - if (source == target) - return false; + if (!(damagetype & DMG_CANHURTSELF)) + { + // You can't kill yourself, idiot... + if (source == target) + return false; - // In COOP/RACE/CHAOS, you can't hurt other players unless cv_friendlyfire is on - if (!cv_friendlyfire.value && (G_PlatformGametype())) - return false; + // In COOP/RACE, you can't hurt other players unless cv_friendlyfire is on + if (!cv_friendlyfire.value && (G_PlatformGametype())) + return false; + } // Tag handling if (G_TagGametype()) - return P_TagDamage(target, inflictor, source, damage); + return P_TagDamage(target, inflictor, source, damage, damagetype); + else if (damagetype & DMG_CANHURTSELF) + return true; else if (G_GametypeHasTeams()) // CTF + Team Match { // Don't allow players on the same team to hurt one another, @@ -2595,12 +3014,14 @@ static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) { - player->pflags &= ~(PF_CARRIED|PF_SLIDING|PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG|PF_NIGHTSMODE); + player->pflags &= ~PF_SLIDING; + + player->powers[pw_carry] = CR_NONE; // Burst weapons and emeralds in Match/CTF only if (source && (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF)) { - P_PlayerRingBurst(player, player->health - 1); + P_PlayerRingBurst(player, player->rings); P_PlayerEmeraldBurst(player, false); } @@ -2615,6 +3036,9 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) P_ResetPlayer(player); + if (!player->spectator) + player->mo->flags2 &= ~MF2_DONTDRAW; + P_SetPlayerMobjState(player->mo, player->mo->info->deathstate); if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) { @@ -2689,10 +3113,7 @@ static void P_SuperDamage(player_t *player, mobj_t *inflictor, mobj_t *source, I P_InstaThrust(player->mo, ang, fallbackspeed); - if (player->charflags & SF_SUPERANIMS) - P_SetPlayerMobjState(player->mo, S_PLAY_SUPERHIT); - else - P_SetPlayerMobjState(player->mo, player->mo->info->painstate); + P_SetPlayerMobjState(player->mo, S_PLAY_STUN); P_ResetPlayer(player); @@ -2704,31 +3125,33 @@ void P_RemoveShield(player_t *player) { if (player->powers[pw_shield] & SH_FORCE) { // Multi-hit - if ((player->powers[pw_shield] & 0xFF) == 0) - player->powers[pw_shield] &= ~SH_FORCE; - else + if (player->powers[pw_shield] & SH_FORCEHP) player->powers[pw_shield]--; + else + player->powers[pw_shield] &= SH_STACK; } - else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_NONE) + else if (player->powers[pw_shield] & SH_NOSTACK) + { // First layer shields + if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ARMAGEDDON) // Give them what's coming to them! + { + P_BlackOw(player); // BAM! + player->pflags |= PF_JUMPDOWN; + } + else + player->powers[pw_shield] &= SH_STACK; + } + else { // Second layer shields - player->powers[pw_shield] = SH_NONE; - // Reset fireflower - if (!player->powers[pw_super]) + if (((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) && !(player->powers[pw_super] || (mariomode && player->powers[pw_invulnerability]))) { player->mo->color = player->skincolor; G_GhostAddColor(GHC_NORMAL); } + player->powers[pw_shield] = SH_NONE; } - else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_BOMB) // Give them what's coming to them! - { - P_BlackOw(player); // BAM! - player->pflags |= PF_JUMPDOWN; - } - else - player->powers[pw_shield] = player->powers[pw_shield] & SH_STACK; } -static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage) +static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { // Must do pain first to set flashing -- P_RemoveShield can cause damage P_DoPlayerPain(player, source, inflictor); @@ -2737,7 +3160,7 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); - if (source && (source->type == MT_SPIKE || (source->type == MT_NULL && source->threshold == 43))) // spikes + if (damagetype == DMG_SPIKE) // spikes S_StartSound(player->mo, sfx_spkdth); else S_StartSound (player->mo, sfx_shldls); // Ba-Dum! Shield loss. @@ -2756,21 +3179,18 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, { // Award no points when players shoot each other when cv_friendlyfire is on. if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo)) - P_AddPlayerScore(source->player, cv_match_scoring.value == 1 ? 25 : 50); + P_AddPlayerScore(source->player, 50); } } -static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage) +static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype, boolean dospheres) { - if (!(inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) - { - P_DoPlayerPain(player, source, inflictor); + P_DoPlayerPain(player, source, inflictor); - P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); + P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); - if (source && (source->type == MT_SPIKE || (source->type == MT_NULL && source->threshold == 43))) // spikes - S_StartSound(player->mo, sfx_spkdth); - } + if (damagetype == DMG_SPIKE) // spikes + S_StartSound(player->mo, sfx_spkdth); if (source && source->player && !player->powers[pw_super]) //don't score points against super players { @@ -2792,26 +3212,86 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN // Ring loss sound plays despite hitting spikes P_PlayRinglossSound(player->mo); // Ringledingle! + P_PlayerRingBurst(player, damage); + + if (dospheres) + { + player->spheres -= damage; + if (player->spheres < 0) + player->spheres = 0; + } + else + { + player->rings -= damage; + if (player->rings < 0) + player->rings = 0; + } +} + +// +// P_SpecialStageDamage +// +// Do old special stage-style damaging +// Removes 5 seconds from the player, or knocks off their shield if they have one. +// If they don't have anything, just knock the player back anyway (this doesn't kill them). +// +void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source) +{ + tic_t oldnightstime = player->nightstime; + + if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super]) + return; + + if (player->powers[pw_shield] || player->bot) //If One-Hit Shield + { + P_RemoveShield(player); + S_StartSound(player->mo, sfx_shldls); // Ba-Dum! Shield loss. + } + else + { + S_StartSound(player->mo, sfx_nghurt); + if (player->nightstime > 5*TICRATE) + player->nightstime -= 5*TICRATE; + else + player->nightstime = 0; + } + + P_DoPlayerPain(player, inflictor, source); + + if (gametype == GT_CTF && player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)) + P_PlayerFlagBurst(player, false); + + if (oldnightstime > 10*TICRATE + && player->nightstime < 10*TICRATE) + { + if (mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN) + { + S_FadeMusic(0, 10*MUSICRATE); + S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. + } + else + S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false); + } } /** Damages an object, which may or may not be a player. * For melee attacks, source and inflictor are the same. * - * \param target The object being damaged. - * \param inflictor The thing that caused the damage: creature, missile, - * gargoyle, and so forth. Can be NULL in the case of - * environmental damage, such as slime or crushing. - * \param source The creature or person responsible. For example, if a - * player is hit by a ring, the player who shot it. In some - * cases, the target will go after this object after - * receiving damage. This can be NULL. - * \param damage Amount of damage to be dealt. 10000 is instant death. + * \param target The object being damaged. + * \param inflictor The thing that caused the damage: creature, missile, + * gargoyle, and so forth. Can be NULL in the case of + * environmental damage, such as slime or crushing. + * \param source The creature or person responsible. For example, if a + * player is hit by a ring, the player who shot it. In some + * cases, the target will go after this object after + * receiving damage. This can be NULL. + * \param damage Amount of damage to be dealt. + * \param damagetype Type of damage to be dealt. If bit 7 (0x80) is set, this is an instant-kill. * \return True if the target sustained damage, otherwise false. * \todo Clean up this mess, split into multiple functions. - * \todo Get rid of the magic number 10000. * \sa P_KillMobj */ -boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage) +boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { player_t *player; #ifdef HAVE_BLUA @@ -2829,9 +3309,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // Spectator handling if (netgame) { - if (damage == 42000 && target->player && target->player->spectator) - damage = 10000; - else if (target->player && target->player->spectator) + if (damagetype != DMG_SPECTATOR && target->player && target->player->spectator) return false; if (source && source->player && source->player->spectator) @@ -2842,7 +3320,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // Everything above here can't be forced. if (!metalrecording) { - UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage); + UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage, damagetype); if (P_MobjWasRemoved(target)) return (shouldForce == 1); // mobj was removed if (shouldForce == 1) @@ -2871,62 +3349,26 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (!force) { // Special case for team ring boxes - if (target->type == MT_REDRINGBOX && !(source->player->ctfteam == 1)) + if (target->type == MT_RING_REDBOX && !(source->player->ctfteam == 1)) return false; - if (target->type == MT_BLUERINGBOX && !(source->player->ctfteam == 2)) + if (target->type == MT_RING_BLUEBOX && !(source->player->ctfteam == 2)) return false; } - // Special case for Crawla Commander - if (target->type == MT_CRAWLACOMMANDER) - { - if (!force && target->fuse) // Invincible - return false; - -#ifdef HAVE_BLUA - if (LUAh_MobjDamage(target, inflictor, source, damage) || P_MobjWasRemoved(target)) - return true; -#endif - - if (target->health > 1) - { - if (target->info->painsound) - S_StartSound(target, target->info->painsound); - - target->fuse = TICRATE/2; - target->flags2 |= MF2_FRET; - } - else - { - target->flags |= MF_NOGRAVITY; - target->fuse = 0; - } - - target->momx = target->momy = target->momz = 0; - - P_InstaThrust(target, target->angle-ANGLE_180, FixedMul(5*FRACUNIT, target->scale)); - } - else if (target->flags & MF_BOSS) + if (target->flags & (MF_ENEMY|MF_BOSS)) { if (!force && target->flags2 & MF2_FRET) // Currently flashing from being hit return false; #ifdef HAVE_BLUA - if (LUAh_MobjDamage(target, inflictor, source, damage) || P_MobjWasRemoved(target)) + if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype) || P_MobjWasRemoved(target)) return true; #endif if (target->health > 1) target->flags2 |= MF2_FRET; } -#ifdef HAVE_BLUA - else if (target->flags & MF_ENEMY) - { - if (LUAh_MobjDamage(target, inflictor, source, damage) || P_MobjWasRemoved(target)) - return true; - } -#endif player = target->player; @@ -2937,11 +3379,30 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (player->exiting) return false; - if (!(target->player->pflags & (PF_NIGHTSMODE|PF_NIGHTSFALL)) && (maptol & TOL_NIGHTS)) + if (player->pflags & PF_GODMODE) + return false; + + if ((maptol & TOL_NIGHTS) && target->player->powers[pw_carry] != CR_NIGHTSMODE && target->player->powers[pw_carry] != CR_NIGHTSFALL) return false; + + switch (damagetype) + { +#define DAMAGECASE(type)\ + case DMG_##type:\ + if (player->powers[pw_shield] & SH_PROTECT##type)\ + return false;\ + break + DAMAGECASE(WATER); + DAMAGECASE(FIRE); + DAMAGECASE(ELECTRIC); + DAMAGECASE(SPIKE); +#undef DAMAGECASE + default: + break; + } } - if (player->pflags & PF_NIGHTSMODE) // NiGHTS damage handling + if (player->powers[pw_carry] == CR_NIGHTSMODE) // NiGHTS damage handling { if (!force) { @@ -2949,191 +3410,148 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; // Don't hit yourself with your own paraloop, baka if (source && source->player && !cv_friendlyfire.value && (gametype == GT_COOP - || (G_GametypeHasTeams() && target->player->ctfteam == source->player->ctfteam))) + || (G_GametypeHasTeams() && player->ctfteam == source->player->ctfteam))) return false; // Don't run eachother over in special stages and team games and such } #ifdef HAVE_BLUA - if (LUAh_MobjDamage(target, inflictor, source, damage)) + if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) return true; #endif P_NiGHTSDamage(target, source); // -5s :( return true; } - if (!force && inflictor && (inflictor->flags & MF_FIRE)) + if (G_IsSpecialStage(gamemap)) { - if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) - return false; // Invincible to fire objects - - if (G_PlatformGametype() && source && source->player) - return false; // Don't get hurt by fire generated from friends. + P_SpecialStageDamage(player, inflictor, source); + return true; } - // Sudden-Death mode - if (source && source->type == MT_PLAYER) + if (!force && inflictor && inflictor->flags & MF_FIRE) { - if ((gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF) && cv_suddendeath.value - && !player->powers[pw_flashing] && !player->powers[pw_invulnerability]) - damage = 10000; + if (player->powers[pw_shield] & SH_PROTECTFIRE) + return false; // Invincible to fire objects + + if (G_PlatformGametype() && inflictor && source && source->player) + return false; // Don't get hurt by fire generated from friends. } // Player hits another player if (!force && source && source->player) { - if (!P_PlayerHitsPlayer(target, inflictor, source, damage)) + if (!P_PlayerHitsPlayer(target, inflictor, source, damage, damagetype)) return false; } - if (!force && player->pflags & PF_GODMODE) - return false; - // Instant-Death - if (damage == 10000) + if (damagetype & DMG_DEATHMASK) + { P_KillPlayer(player, source, damage); + player->rings = player->spheres = 0; + } else if (metalrecording) { if (!inflictor) inflictor = source; if (inflictor && inflictor->flags & MF_ENEMY) { // Metal Sonic destroy enemy !! - P_KillMobj(inflictor, NULL, target); + P_KillMobj(inflictor, NULL, target, damagetype); return false; } else if (inflictor && inflictor->flags & MF_MISSILE) return false; // Metal Sonic walk through flame !! else { // Oh no! Metal Sonic is hit !! - P_ShieldDamage(player, inflictor, source, damage); + P_ShieldDamage(player, inflictor, source, damage, damagetype); return true; } } - else if (player->powers[pw_invulnerability] || player->powers[pw_flashing] // ignore bouncing & such in invulnerability - || (player->powers[pw_super] && !(ALL7EMERALDS(player->powers[pw_emeralds]) && inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player)))) + else if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super]) // ignore bouncing & such in invulnerability { - if (force || (inflictor && (inflictor->flags & MF_MISSILE) - && (inflictor->flags2 & MF2_SUPERFIRE) - && player->powers[pw_super])) + if (force + || (inflictor && inflictor->flags & MF_MISSILE && inflictor->flags2 & MF2_SUPERFIRE)) // Super Sonic is stunned! { #ifdef HAVE_BLUA - if (!LUAh_MobjDamage(target, inflictor, source, damage)) + if (!LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) #endif P_SuperDamage(player, inflictor, source, damage); return true; } - else - return false; + return false; } #ifdef HAVE_BLUA - else if (LUAh_MobjDamage(target, inflictor, source, damage)) + else if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) return true; #endif - else if (!player->powers[pw_super] && (player->powers[pw_shield] || player->bot)) //If One-Hit Shield + else if (player->powers[pw_shield] || player->bot) //If One-Hit Shield { - P_ShieldDamage(player, inflictor, source, damage); + P_ShieldDamage(player, inflictor, source, damage, damagetype); damage = 0; } - else if (player->mo->health > 1) // No shield but have rings. + else if (player->powers[pw_carry] == CR_NIGHTSFALL) { - damage = player->mo->health - 1; - P_RingDamage(player, inflictor, source, damage); + // always damage so we can recoil upon losing points + damage = player->spheres; + P_RingDamage(player, inflictor, source, damage, damagetype, true); + damage = 0; } - else // No shield, no rings, no invincibility. + else if (player->rings > 0) // No shield but have rings. { - // To reduce griefing potential, don't allow players to be killed - // by friendly fire. Spilling their rings and other items is enough. - if (force || !(G_GametypeHasTeams() - && source && source->player && (source->player->ctfteam == player->ctfteam) - && cv_friendlyfire.value)) - { - damage = 1; - P_KillPlayer(player, source, damage); - } - else - { - damage = 0; - P_ShieldDamage(player, inflictor, source, damage); - } + damage = player->rings; + P_RingDamage(player, inflictor, source, damage, damagetype, false); + damage = 0; } - - if (inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) + // To reduce griefing potential, don't allow players to be killed + // by friendly fire. Spilling their rings and other items is enough. + else if (!force && G_GametypeHasTeams() + && source && source->player && (source->player->ctfteam == player->ctfteam) + && cv_friendlyfire.value) { - if (player->powers[pw_shield]) - { - P_RemoveShield(player); - return true; - } - else - { - player->health -= (10 * (1 << (INT32)(player->powers[pw_super] / 10500))); - if (player->health < 2) - player->health = 2; - } - - if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) - P_PlayerFlagBurst(player, false); + damage = 0; + P_ShieldDamage(player, inflictor, source, damage, damagetype); } - else + else // No shield, no rings, no invincibility. { - player->health -= damage; // mirror mobj health here - if (damage < 10000) - { - target->player->powers[pw_flashing] = flashingtics; - if (damage > 0) // don't spill emeralds/ammo/panels for shield damage - P_PlayerRingBurst(player, damage); - } + damage = 1; + P_KillPlayer(player, source, damage); } - if (player->health < 0) - player->health = 0; - - P_HitDeathMessages(player, inflictor, source); - P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); } // Killing dead. Just for kicks. // Require source and inflictor be player. Don't hurt for firing rings. if (cv_killingdead.value && (source && source->player) && (inflictor && inflictor->player) && P_RandomChance(5*FRACUNIT/16)) - P_DamageMobj(source, target, target, 1); + P_DamageMobj(source, target, target, 1, 0); // do the damage - if (player && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]) && inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player)) - { - target->health -= (10 * (1 << (INT32)(player->powers[pw_super] / 10500))); - if (target->health < 2) - target->health = 2; - } + if (damagetype & DMG_DEATHMASK) + target->health = 0; else target->health -= damage; + if (player) + P_HitDeathMessages(player, inflictor, source, damagetype); + if (source && source->player && target) G_GhostAddHit(target); if (target->health <= 0) { - P_KillMobj(target, inflictor, source); + P_KillMobj(target, inflictor, source, damagetype); return true; } if (player) - { - if (!(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) - P_ResetPlayer(target->player); - } + P_ResetPlayer(target->player); + else if ((target->type == MT_EGGMOBILE2) // egg slimer + && (target->health < target->info->damage)) // in pinch phase + P_SetMobjState(target, target->info->meleestate); // go to pinch pain state else - switch (target->type) - { - case MT_EGGMOBILE2: // egg slimer - if (target->health < target->info->damage) // in pinch phase - { - P_SetMobjState(target, target->info->meleestate); // go to pinch pain state - break; - } - /* FALLTHRU */ - default: - P_SetMobjState(target, target->info->painstate); - break; - } + P_SetMobjState(target, target->info->painstate); + + if (target->type == MT_HIVEELEMENTAL) + target->extravalue1 += 3; target->reactiontime = 0; // we're awake now... @@ -3142,16 +3560,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // if not intent on another player, // chase after this one P_SetTarget(&target->target, source); - if (target->state == &states[target->info->spawnstate] && target->info->seestate != S_NULL) - { - if (player) - { - if (!(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) - P_SetPlayerMobjState(target, target->info->seestate); - } - else - P_SetMobjState(target, target->info->seestate); - } } return true; @@ -3171,33 +3579,32 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) angle_t fa; fixed_t ns; fixed_t z; + boolean nightsreplace = ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)); // Better safe than sorry. if (!player) return; // If no health, don't spawn ring! - if (player->mo->health <= 1) + if (((maptol & TOL_NIGHTS) && player->spheres <= 0) || (!(maptol & TOL_NIGHTS) && player->rings <= 0)) num_rings = 0; - if (num_rings > 32 && !(player->pflags & PF_NIGHTSFALL)) + if (num_rings > 32 && player->powers[pw_carry] != CR_NIGHTSFALL) num_rings = 32; if (player->powers[pw_emeralds]) P_PlayerEmeraldBurst(player, false); // Spill weapons first - if (player->ringweapons) - P_PlayerWeaponPanelBurst(player); - - // Spill the ammo - P_PlayerWeaponAmmoBurst(player); + P_PlayerWeaponPanelOrAmmoBurst(player); for (i = 0; i < num_rings; i++) { INT32 objType = mobjinfo[MT_RING].reactiontime; if (mariomode) objType = mobjinfo[MT_COIN].reactiontime; + else if (player->powers[pw_carry] == CR_NIGHTSFALL) + objType = mobjinfo[(nightsreplace ? MT_NIGHTSCHIP : MT_BLUESPHERE)].reactiontime; z = player->mo->z; if (player->mo->eflags & MFE_VERTICALFLIP) @@ -3216,7 +3623,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) // Make rings spill out around the player in 16 directions like SA, but spill like Sonic 2. // Technically a non-SA way of spilling rings. They just so happen to be a little similar. - if (player->pflags & PF_NIGHTSFALL) + if (player->powers[pw_carry] == CR_NIGHTSFALL) { ns = FixedMul(((i*FRACUNIT)/16)+2*FRACUNIT, mo->scale); mo->momx = FixedMul(FINECOSINE(fa),ns); @@ -3226,6 +3633,9 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) P_SetObjectMomZ(mo, 8*FRACUNIT, false); mo->fuse = 20*TICRATE; // Adjust fuse for NiGHTS + + // Toggle bonus time colors + P_SetMobjState(mo, (player->bonustime ? mo->info->raisestate : mo->info->spawnstate)); } else { @@ -3260,9 +3670,6 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) player->losstime += 10*TICRATE; - if (P_IsObjectOnGround(player->mo)) - player->pflags &= ~PF_NIGHTSFALL; - return; } @@ -3448,6 +3855,75 @@ void P_PlayerWeaponAmmoBurst(player_t *player) } } +void P_PlayerWeaponPanelOrAmmoBurst(player_t *player) +{ + mobj_t *mo; + angle_t fa; + fixed_t ns; + INT32 i = 0; + fixed_t z; + + #define SETUP_DROP(thingtype) \ + z = player->mo->z; \ + if (player->mo->eflags & MFE_VERTICALFLIP) \ + z += player->mo->height - mobjinfo[thingtype].height; \ + fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT)) & FINEMASK; \ + ns = FixedMul(3*FRACUNIT, player->mo->scale); \ + + #define DROP_WEAPON(rwflag, pickup, ammo, power) \ + if (player->ringweapons & rwflag) \ + { \ + player->ringweapons &= ~rwflag; \ + SETUP_DROP(pickup) \ + mo = P_SpawnMobj(player->mo->x, player->mo->y, z, pickup); \ + mo->reactiontime = 0; \ + mo->flags2 |= MF2_DONTRESPAWN; \ + mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ + P_SetTarget(&mo->target, player->mo); \ + mo->fuse = 12*TICRATE; \ + mo->destscale = player->mo->scale; \ + P_SetScale(mo, player->mo->scale); \ + mo->momx = FixedMul(FINECOSINE(fa),ns); \ + if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ + mo->momy = FixedMul(FINESINE(fa),ns); \ + P_SetObjectMomZ(mo, 4*FRACUNIT, false); \ + if (i & 1) \ + P_SetObjectMomZ(mo, 4*FRACUNIT, true); \ + ++i; \ + } \ + else if (player->powers[power] > 0) \ + { \ + SETUP_DROP(ammo) \ + mo = P_SpawnMobj(player->mo->x, player->mo->y, z, ammo); \ + mo->health = player->powers[power]; \ + mo->flags2 |= MF2_DONTRESPAWN; \ + mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ + P_SetTarget(&mo->target, player->mo); \ + mo->fuse = 12*TICRATE; \ + mo->destscale = player->mo->scale; \ + P_SetScale(mo, player->mo->scale); \ + mo->momx = FixedMul(FINECOSINE(fa),ns); \ + if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ + mo->momy = FixedMul(FINESINE(fa),ns); \ + P_SetObjectMomZ(mo, 3*FRACUNIT, false); \ + if (i & 1) \ + P_SetObjectMomZ(mo, 3*FRACUNIT, true); \ + player->powers[power] = 0; \ + ++i; \ + } + + DROP_WEAPON(RW_BOUNCE, MT_BOUNCEPICKUP, MT_BOUNCERING, pw_bouncering); + DROP_WEAPON(RW_RAIL, MT_RAILPICKUP, MT_RAILRING, pw_railring); + DROP_WEAPON(RW_AUTO, MT_AUTOPICKUP, MT_AUTOMATICRING, pw_automaticring); + DROP_WEAPON(RW_EXPLODE, MT_EXPLODEPICKUP, MT_EXPLOSIONRING, pw_explosionring); + DROP_WEAPON(RW_SCATTER, MT_SCATTERPICKUP, MT_SCATTERRING, pw_scatterring); + DROP_WEAPON(RW_GRENADE, MT_GRENADEPICKUP, MT_GRENADERING, pw_grenadering); + DROP_WEAPON(0, 0, MT_INFINITYRING, pw_infinityring); + + #undef DROP_WEAPON + #undef SETUP_DROP +} + // // P_PlayerEmeraldBurst // diff --git a/src/p_lights.c b/src/p_lights.c index 2da38d1dc14052a0b8f8b0d528900142e481f3c7..67ec55e80b42125ded814d2ba48ffdb8235b737a 100644 --- a/src/p_lights.c +++ b/src/p_lights.c @@ -23,7 +23,7 @@ * * \param sector The sector to remove effects from. */ -static void P_RemoveLighting(sector_t *sector) +void P_RemoveLighting(sector_t *sector) { if (sector->lightingdata) { @@ -322,39 +322,70 @@ glow_t *P_SpawnAdjustableGlowingLight(sector_t *minsector, sector_t *maxsector, return g; } -/** Fades all the lights in sectors with a particular tag to a new +/** Fades all the lights in specified sector to a new * value. * - * \param tag Tag to look for sectors by. + * \param sector Target sector * \param destvalue The final light value in these sectors. - * \param speed Speed of the fade; the change to the ligh + * \param speed If tic-based: total duration of effect. + * If speed-based: Speed of the fade; the change to the ligh * level in each sector per tic. - * \todo Calculate speed better so that it is possible to specify - * the time for completion of the fade, and all lights fade - * in this time regardless of initial values. + * \param ticbased Use a specific duration for the fade, defined by speed * \sa T_LightFade */ -void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed) +void P_FadeLightBySector(sector_t *sector, INT32 destvalue, INT32 speed, boolean ticbased) { - INT32 i; lightlevel_t *ll; - sector_t *sector; - // search all sectors for ones with tag - for (i = -1; (i = P_FindSectorFromTag(tag, i)) >= 0 ;) + P_RemoveLighting(sector); // remove the old lighting effect first + + if ((ticbased && !speed) || sector->lightlevel == destvalue) // set immediately { - sector = §ors[i]; + sector->lightlevel = destvalue; + return; + } + + ll = Z_Calloc(sizeof (*ll), PU_LEVSPEC, NULL); + ll->thinker.function.acp1 = (actionf_p1)T_LightFade; + sector->lightingdata = ll; // set it to the lightlevel_t + + P_AddThinker(&ll->thinker); // add thinker - P_RemoveLighting(sector); // remove the old lighting effect first - ll = Z_Calloc(sizeof (*ll), PU_LEVSPEC, NULL); - ll->thinker.function.acp1 = (actionf_p1)T_LightFade; - sector->lightingdata = ll; // set it to the lightlevel_t + ll->sector = sector; + ll->sourcelevel = sector->lightlevel; + ll->destlevel = destvalue; - P_AddThinker(&ll->thinker); // add thinker + ll->fixedcurlevel = sector->lightlevel<<FRACBITS; - ll->sector = sector; - ll->destlevel = destvalue; - ll->speed = speed; + if (ticbased) + { + // Speed means duration. + ll->timer = abs(speed); + ll->fixedpertic = FixedDiv((destvalue<<FRACBITS) - ll->fixedcurlevel, speed<<FRACBITS); + } + else + { + // Speed means increment per tic (literally speed). + ll->timer = FixedDiv((destvalue<<FRACBITS) - ll->fixedcurlevel, speed<<FRACBITS)>>FRACBITS; + ll->fixedpertic = speed<<FRACBITS; + } +} + +void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased, boolean force) +{ + INT32 i; + // search all sectors for ones with tag + for (i = -1; (i = P_FindSectorFromTag(tag, i)) >= 0 ;) + { + if (!force && ticbased // always let speed fader execute + && sectors[i].lightingdata + && ((lightlevel_t*)sectors[i].lightingdata)->thinker.function.acp1 == (actionf_p1)T_LightFade) + // && ((lightlevel_t*)sectors[i].lightingdata)->timer > 2) + { + CONS_Debug(DBG_GAMELOGIC, "Line type 420 Executor: Fade light thinker already exists, timer: %d\n", ((lightlevel_t*)sectors[i].lightingdata)->timer); + continue; + } + P_FadeLightBySector(§ors[i], destvalue, speed, ticbased); } } @@ -365,30 +396,13 @@ void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed) */ void T_LightFade(lightlevel_t *ll) { - if (ll->sector->lightlevel < ll->destlevel) + if (--ll->timer <= 0) { - // increase the lightlevel - if (ll->sector->lightlevel + ll->speed >= ll->destlevel) - { - // stop changing light level - ll->sector->lightlevel = (INT16)ll->destlevel; // set to dest lightlevel - - P_RemoveLighting(ll->sector); // clear lightingdata, remove thinker - } - else - ll->sector->lightlevel = (INT16)(ll->sector->lightlevel + (INT16)ll->speed); // move lightlevel + ll->sector->lightlevel = ll->destlevel; // set to dest lightlevel + P_RemoveLighting(ll->sector); // clear lightingdata, remove thinker + return; } - else - { - // decrease lightlevel - if (ll->sector->lightlevel - ll->speed <= ll->destlevel) - { - // stop changing light level - ll->sector->lightlevel = (INT16)ll->destlevel; // set to dest lightlevel - P_RemoveLighting(ll->sector); // clear lightingdata, remove thinker - } - else - ll->sector->lightlevel = (INT16)(ll->sector->lightlevel - (INT16)ll->speed); // move lightlevel - } + ll->fixedcurlevel = ll->fixedcurlevel + ll->fixedpertic; + ll->sector->lightlevel = (ll->fixedcurlevel)>>FRACBITS; } diff --git a/src/p_local.h b/src/p_local.h index 9164fa7a0554868ddedb6e6ab9b228c3fe2e5ab4..2149a95bf06419c039a95d17927aedd16ecb81e9 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -25,10 +25,8 @@ #define FLOATSPEED (FRACUNIT*4) -#define VIEWHEIGHTS "41" - // Maximum player score. -#define MAXSCORE 999999990 +#define MAXSCORE 99999990 // 999999990 // mapblocks are used to check movement // against lines and things @@ -56,9 +54,13 @@ #define AIMINGTOSLOPE(aiming) FINESINE((aiming>>ANGLETOFINESHIFT) & FINEMASK) -#define mariomode (maptol & TOL_MARIO) #define twodlevel (maptol & TOL_2D) +#define mariomode (maptol & TOL_MARIO) + +#define P_GetPlayerHeight(player) FixedMul(player->height, player->mo->scale) +#define P_GetPlayerSpinHeight(player) FixedMul(player->spinheight, player->mo->scale) + // // P_TICK // @@ -115,14 +117,14 @@ extern consvar_t cv_cam2_speed, cv_cam2_rotate, cv_cam2_rotspeed; extern fixed_t t_cam_dist, t_cam_height, t_cam_rotate; extern fixed_t t_cam2_dist, t_cam2_height, t_cam2_rotate; -fixed_t P_GetPlayerHeight(player_t *player); -fixed_t P_GetPlayerSpinHeight(player_t *player); INT32 P_GetPlayerControlDirection(player_t *player); void P_AddPlayerScore(player_t *player, UINT32 amount); +void P_StealPlayerScore(player_t *player, UINT32 amount); void P_ResetCamera(player_t *player, camera_t *thiscam); boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam); void P_SlideCameraMove(camera_t *thiscam); boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled); +pflags_t P_GetJumpFlags(player_t *player); boolean P_PlayerInPain(player_t *player); void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor); void P_ResetPlayer(player_t *player); @@ -133,21 +135,31 @@ boolean P_IsObjectOnGround(mobj_t *mo); boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec); boolean P_InSpaceSector(mobj_t *mo); boolean P_InQuicksand(mobj_t *mo); +boolean P_PlayerHitFloor(player_t *player); void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative); void P_RestoreMusic(player_t *player); void P_SpawnShieldOrb(player_t *player); +void P_SwitchShield(player_t *player, UINT16 shieldtype); mobj_t *P_SpawnGhostMobj(mobj_t *mobj); void P_GivePlayerRings(player_t *player, INT32 num_rings); +void P_GivePlayerSpheres(player_t *player, INT32 num_spheres); void P_GivePlayerLives(player_t *player, INT32 numlives); +void P_GiveCoopLives(player_t *player, INT32 numlives, boolean sound); UINT8 P_GetNextEmerald(void); void P_GiveEmerald(boolean spawnObj); +#if 0 void P_ResetScore(player_t *player); +#else +#define P_ResetScore(player) player->scoreadd = 0 +#endif boolean P_AutoPause(void); void P_DoJumpShield(player_t *player); +void P_DoBubbleBounce(player_t *player); +void P_DoAbilityBounce(player_t *player, boolean changemomz); void P_BlackOw(player_t *player); -void P_ElementalFireTrail(player_t *player); +void P_ElementalFire(player_t *player, boolean cropcircle); void P_DoPityCheck(player_t *player); void P_PlayerThink(player_t *player); @@ -160,12 +172,16 @@ fixed_t P_ReturnThrustX(mobj_t *mo, angle_t angle, fixed_t move); fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move); void P_InstaThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move); -boolean P_LookForEnemies(player_t *player); +mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet); void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius); void P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user boolean P_SuperReady(player_t *player); void P_DoJump(player_t *player, boolean soundandstate); +#if 0 boolean P_AnalogMove(player_t *player); +#else +#define P_AnalogMove(player) (player->pflags & PF_ANALOGMODE) +#endif boolean P_TransferToNextMare(player_t *player); UINT8 P_FindLowestMare(void); void P_FindEmerald(void); @@ -180,6 +196,9 @@ void P_PlayLivesJingle(player_t *player); #define P_PlayDeathSound(s) S_StartSound(s, sfx_altdi1 + P_RandomKey(4)); #define P_PlayVictorySound(s) S_StartSound(s, sfx_victr1 + P_RandomKey(4)); +boolean P_GetLives(player_t *player); +boolean P_SpectatorJoinGame(player_t *player); +void P_RestoreMultiMusic(player_t *player); // // P_MOBJ @@ -194,7 +213,7 @@ void P_PlayLivesJingle(player_t *player); extern mapthing_t *itemrespawnque[ITEMQUESIZE]; extern tic_t itemrespawntime[ITEMQUESIZE]; extern size_t iquehead, iquetail; -extern consvar_t cv_gravity, cv_viewheight; +extern consvar_t cv_gravity, cv_movebob; void P_RespawnSpecials(void); @@ -210,6 +229,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state); boolean P_SetMobjState(mobj_t *mobj, statenum_t state); void P_RunShields(void); void P_RunOverlays(void); +void P_HandleMinecartSegments(mobj_t *mobj); void P_MobjThinker(mobj_t *mobj); boolean P_RailThinker(mobj_t *mobj); void P_PushableThinker(mobj_t *mobj); @@ -235,6 +255,9 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover); boolean P_CheckDeathPitCollide(mobj_t *mo); boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover); +void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype); + +mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type); mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type); mobj_t *P_SpawnXYZMissile(mobj_t *source, mobj_t *dest, mobjtype_t type, fixed_t x, fixed_t y, fixed_t z); @@ -257,6 +280,8 @@ mobj_t *P_GetClosestAxis(mobj_t *source); boolean P_CanRunOnWater(player_t *player, ffloor_t *rover); +void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot); + void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration); #define PAL_WHITE 1 #define PAL_MIXUP 2 @@ -283,6 +308,13 @@ boolean P_CheckMissileRange(mobj_t *actor); void P_NewChaseDir(mobj_t *actor); boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed_t dist); +mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers); +void P_InternalFlickySetColor(mobj_t *actor, UINT8 extrainfo); +#define P_IsFlickyCenter(type) (type > MT_FLICKY_01 && type < MT_SEED && (type - MT_FLICKY_01) % 2 ? 1 : 0) +void P_InternalFlickyBubble(mobj_t *actor); +void P_InternalFlickyFly(mobj_t *actor, fixed_t flyspeed, fixed_t targetdist, fixed_t chasez); +void P_InternalFlickyHop(mobj_t *actor, fixed_t momz, fixed_t momh, angle_t angle); + // // P_MAP // @@ -292,6 +324,7 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed extern boolean floatok; extern fixed_t tmfloorz; extern fixed_t tmceilingz; +extern ffloor_t *tmfloorrover, *tmceilingrover; extern mobj_t *tmfloorthing, *tmhitthing, *tmthing; extern camera_t *mapcampointer; extern fixed_t tmx; @@ -332,7 +365,7 @@ void P_DelPrecipSeclist(mprecipsecnode_t *node); void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y); void P_Initsecnode(void); -void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist); +void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 damagetype); fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height); boolean PIT_PushableMoved(mobj_t *thing); @@ -366,15 +399,37 @@ typedef struct BasicFF_s INT32 Magnitude; ///< Magnitude of the effect, in the range from 0 through 10,000. } BasicFF_t; +/* Damage/death types, for P_DamageMobj and related */ +//// Damage types +//#define DMG_NORMAL 0 (unneeded?) +#define DMG_WATER 1 +#define DMG_FIRE 2 +#define DMG_ELECTRIC 3 +#define DMG_SPIKE 4 +#define DMG_NUKE 5 // bomb shield +//#define DMG_SPECIALSTAGE 6 +//// Death types - cannot be combined with damage types +#define DMG_INSTAKILL 0x80 +#define DMG_DROWNED 0x80+1 +#define DMG_SPACEDROWN 0x80+2 +#define DMG_DEATHPIT 0x80+3 +#define DMG_CRUSHED 0x80+4 +#define DMG_SPECTATOR 0x80+5 +// Masks +#define DMG_CANHURTSELF 0x40 // Flag - can hurt self/team indirectly, such as through mines +#define DMG_DEATHMASK DMG_INSTAKILL // if bit 7 is set, this is a death type instead of a damage type + void P_ForceFeed(const player_t *player, INT32 attack, INT32 fade, tic_t duration, INT32 period); void P_ForceConstant(const BasicFF_t *FFInfo); void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End); void P_RemoveShield(player_t *player); -boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage); -void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source); +void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source); +boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); +void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); void P_PlayerRingBurst(player_t *player, INT32 num_rings); /// \todo better fit in p_user.c void P_PlayerWeaponPanelBurst(player_t *player); void P_PlayerWeaponAmmoBurst(player_t *player); +void P_PlayerWeaponPanelOrAmmoBurst(player_t *player); void P_PlayerEmeraldBurst(player_t *player, boolean toss); void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck); @@ -389,6 +444,7 @@ void P_ResetStarposts(void); boolean P_CanPickupItem(player_t *player, boolean weapon); void P_DoNightsScore(player_t *player); +void P_DoMatchSuper(player_t *player); // // P_SPEC diff --git a/src/p_map.c b/src/p_map.c index 95ad0258813acc587555ded086c4d7b6d58aadd6..abd4174d67c1748a65266082e64f55183a295f37 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -52,6 +52,7 @@ fixed_t tmfloorz, tmceilingz; static fixed_t tmdropoffz, tmdrpoffceilz; // drop-off floor/ceiling heights mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz is from a sector mobj_t *tmhitthing; // the solid thing you bumped into (for collisions) +ffloor_t *tmfloorrover, *tmceilingrover; #ifdef ESLOPE pslope_t *tmfloorslope, *tmceilingslope; #endif @@ -101,6 +102,8 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z) thing->floorz = tmfloorz; thing->ceilingz = tmceilingz; + thing->floorrover = tmfloorrover; + thing->ceilingrover = tmceilingrover; return true; } @@ -109,68 +112,204 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z) // MOVEMENT ITERATOR FUNCTIONS // ========================================================================= +// P_DoSpring +// +// MF_SPRING does some weird, mildly hacky stuff sometimes. +// mass = vertical speed +// damage = horizontal speed +// raisestate = state to change spring to on collision +// reactiontime = number of times it can give 10 points (0 is standard) +// painchance = spring mode: +// 0 = standard vanilla spring behaviour +// Positive spring modes are minor variants of vanilla spring behaviour. +// 1 = launch players in jump +// 2 = don't modify player at all, just add momentum +// Negative spring modes are mildly-related gimmicks with customisation. +// -1 = pinball bumper +// Any other spring mode defaults to standard vanilla spring behaviour, +// ****** but forward compatibility is not guaranteed for these. ****** +// + boolean P_DoSpring(mobj_t *spring, mobj_t *object) { - INT32 pflags; - fixed_t offx, offy; fixed_t vertispeed = spring->info->mass; fixed_t horizspeed = spring->info->damage; + boolean final = false; - if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic + // Object was already sprung this tic + if (object->eflags & MFE_SPRUNG) return false; // Spectators don't trigger springs. if (object->player && object->player->spectator) return false; - if (object->player && (object->player->pflags & PF_NIGHTSMODE)) - { - /*Someone want to make these work like bumpers?*/ + // "Even in Death" is a song from Volume 8, not a command. + if (!spring->health || !object->health) return false; - } -#ifdef ESLOPE - object->standingslope = NULL; // Okay, now we can't return - no launching off at silly angles for you. -#endif + if (spring->info->painchance == -1) // Pinball bumper mode. + { + // The first of the entirely different spring modes! + // Some of the attributes mean different things here. + // mass = default strength (can be controlled by mapthing's spawnangle) + // damage = unused + angle_t horizangle, vertiangle; - object->eflags |= MFE_SPRUNG; // apply this flag asap! - spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify + if (!vertispeed) + return false; - if (horizspeed && vertispeed) // Mimic SA - { - object->momx = object->momy = 0; - P_TryMove(object, spring->x, spring->y, true); + if (object->player && object->player->homing) // Sonic Heroes and Shadow the Hedgehog are the only games to contain homing-attackable bumpers! + { + horizangle = 0; + vertiangle = ((object->eflags & MFE_VERTICALFLIP) ? ANGLE_270 : ANGLE_90) >> ANGLETOFINESHIFT; + object->player->pflags &= ~PF_THOKKED; + if (spring->eflags & MFE_VERTICALFLIP) + object->z = spring->z - object->height - 1; + else + object->z = spring->z + spring->height + 1; + } + else + { + horizangle = R_PointToAngle2(spring->x, spring->y, object->x, object->y); + vertiangle = (R_PointToAngle2( + 0, + spring->z + spring->height/2, + FixedHypot(object->x - spring->x, object->y - spring->y), + object->z + object->height/2) + >> ANGLETOFINESHIFT) & FINEMASK; + } + + if (spring->spawnpoint && spring->spawnpoint->angle > 0) + vertispeed = (spring->spawnpoint->angle<<(FRACBITS-1))/5; + vertispeed = FixedMul(vertispeed, FixedMul(object->scale, spring->scale)); + + if (object->player) + { + fixed_t playervelocity; + + if (!(object->player->pflags & PF_THOKKED) && !(object->player->homing) + && ((playervelocity = FixedDiv(9*FixedHypot(object->player->speed, object->momz), 10<<FRACBITS)) > vertispeed)) + vertispeed = playervelocity; + + if (object->player->powers[pw_carry] == CR_NIGHTSMODE) // THIS has NiGHTS support, at least... + { + angle_t nightsangle = 0; + + if (object->player->bumpertime >= TICRATE/4) + return false; + + if ((object->player->pflags & PF_TRANSFERTOCLOSEST) && object->player->axis1 && object->player->axis2) + { + nightsangle = R_PointToAngle2(object->player->axis1->x, object->player->axis1->y, object->player->axis2->x, object->player->axis2->y); + nightsangle += ANGLE_90; + } + else if (object->target) + { + if (object->target->flags2 & MF2_AMBUSH) + nightsangle = R_PointToAngle2(object->target->x, object->target->y, object->x, object->y); + else + nightsangle = R_PointToAngle2(object->x, object->y, object->target->x, object->target->y); + } + + object->player->flyangle = AngleFixed(R_PointToAngle2( + 0, + spring->z + spring->height/2, + FixedMul( + FINESINE(((nightsangle - horizangle) >> ANGLETOFINESHIFT) & FINEMASK), + FixedHypot(object->x - spring->x, object->y - spring->y)), + object->z + object->height/2))>>FRACBITS; + + object->player->bumpertime = TICRATE/2; + } + else + { + INT32 pflags = object->player->pflags & (PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_BOUNCING); // Not identical to below... + UINT8 secondjump = object->player->secondjump; + if (object->player->pflags & PF_GLIDING) + P_SetPlayerMobjState(object, S_PLAY_FALL); + P_ResetPlayer(object->player); + object->player->pflags |= pflags; + object->player->secondjump = secondjump; + } + } + + if (!P_IsObjectOnGround(object)) // prevents uncurling when spinning due to "landing" + object->momz = FixedMul(vertispeed, FINESINE(vertiangle)); + P_InstaThrust(object, horizangle, FixedMul(vertispeed, FINECOSINE(vertiangle))); + + object->eflags |= MFE_SPRUNG; // apply this flag asap! + + goto springstate; } + // Does nothing? + if (!vertispeed && !horizspeed) + return false; + +#ifdef ESLOPE + object->standingslope = NULL; // Okay, now we know it's not going to be relevant - no launching off at silly angles for you. +#endif + if (spring->eflags & MFE_VERTICALFLIP) vertispeed *= -1; - if (vertispeed > 0) - object->z = spring->z + spring->height + 1; - else if (vertispeed < 0) - object->z = spring->z - object->height - 1; - else + if (object->player && (object->player->powers[pw_carry] == CR_NIGHTSMODE)) { - // Horizontal springs teleport you in FRONT of them. - object->momx = object->momy = 0; + /*Someone want to make these work like bumpers?*/ + return false; + } - // Overestimate the distance to position you at - offx = P_ReturnThrustX(spring, spring->angle, (spring->radius + object->radius + 1) * 2); - offy = P_ReturnThrustY(spring, spring->angle, (spring->radius + object->radius + 1) * 2); + if (object->player + && ((object->player->charability == CA_TWINSPIN && object->player->panim == PA_ABILITY) + || (object->player->charability2 == CA2_MELEE && object->player->panim == PA_ABILITY2))) + { + S_StartSound(object, sfx_s3k8b); + if (horizspeed) + horizspeed = FixedMul(horizspeed, (4*FRACUNIT)/3); + if (vertispeed) + vertispeed = FixedMul(vertispeed, (6*FRACUNIT)/5); // aprox square root of above + } - // Make it square by clipping - if (offx > (spring->radius + object->radius + 1)) - offx = spring->radius + object->radius + 1; - else if (offx < -(spring->radius + object->radius + 1)) - offx = -(spring->radius + object->radius + 1); + object->eflags |= MFE_SPRUNG; // apply this flag asap! + spring->flags &= ~(MF_SPRING|MF_SPECIAL); // De-solidify - if (offy > (spring->radius + object->radius + 1)) - offy = spring->radius + object->radius + 1; - else if (offy < -(spring->radius + object->radius + 1)) - offy = -(spring->radius + object->radius + 1); + if (spring->info->painchance != 2) + { + if ((horizspeed && vertispeed) || (object->player && object->player->homing)) // Mimic SA + { + object->momx = object->momy = 0; + P_TryMove(object, spring->x, spring->y, true); + } - // Set position! - P_TryMove(object, spring->x + offx, spring->y + offy, true); + if (vertispeed > 0) + object->z = spring->z + spring->height + 1; + else if (vertispeed < 0) + object->z = spring->z - object->height - 1; + else + { + fixed_t offx, offy; + // Horizontal springs teleport you in FRONT of them. + object->momx = object->momy = 0; + + // Overestimate the distance to position you at + offx = P_ReturnThrustX(spring, spring->angle, (spring->radius + object->radius + 1) * 2); + offy = P_ReturnThrustY(spring, spring->angle, (spring->radius + object->radius + 1) * 2); + + // Make it square by clipping + if (offx > (spring->radius + object->radius + 1)) + offx = spring->radius + object->radius + 1; + else if (offx < -(spring->radius + object->radius + 1)) + offx = -(spring->radius + object->radius + 1); + + if (offy > (spring->radius + object->radius + 1)) + offy = spring->radius + object->radius + 1; + else if (offy < -(spring->radius + object->radius + 1)) + offy = -(spring->radius + object->radius + 1); + + // Set position! + P_TryMove(object, spring->x + offx, spring->y + offy, true); + } } if (vertispeed) @@ -180,50 +319,89 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) P_InstaThrustEvenIn2D(object, spring->angle, FixedMul(horizspeed,FixedSqrt(FixedMul(object->scale, spring->scale)))); // Re-solidify - spring->flags |= (spring->info->flags & (MF_SPECIAL|MF_SOLID)); - - P_SetMobjState(spring, spring->info->raisestate); + spring->flags |= (spring->info->flags & (MF_SPRING|MF_SPECIAL)); if (object->player) { + INT32 pflags; + UINT8 secondjump; + boolean washoming; + if (spring->flags & MF_ENEMY) // Spring shells P_SetTarget(&spring->target, object); - if (horizspeed && object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0) + if (horizspeed) { - object->angle = spring->angle; - - if (!demoplayback || P_AnalogMove(object->player)) + object->player->drawangle = spring->angle; + if (object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0) { - if (object->player == &players[consoleplayer]) - localangle = spring->angle; - else if (object->player == &players[secondarydisplayplayer]) - localangle2 = spring->angle; + object->angle = spring->angle; + + if (!demoplayback || P_AnalogMove(object->player)) + { + if (object->player == &players[consoleplayer]) + localangle = spring->angle; + else if (object->player == &players[secondarydisplayplayer]) + localangle2 = spring->angle; + } } } - pflags = object->player->pflags & (PF_JUMPED|PF_SPINNING|PF_THOKKED); // I still need these. + pflags = object->player->pflags & (PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_BOUNCING); // I still need these. + secondjump = object->player->secondjump; + washoming = object->player->homing; + if (object->player->pflags & PF_GLIDING) + P_SetPlayerMobjState(object, S_PLAY_FALL); P_ResetPlayer(object->player); - if (P_MobjFlip(object)*vertispeed > 0) - P_SetPlayerMobjState(object, S_PLAY_SPRING); - else if (P_MobjFlip(object)*vertispeed < 0) - P_SetPlayerMobjState(object, S_PLAY_FALL1); - else // horizontal spring + if (spring->info->painchance == 1) // For all those ancient, SOC'd abilities. { - if (pflags & (PF_JUMPED|PF_SPINNING) && object->player->panim == PA_ROLL) - object->player->pflags = pflags; + object->player->pflags |= P_GetJumpFlags(object->player); + P_SetPlayerMobjState(object, S_PLAY_JUMP); + } + else if ((spring->info->painchance == 2) || (pflags & PF_BOUNCING)) // Adding momentum only. + { + object->player->pflags |= (pflags &~ PF_STARTJUMP); + object->player->secondjump = secondjump; + if (washoming) + object->player->pflags &= ~PF_THOKKED; + } + else if (!vertispeed) + { + if (pflags & (PF_JUMPED|PF_SPINNING)) + { + object->player->pflags |= pflags; + object->player->secondjump = secondjump; + } else - P_SetPlayerMobjState(object, S_PLAY_RUN1); + P_SetPlayerMobjState(object, S_PLAY_WALK); } + else if (P_MobjFlip(object)*vertispeed > 0) + P_SetPlayerMobjState(object, S_PLAY_SPRING); + else + P_SetPlayerMobjState(object, S_PLAY_FALL); + } + +#ifdef ESLOPE + object->standingslope = NULL; // And again. +#endif + + final = true; - if (spring->info->painchance) +springstate: + if ((statenum_t)(spring->state-states) < spring->info->raisestate) + { + P_SetMobjState(spring, spring->info->raisestate); + if (object->player && spring->reactiontime && !(spring->info->flags & MF_ENEMY)) { - object->player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(object, S_PLAY_ATK1); + if (object->player->powers[pw_carry] != CR_NIGHTSMODE) // don't make graphic in NiGHTS + P_SetMobjState(P_SpawnMobj(spring->x, spring->y, spring->z + (spring->height/2), MT_SCORE), mobjinfo[MT_SCORE].spawnstate+11); + P_AddPlayerScore(object->player, 10); + spring->reactiontime--; } } - return true; + + return final; } static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) @@ -274,7 +452,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) { P_ResetPlayer(p); if (p->panim != PA_FALL) - P_SetPlayerMobjState(object, S_PLAY_FALL1); + P_SetPlayerMobjState(object, S_PLAY_FALL); } break; case MT_STEAM: // Steam @@ -289,7 +467,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) { P_ResetPlayer(p); if (p->panim != PA_FALL) - P_SetPlayerMobjState(object, S_PLAY_FALL1); + P_SetPlayerMobjState(object, S_PLAY_FALL); } break; default: @@ -302,23 +480,21 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) INT32 p; fixed_t zdist; // z distance between the two players' bottoms - if ((tails->pflags & PF_CARRIED) && tails->mo->tracer == sonic->mo) + if (tails->powers[pw_carry]) return; - if ((sonic->pflags & PF_CARRIED) && sonic->mo->tracer == tails->mo) + if (sonic->powers[pw_carry]) return; - if (!tails->powers[pw_tailsfly] && !(tails->charability == CA_FLY && (tails->mo->state >= &states[S_PLAY_SPC1] && tails->mo->state <= &states[S_PLAY_SPC4]))) + if (tails->spectator) return; - - if (tails->bot == 1) + if (sonic->spectator) return; - if (sonic->pflags & PF_NIGHTSMODE) + if (!(tails->pflags & PF_CANCARRY)) return; - if (sonic->mo->tracer && sonic->mo->tracer->type == MT_TUBEWAYPOINT - && !(sonic->pflags & PF_ROPEHANG)) - return; // don't steal players from zoomtubes! + if (tails->bot == 1) + return; if ((sonic->mo->eflags & MFE_VERTICALFLIP) != (tails->mo->eflags & MFE_VERTICALFLIP)) return; // Both should be in same gravity @@ -334,57 +510,91 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) // Search in case another player is already being carried by this fox. for (p = 0; p < MAXPLAYERS; p++) if (playeringame[p] && players[p].mo - && players[p].pflags & PF_CARRIED && players[p].mo->tracer == tails->mo) + && players[p].powers[pw_carry] == CR_PLAYER && players[p].mo->tracer == tails->mo) return; + // Why block opposing teams from tailsflying each other? + // Sneaking into the hands of a flying tails player in Race might be a viable strategy, who knows. + /* + if (gametype == GT_RACE || gametype == GT_COMPETITION + || (netgame && (tails->spectator || sonic->spectator)) + || (G_TagGametype() && (!(tails->pflags & PF_TAGIT) != !(sonic->pflags & PF_TAGIT))) + || (gametype == GT_MATCH) + || (G_GametypeHasTeams() && tails->ctfteam != sonic->ctfteam)) + return; */ + if (tails->mo->eflags & MFE_VERTICALFLIP) zdist = (sonic->mo->z + sonic->mo->height) - (tails->mo->z + tails->mo->height); else zdist = tails->mo->z - sonic->mo->z; - if (zdist <= sonic->mo->height + FixedMul(FRACUNIT, sonic->mo->scale) + if (zdist <= sonic->mo->height + sonic->mo->scale // FixedMul(FRACUNIT, sonic->mo->scale), but scale == FRACUNIT by default && zdist > sonic->mo->height*2/3 && P_MobjFlip(tails->mo)*sonic->mo->momz <= 0) { - // Why block opposing teams from tailsflying each other? - // Sneaking into the hands of a flying tails player in Race might be a viable strategy, who knows. - /* - if (gametype == GT_RACE || gametype == GT_COMPETITION - || (netgame && (tails->spectator || sonic->spectator)) - || (G_TagGametype() && (!(tails->pflags & PF_TAGIT) != !(sonic->pflags & PF_TAGIT))) - || (gametype == GT_MATCH) - || (G_GametypeHasTeams() && tails->ctfteam != sonic->ctfteam)) - sonic->pflags &= ~PF_CARRIED; */ - if (tails->spectator || sonic->spectator) - sonic->pflags &= ~PF_CARRIED; - else - { - if (sonic-players == consoleplayer && botingame) - CV_SetValue(&cv_analog2, false); - P_ResetPlayer(sonic); - P_SetTarget(&sonic->mo->tracer, tails->mo); - sonic->pflags |= PF_CARRIED; - S_StartSound(sonic->mo, sfx_s3k4a); - P_UnsetThingPosition(sonic->mo); - sonic->mo->x = tails->mo->x; - sonic->mo->y = tails->mo->y; - P_SetThingPosition(sonic->mo); - } + if (sonic-players == consoleplayer && botingame) + CV_SetValue(&cv_analog2, false); + P_ResetPlayer(sonic); + P_SetTarget(&sonic->mo->tracer, tails->mo); + sonic->powers[pw_carry] = CR_PLAYER; + S_StartSound(sonic->mo, sfx_s3k4a); + P_UnsetThingPosition(sonic->mo); + sonic->mo->x = tails->mo->x; + sonic->mo->y = tails->mo->y; + P_SetThingPosition(sonic->mo); } else { if (sonic-players == consoleplayer && botingame) CV_SetValue(&cv_analog2, true); - sonic->pflags &= ~PF_CARRIED; + P_SetTarget(&sonic->mo->tracer, NULL); + sonic->powers[pw_carry] = CR_NONE; } } +// Boss 5 post-defeat comedy +static void P_SlapStick(mobj_t *fang, mobj_t *pole) +{ + fixed_t momx1, momx2, momy1, momy2; + +#define dist 3 + momx1 = pole->momx/dist; + momy1 = pole->momy/dist; + momx2 = fang->momx/dist; + momy2 = fang->momy/dist; + + pole->tracer->momx = momx1 + (dist-1)*momx2; + pole->tracer->momy = momy1 + (dist-1)*momy2; + fang->momx = (dist-1)*momx1 + momx2; + fang->momy = (dist-1)*momy1 + momy2; +#undef dist + + P_SetMobjState(pole, pole->info->deathstate); + + P_SetObjectMomZ(pole->tracer, 6*FRACUNIT, false); + pole->tracer->flags &= ~(MF_NOGRAVITY|MF_NOCLIP); + pole->tracer->movedir = ANGLE_67h; + if ((R_PointToAngle(fang->x - pole->tracer->x, fang->y - pole->tracer->y) - pole->angle) > ANGLE_180) + pole->tracer->movedir = InvAngle(pole->tracer->movedir); + + P_SetObjectMomZ(fang, 14*FRACUNIT, false); + fang->flags |= MF_NOGRAVITY|MF_NOCLIP; + P_SetMobjState(fang, fang->info->xdeathstate); + + pole->tracer->tics = pole->tics = fang->tics; + + var1 = var2 = 0; + A_Scream(pole->tracer); + S_StartSound(fang, sfx_altdi1); + + P_SetTarget(&pole->tracer, NULL); +} + // // PIT_CheckThing // static boolean PIT_CheckThing(mobj_t *thing) { fixed_t blockdist; - boolean iwassprung = false; // don't clip against self if (thing == tmthing) @@ -429,7 +639,9 @@ static boolean PIT_CheckThing(mobj_t *thing) // Metal Sonic destroys tiny baby objects. if (tmthing->type == MT_METALSONIC_RACE - && (thing->flags & (MF_MISSILE|MF_ENEMY|MF_BOSS) || thing->type == MT_SPIKE)) + && (thing->flags & (MF_MISSILE|MF_ENEMY|MF_BOSS) + || (thing->type == MT_SPIKE + || thing->type == MT_WALLSPIKE))) { if ((thing->flags & (MF_ENEMY|MF_BOSS)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE))) return true; @@ -441,27 +653,69 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // overhead if (tmthing->z + tmthing->height < thing->z) return true; // underneath - if (thing->type == MT_SPIKE) + if (thing->type == MT_SPIKE + || thing->type == MT_WALLSPIKE) + { + mobjtype_t type = thing->type; + if (thing->flags & MF_SOLID) + S_StartSound(tmthing, thing->info->deathsound); + for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext) + if (thing->type == type && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y), thing->z - tmthing->z) < 56*thing->scale)//FixedMul(56*FRACUNIT, thing->scale)) + P_KillMobj(thing, tmthing, tmthing, 0); + } + else + { + thing->health = 0; + P_KillMobj(thing, tmthing, tmthing, 0); + } + return true; + } + + // SF_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes. + if ((tmthing->player) + && (((tmthing->player->charflags & SF_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE) + && (thing->flags & (MF_MONITOR) + || (thing->type == MT_SPIKE + || thing->type == MT_WALLSPIKE))) + || ((((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY)) + || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)) + && (thing->type == MT_SPIKE + || thing->type == MT_WALLSPIKE)))) + { + if ((thing->flags & (MF_MONITOR)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE))) + return true; + blockdist = thing->radius + tmthing->radius; + if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist) + return true; // didn't hit it + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z) + return true; // underneath + if (thing->type == MT_SPIKE + || thing->type == MT_WALLSPIKE) { - S_StartSound(tmthing, thing->info->deathsound); + mobjtype_t type = thing->type; + if (thing->flags & MF_SOLID) + S_StartSound(tmthing, thing->info->deathsound); for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext) - if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale)) - P_KillMobj(thing, tmthing, tmthing); + if (thing->type == type && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y), thing->z - tmthing->z) < 56*thing->scale)//FixedMul(56*FRACUNIT, thing->scale)) + P_KillMobj(thing, tmthing, tmthing, 0); } else { thing->health = 0; - P_KillMobj(thing, tmthing, tmthing); + P_KillMobj(thing, tmthing, tmthing, 0); } return true; } - if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE))) + if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE|MF_SPRING))) return true; // Don't collide with your buddies while NiGHTS-flying. if (tmthing->player && thing->player && (maptol & TOL_NIGHTS) - && ((tmthing->player->pflags & PF_NIGHTSMODE) || (thing->player->pflags & PF_NIGHTSMODE))) + && ((tmthing->player->powers[pw_carry] == CR_NIGHTSMODE) || (thing->player->powers[pw_carry] == CR_NIGHTSMODE))) return true; blockdist = thing->radius + tmthing->radius; @@ -469,6 +723,80 @@ static boolean PIT_CheckThing(mobj_t *thing) if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist) return true; // didn't hit it + if (thing->flags & MF_PAPERCOLLISION) // CAUTION! Very easy to get stuck inside MF_SOLID objects. Giving the player MF_PAPERCOLLISION is a bad idea unless you know what you're doing. + { + fixed_t cosradius, sinradius; + vertex_t v1, v2; // fake vertexes + line_t junk; // fake linedef + + cosradius = FixedMul(thing->radius, FINECOSINE(thing->angle>>ANGLETOFINESHIFT)); + sinradius = FixedMul(thing->radius, FINESINE(thing->angle>>ANGLETOFINESHIFT)); + + v1.x = thing->x - cosradius; + v1.y = thing->y - sinradius; + v2.x = thing->x + cosradius; + v2.y = thing->y + sinradius; + + junk.v1 = &v1; + junk.v2 = &v2; + junk.dx = 2*cosradius; // v2.x - v1.x; + junk.dy = 2*sinradius; // v2.y - v1.y; + + if (tmthing->flags & MF_PAPERCOLLISION) // more strenuous checking to prevent clipping issues + { + INT32 check1, check2, check3, check4; + fixed_t tmcosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT)); + fixed_t tmsinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT)); + if (abs(thing->x - tmx) >= (abs(tmcosradius) + abs(cosradius)) || abs(thing->y - tmy) >= (abs(tmsinradius) + abs(sinradius))) + return true; // didn't hit it + check1 = P_PointOnLineSide(tmx - tmcosradius, tmy - tmsinradius, &junk); + check2 = P_PointOnLineSide(tmx + tmcosradius, tmy + tmsinradius, &junk); + check3 = P_PointOnLineSide(tmx + tmthing->momx - tmcosradius, tmy + tmthing->momy - tmsinradius, &junk); + check4 = P_PointOnLineSide(tmx + tmthing->momx + tmcosradius, tmy + tmthing->momy + tmsinradius, &junk); + if ((check1 == check2) && (check2 == check3) && (check3 == check4)) + return true; // the line doesn't cross between collider's start or end + } + else + { + if (abs(thing->x - tmx) >= (tmthing->radius + abs(cosradius)) || abs(thing->y - tmy) >= (tmthing->radius + abs(sinradius))) + return true; // didn't hit it + if ((P_PointOnLineSide(tmx - tmthing->radius, tmy - tmthing->radius, &junk) + == P_PointOnLineSide(tmx + tmthing->radius, tmy + tmthing->radius, &junk)) + && (P_PointOnLineSide(tmx + tmthing->radius, tmy - tmthing->radius, &junk) + == P_PointOnLineSide(tmx - tmthing->radius, tmy + tmthing->radius, &junk))) + return true; // the line doesn't cross between either pair of opposite corners + } + } + else if (tmthing->flags & MF_PAPERCOLLISION) + { + fixed_t tmcosradius, tmsinradius; + vertex_t v1, v2; // fake vertexes + line_t junk; // fake linedef + + tmcosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT)); + tmsinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT)); + + if (abs(thing->x - tmx) >= (thing->radius + abs(tmcosradius)) || abs(thing->y - tmy) >= (thing->radius + abs(tmsinradius))) + return true; // didn't hit it + + v1.x = tmx - tmcosradius; + v1.y = tmy - tmsinradius; + v2.x = tmx + tmcosradius; + v2.y = tmy + tmsinradius; + + junk.v1 = &v1; + junk.v2 = &v2; + junk.dx = 2*tmcosradius; // v2.x - v1.x; + junk.dy = 2*tmsinradius; // v2.y - v1.y; + + // no need to check whether other thing has MF_PAPERCOLLISION, since would fall under other condition + if ((P_PointOnLineSide(thing->x - thing->radius, thing->y - thing->radius, &junk) + == P_PointOnLineSide(thing->x + thing->radius, thing->y + thing->radius, &junk)) + && (P_PointOnLineSide(thing->x + thing->radius, thing->y - thing->radius, &junk) + == P_PointOnLineSide(thing->x - thing->radius, thing->y + thing->radius, &junk))) + return true; // the line doesn't cross between either pair of opposite corners + } + #ifdef HAVE_BLUA { UINT8 shouldCollide = LUAh_MobjCollide(thing, tmthing); // checks hook for thing's type @@ -490,6 +818,145 @@ static boolean PIT_CheckThing(mobj_t *thing) } #endif + if (tmthing->type == MT_MINECART) + { + //height check + if (tmthing->z > thing->z + thing->height || thing->z > tmthing->z + tmthing->height || !(thing->health)) + return true; + + if (thing->type == MT_TNTBARREL) + P_KillMobj(thing, tmthing, tmthing->target, 0); + else if ((thing->flags & MF_MONITOR) || (thing->flags & MF_ENEMY)) + { + P_KillMobj(thing, tmthing, tmthing->target, 0); + if (tmthing->momz*P_MobjFlip(tmthing) < 0) + tmthing->momz = abs(tmthing->momz)*P_MobjFlip(tmthing); + } + } + + if (thing->type == MT_SALOONDOOR && tmthing->player) + { + if (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer) && tmthing->tracer->health) + { + fixed_t dx = tmthing->tracer->momx; + fixed_t dy = tmthing->tracer->momy; + fixed_t dm = min(FixedHypot(dx, dy), 16*FRACUNIT); + angle_t ang = R_PointToAngle2(0, 0, dx, dy) - thing->angle; + fixed_t s = FINESINE((ang >> ANGLETOFINESHIFT) & FINEMASK); + S_StartSound(tmthing, thing->info->activesound); + thing->extravalue2 += 2*FixedMul(s, dm)/3; + return true; + } + } + + if (thing->type == MT_TNTBARREL && tmthing->player) + { + if (tmthing->momz < 0) + { + if (tmthing->z + tmthing->momz > thing->z + thing->height) + return true; + } + else + { + if (tmthing->z > thing->z + thing->height) + return true; + } + + if (tmthing->momz > 0) + { + if (tmthing->z + tmthing->height + tmthing->momz < thing->z) + return true; + } + else + { + if (tmthing->z + tmthing->height < thing->z) + return true; + } + + if ((tmthing->player->pflags & (PF_SPINNING | PF_GLIDING)) + || ((tmthing->player->pflags & PF_JUMPED) + && (!(tmthing->player->pflags & PF_NOJUMPDAMAGE) + || (tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) + || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2) + || ((tmthing->player->charflags & SF_STOMPDAMAGE || tmthing->player->pflags & PF_BOUNCING) + && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height / 2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)) + || (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (tmthing->player->pflags & PF_SHIELDABILITY))) + P_DamageMobj(thing, tmthing, tmthing, 1, 0); + } + + if (thing->type == MT_VULTURE && tmthing->type == MT_VULTURE) + { + fixed_t dx = thing->x - tmthing->x; + fixed_t dy = thing->y - tmthing->y; + fixed_t dz = thing->z - tmthing->z; + fixed_t dm = FixedHypot(dz, FixedHypot(dx, dy)); + thing->momx += FixedDiv(dx, dm); + thing->momy += FixedDiv(dy, dm); + thing->momz += FixedDiv(dz, dm); + } + + if (tmthing->type == MT_FANG && thing->type == MT_FSGNB) + { + if (thing->z > tmthing->z + tmthing->height) + return true; // overhead + if (thing->z + thing->height < tmthing->z) + return true; // underneath + if (!thing->tracer) + return true; + P_SlapStick(tmthing, thing); + // no return value was used in the original prototype script at this point, + // so I'm assuming we fall back on the solid code to determine how it all ends? + // -- Monster Iestyn + } + + // Billiards mines! + if (thing->type == MT_BIGMINE) + { + if (tmthing->type == MT_BIGMINE) + { + if (!tmthing->momx && !tmthing->momy) + return true; + if ((statenum_t)(thing->state-states) >= thing->info->meleestate) + return true; + if (thing->z > tmthing->z + tmthing->height) + return true; // overhead + if (thing->z + thing->height < tmthing->z) + return true; // underneath + + thing->momx = tmthing->momx/3; + thing->momy = tmthing->momy/3; + thing->momz = tmthing->momz/3; + tmthing->momx /= -8; + tmthing->momy /= -8; + tmthing->momz /= -8; + if (thing->info->activesound) + S_StartSound(thing, thing->info->activesound); + P_SetMobjState(thing, thing->info->meleestate); + P_SetTarget(&thing->tracer, tmthing->tracer); + return true; + } + else if (tmthing->type == MT_CRUSHCLAW) + { + if (tmthing->extravalue1 <= 0) + return true; + if ((statenum_t)(thing->state-states) >= thing->info->meleestate) + return true; + if (thing->z > tmthing->z + tmthing->height) + return true; // overhead + if (thing->z + thing->height < tmthing->z) + return true; // underneath + + thing->momx = P_ReturnThrustX(tmthing, tmthing->angle, 2*tmthing->extravalue1*tmthing->scale/3); + thing->momy = P_ReturnThrustY(tmthing, tmthing->angle, 2*tmthing->extravalue1*tmthing->scale/3); + if (thing->info->activesound) + S_StartSound(thing, thing->info->activesound); + P_SetMobjState(thing, thing->info->meleestate); + if (tmthing->tracer) + P_SetTarget(&thing->tracer, tmthing->tracer->target); + return false; + } + } + // When solid spikes move, assume they just popped up and teleport things on top of them to hurt. if (tmthing->type == MT_SPIKE && tmthing->flags & MF_SOLID) { @@ -503,30 +970,42 @@ static boolean PIT_CheckThing(mobj_t *thing) else thing->z = tmthing->z + tmthing->height + FixedMul(FRACUNIT, tmthing->scale); if (thing->flags & MF_SHOOTABLE) - P_DamageMobj(thing, tmthing, tmthing, 1); + P_DamageMobj(thing, tmthing, tmthing, 1, 0); return true; } - if (thing->flags & MF_PAIN) + if (thing->flags & MF_PAIN && tmthing->player) { // Player touches painful thing sitting on the floor // see if it went over / under if (thing->z > tmthing->z + tmthing->height) return true; // overhead if (thing->z + thing->height < tmthing->z) return true; // underneath - if (tmthing->player && tmthing->flags & MF_SHOOTABLE && thing->health > 0) - P_DamageMobj(tmthing, thing, thing, 1); + if (tmthing->flags & MF_SHOOTABLE && thing->health > 0) + { + UINT8 damagetype = (thing->info->mass & 0xFF); + if (!damagetype && thing->flags & MF_FIRE) // BURN! + damagetype = DMG_FIRE; + if (P_DamageMobj(tmthing, thing, thing, 1, damagetype) && (damagetype = (thing->info->mass>>8))) + S_StartSound(thing, damagetype); + } return true; } - else if (tmthing->flags & MF_PAIN) + else if (tmthing->flags & MF_PAIN && thing->player) { // Painful thing splats player in the face // see if it went over / under if (tmthing->z > thing->z + thing->height) return true; // overhead if (tmthing->z + tmthing->height < thing->z) return true; // underneath - if (thing->player && thing->flags & MF_SHOOTABLE && tmthing->health > 0) - P_DamageMobj(thing, tmthing, tmthing, 1); + if (thing->flags & MF_SHOOTABLE && tmthing->health > 0) + { + UINT8 damagetype = (tmthing->info->mass & 0xFF); + if (!damagetype && tmthing->flags & MF_FIRE) // BURN! + damagetype = DMG_FIRE; + if (P_DamageMobj(thing, tmthing, tmthing, 1, damagetype) && (damagetype = (tmthing->info->mass>>8))) + S_StartSound(tmthing, damagetype); + } return true; } @@ -572,6 +1051,7 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (tmz > thzh - sprarea && tmz < thzh) // Don't damage people springing up / down return true; } + // missiles can hit other things if (tmthing->flags & MF_MISSILE || tmthing->type == MT_SHELL) { @@ -621,42 +1101,21 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->flags & MF_MISSILE && thing->player && tmthing->target && tmthing->target->player && thing->player->ctfteam == tmthing->target->player->ctfteam - && thing->player->pflags & PF_CARRIED && thing->tracer == tmthing->target) + && thing->player->powers[pw_carry] == CR_PLAYER && thing->tracer == tmthing->target) return true; // Don't give rings to your carry player by accident. if (thing->type == MT_EGGSHIELD) { - fixed_t touchx, touchy; - angle_t angle; + angle_t angle = (R_PointToAngle2(thing->x, thing->y, tmthing->x - tmthing->momx, tmthing->y - tmthing->momy) - thing->angle) - ANGLE_90; - if (P_AproxDistance(tmthing->x-thing->x, tmthing->y-thing->y) > - P_AproxDistance((tmthing->x-tmthing->momx)-thing->x, (tmthing->y-tmthing->momy)-thing->y)) - { - touchx = tmthing->x + tmthing->momx; - touchy = tmthing->y + tmthing->momy; - } - else - { - touchx = tmthing->x; - touchy = tmthing->y; - } - - angle = R_PointToAngle2(thing->x, thing->y, touchx, touchy) - thing->angle; - - if (!(angle > ANGLE_90 && angle < ANGLE_270)) // hit front of shield, didn't destroy it - return false; - else // hit shield from behind, shield is destroyed! - { - P_KillMobj(thing, tmthing, tmthing); - return false; - } + if (angle < ANGLE_180) // hit shield from behind, shield is destroyed! + P_KillMobj(thing, tmthing, tmthing, 0); + return false; } - if (tmthing->type == MT_SHELL && tmthing->threshold > TICRATE) - return true; // damage / explode if (tmthing->flags & MF_ENEMY) // An actual ENEMY! (Like the deton, for example) - P_DamageMobj(thing, tmthing, tmthing, 1); + P_DamageMobj(thing, tmthing, tmthing, 1, 0); else if (tmthing->type == MT_BLACKEGGMAN_MISSILE && thing->player && (thing->player->pflags & PF_JUMPED) && !thing->player->powers[pw_flashing] @@ -664,8 +1123,8 @@ static boolean PIT_CheckThing(mobj_t *thing) && tmthing->target != thing) { // Hop on the missile for a ride! - thing->player->pflags |= PF_ITEMHANG; - thing->player->pflags &= ~PF_JUMPED; + thing->player->powers[pw_carry] = CR_GENERIC; + thing->player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE); P_SetTarget(&thing->tracer, tmthing); P_SetTarget(&tmthing->target, thing); // Set owner to the player P_SetTarget(&tmthing->tracer, NULL); // Disable homing-ness @@ -683,7 +1142,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - else if (tmthing->type == MT_BLACKEGGMAN_MISSILE && thing->player && ((thing->player->pflags & PF_ITEMHANG) || (thing->player->pflags & PF_JUMPED))) + else if (tmthing->type == MT_BLACKEGGMAN_MISSILE && thing->player && ((thing->player->powers[pw_carry] == CR_GENERIC) || (thing->player->pflags & PF_JUMPED))) { // Ignore } @@ -694,8 +1153,13 @@ static boolean PIT_CheckThing(mobj_t *thing) tmthing->y = thing->y; P_SetThingPosition(tmthing); } - else - P_DamageMobj(thing, tmthing, tmthing->target, 1); + else if (!(tmthing->type == MT_SHELL && thing->player)) // player collision handled in touchspecial + { + UINT8 damagetype = tmthing->info->mass; + if (!damagetype && tmthing->flags & MF_FIRE) // BURN! + damagetype = DMG_FIRE; + P_DamageMobj(thing, tmthing, tmthing->target, 1, damagetype); + } // don't traverse any more @@ -765,24 +1229,37 @@ static boolean PIT_CheckThing(mobj_t *thing) P_SetTarget(&thing->target, tmthing); } - // Respawn rings and items + // NiGHTS lap logic if ((tmthing->type == MT_NIGHTSDRONE || thing->type == MT_NIGHTSDRONE) && (tmthing->player || thing->player)) { mobj_t *droneobj = (tmthing->type == MT_NIGHTSDRONE) ? tmthing : thing; player_t *pl = (droneobj == thing) ? tmthing->player : thing->player; - // Must be in bonus time, and must be NiGHTS, must wait about a second + // Must be NiGHTS, must wait about a second // must be flying in the SAME DIRECTION as the last time you came through. // not (your direction) xor (stored direction) // In other words, you can't u-turn and respawn rings near the drone. - if (pl->bonustime && (pl->pflags & PF_NIGHTSMODE) && (INT32)leveltime > droneobj->extravalue2 && ( + if ((pl->powers[pw_carry] == CR_NIGHTSMODE) && (INT32)leveltime > droneobj->extravalue2 && ( !(pl->flyangle > 90 && pl->flyangle < 270) ^ (droneobj->extravalue1 > 90 && droneobj->extravalue1 < 270) )) { - // Reload all the fancy ring stuff! - P_ReloadRings(); + pl->marelap++; + pl->totalmarelap++; + pl->lapbegunat = leveltime; + pl->lapstartedtime = pl->nightstime; + + if (pl->bonustime) + { + pl->marebonuslap++; + pl->totalmarebonuslap++; + + // Respawn rings and items + P_ReloadRings(); + } + + P_RunNightsLapExecutors(pl->mo); } droneobj->extravalue1 = pl->flyangle; droneobj->extravalue2 = (INT32)leveltime + TICRATE; @@ -808,24 +1285,77 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->eflags & MFE_VERTICALFLIP) { if (thing->z + thing->height <= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) - && thing->z + thing->height + thing->momz >= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz) - P_DamageMobj(thing, tmthing, tmthing, 1); + && thing->z + thing->height + thing->momz >= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz + && !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && thing->eflags & MFE_VERTICALFLIP)) + P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE); } else if (thing->z >= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) - && thing->z + thing->momz <= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz) - P_DamageMobj(thing, tmthing, tmthing, 1); + && thing->z + thing->momz <= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz + && !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && !(thing->eflags & MFE_VERTICALFLIP))) + P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE); } else if (thing->type == MT_SPIKE && thing->flags & MF_SOLID && tmthing->player) // unfortunate player falls into spike?! { if (thing->eflags & MFE_VERTICALFLIP) { if (tmthing->z + tmthing->height <= thing->z - FixedMul(FRACUNIT, thing->scale) - && tmthing->z + tmthing->height + tmthing->momz >= thing->z - FixedMul(FRACUNIT, thing->scale)) - P_DamageMobj(tmthing, thing, thing, 1); + && tmthing->z + tmthing->height + tmthing->momz >= thing->z - FixedMul(FRACUNIT, thing->scale) + && !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && tmthing->eflags & MFE_VERTICALFLIP)) + P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE); } else if (tmthing->z >= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) - && tmthing->z + tmthing->momz <= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)) - P_DamageMobj(tmthing, thing, thing, 1); + && tmthing->z + tmthing->momz <= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) + && !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && !(tmthing->eflags & MFE_VERTICALFLIP))) + P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE); + } + + if (tmthing->type == MT_WALLSPIKE && tmthing->flags & MF_SOLID && thing->player) // wall spike impales player + { + fixed_t bottomz, topz; + bottomz = tmthing->z; + topz = tmthing->z + tmthing->height; + if (tmthing->eflags & MFE_VERTICALFLIP) + bottomz -= FixedMul(FRACUNIT, tmthing->scale); + else + topz += FixedMul(FRACUNIT, tmthing->scale); + + if (thing->z + thing->height > bottomz // above bottom + && thing->z < topz) // below top + // don't check angle, the player was clearly in the way in this case + P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE); + } + else if (thing->type == MT_WALLSPIKE && thing->flags & MF_SOLID && tmthing->player) + { + fixed_t bottomz, topz; + angle_t touchangle = R_PointToAngle2(thing->tracer->x, thing->tracer->y, tmthing->x, tmthing->y); + + if (P_PlayerInPain(tmthing->player) && (tmthing->momx || tmthing->momy)) + { + angle_t playerangle = R_PointToAngle2(0, 0, tmthing->momx, tmthing->momy) - touchangle; + if (playerangle > ANGLE_180) + playerangle = InvAngle(playerangle); + if (playerangle < ANGLE_90) + return true; // Yes, this is intentionally outside the z-height check. No standing on spikes whilst moving away from them. + } + + bottomz = thing->z; + topz = thing->z + thing->height; + + if (thing->eflags & MFE_VERTICALFLIP) + bottomz -= FixedMul(FRACUNIT, thing->scale); + else + topz += FixedMul(FRACUNIT, thing->scale); + + if (tmthing->z + tmthing->height > bottomz // above bottom + && tmthing->z < topz // below top + && !P_MobjWasRemoved(thing->tracer)) // this probably wouldn't work if we didn't have a tracer + { // use base as a reference point to determine what angle you touched the spike at + touchangle = thing->angle - touchangle; + if (touchangle > ANGLE_180) + touchangle = InvAngle(touchangle); + if (touchangle <= ANGLE_22h) // if you touched it at this close an angle, you get poked! + P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE); + } } if (thing->flags & MF_PUSHABLE) @@ -837,15 +1367,28 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->flags & MF_PUSHABLE) { if (thing->type == MT_FAN || thing->type == MT_STEAM) + { P_DoFanAndGasJet(thing, tmthing); + return true; + } else if (thing->flags & MF_SPRING) { if ( thing->z <= tmthing->z + tmthing->height && tmthing->z <= thing->z + thing->height) - iwassprung = P_DoSpring(thing, tmthing); + if (P_DoSpring(thing, tmthing)) + return false; + return true; } } + // thanks to sal for solidenemies dot lua + if (thing->flags & (MF_ENEMY|MF_BOSS) && tmthing->flags & (MF_ENEMY|MF_BOSS)) + { + if ((thing->z + thing->height >= tmthing->z) + && (tmthing->z + tmthing->height >= thing->z)) + return false; + } + // Damage other players when invincible if (tmthing->player && thing->player // Make sure they aren't able to damage you ANYWHERE along the Z axis, you have to be TOUCHING the person. @@ -853,12 +1396,12 @@ static boolean PIT_CheckThing(mobj_t *thing) { if (G_RingSlingerGametype() && (!G_GametypeHasTeams() || tmthing->player->ctfteam != thing->player->ctfteam)) { - if ((tmthing->player->powers[pw_invulnerability] || tmthing->player->powers[pw_super]) + if ((tmthing->player->powers[pw_invulnerability] || tmthing->player->powers[pw_super] || (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) && (tmthing->player->pflags & PF_SHIELDABILITY))) && !thing->player->powers[pw_super]) - P_DamageMobj(thing, tmthing, tmthing, 1); - else if ((thing->player->powers[pw_invulnerability] || thing->player->powers[pw_super]) + P_DamageMobj(thing, tmthing, tmthing, 1, 0); + else if ((thing->player->powers[pw_invulnerability] || thing->player->powers[pw_super] || (((thing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) && (thing->player->pflags & PF_SHIELDABILITY))) && !tmthing->player->powers[pw_super]) - P_DamageMobj(tmthing, thing, thing, 1); + P_DamageMobj(tmthing, thing, thing, 1, 0); } // If players are using touch tag, seekers damage hiders. @@ -866,9 +1409,9 @@ static boolean PIT_CheckThing(mobj_t *thing) ((thing->player->pflags & PF_TAGIT) != (tmthing->player->pflags & PF_TAGIT))) { if ((tmthing->player->pflags & PF_TAGIT) && !(thing->player->pflags & PF_TAGIT)) - P_DamageMobj(thing, tmthing, tmthing, 1); + P_DamageMobj(thing, tmthing, tmthing, 1, 0); else if ((thing->player->pflags & PF_TAGIT) && !(tmthing->player->pflags & PF_TAGIT)) - P_DamageMobj(tmthing, thing, tmthing, 1); + P_DamageMobj(tmthing, thing, tmthing, 1, 0); } } @@ -884,7 +1427,11 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (thing->player) { if (thing->player-players == consoleplayer && botingame) CV_SetValue(&cv_analog2, true); - thing->player->pflags &= ~PF_CARRIED; + if (thing->player->powers[pw_carry] == CR_PLAYER) + { + P_SetTarget(&thing->tracer, NULL); + thing->player->powers[pw_carry] = CR_NONE; + } } if (thing->player) @@ -906,7 +1453,7 @@ static boolean PIT_CheckThing(mobj_t *thing) { // Objects kill you if it falls from above. if (thing != tmthing->target) - P_DamageMobj(thing, tmthing, tmthing->target, 10000); + P_DamageMobj(thing, tmthing, tmthing->target, 1, DMG_CRUSHED); tmthing->momz = -tmthing->momz/2; // Bounce, just for fun! // The tmthing->target allows the pusher of the object @@ -925,44 +1472,66 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->type == MT_FAN || thing->type == MT_STEAM) P_DoFanAndGasJet(thing, tmthing); - else if (thing->flags & MF_SPRING) + else if (thing->flags & MF_SPRING && tmthing->player->powers[pw_carry] != CR_MINECART) { if ( thing->z <= tmthing->z + tmthing->height && tmthing->z <= thing->z + thing->height) - iwassprung = P_DoSpring(thing, tmthing); + if (P_DoSpring(thing, tmthing)) + return false; + return true; } - // Are you touching the side of the object you're interacting with? - else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height - && thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z) + // Monitor? + else if (thing->flags & MF_MONITOR + && !((thing->type == MT_RING_REDBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_RING_BLUEBOX && tmthing->player->ctfteam != 2))) { - if (thing->flags & MF_MONITOR - && tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)) + // 0 = none, 1 = elemental pierce, 2 = bubble bounce + UINT8 elementalpierce = (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (tmthing->player->pflags & PF_SHIELDABILITY) + ? (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) ? 1 : 2) + : 0); + if (!(thing->flags & MF_SOLID) + || tmthing->player->pflags & (PF_SPINNING|PF_GLIDING) + || ((tmthing->player->pflags & PF_JUMPED) + && (!(tmthing->player->pflags & PF_NOJUMPDAMAGE) + || (tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) + || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2) + || ((tmthing->player->charflags & SF_STOMPDAMAGE || tmthing->player->pflags & PF_BOUNCING) + && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)) + || elementalpierce) { - SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed. - fixed_t *momz = &tmthing->momz; // tmthing gets changed by P_DamageMobj, so we need a new pointer?! X_x;; - P_DamageMobj(thing, tmthing, tmthing, 1); // break the monitor - // Going down? Then bounce back up. - if ((P_MobjWasRemoved(thing) // Monitor was removed - || !thing->health) // or otherwise popped - && (flipval*(*momz) < 0)) // monitor is on the floor and you're going down, or on the ceiling and you're going up - *momz = -*momz; // Therefore, you should be thrust in the opposite direction, vertically. - return false; + if (thing->z - thing->scale <= tmthing->z + tmthing->height + && thing->z + thing->height + thing->scale >= tmthing->z) + { + player_t *player = tmthing->player; + SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed. + fixed_t *momz = &tmthing->momz; // tmthing gets changed by P_DamageMobj, so we need a new pointer?! X_x;; + fixed_t *z = &tmthing->z; // aau. + // Going down? Then bounce back up. + if (P_DamageMobj(thing, tmthing, tmthing, 1, 0) // break the monitor + && (flipval*(*momz) < 0) // monitor is on the floor and you're going down, or on the ceiling and you're going up + && (elementalpierce != 1)) // you're not piercing through the monitor... + { + if (elementalpierce == 2) + P_DoBubbleBounce(player); + else if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) + *momz = -*momz; // Therefore, you should be thrust in the opposite direction, vertically. + } + if (!(elementalpierce == 1 && thing->flags & MF_GRENADEBOUNCE)) // prevent gold monitor clipthrough. + { + if (player->pflags & PF_BOUNCING) + P_DoAbilityBounce(player, false); + return false; + } + else + *z -= *momz; // to ensure proper collision. + } + + return true; } } } - if (thing->flags & MF_SPRING && (tmthing->player || tmthing->flags & MF_PUSHABLE)) - { - if (iwassprung) // this spring caused you to gain MFE_SPRUNG just now... - return false; // "cancel" P_TryMove via blocking so you keep your current position - } - else if (tmthing->flags & MF_SPRING && (thing->player || thing->flags & MF_PUSHABLE)) - ; // Fix a few nasty spring-jumping bugs that happen sometimes. - // Monitors are not treated as solid to players who are jumping, spinning or gliding, - // unless it's a CTF team monitor and you're on the wrong team - else if (thing->flags & MF_MONITOR && tmthing->player && tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING) - && !((thing->type == MT_REDRINGBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_BLUERINGBOX && tmthing->player->ctfteam != 2))) - ; + if ((!tmthing->player) && (thing->player)) + ; // no solid thing should ever be able to step up onto a player // z checking at last // Treat noclip things as non-solid! else if ((thing->flags & (MF_SOLID|MF_NOCLIP)) == MF_SOLID @@ -980,6 +1549,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->z + thing->height > tmfloorz) { tmfloorz = thing->z + thing->height; + tmfloorrover = NULL; #ifdef ESLOPE tmfloorslope = NULL; #endif @@ -989,16 +1559,18 @@ static boolean PIT_CheckThing(mobj_t *thing) topz = thing->z - thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways - if (thing->flags & MF_SPRING) - ; // block only when jumping not high enough, // (dont climb max. 24units while already in air) // since return false doesn't handle momentum properly, // we lie to P_TryMove() so it's always too high - else if (tmthing->player && tmthing->z + tmthing->height > topz + if (tmthing->player && tmthing->z + tmthing->height > topz && tmthing->z + tmthing->height < tmthing->ceilingz) { + if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->info->flags & MF_MONITOR)) // Gold monitor hack... + return false; + tmfloorz = tmceilingz = topz; // block while in air + tmceilingrover = NULL; #ifdef ESLOPE tmceilingslope = NULL; #endif @@ -1007,6 +1579,7 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height) { tmceilingz = topz; + tmceilingrover = NULL; #ifdef ESLOPE tmceilingslope = NULL; #endif @@ -1023,6 +1596,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->z < tmceilingz) { tmceilingz = thing->z; + tmceilingrover = NULL; #ifdef ESLOPE tmceilingslope = NULL; #endif @@ -1032,16 +1606,18 @@ static boolean PIT_CheckThing(mobj_t *thing) topz = thing->z + thing->height + thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways - if (thing->flags & MF_SPRING) - ; // block only when jumping not high enough, // (dont climb max. 24units while already in air) // since return false doesn't handle momentum properly, // we lie to P_TryMove() so it's always too high - else if (tmthing->player && tmthing->z < topz + if (tmthing->player && tmthing->z < topz && tmthing->z > tmthing->floorz) { + if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->info->flags & MF_MONITOR)) // Gold monitor hack... + return false; + tmfloorz = tmceilingz = topz; // block while in air + tmfloorrover = NULL; #ifdef ESLOPE tmfloorslope = NULL; #endif @@ -1050,6 +1626,7 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z) { tmfloorz = topz; + tmfloorrover = NULL; #ifdef ESLOPE tmfloorslope = NULL; #endif @@ -1138,6 +1715,32 @@ static boolean PIT_CheckLine(line_t *ld) if (P_BoxOnLineSide(tmbbox, ld) != -1) return true; + if (tmthing->flags & MF_PAPERCOLLISION) // Caution! Turning whilst up against a wall will get you stuck. You probably shouldn't give the player this flag. + { + fixed_t cosradius, sinradius; + cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT)); + sinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT)); + if (P_PointOnLineSide(tmx - cosradius, tmy - sinradius, ld) + == P_PointOnLineSide(tmx + cosradius, tmy + sinradius, ld)) + return true; // the line doesn't cross between collider's start or end +#ifdef PAPER_COLLISIONCORRECTION + { + fixed_t dist; + vertex_t result; + angle_t langle; + P_ClosestPointOnLine(tmx, tmy, ld, &result); + langle = R_PointToAngle2(ld->v1->x, ld->v1->y, ld->v2->x, ld->v2->y); + langle += ANGLE_90*(P_PointOnLineSide(tmx, tmy, ld) ? -1 : 1); + dist = abs(FixedMul(tmthing->radius, FINECOSINE((tmthing->angle - langle)>>ANGLETOFINESHIFT))); + cosradius = FixedMul(dist, FINECOSINE(langle>>ANGLETOFINESHIFT)); + sinradius = FixedMul(dist, FINESINE(langle>>ANGLETOFINESHIFT)); + tmthing->flags |= MF_NOCLIP; + P_TeleportMove(tmthing, result.x + cosradius - tmthing->momx, result.y + sinradius - tmthing->momy, tmthing->z); + tmthing->flags &= ~MF_NOCLIP; + } +#endif + } + // A line has been hit // The moving thing's destination position will cross @@ -1175,6 +1778,7 @@ static boolean PIT_CheckLine(line_t *ld) { tmceilingz = opentop; ceilingline = ld; + tmceilingrover = NULL; #ifdef ESLOPE tmceilingslope = opentopslope; #endif @@ -1183,6 +1787,7 @@ static boolean PIT_CheckLine(line_t *ld) if (openbottom > tmfloorz) { tmfloorz = openbottom; + tmfloorrover = NULL; #ifdef ESLOPE tmfloorslope = openbottomslope; #endif @@ -1264,6 +1869,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) // will adjust them. tmfloorz = tmdropoffz = P_GetFloorZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->floorheight; tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->ceilingheight; + tmfloorrover = NULL; + tmceilingrover = NULL; #ifdef ESLOPE tmfloorslope = newsubsec->sector->f_slope; tmceilingslope = newsubsec->sector->c_slope; @@ -1307,6 +1914,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) { if (tmfloorz < topheight - sinklevel) { tmfloorz = topheight - sinklevel; + tmfloorrover = rover; #ifdef ESLOPE tmfloorslope = *rover->t_slope; #endif @@ -1316,6 +1924,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) { if (tmceilingz > bottomheight + sinklevel) { tmceilingz = bottomheight + sinklevel; + tmceilingrover = rover; #ifdef ESLOPE tmceilingslope = *rover->b_slope; #endif @@ -1330,7 +1939,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) else if (thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE)) ; else if (!((rover->flags & FF_BLOCKPLAYER && thing->player) - || (rover->flags & FF_BLOCKOTHERS && !thing->player) + || (rover->flags & FF_BLOCKOTHERS && !thing->player) || rover->flags & FF_QUICKSAND)) continue; @@ -1340,6 +1949,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) { if (tmfloorz < thing->z) { tmfloorz = thing->z; + tmfloorrover = rover; #ifdef ESLOPE tmfloorslope = NULL; #endif @@ -1358,6 +1968,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) && !(rover->flags & FF_REVERSEPLATFORM)) { tmfloorz = tmdropoffz = topheight; + tmfloorrover = rover; #ifdef ESLOPE tmfloorslope = *rover->t_slope; #endif @@ -1367,6 +1978,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) && !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))) { tmceilingz = tmdrpoffceilz = bottomheight; + tmceilingrover = rover; #ifdef ESLOPE tmceilingslope = *rover->b_slope; #endif @@ -1851,6 +2463,8 @@ boolean PIT_PushableMoved(mobj_t *thing) mobj_t *oldthing = tmthing; line_t *oldceilline = ceilingline; line_t *oldblockline = blockingline; + ffloor_t *oldflrrover = tmfloorrover; + ffloor_t *oldceilrover = tmceilingrover; #ifdef ESLOPE pslope_t *oldfslope = tmfloorslope; pslope_t *oldcslope = tmceilingslope; @@ -1867,6 +2481,8 @@ boolean PIT_PushableMoved(mobj_t *thing) P_SetTarget(&tmthing, oldthing); ceilingline = oldceilline; blockingline = oldblockline; + tmfloorrover = oldflrrover; + tmceilingrover = oldceilrover; #ifdef ESLOPE tmfloorslope = oldfslope; tmceilingslope = oldcslope; @@ -1936,7 +2552,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) // Don't 'step up' while springing, // Only step up "if needed". - if (thing->state == &states[S_PLAY_SPRING] + if (thing->player->panim == PA_SPRING && P_MobjFlip(thing)*thing->momz > FixedMul(FRACUNIT, thing->scale)) maxstep = 0; } @@ -1977,6 +2593,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (thingtop == thing->ceilingz && tmceilingz > thingtop && tmceilingz - thingtop <= maxstep) { thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; + thing->ceilingrover = tmceilingrover; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } #ifdef ESLOPE @@ -1984,6 +2601,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) else if (tmceilingslope && tmceilingz < thingtop && thingtop - tmceilingz <= maxstep) { thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; + thing->ceilingrover = tmceilingrover; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } #endif @@ -1991,6 +2609,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep) { thing->z = thing->floorz = tmfloorz; + thing->floorrover = tmfloorrover; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } #ifdef ESLOPE @@ -1998,6 +2617,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) else if (tmfloorslope && tmfloorz > thing->z && tmfloorz - thing->z <= maxstep) { thing->z = thing->floorz = tmfloorz; + thing->floorrover = tmfloorrover; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } #endif @@ -2061,6 +2681,8 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) thing->floorz = tmfloorz; thing->ceilingz = tmceilingz; + thing->floorrover = tmfloorrover; + thing->ceilingrover = tmceilingrover; #ifdef ESLOPE if (!(thing->flags & MF_NOCLIPHEIGHT)) @@ -2141,6 +2763,8 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y) thing->floorz = tmfloorz; thing->ceilingz = tmceilingz; + thing->floorrover = tmfloorrover; + thing->ceilingrover = tmceilingrover; thing->x = x; thing->y = y; @@ -2167,7 +2791,10 @@ static boolean P_ThingHeightClip(mobj_t *thing) { boolean floormoved; fixed_t oldfloorz = thing->floorz; + ffloor_t *oldfloorrover = thing->floorrover; + ffloor_t *oldceilingrover = thing->ceilingrover; boolean onfloor = P_IsObjectOnGround(thing);//(thing->z <= thing->floorz); + ffloor_t *rover = NULL; if (thing->flags & MF_NOCLIPHEIGHT) return true; @@ -2182,6 +2809,8 @@ static boolean P_ThingHeightClip(mobj_t *thing) thing->floorz = tmfloorz; thing->ceilingz = tmceilingz; + thing->floorrover = tmfloorrover; + thing->ceilingrover = tmceilingrover; // Ugly hack?!?! As long as just ceilingz is the lowest, // you'll still get crushed, right? @@ -2190,16 +2819,23 @@ static boolean P_ThingHeightClip(mobj_t *thing) if (onfloor && !(thing->flags & MF_NOGRAVITY) && floormoved) { - if (thing->eflags & MFE_VERTICALFLIP) - thing->pmomz = thing->ceilingz - (thing->z + thing->height); - else - thing->pmomz = thing->floorz - thing->z; - thing->eflags |= MFE_APPLYPMOMZ; + rover = (thing->eflags & MFE_VERTICALFLIP) ? oldceilingrover : oldfloorrover; - if (thing->eflags & MFE_VERTICALFLIP) - thing->z = thing->ceilingz - thing->height; - else - thing->z = thing->floorz; + // Match the Thing's old floorz to an FOF and check for FF_EXISTS + // If ~FF_EXISTS, don't set mobj Z. + if (!rover || ((rover->flags & FF_EXISTS) && (rover->flags & FF_SOLID))) + { + if (thing->eflags & MFE_VERTICALFLIP) + thing->pmomz = thing->ceilingz - (thing->z + thing->height); + else + thing->pmomz = thing->floorz - thing->z; + thing->eflags |= MFE_APPLYPMOMZ; + + if (thing->eflags & MFE_VERTICALFLIP) + thing->z = thing->ceilingz - thing->height; + else + thing->z = thing->floorz; + } } else if (!tmfloorthing) { @@ -2677,7 +3313,7 @@ isblocking: slidemo->player->climbing = 5; } - slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_THOKKED); + slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED); slidemo->player->glidetime = 0; slidemo->player->secondjump = 0; @@ -2823,12 +3459,86 @@ void P_SlideMove(mobj_t *mo) INT16 hitcount = 0; boolean success = false; + boolean papercol = false; + vertex_t v1, v2; // fake vertexes + line_t junk; // fake linedef + if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height) { // Don't mess with your momentum if it's a pushable object. Pushables do their own crazy things already. if (tmhitthing->flags & MF_PUSHABLE) return; + if (tmhitthing->flags & MF_PAPERCOLLISION) + { + fixed_t cosradius, sinradius, num, den; + + // 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; + } + + papercol = true; + slidemo = mo; + bestslideline = &junk; + + cosradius = FixedMul(tmhitthing->radius, FINECOSINE(tmhitthing->angle>>ANGLETOFINESHIFT)); + sinradius = FixedMul(tmhitthing->radius, FINESINE(tmhitthing->angle>>ANGLETOFINESHIFT)); + + v1.x = tmhitthing->x - cosradius; + v1.y = tmhitthing->y - sinradius; + v2.x = tmhitthing->x + cosradius; + v2.y = tmhitthing->y + sinradius; + + junk.v1 = &v1; + junk.v2 = &v2; + junk.dx = 2*cosradius; // v2.x - v1.x; + junk.dy = 2*sinradius; // v2.y - v1.y; + + junk.slopetype = !cosradius ? ST_VERTICAL : !sinradius ? ST_HORIZONTAL : + ((sinradius > 0) == (cosradius > 0)) ? ST_POSITIVE : ST_NEGATIVE; + + bestslidefrac = FRACUNIT+1; + + den = FixedMul(junk.dy>>8, mo->momx) - FixedMul(junk.dx>>8, mo->momy); + + if (!den) + bestslidefrac = 0; + else + { + fixed_t frac; +#define P_PaperTraverse(startx, starty) \ + num = FixedMul((v1.x - leadx)>>8, junk.dy) + FixedMul((leady - v1.y)>>8, junk.dx); \ + frac = FixedDiv(num, den); \ + if (frac < bestslidefrac) \ + bestslidefrac = frac + P_PaperTraverse(leadx, leady); + P_PaperTraverse(trailx, leady); + P_PaperTraverse(leadx, traily); +#undef dowork + } + + goto papercollision; + } + // Thankfully box collisions are a lot simpler than arbitrary lines. There's only four possible cases. if (mo->y + mo->radius <= tmhitthing->y - tmhitthing->radius) { @@ -2859,7 +3569,7 @@ void P_SlideMove(mobj_t *mo) bestslideline = NULL; retry: - if (++hitcount == 3) + if ((++hitcount == 3) || papercol) goto stairstep; // don't loop forever // trace along the three leading corners @@ -2901,6 +3611,7 @@ retry: return; } +papercollision: // move up to the wall if (bestslidefrac == FRACUNIT+1) { @@ -3128,6 +3839,7 @@ bounceback: static fixed_t bombdamage; static mobj_t *bombsource; static mobj_t *bombspot; +static UINT8 bombdamagetype; // // PIT_RadiusAttack @@ -3138,17 +3850,13 @@ static boolean PIT_RadiusAttack(mobj_t *thing) { fixed_t dx, dy, dz, dist; - if (thing == bombspot // ignore the bomb itself (Deton fix) - || (bombsource && thing->type == bombsource->type)) // ignore the type of guys who dropped the bomb (Jetty-Syn Bomber or Skim can bomb eachother, but not themselves.) - return true; - - if (!(thing->flags & MF_SHOOTABLE)) + if (thing == bombspot) // ignore the bomb itself (Deton fix) return true; - if (thing->flags & MF_BOSS) + if ((thing->flags & (MF_MONITOR|MF_SHOOTABLE)) != MF_SHOOTABLE) return true; - if (thing->flags & MF_MONITOR) + if (bombsource && thing->type == bombsource->type && !(bombdamagetype & DMG_CANHURTSELF)) // ignore the type of guys who dropped the bomb (Jetty-Syn Bomber or Skim can bomb eachother, but not themselves.) return true; dx = abs(thing->x - bombspot->x); @@ -3172,7 +3880,7 @@ static boolean PIT_RadiusAttack(mobj_t *thing) if (P_CheckSight(thing, bombspot)) { // must be in direct path - P_DamageMobj(thing, bombspot, bombsource, 1); // Tails 01-11-2001 + P_DamageMobj(thing, bombspot, bombsource, 1, bombdamagetype); // Tails 01-11-2001 } return true; @@ -3182,7 +3890,7 @@ static boolean PIT_RadiusAttack(mobj_t *thing) // P_RadiusAttack // Source is the creature that caused the explosion at spot. // -void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist) +void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 damagetype) { INT32 x, y; INT32 xl, xh, yl, yh; @@ -3199,6 +3907,7 @@ void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist) bombspot = spot; bombsource = source; bombdamage = FixedMul(damagedist, spot->scale); + bombdamagetype = damagetype; for (y = yl; y <= yh; y++) for (x = xl; x <= xh; x++) @@ -3227,6 +3936,8 @@ static boolean nofit; static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) { mobj_t *killer = NULL; + //If a thing is both pushable and vulnerable, it doesn't block the crusher because it gets killed. + boolean immunepushable = ((thing->flags & (MF_PUSHABLE | MF_SHOOTABLE)) == MF_PUSHABLE); if (P_ThingHeightClip(thing)) { @@ -3245,7 +3956,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) // just be blocked by another object - check if it's really a ceiling! if (thing->z + thing->height > thing->ceilingz && thing->z <= thing->ceilingz) { - if (thing->flags & MF_PUSHABLE && thing->z + thing->height > thing->subsector->sector->ceilingheight) + if (immunepushable && thing->z + thing->height > thing->subsector->sector->ceilingheight) { //Thing is a pushable and blocks the moving ceiling nofit = true; @@ -3253,7 +3964,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) } //Check FOFs in the sector - if (thing->subsector->sector->ffloors && (realcrush || thing->flags & MF_PUSHABLE)) + if (thing->subsector->sector->ffloors && (realcrush || immunepushable)) { ffloor_t *rover; fixed_t topheight, bottomheight; @@ -3280,7 +3991,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) delta2 = thingtop - (bottomheight + topheight)/2; if (bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2)) { - if (thing->flags & MF_PUSHABLE) + if (immunepushable) { //FOF is blocked by pushable nofit = true; @@ -3318,22 +4029,15 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) { // Crush the object if (netgame && thing->player && thing->player->spectator) - P_DamageMobj(thing, NULL, NULL, 42000); // Respawn crushed spectators + P_DamageMobj(thing, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators else - { - if (!killer) - { - //Nobody is responsible for crushing the object, so give a generic crush message - killer = P_SpawnMobj(thing->x, thing->y, thing->z, MT_NULL); - killer->threshold = 44; // Special flag for crushing - } - P_DamageMobj(thing, killer, killer, 10000); - } + P_DamageMobj(thing, killer, killer, 1, DMG_CRUSHED); + return true; } } if (realcrush && crushchange) - P_DamageMobj(thing, NULL, NULL, 1); + P_DamageMobj(thing, NULL, NULL, 1, 0); // keep checking (crush other things) return true; diff --git a/src/p_mobj.c b/src/p_mobj.c index e2543f553aa95cbe0e7ed2a719f926ef1e8454a2..5844034086856e8dc90a9563ad3e64e61c370e4b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -34,10 +34,12 @@ #ifdef ESLOPE #include "p_slopes.h" #endif +#include "f_finale.h" +#include "m_cond.h" + +static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}}; +consvar_t cv_movebob = {"movebob", "1.0", CV_FLOAT|CV_SAVE, CV_BobSpeed, NULL, 0, NULL, NULL, 0, 0, NULL}; -// protos. -static CV_PossibleValue_t viewheight_cons_t[] = {{16, "MIN"}, {56, "MAX"}, {0, NULL}}; -consvar_t cv_viewheight = {"viewheight", VIEWHEIGHTS, 0, viewheight_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef WALLSPLATS consvar_t cv_splats = {"splats", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif @@ -81,6 +83,41 @@ void P_AddCachedAction(mobj_t *mobj, INT32 statenum) actioncachehead.prev = newaction; } +// +// P_SetupStateAnimation +// +FUNCINLINE static ATTRINLINE void P_SetupStateAnimation(mobj_t *mobj, state_t *st) +{ + INT32 animlength = (mobj->sprite == SPR_PLAY && mobj->skin) + ? (INT32)(((skin_t *)mobj->skin)->sprites[mobj->sprite2].numframes) - 1 + : st->var1; + + if (!(st->frame & FF_ANIMATE)) + return; + + if (animlength <= 0 || st->var2 == 0) + { + mobj->frame &= ~FF_ANIMATE; + return; // Crash/stupidity prevention + } + + mobj->anim_duration = (UINT16)st->var2; + + if (st->frame & FF_GLOBALANIM) + { + // Attempt to account for the pre-ticker for objects spawned on load + if (!leveltime) return; + + mobj->anim_duration -= (leveltime + 2) % st->var2; // Duration synced to timer + mobj->frame += ((leveltime + 2) / st->var2) % (animlength + 1); // Frame synced to timer (duration taken into account) + } + else if (st->frame & FF_RANDOMANIM) + { + mobj->frame += P_RandomKey(animlength + 1); // Random starting frame + mobj->anim_duration -= P_RandomKey(st->var2); // Random duration for first frame + } +} + // // P_CycleStateAnimation // @@ -89,13 +126,23 @@ FUNCINLINE static ATTRINLINE void P_CycleStateAnimation(mobj_t *mobj) // var2 determines delay between animation frames if (!(mobj->frame & FF_ANIMATE) || --mobj->anim_duration != 0) return; + mobj->anim_duration = (UINT16)mobj->state->var2; - // compare the current sprite frame to the one we started from - // if more than var1 away from it, swap back to the original - // else just advance by one - if (((++mobj->frame) & FF_FRAMEMASK) - (mobj->state->frame & FF_FRAMEMASK) > (UINT32)mobj->state->var1) - mobj->frame = (mobj->state->frame & FF_FRAMEMASK) | (mobj->frame & ~FF_FRAMEMASK); + if (mobj->sprite != SPR_PLAY) + { + // compare the current sprite frame to the one we started from + // if more than var1 away from it, swap back to the original + // else just advance by one + if (((++mobj->frame) & FF_FRAMEMASK) - (mobj->state->frame & FF_FRAMEMASK) > (UINT32)mobj->state->var1) + mobj->frame = (mobj->state->frame & FF_FRAMEMASK) | (mobj->frame & ~FF_FRAMEMASK); + + return; + } + + // sprite2 version of above + if (mobj->skin && (((++mobj->frame) & FF_FRAMEMASK) >= (UINT32)(((skin_t *)mobj->skin)->sprites[mobj->sprite2].numframes))) + mobj->frame &= ~FF_FRAMEMASK; } // @@ -163,54 +210,27 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) I_Error("P_SetPlayerMobjState used for non-player mobj. Use P_SetMobjState instead!\n(Mobj type: %d, State: %d)", mobj->type, state); #endif - // Catch state changes for Super Sonic - if (player->powers[pw_super] && (player->charflags & SF_SUPERANIMS)) + // Catch falling for nojumpspin + if ((state == S_PLAY_JUMP) && (player->charflags & SF_NOJUMPSPIN) && (P_MobjFlip(mobj)*mobj->momz < 0)) + return P_SetPlayerMobjState(mobj, S_PLAY_FALL); + + // Catch swimming versus flying + if (state == S_PLAY_FLY && player->mo->eflags & MFE_UNDERWATER) + return P_SetPlayerMobjState(player->mo, S_PLAY_SWIM); + else if (state == S_PLAY_SWIM && !(player->mo->eflags & MFE_UNDERWATER)) + return P_SetPlayerMobjState(player->mo, S_PLAY_FLY); + + // Catch SF_NOSUPERSPIN jumps for Supers + if (player->powers[pw_super] && (player->charflags & SF_NOSUPERSPIN)) { - switch (state) + if (state == S_PLAY_JUMP) { - case S_PLAY_STND: - case S_PLAY_TAP1: - case S_PLAY_TAP2: - case S_PLAY_GASP: - P_SetPlayerMobjState(mobj, S_PLAY_SUPERSTAND); - return true; - case S_PLAY_FALL1: - case S_PLAY_SPRING: - case S_PLAY_RUN1: - case S_PLAY_RUN2: - case S_PLAY_RUN3: - case S_PLAY_RUN4: - P_SetPlayerMobjState(mobj, S_PLAY_SUPERWALK1); - return true; - case S_PLAY_FALL2: - case S_PLAY_RUN5: - case S_PLAY_RUN6: - case S_PLAY_RUN7: - case S_PLAY_RUN8: - P_SetPlayerMobjState(mobj, S_PLAY_SUPERWALK2); + if (player->mo->state-states == S_PLAY_WALK) + return P_SetPlayerMobjState(mobj, S_PLAY_FLOAT); return true; - case S_PLAY_SPD1: - case S_PLAY_SPD2: - P_SetPlayerMobjState(mobj, S_PLAY_SUPERFLY1); - return true; - case S_PLAY_SPD3: - case S_PLAY_SPD4: - P_SetPlayerMobjState(mobj, S_PLAY_SUPERFLY2); - return true; - case S_PLAY_TEETER1: - case S_PLAY_TEETER2: - P_SetPlayerMobjState(mobj, S_PLAY_SUPERTEETER); - return true; - case S_PLAY_ATK1: - case S_PLAY_ATK2: - case S_PLAY_ATK3: - case S_PLAY_ATK4: - if (!(player->charflags & SF_SUPERSPIN)) - return true; - break; - default: - break; } + else if (player->mo->state-states == S_PLAY_FLOAT && state == S_PLAY_STND) + return true; } // You were in pain state after taking a hit, and you're moving out of pain state now? else if (mobj->state == &states[mobj->info->painstate] && player->powers[pw_flashing] == flashingtics && state != mobj->info->painstate) @@ -222,23 +242,67 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) // Set animation state // The pflags version of this was just as convoluted. - if ((state >= S_PLAY_STND && state <= S_PLAY_TAP2) || (state >= S_PLAY_TEETER1 && state <= S_PLAY_TEETER2) || state == S_PLAY_CARRY - || state == S_PLAY_SUPERSTAND || state == S_PLAY_SUPERTEETER) + switch(state) + { + case S_PLAY_STND: + case S_PLAY_WAIT: player->panim = PA_IDLE; - else if ((state >= S_PLAY_RUN1 && state <= S_PLAY_RUN8) - || (state >= S_PLAY_SUPERWALK1 && state <= S_PLAY_SUPERWALK2)) + break; + case S_PLAY_EDGE: + player->panim = PA_EDGE; + break; + case S_PLAY_WALK: + case S_PLAY_SKID: + case S_PLAY_FLOAT: player->panim = PA_WALK; - else if ((state >= S_PLAY_SPD1 && state <= S_PLAY_SPD4) - || (state >= S_PLAY_SUPERFLY1 && state <= S_PLAY_SUPERFLY2)) + break; + case S_PLAY_RUN: + case S_PLAY_FLOAT_RUN: player->panim = PA_RUN; - else if (state >= S_PLAY_ATK1 && state <= S_PLAY_ATK4) + break; + case S_PLAY_DASH: + player->panim = PA_DASH; + break; + case S_PLAY_PAIN: + case S_PLAY_STUN: + player->panim = PA_PAIN; + break; + case S_PLAY_ROLL: + //case S_PLAY_SPINDASH: -- everyone can ROLL thanks to zoom tubes... player->panim = PA_ROLL; - else if (state >= S_PLAY_FALL1 && state <= S_PLAY_FALL2) + break; + case S_PLAY_JUMP: + player->panim = PA_JUMP; + break; + case S_PLAY_SPRING: + player->panim = PA_SPRING; + break; + case S_PLAY_FALL: player->panim = PA_FALL; - else if (state >= S_PLAY_ABL1 && state <= S_PLAY_ABL2) + break; + case S_PLAY_FLY: + case S_PLAY_SWIM: + case S_PLAY_GLIDE: + case S_PLAY_BOUNCE: + case S_PLAY_BOUNCE_LANDING: + case S_PLAY_TWINSPIN: player->panim = PA_ABILITY; - else + break; + case S_PLAY_SPINDASH: // ...but the act of SPINDASHING is charability2 specific. + case S_PLAY_FIRE: + case S_PLAY_FIRE_FINISH: + case S_PLAY_MELEE: + case S_PLAY_MELEE_FINISH: + case S_PLAY_MELEE_LANDING: + player->panim = PA_ABILITY2; + break; + case S_PLAY_RIDE: + player->panim = PA_RIDE; + break; + default: player->panim = PA_ETC; + break; + } if (recursion++) // if recursion detected, memset(seenstate = tempstate, 0, sizeof tempstate); // clear state table @@ -259,17 +323,14 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) mobj->tics = st->tics; // Adjust the player's animation speed to match their velocity. - if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST)) + if (state == S_PLAY_STND && player->powers[pw_super] && skins[player->skin].sprites[SPR2_WAIT|FF_SPR2SUPER].numframes == 0) // if no super wait, don't wait at all + mobj->tics = -1; + else if (player->panim == PA_EDGE && (player->charflags & SF_FASTEDGE)) + mobj->tics = 2; + else if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST)) { - fixed_t speed = FixedDiv(player->speed, mobj->scale); - if (player->panim == PA_ROLL) - { - if (speed > 16<<FRACBITS) - mobj->tics = 1; - else - mobj->tics = 2; - } - else if (player->panim == PA_FALL) + fixed_t speed;// = FixedDiv(player->speed, FixedMul(mobj->scale, player->mo->movefactor)); + if (player->panim == PA_FALL) { speed = FixedDiv(abs(mobj->momz), mobj->scale); if (speed < 10<<FRACBITS) @@ -281,30 +342,111 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) else mobj->tics = 1; } - else if (P_IsObjectOnGround(mobj) || player->powers[pw_super]) // Only if on the ground or superflying. + else if (player->panim == PA_ABILITY2 && player->charability2 == CA2_SPINDASH) + { + fixed_t step = (player->maxdash - player->mindash)/4; + speed = (player->dashspeed - player->mindash); + if (speed > 3*step) + mobj->tics = 1; + else if (speed > step) + mobj->tics = 2; + else + mobj->tics = 3; + } + else { - if (player->panim == PA_WALK) + speed = FixedDiv(player->speed, FixedMul(mobj->scale, player->mo->movefactor)); + if (player->panim == PA_ROLL || player->panim == PA_JUMP) { - if (speed > 12<<FRACBITS) - mobj->tics = 2; - else if (speed > 6<<FRACBITS) - mobj->tics = 3; + if (speed > 16<<FRACBITS) + mobj->tics = 1; else - mobj->tics = 4; + mobj->tics = 2; } - else if (player->panim == PA_RUN) + else if (P_IsObjectOnGround(mobj) || ((player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super]) // Only if on the ground or superflying. { - if (speed > 52<<FRACBITS) - mobj->tics = 1; + if (player->panim == PA_WALK) + { + if (speed > 12<<FRACBITS) + mobj->tics = 2; + else if (speed > 6<<FRACBITS) + mobj->tics = 3; + else + mobj->tics = 4; + } + else if ((player->panim == PA_RUN) || (player->panim == PA_DASH)) + { + if (speed > 52<<FRACBITS) + mobj->tics = 1; + else + mobj->tics = 2; + } + } + } + } + + // Player animations + if (st->sprite == SPR_PLAY) + { + skin_t *skin = ((skin_t *)mobj->skin); + UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1; + UINT8 numframes, spr2; + + if (skin) + { + spr2 = P_GetSkinSprite2(skin, (((player->powers[pw_super]) ? FF_SPR2SUPER : 0)|st->frame) & FF_FRAMEMASK, mobj->player); + numframes = skin->sprites[spr2].numframes; + } + else + { + spr2 = 0; + frame = 0; + numframes = 0; + } + + if (mobj->sprite != SPR_PLAY) + { + mobj->sprite = SPR_PLAY; + frame = 0; + } + else if (mobj->sprite2 != spr2) + { + if ((st->frame & FF_SPR2MIDSTART) && numframes && P_RandomChance(FRACUNIT/2)) + frame = numframes/2; + else + frame = 0; + } + + if (frame >= numframes) + { + if (st->frame & FF_SPR2ENDSTATE) // no frame advancement + { + if (st->var1 == mobj->state-states) + frame--; else - mobj->tics = 2; + { + if (mobj->frame & FF_FRAMEMASK) + mobj->frame--; + return P_SetPlayerMobjState(mobj, st->var1); + } } + else + frame = 0; } + + mobj->sprite2 = spr2; + mobj->frame = frame|(st->frame&~FF_FRAMEMASK); + if (mobj->color >= MAXSKINCOLORS && mobj->color < MAXTRANSLATIONS) // Super colours? Super bright! + mobj->frame |= FF_FULLBRIGHT; + } + // Regular sprites + else + { + mobj->sprite = st->sprite; + mobj->frame = st->frame; } - mobj->sprite = st->sprite; - mobj->frame = st->frame; - mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set + P_SetupStateAnimation(mobj, st); // Modified handling. // Call action functions when the state is set @@ -370,9 +512,67 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) st = &states[state]; mobj->state = st; mobj->tics = st->tics; - mobj->sprite = st->sprite; - mobj->frame = st->frame; - mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set + + // Player animations + if (st->sprite == SPR_PLAY) + { + skin_t *skin = ((skin_t *)mobj->skin); + UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1; + UINT8 numframes, spr2; + + if (skin) + { + spr2 = P_GetSkinSprite2(skin, st->frame & FF_FRAMEMASK, mobj->player); + numframes = skin->sprites[spr2].numframes; + } + else + { + spr2 = 0; + frame = 0; + numframes = 0; + } + + if (mobj->sprite != SPR_PLAY) + { + mobj->sprite = SPR_PLAY; + frame = 0; + } + else if (mobj->sprite2 != spr2) + { + if ((st->frame & FF_SPR2MIDSTART) && numframes && P_RandomChance(FRACUNIT/2)) + frame = numframes/2; + else + frame = 0; + } + + if (frame >= numframes) + { + if (st->frame & FF_SPR2ENDSTATE) // no frame advancement + { + if (st->var1 == mobj->state-states) + frame--; + else + { + if (mobj->frame & FF_FRAMEMASK) + mobj->frame--; + return P_SetMobjState(mobj, st->var1); + } + } + else + frame = 0; + } + + mobj->sprite2 = spr2; + mobj->frame = frame|(st->frame&~FF_FRAMEMASK); + } + // Regular sprites + else + { + mobj->sprite = st->sprite; + mobj->frame = st->frame; + } + + P_SetupStateAnimation(mobj, st); // Modified handling. // Call action functions when the state is set @@ -426,7 +626,7 @@ boolean P_SetMobjStateNF(mobj_t *mobj, statenum_t state) mobj->tics = st->tics; mobj->sprite = st->sprite; mobj->frame = st->frame; - mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set + P_SetupStateAnimation(mobj, st); return true; } @@ -445,7 +645,7 @@ static boolean P_SetPrecipMobjState(precipmobj_t *mobj, statenum_t state) mobj->tics = st->tics; mobj->sprite = st->sprite; mobj->frame = st->frame; - mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set + P_SetupStateAnimation((mobj_t*)mobj, st); return true; } @@ -653,14 +853,12 @@ void P_EmeraldManager(void) else break; - if (leveltime < TICRATE) // Start of map - spawnpoints[j]->threshold = 60*TICRATE + P_RandomByte() * (TICRATE/5); - else - spawnpoints[j]->threshold = P_RandomByte() * (TICRATE/5); - + spawnpoints[j]->threshold = emeraldspawndelay + P_RandomByte() * (TICRATE/5); break; } } + + emeraldspawndelay = 0; } // @@ -680,7 +878,7 @@ void P_ExplodeMissile(mobj_t *mo) if (mo->type == MT_DETON) { - P_RadiusAttack(mo, mo, 96*FRACUNIT); + P_RadiusAttack(mo, mo, 96*FRACUNIT, 0); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); P_SetScale(explodemo, mo->scale); @@ -706,9 +904,6 @@ void P_ExplodeMissile(mobj_t *mo) explodemo->momx -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momy -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); S_StartSound(explodemo, sfx_cybdth); - - // Hack: Release an animal. - P_DamageMobj(mo, NULL, NULL, 10000); } mo->flags &= ~MF_MISSILE; @@ -1220,11 +1415,8 @@ static void P_PlayerFlip(mobj_t *mo) G_GhostAddFlip(); // Flip aiming to match! - if (mo->player->pflags & PF_NIGHTSMODE) // NiGHTS doesn't use flipcam - { - if (mo->tracer) - mo->tracer->eflags ^= MFE_VERTICALFLIP; - } + if (mo->player->powers[pw_carry] == CR_NIGHTSMODE) // NiGHTS doesn't use flipcam + ; else if (mo->player->pflags & PF_FLIPCAM) { mo->player->aiming = InvAngle(mo->player->aiming); @@ -1318,9 +1510,9 @@ fixed_t P_GetMobjGravity(mobj_t *mo) { if ((mo->player->pflags & PF_GLIDING) || (mo->player->charability == CA_FLY && (mo->player->powers[pw_tailsfly] - || (mo->state >= &states[S_PLAY_SPC1] && mo->state <= &states[S_PLAY_SPC4])))) + || mo->state-states == S_PLAY_FLY_TIRED))) gravityadd = gravityadd/3; // less gravity while flying/gliding - if (mo->player->climbing || (mo->player->pflags & PF_NIGHTSMODE)) + if (mo->player->climbing || (mo->player->powers[pw_carry] == CR_NIGHTSMODE)) gravityadd = 0; if (!(mo->flags2 & MF2_OBJECTFLIP) != !(mo->player->powers[pw_gravityboots])) // negated to turn numeric into bool - would be double negated, but not needed if both would be @@ -1348,6 +1540,8 @@ fixed_t P_GetMobjGravity(mobj_t *mo) { case MT_FLINGRING: case MT_FLINGCOIN: + case MT_FLINGBLUESPHERE: + case MT_FLINGNIGHTSCHIP: case MT_FLINGEMERALD: case MT_BOUNCERING: case MT_RAILRING: @@ -1416,7 +1610,6 @@ void P_CheckGravity(mobj_t *mo, boolean affect) } #define STOPSPEED (FRACUNIT) -#define FRICTION (ORIG_FRICTION) // 0.90625 // // P_SceneryXYFriction @@ -1449,7 +1642,6 @@ static void P_SceneryXYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy) { // Stolen from P_SpawnFriction mo->friction = FRACUNIT - 0x100; - mo->movefactor = ((0x10092 - mo->friction)*(0x70))/0x158; } else mo->friction = ORIG_FRICTION; @@ -1474,9 +1666,12 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy) // spinning friction if (player->pflags & PF_SPINNING && (player->rmomx || player->rmomy) && !(player->pflags & PF_STARTDASH)) { - const fixed_t ns = FixedDiv(549*FRICTION,500*FRACUNIT); - mo->momx = FixedMul(mo->momx, ns); - mo->momy = FixedMul(mo->momy, ns); + if (twodlevel || player->mo->flags2 & MF2_TWOD) // Otherwise handled in P_3DMovement + { + const fixed_t ns = FixedDiv(549*ORIG_FRICTION,500*FRACUNIT); + mo->momx = FixedMul(mo->momx, ns); + mo->momy = FixedMul(mo->momy, ns); + } } else if (abs(player->rmomx) < FixedMul(STOPSPEED, mo->scale) && abs(player->rmomy) < FixedMul(STOPSPEED, mo->scale) @@ -1492,7 +1687,7 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy) mo->momx = player->cmomx; mo->momy = player->cmomy; } - else + else if (!(mo->eflags & MFE_SPRUNG)) { if (oldx == mo->x && oldy == mo->y) // didn't go anywhere { @@ -1693,7 +1888,8 @@ void P_XYMovement(mobj_t *mo) if (CheckForBustableBlocks && mo->flags & MF_PUSHABLE) P_PushableCheckBustables(mo); - if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) && !(mo->eflags & MFE_SPRUNG)) + if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) + && !(P_MobjWasRemoved(mo) || mo->eflags & MFE_SPRUNG)) { // blocked move moved = false; @@ -1703,7 +1899,17 @@ void P_XYMovement(mobj_t *mo) B_MoveBlocked(player); } - if (mo->flags & MF_BOUNCE) +#ifdef HAVE_BLUA + if (LUAh_MobjMoveBlocked(mo)) + { + if (P_MobjWasRemoved(mo)) + return; + } + else +#endif + if (P_MobjWasRemoved(mo)) + return; + else if (mo->flags & MF_BOUNCE) { P_BounceMove(mo); xmove = ymove = 0; @@ -1752,8 +1958,41 @@ void P_XYMovement(mobj_t *mo) } else if (player || mo->flags & (MF_SLIDEME|MF_PUSHABLE)) { // try to slide along it +#ifdef ESLOPE + // Wall transfer part 1. + pslope_t *transferslope = NULL; + fixed_t transfermomz = 0; + if (oldslope && (P_MobjFlip(mo)*(predictedz - mo->z) > 0)) // Only for moving up (relative to gravity), otherwise there's a failed launch when going down slopes and hitting walls + { + transferslope = ((mo->standingslope) ? mo->standingslope : oldslope); + if (((transferslope->zangle < ANGLE_180) ? transferslope->zangle : InvAngle(transferslope->zangle)) >= ANGLE_45) // Prevent some weird stuff going on on shallow slopes. + transfermomz = P_GetWallTransferMomZ(mo, transferslope); + } +#endif + P_SlideMove(mo); + if (player) + player->powers[pw_pushing] = 3; xmove = ymove = 0; + +#ifdef ESLOPE + // Wall transfer part 2. + if (transfermomz && transferslope) // Are we "transferring onto the wall" (really just a disguised vertical launch)? + { + angle_t relation; // Scale transfer momentum based on how head-on it is to the slope. + if (mo->momx || mo->momy) // "Guess" the angle of the wall you hit using new momentum + relation = transferslope->xydirection - R_PointToAngle2(0, 0, mo->momx, mo->momy); + else // Give it for free, I guess. + relation = ANGLE_90; + transfermomz = FixedMul(transfermomz, + abs(FINESINE((relation >> ANGLETOFINESHIFT) & FINEMASK))); + if (P_MobjFlip(mo)*(transfermomz - mo->momz) > 2*FRACUNIT) // Do the actual launch! + { + mo->momz = transfermomz; + mo->standingslope = NULL; + } + } +#endif } else if (mo->type == MT_SPINFIRE) { @@ -1860,7 +2099,7 @@ void P_XYMovement(mobj_t *mo) // Check the gravity status. P_CheckGravity(mo, false); - if (player && !moved && player->pflags & PF_NIGHTSMODE && mo->target) + if (player && !moved && player->powers[pw_carry] == CR_NIGHTSMODE && mo->target) { angle_t fa; @@ -1897,13 +2136,13 @@ void P_XYMovement(mobj_t *mo) if (mo->flags & MF_NOCLIPHEIGHT) return; // no frictions for objects that can pass through floors - if (mo->flags & MF_MISSILE || mo->flags2 & MF2_SKULLFLY || mo->type == MT_SHELL || mo->type == MT_VULTURE) + if (mo->flags & MF_MISSILE || mo->flags2 & MF2_SKULLFLY || mo->type == MT_SHELL || mo->type == MT_VULTURE || mo->type == MT_PENGUINATOR) return; // no friction for missiles ever if (player && player->homing) // no friction for homing return; - if (player && player->pflags & PF_NIGHTSMODE) + if (player && player->powers[pw_carry] == CR_NIGHTSMODE) return; // no friction for NiGHTS players #ifdef ESLOPE @@ -1964,7 +2203,7 @@ static void P_SceneryXYMovement(mobj_t *mo) // 1 - forces false check for water (rings) // 2 - forces false check for water + different quicksand behaviour (scenery) // -static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype) +void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype) { ffloor_t *rover; fixed_t delta1, delta2, thingtop; @@ -1983,14 +2222,16 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL); bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL); - if (mo->player && (P_CheckSolidLava(mo, rover) || P_CanRunOnWater(mo->player, rover))) // only the player should be affected + if (mo->player && (P_CheckSolidLava(mo, rover) || P_CanRunOnWater(mo->player, rover))) // only the player should stand on lava or run on water ; else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only continue; else if (rover->flags & FF_QUICKSAND) // quicksand ; - else if (!((rover->flags & FF_BLOCKPLAYER && mo->player) // solid to players? - || (rover->flags & FF_BLOCKOTHERS && !mo->player))) // solid to others? + else if (!( // if it's not either of the following... + (rover->flags & (FF_BLOCKPLAYER|FF_MARIO) && mo->player) // ...solid to players? (mario blocks are always solid from beneath to players) + || (rover->flags & FF_BLOCKOTHERS && !mo->player) // ...solid to others? + )) // ...don't take it into account. continue; if (rover->flags & FF_QUICKSAND) { @@ -2015,7 +2256,9 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp delta1 = mo->z - (bottomheight + ((topheight - bottomheight)/2)); delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2)); + if (topheight > mo->floorz && abs(delta1) < abs(delta2) + && (rover->flags & FF_SOLID) // Non-FF_SOLID Mario blocks are only solid from bottom && !(rover->flags & FF_REVERSEPLATFORM) && ((P_MobjFlip(mo)*mo->momz >= 0) || (!(rover->flags & FF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference) { @@ -2023,7 +2266,7 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp } if (bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2) && !(rover->flags & FF_PLATFORM) - && ((P_MobjFlip(mo)*mo->momz >= 0) || (!(rover->flags & FF_REVERSEPLATFORM)))) // In normal gravity, only clip for FOFs that are intangible from the top if you're coming from below + && ((P_MobjFlip(mo)*mo->momz >= 0) || ((rover->flags & FF_SOLID) && !(rover->flags & FF_REVERSEPLATFORM)))) // In normal gravity, only clip for FOFs that are intangible from the top if you're coming from below { mo->ceilingz = bottomheight; } @@ -2122,6 +2365,9 @@ boolean P_CheckDeathPitCollide(mobj_t *mo) I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); + if (mo->player && mo->player->pflags & PF_GODMODE) + return false; + if (((mo->z <= mo->subsector->sector->floorheight && !(mo->eflags & MFE_VERTICALFLIP) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR)) || (mo->z + mo->height >= mo->subsector->sector->ceilingheight @@ -2161,6 +2407,7 @@ boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover) static boolean P_ZMovement(mobj_t *mo) { fixed_t dist, delta; + boolean onground; I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); @@ -2178,13 +2425,14 @@ static boolean P_ZMovement(mobj_t *mo) mo->eflags &= ~MFE_APPLYPMOMZ; } mo->z += mo->momz; + onground = P_IsObjectOnGround(mo); #ifdef ESLOPE if (mo->standingslope) { if (mo->flags & MF_NOCLIPHEIGHT) mo->standingslope = NULL; - else if (!P_IsObjectOnGround(mo)) + else if (!onground) P_SlopeLaunch(mo); } #endif @@ -2215,6 +2463,23 @@ static boolean P_ZMovement(mobj_t *mo) mo->flags |= MF_NOGRAVITY; } break; + case MT_SPINFIRE: + if (P_CheckDeathPitCollide(mo)) + { + P_RemoveMobj(mo); + return false; + } + if (mo->momz + && !(mo->flags & MF_NOGRAVITY) + && ((!(mo->eflags & MFE_VERTICALFLIP) && mo->z <= mo->floorz) + || ((mo->eflags & MFE_VERTICALFLIP) && mo->z+mo->height >= mo->ceilingz))) + { + mo->flags |= MF_NOGRAVITY; + mo->momx = 8; // this is a hack which is used to ensure it still behaves as a missile and can damage others + mo->momy = mo->momz = 0; + mo->z = ((mo->eflags & MFE_VERTICALFLIP) ? mo->ceilingz-mo->height : mo->floorz); + } + break; case MT_GOOP: if (P_CheckDeathPitCollide(mo)) { @@ -2253,11 +2518,16 @@ static boolean P_ZMovement(mobj_t *mo) case MT_RING: // Ignore still rings case MT_COIN: - case MT_BLUEBALL: + case MT_BLUESPHERE: + case MT_BOMBSPHERE: + case MT_NIGHTSCHIP: + case MT_NIGHTSSTAR: case MT_REDTEAMRING: case MT_BLUETEAMRING: case MT_FLINGRING: case MT_FLINGCOIN: + case MT_FLINGBLUESPHERE: + case MT_FLINGNIGHTSCHIP: case MT_FLINGEMERALD: // Remove flinged stuff from death pits. if (P_CheckDeathPitCollide(mo)) @@ -2290,18 +2560,15 @@ static boolean P_ZMovement(mobj_t *mo) if (!(mo->momx || mo->momy || mo->momz)) return true; break; - case MT_NIGHTSWING: - if (!(mo->momx || mo->momy || mo->momz)) - return true; - break; case MT_FLAMEJET: case MT_VERTICALFLAMEJET: if (!(mo->flags & MF_BOUNCE)) return true; break; case MT_SPIKE: + case MT_WALLSPIKE: // Dead spike particles disappear upon ground contact - if ((mo->z <= mo->floorz || mo->z + mo->height >= mo->ceilingz) && mo->health <= 0) + if (!mo->health && (mo->z <= mo->floorz || mo->z + mo->height >= mo->ceilingz)) { P_RemoveMobj(mo); return false; @@ -2311,23 +2578,22 @@ static boolean P_ZMovement(mobj_t *mo) break; } - if (P_CheckDeathPitCollide(mo)) + if (!mo->player && P_CheckDeathPitCollide(mo)) { - if (mo->flags & MF_PUSHABLE) - { - // Remove other pushable items from death pits. - P_RemoveMobj(mo); - return false; - } - else if (mo->flags & MF_ENEMY || mo->flags & MF_BOSS) + if (mo->flags & MF_ENEMY || mo->flags & MF_BOSS || mo->type == MT_MINECART) { - // Kill enemies and bosses that fall into death pits. + // Kill enemies, bosses and minecarts that fall into death pits. if (mo->health) { - P_KillMobj(mo, NULL, NULL); + P_KillMobj(mo, NULL, NULL, 0); return false; } } + else + { + P_RemoveMobj(mo); + return false; + } } if (P_MobjFlip(mo)*mo->momz < 0 @@ -2440,9 +2706,7 @@ static boolean P_ZMovement(mobj_t *mo) if (P_MobjFlip(mo)*mom.z < 0) // falling { - if (!tmfloorthing || tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR) - || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER) - mo->eflags |= MFE_JUSTHITFLOOR; + mo->eflags |= MFE_JUSTHITFLOOR; if (mo->flags2 & MF2_SKULLFLY) // the skull slammed into something mom.z = -mom.z; @@ -2450,6 +2714,8 @@ static boolean P_ZMovement(mobj_t *mo) // Flingrings bounce if (mo->type == MT_FLINGRING || mo->type == MT_FLINGCOIN + || mo->type == MT_FLINGBLUESPHERE + || mo->type == MT_FLINGNIGHTSCHIP || P_WeaponOrPanel(mo->type) || mo->type == MT_FLINGEMERALD || mo->type == MT_BIGTUMBLEWEED @@ -2468,7 +2734,7 @@ static boolean P_ZMovement(mobj_t *mo) && abs(mom.y) < FixedMul(STOPSPEED, mo->scale) && abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale)) { - if (mo->flags & MF_AMBUSH) + if (mo->flags2 & MF2_AMBUSH) { // If deafed, give the tumbleweed another random kick if it runs out of steam. mom.z += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale); @@ -2499,12 +2765,11 @@ static boolean P_ZMovement(mobj_t *mo) // Stolen from P_SpawnFriction mo->friction = FRACUNIT - 0x100; - mo->movefactor = ((0x10092 - mo->friction)*(0x70))/0x158; } else if (mo->type == MT_FALLINGROCK) { if (P_MobjFlip(mo)*mom.z > FixedMul(2*FRACUNIT, mo->scale)) - S_StartSound(mo, mo->info->activesound + P_RandomKey(mo->info->mass)); + S_StartSound(mo, mo->info->activesound + P_RandomKey(mo->info->reactiontime)); mom.z /= 2; // Rocks not so bouncy @@ -2523,14 +2788,11 @@ static boolean P_ZMovement(mobj_t *mo) mom.z = 0; } } - else if (tmfloorthing && (tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR) - || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER)) - mom.z = tmfloorthing->momz; - else if (!tmfloorthing) - mom.z = 0; + else + mom.z = (tmfloorthing ? tmfloorthing->momz : 0); + } - else if (tmfloorthing && (tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR) - || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER)) + else if (tmfloorthing) mom.z = tmfloorthing->momz; #ifdef ESLOPE @@ -2616,6 +2878,8 @@ static boolean P_ZMovement(mobj_t *mo) static void P_PlayerZMovement(mobj_t *mo) { + boolean onground; + I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); @@ -2638,7 +2902,7 @@ static void P_PlayerZMovement(mobj_t *mo) mo->player->viewheight -= mo->floorz - mo->z; mo->player->deltaviewheight = - (FixedMul(cv_viewheight.value<<FRACBITS, mo->scale) - mo->player->viewheight)>>3; + (FixedMul(41*mo->player->height/48, mo->scale) - mo->player->viewheight)>>3; } // adjust height @@ -2649,6 +2913,7 @@ static void P_PlayerZMovement(mobj_t *mo) } mo->z += mo->momz; + onground = P_IsObjectOnGround(mo); // Have player fall through floor? if (mo->player->playerstate == PST_DEAD @@ -2660,20 +2925,20 @@ static void P_PlayerZMovement(mobj_t *mo) { if (mo->flags & MF_NOCLIPHEIGHT) mo->standingslope = NULL; - else if (!P_IsObjectOnGround(mo)) + else if (!onground) P_SlopeLaunch(mo); } #endif // clip movement - if (P_IsObjectOnGround(mo) && !(mo->flags & MF_NOCLIPHEIGHT)) + if (onground && !(mo->flags & MF_NOCLIPHEIGHT)) { if (mo->eflags & MFE_VERTICALFLIP) mo->z = mo->ceilingz - mo->height; else mo->z = mo->floorz; - if (mo->player->pflags & PF_NIGHTSMODE) + if (mo->player->powers[pw_carry] == CR_NIGHTSMODE) { // bounce off floor if you were flying towards it if ((mo->eflags & MFE_VERTICALFLIP && mo->player->flyangle > 0 && mo->player->flyangle < 180) @@ -2688,7 +2953,7 @@ static void P_PlayerZMovement(mobj_t *mo) goto nightsdone; } // Get up if you fell. - if (mo->state == &states[mo->info->painstate] || mo->state == &states[S_PLAY_SUPERHIT]) + if (mo->player->panim == PA_PAIN) P_SetPlayerMobjState(mo, S_PLAY_STND); #ifdef ESLOPE @@ -2700,147 +2965,97 @@ static void P_PlayerZMovement(mobj_t *mo) if (P_MobjFlip(mo)*mo->momz < 0) // falling { + boolean clipmomz = !(P_CheckDeathPitCollide(mo)); + mo->pmomz = 0; // We're on a new floor, don't keep doing platform movement. // Squat down. Decrease viewheight for a moment after hitting the ground (hard), if (P_MobjFlip(mo)*mo->momz < -FixedMul(8*FRACUNIT, mo->scale)) mo->player->deltaviewheight = (P_MobjFlip(mo)*mo->momz)>>3; // make sure momz is negative - if (!tmfloorthing || tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR) - || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER) // Spin Attack + mo->eflags |= MFE_JUSTHITFLOOR; // Spin Attack + { - mo->eflags |= MFE_JUSTHITFLOOR; // Spin Attack +#ifdef POLYOBJECTS + // Check if we're on a polyobject + // that triggers a linedef executor. + msecnode_t *node; + boolean stopmovecut = false; - if (mo->eflags & MFE_JUSTHITFLOOR) + for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) { -#ifdef POLYOBJECTS - // Check if we're on a polyobject - // that triggers a linedef executor. - msecnode_t *node; - boolean stopmovecut = false; + sector_t *sec = node->m_sector; + subsector_t *newsubsec; + size_t i; - for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) + for (i = 0; i < numsubsectors; i++) { - sector_t *sec = node->m_sector; - subsector_t *newsubsec; - size_t i; + newsubsec = &subsectors[i]; - for (i = 0; i < numsubsectors; i++) - { - newsubsec = &subsectors[i]; + if (newsubsec->sector != sec) + continue; - if (newsubsec->sector != sec) - continue; + if (newsubsec->polyList) + { + polyobj_t *po = newsubsec->polyList; + sector_t *polysec; - if (newsubsec->polyList) + while(po) { - polyobj_t *po = newsubsec->polyList; - sector_t *polysec; - - while(po) + if (!P_MobjInsidePolyobj(po, mo) || !(po->flags & POF_SOLID)) { - if (!P_MobjInsidePolyobj(po, mo) || !(po->flags & POF_SOLID)) - { - po = (polyobj_t *)(po->link.next); - continue; - } - - // We're inside it! Yess... - polysec = po->lines[0]->backsector; - - // Moving polyobjects should act like conveyors if the player lands on one. (I.E. none of the momentum cut thing below) -Red - if ((mo->z == polysec->ceilingheight || mo->z+mo->height == polysec->floorheight) && po->thinker) - stopmovecut = true; - - if (!(po->flags & POF_LDEXEC)) - { - po = (polyobj_t *)(po->link.next); - continue; - } - - if (mo->z == polysec->ceilingheight) - { - // We're landing on a PO, so check for - // a linedef executor. - // Trigger tags are 32000 + the PO's ID number. - P_LinedefExecute((INT16)(32000 + po->id), mo, NULL); - } + po = (polyobj_t *)(po->link.next); + continue; + } + + // We're inside it! Yess... + polysec = po->lines[0]->backsector; + + // Moving polyobjects should act like conveyors if the player lands on one. (I.E. none of the momentum cut thing below) -Red + if ((mo->z == polysec->ceilingheight || mo->z+mo->height == polysec->floorheight) && po->thinker) + stopmovecut = true; + if (!(po->flags & POF_LDEXEC)) + { po = (polyobj_t *)(po->link.next); + continue; + } + + if (mo->z == polysec->ceilingheight) + { + // We're landing on a PO, so check for + // a linedef executor. + // Trigger tags are 32000 + the PO's ID number. + P_LinedefExecute((INT16)(32000 + po->id), mo, NULL); } + + po = (polyobj_t *)(po->link.next); } } } + } - if (!stopmovecut) + if (!stopmovecut) #endif - // Cut momentum in half when you hit the ground and - // aren't pressing any controls. - if (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy && !(mo->player->pflags & PF_SPINNING)) - { - mo->momx = mo->momx/2; - mo->momy = mo->momy/2; - } - } - - if (mo->health) + // Cut momentum in half when you hit the ground and + // aren't pressing any controls. + if (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy && !(mo->player->pflags & PF_SPINNING)) { - if (mo->player->pflags & PF_GLIDING) // ground gliding - { - mo->player->skidtime = TICRATE; - mo->tics = -1; - } - else if (mo->player->pflags & PF_JUMPED || (mo->player->pflags & (PF_SPINNING|PF_USEDOWN)) != (PF_SPINNING|PF_USEDOWN) - || mo->player->powers[pw_tailsfly] || (mo->state >= &states[S_PLAY_SPC1] && mo->state <= &states[S_PLAY_SPC4])) - { - if (mo->player->cmomx || mo->player->cmomy) - { - if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN) - P_SetPlayerMobjState(mo, S_PLAY_SPD1); - else if ((mo->player->rmomx || mo->player->rmomy) && mo->player->panim != PA_WALK) - P_SetPlayerMobjState(mo, S_PLAY_RUN1); - else if (!mo->player->rmomx && !mo->player->rmomy && mo->player->panim != PA_IDLE) - P_SetPlayerMobjState(mo, S_PLAY_STND); - } - else - { - if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN) - P_SetPlayerMobjState(mo, S_PLAY_SPD1); - else if ((mo->momx || mo->momy) && mo->player->panim != PA_WALK) - P_SetPlayerMobjState(mo, S_PLAY_RUN1); - else if (!mo->momx && !mo->momy && mo->player->panim != PA_IDLE) - P_SetPlayerMobjState(mo, S_PLAY_STND); - } - } - - if (mo->player->pflags & PF_JUMPED) - mo->player->pflags &= ~PF_SPINNING; - else if (!(mo->player->pflags & PF_USEDOWN)) - mo->player->pflags &= ~PF_SPINNING; - - if (!(mo->player->pflags & PF_GLIDING)) - mo->player->pflags &= ~PF_JUMPED; - mo->player->pflags &= ~PF_THOKKED; - //mo->player->pflags &= ~PF_GLIDING; - mo->player->jumping = 0; - mo->player->secondjump = 0; - mo->player->glidetime = 0; - mo->player->climbing = 0; - mo->player->powers[pw_tailsfly] = 0; + mo->momx >>= 1; + mo->momy >>= 1; } } - if (!(mo->player->pflags & PF_SPINNING)) + + clipmomz = P_PlayerHitFloor(mo->player); + + if (!(mo->player->pflags & PF_SPINNING) && mo->player->powers[pw_carry] != CR_NIGHTSMODE) mo->player->pflags &= ~PF_STARTDASH; - if (tmfloorthing && (tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR) - || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER)) - mo->momz = tmfloorthing->momz; - else if (!tmfloorthing) - mo->momz = 0; + if (clipmomz) + mo->momz = (tmfloorthing ? tmfloorthing->momz : 0); } - else if (tmfloorthing && (tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR) - || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER)) + else if (tmfloorthing) mo->momz = tmfloorthing->momz; } else if (!(mo->flags & MF_NOGRAVITY)) // Gravity here! @@ -2873,7 +3088,7 @@ nightsdone: else mo->z = mo->ceilingz - mo->height; - if (mo->player->pflags & PF_NIGHTSMODE) + if (mo->player->powers[pw_carry] == CR_NIGHTSMODE) { // bounce off ceiling if you were flying towards it if ((mo->eflags & MFE_VERTICALFLIP && mo->player->flyangle > 180 && mo->player->flyangle <= 359) @@ -2911,8 +3126,13 @@ nightsdone: if (rover->flags & FF_MARIO && !(mo->eflags & MFE_VERTICALFLIP) // if you were flipped, your head isn't actually hitting your ceilingz is it? && *rover->bottomheight == mo->ceilingz) // The player's head hit the bottom! + { // DO THE MARIO! - EV_MarioBlock(rover->master->frontsector, node->m_sector, *rover->topheight, mo); + if (rover->flags & FF_SHATTERBOTTOM) // Brick block! + EV_CrumbleChain(node->m_sector, rover); + else // Question block! + EV_MarioBlock(rover, node->m_sector, mo); + } } } // Ugly ugly billions of braces! Argh! } @@ -3001,34 +3221,26 @@ static boolean P_SceneryZMovement(mobj_t *mo) if ((!(mo->eflags & MFE_VERTICALFLIP) && mo->z <= mo->floorz) || (mo->eflags & MFE_VERTICALFLIP && mo->z+mo->height >= mo->ceilingz)) { - // DO NOT use random numbers here. - // SonicCD mode is console togglable and - // affects demos. - UINT8 rltime = (leveltime & 4); - - if (!rltime) - P_SpawnMobj(mo->x, mo->y, mo->floorz, MT_GFZFLOWER3); - else if (rltime == 2) - P_SpawnMobj(mo->x, mo->y, mo->floorz, MT_GFZFLOWER2); - else - P_SpawnMobj(mo->x, mo->y, mo->floorz, MT_GFZFLOWER1); + mobjtype_t flowertype = ((P_RandomChance(FRACUNIT/2)) ? MT_GFZFLOWER1 : MT_GFZFLOWER3); + mobj_t *flower = P_SpawnMobjFromMobj(mo, 0, 0, 0, flowertype); + if (flower) + { + P_SetScale(flower, mo->scale/16); + flower->destscale = mo->scale; + flower->scalespeed = mo->scale/8; + } P_RemoveMobj(mo); return false; } - default: break; } - // Fix for any silly pushables like the egg statues that are also scenery for some reason -- Monster Iestyn if (P_CheckDeathPitCollide(mo)) { - if (mo->flags & MF_PUSHABLE) - { - P_RemoveMobj(mo); - return false; - } + P_RemoveMobj(mo); + return false; } // clip movement @@ -3043,12 +3255,9 @@ static boolean P_SceneryZMovement(mobj_t *mo) if (P_MobjFlip(mo)*mo->momz < 0) // falling { - if (!tmfloorthing || tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR) - || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER) - mo->eflags |= MFE_JUSTHITFLOOR; // Spin Attack + mo->eflags |= MFE_JUSTHITFLOOR; // Spin Attack - if (tmfloorthing && (tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR) - || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER)) + if (tmfloorthing) mo->momz = tmfloorthing->momz; else if (!tmfloorthing) mo->momz = 0; @@ -3090,8 +3299,8 @@ boolean P_CanRunOnWater(player_t *player, ffloor_t *rover) #endif *rover->topheight; - if (!(player->pflags & PF_NIGHTSMODE) && !player->homing - && (((player->charability == CA_SWIM) || player->powers[pw_super] || player->charflags & SF_RUNONWATER) && player->mo->ceilingz-topheight >= player->mo->height) + if (!player->powers[pw_carry] && !player->homing + && ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= 3*TICRATE) && player->mo->ceilingz-topheight >= player->mo->height) && (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale) && !(player->pflags & PF_SLIDING) && abs(player->mo->z - topheight) < FixedMul(30*FRACUNIT, player->mo->scale)) @@ -3110,10 +3319,12 @@ void P_MobjCheckWater(mobj_t *mobj) boolean waterwasnotset = (mobj->watertop == INT32_MAX); boolean wasinwater = (mobj->eflags & MFE_UNDERWATER) == MFE_UNDERWATER; boolean wasingoo = (mobj->eflags & MFE_GOOWATER) == MFE_GOOWATER; - fixed_t thingtop = mobj->z + mobj->height; // especially for players, infotable height does not neccessarily match actual height + fixed_t thingtop = mobj->z + mobj->height; sector_t *sector = mobj->subsector->sector; ffloor_t *rover; player_t *p = mobj->player; // Will just be null if not a player. + fixed_t height = (p ? P_GetPlayerHeight(p) : mobj->height); // for players, calculation height does not necessarily match actual height for gameplay reasons (spin, etc) + boolean wasgroundpounding = (p && (mobj->eflags & MFE_GOOWATER) && ((p->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (p->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (p->pflags & PF_SHIELDABILITY)); // Default if no water exists. mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT; @@ -3142,14 +3353,14 @@ void P_MobjCheckWater(mobj_t *mobj) if (mobj->eflags & MFE_VERTICALFLIP) { - if (topheight < (thingtop - FixedMul(mobj->info->height/2, mobj->scale)) + if (topheight < (thingtop - (height>>1)) || bottomheight > thingtop) continue; } else { if (topheight < mobj->z - || bottomheight > (mobj->z + FixedMul(mobj->info->height/2, mobj->scale))) + || bottomheight > (mobj->z + (height>>1))) continue; } @@ -3158,16 +3369,16 @@ void P_MobjCheckWater(mobj_t *mobj) mobj->waterbottom = bottomheight; // Just touching the water? - if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height, mobj->scale) < bottomheight) - || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height, mobj->scale) > topheight)) + if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - height < bottomheight) + || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + height > topheight)) { mobj->eflags |= MFE_TOUCHWATER; if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY)) mobj->eflags |= MFE_GOOWATER; } // Actually in the water? - if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height/2, mobj->scale) > bottomheight) - || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height/2, mobj->scale) < topheight)) + if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - (height>>1) > bottomheight) + || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + (height>>1) < topheight)) { mobj->eflags |= MFE_UNDERWATER; if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY)) @@ -3175,20 +3386,33 @@ void P_MobjCheckWater(mobj_t *mobj) } } + // Spectators and dead players don't get to do any of the things after this. + if (p && (p->spectator || p->playerstate != PST_LIVE)) + return; + // Specific things for underwater players if (p && (mobj->eflags & MFE_UNDERWATER) == MFE_UNDERWATER) { if (!((p->powers[pw_super]) || (p->powers[pw_invulnerability]))) { - if ((p->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT) - { // Water removes attract shield. + boolean electric = !!(p->powers[pw_shield] & SH_PROTECTELECTRIC); +#define SH_OP (SH_PROTECTFIRE|SH_PROTECTWATER|SH_PROTECTELECTRIC) + if ((p->powers[pw_shield] & SH_OP) == SH_OP) // No. + P_KillMobj(mobj, NULL, NULL, DMG_INSTAKILL); +#undef SH_OP + else if (electric || ((p->powers[pw_shield] & SH_PROTECTFIRE) && !(p->powers[pw_shield] & SH_PROTECTWATER))) + { // Water removes electric and non-water fire shields... + P_FlashPal(p, + electric + ? PAL_WHITE + : PAL_NUKE, + 1); p->powers[pw_shield] = p->powers[pw_shield] & SH_STACK; - P_FlashPal(p, PAL_WHITE, 1); } } // Drown timer setting - if ((p->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL // Has elemental + if ((p->powers[pw_shield] & SH_PROTECTWATER) // Has water protection || (p->exiting) // Or exiting || (maptol & TOL_NIGHTS) // Or in NiGHTS mode || (mariomode)) // Or in Mario mode... @@ -3201,16 +3425,18 @@ void P_MobjCheckWater(mobj_t *mobj) // Then we'll set it! p->powers[pw_underwater] = underwatertics + 1; } + + if (wasgroundpounding) + { + p->pflags &= ~PF_SHIELDABILITY; + mobj->momz >>= 1; + } } // The rest of this code only executes on a water state change. if (waterwasnotset || !!(mobj->eflags & MFE_UNDERWATER) == wasinwater) return; - // Spectators and dead players also don't count. - if (p && (p->spectator || p->playerstate != PST_LIVE)) - return; - if ((p) // Players || (mobj->flags & MF_PUSHABLE) // Pushables || ((mobj->info->flags & MF_PUSHABLE) && mobj->fuse) // Previously pushable, might be moving still @@ -3218,13 +3444,11 @@ void P_MobjCheckWater(mobj_t *mobj) { // Check to make sure you didn't just cross into a sector to jump out of // that has shallower water than the block you were originally in. - if (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->watertop-mobj->floorz <= FixedMul(mobj->info->height, mobj->scale)>>1) - return; - - if ((mobj->eflags & MFE_VERTICALFLIP) && mobj->ceilingz-mobj->waterbottom <= FixedMul(mobj->info->height, mobj->scale)>>1) + if ((!(mobj->eflags & MFE_VERTICALFLIP) && mobj->watertop-mobj->floorz <= height>>1) + || ((mobj->eflags & MFE_VERTICALFLIP) && mobj->ceilingz-mobj->waterbottom <= height>>1)) return; - if ((mobj->eflags & MFE_GOOWATER || wasingoo)) { // Decide what happens to your momentum when you enter/leave goopy water. + if (!wasgroundpounding && (mobj->eflags & MFE_GOOWATER || wasingoo)) { // Decide what happens to your momentum when you enter/leave goopy water. if (P_MobjFlip(mobj)*mobj->momz < 0) // You are entering the goo? mobj->momz = FixedMul(mobj->momz, FixedDiv(2*FRACUNIT, 5*FRACUNIT)); // kill momentum significantly, to make the goo feel thick. } @@ -3233,8 +3457,8 @@ void P_MobjCheckWater(mobj_t *mobj) if (P_MobjFlip(mobj)*mobj->momz < 0) { - if ((mobj->eflags & MFE_VERTICALFLIP && thingtop-(FixedMul(mobj->info->height, mobj->scale)>>1)-mobj->momz <= mobj->waterbottom) - || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(FixedMul(mobj->info->height, mobj->scale)>>1)-mobj->momz >= mobj->watertop)) + if ((mobj->eflags & MFE_VERTICALFLIP && thingtop-(height>>1)-mobj->momz <= mobj->waterbottom) + || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(height>>1)-mobj->momz >= mobj->watertop)) { // Spawn a splash mobj_t *splish; @@ -3267,8 +3491,8 @@ void P_MobjCheckWater(mobj_t *mobj) } else if (P_MobjFlip(mobj)*mobj->momz > 0) { - if (((mobj->eflags & MFE_VERTICALFLIP && thingtop-(FixedMul(mobj->info->height, mobj->scale)>>1)-mobj->momz > mobj->waterbottom) - || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(FixedMul(mobj->info->height, mobj->scale)>>1)-mobj->momz < mobj->watertop)) + if (((mobj->eflags & MFE_VERTICALFLIP && thingtop-(height>>1)-mobj->momz > mobj->waterbottom) + || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(height>>1)-mobj->momz < mobj->watertop)) && !(mobj->eflags & MFE_UNDERWATER)) // underwater check to prevent splashes on opposite side { // Spawn a splash @@ -3373,10 +3597,10 @@ static void P_SceneryCheckWater(mobj_t *mobj) #endif if (topheight <= mobj->z - || bottomheight > (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale))) + || bottomheight > (mobj->z + (mobj->height>>1))) continue; - if (mobj->z + FixedMul(mobj->info->height, mobj->scale) > topheight) + if (mobj->z + mobj->height > topheight) mobj->eflags |= MFE_TOUCHWATER; else mobj->eflags &= ~MFE_TOUCHWATER; @@ -3385,7 +3609,7 @@ static void P_SceneryCheckWater(mobj_t *mobj) mobj->watertop = topheight; mobj->waterbottom = bottomheight; - if (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale) < topheight) + if (mobj->z + (mobj->height>>1) < topheight) mobj->eflags |= MFE_UNDERWATER; else mobj->eflags &= ~MFE_UNDERWATER; @@ -3481,14 +3705,14 @@ void P_DestroyRobots(void) continue; // not a mobj thinker mo = (mobj_t *)think; - if (mo->health <= 0 || !(mo->flags & MF_ENEMY || mo->flags & MF_BOSS)) + if (mo->health <= 0 || !(mo->flags & (MF_ENEMY|MF_BOSS))) continue; // not a valid enemy if (mo->type == MT_PLAYER) // Don't chase after other players! continue; // Found a target enemy - P_KillMobj(mo, players[consoleplayer].mo, players[consoleplayer].mo); + P_KillMobj(mo, players[consoleplayer].mo, players[consoleplayer].mo, 0); } } @@ -3504,7 +3728,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled || (thiscam == &camera2 && players[secondarydisplayplayer].mo && (players[secondarydisplayplayer].mo->flags2 & MF2_TWOD))) itsatwodlevel = true; - if (player->pflags & PF_FLIPCAM && !(player->pflags & PF_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP) + if (player->pflags & PF_FLIPCAM && !(player->powers[pw_carry] == CR_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP) postimg = postimg_flip; else if (player->awayviewtics && player->awayviewmobj && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist { @@ -3638,21 +3862,27 @@ static void P_PlayerMobjThinker(mobj_t *mobj) // momentum movement mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN; + if (mobj->state-states == S_PLAY_BOUNCE_LANDING) + goto animonly; // no need for checkposition - doesn't move at ALL + // Zoom tube - if (mobj->tracer && mobj->tracer->type == MT_TUBEWAYPOINT) + if (mobj->tracer) { - P_UnsetThingPosition(mobj); - mobj->x += mobj->momx; - mobj->y += mobj->momy; - mobj->z += mobj->momz; - P_SetThingPosition(mobj); - P_CheckPosition(mobj, mobj->x, mobj->y); - goto animonly; - } - else if (mobj->player->pflags & PF_MACESPIN && mobj->tracer) - { - P_CheckPosition(mobj, mobj->x, mobj->y); - goto animonly; + if (mobj->player->powers[pw_carry] == CR_ZOOMTUBE || mobj->player->powers[pw_carry] == CR_ROPEHANG) + { + P_UnsetThingPosition(mobj); + mobj->x += mobj->momx; + mobj->y += mobj->momy; + mobj->z += mobj->momz; + P_SetThingPosition(mobj); + P_CheckPosition(mobj, mobj->x, mobj->y); + goto animonly; + } + else if (mobj->player->powers[pw_carry] == CR_MACESPIN) + { + P_CheckPosition(mobj, mobj->x, mobj->y); + goto animonly; + } } // Needed for gravity boots @@ -3755,30 +3985,20 @@ static void P_PlayerMobjThinker(mobj_t *mobj) } else { - if (!(mobj->player->pflags & PF_NIGHTSMODE)) // "jumping" is used for drilling - mobj->player->jumping = 0; - mobj->player->pflags &= ~PF_JUMPED; + if (!(mobj->player->powers[pw_carry] == CR_NIGHTSMODE)) // used for drilling + mobj->player->pflags &= ~PF_STARTJUMP; + mobj->player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE); if (mobj->player->secondjump || mobj->player->powers[pw_tailsfly]) { mobj->player->secondjump = 0; mobj->player->powers[pw_tailsfly] = 0; - P_SetPlayerMobjState(mobj, S_PLAY_RUN1); + P_SetPlayerMobjState(mobj, S_PLAY_WALK); } mobj->eflags &= ~MFE_JUSTHITFLOOR; } animonly: - // cycle through states, - // calling action functions at transitions - if (mobj->tics != -1) - { - mobj->tics--; - - // you can cycle through multiple states in a tic - if (!mobj->tics) - if (!P_SetPlayerMobjState(mobj, mobj->state->nextstate)) - return; // freed itself - } + P_CyclePlayerMobjState(mobj); } static void CalculatePrecipFloor(precipmobj_t *mobj) @@ -3881,17 +4101,18 @@ void P_RainThinker(precipmobj_t *mobj) } // adjust height - if ((mobj->z += mobj->momz) <= mobj->floorz) + if ((mobj->z += mobj->momz) > mobj->floorz) + return; + + // no splashes on sky or bottomless pits + if (mobj->precipflags & PCF_PIT) { - // no splashes on sky or bottomless pits - if (mobj->precipflags & PCF_PIT) - mobj->z = mobj->ceilingz; - else - { - mobj->z = mobj->floorz; - P_SetPrecipMobjState(mobj, S_SPLASH1); - } + mobj->z = mobj->ceilingz; + return; } + + mobj->z = mobj->floorz; + P_SetPrecipMobjState(mobj, S_SPLASH1); } static void P_RingThinker(mobj_t *mobj) @@ -3951,15 +4172,15 @@ boolean P_BossTargetPlayer(mobj_t *actor, boolean closest) player = &players[actor->lastlook]; - if (player->health <= 0) - continue; // dead - if (player->pflags & PF_INVIS || player->bot || player->spectator) continue; // ignore notarget if (!player->mo || P_MobjWasRemoved(player->mo)) continue; + if (player->mo->health <= 0) + continue; //dead + if (!P_CheckSight(actor, player->mo)) continue; // out of sight @@ -3989,15 +4210,15 @@ boolean P_SupermanLook4Players(mobj_t *actor) { if (playeringame[c]) { - if (players[c].health <= 0) - continue; // dead - if (players[c].pflags & PF_INVIS) continue; // ignore notarget if (!players[c].mo || players[c].bot) continue; + if (players[c].mo->health <= 0) + continue; // dead + playersinthegame[stop] = &players[c]; stop++; } @@ -4077,7 +4298,15 @@ static void P_Boss1Thinker(mobj_t *mobj) return; } - if (mobj->state != &states[mobj->info->spawnstate] && mobj->health > 0 && mobj->flags & MF_FLOAT && !(mobj->flags2 & MF2_SKULLFLY)) + if (mobj->flags2 & MF2_SKULLFLY) + { + fixed_t dist = (mobj->eflags & MFE_VERTICALFLIP) + ? ((mobj->ceilingz-(2*mobj->height)) - (mobj->z+mobj->height)) + : (mobj->z - (mobj->floorz+(2*mobj->height))); + if (dist > 0 && P_MobjFlip(mobj)*mobj->momz > 0) + mobj->momz = FixedMul(mobj->momz, FRACUNIT - (dist>>12)); + } + else if (mobj->state != &states[mobj->info->spawnstate] && mobj->health > 0 && mobj->flags & MF_FLOAT) mobj->momz = FixedMul(mobj->momz,7*FRACUNIT/8); if (mobj->state == &states[mobj->info->meleestate] @@ -4194,7 +4423,7 @@ static void P_Boss3Thinker(mobj_t *mobj) continue; if (players[i].mo->eflags & MFE_UNDERWATER) - P_DamageMobj(players[i].mo, mobj, mobj, 1); + P_DamageMobj(players[i].mo, mobj, mobj, 1, 0); } // Make the water flash @@ -4535,7 +4764,7 @@ static void P_Boss4PopSpikeballs(mobj_t *mobj) P_SetTarget(&base->tracer, NULL); for (seg = base; seg; seg = seg->hnext) if (seg->health) - P_KillMobj(seg, NULL, NULL); + P_KillMobj(seg, NULL, NULL, 0); base = next; } } @@ -4785,6 +5014,47 @@ static void P_Boss4Thinker(mobj_t *mobj) A_FaceTarget(mobj); } +// +// AI for the fifth boss. +// +static void P_Boss5Thinker(mobj_t *mobj) +{ + if (!mobj->health) + { + if (mobj->state == &states[mobj->info->xdeathstate]) + mobj->momz -= (2*FRACUNIT)/3; + else if (mobj->tracer && P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y) < 2*mobj->radius) + mobj->flags &= ~MF_NOCLIP; + } + else + { + if (mobj->flags2 & MF2_FRET && (leveltime & 1) + && mobj->state != &states[S_FANG_PAIN1] && mobj->state != &states[S_FANG_PAIN2]) + mobj->flags2 |= MF2_DONTDRAW; + else + mobj->flags2 &= ~MF2_DONTDRAW; + } + + if (mobj->state == &states[S_FANG_BOUNCE3] + || mobj->state == &states[S_FANG_BOUNCE4] + || mobj->state == &states[S_FANG_PINCHBOUNCE3] + || mobj->state == &states[S_FANG_PINCHBOUNCE4]) + { + if (P_MobjFlip(mobj)*mobj->momz > 0 + && abs(mobj->momx) < FRACUNIT/2 && abs(mobj->momy) < FRACUNIT/2 + && !P_IsObjectOnGround(mobj)) + { + mobj_t *prevtarget = mobj->target; + P_SetTarget(&mobj->target, NULL); + var1 = var2 = 0; + A_DoNPCPain(mobj); + P_SetTarget(&mobj->target, prevtarget); + P_SetMobjState(mobj, S_FANG_WALLHIT); + mobj->extravalue2++; + } + } +} + // // AI for Black Eggman // Note: You CANNOT have more than ONE Black Eggman @@ -4835,7 +5105,7 @@ static void P_Boss7Thinker(mobj_t *mobj) { INT32 i; - P_KillMobj(mobj, NULL, NULL); + P_KillMobj(mobj, NULL, NULL, 0); // It was a team effort for (i = 0; i < MAXPLAYERS; i++) @@ -4886,7 +5156,7 @@ static void P_Boss7Thinker(mobj_t *mobj) && players[i].mo->z < mobj->z + mobj->height + 128*FRACUNIT) // You can't be in the vicinity, either... { // Punch him! - P_DamageMobj(players[i].mo, mobj, mobj, 1); + P_DamageMobj(players[i].mo, mobj, mobj, 1, 0); mobj->state->nextstate = mobj->info->spawnstate; // Laugh @@ -4961,10 +5231,10 @@ static void P_Boss7Thinker(mobj_t *mobj) if (players[i].mo->health <= 0) continue; - if (players[i].powers[pw_ingoop]) + if (players[i].powers[pw_carry] == CR_BRAKGOOP) { closestNum = -1; - closestdist = 16384*FRACUNIT; // Just in case... + closestdist = INT32_MAX; // Just in case... // Find waypoint he is closest to for (th = thinkercap.next; th != &thinkercap; th = th->next) @@ -5109,7 +5379,7 @@ static void P_Boss7Thinker(mobj_t *mobj) if (players[i].mo->z < mobj->z - 64*FRACUNIT) continue; - P_DamageMobj(players[i].mo, mobj, mobj, 1); + P_DamageMobj(players[i].mo, mobj, mobj, 1, 0); // Laugh S_StartSound(0, sfx_bewar1 + P_RandomKey(4)); @@ -5122,6 +5392,15 @@ static void P_Boss7Thinker(mobj_t *mobj) } +#define vectorise mobj->movedir = ANGLE_11hh - FixedAngle(FixedMul(AngleFixed(ANGLE_11hh), FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS)));\ + if (P_RandomChance(FRACUNIT/2))\ + mobj->movedir = InvAngle(mobj->movedir);\ + mobj->threshold = 6 + (FixedMul(24<<FRACBITS, FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS))>>FRACBITS);\ + if (mobj->info->activesound)\ + S_StartSound(mobj, mobj->info->activesound);\ + if (mobj->info->painchance)\ + P_SetMobjState(mobj, mobj->info->painchance) + // Metal Sonic battle boss // You CAN put multiple Metal Sonics in a single map // because I am a totally competent programmer who can do shit right. @@ -5166,19 +5445,41 @@ static void P_Boss9Thinker(mobj_t *mobj) if (mobj->health <= 0) return; + if ((statenum_t)(mobj->state-states) == mobj->info->meleestate) + { + P_InstaThrust(mobj, mobj->angle, -4*FRACUNIT); + P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true); + mobj->momz -= gravity; + if (mobj->z < mobj->watertop) + { + mobj->watertop = mobj->target->floorz + 32*FRACUNIT; + P_SetMobjState(mobj, mobj->info->spawnstate); + } + return; + } + if ((!mobj->target || !(mobj->target->flags & MF_SHOOTABLE))) { + if (mobj->tracer) + P_RemoveMobj(mobj->tracer); P_BossTargetPlayer(mobj, false); if (mobj->target && (!P_IsObjectOnGround(mobj->target) || mobj->target->player->pflags & PF_SPINNING)) P_SetTarget(&mobj->target, NULL); // Wait for them to hit the ground first if (!mobj->target) // Still no target, aww. { // Reset the boss. + if (mobj->tracer) + P_RemoveMobj(mobj->tracer); P_SetMobjState(mobj, mobj->info->spawnstate); mobj->fuse = 0; mobj->momx = FixedDiv(mobj->momx, FRACUNIT + (FRACUNIT>>2)); mobj->momy = FixedDiv(mobj->momy, FRACUNIT + (FRACUNIT>>2)); mobj->momz = FixedDiv(mobj->momz, FRACUNIT + (FRACUNIT>>2)); + mobj->watertop = mobj->floorz + 32*FRACUNIT; + mobj->momz = (mobj->watertop - mobj->z)>>3; + mobj->threshold = 0; + mobj->movecount = 0; + mobj->flags = mobj->info->flags; return; } else if (!mobj->fuse) @@ -5226,7 +5527,8 @@ static void P_Boss9Thinker(mobj_t *mobj) } if (spawner) { mobj_t *missile = P_SpawnMissile(spawner, mobj, MT_MSGATHER); - missile->momz = FixedDiv(missile->momz, 7*FRACUNIT/4); + if (mobj->health > mobj->info->damage) + missile->momz = FixedDiv(missile->momz, 7*FRACUNIT/5); if (dist == 0) missile->fuse = 0; else @@ -5238,16 +5540,22 @@ static void P_Boss9Thinker(mobj_t *mobj) // Pre-threshold reactiontime stuff for attack phases if (mobj->reactiontime && mobj->movecount == 3) { + mobj->reactiontime--; + if (mobj->movedir == 0 || mobj->movedir == 2) { // Pausing between bounces in the pinball phase if (mobj->target->player->powers[pw_tailsfly]) // Trying to escape, eh? mobj->watertop = mobj->target->z + mobj->target->momz*6; // Readjust your aim. >:3 else mobj->watertop = mobj->target->floorz + 16*FRACUNIT; - if (!(mobj->threshold%4)) + + if (!(mobj->threshold%4)) { mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x + mobj->target->momx*4, mobj->target->y + mobj->target->momy*4); + if (!mobj->reactiontime) + S_StartSound(mobj, sfx_zoom); // zoom! + } } - // Pausing between energy ball shots - mobj->reactiontime--; + // else -- Pausing between energy ball shots + return; } @@ -5319,20 +5627,28 @@ static void P_Boss9Thinker(mobj_t *mobj) P_InstaThrust(mobj, mobj->angle, 30*FRACUNIT); if (!P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true)) { // Hit a wall? Find a direction to bounce mobj->threshold--; - if (mobj->threshold) { - P_SetMobjState(mobj, mobj->state->nextstate); - if (mobj->info->mass) - S_StartSound(mobj, mobj->info->mass); - if (!(mobj->threshold%4)) { // We've decided to lock onto the player this bounce. - mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x + mobj->target->momx*4, mobj->target->y + mobj->target->momy*4); - mobj->reactiontime = TICRATE; // targetting time - } else { // No homing, just use P_BounceMove - P_BounceMove(mobj); - mobj->angle = R_PointToAngle2(0,0,mobj->momx,mobj->momy); - mobj->reactiontime = TICRATE/4; // just a pause before you bounce away - } - mobj->momx = mobj->momy = 0; + P_SetMobjState(mobj, mobj->state->nextstate); + if (!mobj->threshold) { // failed bounce! + S_StartSound(mobj, sfx_mspogo); + P_BounceMove(mobj); + mobj->angle = R_PointToAngle2(mobj->momx, mobj->momy,0,0); + mobj->momz = 4*FRACUNIT; + mobj->flags &= ~MF_PAIN; + mobj->fuse = 10*TICRATE; + mobj->movecount = 0; + P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_CYBRAKDEMON_VILE_EXPLOSION); + P_SetMobjState(mobj, mobj->info->meleestate); + } else if (!(mobj->threshold%4)) { // We've decided to lock onto the player this bounce. + S_StartSound(mobj, sfx_s3k5a); + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x + mobj->target->momx*4, mobj->target->y + mobj->target->momy*4); + mobj->reactiontime = TICRATE - 5*(mobj->info->damage - mobj->health); // targetting time + } else { // No homing, just use P_BounceMove + S_StartSound(mobj, sfx_s3kaa); // make the bounces distinct... + P_BounceMove(mobj); + mobj->angle = R_PointToAngle2(0,0,mobj->momx,mobj->momy); + mobj->reactiontime = 1; // TICRATE/4; // just a pause before you bounce away } + mobj->momx = mobj->momy = 0; } return; } @@ -5341,8 +5657,9 @@ static void P_Boss9Thinker(mobj_t *mobj) mobj->angle += mobj->movedir; P_InstaThrust(mobj, mobj->angle, -speed); while (!P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true) && tries++ < 16) { - mobj->angle += mobj->movedir; - P_InstaThrust(mobj, mobj->angle, -speed); + S_StartSound(mobj, sfx_mspogo); + P_BounceMove(mobj); + mobj->angle = R_PointToAngle2(mobj->momx, mobj->momy,0,0); } mobj->momx = mobj->momy = 0; mobj->threshold--; @@ -5459,9 +5776,9 @@ static void P_Boss9Thinker(mobj_t *mobj) S_StartSound(mobj, mobj->info->seesound); P_SetMobjState(mobj, mobj->info->seestate); if (mobj->movedir == 2) - mobj->threshold = 16; // bounce 16 times + mobj->threshold = 12; // bounce 12 times else - mobj->threshold = 32; // bounce 32 times + mobj->threshold = 24; // bounce 24 times mobj->watertop = mobj->target->floorz + 16*FRACUNIT; P_LinedefExecute(LE_PINCHPHASE, mobj, NULL); } else { @@ -5544,14 +5861,7 @@ static void P_Boss9Thinker(mobj_t *mobj) if (danger) { // An incoming attack is detected! What should we do?! // Go into vector form! - mobj->movedir = ANGLE_11hh - FixedAngle(FixedMul(AngleFixed(ANGLE_11hh), FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS))); - if (P_RandomChance(FRACUNIT/2)) - mobj->movedir = InvAngle(mobj->movedir); - mobj->threshold = 6 + (FixedMul(24<<FRACBITS, FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS))>>FRACBITS); - if (mobj->info->activesound) - S_StartSound(mobj, mobj->info->activesound); - if (mobj->info->painchance) - P_SetMobjState(mobj, mobj->info->painchance); + vectorise; return; } @@ -5566,6 +5876,7 @@ static void P_Boss9Thinker(mobj_t *mobj) } } } +#undef vectorise // // P_GetClosestAxis @@ -5822,8 +6133,8 @@ void P_SetScale(mobj_t *mobj, fixed_t newscale) mobj->scale = newscale; - mobj->radius = FixedMul(mobj->info->radius, newscale); - mobj->height = FixedMul(mobj->info->height, newscale); + mobj->radius = FixedMul(FixedDiv(mobj->radius, oldscale), newscale); + mobj->height = FixedMul(FixedDiv(mobj->height, oldscale), newscale); player = mobj->player; @@ -5831,16 +6142,17 @@ void P_SetScale(mobj_t *mobj, fixed_t newscale) { G_GhostAddScale(newscale); player->viewheight = FixedMul(FixedDiv(player->viewheight, oldscale), newscale); // Nonono don't calculate viewheight elsewhere, this is the best place for it! - player->dashspeed = FixedMul(FixedDiv(player->dashspeed, oldscale), newscale); // Prevents the player from having to re-charge up spindash if the player grew in size } } void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on your target { fixed_t dist, ndist, speedmul; + angle_t vangle; fixed_t tx = dest->x; fixed_t ty = dest->y; fixed_t tz = dest->z + (dest->height/2); // Aim for center + fixed_t xydist = P_AproxDistance(tx - source->x, ty - source->y); if (!dest || dest->health <= 0 || !dest->player || !source->tracer) return; @@ -5849,19 +6161,40 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y source->angle = R_PointToAngle2(source->x, source->y, tx, ty); // change slope - dist = P_AproxDistance(P_AproxDistance(tx - source->x, ty - source->y), tz - source->z); + dist = P_AproxDistance(xydist, tz - source->z); if (dist < 1) dist = 1; - if (nightsgrab) - speedmul = P_AproxDistance(dest->momx, dest->momy) + FixedMul(8*FRACUNIT, source->scale); + if (nightsgrab && source->movefactor) + { + source->movefactor += FRACUNIT/2; + + if (dist < source->movefactor) + { + source->momx = source->momy = source->momz = 0; + P_TeleportMove(source, tx, ty, tz); + } + else + { + vangle = R_PointToAngle2(source->z, 0, tz, xydist); + + source->momx = FixedMul(FINESINE(vangle >> ANGLETOFINESHIFT), FixedMul(FINECOSINE(source->angle >> ANGLETOFINESHIFT), source->movefactor)); + source->momy = FixedMul(FINESINE(vangle >> ANGLETOFINESHIFT), FixedMul(FINESINE(source->angle >> ANGLETOFINESHIFT), source->movefactor)); + source->momz = FixedMul(FINECOSINE(vangle >> ANGLETOFINESHIFT), source->movefactor); + } + } else - speedmul = P_AproxDistance(dest->momx, dest->momy) + FixedMul(source->info->speed, source->scale); + { + if (nightsgrab) + speedmul = P_AproxDistance(dest->momx, dest->momy) + FixedMul(8*FRACUNIT, source->scale); + else + speedmul = P_AproxDistance(dest->momx, dest->momy) + FixedMul(source->info->speed, source->scale); - source->momx = FixedMul(FixedDiv(tx - source->x, dist), speedmul); - source->momy = FixedMul(FixedDiv(ty - source->y, dist), speedmul); - source->momz = FixedMul(FixedDiv(tz - source->z, dist), speedmul); + source->momx = FixedMul(FixedDiv(tx - source->x, dist), speedmul); + source->momy = FixedMul(FixedDiv(ty - source->y, dist), speedmul); + source->momz = FixedMul(FixedDiv(tz - source->z, dist), speedmul); + } // Instead of just unsetting NOCLIP like an idiot, let's check the distance to our target. ndist = P_AproxDistance(P_AproxDistance(tx - (source->x+source->momx), @@ -5886,6 +6219,7 @@ static void P_NightsItemChase(mobj_t *thing) { P_SetTarget(&thing->tracer, NULL); thing->flags2 &= ~MF2_NIGHTSPULL; + thing->movefactor = 0; return; } @@ -5895,6 +6229,222 @@ static void P_NightsItemChase(mobj_t *thing) P_Attract(thing, thing->tracer, true); } +// +// P_MaceRotate +// Spins a hnext-chain of objects around its centerpoint, side to side or periodically. +// +void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) +{ + TVector unit_lengthways, unit_sideways, pos_lengthways, pos_sideways; + TVector *res; + fixed_t radius, dist, zstore; + angle_t fa; + boolean dosound = false; + mobj_t *mobj = center->hnext, *hnext = NULL; + + INT32 lastthreshold = -1; // needs to never be equal at start of loop + fixed_t lastfriction = INT32_MIN; // ditto; almost certainly never, but... + + INT32 rot; + INT32 prevrot; + + dist = pos_sideways[0] = pos_sideways[1] = pos_sideways[2] = pos_sideways[3] = unit_sideways[3] =\ + pos_lengthways[0] = pos_lengthways[1] = pos_lengthways[2] = pos_lengthways[3] = 0; + + while (mobj) + { + if (P_MobjWasRemoved(mobj) || !mobj->health) + { + mobj = mobj->hnext; + continue; + } + + mobj->momx = mobj->momy = mobj->momz = 0; + + if (mobj->threshold != lastthreshold + || mobj->friction != lastfriction) + { + rot = (baserot + mobj->threshold) & FINEMASK; + prevrot = (baseprevrot + mobj->threshold) & FINEMASK; + + pos_lengthways[0] = pos_lengthways[1] = pos_lengthways[2] = pos_lengthways[3] = 0; + + dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); + dist = ((center->scale == FRACUNIT) ? dist : FixedMul(dist, center->scale)); + + fa = (FixedAngle(center->movefactor*FRACUNIT) >> ANGLETOFINESHIFT); + radius = FixedMul(dist, FINECOSINE(fa)); + unit_lengthways[1] = -FixedMul(dist, FINESINE(fa)); + unit_lengthways[3] = FRACUNIT; + + // Swinging Chain. + if (center->flags2 & MF2_STRONGBOX) + { + fixed_t swingmag = FixedMul(FINECOSINE(rot), center->lastlook << FRACBITS); + fixed_t prevswingmag = FINECOSINE(prevrot); + + if ((prevswingmag > 0) != (swingmag > 0)) // just passed its lowest point + dosound = true; + + fa = ((FixedAngle(swingmag) >> ANGLETOFINESHIFT) + mobj->friction) & FINEMASK; + + unit_lengthways[0] = FixedMul(FINESINE(fa), -radius); + unit_lengthways[2] = FixedMul(FINECOSINE(fa), -radius); + } + // Rotating Chain. + else + { + angle_t prevfa = (prevrot + mobj->friction) & FINEMASK; + fa = (rot + mobj->friction) & FINEMASK; + + if (!(prevfa > (FINEMASK/2)) && (fa > (FINEMASK/2))) // completed a full swing + dosound = true; + + unit_lengthways[0] = FixedMul(FINECOSINE(fa), radius); + unit_lengthways[2] = FixedMul(FINESINE(fa), radius); + } + + // Calculate the angle matrixes for the link. + res = VectorMatrixMultiply(unit_lengthways, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT)); + M_Memcpy(&unit_lengthways, res, sizeof(unit_lengthways)); + res = VectorMatrixMultiply(unit_lengthways, *RotateZMatrix(center->angle)); + M_Memcpy(&unit_lengthways, res, sizeof(unit_lengthways)); + + lastthreshold = mobj->threshold; + lastfriction = mobj->friction; + } + + if (dosound && (mobj->flags2 & MF2_BOSSNOTRAP)) + { + S_StartSound(mobj, mobj->info->activesound); + dosound = false; + } + + if (pos_sideways[3] != mobj->movefactor) + { + if (!unit_sideways[3]) + { + unit_sideways[1] = dist; + unit_sideways[0] = unit_sideways[2] = 0; + unit_sideways[3] = FRACUNIT; + + res = VectorMatrixMultiply(unit_sideways, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT)); + M_Memcpy(&unit_sideways, res, sizeof(unit_sideways)); + res = VectorMatrixMultiply(unit_sideways, *RotateZMatrix(center->angle)); + M_Memcpy(&unit_sideways, res, sizeof(unit_sideways)); + } + + if (pos_sideways[3] > mobj->movefactor) + { + do + { + pos_sideways[0] -= unit_sideways[0]; + pos_sideways[1] -= unit_sideways[1]; + pos_sideways[2] -= unit_sideways[2]; + } + while ((--pos_sideways[3]) != mobj->movefactor); + } + else + { + do + { + pos_sideways[0] += unit_sideways[0]; + pos_sideways[1] += unit_sideways[1]; + pos_sideways[2] += unit_sideways[2]; + } + while ((++pos_sideways[3]) != mobj->movefactor); + } + } + + hnext = mobj->hnext; // just in case the mobj is removed + + if (pos_lengthways[3] > mobj->movecount) + { + do + { + pos_lengthways[0] -= unit_lengthways[0]; + pos_lengthways[1] -= unit_lengthways[1]; + pos_lengthways[2] -= unit_lengthways[2]; + } + while ((--pos_lengthways[3]) != mobj->movecount); + } + else if (pos_lengthways[3] < mobj->movecount) + { + do + { + pos_lengthways[0] += unit_lengthways[0]; + pos_lengthways[1] += unit_lengthways[1]; + pos_lengthways[2] += unit_lengthways[2]; + } + while ((++pos_lengthways[3]) != mobj->movecount); + } + + P_UnsetThingPosition(mobj); + + mobj->x = center->x; + mobj->y = center->y; + mobj->z = center->z; + + // Add on the appropriate distances to the center's co-ordinates. + if (pos_lengthways[3]) + { + mobj->x += pos_lengthways[0]; + mobj->y += pos_lengthways[1]; + zstore = pos_lengthways[2] + pos_sideways[2]; + } + else + zstore = pos_sideways[2]; + + mobj->x += pos_sideways[0]; + mobj->y += pos_sideways[1]; + + // Cut the height to align the link with the axis. + if (mobj->type == MT_SMALLMACECHAIN || mobj->type == MT_BIGMACECHAIN || mobj->type == MT_SMALLGRABCHAIN || mobj->type == MT_BIGGRABCHAIN) + zstore -= P_MobjFlip(mobj)*mobj->height/4; + else + zstore -= P_MobjFlip(mobj)*mobj->height/2; + + mobj->z += zstore; + +#if 0 // toaster's testing flashie! + if (!(mobj->movecount & 1) && !(leveltime & TICRATE)) // I had a brainfart and the flashing isn't exactly what I expected it to be, but it's actually much more useful. + mobj->flags2 ^= MF2_DONTDRAW; +#endif + + P_SetThingPosition(mobj); + +#if 0 // toaster's height-clipping dealie! + if (!pos_lengthways[3] || P_MobjWasRemoved(mobj) || (mobj->flags & MF_NOCLIPHEIGHT)) + goto cont; + + if ((fa = ((center->threshold & (FINEMASK/2)) << ANGLETOFINESHIFT)) > ANGLE_45 && fa < ANGLE_135) // only move towards center when the motion is towards/away from the ground, rather than alongside it + goto cont; + + if (mobj->subsector->sector->ffloors) + P_AdjustMobjFloorZ_FFloors(mobj, mobj->subsector->sector, 2); + + if (mobj->floorz > mobj->z) + zstore = (mobj->floorz - zstore); + else if (mobj->ceilingz < mobj->z) + zstore = (mobj->ceilingz - mobj->height - zstore); + else + goto cont; + + zstore = FixedDiv(zstore, dist); // Still needs work... scaling factor is wrong! + + P_UnsetThingPosition(mobj); + + mobj->x -= FixedMul(unit_lengthways[0], zstore); + mobj->y -= FixedMul(unit_lengthways[1], zstore); + + P_SetThingPosition(mobj); + +cont: +#endif + mobj = hnext; + } +} + static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) { if (!thing->target || thing->target->health <= 0 || !thing->target->player @@ -5907,7 +6457,7 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) // TODO: Make an MT_SHIELDORB which changes color/states to always match the appropriate shield, // instead of having completely seperate mobjtypes. - if (shield != SH_FORCE) + if (!(shield & SH_FORCE)) { // Regular shields check for themselves only if ((shieldtype_t)(thing->target->player->powers[pw_shield] & SH_NOSTACK) != shield) { @@ -5921,9 +6471,9 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) return false; } - if (shield == SH_FORCE && thing->movecount != (thing->target->player->powers[pw_shield] & 0xFF)) + if (shield & SH_FORCE && thing->movecount != (thing->target->player->powers[pw_shield] & SH_FORCEHP)) { - thing->movecount = (thing->target->player->powers[pw_shield] & 0xFF); + thing->movecount = (thing->target->player->powers[pw_shield] & SH_FORCEHP); if (thing->movecount < 1) { if (thing->info->painstate) @@ -5943,14 +6493,15 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) thing->flags |= MF_NOCLIPHEIGHT; thing->eflags = (thing->eflags & ~MFE_VERTICALFLIP)|(thing->target->eflags & MFE_VERTICALFLIP); - P_SetScale(thing, thing->target->scale); + P_SetScale(thing, FixedMul(thing->target->scale, thing->target->player->shieldscale)); + thing->destscale = thing->scale; P_UnsetThingPosition(thing); thing->x = thing->target->x; thing->y = thing->target->y; if (thing->eflags & MFE_VERTICALFLIP) - thing->z = thing->target->z + thing->target->height - thing->height + FixedDiv(P_GetPlayerHeight(thing->target->player) - thing->target->height, 3*FRACUNIT) - FixedMul(2*FRACUNIT, thing->target->scale); + thing->z = thing->target->z + (thing->target->height - thing->height + FixedDiv(P_GetPlayerHeight(thing->target->player) - thing->target->height, 3*FRACUNIT)) - FixedMul(2*FRACUNIT, thing->target->scale); else - thing->z = thing->target->z - FixedDiv(P_GetPlayerHeight(thing->target->player) - thing->target->height, 3*FRACUNIT) + FixedMul(2*FRACUNIT, thing->target->scale); + thing->z = thing->target->z - (FixedDiv(P_GetPlayerHeight(thing->target->player) - thing->target->height, 3*FRACUNIT)) + FixedMul(2*FRACUNIT, thing->target->scale); P_SetThingPosition(thing); P_CheckPosition(thing, thing->x, thing->y); @@ -5973,7 +6524,7 @@ void P_RunShields(void) // run shields for (i = 0; i < numshields; i++) { - P_ShieldLook(shields[i], shields[i]->info->speed); + P_ShieldLook(shields[i], shields[i]->threshold); P_SetTarget(&shields[i], NULL); } numshields = 0; @@ -5981,7 +6532,7 @@ void P_RunShields(void) static boolean P_AddShield(mobj_t *thing) { - shieldtype_t shield = thing->info->speed; + shieldtype_t shield = thing->threshold; if (!thing->target || thing->target->health <= 0 || !thing->target->player || (thing->target->player->powers[pw_shield] & SH_NOSTACK) == SH_NONE || thing->target->player->powers[pw_super] @@ -5991,7 +6542,7 @@ static boolean P_AddShield(mobj_t *thing) return false; } - if (shield != SH_FORCE) + if (!(shield & SH_FORCE)) { // Regular shields check for themselves only if ((shieldtype_t)(thing->target->player->powers[pw_shield] & SH_NOSTACK) != shield) { @@ -6029,6 +6580,13 @@ void P_RunOverlays(void) if (!mo->target) continue; + + if (P_MobjWasRemoved(mo->target)) + { + P_RemoveMobj(mo); + continue; + } + if (!splitscreen /*&& rendermode != render_soft*/) { angle_t viewingangle; @@ -6171,6 +6729,67 @@ static void P_KoopaThinker(mobj_t *koopa) } } +// Spawns and chains the minecart sides. +static void P_SpawnMinecartSegments(mobj_t *mobj, boolean mode) +{ + fixed_t x = mobj->x; + fixed_t y = mobj->y; + fixed_t z = mobj->z; + mobj_t *prevseg = mobj; + mobj_t *seg; + UINT8 i; + + for (i = 0; i < 4; i++) + { + seg = P_SpawnMobj(x, y, z, MT_MINECARTSEG); + P_SetMobjState(seg, (statenum_t)(S_MINECARTSEG_FRONT + i)); + if (i >= 2) + seg->extravalue1 = (i == 2) ? -18 : 18; + else + { + seg->extravalue2 = (i == 0) ? 24 : -24; + seg->cusval = -90; + } + if (!mode) + seg->frame &= ~FF_ANIMATE; + P_SetTarget(&prevseg->tracer, seg); + prevseg = seg; + } +} + +// Updates the chained segments. +static void P_UpdateMinecartSegments(mobj_t *mobj) +{ + mobj_t *seg = mobj->tracer; + fixed_t x = mobj->x; + fixed_t y = mobj->y; + fixed_t z = mobj->z; + angle_t ang = mobj->angle; + angle_t fa = (ang >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t c = FINECOSINE(fa); + fixed_t s = FINESINE(fa); + INT32 dx, dy; + INT32 sang; + + while (seg) + { + dx = seg->extravalue1; + dy = seg->extravalue2; + sang = seg->cusval; + P_TeleportMove(seg, x + s*dx + c*dy, y - c*dx + s*dy, z); + seg->angle = ang + FixedAngle(FRACUNIT*sang); + seg->flags2 = (seg->flags2 & ~MF2_DONTDRAW) | (mobj->flags2 & MF2_DONTDRAW); + seg = seg->tracer; + } +} + +void P_HandleMinecartSegments(mobj_t *mobj) +{ + if (!mobj->tracer) + P_SpawnMinecartSegments(mobj, (mobj->type == MT_MINECART)); + P_UpdateMinecartSegments(mobj); +} + // // P_MobjThinker // @@ -6187,9 +6806,12 @@ void P_MobjThinker(mobj_t *mobj) P_SetTarget(&mobj->target, NULL); if (mobj->tracer && P_MobjWasRemoved(mobj->tracer)) P_SetTarget(&mobj->tracer, NULL); + if (mobj->hnext && P_MobjWasRemoved(mobj->hnext)) + P_SetTarget(&mobj->hnext, NULL); + if (mobj->hprev && P_MobjWasRemoved(mobj->hprev)) + P_SetTarget(&mobj->hprev, NULL); - mobj->flags2 &= ~MF2_PUSHED; - mobj->eflags &= ~MFE_SPRUNG; + mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG); tmfloorthing = tmhitthing = NULL; @@ -6209,7 +6831,7 @@ void P_MobjThinker(mobj_t *mobj) fixed_t oldheight = mobj->height; UINT8 correctionType = 0; // Don't correct Z position, just gain height - if (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz + if ((mobj->flags & MF_NOCLIPHEIGHT || (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz)) && mobj->type != MT_EGGMOBILE_FIRE) correctionType = 1; // Correct Z position by centering else if (mobj->eflags & MFE_VERTICALFLIP) @@ -6240,10 +6862,21 @@ void P_MobjThinker(mobj_t *mobj) } } - if (mobj->type == MT_GHOST && mobj->fuse > 0 // Not guaranteed to be MF_SCENERY or not MF_SCENERY! - && (signed)(mobj->frame >> FF_TRANSSHIFT) < (NUMTRANSMAPS-1) - mobj->fuse / 2) - // fade out when nearing the end of fuse... - mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - mobj->fuse / 2) << FF_TRANSSHIFT); + if ((mobj->type == MT_GHOST || mobj->type == MT_THOK) && mobj->fuse > 0) // Not guaranteed to be MF_SCENERY or not MF_SCENERY! + { + if (mobj->flags2 & MF2_BOSSNOTRAP) // "fast" flag + { + if ((signed)((mobj->frame & FF_TRANSMASK) >> FF_TRANSSHIFT) < (NUMTRANSMAPS-1) - (2*mobj->fuse)/3) + // fade out when nearing the end of fuse... + mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - (2*mobj->fuse)/3) << FF_TRANSSHIFT); + } + else + { + if ((signed)((mobj->frame & FF_TRANSMASK) >> FF_TRANSSHIFT) < (NUMTRANSMAPS-1) - mobj->fuse / 2) + // fade out when nearing the end of fuse... + mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - mobj->fuse / 2) << FF_TRANSSHIFT); + } + } // Special thinker for scenery objects if (mobj->flags & MF_SCENERY) @@ -6254,8 +6887,82 @@ void P_MobjThinker(mobj_t *mobj) if (P_MobjWasRemoved(mobj)) return; #endif + + if (mobj->flags2 & MF2_SHIELD) + if (!P_AddShield(mobj)) + return; + switch (mobj->type) { + case MT_MACEPOINT: + case MT_CHAINMACEPOINT: + case MT_SPRINGBALLPOINT: + case MT_CHAINPOINT: + case MT_FIREBARPOINT: + case MT_CUSTOMMACEPOINT: + case MT_HIDDEN_SLING: + { + angle_t oldmovedir = mobj->movedir; + + // Always update movedir to prevent desyncing (in the traditional sense, not the netplay sense). + mobj->movedir = (mobj->movedir + mobj->lastlook) & FINEMASK; + + // If too far away and not deliberately spitting in the face of optimisation, don't think! + if (!(mobj->flags2 & MF2_BOSSNOTRAP)) + { + UINT8 i; + // Quick! Look through players! Don't move unless a player is relatively close by. + // The below is selected based on CEZ2's first room. I promise you it is a coincidence that it looks like the weed number. + for (i = 0; i < MAXPLAYERS; ++i) + if (playeringame[i] && players[i].mo + && P_AproxDistance(P_AproxDistance(mobj->x - players[i].mo->x, mobj->y - players[i].mo->y), mobj->z - players[i].mo->z) < (4200<<FRACBITS)) + break; // Stop looking. + if (i == MAXPLAYERS) + { + if (!(mobj->flags2 & MF2_BEYONDTHEGRAVE)) + { + mobj_t *ref = mobj; + + // stop/hide all your babies + while ((ref = ref->hnext)) + { + ref->eflags = (((ref->flags & MF_NOTHINK) ? 0 : 1) + | ((ref->flags & MF_NOCLIPTHING) ? 0 : 2) + | ((ref->flags2 & MF2_DONTDRAW) ? 0 : 4)); // oh my god this is nasty. + ref->flags |= MF_NOTHINK|MF_NOCLIPTHING; + ref->flags2 |= MF2_DONTDRAW; + ref->momx = ref->momy = ref->momz = 0; + } + + mobj->flags2 |= MF2_BEYONDTHEGRAVE; + } + + break; // don't make bubble! + } + else if (mobj->flags2 & MF2_BEYONDTHEGRAVE) + { + mobj_t *ref = mobj; + + // start/show all your babies + while ((ref = ref->hnext)) + { + if (ref->eflags & 1) + ref->flags &= ~MF_NOTHINK; + if (ref->eflags & 2) + ref->flags &= ~MF_NOCLIPTHING; + if (ref->eflags & 4) + ref->flags2 &= ~MF2_DONTDRAW; + ref->eflags = 0; // le sign + } + + mobj->flags2 &= ~MF2_BEYONDTHEGRAVE; + } + } + + // Okay, time to MOVE + P_MaceRotate(mobj, mobj->movedir, oldmovedir); + } + break; case MT_HOOP: if (mobj->fuse > 1) P_MoveHoop(mobj); @@ -6310,46 +7017,172 @@ void P_MobjThinker(mobj_t *mobj) else P_AddOverlay(mobj); break; - case MT_BLACKORB: - case MT_WHITEORB: - case MT_GREENORB: - case MT_YELLOWORB: - case MT_BLUEORB: - case MT_PITYORB: - if (!P_AddShield(mobj)) + case MT_PITY_ORB: + case MT_WHIRLWIND_ORB: + case MT_ARMAGEDDON_ORB: + if (!(mobj->flags2 & MF2_SHIELD)) return; break; - case MT_WATERDROP: - P_SceneryCheckWater(mobj); - if ((mobj->z <= mobj->floorz || mobj->z <= mobj->watertop) - && mobj->health > 0) - { - mobj->health = 0; - P_SetMobjState(mobj, mobj->info->deathstate); - S_StartSound(mobj, mobj->info->deathsound+P_RandomKey(mobj->info->mass)); + case MT_ATTRACT_ORB: + if (!(mobj->flags2 & MF2_SHIELD)) return; + if (/*(mobj->target) -- the following is implicit by P_AddShield + && (mobj->target->player) + && */ (mobj->target->player->homing) && (mobj->target->player->pflags & PF_SHIELDABILITY)) + { + P_SetMobjState(mobj, mobj->info->painstate); + mobj->tics++; } break; - case MT_BUBBLES: - P_SceneryCheckWater(mobj); + case MT_ELEMENTAL_ORB: + if (!(mobj->flags2 & MF2_SHIELD)) + return; + if (mobj->tracer + /* && mobj->target -- the following is implicit by P_AddShield + && mobj->target->player + && (mobj->target->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL */ + && mobj->target->player->pflags & PF_SHIELDABILITY + && ((statenum_t)(mobj->tracer->state-states) < mobj->info->raisestate + || (mobj->tracer->state->nextstate < mobj->info->raisestate && mobj->tracer->tics == 1))) + { + P_SetMobjState(mobj, mobj->info->painstate); + mobj->tics++; + P_SetMobjState(mobj->tracer, mobj->info->raisestate); + mobj->tracer->tics++; + } break; - case MT_SMALLBUBBLE: - case MT_MEDIUMBUBBLE: - case MT_EXTRALARGEBUBBLE: // start bubble dissipate - P_SceneryCheckWater(mobj); - if (P_MobjWasRemoved(mobj)) // bubble was removed by not being in water + case MT_FORCE_ORB: + if (!(mobj->flags2 & MF2_SHIELD)) return; - if (!(mobj->eflags & MFE_UNDERWATER) - || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + mobj->height >= mobj->ceilingz) - || (mobj->eflags & MFE_VERTICALFLIP && mobj->z <= mobj->floorz) - || (P_CheckDeathPitCollide(mobj)) - || --mobj->fuse <= 0) // Bubbles eventually dissipate if they can't reach the surface. + if (/* + && mobj->target -- the following is implicit by P_AddShield + && mobj->target->player + && (mobj->target->player->powers[pw_shield] & SH_FORCE) + && */ (mobj->target->player->pflags & PF_SHIELDABILITY)) + { + mobj_t *whoosh = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_GHOST); // done here so the offset is correct + P_SetMobjState(whoosh, mobj->info->raisestate); + whoosh->destscale = whoosh->scale<<1; + whoosh->scalespeed = FixedMul(whoosh->scalespeed, whoosh->scale); + whoosh->height = 38*whoosh->scale; + whoosh->fuse = 10; + whoosh->flags |= MF_NOCLIPHEIGHT; + whoosh->momz = mobj->target->momz; // Stay reasonably centered for a few frames + mobj->target->player->pflags &= ~PF_SHIELDABILITY; // prevent eternal whoosh + } + /* FALLTHRU */ + case MT_FLAMEAURA_ORB: + if (!(mobj->flags2 & MF2_SHIELD)) + return; + mobj->angle = mobj->target->angle; // implicitly okay because of P_AddShield + if (mobj->tracer + /* && mobj->target -- the following is implicit by P_AddShield + && mobj->target->player + && (mobj->target->player->powers[pw_shield] & SH_NOSTACK) == SH_FLAMEAURA */ + && mobj->target->player->pflags & PF_SHIELDABILITY + && ((statenum_t)(mobj->tracer->state-states) < mobj->info->raisestate + || (mobj->tracer->state->nextstate < mobj->info->raisestate && mobj->tracer->tics == 1))) + { + P_SetMobjState(mobj, mobj->info->painstate); + mobj->tics++; + P_SetMobjState(mobj->tracer, mobj->info->raisestate); + mobj->tracer->tics++; + } + break; + case MT_BUBBLEWRAP_ORB: + if (!(mobj->flags2 & MF2_SHIELD)) + return; + if (mobj->tracer + /* && mobj->target -- the following is implicit by P_AddShield + && mobj->target->player + && (mobj->target->player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP */ + ) + { + if (mobj->target->player->pflags & PF_SHIELDABILITY + && ((statenum_t)(mobj->state-states) < mobj->info->painstate + || (mobj->state->nextstate < mobj->info->painstate && mobj->tics == 1))) + { + P_SetMobjState(mobj, mobj->info->painstate); + mobj->tics++; + P_SetMobjState(mobj->tracer, mobj->info->raisestate); + mobj->tracer->tics++; + } + else if (mobj->target->eflags & MFE_JUSTHITFLOOR + && (statenum_t)(mobj->state-states) == mobj->info->painstate) + { + P_SetMobjState(mobj, mobj->info->painstate+1); + mobj->tics++; + P_SetMobjState(mobj->tracer, mobj->info->raisestate+1); + mobj->tracer->tics++; + } + } + break; + case MT_THUNDERCOIN_ORB: + if (!(mobj->flags2 & MF2_SHIELD)) + return; + if (mobj->tracer + /* && mobj->target -- the following is implicit by P_AddShield + && mobj->target->player + && (mobj->target->player->powers[pw_shield] & SH_NOSTACK) == SH_THUNDERCOIN */ + && (mobj->target->player->pflags & PF_SHIELDABILITY)) + { + P_SetMobjState(mobj, mobj->info->painstate); + mobj->tics++; + P_SetMobjState(mobj->tracer, mobj->info->raisestate); + mobj->tracer->tics++; + mobj->target->player->pflags &= ~PF_SHIELDABILITY; // prevent eternal spark + } + break; + case MT_WATERDROP: + P_SceneryCheckWater(mobj); + if ((mobj->z <= mobj->floorz || mobj->z <= mobj->watertop) + && mobj->health > 0) + { + mobj->health = 0; + P_SetMobjState(mobj, mobj->info->deathstate); + S_StartSound(mobj, mobj->info->deathsound+P_RandomKey(mobj->info->mass)); + return; + } + break; + case MT_BUBBLES: + P_SceneryCheckWater(mobj); + break; + case MT_SMALLBUBBLE: + case MT_MEDIUMBUBBLE: + case MT_EXTRALARGEBUBBLE: // start bubble dissipate + P_SceneryCheckWater(mobj); + if (P_MobjWasRemoved(mobj)) // bubble was removed by not being in water + return; + if (!(mobj->eflags & MFE_UNDERWATER) + || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + mobj->height >= mobj->ceilingz) + || (mobj->eflags & MFE_VERTICALFLIP && mobj->z <= mobj->floorz) + || (P_CheckDeathPitCollide(mobj)) + || --mobj->fuse <= 0) // Bubbles eventually dissipate if they can't reach the surface. { // no playing sound: no point; the object is being removed P_RemoveMobj(mobj); return; } break; + case MT_LOCKON: + if (!mobj->target) + { + P_RemoveMobj(mobj); + return; + } + mobj->x = mobj->target->x; + mobj->y = mobj->target->y; + + mobj->eflags |= (mobj->target->eflags & MFE_VERTICALFLIP); + + mobj->destscale = mobj->target->destscale; + P_SetScale(mobj, mobj->target->scale); + + if (!(mobj->eflags & MFE_VERTICALFLIP)) + mobj->z = mobj->target->z + mobj->target->height + FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->target->scale); + else + mobj->z = mobj->target->z - FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->target->scale) - mobj->height; + break; case MT_DROWNNUMBERS: if (!mobj->target) { @@ -6405,7 +7238,7 @@ void P_MobjThinker(mobj_t *mobj) flame->angle = mobj->angle; - if (mobj->flags & MF_AMBUSH) // Wave up and down instead of side-to-side + if (mobj->flags2 & MF2_AMBUSH) // Wave up and down instead of side-to-side flame->momz = mobj->fuse << (FRACBITS-2); else flame->angle += FixedAngle(mobj->fuse*FRACUNIT); @@ -6440,7 +7273,7 @@ void P_MobjThinker(mobj_t *mobj) strength -= ((20*FRACUNIT)/16)*mobj->movedir; // If deaf'd, the object spawns on the ceiling. - if (mobj->flags & MF_AMBUSH) + if (mobj->flags2 & MF2_AMBUSH) { mobj->z = mobj->ceilingz-mobj->height; flame->momz = -strength; @@ -6451,8 +7284,37 @@ void P_MobjThinker(mobj_t *mobj) S_StartSound(flame, sfx_fire); } break; + case MT_FLICKY_01_CENTER: + case MT_FLICKY_02_CENTER: + case MT_FLICKY_03_CENTER: + case MT_FLICKY_04_CENTER: + case MT_FLICKY_05_CENTER: + case MT_FLICKY_06_CENTER: + case MT_FLICKY_07_CENTER: + case MT_FLICKY_08_CENTER: + case MT_FLICKY_09_CENTER: + case MT_FLICKY_10_CENTER: + case MT_FLICKY_11_CENTER: + case MT_FLICKY_12_CENTER: + case MT_FLICKY_13_CENTER: + case MT_FLICKY_14_CENTER: + case MT_FLICKY_15_CENTER: + case MT_FLICKY_16_CENTER: + case MT_SECRETFLICKY_01_CENTER: + case MT_SECRETFLICKY_02_CENTER: + if (mobj->tracer && (mobj->flags & MF_NOCLIPTHING) + && (mobj->flags & MF_GRENADEBOUNCE)) + // for now: only do this bounce routine if flicky is in-place. \todo allow in all movements + { + if (!(mobj->tracer->flags2 & MF2_OBJECTFLIP) && mobj->tracer->z <= mobj->tracer->floorz) + mobj->tracer->momz = 7*FRACUNIT; + else if ((mobj->tracer->flags2 & MF2_OBJECTFLIP) && mobj->tracer->z >= mobj->tracer->ceilingz - mobj->tracer->height) + mobj->tracer->momz = -7*FRACUNIT; + } + break; case MT_SEED: - mobj->momz = mobj->info->speed; + if (P_MobjFlip(mobj)*mobj->momz < mobj->info->speed) + mobj->momz = P_MobjFlip(mobj)*mobj->info->speed; break; case MT_ROCKCRUMBLE1: case MT_ROCKCRUMBLE2: @@ -6470,6 +7332,7 @@ void P_MobjThinker(mobj_t *mobj) case MT_ROCKCRUMBLE14: case MT_ROCKCRUMBLE15: case MT_ROCKCRUMBLE16: + case MT_WOODDEBRIS: if (mobj->z <= P_FloorzAtPos(mobj->x, mobj->y, mobj->z, mobj->height) && mobj->state != &states[mobj->info->deathstate]) { @@ -6477,6 +7340,63 @@ void P_MobjThinker(mobj_t *mobj) return; } break; + case MT_PARTICLEGEN: + if (!mobj->lastlook) + return; + + if (!mobj->threshold) + return; + + if (--mobj->fuse <= 0) + { + INT32 i = 0; + mobj_t *spawn; + fixed_t bottomheight, topheight; + INT32 type = mobj->threshold, line = mobj->cvmem; + + mobj->fuse = (tic_t)mobj->reactiontime; + + bottomheight = lines[line].frontsector->floorheight; + topheight = lines[line].frontsector->ceilingheight - mobjinfo[(mobjtype_t)type].height; + + if (mobj->waterbottom != bottomheight || mobj->watertop != topheight) + { + if (mobj->movefactor && (topheight > bottomheight)) + mobj->health = (tic_t)(FixedDiv((topheight - bottomheight), abs(mobj->movefactor)) >> FRACBITS); + else + mobj->health = 0; + + mobj->z = ((mobj->flags2 & MF2_OBJECTFLIP) ? topheight : bottomheight); + } + + if (!mobj->health) + return; + + for (i = 0; i < mobj->lastlook; i++) + { + spawn = P_SpawnMobj( + mobj->x + FixedMul(FixedMul(mobj->friction, mobj->scale), FINECOSINE(mobj->angle>>ANGLETOFINESHIFT)), + mobj->y + FixedMul(FixedMul(mobj->friction, mobj->scale), FINESINE(mobj->angle>>ANGLETOFINESHIFT)), + mobj->z, + (mobjtype_t)mobj->threshold); + P_SetScale(spawn, mobj->scale); + spawn->momz = FixedMul(mobj->movefactor, spawn->scale); + spawn->destscale = spawn->scale/100; + spawn->scalespeed = spawn->scale/mobj->health; + spawn->tics = (tic_t)mobj->health; + spawn->flags2 |= (mobj->flags2 & MF2_OBJECTFLIP); + spawn->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones + + mobj->angle += mobj->movedir; + } + + mobj->angle += (angle_t)mobj->movecount; + } + break; + case MT_FSGNA: + if (mobj->movedir) + mobj->angle += mobj->movedir; + break; default: if (mobj->fuse) { // Scenery object fuse! Very basic! @@ -6523,7 +7443,7 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL && (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) { - P_KillMobj(mobj, NULL, NULL); + P_KillMobj(mobj, NULL, NULL, 0); return; } } @@ -6566,6 +7486,9 @@ void P_MobjThinker(mobj_t *mobj) case MT_EGGMOBILE4: P_Boss4Thinker(mobj); break; + case MT_FANG: + P_Boss5Thinker(mobj); + break; case MT_BLACKEGGMAN: P_Boss7Thinker(mobj); break; @@ -6584,7 +7507,7 @@ void P_MobjThinker(mobj_t *mobj) else if (mobj->health <= 0) // Dead things think differently than the living. switch (mobj->type) { - case MT_BLUEBALL: + case MT_BLUESPHERE: if ((mobj->tics>>2)+1 > 0 && (mobj->tics>>2)+1 <= tr_trans60) // tr_trans50 through tr_trans90, shifting once every second frame mobj->frame = (NUMTRANSMAPS-((mobj->tics>>2)+1))<<FF_TRANSSHIFT; else // tr_trans60 otherwise @@ -6597,18 +7520,21 @@ void P_MobjThinker(mobj_t *mobj) return; } break; + case MT_EGGSHIELD: + mobj->flags2 ^= MF2_DONTDRAW; + break; case MT_EGGTRAP: // Egg Capsule animal release if (mobj->fuse > 0 && mobj->fuse < 2*TICRATE-(TICRATE/7) && (mobj->fuse & 3)) { - INT32 i,j; + INT32 i; fixed_t x,y,z; fixed_t ns; mobj_t *mo2; + mobj_t *flicky; - i = P_RandomByte(); z = mobj->subsector->sector->floorheight + ((P_RandomByte()&63)*FRACUNIT); - for (j = 0; j < 2; j++) + for (i = 0; i < 2; i++) { const angle_t fa = (P_RandomByte()*FINEANGLES/16) & FINEMASK; ns = 64 * FRACUNIT; @@ -6616,25 +7542,22 @@ void P_MobjThinker(mobj_t *mobj) y = mobj->y + FixedMul(FINECOSINE(fa),ns); mo2 = P_SpawnMobj(x, y, z, MT_EXPLODE); + P_SetMobjStateNF(mo2, S_XPLD_EGGTRAP); // so the flickies don't lose their target if they spawn ns = 4 * FRACUNIT; mo2->momx = FixedMul(FINESINE(fa),ns); mo2->momy = FixedMul(FINECOSINE(fa),ns); - i = P_RandomByte(); - - if (i % 5 == 0) - P_SpawnMobj(x, y, z, MT_CHICKEN); - else if (i % 4 == 0) - P_SpawnMobj(x, y, z, MT_COW); - else if (i % 3 == 0) - { - P_SpawnMobj(x, y, z, MT_BIRD); + if (P_RandomChance(FRACUNIT/4)) // I filled a spreadsheet trying to get the equivalent chance to the original P_RandomByte hack! S_StartSound(mo2, mobj->info->deathsound); - } - else if ((i & 1) == 0) - P_SpawnMobj(x, y, z, MT_BUNNY); - else - P_SpawnMobj(x, y, z, MT_MOUSE); + + flicky = P_InternalFlickySpawn(mo2, 0, 8*FRACUNIT, false); + if (!flicky) + break; + + P_SetTarget(&flicky->target, mo2); + flicky->momx = mo2->momx; + flicky->momy = mo2->momy; + flicky->angle = fa << ANGLETOFINESHIFT; } mobj->fuse--; @@ -6642,532 +7565,1042 @@ void P_MobjThinker(mobj_t *mobj) break; case MT_PLAYER: /// \todo Have the player's dead body completely finish its animation even if they've already respawned. - if (!(mobj->flags2 & MF2_DONTDRAW)) + if (!mobj->fuse) + { // Go away. + /// \todo Actually go ahead and remove mobj completely, and fix any bugs and crashes doing this creates. Chasecam should stop moving, and F12 should never return to it. + mobj->momz = 0; + if (mobj->player) + mobj->flags2 |= MF2_DONTDRAW; + else // safe to remove, nobody's going to complain! + { + P_RemoveMobj(mobj); + return; + } + } + else // Apply gravity to fall downwards. { - if (!mobj->fuse) - { // Go away. - /// \todo Actually go ahead and remove mobj completely, and fix any bugs and crashes doing this creates. Chasecam should stop moving, and F12 should never return to it. - mobj->momz = 0; - if (mobj->player) - mobj->flags2 |= MF2_DONTDRAW; - else // safe to remove, nobody's going to complain! - { - P_RemoveMobj(mobj); - return; - } + if (mobj->player && !(mobj->fuse % 8) && (mobj->player->charflags & SF_MACHINE)) + { + fixed_t r = mobj->radius >> FRACBITS; + mobj_t *explosion = P_SpawnMobj( + mobj->x + (P_RandomRange(r, -r) << FRACBITS), + mobj->y + (P_RandomRange(r, -r) << FRACBITS), + mobj->z + (P_RandomKey(mobj->height >> FRACBITS) << FRACBITS), + MT_BOSSEXPLODE); + S_StartSound(explosion, sfx_cybdth); } - else // Apply gravity to fall downwards. - P_SetObjectMomZ(mobj, -2*FRACUNIT/3, true); + if (mobj->movedir == DMG_DROWNED) + P_SetObjectMomZ(mobj, -FRACUNIT / 2, true); // slower fall from drowning + else + P_SetObjectMomZ(mobj, -2 * FRACUNIT / 3, true); } break; default: break; } - else switch (mobj->type) + else { - case MT_FALLINGROCK: - // Despawn rocks here in case zmovement code can't do so (blame slopes) - if (!mobj->momx && !mobj->momy && !mobj->momz - && ((mobj->eflags & MFE_VERTICALFLIP) ? - mobj->z + mobj->height >= mobj->ceilingz - : mobj->z <= mobj->floorz)) + if ((mobj->flags & MF_ENEMY) && (mobj->state->nextstate == mobj->info->spawnstate && mobj->tics == 1)) + mobj->flags2 &= ~MF2_FRET; + + // Angle-to-tracer to trigger a linedef exec + // See Linedef Exec 457 (Track mobj angle to point) + if ((mobj->eflags & MFE_TRACERANGLE) && mobj->tracer && mobj->extravalue2) + { + // mobj->lastlook - Don't disable behavior after first failure + // mobj->extravalue1 - Angle tolerance + // mobj->extravalue2 - Exec tag upon failure + // mobj->cvval - Allowable failure delay + // mobj->cvmem - Failure timer + + angle_t ang = mobj->angle - R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y); + + // \todo account for distance between mobj and tracer + // Because closer mobjs can be facing beyond the angle tolerance + // yet tracer is still in the camera view + + // failure state: mobj is not facing tracer + // Reasaonable defaults: ANGLE_67h, ANGLE_292h + if (ang >= (angle_t)mobj->extravalue1 && ang <= ANGLE_MAX - (angle_t)mobj->extravalue1) { - P_RemoveMobj(mobj); - return; + if (mobj->cvmem) + mobj->cvmem--; + else + { + INT32 exectag = mobj->extravalue2; // remember this before we erase the values + + if (mobj->lastlook) + mobj->cvmem = mobj->cusval; // reset timer for next failure + else + { + // disable after first failure + mobj->eflags &= ~MFE_TRACERANGLE; + mobj->lastlook = mobj->extravalue1 = mobj->extravalue2 = mobj->cvmem = mobj->cusval = 0; + } + + P_LinedefExecute(exectag, mobj, NULL); + } } - P_MobjCheckWater(mobj); - break; - case MT_EMERALDSPAWN: - if (mobj->threshold) - { - mobj->threshold--; + else + mobj->cvmem = mobj->cusval; // reset failure timer + } - if (!mobj->threshold && !mobj->target && mobj->reactiontime) + switch (mobj->type) + { + case MT_WALLSPIKEBASE: + if (!mobj->target) { + P_RemoveMobj(mobj); + return; + } + mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|(mobj->target->frame & FF_FRAMEMASK); +#if 0 + if (mobj->angle != mobj->target->angle + ANGLE_90) // reposition if not the correct angle { - mobj_t *emerald = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->reactiontime); - emerald->threshold = 42; - P_SetTarget(&mobj->target, emerald); - P_SetTarget(&emerald->target, mobj); + mobj_t *target = mobj->target; // shortcut + const fixed_t baseradius = target->radius - (target->scale/2); //FixedMul(FRACUNIT/2, target->scale); + P_UnsetThingPosition(mobj); + mobj->x = target->x - P_ReturnThrustX(target, target->angle, baseradius); + mobj->y = target->y - P_ReturnThrustY(target, target->angle, baseradius); + P_SetThingPosition(mobj); + mobj->angle = target->angle + ANGLE_90; } - } - break; - case MT_AQUABUZZ: - case MT_BIGAIRMINE: - { - if (mobj->tracer && mobj->tracer->player && mobj->tracer->health > 0 - && P_AproxDistance(P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z - mobj->z) <= mobj->radius * 16) +#endif + break; + case MT_FALLINGROCK: + // Despawn rocks here in case zmovement code can't do so (blame slopes) + if (!mobj->momx && !mobj->momy && !mobj->momz + && ((mobj->eflags & MFE_VERTICALFLIP) ? + mobj->z + mobj->height >= mobj->ceilingz + : mobj->z <= mobj->floorz)) { - // Home in on the target. - P_HomingAttack(mobj, mobj->tracer); - - if (mobj->z < mobj->floorz) - mobj->z = mobj->floorz; + P_RemoveMobj(mobj); + return; + } + P_MobjCheckWater(mobj); + break; + case MT_ARROW: + if (mobj->flags & MF_MISSILE) + { + // Calculate the angle of movement. + /* + momz + / | + / | + / | + 0------dist(momx,momy) + */ + + fixed_t dist = P_AproxDistance(mobj->momx, mobj->momy); + angle_t angle = R_PointToAngle2(0, 0, dist, mobj->momz); + + if (angle > ANG20 && angle <= ANGLE_180) + mobj->frame = 2; + else if (angle < ANG340 && angle > ANGLE_180) + mobj->frame = 0; + else + mobj->frame = 1; - if (leveltime % mobj->info->painchance == 0) + if (!(mobj->extravalue1) && (mobj->momz < 0)) + { + mobj->extravalue1 = 1; S_StartSound(mobj, mobj->info->activesound); + } + if (leveltime & 1) + { + mobj_t *dust = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_PARTICLE); + dust->tics = 18; + dust->scalespeed = 4096; + dust->destscale = FRACUNIT/32; + } } else + mobj->flags2 ^= MF2_DONTDRAW; + break; + case MT_EMERALDSPAWN: + if (mobj->threshold) { - // Try to find a player - P_LookForPlayers(mobj, true, true, mobj->radius * 16); - mobj->momx >>= 1; - mobj->momy >>= 1; - mobj->momz >>= 1; + mobj->threshold--; + + if (!mobj->threshold && !mobj->target && mobj->reactiontime) + { + mobj_t *emerald = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->reactiontime); + emerald->threshold = 42; + P_SetTarget(&mobj->target, emerald); + P_SetTarget(&emerald->target, mobj); + } } - } - break; - case MT_BIGMINE: - { - if (mobj->tracer && mobj->tracer->player && mobj->tracer->health > 0 - && P_AproxDistance(P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z - mobj->z) <= mobj->radius * 16) + break; + case MT_BUBBLEBUZZ: + mobj->eflags |= MFE_UNDERWATER; //P_MobjCheckWater(mobj); // solely for MFE_UNDERWATER for A_FlickySpawn { - P_MobjCheckWater(mobj); - - // Home in on the target. - P_HomingAttack(mobj, mobj->tracer); - - // Don't let it go out of water - if (mobj->z + mobj->height > mobj->watertop) - mobj->z = mobj->watertop - mobj->height; + if (mobj->tracer && mobj->tracer->player && mobj->tracer->health > 0 + && P_AproxDistance(P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z - mobj->z) <= mobj->radius * 16) + { + // Home in on the target. + P_HomingAttack(mobj, mobj->tracer); - if (mobj->z < mobj->floorz) - mobj->z = mobj->floorz; + if (mobj->z < mobj->floorz) + mobj->z = mobj->floorz; - if (leveltime % mobj->info->painchance == 0) - S_StartSound(mobj, mobj->info->activesound); + if (leveltime % mobj->info->painchance == 0) + S_StartSound(mobj, mobj->info->activesound); + } + else + { + // Try to find a player + P_LookForPlayers(mobj, true, true, mobj->radius * 16); + mobj->momx >>= 1; + mobj->momy >>= 1; + mobj->momz >>= 1; + } } - else + break; + case MT_BUMBLEBORE: { - // Try to find a player - P_LookForPlayers(mobj, true, true, mobj->radius * 16); - mobj->momx >>= 1; - mobj->momy >>= 1; - mobj->momz >>= 1; - } - } - break; - case MT_SPINMACEPOINT: - if (leveltime & 1) - { - if (mobj->lastlook > mobj->movecount) - mobj->lastlook--; -/* - if (mobj->threshold > mobj->movefactor) - mobj->threshold -= FRACUNIT; - else if (mobj->threshold < mobj->movefactor) - mobj->threshold += FRACUNIT;*/ - } - break; - case MT_EGGCAPSULE: - if (!mobj->reactiontime) - { - // Target nearest player on your mare. - // (You can make it float up/down by adding MF_FLOAT, - // but beware level design pitfalls.) - fixed_t shortest = 1024*FRACUNIT; - INT32 i; - P_SetTarget(&mobj->target, NULL); - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].mo - && players[i].mare == mobj->threshold && players[i].health > 1) + statenum_t st = mobj->state-states; + if (st == S_BUMBLEBORE_FLY1 || st == S_BUMBLEBORE_FLY2) { - fixed_t dist = P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y); - if (dist < shortest) + if (!mobj->target) + P_SetMobjState(mobj, mobj->info->spawnstate); + else if (P_MobjFlip(mobj)*((mobj->z + (mobj->height>>1)) - (mobj->target->z + (mobj->target->height>>1))) > 0 + && R_PointToDist2(mobj->x, mobj->y, mobj->target->x, mobj->target->y) <= 32*FRACUNIT) { - P_SetTarget(&mobj->target, players[i].mo); - shortest = dist; + mobj->momx >>= 1; + mobj->momy >>= 1; + if (++mobj->movefactor == 4) + { + S_StartSound(mobj, mobj->info->seesound); + mobj->momx = mobj->momy = mobj->momz = 0; + mobj->flags = (mobj->flags|MF_PAIN) & ~MF_NOGRAVITY; + P_SetMobjState(mobj, mobj->info->meleestate); + } } + else + mobj->movefactor = 0; + } + else if (st == S_BUMBLEBORE_RAISE || st == S_BUMBLEBORE_FALL2) // no _FALL1 because it's an 0-tic + { + if (P_IsObjectOnGround(mobj)) + { + S_StopSound(mobj); + S_StartSound(mobj, mobj->info->attacksound); + mobj->flags = (mobj->flags|MF_NOGRAVITY) & ~MF_PAIN; + mobj->momx = mobj->momy = mobj->momz = 0; + P_SetMobjState(mobj, mobj->info->painstate); + } + else + { + mobj->angle += ANGLE_22h; + mobj->frame = mobj->state->frame + ((mobj->tics & 2)>>1); + } + } + else if (st == S_BUMBLEBORE_STUCK2 && mobj->tics < TICRATE) + mobj->frame = mobj->state->frame + ((mobj->tics & 2)>>1); + } + break; + case MT_BIGMINE: + mobj->extravalue1 += 3; + mobj->extravalue1 %= 360; + P_UnsetThingPosition(mobj); + mobj->z += FINESINE(mobj->extravalue1*(FINEMASK+1)/360); + P_SetThingPosition(mobj); + break; + case MT_FLAME: + if (mobj->flags2 & MF2_BOSSNOTRAP) + { + if (!mobj->target || P_MobjWasRemoved(mobj->target)) + { + if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) + P_RemoveMobj(mobj->tracer); + P_RemoveMobj(mobj); + return; + } + mobj->z = mobj->target->z + mobj->target->momz; + if (!(mobj->eflags & MFE_VERTICALFLIP)) + mobj->z += mobj->target->height; + } + if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) + { + mobj->tracer->z = mobj->z + P_MobjFlip(mobj)*20*mobj->scale; + if (mobj->eflags & MFE_VERTICALFLIP) + mobj->tracer->z += mobj->height; + } + break; + case MT_WAVINGFLAG: + { + fixed_t base = (leveltime<<(FRACBITS+1)); + mobj_t *seg = mobj->tracer, *prev = mobj; + mobj->movedir = mobj->angle + + ((((FINESINE((FixedAngle(base<<1)>>ANGLETOFINESHIFT) & FINEMASK) + + FINESINE((FixedAngle(base<<4)>>ANGLETOFINESHIFT) & FINEMASK))>>1) + + FINESINE((FixedAngle(base*9)>>ANGLETOFINESHIFT) & FINEMASK) + + FINECOSINE(((FixedAngle(base*9))>>ANGLETOFINESHIFT) & FINEMASK))<<12); //*2^12 + while (seg) + { + seg->movedir = seg->angle; + seg->angle = prev->movedir; + P_UnsetThingPosition(seg); + seg->x = prev->x + P_ReturnThrustX(prev, prev->angle, prev->radius); + seg->y = prev->y + P_ReturnThrustY(prev, prev->angle, prev->radius); + seg->z = prev->z + prev->height - (seg->scale>>1); + P_SetThingPosition(seg); + prev = seg; + seg = seg->tracer; + } + } + break; + case MT_SPINCUSHION: + if (mobj->target && mobj->state-states >= S_SPINCUSHION_AIM1 && mobj->state-states <= S_SPINCUSHION_AIM5) + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); + break; + case MT_CRUSHCLAW: + if (mobj->state-states == S_CRUSHCLAW_STAY && mobj->target) + { + mobj_t *chain = mobj->target->target; + SINT8 sign = ((mobj->tics & 1) ? mobj->tics : -(SINT8)(mobj->tics)); + while (chain) + { + chain->z = chain->watertop + sign*mobj->scale; + sign = -sign; + chain = chain->target; + } + } + break; + case MT_SMASHINGSPIKEBALL: + mobj->momx = mobj->momy = 0; + if (mobj->state-states == S_SMASHSPIKE_FALL && P_IsObjectOnGround(mobj)) + { + P_SetMobjState(mobj, S_SMASHSPIKE_STOMP1); + S_StartSound(mobj, sfx_spsmsh); + } + else if (mobj->state-states == S_SMASHSPIKE_RISE2 && P_MobjFlip(mobj)*(mobj->z - mobj->movecount) >= 0) + { + mobj->momz = 0; + P_SetMobjState(mobj, S_SMASHSPIKE_FLOAT); + } + break; + case MT_HANGSTER: + { + statenum_t st = mobj->state-states; + //ghost image trail when flying down + if (st == S_HANGSTER_SWOOP1 || st == S_HANGSTER_SWOOP2) + { + P_SpawnGhostMobj(mobj); + //curve when in line with target, otherwise curve to avoid crashing into floor + if ((mobj->z - mobj->floorz <= 80*FRACUNIT) || (mobj->target && (mobj->z - mobj->target->z <= 80*FRACUNIT))) + P_SetMobjState(mobj, (st = S_HANGSTER_ARC1)); } - } - break; - case MT_EGGMOBILE2_POGO: - if (!mobj->target - || !mobj->target->health - || mobj->target->state == &states[mobj->target->info->spawnstate] - || mobj->target->state == &states[mobj->target->info->raisestate]) - { - P_RemoveMobj(mobj); - return; - } - P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z - mobj->height); - break; - case MT_HAMMER: - if (mobj->z <= mobj->floorz) - { - P_RemoveMobj(mobj); - return; - } - break; - case MT_KOOPA: - P_KoopaThinker(mobj); - break; - case MT_REDRING: - if (((mobj->z < mobj->floorz) || (mobj->z + mobj->height > mobj->ceilingz)) - && mobj->flags & MF_MISSILE) - { - P_ExplodeMissile(mobj); - return; - } - break; - case MT_BOSSFLYPOINT: - return; - case MT_NIGHTSCORE: - mobj->color = (UINT8)(leveltime % SKINCOLOR_WHITE); - break; - case MT_JETFUME1: - { - fixed_t jetx, jety; - if (!mobj->target // if you have no target - || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now - { // then remove yourself as well! + //swoop arc movement stuff + if (st == S_HANGSTER_ARC1) + { + A_FaceTarget(mobj); + P_Thrust(mobj, mobj->angle, 1*FRACUNIT); + } + else if (st == S_HANGSTER_ARC2) + P_Thrust(mobj, mobj->angle, 2*FRACUNIT); + else if (st == S_HANGSTER_ARC3) + P_Thrust(mobj, mobj->angle, 4*FRACUNIT); + //if movement has stopped while flying (like hitting a wall), fly up immediately + else if (st == S_HANGSTER_FLY1 && !mobj->momx && !mobj->momy) + { + mobj->extravalue1 = 0; + P_SetMobjState(mobj, S_HANGSTER_ARCUP1); + } + //after swooping back up, check for ceiling + else if ((st == S_HANGSTER_RETURN1 || st == S_HANGSTER_RETURN2) && mobj->momz == 0 && mobj->ceilingz == (mobj->z + mobj->height)) + P_SetMobjState(mobj, (st = S_HANGSTER_RETURN3)); + + //should you roost on a ceiling with F_SKY1 as its flat, disappear forever + if (st == S_HANGSTER_RETURN3 && mobj->momz == 0 && mobj->ceilingz == (mobj->z + mobj->height) + && mobj->subsector->sector->ceilingpic == skyflatnum + && mobj->subsector->sector->ceilingheight == mobj->ceilingz) + { + P_RemoveMobj(mobj); + return; + } + } + break; + case MT_EGGCAPSULE: + if (!mobj->reactiontime) + { + // Target nearest player on your mare. + // (You can make it float up/down by adding MF_FLOAT, + // but beware level design pitfalls.) + fixed_t shortest = 1024*FRACUNIT; + INT32 i; + P_SetTarget(&mobj->target, NULL); + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].mo + && players[i].mare == mobj->threshold && players[i].spheres > 0) + { + fixed_t dist = P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y); + if (dist < shortest) + { + P_SetTarget(&mobj->target, players[i].mo); + shortest = dist; + } + } + } + break; + case MT_EGGMOBILE2_POGO: + if (!mobj->target + || !mobj->target->health + || mobj->target->state == &states[mobj->target->info->spawnstate] + || mobj->target->state == &states[mobj->target->info->raisestate]) + { + P_RemoveMobj(mobj); + return; + } + P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z - mobj->height); + break; + case MT_HAMMER: + if (mobj->z <= mobj->floorz) + { P_RemoveMobj(mobj); return; } + break; + case MT_KOOPA: + P_KoopaThinker(mobj); + break; + case MT_REDRING: + if (((mobj->z < mobj->floorz) || (mobj->z + mobj->height > mobj->ceilingz)) + && mobj->flags & MF_MISSILE) + { + P_ExplodeMissile(mobj); + return; + } + break; + case MT_BOSSFLYPOINT: + return; + case MT_NIGHTSCORE: + mobj->color = (UINT8)(leveltime % SKINCOLOR_WHITE); + break; + case MT_JETFUME1: + { + fixed_t jetx, jety; - jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, FixedMul(-64*FRACUNIT, mobj->target->scale)); - jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, FixedMul(-64*FRACUNIT, mobj->target->scale)); + if (!mobj->target // if you have no target + || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now + { // then remove yourself as well! + P_RemoveMobj(mobj); + return; + } - if (mobj->fuse == 56) // First one + jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, FixedMul(-64*FRACUNIT, mobj->target->scale)); + jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, FixedMul(-64*FRACUNIT, mobj->target->scale)); + + if (mobj->fuse == 56) // First one + { + P_UnsetThingPosition(mobj); + mobj->x = jetx; + mobj->y = jety; + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(38*FRACUNIT, mobj->target->scale); + else + mobj->z = mobj->target->z + FixedMul(38*FRACUNIT, mobj->target->scale); + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_SetThingPosition(mobj); + } + else if (mobj->fuse == 57) + { + P_UnsetThingPosition(mobj); + mobj->x = jetx + P_ReturnThrustX(mobj->target, mobj->target->angle-ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); + mobj->y = jety + P_ReturnThrustY(mobj->target, mobj->target->angle-ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(12*FRACUNIT, mobj->target->scale); + else + mobj->z = mobj->target->z + FixedMul(12*FRACUNIT, mobj->target->scale); + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_SetThingPosition(mobj); + } + else if (mobj->fuse == 58) + { + P_UnsetThingPosition(mobj); + mobj->x = jetx + P_ReturnThrustX(mobj->target, mobj->target->angle+ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); + mobj->y = jety + P_ReturnThrustY(mobj->target, mobj->target->angle+ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(12*FRACUNIT, mobj->target->scale); + else + mobj->z = mobj->target->z + FixedMul(12*FRACUNIT, mobj->target->scale); + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_SetThingPosition(mobj); + } + else if (mobj->fuse == 59) + { + jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, -mobj->target->radius); + jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, -mobj->target->radius); + P_UnsetThingPosition(mobj); + mobj->x = jetx; + mobj->y = jety; + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->target->z + mobj->target->height/2 + mobj->height/2; + else + mobj->z = mobj->target->z + mobj->target->height/2 - mobj->height/2; + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_SetThingPosition(mobj); + } + mobj->fuse++; + } + break; + case MT_PROPELLER: { + fixed_t jetx, jety; + + if (!mobj->target // if you have no target + || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now + { // then remove yourself as well! + P_RemoveMobj(mobj); + return; + } + + jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, FixedMul(-60*FRACUNIT, mobj->target->scale)); + jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, FixedMul(-60*FRACUNIT, mobj->target->scale)); + P_UnsetThingPosition(mobj); mobj->x = jetx; mobj->y = jety; - if (mobj->target->eflags & MFE_VERTICALFLIP) - mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(38*FRACUNIT, mobj->target->scale); - else - mobj->z = mobj->target->z + FixedMul(38*FRACUNIT, mobj->target->scale); + mobj->z = mobj->target->z + FixedMul(17*FRACUNIT, mobj->target->scale); + mobj->angle = mobj->target->angle - ANGLE_180; mobj->floorz = mobj->z; mobj->ceilingz = mobj->z+mobj->height; P_SetThingPosition(mobj); } - else if (mobj->fuse == 57) + break; + case MT_JETFLAME: { + if (!mobj->target // if you have no target + || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now + { // then remove yourself as well! + P_RemoveMobj(mobj); + return; + } + P_UnsetThingPosition(mobj); - mobj->x = jetx + P_ReturnThrustX(mobj->target, mobj->target->angle-ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); - mobj->y = jety + P_ReturnThrustY(mobj->target, mobj->target->angle-ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); - if (mobj->target->eflags & MFE_VERTICALFLIP) - mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(12*FRACUNIT, mobj->target->scale); - else - mobj->z = mobj->target->z + FixedMul(12*FRACUNIT, mobj->target->scale); + mobj->x = mobj->target->x; + mobj->y = mobj->target->y; + mobj->z = mobj->target->z - FixedMul(50*FRACUNIT, mobj->target->scale); mobj->floorz = mobj->z; mobj->ceilingz = mobj->z+mobj->height; P_SetThingPosition(mobj); } - else if (mobj->fuse == 58) + break; + case MT_NIGHTSDRONE: + { + // variable setup + mobj_t *goalpost = NULL; + mobj_t *sparkle = NULL; + mobj_t *droneman = NULL; + + boolean flip = mobj->flags2 & MF2_OBJECTFLIP; + boolean topaligned = (mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); + boolean middlealigned = (mobj->flags & MF_GRENADEBOUNCE) && !(mobj->flags & MF_SLIDEME); + boolean bottomoffsetted = !(mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); + boolean flipchanged = false; + + fixed_t dronemanoffset, goaloffset, sparkleoffset, droneboxmandiff, dronemangoaldiff; + + if (mobj->target && mobj->target->type == MT_NIGHTSDRONE_GOAL) + { + goalpost = mobj->target; + if (goalpost->target && goalpost->target->type == MT_NIGHTSDRONE_SPARKLING) + sparkle = goalpost->target; + if (goalpost->tracer && goalpost->tracer->type == MT_NIGHTSDRONE_MAN) + droneman = goalpost->tracer; + } + + if (!goalpost || !sparkle || !droneman) + break; + + // did NIGHTSDRONE position, scale, flip, or flags change? all elements need to be synced + droneboxmandiff = max(mobj->height - droneman->height, 0); + dronemangoaldiff = max(droneman->height - goalpost->height, 0); + + if (!(goalpost->flags2 & MF2_OBJECTFLIP) && (mobj->flags2 & MF2_OBJECTFLIP)) + { + goalpost->eflags |= MFE_VERTICALFLIP; + goalpost->flags2 |= MF2_OBJECTFLIP; + sparkle->eflags |= MFE_VERTICALFLIP; + sparkle->flags2 |= MF2_OBJECTFLIP; + droneman->eflags |= MFE_VERTICALFLIP; + droneman->flags2 |= MF2_OBJECTFLIP; + flipchanged = true; + } + else if ((goalpost->flags2 & MF2_OBJECTFLIP) && !(mobj->flags2 & MF2_OBJECTFLIP)) + { + goalpost->eflags &= ~MFE_VERTICALFLIP; + goalpost->flags2 &= ~MF2_OBJECTFLIP; + sparkle->eflags &= ~MFE_VERTICALFLIP; + sparkle->flags2 &= ~MF2_OBJECTFLIP; + droneman->eflags &= ~MFE_VERTICALFLIP; + droneman->flags2 &= ~MF2_OBJECTFLIP; + flipchanged = true; + } + + if (goalpost->destscale != mobj->destscale + || goalpost->movefactor != mobj->z + || goalpost->friction != mobj->height + || flipchanged + || goalpost->threshold != (INT32)(mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE))) + { + goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; + + // straight copy-pasta from P_SpawnMapThing, case MT_NIGHTSDRONE + if (!flip) + { + if (topaligned) // Align droneman to top of hitbox + { + dronemanoffset = droneboxmandiff; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (middlealigned) // Align droneman to center of hitbox + { + dronemanoffset = droneboxmandiff / 2; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (bottomoffsetted) + { + dronemanoffset = 24*FRACUNIT; + goaloffset = dronemangoaldiff + dronemanoffset; + } + else + { + dronemanoffset = 0; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + + sparkleoffset = goaloffset - FixedMul(15*FRACUNIT, mobj->scale); + } + else + { + if (topaligned) // Align droneman to top of hitbox + { + dronemanoffset = 0; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (middlealigned) // Align droneman to center of hitbox + { + dronemanoffset = droneboxmandiff / 2; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (bottomoffsetted) + { + dronemanoffset = droneboxmandiff - FixedMul(24*FRACUNIT, mobj->scale); + goaloffset = dronemangoaldiff + dronemanoffset; + } + else + { + dronemanoffset = droneboxmandiff; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + + sparkleoffset = goaloffset + FixedMul(15*FRACUNIT, mobj->scale); + } + + P_TeleportMove(goalpost, mobj->x, mobj->y, mobj->z + goaloffset); + P_TeleportMove(sparkle, mobj->x, mobj->y, mobj->z + sparkleoffset); + if (goalpost->movefactor != mobj->z || goalpost->friction != mobj->height) + { + P_TeleportMove(droneman, mobj->x, mobj->y, mobj->z + dronemanoffset); + goalpost->movefactor = mobj->z; + goalpost->friction = mobj->height; + } + goalpost->threshold = mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE); + } + else + { + if (goalpost->x != mobj->x || goalpost->y != mobj->y) + { + P_TeleportMove(goalpost, mobj->x, mobj->y, goalpost->z); + P_TeleportMove(sparkle, mobj->x, mobj->y, sparkle->z); + } + + if (droneman->x != mobj->x || droneman->y != mobj->y) + P_TeleportMove(droneman, mobj->x, mobj->y, + droneman->z >= mobj->floorz && droneman->z <= mobj->ceilingz ? droneman->z : mobj->z); + } + + // now toggle states! + // GOAL mode? + if (sparkle->state >= &states[S_NIGHTSDRONE_SPARKLING1] && sparkle->state <= &states[S_NIGHTSDRONE_SPARKLING16]) + { + INT32 i; + boolean bonustime = false; + + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].bonustime && players[i].powers[pw_carry] == CR_NIGHTSMODE) + { + bonustime = true; + break; + } + + if (!bonustime) + { + CONS_Debug(DBG_NIGHTSBASIC, "Removing goal post\n"); + if (goalpost && goalpost->state != &states[S_INVISIBLE]) + P_SetMobjState(goalpost, S_INVISIBLE); + if (sparkle && sparkle->state != &states[S_INVISIBLE]) + P_SetMobjState(sparkle, S_INVISIBLE); + } + } + // Invisible/bouncing mode. + else + { + INT32 i; + boolean bonustime = false; + fixed_t zcomp; + + // Bouncy bouncy! + if (!flip) + { + if (topaligned) + zcomp = droneboxmandiff + mobj->z; + else if (middlealigned) + zcomp = (droneboxmandiff / 2) + mobj->z; + else if (bottomoffsetted) + zcomp = mobj->z + FixedMul(24*FRACUNIT, mobj->scale); + else + zcomp = mobj->z; + } + else + { + if (topaligned) + zcomp = mobj->z; + else if (middlealigned) + zcomp = (droneboxmandiff / 2) + mobj->z; + else if (bottomoffsetted) + zcomp = mobj->z + droneboxmandiff - FixedMul(24*FRACUNIT, mobj->scale); + else + zcomp = mobj->z + droneboxmandiff; + } + + droneman->angle += ANG10; + if (!flip && droneman->z <= zcomp) + droneman->momz = FixedMul(5*FRACUNIT, droneman->scale); + else if (flip && droneman->z >= zcomp) + droneman->momz = FixedMul(-5*FRACUNIT, droneman->scale); + + // state switching logic + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].bonustime && players[i].powers[pw_carry] == CR_NIGHTSMODE) + { + bonustime = true; + break; + } + + if (bonustime) + { + CONS_Debug(DBG_NIGHTSBASIC, "Adding goal post\n"); + if (!(droneman->flags2 & MF2_DONTDRAW)) + droneman->flags2 |= MF2_DONTDRAW; + if (goalpost->state == &states[S_INVISIBLE]) + P_SetMobjState(goalpost, mobjinfo[goalpost->type].meleestate); + if (sparkle->state == &states[S_INVISIBLE]) + P_SetMobjState(sparkle, mobjinfo[sparkle->type].meleestate); + } + else if (!G_IsSpecialStage(gamemap)) + { + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].powers[pw_carry] != CR_NIGHTSMODE) + { + bonustime = true; // variable reuse + break; + } + + if (bonustime) + { + // show droneman if at least one player is non-nights + if (goalpost->state != &states[S_INVISIBLE]) + P_SetMobjState(goalpost, S_INVISIBLE); + if (sparkle->state != &states[S_INVISIBLE]) + P_SetMobjState(sparkle, S_INVISIBLE); + if (droneman->state != &states[mobjinfo[droneman->type].meleestate]) + P_SetMobjState(droneman, mobjinfo[droneman->type].meleestate); + if (droneman->flags2 & MF2_DONTDRAW) + droneman->flags2 &= ~MF2_DONTDRAW; + } + else + { + // else, hide it + if (!(droneman->flags2 & MF2_DONTDRAW)) + droneman->flags2 |= MF2_DONTDRAW; + } + } + } + } + break; + case MT_PLAYER: + if (mobj->player) + P_PlayerMobjThinker(mobj); + return; + case MT_SKIM: + // check mobj against possible water content, before movement code + P_MobjCheckWater(mobj); + + // Keep Skim at water surface + if (mobj->z <= mobj->watertop) { - P_UnsetThingPosition(mobj); - mobj->x = jetx + P_ReturnThrustX(mobj->target, mobj->target->angle+ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); - mobj->y = jety + P_ReturnThrustY(mobj->target, mobj->target->angle+ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); - if (mobj->target->eflags & MFE_VERTICALFLIP) - mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(12*FRACUNIT, mobj->target->scale); - else - mobj->z = mobj->target->z + FixedMul(12*FRACUNIT, mobj->target->scale); - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_SetThingPosition(mobj); + mobj->flags |= MF_NOGRAVITY; + if (mobj->z < mobj->watertop) + { + if (mobj->watertop - mobj->z <= FixedMul(mobj->info->speed*FRACUNIT, mobj->scale)) + mobj->z = mobj->watertop; + else + mobj->momz = FixedMul(mobj->info->speed*FRACUNIT, mobj->scale); + } } - else if (mobj->fuse == 59) + else { - jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, -mobj->target->radius); - jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, -mobj->target->radius); - P_UnsetThingPosition(mobj); - mobj->x = jetx; - mobj->y = jety; - if (mobj->target->eflags & MFE_VERTICALFLIP) - mobj->z = mobj->target->z + mobj->target->height/2 + mobj->height/2; - else - mobj->z = mobj->target->z + mobj->target->height/2 - mobj->height/2; - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_SetThingPosition(mobj); + mobj->flags &= ~MF_NOGRAVITY; + if (mobj->z > mobj->watertop && mobj->z - mobj->watertop < FixedMul(MAXSTEPMOVE, mobj->scale)) + mobj->z = mobj->watertop; } - mobj->fuse++; - } - break; - case MT_PROPELLER: - { - fixed_t jetx, jety; + break; + case MT_RING: + case MT_COIN: + case MT_BLUESPHERE: + case MT_BOMBSPHERE: + case MT_NIGHTSCHIP: + case MT_NIGHTSSTAR: + case MT_REDTEAMRING: + case MT_BLUETEAMRING: + // No need to check water. Who cares? + P_RingThinker(mobj); + if (mobj->flags2 & MF2_NIGHTSPULL) + P_NightsItemChase(mobj); + else + A_AttractChase(mobj); + return; + // Flung items + case MT_FLINGRING: + case MT_FLINGCOIN: + case MT_FLINGBLUESPHERE: + case MT_FLINGNIGHTSCHIP: + if (mobj->flags2 & MF2_NIGHTSPULL) + P_NightsItemChase(mobj); + else + A_AttractChase(mobj); + break; + case MT_EMBLEM: + if (mobj->flags2 & MF2_NIGHTSPULL) + P_NightsItemChase(mobj); + break; + case MT_SHELL: + if (mobj->threshold && mobj->threshold != TICRATE) + mobj->threshold--; - if (!mobj->target // if you have no target - || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now - { // then remove yourself as well! - P_RemoveMobj(mobj); - return; + if (mobj->threshold >= TICRATE) + { + mobj->angle += ((mobj->movedir == 1) ? ANGLE_22h : ANGLE_337h); + P_InstaThrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), (mobj->info->speed*mobj->scale)); } - - jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, FixedMul(-60*FRACUNIT, mobj->target->scale)); - jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, FixedMul(-60*FRACUNIT, mobj->target->scale)); - - P_UnsetThingPosition(mobj); - mobj->x = jetx; - mobj->y = jety; - mobj->z = mobj->target->z + FixedMul(17*FRACUNIT, mobj->target->scale); - mobj->angle = mobj->target->angle - ANGLE_180; - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_SetThingPosition(mobj); - } - break; - case MT_JETFLAME: - { - if (!mobj->target // if you have no target - || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now - { // then remove yourself as well! - P_RemoveMobj(mobj); + break; + case MT_TURRET: + P_MobjCheckWater(mobj); + P_CheckPosition(mobj, mobj->x, mobj->y); + if (P_MobjWasRemoved(mobj)) return; - } - - P_UnsetThingPosition(mobj); - mobj->x = mobj->target->x; - mobj->y = mobj->target->y; - mobj->z = mobj->target->z - FixedMul(50*FRACUNIT, mobj->target->scale); - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_SetThingPosition(mobj); - } - break; - case MT_NIGHTSDRONE: - if (mobj->state >= &states[S_NIGHTSDRONE_SPARKLING1] && mobj->state <= &states[S_NIGHTSDRONE_SPARKLING16]) - { - mobj->flags2 &= ~MF2_DONTDRAW; - mobj->z = mobj->floorz + mobj->height + (mobj->spawnpoint->options >> ZSHIFT) * FRACUNIT; - mobj->angle = 0; + mobj->floorz = tmfloorz; + mobj->ceilingz = tmceilingz; + mobj->floorrover = tmfloorrover; + mobj->ceilingrover = tmceilingrover; - if (!mobj->target) + if ((mobj->eflags & MFE_UNDERWATER) && mobj->health > 0) { - mobj_t *goalpost = P_SpawnMobj(mobj->x, mobj->y, mobj->z + FRACUNIT, MT_NIGHTSGOAL); - CONS_Debug(DBG_NIGHTSBASIC, "Adding goal post\n"); - goalpost->angle = mobj->angle; - P_SetTarget(&mobj->target, goalpost); + P_SetMobjState(mobj, mobj->info->deathstate); + mobj->health = 0; + mobj->flags2 &= ~MF2_FIRING; } + else if (mobj->health > 0 && mobj->z + mobj->height > mobj->ceilingz) // Crushed + { + INT32 i,j; + fixed_t ns; + fixed_t x,y,z; + mobj_t *mo2; - if (G_IsSpecialStage(gamemap)) - { // Never show the NiGHTS drone in special stages. Check ANYONE for bonustime. - INT32 i; - boolean bonustime = false; - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].bonustime) + z = mobj->subsector->sector->floorheight + FixedMul(64*FRACUNIT, mobj->scale); + for (j = 0; j < 2; j++) + { + for (i = 0; i < 32; i++) { - bonustime = true; - break; + const angle_t fa = (i*FINEANGLES/16) & FINEMASK; + ns = FixedMul(64 * FRACUNIT, mobj->scale); + x = mobj->x + FixedMul(FINESINE(fa),ns); + y = mobj->y + FixedMul(FINECOSINE(fa),ns); + + mo2 = P_SpawnMobj(x, y, z, MT_EXPLODE); + ns = FixedMul(16 * FRACUNIT, mobj->scale); + mo2->momx = FixedMul(FINESINE(fa),ns); + mo2->momy = FixedMul(FINECOSINE(fa),ns); } - if (!bonustime) - { - mobj->flags &= ~MF_NOGRAVITY; - P_SetMobjState(mobj, S_NIGHTSDRONE1); - mobj->flags2 |= MF2_DONTDRAW; + z -= FixedMul(32*FRACUNIT, mobj->scale); } + P_SetMobjState(mobj, mobj->info->deathstate); + mobj->health = 0; + mobj->flags2 &= ~MF2_FIRING; } - else if (mobj->tracer && mobj->tracer->player) + break; + case MT_BLUEFLAG: + case MT_REDFLAG: { - if (!(mobj->tracer->player->pflags & PF_NIGHTSMODE)) - { - mobj->flags &= ~MF_NOGRAVITY; - mobj->flags2 &= ~MF2_DONTDRAW; - P_SetMobjState(mobj, S_NIGHTSDRONE1); - } - else if (!mobj->tracer->player->bonustime) + sector_t *sec2; + sec2 = P_ThingOnSpecial3DFloor(mobj); + if ((sec2 && GETSECSPECIAL(sec2->special, 4) == 2) || (GETSECSPECIAL(mobj->subsector->sector->special, 4) == 2)) + mobj->fuse = 1; // Return to base. + break; + } + case MT_CANNONBALL: +#ifdef FLOORSPLATS + R_AddFloorSplat(mobj->tracer->subsector, mobj->tracer, "TARGET", mobj->tracer->x, + mobj->tracer->y, mobj->tracer->floorz, SPLATDRAWMODE_SHADE); +#endif + break; + case MT_SPINDUST: // Spindash dust + mobj->momx = FixedMul(mobj->momx, (3*FRACUNIT)/4); // originally 50000 + mobj->momy = FixedMul(mobj->momy, (3*FRACUNIT)/4); // same + //mobj->momz = mobj->momz+P_MobjFlip(mobj)/3; // no meaningful change in value to be frank + if (mobj->state >= &states[S_SPINDUST_BUBBLE1] && mobj->state <= &states[S_SPINDUST_BUBBLE4]) // bubble dust! { - mobj->flags &= ~MF_NOGRAVITY; - P_SetMobjState(mobj, S_NIGHTSDRONE1); + P_MobjCheckWater(mobj); + if (mobj->watertop != mobj->subsector->sector->floorheight - 1000*FRACUNIT + && mobj->z+mobj->height >= mobj->watertop - 5*FRACUNIT) + mobj->flags2 |= MF2_DONTDRAW; } + break; + case MT_TRAINDUSTSPAWNER: + if (leveltime % 5 == 0) { + mobj_t *traindust = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_PARTICLE); + traindust->flags = MF_SCENERY; + P_SetMobjState(traindust, S_TRAINDUST); + traindust->frame = P_RandomRange(0, 8) | FF_TRANS90; + traindust->angle = mobj->angle; + traindust->tics = TICRATE * 4; + traindust->destscale = FRACUNIT * 64; + traindust->scalespeed = FRACUNIT / 24; + P_SetScale(traindust, FRACUNIT * 6); } - } - else - { - if (G_IsSpecialStage(gamemap)) - { // Never show the NiGHTS drone in special stages. Check ANYONE for bonustime. - INT32 i; + break; + case MT_TRAINSTEAMSPAWNER: + if (leveltime % 5 == 0) { + mobj_t *steam = P_SpawnMobj(mobj->x + FRACUNIT*P_SignedRandom() / 2, mobj->y + FRACUNIT*P_SignedRandom() / 2, mobj->z, MT_PARTICLE); + P_SetMobjState(steam, S_TRAINSTEAM); + steam->frame = P_RandomRange(0, 1) | FF_TRANS90; + steam->tics = TICRATE * 8; + steam->destscale = FRACUNIT * 64; + steam->scalespeed = FRACUNIT / 8; + P_SetScale(steam, FRACUNIT * 16); + steam->momx = P_SignedRandom() * 32; + steam->momy = -64 * FRACUNIT; + steam->momz = 2 * FRACUNIT; + } + break; + case MT_CANARIVORE_GAS: + { + fixed_t momz; - boolean bonustime = false; - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].bonustime) - { - bonustime = true; - break; - } + if (mobj->flags2 & MF2_AMBUSH) + { + mobj->momx = FixedMul(mobj->momx, 50 * FRACUNIT / 51); + mobj->momy = FixedMul(mobj->momy, 50 * FRACUNIT / 51); + break; + } - if (bonustime) + if (mobj->eflags & MFE_VERTICALFLIP) { - P_SetMobjState(mobj, S_NIGHTSDRONE_SPARKLING1); - mobj->flags |= MF_NOGRAVITY; + if ((mobj->z + mobj->height + mobj->momz) <= mobj->ceilingz) + break; } else { - if (mobj->target) - { - CONS_Debug(DBG_NIGHTSBASIC, "Removing goal post\n"); - P_RemoveMobj(mobj->target); - P_SetTarget(&mobj->target, NULL); - } - mobj->flags2 |= MF2_DONTDRAW; + if ((mobj->z + mobj->momz) >= mobj->floorz) + break; } + + momz = abs(mobj->momz); + if (R_PointToDist2(0, 0, mobj->momx, mobj->momy) < momz) + P_InstaThrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), momz); + mobj->flags2 |= MF2_AMBUSH; + break; } - else if (mobj->tracer && mobj->tracer->player) + case MT_SALOONDOOR: { - if (mobj->target) + fixed_t x = mobj->tracer->x; + fixed_t y = mobj->tracer->y; + fixed_t z = mobj->tracer->z; + angle_t oang = FixedAngle(mobj->extravalue1); + angle_t fa = (oang >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t c0 = -96*FINECOSINE(fa); + fixed_t s0 = -96*FINESINE(fa); + angle_t fma; + fixed_t c, s; + angle_t angdiff; + + // Adjust angular speed + fixed_t da = AngleFixed(mobj->angle - oang); + if (da > 180*FRACUNIT) + da -= 360*FRACUNIT; + mobj->extravalue2 = 8*(mobj->extravalue2 - da/32)/9; + + // Update angle + mobj->angle += FixedAngle(mobj->extravalue2); + + angdiff = mobj->angle - FixedAngle(mobj->extravalue1); + if (angdiff > (ANGLE_90 - ANG2) && angdiff < ANGLE_180) { - CONS_Debug(DBG_NIGHTSBASIC, "Removing goal post\n"); - P_RemoveMobj(mobj->target); - P_SetTarget(&mobj->target, NULL); + mobj->angle = FixedAngle(mobj->extravalue1) + (ANGLE_90 - ANG2); + mobj->extravalue2 /= 2; } - - if (mobj->tracer->player->pflags & PF_NIGHTSMODE) + else if (angdiff < (ANGLE_270 + ANG2) && angdiff >= ANGLE_180) { - if (mobj->tracer->player->bonustime) - { - P_SetMobjState(mobj, S_NIGHTSDRONE_SPARKLING1); - mobj->flags |= MF_NOGRAVITY; - } - else - mobj->flags2 |= MF2_DONTDRAW; + mobj->angle = FixedAngle(mobj->extravalue1) + (ANGLE_270 + ANG2); + mobj->extravalue2 /= 2; } - else // Not NiGHTS - mobj->flags2 &= ~MF2_DONTDRAW; - } - mobj->angle += ANG10; - if (mobj->z <= mobj->floorz) - mobj->momz = 5*FRACUNIT; - } - break; - case MT_PLAYER: - if (mobj->player) - P_PlayerMobjThinker(mobj); - return; - case MT_SKIM: - // check mobj against possible water content, before movement code - P_MobjCheckWater(mobj); - // Keep Skim at water surface - if (mobj->z <= mobj->watertop) - { - mobj->flags |= MF_NOGRAVITY; - if (mobj->z < mobj->watertop) + // Update position + fma = (mobj->angle >> ANGLETOFINESHIFT) & FINEMASK; + c = 48*FINECOSINE(fma); + s = 48*FINESINE(fma); + P_TeleportMove(mobj, x + c0 + c, y + s0 + s, z); + break; + } + case MT_MINECARTSPAWNER: + P_HandleMinecartSegments(mobj); + if (!mobj->fuse || mobj->fuse > TICRATE) + break; + if (mobj->fuse == 2) { - if (mobj->watertop - mobj->z <= FixedMul(mobj->info->speed*FRACUNIT, mobj->scale)) - mobj->z = mobj->watertop; + mobj->fuse = 0; + break; + } + mobj->flags2 ^= MF2_DONTDRAW; + break; + case MT_SPINFIRE: + if (mobj->flags & MF_NOGRAVITY) + { + if (mobj->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->ceilingz - mobj->height; else - mobj->momz = FixedMul(mobj->info->speed*FRACUNIT, mobj->scale); + mobj->z = mobj->floorz; } - } - else - { - mobj->flags &= ~MF_NOGRAVITY; - if (mobj->z > mobj->watertop && mobj->z - mobj->watertop < FixedMul(MAXSTEPMOVE, mobj->scale)) - mobj->z = mobj->watertop; - } - break; - case MT_RING: - case MT_COIN: - case MT_BLUEBALL: - case MT_REDTEAMRING: - case MT_BLUETEAMRING: - // No need to check water. Who cares? - P_RingThinker(mobj); - if (mobj->flags2 & MF2_NIGHTSPULL) - P_NightsItemChase(mobj); - else - A_AttractChase(mobj); - return; - // Flung items - case MT_FLINGRING: - case MT_FLINGCOIN: - if (mobj->flags2 & MF2_NIGHTSPULL) - P_NightsItemChase(mobj); - else - A_AttractChase(mobj); - break; - case MT_NIGHTSWING: - if (mobj->flags2 & MF2_NIGHTSPULL) - P_NightsItemChase(mobj); - break; - case MT_SHELL: - if (mobj->threshold > TICRATE) - mobj->threshold--; - - if (mobj->state != &states[S_SHELL]) - { - mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); - P_InstaThrust(mobj, mobj->angle, FixedMul(mobj->info->speed, mobj->scale)); - } - break; - case MT_TURRET: - P_MobjCheckWater(mobj); - P_CheckPosition(mobj, mobj->x, mobj->y); - if (P_MobjWasRemoved(mobj)) - return; - mobj->floorz = tmfloorz; - mobj->ceilingz = tmceilingz; - - if ((mobj->eflags & MFE_UNDERWATER) && mobj->health > 0) - { - P_SetMobjState(mobj, mobj->info->deathstate); - mobj->health = 0; - mobj->flags2 &= ~MF2_FIRING; - } - else if (mobj->health > 0 && mobj->z + mobj->height > mobj->ceilingz) // Crushed - { - INT32 i,j; - fixed_t ns; - fixed_t x,y,z; - mobj_t *mo2; + /* FALLTHRU */ + default: + // check mobj against possible water content, before movement code + P_MobjCheckWater(mobj); - z = mobj->subsector->sector->floorheight + FixedMul(64*FRACUNIT, mobj->scale); - for (j = 0; j < 2; j++) + // Extinguish fire objects in water + if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL + && (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) { - for (i = 0; i < 32; i++) - { - const angle_t fa = (i*FINEANGLES/16) & FINEMASK; - ns = FixedMul(64 * FRACUNIT, mobj->scale); - x = mobj->x + FixedMul(FINESINE(fa),ns); - y = mobj->y + FixedMul(FINECOSINE(fa),ns); - - mo2 = P_SpawnMobj(x, y, z, MT_EXPLODE); - ns = FixedMul(16 * FRACUNIT, mobj->scale); - mo2->momx = FixedMul(FINESINE(fa),ns); - mo2->momy = FixedMul(FINECOSINE(fa),ns); - } - z -= FixedMul(32*FRACUNIT, mobj->scale); + P_KillMobj(mobj, NULL, NULL, 0); + return; } - P_SetMobjState(mobj, mobj->info->deathstate); - mobj->health = 0; - mobj->flags2 &= ~MF2_FIRING; - } - break; - case MT_BLUEFLAG: - case MT_REDFLAG: - { - sector_t *sec2; - sec2 = P_ThingOnSpecial3DFloor(mobj); - if ((sec2 && GETSECSPECIAL(sec2->special, 4) == 2) || (GETSECSPECIAL(mobj->subsector->sector->special, 4) == 2)) - mobj->fuse = 1; // Return to base. break; - } - case MT_CANNONBALL: -#ifdef FLOORSPLATS - R_AddFloorSplat(mobj->tracer->subsector, mobj->tracer, "TARGET", mobj->tracer->x, - mobj->tracer->y, mobj->tracer->floorz, SPLATDRAWMODE_SHADE); -#endif - break; - case MT_SPINFIRE: - if (mobj->eflags & MFE_VERTICALFLIP) - mobj->z = mobj->ceilingz - mobj->height; - else - mobj->z = mobj->floorz; - /* FALLTHRU */ - default: - // check mobj against possible water content, before movement code - P_MobjCheckWater(mobj); - - // Extinguish fire objects in water - if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL - && (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) - { - P_KillMobj(mobj, NULL, NULL); - return; - } - break; + } } if (P_MobjWasRemoved(mobj)) return; @@ -7184,7 +8617,7 @@ void P_MobjThinker(mobj_t *mobj) { mobj_t *missile; - if (mobj->target->player && mobj->target->player->nightstime) + if (mobj->target->player && mobj->target->player->powers[pw_carry] == CR_NIGHTSMODE) { fixed_t oldval = mobjinfo[mobj->extravalue1].speed; @@ -7222,6 +8655,10 @@ void P_MobjThinker(mobj_t *mobj) // Check fuse if (mobj->fuse) { + + if (mobj->type == MT_SNAPPER_HEAD || mobj->type == MT_SNAPPER_LEG || mobj->type == MT_MINECARTSEG) + mobj->flags2 ^= MF2_DONTDRAW; + mobj->fuse--; if (!mobj->fuse) { @@ -7230,9 +8667,51 @@ void P_MobjThinker(mobj_t *mobj) mobj_t *flagmo, *newmobj; #ifdef HAVE_BLUA - if (!LUAh_MobjFuse(mobj) && !P_MobjWasRemoved(mobj)) + if (LUAh_MobjFuse(mobj) || P_MobjWasRemoved(mobj)) + ; + else #endif - switch (mobj->type) + if (mobj->info->flags & MF_MONITOR) + { + // Special case for ALL monitors. + // If a box's speed is nonzero, it's allowed to respawn as a WRM/SRM. + if (mobj->info->speed != 0 && (mobj->flags2 & (MF2_AMBUSH|MF2_STRONGBOX))) + { + mobjtype_t spawnchance[64]; + INT32 numchoices = 0, i = 0; + +// This define should make it a lot easier to organize and change monitor weights +#define SETMONITORCHANCES(type, strongboxamt, weakboxamt) \ +for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) spawnchance[numchoices++] = type + + // Type SRM WRM + SETMONITORCHANCES(MT_SNEAKERS_BOX, 0, 10); // Super Sneakers + SETMONITORCHANCES(MT_INVULN_BOX, 2, 0); // Invincibility + SETMONITORCHANCES(MT_WHIRLWIND_BOX, 3, 8); // Whirlwind Shield + SETMONITORCHANCES(MT_ELEMENTAL_BOX, 3, 8); // Elemental Shield + SETMONITORCHANCES(MT_ATTRACT_BOX, 2, 0); // Attraction Shield + SETMONITORCHANCES(MT_FORCE_BOX, 3, 3); // Force Shield + SETMONITORCHANCES(MT_ARMAGEDDON_BOX, 2, 0); // Armageddon Shield + SETMONITORCHANCES(MT_MIXUP_BOX, 0, 1); // Teleporters + SETMONITORCHANCES(MT_RECYCLER_BOX, 0, 1); // Recycler + SETMONITORCHANCES(MT_1UP_BOX, 1, 1); // 1-Up + // ======================================= + // Total 16 32 + +#undef SETMONITORCHANCES + + i = P_RandomKey(numchoices); // Gotta love those random numbers! + newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, spawnchance[i]); + } + else + newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type); + + // Transfer flags2 (ambush, strongbox, objectflip) + newmobj->flags2 = mobj->flags2; + P_RemoveMobj(mobj); // make sure they disappear + return; + } + else switch (mobj->type) { // gargoyle and snowman handled in P_PushableThinker, not here case MT_THROWNGRENADE: @@ -7295,68 +8774,6 @@ void P_MobjThinker(mobj_t *mobj) } P_RemoveMobj(mobj); return; - case MT_YELLOWTV: // Ring shield box - case MT_BLUETV: // Force shield box - case MT_GREENTV: // Water shield box - case MT_BLACKTV: // Bomb shield box - case MT_WHITETV: // Jump shield box - case MT_SNEAKERTV: // Super Sneaker box - case MT_SUPERRINGBOX: // 10-Ring box - case MT_REDRINGBOX: // Red Team 10-Ring box - case MT_BLUERINGBOX: // Blue Team 10-Ring box - case MT_INV: // Invincibility box - case MT_MIXUPBOX: // Teleporter Mixup box - case MT_RECYCLETV: // Recycler box - case MT_SCORETVSMALL: - case MT_SCORETVLARGE: - case MT_PRUP: // 1up! - case MT_EGGMANBOX: // Eggman box - case MT_GRAVITYBOX: // Gravity box - case MT_QUESTIONBOX: - if ((mobj->flags & MF_AMBUSH || mobj->flags2 & MF2_STRONGBOX) && mobj->type != MT_QUESTIONBOX) - { - mobjtype_t spawnchance[64]; - INT32 numchoices = 0, i = 0; - -// This define should make it a lot easier to organize and change monitor weights -#define SETMONITORCHANCES(type, strongboxamt, weakboxamt) \ -for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) spawnchance[numchoices++] = type - - // Type SRM WRM - SETMONITORCHANCES(MT_SNEAKERTV, 0, 10); // Super Sneakers - SETMONITORCHANCES(MT_INV, 2, 0); // Invincibility - SETMONITORCHANCES(MT_WHITETV, 3, 8); // Whirlwind Shield - SETMONITORCHANCES(MT_GREENTV, 3, 8); // Elemental Shield - SETMONITORCHANCES(MT_YELLOWTV, 2, 0); // Attraction Shield - SETMONITORCHANCES(MT_BLUETV, 3, 3); // Force Shield - SETMONITORCHANCES(MT_BLACKTV, 2, 0); // Armageddon Shield - SETMONITORCHANCES(MT_MIXUPBOX, 0, 1); // Teleporters - SETMONITORCHANCES(MT_RECYCLETV, 0, 1); // Recycler - SETMONITORCHANCES(MT_PRUP, 1, 1); // 1-Up - // ====================================== - // Total 16 32 - -#undef SETMONITORCHANCES - - i = P_RandomKey(numchoices); // Gotta love those random numbers! - newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, spawnchance[i]); - - // If the monitor respawns randomly, transfer the flag. - if (mobj->flags & MF_AMBUSH) - newmobj->flags |= MF_AMBUSH; - - // Transfer flags2 (strongbox, objectflip) - newmobj->flags2 = mobj->flags2; - } - else - { - newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type); - - // Transfer flags2 (strongbox, objectflip) - newmobj->flags2 = mobj->flags2; - } - P_RemoveMobj(mobj); // make sure they disappear - return; case MT_METALSONIC_BATTLE: break; // don't remove case MT_SPIKE: @@ -7365,6 +8782,12 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s if (mobj->spawnpoint) mobj->fuse += mobj->spawnpoint->angle; break; + case MT_WALLSPIKE: + P_SetMobjState(mobj, mobj->state->nextstate); + mobj->fuse = mobj->info->speed; + if (mobj->spawnpoint) + mobj->fuse += (mobj->spawnpoint->angle/360); + break; case MT_NIGHTSCORE: P_RemoveMobj(mobj); return; @@ -7373,6 +8796,7 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s default: P_SetMobjState(mobj, mobj->info->xdeathstate); // will remove the mobj if S_NULL. break; + // Looking for monitors? They moved to a special condition above. } if (P_MobjWasRemoved(mobj)) return; @@ -7411,6 +8835,8 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s #ifdef ESLOPE // Sliding physics for slidey mobjs! if (mobj->type == MT_FLINGRING || mobj->type == MT_FLINGCOIN + || mobj->type == MT_FLINGBLUESPHERE + || mobj->type == MT_FLINGNIGHTSCHIP || P_WeaponOrPanel(mobj->type) || mobj->type == MT_FLINGEMERALD || mobj->type == MT_BIGTUMBLEWEED @@ -7426,7 +8852,7 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s if (mobj->flags & (MF_ENEMY|MF_BOSS) && mobj->health && P_CheckDeathPitCollide(mobj)) // extra pit check in case these didn't have momz { - P_KillMobj(mobj, NULL, NULL); + P_KillMobj(mobj, NULL, NULL, DMG_DEATHPIT); return; } @@ -7440,7 +8866,7 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s && !(mobj->flags & MF_NOCLIPHEIGHT) && mobj->health > 0) { - P_KillMobj(mobj, NULL, NULL); + P_KillMobj(mobj, NULL, NULL, DMG_CRUSHED); return; } } @@ -7534,6 +8960,16 @@ void P_PushableThinker(mobj_t *mobj) if (mobj->flags & MF_PUSHABLE && !(mobj->momx || mobj->momy)) P_TryMove(mobj, mobj->x, mobj->y, true); + if (mobj->type == MT_MINECART && mobj->health) + { + // If player is ded, remove this minecart + if (!mobj->target || P_MobjWasRemoved(mobj->target) || !mobj->target->health || !mobj->target->player || mobj->target->player->powers[pw_carry] != CR_MINECART) + { + P_KillMobj(mobj, NULL, NULL, 0); + return; + } + } + if (mobj->fuse == 1) // it would explode in the MobjThinker code { mobj_t *spawnmo; @@ -7616,6 +9052,8 @@ void P_SceneryThinker(mobj_t *mobj) return; mobj->floorz = tmfloorz; mobj->ceilingz = tmceilingz; + mobj->floorrover = tmfloorrover; + mobj->ceilingrover = tmceilingrover; } else { @@ -7651,7 +9089,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->height = info->height; mobj->flags = info->flags; - mobj->health = info->spawnhealth; + mobj->health = (info->spawnhealth ? info->spawnhealth : 1); mobj->reactiontime = info->reactiontime; @@ -7665,11 +9103,11 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->tics = st->tics; mobj->sprite = st->sprite; mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits.. - mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set + P_SetupStateAnimation(mobj, st); mobj->friction = ORIG_FRICTION; - mobj->movefactor = ORIG_FRICTION_FACTOR; + mobj->movefactor = FRACUNIT; // All mobjs are created at 100% scale. mobj->scale = FRACUNIT; @@ -7698,6 +9136,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) #endif mobj->subsector->sector->ceilingheight; + mobj->floorrover = NULL; + mobj->ceilingrover = NULL; + // Tells MobjCheckWater that the water height was not set. mobj->watertop = INT32_MAX; @@ -7740,8 +9181,11 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) #endif switch (mobj->type) { + case MT_ALTVIEWMAN: + if (titlemapinaction) mobj->flags &= ~MF_NOTHINK; + break; case MT_CYBRAKDEMON_NAPALM_BOMB_LARGE: - mobj->fuse = mobj->info->mass; + mobj->fuse = mobj->info->painchance; break; case MT_BLACKEGGMAN: { @@ -7751,12 +9195,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) P_SetTarget(&spawn->target, mobj); } break; - case MT_BLACKEGGMAN_HELPER: - // Collision helper can be stood on but not pushed - mobj->flags2 |= MF2_STANDONME; - break; - case MT_SPIKE: - mobj->flags2 |= MF2_STANDONME; + case MT_FAKEMOBILE: + case MT_EGGSHIELD: + mobj->flags2 |= MF2_INVERTAIMABLE; break; case MT_DETON: mobj->movedir = 0; @@ -7771,52 +9212,94 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) } break; case MT_UNIDUS: - { - INT32 i; - mobj_t *ball; - // Spawn "damage" number of "painchance" spikeball mobjs - // threshold is the distance they should keep from the MT_UNIDUS (touching radius + ball painchance) - for (i = 0; i < mobj->info->damage; i++) { - ball = P_SpawnMobj(x, y, z, mobj->info->painchance); - ball->destscale = mobj->scale; - P_SetScale(ball, mobj->scale); - P_SetTarget(&ball->target, mobj); - ball->movedir = FixedAngle(FixedMul(FixedDiv(i<<FRACBITS, mobj->info->damage<<FRACBITS), 360<<FRACBITS)); - ball->threshold = ball->radius + mobj->radius + FixedMul(ball->info->painchance, ball->scale); - - var1 = ball->state->var1, var2 = ball->state->var2; - ball->state->action.acp1(ball); + INT32 i; + mobj_t *ball; + // Spawn "damage" number of "painchance" spikeball mobjs + // threshold is the distance they should keep from the MT_UNIDUS (touching radius + ball painchance) + for (i = 0; i < mobj->info->damage; i++) + { + ball = P_SpawnMobj(x, y, z, mobj->info->painchance); + ball->destscale = mobj->scale; + P_SetScale(ball, mobj->scale); + P_SetTarget(&ball->target, mobj); + ball->movedir = FixedAngle(FixedMul(FixedDiv(i<<FRACBITS, mobj->info->damage<<FRACBITS), 360<<FRACBITS)); + ball->threshold = ball->radius + mobj->radius + FixedMul(ball->info->painchance, ball->scale); + + var1 = ball->state->var1, var2 = ball->state->var2; + ball->state->action.acp1(ball); + } } break; - } case MT_POINTY: - { - INT32 q; - mobj_t *ball, *lastball = mobj; + { + INT32 q; + mobj_t *ball, *lastball = mobj; - for (q = 0; q < mobj->info->painchance; q++) + for (q = 0; q < mobj->info->painchance; q++) + { + ball = P_SpawnMobj(x, y, z, mobj->info->mass); + ball->destscale = mobj->scale; + P_SetScale(ball, mobj->scale); + P_SetTarget(&lastball->tracer, ball); + P_SetTarget(&ball->target, mobj); + lastball = ball; + } + } + break; + case MT_CRUSHSTACEAN: { - ball = P_SpawnMobj(x, y, z, mobj->info->mass); - ball->destscale = mobj->scale; - P_SetScale(ball, mobj->scale); - P_SetTarget(&lastball->tracer, ball); - P_SetTarget(&ball->target, mobj); - lastball = ball; + mobj_t *bigmeatyclaw = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_CRUSHCLAW); + bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270);; + P_SetTarget(&mobj->tracer, bigmeatyclaw); + P_SetTarget(&bigmeatyclaw->tracer, mobj); + mobj->reactiontime >>= 1; + } + break; + case MT_BIGMINE: + mobj->extravalue1 = FixedHypot(mobj->x, mobj->y)>>FRACBITS; + break; + case MT_WAVINGFLAG: + { + mobj_t *prev = mobj, *cur; + UINT8 i; + mobj->destscale <<= 2; + P_SetScale(mobj, mobj->destscale); + for (i = 0; i <= 16; i++) // probably should be < but staying authentic to the Lua version + { + cur = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_WAVINGFLAGSEG); + P_SetTarget(&prev->tracer, cur); + cur->extravalue1 = i; + prev = cur; + } } break; - } case MT_EGGMOBILE2: // Special condition for the 2nd boss. mobj->watertop = mobj->info->speed; break; - case MT_BIRD: - case MT_BUNNY: - case MT_MOUSE: - case MT_CHICKEN: - case MT_COW: - case MT_REDBIRD: - mobj->fuse = P_RandomRange(300, 350); + case MT_FLICKY_08: + mobj->color = (P_RandomChance(FRACUNIT/2) ? SKINCOLOR_RED : SKINCOLOR_AQUA); + break; + case MT_BALLOON: + mobj->color = SKINCOLOR_RED; + break; + case MT_HIVEELEMENTAL: + mobj->extravalue1 = 5; + break; + case MT_SMASHINGSPIKEBALL: + mobj->movecount = mobj->z; + break; + case MT_SPINBOBERT: + { + mobj_t *fire; + fire = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_SPINBOBERT_FIRE1); + P_SetTarget(&fire->target, mobj); + P_SetTarget(&mobj->hnext, fire); + fire = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_SPINBOBERT_FIRE2); + P_SetTarget(&fire->target, mobj); + P_SetTarget(&mobj->hprev, fire); + } break; case MT_REDRING: // Make MT_REDRING red by default mobj->color = skincolor_redring; @@ -7826,8 +9309,14 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_EXTRALARGEBUBBLE: mobj->fuse += 30 * TICRATE; break; + case MT_NIGHTSDRONE: + nummaprings = -1; // no perfect bonus, rings are free + break; case MT_EGGCAPSULE: - mobj->extravalue1 = -1; // timer for how long a player has been at the capsule + mobj->reactiontime = 0; + mobj->extravalue1 = mobj->cvmem =\ + mobj->cusval = mobj->movecount =\ + mobj->lastlook = mobj->extravalue2 = -1; break; case MT_REDTEAMRING: mobj->color = skincolor_redteam; @@ -7837,8 +9326,30 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) break; case MT_RING: case MT_COIN: - case MT_BLUEBALL: - nummaprings++; + case MT_NIGHTSSTAR: + if (nummaprings >= 0) + nummaprings++; + break; + case MT_CORK: + mobj->flags2 |= MF2_SUPERFIRE; + break; + case MT_FBOMB: + mobj->flags2 |= MF2_EXPLOSION; + break; + case MT_OILLAMP: + { + mobj_t* overlay = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); + P_SetTarget(&overlay->target, mobj); + P_SetMobjState(overlay, S_OILLAMPFLARE); + break; + } + case MT_TNTBARREL: + mobj->momx = 1; //stack hack + break; + case MT_MINECARTEND: + mobj->tracer = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_MINECARTENDSOLID); + mobj->tracer->angle = mobj->angle + ANGLE_90; + break; default: break; } @@ -7896,7 +9407,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype mobj->tics = st->tics; mobj->sprite = st->sprite; mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits.. - mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set + P_SetupStateAnimation((mobj_t*)mobj, st); // set subsector and/or block links P_SetPrecipitationThingPosition(mobj); @@ -7912,6 +9423,9 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype #endif mobj->subsector->sector->ceilingheight; + mobj->floorrover = NULL; + mobj->ceilingrover = NULL; + mobj->z = z; mobj->momz = mobjinfo[type].speed; @@ -7973,7 +9487,7 @@ void P_RemoveMobj(mobj_t *mobj) if (mobj->spawnpoint && (mobj->type == MT_RING || mobj->type == MT_COIN - || mobj->type == MT_BLUEBALL + || mobj->type == MT_NIGHTSSTAR || mobj->type == MT_REDTEAMRING || mobj->type == MT_BLUETEAMRING || P_WeaponOrPanel(mobj->type)) @@ -7990,6 +9504,12 @@ void P_RemoveMobj(mobj_t *mobj) if (mobj->type == MT_OVERLAY) P_RemoveOverlay(mobj); + if (mobj->player && mobj->player->followmobj) + { + P_RemoveMobj(mobj->player->followmobj); + P_SetTarget(&mobj->player->followmobj, NULL); + } + mobj->health = 0; // Just because // unlink from sector and block lists @@ -8012,6 +9532,13 @@ void P_RemoveMobj(mobj_t *mobj) // Remove any references to other mobjs. P_SetTarget(&mobj->target, P_SetTarget(&mobj->tracer, NULL)); + if (mobj->hnext && !P_MobjWasRemoved(mobj->hnext)) + P_SetTarget(&mobj->hnext->hprev, mobj->hprev); + if (mobj->hprev && !P_MobjWasRemoved(mobj->hprev)) + P_SetTarget(&mobj->hprev->hnext, mobj->hnext); + + P_SetTarget(&mobj->hnext, P_SetTarget(&mobj->hprev, NULL)); + // free block // DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error. if (mobj->flags & MF_NOTHINK && !mobj->thinker.next) @@ -8094,7 +9621,6 @@ consvar_t cv_itemrespawntime = {"respawnitemtime", "30", CV_NETVAR|CV_CHEAT, res consvar_t cv_itemrespawn = {"respawnitem", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t flagtime_cons_t[] = {{0, "MIN"}, {300, "MAX"}, {0, NULL}}; consvar_t cv_flagtime = {"flagtime", "30", CV_NETVAR|CV_CHEAT, flagtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_suddendeath = {"suddendeath", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; void P_SpawnPrecipitation(void) { @@ -8103,7 +9629,7 @@ void P_SpawnPrecipitation(void) subsector_t *precipsector = NULL; precipmobj_t *rainmo = NULL; - if (dedicated || !cv_precipdensity.value || curWeather == PRECIP_NONE) + if (dedicated || /*!cv_precipdensity*/!cv_drawdist_precip.value || curWeather == PRECIP_NONE) return; // Use the blockmap to narrow down our placing patterns @@ -8112,7 +9638,7 @@ void P_SpawnPrecipitation(void) basex = bmaporgx + (i % bmapwidth) * MAPBLOCKSIZE; basey = bmaporgy + (i / bmapwidth) * MAPBLOCKSIZE; - for (j = 0; j < cv_precipdensity.value; ++j) + //for (j = 0; j < cv_precipdensity.value; ++j) -- density is 1 for us always { x = basex + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3); y = basey + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3); @@ -8365,7 +9891,7 @@ void P_RespawnSpecials(void) #endif ss->sector->ceilingheight) - (mthing->options >> ZSHIFT) * FRACUNIT; if (mthing->options & MTF_AMBUSH - && (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i))) + && (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || i == MT_NIGHTSSTAR || P_WeaponOrPanel(i))) z -= 24*FRACUNIT; z -= mobjinfo[i].height; // Don't forget the height! } @@ -8377,7 +9903,7 @@ void P_RespawnSpecials(void) #endif ss->sector->floorheight) + (mthing->options >> ZSHIFT) * FRACUNIT; if (mthing->options & MTF_AMBUSH - && (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i))) + && (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || i == MT_NIGHTSSTAR || P_WeaponOrPanel(i))) z += 24*FRACUNIT; } @@ -8411,40 +9937,44 @@ void P_SpawnPlayer(INT32 playernum) // spawn as spectator determination if (!G_GametypeHasSpectators()) { - // Special case for (NiGHTS) special stages! - // if stage has already started, force players to become spectators until the next stage - if (multiplayer && netgame && G_IsSpecialStage(gamemap) && useNightsSS && leveltime > 0) - p->spectator = true; - else - p->spectator = false; + p->spectator = p->outofcoop = + (((multiplayer || netgame) && gametype == GT_COOP) // only question status in coop + && ((leveltime > 0 + && ((G_IsSpecialStage(gamemap) && (maptol & TOL_NIGHTS)) // late join special stage + || (cv_coopstarposts.value == 2 && (p->jointime < 1 || p->outofcoop)))) // late join or die in new coop + || (((cv_cooplives.value == 1) || !P_GetLives(p)) && p->lives <= 0))); // game over and can't redistribute lives } - else if (netgame && p->jointime < 1) - p->spectator = true; - else if (multiplayer && !netgame) + else { - // If you're in a team game and you don't have a team assigned yet... - if (G_GametypeHasTeams() && p->ctfteam == 0) + p->outofcoop = false; + if (netgame && p->jointime < 1) + p->spectator = true; + else if (multiplayer && !netgame) { - changeteam_union NetPacket; - UINT16 usvalue; - NetPacket.value.l = NetPacket.value.b = 0; + // If you're in a team game and you don't have a team assigned yet... + if (G_GametypeHasTeams() && p->ctfteam == 0) + { + changeteam_union NetPacket; + UINT16 usvalue; + NetPacket.value.l = NetPacket.value.b = 0; - // Spawn as a spectator, - // yes even in splitscreen mode - p->spectator = true; - if (playernum&1) p->skincolor = skincolor_redteam; - else p->skincolor = skincolor_blueteam; + // Spawn as a spectator, + // yes even in splitscreen mode + p->spectator = true; + if (playernum&1) p->skincolor = skincolor_redteam; + else p->skincolor = skincolor_blueteam; - // but immediately send a team change packet. - NetPacket.packet.playernum = playernum; - NetPacket.packet.verification = true; - NetPacket.packet.newteam = !(playernum&1) + 1; + // but immediately send a team change packet. + NetPacket.packet.playernum = playernum; + NetPacket.packet.verification = true; + NetPacket.packet.newteam = !(playernum&1) + 1; - usvalue = SHORT(NetPacket.value.l|NetPacket.value.b); - SendNetXCmd(XD_TEAMCHANGE, &usvalue, sizeof(usvalue)); + usvalue = SHORT(NetPacket.value.l|NetPacket.value.b); + SendNetXCmd(XD_TEAMCHANGE, &usvalue, sizeof(usvalue)); + } + else // Otherwise, never spectator. + p->spectator = false; } - else // Otherwise, never spectator. - p->spectator = false; } if (G_GametypeHasTeams()) @@ -8461,6 +9991,9 @@ void P_SpawnPlayer(INT32 playernum) p->skincolor = skincolor_blueteam; } + if ((netgame || multiplayer) && (gametype != GT_COOP || leveltime) && !p->spectator && !(maptol & TOL_NIGHTS)) + p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent + mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER); (mobj->player = p)->mo = mobj; @@ -8473,12 +10006,15 @@ void P_SpawnPlayer(INT32 playernum) // (usefulness: when body mobj is detached from player (who respawns), // the dead body mobj retains the skin through the 'spritedef' override). mobj->skin = &skins[p->skin]; + P_SetupStateAnimation(mobj, mobj->state); - mobj->health = p->health; + mobj->health = 1; + p->rings = p->spheres = 0; p->playerstate = PST_LIVE; p->bonustime = false; p->realtime = leveltime; + p->followitem = skins[p->skin].followitem; //awayview stuff p->awayviewmobj = NULL; @@ -8488,6 +10024,27 @@ void P_SpawnPlayer(INT32 playernum) P_SetScale(mobj, mobj->destscale); P_FlashPal(p, 0, 0); // Resets + // Set bounds accurately. + mobj->radius = FixedMul(skins[p->skin].radius, mobj->scale); + mobj->height = P_GetPlayerHeight(p); + + if (!leveltime && ((maptol & TOL_NIGHTS) == TOL_NIGHTS) != (G_IsSpecialStage(gamemap))) // non-special NiGHTS stage or special non-NiGHTS stage + { + if (maptol & TOL_NIGHTS) + { + if (p == players) // this is totally the wrong place to do this aaargh. + { + mobj_t *idya = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_GOTEMERALD); + idya->health = 0; // for identification + P_SetTarget(&idya->target, mobj); + P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate); + P_SetTarget(&mobj->tracer, idya); + } + } + else if (sstimer) + p->nightstime = sstimer; + } + // Spawn with a pity shield if necessary. P_DoPityCheck(p); } @@ -8502,7 +10059,7 @@ void P_AfterPlayerSpawn(INT32 playernum) else if (playernum == secondarydisplayplayer) localangle2 = mobj->angle; - p->viewheight = cv_viewheight.value<<FRACBITS; + p->viewheight = 41*p->height/48; if (p->mo->eflags & MFE_VERTICALFLIP) p->viewz = p->mo->z + p->mo->height - p->viewheight; @@ -8521,6 +10078,7 @@ void P_AfterPlayerSpawn(INT32 playernum) } SV_SpawnPlayer(playernum, mobj->x, mobj->y, mobj->angle); + p->drawangle = mobj->angle; if (camera.chase) { @@ -8684,6 +10242,7 @@ void P_SpawnMapThing(mapthing_t *mthing) mobj_t *mobj; fixed_t x, y, z; subsector_t *ss; + boolean doangle = true; if (!mthing->type) return; // Ignore type-0 things as NOPs @@ -8744,19 +10303,21 @@ void P_SpawnMapThing(mapthing_t *mthing) else if (mthing->type == 750) // Slope vertex point (formerly chaos spawn) return; - else if (mthing->type == 300 // Ring - || mthing->type == 308 || mthing->type == 309 // Team Rings - || mthing->type == 1706 // Nights Wing - || (mthing->type >= 600 && mthing->type <= 609) // Placement patterns - || mthing->type == 1705 || mthing->type == 1713 // NiGHTS Hoops - || mthing->type == 1800) // Mario Coin + else if (mthing->type == mobjinfo[MT_RING].doomednum || mthing->type == mobjinfo[MT_COIN].doomednum + || mthing->type == mobjinfo[MT_REDTEAMRING].doomednum || mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum + || mthing->type == mobjinfo[MT_BLUESPHERE].doomednum || mthing->type == mobjinfo[MT_BOMBSPHERE].doomednum + || (mthing->type >= 600 && mthing->type <= 609) // circles and diagonals + || mthing->type == 1705 || mthing->type == 1713) // hoops { // Don't spawn hoops, wings, or rings yet! return; } // check for players specially - if (mthing->type > 0 && mthing->type <= 32) +#if MAXPLAYERS > 32 +You should think about modifying the deathmatch starts to take full advantage of this! +#endif + if (mthing->type > 0 && mthing->type <= MAXPLAYERS) { // save spots for respawning in network games if (!metalrecording) @@ -8784,7 +10345,7 @@ void P_SpawnMapThing(mapthing_t *mthing) } if (metalrecording) // Metal Sonic can't use these things. - if (mobjinfo[i].flags & (MF_ENEMY|MF_BOSS) || i == MT_EMMY || i == MT_STARPOST) + if (mobjinfo[i].flags & (MF_ENEMY|MF_BOSS) || i == MT_TOKEN || i == MT_STARPOST) return; if (i >= MT_EMERALD1 && i <= MT_EMERALD7) // Pickupable Emeralds @@ -8799,10 +10360,6 @@ void P_SpawnMapThing(mapthing_t *mthing) return; } - if (!G_RingSlingerGametype() || !cv_specialrings.value) - if (P_WeaponOrPanel(i)) - return; // Don't place weapons/panels in non-ringslinger modes - if (i == MT_EMERHUNT) { // Emerald Hunt is Coop only. @@ -8836,45 +10393,48 @@ void P_SpawnMapThing(mapthing_t *mthing) if ((mobjinfo[i].flags & MF_ENEMY) || (mobjinfo[i].flags & MF_BOSS)) return; - // Set powerup boxes to user settings for competition. - if (gametype == GT_COMPETITION) + if (!G_RingSlingerGametype() || !cv_specialrings.value) + if (P_WeaponOrPanel(i)) + return; // Don't place weapons/panels in non-ringslinger modes + + // Altering monitor spawns via cvars + // If MF_GRENADEBOUNCE is set in the monitor's info, + // skip this step. (Used for gold monitors) + // Yeah, this is a dirty hack. + if ((mobjinfo[i].flags & (MF_MONITOR|MF_GRENADEBOUNCE)) == MF_MONITOR) { - if ((mobjinfo[i].flags & MF_MONITOR) && cv_competitionboxes.value) // not Normal + if (gametype == GT_COMPETITION || gametype == GT_RACE) { - if (cv_competitionboxes.value == 1) // Random - i = MT_QUESTIONBOX; - else if (cv_competitionboxes.value == 2) // Teleports - i = MT_MIXUPBOX; + // Set powerup boxes to user settings for competition. + if (cv_competitionboxes.value == 1) // Mystery + i = MT_MYSTERY_BOX; + else if (cv_competitionboxes.value == 2) // Teleport + i = MT_MIXUP_BOX; else if (cv_competitionboxes.value == 3) // None return; // Don't spawn! + // default case: normal } - } - - // Set powerup boxes to user settings for other netplay modes - else if (gametype != GT_COOP) - { - if ((mobjinfo[i].flags & MF_MONITOR) && cv_matchboxes.value) // not Normal + // Set powerup boxes to user settings for other netplay modes + else if (gametype != GT_COOP) { - if (cv_matchboxes.value == 1) // Random - i = MT_QUESTIONBOX; - else if (cv_matchboxes.value == 3) // Don't spawn - return; - else // cv_matchboxes.value == 2, Non-Random + if (cv_matchboxes.value == 1) // Mystery + i = MT_MYSTERY_BOX; + else if (cv_matchboxes.value == 2) // Unchanging { - if (i == MT_QUESTIONBOX) - return; // don't spawn in Non-Random - + if (i == MT_MYSTERY_BOX) + return; // don't spawn mthing->options &= ~(MTF_AMBUSH|MTF_OBJECTSPECIAL); // no random respawning! } + else if (cv_matchboxes.value == 3) // Don't spawn + return; + // default case: normal } } if (gametype != GT_CTF) // CTF specific things { - if (i == MT_BLUETEAMRING || i == MT_REDTEAMRING) - i = MT_RING; - else if (i == MT_BLUERINGBOX || i == MT_REDRINGBOX) - i = MT_SUPERRINGBOX; + if (i == MT_RING_BLUEBOX || i == MT_RING_REDBOX) + i = MT_RING_BOX; else if (i == MT_BLUEFLAG || i == MT_REDFLAG) return; // No flags in non-CTF modes! } @@ -8896,33 +10456,35 @@ void P_SpawnMapThing(mapthing_t *mthing) if (i == MT_STARPOST) return; - // Emerald Tokens -->> Score Tokens - else if (i == MT_EMMY) - return; /// \todo - // 1UPs -->> Score TVs - else if (i == MT_PRUP) // 1UP + else if (i == MT_1UP_BOX) // 1UP { // Either or, doesn't matter which. if (mthing->options & (MTF_AMBUSH|MTF_OBJECTSPECIAL)) - i = MT_SCORETVLARGE; // 10,000 + i = MT_SCORE10K_BOX; // 10,000 else - i = MT_SCORETVSMALL; // 1,000 + i = MT_SCORE1K_BOX; // 1,000 } } if (ultimatemode) { - if (i == MT_PITYTV || i == MT_GREENTV || i == MT_YELLOWTV || i == MT_BLUETV || i == MT_BLACKTV || i == MT_WHITETV) - return; // No shields in Ultimate mode + if (i == MT_PITY_BOX || i == MT_ELEMENTAL_BOX || i == MT_ATTRACT_BOX + || i == MT_FORCE_BOX || i == MT_ARMAGEDDON_BOX || i == MT_WHIRLWIND_BOX + || i == MT_FLAMEAURA_BOX || i == MT_BUBBLEWRAP_BOX || i == MT_THUNDERCOIN_BOX + || i == MT_RING_BOX) + return; // No rings or shields in Ultimate mode - if (i == MT_SUPERRINGBOX && !G_IsSpecialStage(gamemap)) - return; // No rings in Ultimate mode (except special stages) + // Don't include the gold repeating boxes here please. + // They're likely facets of the level's design and therefore required to progress. } - if (i == MT_EMMY && (gametype != GT_COOP || ultimatemode || tokenbits == 30 || tokenlist & (1 << tokenbits++))) + if (i == MT_TOKEN && ((gametype != GT_COOP && gametype != GT_COMPETITION) || ultimatemode || tokenbits == 30 || tokenlist & (1 << tokenbits++))) return; // you already got this token, or there are too many, or the gametype's not right + if (i == MT_EMBLEM && (netgame || multiplayer || (modifiedgame && !savemoddata))) // No cheating!! + return; + // Objectplace landing point noreturns: @@ -8939,7 +10501,7 @@ void P_SpawnMapThing(mapthing_t *mthing) ss->sector->floorheight) + ((mthing->options >> ZSHIFT) << FRACBITS); else if (i == MT_AXIS || i == MT_AXISTRANSFER || i == MT_AXISTRANSFERLINE) z = ONFLOORZ; - else if (i == MT_SPECIALSPIKEBALL || P_WeaponOrPanel(i) || i == MT_EMERALDSPAWN || i == MT_EMMY) + else if (i == MT_SPIKEBALL || P_WeaponOrPanel(i) || i == MT_EMERALDSPAWN || i == MT_TOKEN || i == MT_EMBLEM) { if (mthing->options & MTF_OBJECTFLIP) { @@ -9029,14 +10591,79 @@ void P_SpawnMapThing(mapthing_t *mthing) mobj = P_SpawnMobj(x, y, z, i); mobj->spawnpoint = mthing; +#ifdef HAVE_BLUA + if (LUAh_MapThingSpawn(mobj, mthing)) + { + if (P_MobjWasRemoved(mobj)) + return; + } + else if (P_MobjWasRemoved(mobj)) + return; + else +#endif switch(mobj->type) { + case MT_EMBLEM: + { + INT32 j; + emblem_t *emblem = M_GetLevelEmblems(gamemap); + skincolors_t emcolor; + + while (emblem) + { + if ((emblem->type == ET_GLOBAL || emblem->type == ET_SKIN) && emblem->tag == mthing->angle) + break; + + emblem = M_GetLevelEmblems(-1); + } + + if (!emblem) + { + CONS_Debug(DBG_GAMELOGIC, "No map emblem for map %d with tag %d found!\n", gamemap, mthing->angle); + break; + } + + j = emblem - emblemlocations; + + I_Assert(emblemlocations[j].sprite >= 'A' && emblemlocations[j].sprite <= 'Z'); + P_SetMobjState(mobj, mobj->info->spawnstate + (emblemlocations[j].sprite - 'A')); + + mobj->health = j + 1; + emcolor = M_GetEmblemColor(&emblemlocations[j]); // workaround for compiler complaint about bad function casting + mobj->color = (UINT8)emcolor; + + if (emblemlocations[j].collected + || (emblemlocations[j].type == ET_SKIN && emblemlocations[j].var != players[0].skin)) + { + P_UnsetThingPosition(mobj); + mobj->flags |= MF_NOCLIP; + mobj->flags &= ~MF_SPECIAL; + mobj->flags |= MF_NOBLOCKMAP; + mobj->frame |= (tr_trans50 << FF_TRANSSHIFT); + P_SetThingPosition(mobj); + } + else + { + mobj->frame &= ~FF_TRANSMASK; + + if (emblemlocations[j].type == ET_GLOBAL) + { + mobj->reactiontime = emblemlocations[j].var; + if (emblemlocations[j].var & GE_NIGHTSITEM) + { + mobj->flags |= MF_NIGHTSITEM; + mobj->flags &= ~MF_SPECIAL; + mobj->flags2 |= MF2_DONTDRAW; + } + } + } + break; + } case MT_SKYBOX: - mobj->angle = 0; if (mthing->options & MTF_OBJECTSPECIAL) - skyboxmo[1] = mobj; + skyboxcenterpnts[mthing->extrainfo] = mobj; else - skyboxmo[0] = mobj; + skyboxviewpnts[mthing->extrainfo] = mobj; break; case MT_FAN: if (mthing->options & MTF_OBJECTSPECIAL) @@ -9055,6 +10682,58 @@ void P_SpawnMapThing(mapthing_t *mthing) else mobj->health = FixedMul(ss->sector->ceilingheight-ss->sector->floorheight, 3*(FRACUNIT/4))>>FRACBITS; break; + case MT_BALLOON: + if (mthing->angle > 0) + mobj->color = ((mthing->angle-1) % (MAXSKINCOLORS-1))+1; + break; +#define makesoftwarecorona(mo, h) \ + corona = P_SpawnMobjFromMobj(mo, 0, 0, h<<FRACBITS, MT_PARTICLE);\ + corona->sprite = SPR_FLAM;\ + corona->frame = (FF_FULLBRIGHT|FF_TRANS90|12);\ + corona->tics = -1 + case MT_FLAME: + if (mthing->options & MTF_EXTRA) + { + mobj_t *corona; + makesoftwarecorona(mobj, 20); + P_SetScale(corona, (corona->destscale = mobj->scale*3)); + P_SetTarget(&mobj->tracer, corona); + } + break; + case MT_FLAMEHOLDER: + if (!(mthing->options & MTF_OBJECTSPECIAL)) // Spawn the fire + { + mobj_t *flame = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_FLAME); + P_SetTarget(&flame->target, mobj); + flame->flags2 |= MF2_BOSSNOTRAP; + if (mthing->options & MTF_EXTRA) + { + mobj_t *corona; + makesoftwarecorona(flame, 20); + P_SetScale(corona, (corona->destscale = flame->scale*3)); + P_SetTarget(&flame->tracer, corona); + } + } + break; + case MT_CANDLE: + case MT_CANDLEPRICKET: + if (mthing->options & MTF_EXTRA) + { + mobj_t *corona; + makesoftwarecorona(mobj, ((mobj->type == MT_CANDLE) ? 42 : 176)); + } + break; +#undef makesoftwarecorona + case MT_JACKO1: + case MT_JACKO2: + case MT_JACKO3: + if (!(mthing->options & MTF_EXTRA)) // take the torch out of the crafting recipe + { + mobj_t *overlay = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY); + P_SetTarget(&overlay->target, mobj); + P_SetMobjState(overlay, mobj->info->raisestate); + } + break; case MT_WATERDRIP: if (mthing->angle) mobj->tics = 3*TICRATE + mthing->angle; @@ -9072,119 +10751,394 @@ void P_SpawnMapThing(mapthing_t *mthing) mobj->movedir = mthing->extrainfo; break; case MT_MACEPOINT: - case MT_SWINGMACEPOINT: - case MT_HANGMACEPOINT: - case MT_SPINMACEPOINT: - { - fixed_t mlength, mspeed, mxspeed, mzspeed, mstartangle, mmaxspeed; - mobjtype_t chainlink = MT_SMALLMACECHAIN; - mobjtype_t macetype = MT_SMALLMACE; - boolean firsttime; - mobj_t *spawnee; - size_t line; + case MT_CHAINMACEPOINT: + case MT_SPRINGBALLPOINT: + case MT_CHAINPOINT: + case MT_FIREBARPOINT: + case MT_CUSTOMMACEPOINT: + { + fixed_t mlength, mmaxlength, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mpinch, mroll, mnumnospokes, mwidth, mwidthset, mmin, msound, radiusfactor, widthfactor; + angle_t mspokeangle; + mobjtype_t chainlink, macetype, firsttype, linktype; + boolean mdosound, mdocenter, mchainlike = false; + mobj_t *spawnee = NULL, *hprev = mobj; + mobjflag_t mflagsapply; + mobjflag2_t mflags2apply; + mobjeflag_t meflagsapply; + INT32 line; const size_t mthingi = (size_t)(mthing - mapthings); - // Why does P_FindSpecialLineFromTag not work here?!? - // Monster Iestyn: tag lists haven't been initialised yet for the map, that's why - for (line = 0; line < numlines; line++) - { - if (lines[line].special == 9 && lines[line].tag == mthing->angle) - break; - } + // Find the corresponding linedef special, using angle as tag + // P_FindSpecialLineFromTag works here now =D + line = P_FindSpecialLineFromTag(9, mthing->angle, -1); - if (line == numlines) + if (line == -1) { - CONS_Debug(DBG_GAMELOGIC, "Mace chain (mapthing #%s) needs tagged to a #9 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle); + CONS_Debug(DBG_GAMELOGIC, "Mace chain (mapthing #%s) needs to be tagged to a #9 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle); return; } /* -No deaf - small mace -Deaf - big mace - -ML_NOCLIMB : Direction not controllable +mapthing - +MTF_AMBUSH : + MT_SPRINGBALLPOINT - upgrade from yellow to red spring + anything else - bigger mace/chain theory +MTF_OBJECTSPECIAL - force silent +MTF_GRAVFLIP - flips objects, doesn't affect chain arrangements +Parameter value : number of "spokes" + +linedef - +ML_NOCLIMB : + MT_CHAINPOINT/MT_CHAINMACEPOINT with ML_EFFECT1 applied - Direction not controllable + anything else - no functionality +ML_EFFECT1 : Swings instead of spins +ML_EFFECT2 : Linktype is replaced with macetype for all spokes not ending in chains (inverted for MT_FIREBARPOINT) +ML_EFFECT3 : Spawn a bonus linktype at the hinge point +ML_EFFECT4 : Don't clip inside the ground +ML_EFFECT5 : Don't stop thinking when too far away */ mlength = abs(lines[line].dx >> FRACBITS); - mspeed = abs(lines[line].dy >> FRACBITS); - mxspeed = sides[lines[line].sidenum[0]].textureoffset >> FRACBITS; - mzspeed = sides[lines[line].sidenum[0]].rowoffset >> FRACBITS; - mstartangle = lines[line].frontsector->floorheight >> FRACBITS; - mmaxspeed = lines[line].frontsector->ceilingheight >> FRACBITS; - - mstartangle %= 360; - mxspeed %= 360; - mzspeed %= 360; - - CONS_Debug(DBG_GAMELOGIC, "Mace Chain (mapthing #%s):\n" - "Length is %d\n" + mspeed = abs(lines[line].dy >> (FRACBITS - 4)); + mphase = (sides[lines[line].sidenum[0]].textureoffset >> FRACBITS) % 360; + if ((mminlength = -sides[lines[line].sidenum[0]].rowoffset>>FRACBITS) < 0) + mminlength = 0; + else if (mminlength > mlength-1) + mminlength = mlength-1; + mpitch = (lines[line].frontsector->floorheight >> FRACBITS) % 360; + myaw = (lines[line].frontsector->ceilingheight >> FRACBITS) % 360; + + mnumspokes = mthing->extrainfo + 1; + mspokeangle = FixedAngle((360*FRACUNIT)/mnumspokes)>>ANGLETOFINESHIFT; + + if (lines[line].backsector) + { + mpinch = (lines[line].backsector->floorheight >> FRACBITS) % 360; + mroll = (lines[line].backsector->ceilingheight >> FRACBITS) % 360; + mnumnospokes = (sides[lines[line].sidenum[1]].textureoffset >> FRACBITS); + if ((mwidth = sides[lines[line].sidenum[1]].rowoffset >> FRACBITS) < 0) + mwidth = 0; + } + else + mpinch = mroll = mnumnospokes = mwidth = 0; + + CONS_Debug(DBG_GAMELOGIC, "Mace/Chain (mapthing #%s):\n" + "Length is %d (minus %d)\n" "Speed is %d\n" - "Xspeed is %d\n" - "Zspeed is %d\n" - "startangle is %d\n" - "maxspeed is %d\n", - sizeu1(mthingi), mlength, mspeed, mxspeed, mzspeed, mstartangle, mmaxspeed); + "Phase is %d\n" + "Yaw is %d\n" + "Pitch is %d\n" + "No. of spokes is %d (%d antispokes)\n" + "Pinch is %d\n" + "Roll is %d\n" + "Width is %d\n", + sizeu1(mthingi), mlength, mminlength, mspeed, mphase, myaw, mpitch, mnumspokes, mnumnospokes, mpinch, mroll, mwidth); + + if (mnumnospokes > 0 && (mnumnospokes < mnumspokes)) + mnumnospokes = mnumspokes/mnumnospokes; + else + mnumnospokes = ((mobj->type == MT_CHAINMACEPOINT) ? (mnumspokes) : 0); - mobj->lastlook = mspeed << 4; + mobj->lastlook = mspeed; mobj->movecount = mobj->lastlook; - mobj->health = (FixedAngle(mzspeed*FRACUNIT)>>ANGLETOFINESHIFT) + (FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT); - mobj->threshold = (FixedAngle(mxspeed*FRACUNIT)>>ANGLETOFINESHIFT) + (FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT); - mobj->movefactor = mobj->threshold; - mobj->friction = mmaxspeed; + mobj->angle = FixedAngle(myaw*FRACUNIT); + doangle = false; + mobj->threshold = (FixedAngle(mpitch*FRACUNIT)>>ANGLETOFINESHIFT); + mobj->movefactor = mpinch; + mobj->movedir = 0; + + // Mobjtype selection + switch(mobj->type) + { + case MT_SPRINGBALLPOINT: + macetype = ((mthing->options & MTF_AMBUSH) + ? MT_REDSPRINGBALL + : MT_YELLOWSPRINGBALL); + chainlink = MT_SMALLMACECHAIN; + break; + case MT_FIREBARPOINT: + macetype = ((mthing->options & MTF_AMBUSH) + ? MT_BIGFIREBAR + : MT_SMALLFIREBAR); + chainlink = MT_NULL; + break; + case MT_CUSTOMMACEPOINT: + macetype = (mobjtype_t)sides[lines[line].sidenum[0]].toptexture; + if (lines[line].backsector) + chainlink = (mobjtype_t)sides[lines[line].sidenum[1]].toptexture; + else + chainlink = MT_NULL; + break; + case MT_CHAINPOINT: + if (mthing->options & MTF_AMBUSH) + { + macetype = MT_BIGGRABCHAIN; + chainlink = MT_BIGMACECHAIN; + } + else + { + macetype = MT_SMALLGRABCHAIN; + chainlink = MT_SMALLMACECHAIN; + } + mchainlike = true; + break; + default: + if (mthing->options & MTF_AMBUSH) + { + macetype = MT_BIGMACE; + chainlink = MT_BIGMACECHAIN; + } + else + { + macetype = MT_SMALLMACE; + chainlink = MT_SMALLMACECHAIN; + } + break; + } + + if (!macetype && !chainlink) + break; + + if (mobj->type == MT_CHAINPOINT) + { + if (!mlength) + break; + } + else + mlength++; + firsttype = macetype; + + // Adjustable direction if (lines[line].flags & ML_NOCLIMB) mobj->flags |= MF_SLIDEME; - mobj->reactiontime = 0; - - if (mthing->options & MTF_AMBUSH) + // Swinging + if (lines[line].flags & ML_EFFECT1) { - chainlink = MT_BIGMACECHAIN; - macetype = MT_BIGMACE; + mobj->flags2 |= MF2_STRONGBOX; + mmin = ((mnumnospokes > 1) ? 1 : 0); } + else + mmin = mnumspokes; - if (mthing->options & MTF_OBJECTSPECIAL) - mobj->flags2 |= MF2_BOSSNOTRAP; // shut up maces. + // If over distance away, don't move UNLESS this flag is applied + if (lines[line].flags & ML_EFFECT5) + mobj->flags2 |= MF2_BOSSNOTRAP; - if (mobj->type == MT_HANGMACEPOINT || mobj->type == MT_SPINMACEPOINT) - firsttime = true; + // Make the links the same type as the end - repeated below + if ((mobj->type != MT_CHAINPOINT) && (((lines[line].flags & ML_EFFECT2) == ML_EFFECT2) != (mobj->type == MT_FIREBARPOINT))) // exclusive or + { + linktype = macetype; + radiusfactor = 2; // Double the radius. + } else + radiusfactor = (((linktype = chainlink) == MT_NULL) ? 2 : 1); + + if (!mchainlike) + mchainlike = (firsttype == chainlink); + widthfactor = (mchainlike ? 1 : 2); + + mflagsapply = ((lines[line].flags & ML_EFFECT4) ? 0 : (MF_NOCLIP|MF_NOCLIPHEIGHT)); + mflags2apply = ((mthing->options & MTF_OBJECTFLIP) ? MF2_OBJECTFLIP : 0); + meflagsapply = ((mthing->options & MTF_OBJECTFLIP) ? MFE_VERTICALFLIP : 0); + + msound = (mchainlike ? 0 : (mwidth & 1)); + + // Quick and easy preparatory variable setting + mphase = (FixedAngle(mphase*FRACUNIT)>>ANGLETOFINESHIFT); + mroll = (FixedAngle(mroll*FRACUNIT)>>ANGLETOFINESHIFT); + +#define makemace(mobjtype, dist, moreflags2) {\ + spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobjtype);\ + P_SetTarget(&spawnee->tracer, mobj);\ + spawnee->threshold = mphase;\ + spawnee->friction = mroll;\ + spawnee->movefactor = mwidthset;\ + spawnee->movecount = dist;\ + spawnee->angle = myaw;\ + spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\ + spawnee->flags2 |= (mflags2apply|moreflags2);\ + spawnee->eflags |= meflagsapply;\ + P_SetTarget(&hprev->hnext, spawnee);\ + P_SetTarget(&spawnee->hprev, hprev);\ + hprev = spawnee;\ +} + + mdosound = (mspeed && !(mthing->options & MTF_OBJECTSPECIAL)); + mdocenter = (macetype && (lines[line].flags & ML_EFFECT3)); + + // The actual spawning of spokes + while (mnumspokes-- > 0) { - firsttime = false; + // Offsets + if (lines[line].flags & ML_EFFECT1) // Swinging + mroll = (mroll - mspokeangle) & FINEMASK; + else // Spinning + mphase = (mphase - mspokeangle) & FINEMASK; - spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, macetype); - P_SetTarget(&spawnee->target, mobj); + if (mnumnospokes && !(mnumspokes % mnumnospokes)) // Skipping a "missing" spoke + { + if (mobj->type != MT_CHAINMACEPOINT) + continue; - if (mobj->type == MT_SWINGMACEPOINT) - spawnee->movecount = FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT; + linktype = chainlink; + firsttype = ((mthing->options & MTF_AMBUSH) ? MT_BIGGRABCHAIN : MT_SMALLGRABCHAIN); + mmaxlength = 1 + (mlength - 1)*radiusfactor; + radiusfactor = widthfactor = 1; + } else - spawnee->movecount = 0; + { + if (mobj->type == MT_CHAINMACEPOINT) + { + // Make the links the same type as the end - repeated above + if (lines[line].flags & ML_EFFECT2) + { + linktype = macetype; + radiusfactor = 2; + } + else + radiusfactor = (((linktype = chainlink) == MT_NULL) ? 2 : 1); - spawnee->threshold = FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT; - spawnee->reactiontime = mlength+1; - } + firsttype = macetype; + widthfactor = 2; + } - while (mlength > 0) - { - spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, chainlink); + mmaxlength = mlength; + } - P_SetTarget(&spawnee->target, mobj); + mwidthset = mwidth; + mlengthset = mminlength; - if (mobj->type == MT_HANGMACEPOINT || mobj->type == MT_SWINGMACEPOINT) - spawnee->movecount = FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT; + if (mdocenter) // Innermost link + makemace(linktype, 0, 0); + + // Out from the center... + if (linktype) + { + while ((++mlengthset) < mmaxlength) + makemace(linktype, radiusfactor*mlengthset, 0); + } else - spawnee->movecount = 0; + mlengthset = mmaxlength; - spawnee->threshold = FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT; - spawnee->reactiontime = mlength; + // Outermost mace/link + if (firsttype) + makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); - if (firsttime) + if (!mwidth) + { + if (mdosound && mnumspokes <= mmin) // Can it make a sound? + spawnee->flags2 |= MF2_BOSSNOTRAP; + } + else { - // This is the outermost link in the chain - spawnee->flags |= MF_AMBUSH; - firsttime = false; + // Across the bar! + if (!firsttype) + mwidthset = -mwidth; + else if (mwidth > 0) + { + while ((mwidthset -= widthfactor) > -mwidth) + { + makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); + if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? + spawnee->flags2 |= MF2_BOSSNOTRAP; + } + } + else + { + while ((mwidthset += widthfactor) < -mwidth) + { + makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); + if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? + spawnee->flags2 |= MF2_BOSSNOTRAP; + } + } + mwidth = -mwidth; + + // Outermost mace/link again! + if (firsttype) + makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH); + + // ...and then back into the center! + if (linktype) + while (mlengthset > mminlength) + makemace(linktype, radiusfactor*(mlengthset--), 0); + + if (mdocenter) // Innermost link + makemace(linktype, 0, 0); } + } + +#undef makemace + + break; + } + case MT_PARTICLEGEN: + { + fixed_t radius, speed; + INT32 type, numdivisions, anglespeed, ticcount; + angle_t angledivision; + INT32 line; + const size_t mthingi = (size_t)(mthing - mapthings); + + // Find the corresponding linedef special, using angle as tag + line = P_FindSpecialLineFromTag(15, mthing->angle, -1); + + if (line == -1) + { + CONS_Debug(DBG_GAMELOGIC, "Particle generator (mapthing #%s) needs to be tagged to a #15 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle); + return; + } + + if (sides[lines[line].sidenum[0]].toptexture) + type = sides[lines[line].sidenum[0]].toptexture; // Set as object type in p_setup.c... + else + type = (INT32)MT_PARTICLE; - mlength--; + if (!lines[line].backsector + || (ticcount = (sides[lines[line].sidenum[1]].textureoffset >> FRACBITS)) < 1) + ticcount = 3; + + numdivisions = (mthing->options >> ZSHIFT); + + if (numdivisions) + { + radius = R_PointToDist2(lines[line].v1->x, lines[line].v1->y, lines[line].v2->x, lines[line].v2->y); + anglespeed = (sides[lines[line].sidenum[0]].rowoffset >> FRACBITS) % 360; + angledivision = 360/numdivisions; + } + else + { + numdivisions = 1; // Simple trick to make A_ParticleSpawn simpler. + radius = 0; + anglespeed = 0; + angledivision = 0; } + + speed = abs(sides[lines[line].sidenum[0]].textureoffset); + if (mthing->options & MTF_OBJECTFLIP) + speed *= -1; + + CONS_Debug(DBG_GAMELOGIC, "Particle Generator (mapthing #%s):\n" + "Radius is %d\n" + "Speed is %d\n" + "Anglespeed is %d\n" + "Numdivisions is %d\n" + "Angledivision is %d\n" + "Type is %d\n" + "Tic seperation is %d\n", + sizeu1(mthingi), radius, speed, anglespeed, numdivisions, angledivision, type, ticcount); + + mobj->angle = 0; + mobj->movefactor = speed; + mobj->lastlook = numdivisions; + mobj->movedir = angledivision*ANG1; + mobj->movecount = anglespeed*ANG1; + mobj->friction = radius; + mobj->threshold = type; + mobj->reactiontime = ticcount; + mobj->cvmem = line; + mobj->watertop = mobj->waterbottom = 0; + break; } case MT_ROCKSPAWNER: @@ -9214,9 +11168,130 @@ ML_NOCLIMB : Direction not controllable mobj->health = mthing->angle & 255; mobj->threshold = mthing->angle >> 8; break; - case MT_NIGHTSDRONE: - if (mthing->angle > 0) - mobj->health = mthing->angle; + case MT_IDEYAANCHOR: + mobj->health = mthing->extrainfo; + break; + case MT_NIGHTSDRONE: + { + boolean flip = mthing->options & MTF_OBJECTFLIP; + boolean topaligned = (mthing->options & MTF_OBJECTSPECIAL) && !(mthing->options & MTF_EXTRA); + boolean middlealigned = (mthing->options & MTF_EXTRA) && !(mthing->options & MTF_OBJECTSPECIAL); + boolean bottomoffsetted = !(mthing->options & MTF_OBJECTSPECIAL) && !(mthing->options & MTF_EXTRA); + + INT16 timelimit = mthing->angle & 0xFFF; + fixed_t hitboxradius = ((mthing->angle & 0xF000) >> 12) * 32 * FRACUNIT; + fixed_t hitboxheight = mthing->extrainfo * 32 * FRACUNIT; + fixed_t oldheight = mobj->height; + fixed_t dronemanoffset, goaloffset, sparkleoffset, droneboxmandiff, dronemangoaldiff; + + if (timelimit > 0) + mobj->health = timelimit; + + if (hitboxradius > 0) + mobj->radius = hitboxradius; + + if (hitboxheight > 0) + mobj->height = hitboxheight; + else + mobj->height = mobjinfo[MT_NIGHTSDRONE].height; + + droneboxmandiff = max(mobj->height - mobjinfo[MT_NIGHTSDRONE_MAN].height, 0); + dronemangoaldiff = max(mobjinfo[MT_NIGHTSDRONE_MAN].height - mobjinfo[MT_NIGHTSDRONE_GOAL].height, 0); + + if (flip && mobj->height != oldheight) + P_TeleportMove(mobj, mobj->x, mobj->y, mobj->z - (mobj->height - oldheight)); + + if (!flip) + { + if (topaligned) // Align droneman to top of hitbox + { + dronemanoffset = droneboxmandiff; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (middlealigned) // Align droneman to center of hitbox + { + dronemanoffset = droneboxmandiff / 2; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (bottomoffsetted) + { + dronemanoffset = 24*FRACUNIT; + goaloffset = dronemangoaldiff + dronemanoffset; + } + else + { + dronemanoffset = 0; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + + sparkleoffset = goaloffset - FixedMul(15*FRACUNIT, mobj->scale); + } + else + { + mobj->eflags |= MFE_VERTICALFLIP; + mobj->flags2 |= MF2_OBJECTFLIP; + + if (topaligned) // Align droneman to top of hitbox + { + dronemanoffset = 0; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (middlealigned) // Align droneman to center of hitbox + { + dronemanoffset = droneboxmandiff / 2; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (bottomoffsetted) + { + dronemanoffset = droneboxmandiff - FixedMul(24*FRACUNIT, mobj->scale); + goaloffset = dronemangoaldiff + dronemanoffset; + } + else + { + dronemanoffset = droneboxmandiff; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + + sparkleoffset = goaloffset + FixedMul(15*FRACUNIT, mobj->scale); + } + + // spawn visual elements + { + mobj_t *goalpost = P_SpawnMobjFromMobj(mobj, 0, 0, goaloffset, MT_NIGHTSDRONE_GOAL); + mobj_t *sparkle = P_SpawnMobjFromMobj(mobj, 0, 0, sparkleoffset, MT_NIGHTSDRONE_SPARKLING); + mobj_t *droneman = P_SpawnMobjFromMobj(mobj, 0, 0, dronemanoffset, MT_NIGHTSDRONE_MAN); + + P_SetTarget(&mobj->target, goalpost); + P_SetTarget(&goalpost->target, sparkle); + P_SetTarget(&goalpost->tracer, droneman); + + // correct Z position + if (flip) + { + P_TeleportMove(goalpost, goalpost->x, goalpost->y, mobj->z + goaloffset); + P_TeleportMove(sparkle, sparkle->x, sparkle->y, mobj->z + sparkleoffset); + P_TeleportMove(droneman, droneman->x, droneman->y, mobj->z + dronemanoffset); + } + + // Remember position preference for later + mobj->flags &= ~(MF_SLIDEME | MF_GRENADEBOUNCE); + if (topaligned) + mobj->flags |= MF_SLIDEME; + else if (middlealigned) + mobj->flags |= MF_GRENADEBOUNCE; + else if (!bottomoffsetted) + mobj->flags |= MF_SLIDEME | MF_GRENADEBOUNCE; + + // Remember old Z position and flags for correction detection + goalpost->movefactor = mobj->z; + goalpost->friction = mobj->height; + goalpost->threshold = mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE); + } + } + break; + case MT_HIVEELEMENTAL: + if (mthing->extrainfo) + mobj->extravalue1 = mthing->extrainfo; break; case MT_TRAPGOYLE: case MT_TRAPGOYLEUP: @@ -9224,6 +11299,52 @@ ML_NOCLIMB : Direction not controllable case MT_TRAPGOYLELONG: if (mthing->angle >= 360) mobj->tics += 7*(mthing->angle / 360) + 1; // starting delay + break; + case MT_DSZSTALAGMITE: + case MT_DSZ2STALAGMITE: + case MT_KELP: + if (mthing->options & MTF_OBJECTSPECIAL) { // make mobj twice as big as normal + P_SetScale(mobj, 2*mobj->scale); // not 2*FRACUNIT in case of something like the old ERZ3 mode + mobj->destscale = mobj->scale; + } + break; + case MT_THZTREE: + { // Spawn the branches + angle_t mobjangle = FixedAngle((mthing->angle % 113)<<FRACBITS); + P_SpawnMobjFromMobj(mobj, 1*FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_22h; + P_SpawnMobjFromMobj(mobj, 0, 1*FRACUNIT, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_157h; + P_SpawnMobjFromMobj(mobj, -1*FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_270; + } + break; + case MT_CEZPOLE: + { // Spawn the banner + angle_t mobjangle = FixedAngle(mthing->angle<<FRACBITS); + P_SpawnMobjFromMobj(mobj, + P_ReturnThrustX(mobj, mobjangle, 4<<FRACBITS), + P_ReturnThrustY(mobj, mobjangle, 4<<FRACBITS), + 0, MT_CEZBANNER)->angle = mobjangle + ANGLE_90; + } + break; + case MT_HHZTREE_TOP: + { // Spawn the branches + angle_t mobjangle = FixedAngle(mthing->angle<<FRACBITS) & (ANGLE_90-1); + mobj_t *leaf; +#define doleaf(x, y) \ + leaf = P_SpawnMobjFromMobj(mobj, x, y, 0, MT_HHZTREE_PART);\ + leaf->angle = mobjangle;\ + P_SetMobjState(leaf, leaf->info->seestate);\ + mobjangle += ANGLE_90 + doleaf(1*FRACUNIT, 0); + doleaf(0, 1*FRACUNIT); + doleaf(-1*FRACUNIT, 0); + doleaf(0, -1*FRACUNIT); +#undef doleaf + } + break; + case MT_SMASHINGSPIKEBALL: + if (mthing->angle > 0) + mobj->tics += mthing->angle; + break; default: break; } @@ -9248,35 +11369,14 @@ ML_NOCLIMB : Direction not controllable { // Inverted if uppermost bit is set if (mthing->angle & 16384) - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; if (mthing->angle > 0) mobj->radius = (mthing->angle & 16383)*FRACUNIT; } } - else if (i == MT_EMMY) + else if (i == MT_TOKEN) { - if (mthing->options & MTF_OBJECTSPECIAL) // Mario Block version - mobj->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); - else - { - fixed_t zheight = mobj->z; - mobj_t *tokenobj; - - if (mthing->options & MTF_OBJECTFLIP) - zheight += mobj->height-FixedMul(mobjinfo[MT_TOKEN].height, mobj->scale); // align with emmy properly! - - tokenobj = P_SpawnMobj(x, y, zheight, MT_TOKEN); - P_SetTarget(&mobj->tracer, tokenobj); - tokenobj->destscale = mobj->scale; - P_SetScale(tokenobj, mobj->scale); - if (mthing->options & MTF_OBJECTFLIP) // flip token to match emmy - { - tokenobj->eflags |= MFE_VERTICALFLIP; - tokenobj->flags2 |= MF2_OBJECTFLIP; - } - } - // We advanced tokenbits earlier due to the return check. // Subtract 1 here for the correct value. mobj->health = 1 << (tokenbits - 1); @@ -9286,7 +11386,7 @@ ML_NOCLIMB : Direction not controllable mobj_t *elecmobj; elecmobj = P_SpawnMobj(x, y, z, MT_CYBRAKDEMON_ELECTRIC_BARRIER); P_SetTarget(&elecmobj->target, mobj); - elecmobj->angle = FixedAngle(mthing->angle*FRACUNIT);; + elecmobj->angle = FixedAngle(mthing->angle<<FRACBITS);; elecmobj->destscale = mobj->scale*2; P_SetScale(elecmobj, elecmobj->destscale); } @@ -9324,10 +11424,12 @@ ML_NOCLIMB : Direction not controllable if (mthing->options & MTF_OBJECTSPECIAL) { mobj->flags &= ~MF_SCENERY; - mobj->fuse = mthing->angle + mobj->info->speed; + mobj->fuse = (16 - mthing->extrainfo) * (mthing->angle + mobj->info->speed) / 16; + if (mthing->options & MTF_EXTRA) + P_SetMobjState(mobj, mobj->info->meleestate); } - // Use per-thing collision for spikes if the deaf flag is checked. - if (mthing->options & MTF_AMBUSH && !metalrecording) + // Use per-thing collision for spikes if the deaf flag isn't checked. + if (!(mthing->options & MTF_AMBUSH) && !metalrecording) { P_UnsetThingPosition(mobj); mobj->flags &= ~(MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT); @@ -9335,9 +11437,43 @@ ML_NOCLIMB : Direction not controllable P_SetThingPosition(mobj); } } + else if (i == MT_WALLSPIKE) + { + // Pop up spikes! + if (mthing->options & MTF_OBJECTSPECIAL) + { + mobj->flags &= ~MF_SCENERY; + mobj->fuse = (16 - mthing->extrainfo) * ((mthing->angle/360) + mobj->info->speed) / 16; + if (mthing->options & MTF_EXTRA) + P_SetMobjState(mobj, mobj->info->meleestate); + } + // Use per-thing collision for spikes if the deaf flag isn't checked. + if (!(mthing->options & MTF_AMBUSH) && !metalrecording) + { + P_UnsetThingPosition(mobj); + mobj->flags &= ~(MF_NOBLOCKMAP|MF_NOCLIPHEIGHT); + mobj->flags |= MF_SOLID; + P_SetThingPosition(mobj); + } + + // spawn base + { + const angle_t mobjangle = FixedAngle(mthing->angle<<FRACBITS); // the mobj's own angle hasn't been set quite yet so... + const fixed_t baseradius = mobj->radius - mobj->scale; + mobj_t *base = P_SpawnMobj( + mobj->x - P_ReturnThrustX(mobj, mobjangle, baseradius), + mobj->y - P_ReturnThrustY(mobj, mobjangle, baseradius), + mobj->z, MT_WALLSPIKEBASE); + base->angle = mobjangle + ANGLE_90; + base->destscale = mobj->destscale; + P_SetScale(base, mobj->scale); + P_SetTarget(&base->target, mobj); + P_SetTarget(&mobj->tracer, base); + } + } //count 10 ring boxes into the number of rings equation too. - if (i == MT_SUPERRINGBOX) + if (i == MT_RING_BOX && nummaprings >= 0) nummaprings += 10; if (i == MT_BIGTUMBLEWEED || i == MT_LITTLETUMBLEWEED) @@ -9389,16 +11525,16 @@ ML_NOCLIMB : Direction not controllable } } + if (doangle) + mobj->angle = FixedAngle(mthing->angle<<FRACBITS); + // ignore MTF_ flags and return early if (i == MT_NIGHTSBUMPER) { - mobj->angle = FixedAngle(mthing->angle*FRACUNIT); mthing->mobj = mobj; return; } - mobj->angle = FixedAngle(mthing->angle*FRACUNIT); - if ((mthing->options & MTF_AMBUSH) && (mthing->options & MTF_OBJECTSPECIAL) && (mobj->flags & MF_PUSHABLE)) @@ -9415,25 +11551,16 @@ ML_NOCLIMB : Direction not controllable // Spawn already displayed mobj->flags |= MF_SPECIAL; mobj->flags &= ~MF_NIGHTSITEM; - P_SetMobjState(mobj, mobj->info->seestate); } if (mobj->flags & MF_PUSHABLE) - { mobj->flags &= ~MF_PUSHABLE; - mobj->flags2 |= MF2_STANDONME; - } - if (mobj->flags & MF_MONITOR) + if ((mobj->flags & MF_MONITOR) && mobj->info->speed != 0) { // flag for strong/weak random boxes - if (mthing->type == mobjinfo[MT_SUPERRINGBOX].doomednum || mthing->type == mobjinfo[MT_PRUP].doomednum || - mthing->type == mobjinfo[MT_SNEAKERTV].doomednum || mthing->type == mobjinfo[MT_INV].doomednum || - mthing->type == mobjinfo[MT_WHITETV].doomednum || mthing->type == mobjinfo[MT_GREENTV].doomednum || - mthing->type == mobjinfo[MT_YELLOWTV].doomednum || mthing->type == mobjinfo[MT_BLUETV].doomednum || - mthing->type == mobjinfo[MT_BLACKTV].doomednum || mthing->type == mobjinfo[MT_PITYTV].doomednum || - mthing->type == mobjinfo[MT_RECYCLETV].doomednum || mthing->type == mobjinfo[MT_MIXUPBOX].doomednum) - mobj->flags |= MF_AMBUSH; + // any monitor with nonzero speed is allowed to respawn like this + mobj->flags2 |= MF2_AMBUSH; } else if (mthing->type != mobjinfo[MT_AXIS].doomednum && @@ -9441,19 +11568,17 @@ ML_NOCLIMB : Direction not controllable mthing->type != mobjinfo[MT_AXISTRANSFERLINE].doomednum && mthing->type != mobjinfo[MT_NIGHTSBUMPER].doomednum && mthing->type != mobjinfo[MT_STARPOST].doomednum) - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; } if (mthing->options & MTF_OBJECTSPECIAL) { - // flag for strong/weak random boxes - if (mthing->type == mobjinfo[MT_SUPERRINGBOX].doomednum || mthing->type == mobjinfo[MT_PRUP].doomednum || - mthing->type == mobjinfo[MT_SNEAKERTV].doomednum || mthing->type == mobjinfo[MT_INV].doomednum || - mthing->type == mobjinfo[MT_WHITETV].doomednum || mthing->type == mobjinfo[MT_GREENTV].doomednum || - mthing->type == mobjinfo[MT_YELLOWTV].doomednum || mthing->type == mobjinfo[MT_BLUETV].doomednum || - mthing->type == mobjinfo[MT_BLACKTV].doomednum || mthing->type == mobjinfo[MT_PITYTV].doomednum || - mthing->type == mobjinfo[MT_RECYCLETV].doomednum || mthing->type == mobjinfo[MT_MIXUPBOX].doomednum) - mobj->flags2 |= MF2_STRONGBOX; + if ((mobj->flags & MF_MONITOR) && mobj->info->speed != 0) + { + // flag for strong/weak random boxes + // any monitor with nonzero speed is allowed to respawn like this + mobj->flags2 |= MF2_STRONGBOX; + } // Requires you to be in bonus time to activate if (mobj->flags & MF_NIGHTSITEM) @@ -9475,17 +11600,33 @@ ML_NOCLIMB : Direction not controllable mobj->flags2 |= MF2_OBJECTFLIP; } + // Extra functionality + if (mthing->options & MTF_EXTRA) + { + if (mobj->flags & MF_MONITOR && (mthing->angle & 16384)) + { + // Store line exec tag to run upon popping + mobj->lastlook = (mthing->angle & 16383); + } + } + + // Final set of not being able to draw nightsitems. + if (mobj->flags & MF_NIGHTSITEM) + mobj->flags2 |= MF2_DONTDRAW; + mthing->mobj = mobj; } -void P_SpawnHoopsAndRings(mapthing_t *mthing) +void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) { + mobjtype_t ringthing = MT_RING; mobj_t *mobj = NULL; INT32 r, i; fixed_t x, y, z, finalx, finaly, finalz; sector_t *sec; TVector v, *res; angle_t closestangle, fa; + boolean nightsreplace = ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)); x = mthing->x << FRACBITS; y = mthing->y << FRACBITS; @@ -9758,105 +11899,6 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) return; } - // Wing logo item. - else if (mthing->type == mobjinfo[MT_NIGHTSWING].doomednum) - { - z = -#ifdef ESLOPE - sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif - sec->floorheight; - if (mthing->options >> ZSHIFT) - z += ((mthing->options >> ZSHIFT) << FRACBITS); - - mthing->z = (INT16)(z>>FRACBITS); - - mobj = P_SpawnMobj(x, y, z, MT_NIGHTSWING); - mobj->spawnpoint = mthing; - - if (G_IsSpecialStage(gamemap) && useNightsSS) - P_SetMobjState(mobj, mobj->info->meleestate); - else if (maptol & TOL_XMAS) - P_SetMobjState(mobj, mobj->info->seestate); - - mobj->angle = FixedAngle(mthing->angle*FRACUNIT); - mobj->flags |= MF_AMBUSH; - mthing->mobj = mobj; - } - // All manners of rings and coins - else if (mthing->type == mobjinfo[MT_RING].doomednum || mthing->type == mobjinfo[MT_COIN].doomednum || - mthing->type == mobjinfo[MT_REDTEAMRING].doomednum || mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum) - { - mobjtype_t ringthing = MT_RING; - - // No rings in Ultimate! - if (ultimatemode && !(G_IsSpecialStage(gamemap) || maptol & TOL_NIGHTS)) - return; - - // Which ringthing to use - switch (mthing->type) - { - case 1800: - ringthing = MT_COIN; - break; - case 308: // No team rings in non-CTF - ringthing = (gametype == GT_CTF) ? MT_REDTEAMRING : MT_RING; - break; - case 309: // No team rings in non-CTF - ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING; - break; - default: - // Spawn rings as blue spheres in special stages, ala S3+K. - if (G_IsSpecialStage(gamemap) && useNightsSS) - ringthing = MT_BLUEBALL; - break; - } - - // Set proper height - if (mthing->options & MTF_OBJECTFLIP) - { - z = ( -#ifdef ESLOPE - sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : -#endif - sec->ceilingheight) - mobjinfo[ringthing].height; - if (mthing->options >> ZSHIFT) - z -= ((mthing->options >> ZSHIFT) << FRACBITS); - } - else - { - z = -#ifdef ESLOPE - sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif - sec->floorheight; - if (mthing->options >> ZSHIFT) - z += ((mthing->options >> ZSHIFT) << FRACBITS); - } - - if (mthing->options & MTF_AMBUSH) // Special flag for rings - { - if (mthing->options & MTF_OBJECTFLIP) - z -= 24*FRACUNIT; - else - z += 24*FRACUNIT; - } - - mthing->z = (INT16)(z>>FRACBITS); - - mobj = P_SpawnMobj(x, y, z, ringthing); - mobj->spawnpoint = mthing; - - if (mthing->options & MTF_OBJECTFLIP) - { - mobj->eflags |= MFE_VERTICALFLIP; - mobj->flags2 |= MF2_OBJECTFLIP; - } - - mobj->angle = FixedAngle(mthing->angle*FRACUNIT); - mobj->flags |= MF_AMBUSH; - mthing->mobj = mobj; - } // *** // Special placement patterns // *** @@ -9865,17 +11907,14 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) else if (mthing->type == 600 || mthing->type == 601) { INT32 dist = 64*FRACUNIT; - mobjtype_t ringthing = MT_RING; if (mthing->type == 601) dist = 128*FRACUNIT; - // No rings in Ultimate! - if (ultimatemode && !(G_IsSpecialStage(gamemap) || maptol & TOL_NIGHTS)) - return; + if (ultimatemode) + return; // No rings in Ultimate! - // Spawn rings as blue spheres in special stages, ala S3+K. - if (G_IsSpecialStage(gamemap) && useNightsSS) - ringthing = MT_BLUEBALL; + if (nightsreplace) + ringthing = MT_NIGHTSSTAR; for (r = 1; r <= 5; r++) { @@ -9910,32 +11949,32 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) mobj->angle = FixedAngle(mthing->angle*FRACUNIT); if (mthing->options & MTF_AMBUSH) - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; + + if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR)) + P_SetMobjState(mobj, mobj->info->seestate); } } // Diagonal rings (handles both types) else if (mthing->type == 602 || mthing->type == 603) // Diagonal rings (5) { - angle_t angle = FixedAngle(mthing->angle*FRACUNIT); - mobjtype_t ringthing = MT_RING; INT32 iterations = 5; if (mthing->type == 603) iterations = 10; - // No rings in Ultimate! - if (ultimatemode && !(G_IsSpecialStage(gamemap) || maptol & TOL_NIGHTS)) - return; + if (ultimatemode) + return; // No rings in Ultimate! - // Spawn rings as blue spheres in special stages, ala S3+K. - if (G_IsSpecialStage(gamemap) && useNightsSS) - ringthing = MT_BLUEBALL; + if (nightsreplace) + ringthing = MT_NIGHTSSTAR; - angle >>= ANGLETOFINESHIFT; + closestangle = FixedAngle(mthing->angle*FRACUNIT); + fa = (closestangle >> ANGLETOFINESHIFT); for (r = 1; r <= iterations; r++) { - x += FixedMul(64*FRACUNIT, FINECOSINE(angle)); - y += FixedMul(64*FRACUNIT, FINESINE(angle)); + x += FixedMul(64*FRACUNIT, FINECOSINE(fa)); + y += FixedMul(64*FRACUNIT, FINESINE(fa)); if (mthing->options & MTF_OBJECTFLIP) { @@ -9966,9 +12005,12 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) mobj->flags2 |= MF2_OBJECTFLIP; } - mobj->angle = FixedAngle(mthing->angle*FRACUNIT); + mobj->angle = closestangle; if (mthing->options & MTF_AMBUSH) - mobj->flags |= MF_AMBUSH; + mobj->flags2 |= MF2_AMBUSH; + + if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR)) + P_SetMobjState(mobj, mobj->info->seestate); } } // Rings of items (all six of them) @@ -9976,7 +12018,6 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) { INT32 numitems = 8; INT32 size = 96*FRACUNIT; - mobjtype_t itemToSpawn = MT_NIGHTSWING; if (mthing->type & 1) { @@ -9994,36 +12035,40 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) closestangle = FixedAngle(mthing->angle*FRACUNIT); + switch (mthing->type) + { + case 604: + case 605: + if (ultimatemode) + return; // No rings in Ultimate! + if (nightsreplace) + ringthing = MT_NIGHTSSTAR; + break; + case 608: + case 609: + /*ringthing = (i & 1) ? MT_RING : MT_BLUESPHERE; -- i == 0 is bluesphere + break;*/ + case 606: + case 607: + ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE; + break; + default: + break; + } + // Create the hoop! for (i = 0; i < numitems; i++) { - switch (mthing->type) - { - case 604: - case 605: - itemToSpawn = MT_RING; - break; - case 608: - case 609: - itemToSpawn = (i & 1) ? MT_NIGHTSWING : MT_RING; - break; - case 606: - case 607: - itemToSpawn = MT_NIGHTSWING; - break; - default: - break; - } - - // No rings in Ultimate! - if (itemToSpawn == MT_RING) + if (mthing->type == 608 || mthing->type == 609) { - if (ultimatemode && !(G_IsSpecialStage(gamemap) || (maptol & TOL_NIGHTS))) - continue; - - // Spawn rings as blue spheres in special stages, ala S3+K. - if (G_IsSpecialStage(gamemap) && useNightsSS) - itemToSpawn = MT_BLUEBALL; + if (i & 1) + { + if (ultimatemode) + continue; // No rings in Ultimate! + ringthing = (nightsreplace) ? MT_NIGHTSSTAR : MT_RING; + } + else + ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE; } fa = i*FINEANGLES/numitems; @@ -10039,18 +12084,99 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) finaly = y + v[1]; finalz = z + v[2]; - mobj = P_SpawnMobj(finalx, finaly, finalz, itemToSpawn); + mobj = P_SpawnMobj(finalx, finaly, finalz, ringthing); mobj->z -= mobj->height/2; - if (itemToSpawn == MT_NIGHTSWING) + if (mthing->options & MTF_OBJECTFLIP) { - if (G_IsSpecialStage(gamemap) && useNightsSS) - P_SetMobjState(mobj, mobj->info->meleestate); - else if ((maptol & TOL_XMAS)) - P_SetMobjState(mobj, mobj->info->seestate); + mobj->eflags |= MFE_VERTICALFLIP; + mobj->flags2 |= MF2_OBJECTFLIP; } + + mobj->angle = closestangle; + if (mthing->options & MTF_AMBUSH) + mobj->flags2 |= MF2_AMBUSH; + + if (bonustime && (ringthing == MT_BLUESPHERE || ringthing == MT_NIGHTSCHIP)) + P_SetMobjState(mobj, mobj->info->raisestate); + else if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR)) + P_SetMobjState(mobj, mobj->info->seestate); } - return; + } + // All manners of rings and coins + else + { + + // Which ringthing to use + if (mthing->type == mobjinfo[MT_BLUESPHERE].doomednum) + ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE; + else if (mthing->type == mobjinfo[MT_BOMBSPHERE].doomednum) + ringthing = MT_BOMBSPHERE; + else + { + if (ultimatemode) + return; // No rings in Ultimate! + + if (nightsreplace) + ringthing = MT_NIGHTSSTAR; + else if (mthing->type == mobjinfo[MT_COIN].doomednum) + ringthing = MT_COIN; + else if (mthing->type == mobjinfo[MT_REDTEAMRING].doomednum) // No team rings in non-CTF + ringthing = (gametype == GT_CTF) ? MT_REDTEAMRING : MT_RING; + else if (mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum) // Ditto + ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING; + } + + // Set proper height + if (mthing->options & MTF_OBJECTFLIP) + { + z = ( +#ifdef ESLOPE + sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : +#endif + sec->ceilingheight) - mobjinfo[ringthing].height; + if (mthing->options >> ZSHIFT) + z -= ((mthing->options >> ZSHIFT) << FRACBITS); + } + else + { + z = +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; + if (mthing->options >> ZSHIFT) + z += ((mthing->options >> ZSHIFT) << FRACBITS); + } + + if (mthing->options & MTF_AMBUSH) // Special flag for rings + { + if (mthing->options & MTF_OBJECTFLIP) + z -= 24*FRACUNIT; + else + z += 24*FRACUNIT; + } + + mthing->z = (INT16)(z>>FRACBITS); + + mobj = P_SpawnMobj(x, y, z, ringthing); + mobj->spawnpoint = mthing; + + if (mthing->options & MTF_OBJECTFLIP) + { + mobj->eflags |= MFE_VERTICALFLIP; + mobj->flags2 |= MF2_OBJECTFLIP; + } + + mobj->angle = FixedAngle(mthing->angle*FRACUNIT); + mthing->mobj = mobj; + if (mthing->options & MTF_AMBUSH) + mobj->flags2 |= MF2_AMBUSH; + + if (bonustime && (ringthing == MT_BLUESPHERE || ringthing == MT_NIGHTSCHIP)) + P_SetMobjState(mobj, mobj->info->raisestate); + else if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR)) + P_SetMobjState(mobj, mobj->info->seestate); } } @@ -10377,7 +12503,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai { mobj_t *th; angle_t an; - fixed_t x, y, z, slope = 0; + fixed_t x, y, z, slope = 0, speed; // angle at which you fire, is player angle an = angle; @@ -10409,9 +12535,13 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai P_SetTarget(&th->target, source); + speed = th->info->speed; + if (source->player && source->player->charability == CA_FLY) + speed = FixedMul(speed, 3*FRACUNIT/2); + th->angle = an; - th->momx = FixedMul(th->info->speed, FINECOSINE(an>>ANGLETOFINESHIFT)); - th->momy = FixedMul(th->info->speed, FINESINE(an>>ANGLETOFINESHIFT)); + th->momx = FixedMul(speed, FINECOSINE(an>>ANGLETOFINESHIFT)); + th->momy = FixedMul(speed, FINESINE(an>>ANGLETOFINESHIFT)); if (allowaim) { @@ -10419,7 +12549,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai th->momy = FixedMul(th->momy,FINECOSINE(source->player->aiming>>ANGLETOFINESHIFT)); } - th->momz = FixedMul(th->info->speed, slope); + th->momz = FixedMul(speed, slope); //scaling done here so it doesn't clutter up the code above th->momx = FixedMul(th->momx, th->scale); @@ -10442,3 +12572,34 @@ void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration) pl->flashcount = duration; pl->flashpal = type; } + +// +// P_SpawnMobjFromMobj +// Spawns an object with offsets relative to the position of another object. +// Scale, gravity flip, etc. is taken into account automatically. +// +mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type) +{ + mobj_t *newmobj; + + xofs = FixedMul(xofs, mobj->scale); + yofs = FixedMul(yofs, mobj->scale); + zofs = FixedMul(zofs, mobj->scale); + + newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type); + if (!newmobj) + return NULL; + + if (mobj->eflags & MFE_VERTICALFLIP) + { + fixed_t elementheight = FixedMul(newmobj->info->height, mobj->scale); + + newmobj->eflags |= MFE_VERTICALFLIP; + newmobj->flags2 |= MF2_OBJECTFLIP; + newmobj->z = mobj->z + mobj->height - zofs - elementheight; + } + + newmobj->destscale = mobj->destscale; + P_SetScale(newmobj, mobj->scale); + return newmobj; +} diff --git a/src/p_mobj.h b/src/p_mobj.h index a15a9fc859e6c03fae4c1790f6d8b6565af406e9..936be3bb09e5efff8fc7ce812a22c7e127969386 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -107,8 +107,8 @@ typedef enum MF_NOSECTOR = 1<<3, // Don't use the blocklinks (inert but displayable) MF_NOBLOCKMAP = 1<<4, - // Not to be activated by sound, deaf monster. - MF_AMBUSH = 1<<5, + // Thin, paper-like collision bound (for visual equivalent, see FF_PAPERSPRITE) + MF_PAPERCOLLISION = 1<<5, // You can push this object. It can activate switches and things by pushing it on top. MF_PUSHABLE = 1<<6, // Object is a boss. @@ -151,10 +151,9 @@ typedef enum MF_PAIN = 1<<24, // This mobj will stick to any surface or solid object it touches. MF_STICKY = 1<<25, - // NiGHTS hidden item. Goes to seestate and turns MF_SPECIAL when paralooped. + // NiGHTS hidden item. Goes to seestate and turns MF_SPECIAL when paralooped. MF_NIGHTSITEM = 1<<26, // for chase camera, don't be blocked by things (partial clipping) - // (need comma at end of this for SOC editor) MF_NOCLIPTHING = 1<<27, // Missile bounces like a grenade. MF_GRENADEBOUNCE = 1<<28, @@ -175,24 +174,26 @@ typedef enum MF2_EXPLOSION = 1<<7, // Thrown ring has explosive properties MF2_SCATTER = 1<<8, // Thrown ring has scatter properties MF2_BEYONDTHEGRAVE = 1<<9, // Source of this missile has died and has since respawned. - MF2_PUSHED = 1<<10, // Mobj was already pushed this tic - MF2_SLIDEPUSH = 1<<11, // MF_PUSHABLE that pushes continuously. - MF2_CLASSICPUSH = 1<<12, // Drops straight down when object has negative Z. - MF2_STANDONME = 1<<13, // While not pushable, stand on me anyway. - MF2_INFLOAT = 1<<14, // Floating to a height for a move, don't auto float to target's height. - MF2_DEBRIS = 1<<15, // Splash ring from explosion ring - MF2_NIGHTSPULL = 1<<16, // Attracted from a paraloop - MF2_JUSTATTACKED = 1<<17, // can be pushed by other moving mobjs - MF2_FIRING = 1<<18, // turret fire - MF2_SUPERFIRE = 1<<19, // Firing something with Super Sonic-stopping properties. Or, if mobj has MF_MISSILE, this is the actual fire from it. - MF2_SHADOW = 1<<20, // Fuzzy draw, makes targeting harder. - MF2_STRONGBOX = 1<<21, // Flag used for "strong" random monitors. - MF2_OBJECTFLIP = 1<<22, // Flag for objects that always have flipped gravity. - MF2_SKULLFLY = 1<<23, // Special handling: skull in flight. - MF2_FRET = 1<<24, // Flashing from a previous hit - MF2_BOSSNOTRAP = 1<<25, // No Egg Trap after boss - MF2_BOSSFLEE = 1<<26, // Boss is fleeing! - MF2_BOSSDEAD = 1<<27, // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.) + MF2_SLIDEPUSH = 1<<10, // MF_PUSHABLE that pushes continuously. + MF2_CLASSICPUSH = 1<<11, // Drops straight down when object has negative momz. + MF2_INVERTAIMABLE = 1<<12, // Flips whether it's targetable by A_LookForEnemies (enemies no, decoys yes) + MF2_INFLOAT = 1<<13, // Floating to a height for a move, don't auto float to target's height. + MF2_DEBRIS = 1<<14, // Splash ring from explosion ring + MF2_NIGHTSPULL = 1<<15, // Attracted from a paraloop + MF2_JUSTATTACKED = 1<<16, // can be pushed by other moving mobjs + MF2_FIRING = 1<<17, // turret fire + MF2_SUPERFIRE = 1<<18, // Firing something with Super Sonic-stopping properties. Or, if mobj has MF_MISSILE, this is the actual fire from it. + MF2_SHADOW = 1<<19, // Fuzzy draw, makes targeting harder. + MF2_STRONGBOX = 1<<20, // Flag used for "strong" random monitors. + MF2_OBJECTFLIP = 1<<21, // Flag for objects that always have flipped gravity. + MF2_SKULLFLY = 1<<22, // Special handling: skull in flight. + MF2_FRET = 1<<23, // Flashing from a previous hit + MF2_BOSSNOTRAP = 1<<24, // No Egg Trap after boss + MF2_BOSSFLEE = 1<<25, // Boss is fleeing! + MF2_BOSSDEAD = 1<<26, // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.) + MF2_AMBUSH = 1<<27, // Alternate behaviour typically set by MTF_AMBUSH + MF2_LINKDRAW = 1<<28, // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position) + MF2_SHIELD = 1<<29, // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use) // free: to and including 1<<31 } mobjflag2_t; @@ -232,11 +233,15 @@ typedef enum MFE_VERTICALFLIP = 1<<5, // Goo water MFE_GOOWATER = 1<<6, - // free: to and including 1<<7 + // Mobj was already pushed this tic + MFE_PUSHED = 1<<7, // Mobj was already sprung this tic MFE_SPRUNG = 1<<8, // Platform movement MFE_APPLYPMOMZ = 1<<9, + // Compute and trigger on mobj angle relative to tracer + // See Linedef Exec 457 (Track mobj angle to point) + MFE_TRACERANGLE = 1<<10, // free: to and including 1<<15 } mobjeflag_t; @@ -274,6 +279,7 @@ typedef struct mobj_s angle_t angle; // orientation spritenum_t sprite; // used to find patch_t and flip value UINT32 frame; // frame number, plus bits see p_pspr.h + UINT8 sprite2; // player sprites UINT16 anim_duration; // for FF_ANIMATE states struct msecnode_s *touching_sectorlist; // a linked list of sectors where this object appears @@ -283,6 +289,8 @@ typedef struct mobj_s // The closest interval over all contacted sectors (or things). fixed_t floorz; // Nearest floor below. fixed_t ceilingz; // Nearest ceiling above. + struct ffloor_s *floorrover; // FOF referred by floorz + struct ffloor_s *ceilingrover; // FOF referred by ceilingz // For movement checking. fixed_t radius; @@ -315,7 +323,7 @@ typedef struct mobj_s mobjtype_t type; const mobjinfo_t *info; // &mobjinfo[mobj->type] - INT32 health; // for player this is rings + 1 + INT32 health; // for player this is rings + 1 -- no it isn't, not any more!! // Movement direction, movement generation (zig-zagging). angle_t movedir; // dirtype_t 0-7; also used by Deton for up/down angle @@ -389,6 +397,7 @@ typedef struct precipmobj_s angle_t angle; // orientation spritenum_t sprite; // used to find patch_t and flip value UINT32 frame; // frame number, plus bits see p_pspr.h + UINT8 sprite2; // player sprites UINT16 anim_duration; // for FF_ANIMATE states struct mprecipsecnode_s *touching_sectorlist; // a linked list of sectors where this object appears @@ -398,6 +407,8 @@ typedef struct precipmobj_s // The closest interval over all contacted sectors (or things). fixed_t floorz; // Nearest floor below. fixed_t ceilingz; // Nearest ceiling above. + struct ffloor_s *floorrover; // FOF referred by floorz + struct ffloor_s *ceilingrover; // FOF referred by ceilingz // For movement checking. fixed_t radius; // Fixed at 2*FRACUNIT @@ -436,7 +447,7 @@ void P_MovePlayerToStarpost(INT32 playernum); void P_AfterPlayerSpawn(INT32 playernum); void P_SpawnMapThing(mapthing_t *mthing); -void P_SpawnHoopsAndRings(mapthing_t *mthing); +void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime); void P_SpawnHoopOfSomething(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle); void P_SpawnPrecipitation(void); void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, statenum_t nstate, angle_t rotangle, boolean spawncenter); @@ -455,5 +466,6 @@ void P_EmeraldManager(void); extern mapthing_t *huntemeralds[MAXHUNTEMERALDS]; extern INT32 numhuntemeralds; extern boolean runemeraldmanager; +extern UINT16 emeraldspawndelay; extern INT32 numstarposts; #endif diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 82c57c85bdbaf2fa5f1ef0daa17ddfc60f4d3986..dfa9906ba76d51b9eed428b1ccf98547f3f62cce 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -28,6 +28,10 @@ #include "r_state.h" #include "r_defs.h" + +#define POLYOBJECTS + + #ifdef POLYOBJECTS /* @@ -239,24 +243,39 @@ boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox) // // Polyobj_GetInfo // -// Finds the 'polyobject settings' linedef that shares the same tag -// as the polyobj linedef to get the settings for it. +// Finds the 'polyobject settings' linedef for a polyobject +// the polyobject's id should be set as its tag // -void Polyobj_GetInfo(INT16 tag, INT32 *polyID, INT32 *mirrorID, UINT16 *exparg) +void Polyobj_GetInfo(INT16 poid, INT32 *poflags, INT32 *parentID, INT32 *potrans) { - INT32 i = P_FindSpecialLineFromTag(POLYINFO_SPECIALNUM, tag, -1); + INT32 i = P_FindSpecialLineFromTag(POLYINFO_SPECIALNUM, poid, -1); if (i == -1) - I_Error("Polyobject (tag: %d) needs line %d for information.\n", tag, POLYINFO_SPECIALNUM); + return; // no extra settings to apply, let's leave it + + if (parentID) + *parentID = lines[i].frontsector->special; + + if (potrans) + *potrans = (lines[i].frontsector->floorheight>>FRACBITS) / 100; + + if (lines[i].flags & ML_EFFECT1) + *poflags |= POF_ONESIDE; + + if (lines[i].flags & ML_EFFECT2) + *poflags &= ~POF_SOLID; - if (polyID) - *polyID = lines[i].frontsector->floorheight>>FRACBITS; + if (lines[i].flags & ML_EFFECT3) + *poflags |= POF_PUSHABLESTOP; - if (mirrorID) - *mirrorID = lines[i].frontsector->special; + if (lines[i].flags & ML_EFFECT4) + *poflags |= POF_RENDERPLANES; - if (exparg) - *exparg = (UINT16)lines[i].frontsector->lightlevel; + /*if (lines[i].flags & ML_EFFECT5) + *poflags &= ~POF_CLIPPLANES;*/ + + if (lines[i].flags & ML_NOCLIMB) // Has a linedef executor + *poflags |= POF_LDEXEC; } // Reallocating array maintenance @@ -480,6 +499,7 @@ newseg: CONS_Debug(DBG_POLYOBJ, "Polyobject %d is not closed\n", po->id); } +/* // structure used to store segs during explicit search process typedef struct segitem_s { @@ -555,7 +575,7 @@ static void Polyobj_findExplicit(polyobj_t *po) // free the temporary array Z_Free(segitems); -} +}*/ // Setup functions @@ -593,7 +613,8 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) for (i = 0; i < numsegs; ++i) { seg_t *seg = &segs[i]; - INT32 polyID, parentID; + INT32 poflags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES; + INT32 parentID = 0, potrans = 0; if (seg->side != 0) // needs to be frontfacing continue; @@ -601,42 +622,21 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) if (seg->linedef->special != POLYOBJ_START_LINE) continue; - Polyobj_GetInfo(seg->linedef->tag, &polyID, &parentID, NULL); - - // is it a START line with this polyobject's id? - if (polyID == po->id) - { - po->flags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES; - - if (seg->linedef->flags & ML_EFFECT1) - po->flags |= POF_ONESIDE; - - if (seg->linedef->flags & ML_EFFECT2) - po->flags &= ~POF_SOLID; - - if (seg->linedef->flags & ML_EFFECT3) - po->flags |= POF_PUSHABLESTOP; - - if (seg->linedef->flags & ML_EFFECT4) - po->flags |= POF_RENDERPLANES; - - // TODO: Use a different linedef flag for this if we really need it!! - // This clashes with texture tiling, also done by Effect 5 flag - /*if (seg->linedef->flags & ML_EFFECT5) - po->flags &= ~POF_CLIPPLANES;*/ + if (seg->linedef->tag != po->id) + continue; - if (seg->linedef->flags & ML_NOCLIMB) // Has a linedef executor - po->flags |= POF_LDEXEC; + Polyobj_GetInfo(po->id, &poflags, &parentID, &potrans); // apply extra settings if they exist! - po->spawnflags = po->flags; // save original flags to reference later for netgames! + // save original flags and translucency to reference later for netgames! + po->spawnflags = po->flags = poflags; + po->spawntrans = po->translucency = potrans; - Polyobj_findSegs(po, seg); - po->parent = parentID; - if (po->parent == po->id) // do not allow a self-reference - po->parent = -1; - // TODO: sound sequence is in args[2] - break; - } + Polyobj_findSegs(po, seg); + po->parent = parentID; + if (po->parent == po->id) // do not allow a self-reference + po->parent = -1; + // TODO: sound sequence is in args[2] + break; } CONS_Debug(DBG_POLYOBJ, "PO ID: %d; Num verts: %s\n", po->id, sizeu1(po->numVertices)); @@ -645,6 +645,7 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) if (po->isBad) return; + /* // 2. If no such line existed in the first step, look for a seg with the // "explicit" special with tag matching this polyobject's id number. If // found, continue to search for all such lines, storing them in a @@ -663,8 +664,16 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) if (po->parent == po->id) // do not allow a self-reference po->parent = -1; // TODO: sound sequence is in args[3] - } + }*/ + // make sure array isn't empty + // since Polyobj_findExplicit is disabled currently, we have to do things here instead now! + if (po->segCount == 0) + { + po->isBad = true; + CONS_Debug(DBG_POLYOBJ, "Polyobject %d is empty\n", po->id); + return; + } // set the polyobject's spawn spot po->spawnSpot.x = spawnSpot->x; @@ -980,6 +989,8 @@ static void Polyobj_pushThing(polyobj_t *po, line_t *line, mobj_t *mo) P_CheckPosition(mo, mo->x + momx, mo->y + momy); mo->floorz = tmfloorz; mo->ceilingz = tmceilingz; + mo->floorrover = tmfloorrover; + mo->ceilingrover = tmceilingrover; } } @@ -1143,7 +1154,7 @@ static INT32 Polyobj_clipThings(polyobj_t *po, line_t *line) // // Moves a polyobject on the x-y plane. // -static boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y) +static boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y, boolean checkmobjs) { size_t i; vertex_t vec; @@ -1164,9 +1175,12 @@ static boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y) for (i = 0; i < po->numLines; ++i) Polyobj_bboxAdd(po->lines[i]->bbox, &vec); - // check for blocking things (yes, it needs to be done separately) - for (i = 0; i < po->numLines; ++i) - hitflags |= Polyobj_clipThings(po, po->lines[i]); + if (checkmobjs) + { + // check for blocking things (yes, it needs to be done separately) + for (i = 0; i < po->numLines; ++i) + hitflags |= Polyobj_clipThings(po, po->lines[i]); + } if (hitflags & 2) { @@ -1184,7 +1198,8 @@ static boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y) po->spawnSpot.x += vec.x; po->spawnSpot.y += vec.y; - Polyobj_carryThings(po, x, y); + if (checkmobjs) + Polyobj_carryThings(po, x, y); Polyobj_removeFromBlockmap(po); // unlink it from the blockmap Polyobj_removeFromSubsec(po); // unlink it from its subsector Polyobj_linkToBlockmap(po); // relink to blockmap @@ -1232,7 +1247,7 @@ static void Polyobj_rotateLine(line_t *ld) // determine slopetype ld->slopetype = !ld->dx ? ST_VERTICAL : !ld->dy ? ST_HORIZONTAL : - FixedDiv(ld->dy, ld->dx) > 0 ? ST_POSITIVE : ST_NEGATIVE; + ((ld->dy > 0) == (ld->dx > 0)) ? ST_POSITIVE : ST_NEGATIVE; // update bounding box if (v1->x < v2->x) @@ -1351,7 +1366,7 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, // // Rotates a polyobject around its start point. // -static boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings) +static boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings, boolean checkmobjs) { size_t i; angle_t angle; @@ -1383,11 +1398,14 @@ static boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings) for (i = 0; i < po->numLines; ++i) Polyobj_rotateLine(po->lines[i]); - // check for blocking things - for (i = 0; i < po->numLines; ++i) - hitflags |= Polyobj_clipThings(po, po->lines[i]); + if (checkmobjs) + { + // check for blocking things + for (i = 0; i < po->numLines; ++i) + hitflags |= Polyobj_clipThings(po, po->lines[i]); - Polyobj_rotateThings(po, origin, delta, turnthings); + Polyobj_rotateThings(po, origin, delta, turnthings); + } if (hitflags & 2) { @@ -1603,19 +1621,23 @@ void Polyobj_InitLevel(void) // Called when a savegame is being loaded. Rotates and translates an // existing polyobject to its position when the game was saved. // +// Monster Iestyn 05/04/19: Please do not interact with mobjs! You +// can cause I_Error crashes that way, and all the important mobjs are +// going to be deleted afterwards anyway. +// void Polyobj_MoveOnLoad(polyobj_t *po, angle_t angle, fixed_t x, fixed_t y) { fixed_t dx, dy; // first, rotate to the saved angle - Polyobj_rotate(po, angle, false); + Polyobj_rotate(po, angle, false, false); // determine component distances to translate dx = x - po->spawnSpot.x; dy = y - po->spawnSpot.y; // translate - Polyobj_moveXY(po, dx, dy); + Polyobj_moveXY(po, dx, dy, false); } // Thinker Functions @@ -1655,7 +1677,7 @@ void T_PolyObjRotate(polyrotate_t *th) // rotate by 'speed' angle per frame // if distance == -1, this polyobject rotates perpetually - if (Polyobj_rotate(po, th->speed, th->turnobjs) && th->distance != -1) + if (Polyobj_rotate(po, th->speed, th->turnobjs, true) && th->distance != -1) { INT32 avel = abs(th->speed); @@ -1739,7 +1761,7 @@ void T_PolyObjMove(polymove_t *th) } // move the polyobject one step along its movement angle - if (Polyobj_moveXY(po, th->momx, th->momy)) + if (Polyobj_moveXY(po, th->momx, th->momy, true)) { INT32 avel = abs(th->speed); @@ -1853,7 +1875,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th) fixed_t diffz; amtx = (target->x - th->diffx) - po->centerPt.x; amty = (target->y - th->diffy) - po->centerPt.y; - Polyobj_moveXY(po, amtx, amty); + Polyobj_moveXY(po, amtx, amty, true); // TODO: use T_MovePlane amtz = (po->lines[0]->backsector->ceilingheight - po->lines[0]->backsector->floorheight)/2; diffz = po->lines[0]->backsector->floorheight - (target->z - amtz); @@ -1869,7 +1891,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th) if (po->isBad) continue; - Polyobj_moveXY(po, amtx, amty); + Polyobj_moveXY(po, amtx, amty, true); // TODO: use T_MovePlane po->lines[0]->backsector->floorheight += diffz; // move up/down by same amount as the parent did po->lines[0]->backsector->ceilingheight += diffz; @@ -2032,7 +2054,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th) } // Move the polyobject - Polyobj_moveXY(po, momx, momy); + Polyobj_moveXY(po, momx, momy, true); // TODO: use T_MovePlane po->lines[0]->backsector->floorheight += momz; po->lines[0]->backsector->ceilingheight += momz; @@ -2047,7 +2069,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th) if (po->isBad) continue; - Polyobj_moveXY(po, momx, momy); + Polyobj_moveXY(po, momx, momy, true); // TODO: use T_MovePlane po->lines[0]->backsector->floorheight += momz; po->lines[0]->backsector->ceilingheight += momz; @@ -2096,7 +2118,7 @@ void T_PolyDoorSlide(polyslidedoor_t *th) } // move the polyobject one step along its movement angle - if (Polyobj_moveXY(po, th->momx, th->momy)) + if (Polyobj_moveXY(po, th->momx, th->momy, true)) { INT32 avel = abs(th->speed); @@ -2202,7 +2224,7 @@ void T_PolyDoorSwing(polyswingdoor_t *th) // rotate by 'speed' angle per frame // if distance == -1, this polyobject rotates perpetually - if (Polyobj_rotate(po, th->speed, false) && th->distance != -1) + if (Polyobj_rotate(po, th->speed, false, true) && th->distance != -1) { INT32 avel = abs(th->speed); @@ -2258,7 +2280,7 @@ void T_PolyDoorSwing(polyswingdoor_t *th) } } -// T_PolyObjDisplace: shift a polyobject based on a control sector's heights. -Red +// T_PolyObjDisplace: shift a polyobject based on a control sector's heights. void T_PolyObjDisplace(polydisplace_t *th) { polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); @@ -2267,10 +2289,10 @@ void T_PolyObjDisplace(polydisplace_t *th) if (!po) #ifdef RANGECHECK - I_Error("T_PolyDoorSwing: thinker has invalid id %d\n", th->polyObjNum); + I_Error("T_PolyObjDisplace: thinker has invalid id %d\n", th->polyObjNum); #else { - CONS_Debug(DBG_POLYOBJ, "T_PolyDoorSwing: thinker with invalid id %d removed.\n", th->polyObjNum); + CONS_Debug(DBG_POLYOBJ, "T_PolyObjDisplace: thinker with invalid id %d removed.\n", th->polyObjNum); P_RemoveThinkerDelayed(&th->thinker); return; } @@ -2294,7 +2316,46 @@ void T_PolyObjDisplace(polydisplace_t *th) dx = FixedMul(th->dx, delta); dy = FixedMul(th->dy, delta); - if (Polyobj_moveXY(po, dx, dy)) + if (Polyobj_moveXY(po, dx, dy, true)) + th->oldHeights = newheights; +} + +// T_PolyObjRotDisplace: rotate a polyobject based on a control sector's heights. +void T_PolyObjRotDisplace(polyrotdisplace_t *th) +{ + polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); + fixed_t newheights, delta; + fixed_t rotangle; + + if (!po) +#ifdef RANGECHECK + I_Error("T_PolyObjRotDisplace: thinker has invalid id %d\n", th->polyObjNum); +#else + { + CONS_Debug(DBG_POLYOBJ, "T_PolyObjRotDisplace: thinker with invalid id %d removed.\n", th->polyObjNum); + P_RemoveThinkerDelayed(&th->thinker); + return; + } +#endif + + // check for displacement due to override and reattach when possible + if (po->thinker == NULL) + { + po->thinker = &th->thinker; + + // reset polyobject's thrust + po->thrust = FRACUNIT; + } + + newheights = th->controlSector->floorheight+th->controlSector->ceilingheight; + delta = newheights-th->oldHeights; + + if (!delta) + return; + + rotangle = FixedMul(th->rotscale, delta); + + if (Polyobj_rotate(po, FixedAngle(rotangle), th->turnobjs, true)) th->oldHeights = newheights; } @@ -2757,6 +2818,52 @@ INT32 EV_DoPolyObjDisplace(polydisplacedata_t *prdata) return 1; } +INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *prdata) +{ + polyobj_t *po; + polyobj_t *oldpo; + polyrotdisplace_t *th; + INT32 start; + + if (!(po = Polyobj_GetForNum(prdata->polyObjNum))) + { + CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", prdata->polyObjNum); + return 0; + } + + // don't allow line actions to affect bad polyobjects + if (po->isBad) + return 0; + + // create a new thinker + th = Z_Malloc(sizeof(polyrotdisplace_t), PU_LEVSPEC, NULL); + th->thinker.function.acp1 = (actionf_p1)T_PolyObjRotDisplace; + PolyObj_AddThinker(&th->thinker); + po->thinker = &th->thinker; + + // set fields + th->polyObjNum = prdata->polyObjNum; + + th->controlSector = prdata->controlSector; + th->oldHeights = th->controlSector->floorheight+th->controlSector->ceilingheight; + + th->rotscale = prdata->rotscale; + th->turnobjs = prdata->turnobjs; + + oldpo = po; + + // apply action to mirroring polyobjects as well + start = 0; + while ((po = Polyobj_GetChild(oldpo, &start))) + { + prdata->polyObjNum = po->id; // change id to match child polyobject's + EV_DoPolyObjRotDisplace(prdata); + } + + // action was successful + return 1; +} + void T_PolyObjFlag(polymove_t *th) { polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); @@ -2860,6 +2967,165 @@ INT32 EV_DoPolyObjFlag(line_t *pfdata) return 1; } +void T_PolyObjFade(polyfade_t *th) +{ + boolean stillfading = false; + polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); + + if (!po) +#ifdef RANGECHECK + I_Error("T_PolyObjFade: thinker has invalid id %d\n", th->polyObjNum); +#else + { + CONS_Debug(DBG_POLYOBJ, "T_PolyObjFade: thinker with invalid id %d removed.\n", th->polyObjNum); + P_RemoveThinkerDelayed(&th->thinker); + return; + } +#endif + + // check for displacement due to override and reattach when possible + if (po->thinker == NULL) + po->thinker = &th->thinker; + + stillfading = th->ticbased ? !(--(th->timer) <= 0) + : !((th->timer -= th->duration) <= 0); + + if (th->timer <= 0) + { + po->translucency = max(min(th->destvalue, NUMTRANSMAPS), 0); + + // remove thinker + if (po->thinker == &th->thinker) + po->thinker = NULL; + P_RemoveThinker(&th->thinker); + } + else + { + INT16 delta = abs(th->destvalue - th->sourcevalue); + INT32 duration = th->ticbased ? th->duration + : abs(FixedMul(FixedDiv(256, NUMTRANSMAPS), NUMTRANSMAPS - th->destvalue) + - FixedMul(FixedDiv(256, NUMTRANSMAPS), NUMTRANSMAPS - th->sourcevalue)); // speed-based internal counter duration: delta in 256 scale + fixed_t factor = min(FixedDiv(duration - th->timer, duration), 1*FRACUNIT); + if (th->destvalue < th->sourcevalue) + po->translucency = max(min(po->translucency, th->sourcevalue - (INT16)FixedMul(delta, factor)), th->destvalue); + else if (th->destvalue > th->sourcevalue) + po->translucency = min(max(po->translucency, th->sourcevalue + (INT16)FixedMul(delta, factor)), th->destvalue); + } + + if (!stillfading) + { + // set render flags + if (po->translucency >= NUMTRANSMAPS) // invisible + po->flags &= ~POF_RENDERALL; + else + po->flags |= (po->spawnflags & POF_RENDERALL); + + // set collision + if (th->docollision) + { + if (th->destvalue > th->sourcevalue) // faded out + { + po->flags &= ~POF_SOLID; + po->flags |= POF_NOSPECIALS; + } + else + { + po->flags |= (po->spawnflags & POF_SOLID); + if (!(po->spawnflags & POF_NOSPECIALS)) + po->flags &= ~POF_NOSPECIALS; + } + } + } + else + { + if (po->translucency >= NUMTRANSMAPS) + // HACK: OpenGL renders fully opaque when >= NUMTRANSMAPS + po->translucency = NUMTRANSMAPS-1; + + po->flags |= (po->spawnflags & POF_RENDERALL); + + // set collision + if (th->docollision) + { + if (th->doghostfade) + { + po->flags &= ~POF_SOLID; + po->flags |= POF_NOSPECIALS; + } + else + { + po->flags |= (po->spawnflags & POF_SOLID); + if (!(po->spawnflags & POF_NOSPECIALS)) + po->flags &= ~POF_NOSPECIALS; + } + } + } +} + +INT32 EV_DoPolyObjFade(polyfadedata_t *pfdata) +{ + polyobj_t *po; + polyobj_t *oldpo; + polyfade_t *th; + INT32 start; + + if (!(po = Polyobj_GetForNum(pfdata->polyObjNum))) + { + CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjFade: bad polyobj %d\n", pfdata->polyObjNum); + return 0; + } + + // don't allow line actions to affect bad polyobjects + if (po->isBad) + return 0; + + // already equal, nothing to do + if (po->translucency == pfdata->destvalue) + return 1; + + if (po->thinker && po->thinker->function.acp1 == (actionf_p1)T_PolyObjFade) + P_RemoveThinker(po->thinker); + + // create a new thinker + th = Z_Malloc(sizeof(polyfade_t), PU_LEVSPEC, NULL); + th->thinker.function.acp1 = (actionf_p1)T_PolyObjFade; + PolyObj_AddThinker(&th->thinker); + po->thinker = &th->thinker; + + // set fields + th->polyObjNum = pfdata->polyObjNum; + th->sourcevalue = po->translucency; + th->destvalue = pfdata->destvalue; + th->docollision = pfdata->docollision; + th->doghostfade = pfdata->doghostfade; + + if (pfdata->ticbased) + { + th->ticbased = true; + th->timer = th->duration = abs(pfdata->speed); // pfdata->speed is duration + } + else + { + th->ticbased = false; + th->timer = abs(FixedMul(FixedDiv(256, NUMTRANSMAPS), NUMTRANSMAPS - th->destvalue) + - FixedMul(FixedDiv(256, NUMTRANSMAPS), NUMTRANSMAPS - th->sourcevalue)); // delta converted to 256 scale, use as internal counter + th->duration = abs(pfdata->speed); // use th->duration as speed decrement + } + + oldpo = po; + + // apply action to mirroring polyobjects as well + start = 0; + while ((po = Polyobj_GetChild(oldpo, &start))) + { + pfdata->polyObjNum = po->id; + EV_DoPolyObjFade(pfdata); + } + + // action was successful + return 1; +} + #endif // ifdef POLYOBJECTS // EOF diff --git a/src/p_polyobj.h b/src/p_polyobj.h index 60e996cae3df4ab656dd014104e092484fcdf788..73a11d237fcaf611005c95154b3be6e671d728c8 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -28,7 +28,7 @@ #define POLYOBJ_ANCHOR_DOOMEDNUM 760 #define POLYOBJ_SPAWN_DOOMEDNUM 761 -#define POLYOBJ_SPAWNCRUSH_DOOMEDNUM 762 +#define POLYOBJ_SPAWNCRUSH_DOOMEDNUM 762 // todo: REMOVE #define POLYOBJ_START_LINE 20 #define POLYOBJ_EXPLICIT_LINE 21 @@ -104,6 +104,7 @@ typedef struct polyobj_s // these are saved for netgames, so do not let Lua touch these! INT32 spawnflags; // Flags the polyobject originally spawned with + INT32 spawntrans; // Translucency the polyobject originally spawned with } polyobj_t; // @@ -206,6 +207,31 @@ typedef struct polydisplace_s fixed_t oldHeights; } polydisplace_t; +typedef struct polyrotdisplace_s +{ + thinker_t thinker; // must be first + + INT32 polyObjNum; + struct sector_s *controlSector; + fixed_t rotscale; + UINT8 turnobjs; + fixed_t oldHeights; +} polyrotdisplace_t; + +typedef struct polyfade_s +{ + thinker_t thinker; // must be first + + INT32 polyObjNum; + INT32 sourcevalue; + INT32 destvalue; + boolean docollision; + boolean doghostfade; + boolean ticbased; + INT32 duration; + INT32 timer; +} polyfade_t; + // // Line Activation Data Structures // @@ -265,6 +291,24 @@ typedef struct polydisplacedata_s fixed_t dy; } polydisplacedata_t; +typedef struct polyrotdisplacedata_s +{ + INT32 polyObjNum; + struct sector_s *controlSector; + fixed_t rotscale; + UINT8 turnobjs; +} polyrotdisplacedata_t; + +typedef struct polyfadedata_s +{ + INT32 polyObjNum; + INT32 destvalue; + boolean docollision; + boolean doghostfade; + boolean ticbased; + INT32 speed; +} polyfadedata_t; + // // Functions // @@ -276,7 +320,7 @@ boolean P_PointInsidePolyobj(polyobj_t *po, fixed_t x, fixed_t y); boolean P_MobjTouchingPolyobj(polyobj_t *po, mobj_t *mo); boolean P_MobjInsidePolyobj(polyobj_t *po, mobj_t *mo); boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox); -void Polyobj_GetInfo(INT16 tag, INT32 *polyID, INT32 *parentID, UINT16 *exparg); +void Polyobj_GetInfo(INT16 poid, INT32 *poflags, INT32 *parentID, INT32 *potrans); // thinkers (needed in p_saveg.c) void T_PolyObjRotate(polyrotate_t *); @@ -285,14 +329,18 @@ void T_PolyObjWaypoint (polywaypoint_t *); void T_PolyDoorSlide(polyslidedoor_t *); void T_PolyDoorSwing(polyswingdoor_t *); void T_PolyObjDisplace (polydisplace_t *); +void T_PolyObjRotDisplace (polyrotdisplace_t *); void T_PolyObjFlag (polymove_t *); +void T_PolyObjFade (polyfade_t *); INT32 EV_DoPolyDoor(polydoordata_t *); INT32 EV_DoPolyObjMove(polymovedata_t *); INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *); INT32 EV_DoPolyObjRotate(polyrotdata_t *); INT32 EV_DoPolyObjDisplace(polydisplacedata_t *); +INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *); INT32 EV_DoPolyObjFlag(struct line_s *); +INT32 EV_DoPolyObjFade(polyfadedata_t *); // diff --git a/src/p_pspr.h b/src/p_pspr.h index 16708bcb2a3b19e2f0c23c9b1c90252b8f29579d..c9c66b96133f3d86bf5bce442b3a6ee6657c2d5a 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -35,12 +35,16 @@ #pragma interface #endif -/// \brief Frame flags: only the frame number -#define FF_FRAMEMASK 0x3fff -/// \brief Frame flags: Simple stateless animation -#define FF_ANIMATE 0x4000 -/// \brief Frame flags: frame always appears full bright -#define FF_FULLBRIGHT 0x8000 +/// \brief Frame flags: only the frame number - 0 to 256 (Frames from 0 to 63, Sprite2 number uses 0 to 127 plus FF_SPR2SUPER) +#define FF_FRAMEMASK 0xff + +/// \brief Frame flags - SPR2: Super sprite2 +#define FF_SPR2SUPER 0x80 +/// \brief Frame flags - SPR2: A change of state at the end of Sprite2 animation +#define FF_SPR2ENDSTATE 0x1000 +/// \brief Frame flags - SPR2: 50% of starting in middle of Sprite2 animation +#define FF_SPR2MIDSTART 0x2000 + /// \brief Frame flags: 0 = no trans(opaque), 1-15 = transl. table #define FF_TRANSMASK 0xf0000 /// \brief shift for FF_TRANSMASK @@ -56,6 +60,20 @@ #define FF_TRANS80 (tr_trans80<<FF_TRANSSHIFT) #define FF_TRANS90 (tr_trans90<<FF_TRANSSHIFT) +/// \brief Frame flags: frame always appears full bright +#define FF_FULLBRIGHT 0x00100000 +/// \brief Frame flags: Flip sprite vertically (relative to what it should be for its gravity) +#define FF_VERTICALFLIP 0x00200000 +/// \brief Frame flags: Thin, paper-like sprite (for collision equivalent, see MF_PAPERCOLLISION) +#define FF_PAPERSPRITE 0x00400000 + +/// \brief Frame flags - Animate: Simple stateless animation +#define FF_ANIMATE 0x01000000 +/// \brief Frame flags - Animate: Start at a random place in the animation (mutually exclusive with below) +#define FF_RANDOMANIM 0x02000000 +/// \brief Frame flags - Animate: Sync animation to global timer (mutually exclusive with above) +#define FF_GLOBALANIM 0x04000000 + /** \brief translucency tables \todo add another asm routine which use the fg and bg indexes in the diff --git a/src/p_saveg.c b/src/p_saveg.c index fce72b9271977db0f8ccc7604642a65eec2ca50c..0d58387b9e6be03187077ebf3642cda67cd7365b 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -21,6 +21,7 @@ #include "p_local.h" #include "p_setup.h" #include "p_saveg.h" +#include "r_data.h" #include "r_things.h" #include "r_state.h" #include "w_wad.h" @@ -56,6 +57,8 @@ typedef enum AWAYVIEW = 0x08, FIRSTAXIS = 0x10, SECONDAXIS = 0x20, + FOLLOW = 0x40, + DRONE = 0x80, } player_saveflags; // @@ -64,22 +67,16 @@ typedef enum static inline void P_ArchivePlayer(void) { const player_t *player = &players[consoleplayer]; - INT32 pllives = player->lives; - if (pllives < 3) // Bump up to 3 lives if the player - pllives = 3; // has less than that. - - WRITEUINT8(save_p, player->skincolor); - WRITEUINT8(save_p, player->skin); - + INT16 skininfo = player->skin + (botskin<<5); + SINT8 pllives = player->lives; + if (pllives < startinglivesbalance[numgameovers]) // Bump up to 3 lives if the player + pllives = startinglivesbalance[numgameovers]; // has less than that. + + WRITEUINT16(save_p, skininfo); + WRITEUINT8(save_p, numgameovers); + WRITESINT8(save_p, pllives); WRITEUINT32(save_p, player->score); - WRITEINT32(save_p, pllives); WRITEINT32(save_p, player->continues); - - if (botskin) - { - WRITEUINT8(save_p, botskin); - WRITEUINT8(save_p, botcolor); - } } // @@ -87,22 +84,14 @@ static inline void P_ArchivePlayer(void) // static inline void P_UnArchivePlayer(void) { - savedata.skincolor = READUINT8(save_p); - savedata.skin = READUINT8(save_p); + INT16 skininfo = READUINT16(save_p); + savedata.skin = skininfo & ((1<<5) - 1); + savedata.botskin = skininfo >> 5; - savedata.score = READINT32(save_p); - savedata.lives = READINT32(save_p); + savedata.numgameovers = READUINT8(save_p); + savedata.lives = READSINT8(save_p); + savedata.score = READUINT32(save_p); savedata.continues = READINT32(save_p); - - if (savedata.botcolor) - { - savedata.botskin = READUINT8(save_p); - if (savedata.botskin-1 >= numskins) - savedata.botskin = 0; - savedata.botcolor = READUINT8(save_p); - } - else - savedata.botskin = 0; } // @@ -126,9 +115,11 @@ static void P_NetArchivePlayers(void) // no longer send ticcmds, player name, skin, or color WRITEANGLE(save_p, players[i].aiming); + WRITEANGLE(save_p, players[i].drawangle); WRITEANGLE(save_p, players[i].awayviewaiming); WRITEINT32(save_p, players[i].awayviewtics); - WRITEINT32(save_p, players[i].health); + WRITEINT16(save_p, players[i].rings); + WRITEINT16(save_p, players[i].spheres); WRITESINT8(save_p, players[i].pity); WRITEINT32(save_p, players[i].currentweapon); @@ -147,13 +138,11 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, players[i].score); WRITEFIXED(save_p, players[i].dashspeed); - WRITEINT32(save_p, players[i].dashtime); WRITESINT8(save_p, players[i].lives); WRITESINT8(save_p, players[i].continues); WRITESINT8(save_p, players[i].xtralife); WRITEUINT8(save_p, players[i].gotcontinue); WRITEFIXED(save_p, players[i].speed); - WRITEUINT8(save_p, players[i].jumping); WRITEUINT8(save_p, players[i].secondjump); WRITEUINT8(save_p, players[i].fly1); WRITEUINT8(save_p, players[i].scoreadd); @@ -162,6 +151,7 @@ static void P_NetArchivePlayers(void) WRITEINT32(save_p, players[i].deadtimer); WRITEUINT32(save_p, players[i].exiting); WRITEUINT8(save_p, players[i].homing); + WRITEUINT32(save_p, players[i].dashmode); WRITEUINT32(save_p, players[i].skidtime); //////////////////////////// @@ -209,15 +199,25 @@ static void P_NetArchivePlayers(void) WRITEINT32(save_p, players[i].drillmeter); WRITEUINT8(save_p, players[i].drilldelay); WRITEUINT8(save_p, players[i].bonustime); + WRITEFIXED(save_p, players[i].oldscale); WRITEUINT8(save_p, players[i].mare); - + WRITEUINT8(save_p, players[i].marelap); + WRITEUINT8(save_p, players[i].marebonuslap); WRITEUINT32(save_p, players[i].marebegunat); WRITEUINT32(save_p, players[i].startedtime); WRITEUINT32(save_p, players[i].finishedtime); + WRITEUINT32(save_p, players[i].lapbegunat); + WRITEUINT32(save_p, players[i].lapstartedtime); + WRITEINT16(save_p, players[i].finishedspheres); WRITEINT16(save_p, players[i].finishedrings); WRITEUINT32(save_p, players[i].marescore); WRITEUINT32(save_p, players[i].lastmarescore); + WRITEUINT32(save_p, players[i].totalmarescore); WRITEUINT8(save_p, players[i].lastmare); + WRITEUINT8(save_p, players[i].lastmarelap); + WRITEUINT8(save_p, players[i].lastmarebonuslap); + WRITEUINT8(save_p, players[i].totalmarelap); + WRITEUINT8(save_p, players[i].totalmarebonuslap); WRITEINT32(save_p, players[i].maxlink); WRITEUINT8(save_p, players[i].texttimer); WRITEUINT8(save_p, players[i].textvar); @@ -234,6 +234,12 @@ static void P_NetArchivePlayers(void) if (players[i].axis2) flags |= SECONDAXIS; + if (players[i].followmobj) + flags |= FOLLOW; + + if (players[i].drone) + flags |= DRONE; + WRITEINT16(save_p, players[i].lastsidehit); WRITEINT16(save_p, players[i].lastlinehit); @@ -259,12 +265,22 @@ static void P_NetArchivePlayers(void) if (flags & AWAYVIEW) WRITEUINT32(save_p, players[i].awayviewmobj->mobjnum); + if (flags & FOLLOW) + WRITEUINT32(save_p, players[i].followmobj->mobjnum); + + if (flags & DRONE) + WRITEUINT32(save_p, players[i].drone->mobjnum); + + WRITEFIXED(save_p, players[i].camerascale); + WRITEFIXED(save_p, players[i].shieldscale); + WRITEUINT8(save_p, players[i].charability); WRITEUINT8(save_p, players[i].charability2); WRITEUINT32(save_p, players[i].charflags); WRITEUINT32(save_p, (UINT32)players[i].thokitem); WRITEUINT32(save_p, (UINT32)players[i].spinitem); WRITEUINT32(save_p, (UINT32)players[i].revitem); + WRITEUINT32(save_p, (UINT32)players[i].followitem); WRITEFIXED(save_p, players[i].actionspd); WRITEFIXED(save_p, players[i].mindash); WRITEFIXED(save_p, players[i].maxdash); @@ -274,6 +290,8 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].accelstart); WRITEUINT8(save_p, players[i].acceleration); WRITEFIXED(save_p, players[i].jumpfactor); + WRITEFIXED(save_p, players[i].height); + WRITEFIXED(save_p, players[i].spinheight); } } @@ -301,9 +319,11 @@ static void P_NetUnArchivePlayers(void) // (that data is handled in the server config now) players[i].aiming = READANGLE(save_p); + players[i].drawangle = READANGLE(save_p); players[i].awayviewaiming = READANGLE(save_p); players[i].awayviewtics = READINT32(save_p); - players[i].health = READINT32(save_p); + players[i].rings = READINT16(save_p); + players[i].spheres = READINT16(save_p); players[i].pity = READSINT8(save_p); players[i].currentweapon = READINT32(save_p); @@ -322,13 +342,11 @@ static void P_NetUnArchivePlayers(void) players[i].score = READUINT32(save_p); players[i].dashspeed = READFIXED(save_p); // dashing speed - players[i].dashtime = READINT32(save_p); // dashing speed players[i].lives = READSINT8(save_p); players[i].continues = READSINT8(save_p); // continues that player has acquired players[i].xtralife = READSINT8(save_p); // Ring Extra Life counter players[i].gotcontinue = READUINT8(save_p); // got continue from stage players[i].speed = READFIXED(save_p); // Player's speed (distance formula of MOMX and MOMY values) - players[i].jumping = READUINT8(save_p); // Jump counter players[i].secondjump = READUINT8(save_p); players[i].fly1 = READUINT8(save_p); // Tails flying players[i].scoreadd = READUINT8(save_p); // Used for multiple enemy attack bonus @@ -337,6 +355,7 @@ static void P_NetUnArchivePlayers(void) players[i].deadtimer = READINT32(save_p); // End game if game over lasts too long players[i].exiting = READUINT32(save_p); // Exitlevel timer players[i].homing = READUINT8(save_p); // Are you homing? + players[i].dashmode = READUINT32(save_p); // counter for dashmode ability players[i].skidtime = READUINT32(save_p); // Skid timer //////////////////////////// @@ -384,15 +403,25 @@ static void P_NetUnArchivePlayers(void) players[i].drillmeter = READINT32(save_p); players[i].drilldelay = READUINT8(save_p); players[i].bonustime = (boolean)READUINT8(save_p); + players[i].oldscale = READFIXED(save_p); players[i].mare = READUINT8(save_p); - + players[i].marelap = READUINT8(save_p); + players[i].marebonuslap = READUINT8(save_p); players[i].marebegunat = READUINT32(save_p); players[i].startedtime = READUINT32(save_p); players[i].finishedtime = READUINT32(save_p); + players[i].lapbegunat = READUINT32(save_p); + players[i].lapstartedtime = READUINT32(save_p); + players[i].finishedspheres = READINT16(save_p); players[i].finishedrings = READINT16(save_p); players[i].marescore = READUINT32(save_p); players[i].lastmarescore = READUINT32(save_p); + players[i].totalmarescore = READUINT32(save_p); players[i].lastmare = READUINT8(save_p); + players[i].lastmarelap = READUINT8(save_p); + players[i].lastmarebonuslap = READUINT8(save_p); + players[i].totalmarelap = READUINT8(save_p); + players[i].totalmarebonuslap = READUINT8(save_p); players[i].maxlink = READINT32(save_p); players[i].texttimer = READUINT8(save_p); players[i].textvar = READUINT8(save_p); @@ -422,7 +451,14 @@ static void P_NetUnArchivePlayers(void) if (flags & AWAYVIEW) players[i].awayviewmobj = (mobj_t *)(size_t)READUINT32(save_p); - players[i].viewheight = cv_viewheight.value<<FRACBITS; + if (flags & FOLLOW) + players[i].followmobj = (mobj_t *)(size_t)READUINT32(save_p); + + if (flags & DRONE) + players[i].drone = (mobj_t *)(size_t)READUINT32(save_p); + + players[i].camerascale = READFIXED(save_p); + players[i].shieldscale = READFIXED(save_p); //SetPlayerSkinByNum(i, players[i].skin); players[i].charability = READUINT8(save_p); @@ -431,6 +467,7 @@ static void P_NetUnArchivePlayers(void) players[i].thokitem = (mobjtype_t)READUINT32(save_p); players[i].spinitem = (mobjtype_t)READUINT32(save_p); players[i].revitem = (mobjtype_t)READUINT32(save_p); + players[i].followitem = (mobjtype_t)READUINT32(save_p); players[i].actionspd = READFIXED(save_p); players[i].mindash = READFIXED(save_p); players[i].maxdash = READFIXED(save_p); @@ -440,9 +477,250 @@ static void P_NetUnArchivePlayers(void) players[i].accelstart = READUINT8(save_p); players[i].acceleration = READUINT8(save_p); players[i].jumpfactor = READFIXED(save_p); + players[i].height = READFIXED(save_p); + players[i].spinheight = READFIXED(save_p); + + players[i].viewheight = 41*players[i].height/48; // scale cannot be factored in at this point + } +} + +/// +/// Colormaps +/// + +static extracolormap_t *net_colormaps = NULL; +static UINT32 num_net_colormaps = 0; +static UINT32 num_ffloors = 0; // for loading + +// Copypasta from r_data.c AddColormapToList +// But also check for equality and return the matching index +static UINT32 CheckAddNetColormapToList(extracolormap_t *extra_colormap) +{ + extracolormap_t *exc, *exc_prev = NULL; + UINT32 i = 0; + + if (!net_colormaps) + { + net_colormaps = R_CopyColormap(extra_colormap, false); + net_colormaps->next = 0; + net_colormaps->prev = 0; + num_net_colormaps = i+1; + return i; + } + + for (exc = net_colormaps; exc; exc_prev = exc, exc = exc->next) + { + if (R_CheckEqualColormaps(exc, extra_colormap, true, true, true)) + return i; + i++; + } + + exc_prev->next = R_CopyColormap(extra_colormap, false); + extra_colormap->prev = exc_prev; + extra_colormap->next = 0; + + num_net_colormaps = i+1; + return i; +} + +static extracolormap_t *GetNetColormapFromList(UINT32 index) +{ + // For loading, we have to be tricky: + // We load the sectors BEFORE knowing the colormap values + // So if an index doesn't exist, fill our list with dummy colormaps + // until we get the index we want + // Then when we load the color data, we set up the dummy colormaps + + extracolormap_t *exc, *last_exc = NULL; + UINT32 i = 0; + + if (!net_colormaps) // initialize our list + net_colormaps = R_CreateDefaultColormap(false); + + for (exc = net_colormaps; exc; last_exc = exc, exc = exc->next) + { + if (i++ == index) + return exc; + } + + + // LET'S HOPE that index is a sane value, because we create up to [index] + // entries in net_colormaps. At this point, we don't know + // what the total colormap count is + if (index >= numsectors*3 + num_ffloors) + // if every sector had a unique colormap change AND a fade color thinker which has two colormap entries + // AND every ffloor had a fade FOF thinker with one colormap entry + I_Error("Colormap %d from server is too high for sectors %d", index, (UINT32)numsectors); + + // our index doesn't exist, so just make the entry + for (; i <= index; i++) + { + exc = R_CreateDefaultColormap(false); + if (last_exc) + last_exc->next = exc; + exc->prev = last_exc; + exc->next = NULL; + last_exc = exc; + } + return exc; +} + +static void ClearNetColormaps(void) +{ + // We're actually Z_Freeing each entry here, + // so don't call this in P_NetUnArchiveColormaps (where entries will be used in-game) + extracolormap_t *exc, *exc_next; + + for (exc = net_colormaps; exc; exc = exc_next) + { + exc_next = exc->next; + Z_Free(exc); + } + num_net_colormaps = 0; + num_ffloors = 0; + net_colormaps = NULL; +} + +static void P_NetArchiveColormaps(void) +{ + // We save and then we clean up our colormap mess + extracolormap_t *exc, *exc_next; + UINT32 i = 0; + WRITEUINT32(save_p, num_net_colormaps); // save for safety + + for (exc = net_colormaps; i < num_net_colormaps; i++, exc = exc_next) + { + // We must save num_net_colormaps worth of data + // So fill non-existent entries with default. + if (!exc) + exc = R_CreateDefaultColormap(false); + + WRITEUINT8(save_p, exc->fadestart); + WRITEUINT8(save_p, exc->fadeend); + WRITEUINT8(save_p, exc->fog); + + WRITEINT32(save_p, exc->rgba); + WRITEINT32(save_p, exc->fadergba); + +#ifdef EXTRACOLORMAPLUMPS + WRITESTRINGN(save_p, exc->lumpname, 9); +#endif + + exc_next = exc->next; + Z_Free(exc); // don't need anymore + } + + num_net_colormaps = 0; + num_ffloors = 0; + net_colormaps = NULL; +} + +static void P_NetUnArchiveColormaps(void) +{ + // When we reach this point, we already populated our list with + // dummy colormaps. Now that we are loading the color data, + // set up the dummies. + extracolormap_t *exc, *existing_exc, *exc_next = NULL; + UINT32 i = 0; + + num_net_colormaps = READUINT32(save_p); + + for (exc = net_colormaps; i < num_net_colormaps; i++, exc = exc_next) + { + UINT8 fadestart, fadeend, fog; + INT32 rgba, fadergba; +#ifdef EXTRACOLORMAPLUMPS + char lumpname[9]; +#endif + + fadestart = READUINT8(save_p); + fadeend = READUINT8(save_p); + fog = READUINT8(save_p); + + rgba = READINT32(save_p); + fadergba = READINT32(save_p); + +#ifdef EXTRACOLORMAPLUMPS + READSTRINGN(save_p, lumpname, 9); + + if (lumpname[0]) + { + if (!exc) + // no point making a new entry since nothing points to it, + // but we needed to read the data so now continue + continue; + + exc_next = exc->next; // this gets overwritten during our operations here, so get it now + existing_exc = R_ColormapForName(lumpname); + *exc = *existing_exc; + R_AddColormapToList(exc); // see HACK note below on why we're adding duplicates + continue; + } +#endif + + if (!exc) + // no point making a new entry since nothing points to it, + // but we needed to read the data so now continue + continue; + + exc_next = exc->next; // this gets overwritten during our operations here, so get it now + + exc->fadestart = fadestart; + exc->fadeend = fadeend; + exc->fog = fog; + + exc->rgba = rgba; + exc->fadergba = fadergba; + +#ifdef EXTRACOLORMAPLUMPS + exc->lump = LUMPERROR; + exc->lumpname[0] = 0; +#endif + + existing_exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, fog); + + if (existing_exc) + exc->colormap = existing_exc->colormap; + else + // CONS_Debug(DBG_RENDER, "Creating Colormap: rgba(%d,%d,%d,%d) fadergba(%d,%d,%d,%d)\n", + // R_GetRgbaR(rgba), R_GetRgbaG(rgba), R_GetRgbaB(rgba), R_GetRgbaA(rgba), + // R_GetRgbaR(fadergba), R_GetRgbaG(fadergba), R_GetRgbaB(fadergba), R_GetRgbaA(fadergba)); + exc->colormap = R_CreateLightTable(exc); + + // HACK: If this dummy is a duplicate, we're going to add it + // to the extra_colormaps list anyway. I think this is faster + // than going through every loaded sector and correcting their + // colormap address to the pre-existing one, PER net_colormap entry + R_AddColormapToList(exc); + + if (i < num_net_colormaps-1 && !exc_next) + exc_next = R_CreateDefaultColormap(false); } + + // if we still have a valid net_colormap after iterating up to num_net_colormaps, + // some sector had a colormap index higher than num_net_colormaps. We done goofed or $$$ was corrupted. + // In any case, add them to the colormap list too so that at least the sectors' colormap + // addresses are valid and accounted properly + if (exc_next) + { + existing_exc = R_GetDefaultColormap(); + for (exc = exc_next; exc; exc = exc->next) + { + exc->colormap = existing_exc->colormap; // all our dummies are default values + R_AddColormapToList(exc); + } + } + + // Don't need these anymore + num_net_colormaps = 0; + num_ffloors = 0; + net_colormaps = NULL; } +/// +/// World Archiving +/// + #define SD_FLOORHT 0x01 #define SD_CEILHT 0x02 #define SD_FLOORPIC 0x04 @@ -457,10 +735,14 @@ static void P_NetUnArchivePlayers(void) #define SD_FYOFFS 0x02 #define SD_CXOFFS 0x04 #define SD_CYOFFS 0x08 -#define SD_TAG 0x10 -#define SD_FLOORANG 0x20 -#define SD_CEILANG 0x40 -#define SD_TAGLIST 0x80 +#define SD_FLOORANG 0x10 +#define SD_CEILANG 0x20 +#define SD_TAG 0x40 +#define SD_DIFF3 0x80 + +// diff3 flags +#define SD_TAGLIST 0x01 +#define SD_COLORMAP 0x02 #define LD_FLAG 0x01 #define LD_SPECIAL 0x02 @@ -493,7 +775,10 @@ static void P_NetArchiveWorld(void) mapsidedef_t *msd; maplinedef_t *mld; const sector_t *ss = sectors; - UINT8 diff, diff2; + UINT8 diff, diff2, diff3; + + // initialize colormap vars because paranoia + ClearNetColormaps(); WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD); put = save_p; @@ -520,7 +805,7 @@ static void P_NetArchiveWorld(void) for (i = 0; i < numsectors; i++, ss++, ms++) { - diff = diff2 = 0; + diff = diff2 = diff3 = 0; if (ss->floorheight != SHORT(ms->floorheight)<<FRACBITS) diff |= SD_FLOORHT; if (ss->ceilingheight != SHORT(ms->ceilingheight)<<FRACBITS) @@ -554,7 +839,10 @@ static void P_NetArchiveWorld(void) if (ss->tag != SHORT(ms->tag)) diff2 |= SD_TAG; if (ss->nexttag != ss->spawn_nexttag || ss->firsttag != ss->spawn_firsttag) - diff2 |= SD_TAGLIST; + diff3 |= SD_TAGLIST; + + if (ss->extra_colormap != ss->spawn_extra_colormap) + diff3 |= SD_COLORMAP; // Check if any of the sector's FOFs differ from how they spawned if (ss->ffloors) @@ -571,6 +859,9 @@ static void P_NetArchiveWorld(void) } } + if (diff3) + diff2 |= SD_DIFF3; + if (diff2) diff |= SD_DIFF2; @@ -582,6 +873,8 @@ static void P_NetArchiveWorld(void) WRITEUINT8(put, diff); if (diff & SD_DIFF2) WRITEUINT8(put, diff2); + if (diff2 & SD_DIFF3) + WRITEUINT8(put, diff3); if (diff & SD_FLOORHT) WRITEFIXED(put, ss->floorheight); if (diff & SD_CEILHT) @@ -602,18 +895,22 @@ static void P_NetArchiveWorld(void) WRITEFIXED(put, ss->ceiling_xoffs); if (diff2 & SD_CYOFFS) WRITEFIXED(put, ss->ceiling_yoffs); - if (diff2 & SD_TAG) // save only the tag - WRITEINT16(put, ss->tag); if (diff2 & SD_FLOORANG) WRITEANGLE(put, ss->floorpic_angle); if (diff2 & SD_CEILANG) WRITEANGLE(put, ss->ceilingpic_angle); - if (diff2 & SD_TAGLIST) // save both firsttag and nexttag + if (diff2 & SD_TAG) // save only the tag + WRITEINT16(put, ss->tag); + if (diff3 & SD_TAGLIST) // save both firsttag and nexttag { // either of these could be changed even if tag isn't WRITEINT32(put, ss->firsttag); WRITEINT32(put, ss->nexttag); } + if (diff3 & SD_COLORMAP) + WRITEUINT32(put, CheckAddNetColormapToList(ss->extra_colormap)); + // returns existing index if already added, or appends to net_colormaps and returns new index + // Special case: save the stats of all modified ffloors along with their ffloor "number"s // we don't bother with ffloors that haven't changed, that would just add to savegame even more than is really needed if (diff & SD_FFLOORS) @@ -650,7 +947,7 @@ static void P_NetArchiveWorld(void) // do lines for (i = 0; i < numlines; i++, mld++, li++) { - diff = diff2 = 0; + diff = diff2 = diff3 = 0; if (li->special != SHORT(mld->special)) diff |= LD_SPECIAL; @@ -742,11 +1039,22 @@ static void P_NetUnArchiveWorld(void) line_t *li; side_t *si; UINT8 *get; - UINT8 diff, diff2; + UINT8 diff, diff2, diff3; if (READUINT32(save_p) != ARCHIVEBLOCK_WORLD) I_Error("Bad $$$.sav at archive block World"); + // initialize colormap vars because paranoia + ClearNetColormaps(); + + // count the level's ffloors so that colormap loading can have an upper limit + for (i = 0; i < numsectors; i++) + { + ffloor_t *rover; + for (rover = sectors[i].ffloors; rover; rover = rover->next) + num_ffloors++; + } + get = save_p; for (;;) @@ -764,6 +1072,10 @@ static void P_NetUnArchiveWorld(void) diff2 = READUINT8(get); else diff2 = 0; + if (diff2 & SD_DIFF3) + diff3 = READUINT8(get); + else + diff3 = 0; if (diff & SD_FLOORHT) sectors[i].floorheight = READFIXED(get); @@ -792,17 +1104,20 @@ static void P_NetUnArchiveWorld(void) sectors[i].ceiling_xoffs = READFIXED(get); if (diff2 & SD_CYOFFS) sectors[i].ceiling_yoffs = READFIXED(get); + if (diff2 & SD_FLOORANG) + sectors[i].floorpic_angle = READANGLE(get); + if (diff2 & SD_CEILANG) + sectors[i].ceilingpic_angle = READANGLE(get); if (diff2 & SD_TAG) sectors[i].tag = READINT16(get); // DON'T use P_ChangeSectorTag - if (diff2 & SD_TAGLIST) + if (diff3 & SD_TAGLIST) { sectors[i].firsttag = READINT32(get); sectors[i].nexttag = READINT32(get); } - if (diff2 & SD_FLOORANG) - sectors[i].floorpic_angle = READANGLE(get); - if (diff2 & SD_CEILANG) - sectors[i].ceilingpic_angle = READANGLE(get); + + if (diff3 & SD_COLORMAP) + sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(get)); if (diff & SD_FFLOORS) { @@ -861,6 +1176,9 @@ static void P_NetUnArchiveWorld(void) diff2 = READUINT8(get); else diff2 = 0; + + diff3 = 0; + if (diff & LD_FLAG) li->flags = READINT16(get); if (diff & LD_SPECIAL) @@ -942,11 +1260,13 @@ typedef enum MD2_EXTVAL1 = 1<<5, MD2_EXTVAL2 = 1<<6, MD2_HNEXT = 1<<7, -#ifdef ESLOPE MD2_HPREV = 1<<8, - MD2_SLOPE = 1<<9 + MD2_FLOORROVER = 1<<9, +#ifdef ESLOPE + MD2_CEILINGROVER = 1<<10, + MD2_SLOPE = 1<<11 #else - MD2_HPREV = 1<<8 + MD2_CEILINGROVER = 1<<10 #endif } mobj_diff2_t; @@ -981,6 +1301,9 @@ typedef enum tc_noenemies, tc_eachtime, tc_disappear, + tc_fade, + tc_fadecolormap, + tc_planedisplace, #ifdef POLYOBJECTS tc_polyrotate, // haleyjd 03/26/06: polyobjects tc_polymove, @@ -989,6 +1312,8 @@ typedef enum tc_polyswingdoor, tc_polyflag, tc_polydisplace, + tc_polyrotdisplace, + tc_polyfade, #endif tc_end } specials_e; @@ -1079,6 +1404,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff |= MD_TICS; if (mobj->sprite != mobj->state->sprite) diff |= MD_SPRITE; + if (mobj->sprite == SPR_PLAY && mobj->sprite2 != 0) + diff |= MD_SPRITE; if (mobj->frame != mobj->state->frame) diff |= MD_FRAME; if (mobj->anim_duration != (UINT16)mobj->state->var2) @@ -1102,7 +1429,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff |= MD_TRACER; if (mobj->friction != ORIG_FRICTION) diff |= MD_FRICTION; - if (mobj->movefactor != ORIG_FRICTION_FACTOR) + if (mobj->movefactor != FRACUNIT) diff |= MD_MOVEFACTOR; if (mobj->fuse) diff |= MD_FUSE; @@ -1138,6 +1465,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_HNEXT; if (mobj->hprev) diff2 |= MD2_HPREV; + if (mobj->floorrover) + diff2 |= MD2_FLOORROVER; + if (mobj->ceilingrover) + diff2 |= MD2_CEILINGROVER; #ifdef ESLOPE if (mobj->standingslope) diff2 |= MD2_SLOPE; @@ -1161,6 +1492,46 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, mobj->floorz); WRITEFIXED(save_p, mobj->ceilingz); + if (diff2 & MD2_FLOORROVER) + { + ffloor_t *rover; + size_t i = 0; + UINT32 roverindex = 0; + + for (rover = mobj->floorrover->target->ffloors; rover; rover = rover->next) + { + if (rover == mobj->floorrover) + { + roverindex = i; + break; + } + i++; + } + + WRITEUINT32(save_p, (UINT32)(mobj->floorrover->target - sectors)); + WRITEUINT32(save_p, rover ? roverindex : i); // store max index to denote invalid ffloor ref + } + + if (diff2 & MD2_CEILINGROVER) + { + ffloor_t *rover; + size_t i = 0; + UINT32 roverindex = 0; + + for (rover = mobj->ceilingrover->target->ffloors; rover; rover = rover->next) + { + if (rover == mobj->ceilingrover) + { + roverindex = i; + break; + } + i++; + } + + WRITEUINT32(save_p, (UINT32)(mobj->ceilingrover->target - sectors)); + WRITEUINT32(save_p, rover ? roverindex : i); // store max index to denote invalid ffloor ref + } + if (diff & MD_SPAWNPOINT) { size_t z; @@ -1202,8 +1573,11 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT16(save_p, mobj->state-states); if (diff & MD_TICS) WRITEINT32(save_p, mobj->tics); - if (diff & MD_SPRITE) + if (diff & MD_SPRITE) { WRITEUINT16(save_p, mobj->sprite); + if (mobj->sprite == SPR_PLAY) + WRITEUINT8(save_p, mobj->sprite2); + } if (diff & MD_FRAME) { WRITEUINT32(save_p, mobj->frame); @@ -1505,8 +1879,11 @@ static void SaveLightlevelThinker(const thinker_t *th, const UINT8 type) const lightlevel_t *ht = (const void *)th; WRITEUINT8(save_p, type); WRITEUINT32(save_p, SaveSector(ht->sector)); - WRITEINT32(save_p, ht->destlevel); - WRITEINT32(save_p, ht->speed); + WRITEINT16(save_p, ht->sourcelevel); + WRITEINT16(save_p, ht->destlevel); + WRITEFIXED(save_p, ht->fixedcurlevel); + WRITEFIXED(save_p, ht->fixedpertic); + WRITEINT32(save_p, ht->timer); } // @@ -1542,6 +1919,66 @@ static void SaveDisappearThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->exists); } +// +// SaveFadeThinker +// +// Saves a fade_t thinker +// +static void SaveFadeThinker(const thinker_t *th, const UINT8 type) +{ + const fade_t *ht = (const void *)th; + WRITEUINT8(save_p, type); + WRITEUINT32(save_p, CheckAddNetColormapToList(ht->dest_exc)); + WRITEUINT32(save_p, ht->sectornum); + WRITEUINT32(save_p, ht->ffloornum); + WRITEINT32(save_p, ht->alpha); + WRITEINT16(save_p, ht->sourcevalue); + WRITEINT16(save_p, ht->destvalue); + WRITEINT16(save_p, ht->destlightlevel); + WRITEINT16(save_p, ht->speed); + WRITEUINT8(save_p, (UINT8)ht->ticbased); + WRITEINT32(save_p, ht->timer); + WRITEUINT8(save_p, ht->doexists); + WRITEUINT8(save_p, ht->dotranslucent); + WRITEUINT8(save_p, ht->dolighting); + WRITEUINT8(save_p, ht->docolormap); + WRITEUINT8(save_p, ht->docollision); + WRITEUINT8(save_p, ht->doghostfade); + WRITEUINT8(save_p, ht->exactalpha); +} + +// +// SaveFadeColormapThinker +// +// Saves a fadecolormap_t thinker +// +static void SaveFadeColormapThinker(const thinker_t *th, const UINT8 type) +{ + const fadecolormap_t *ht = (const void *)th; + WRITEUINT8(save_p, type); + WRITEUINT32(save_p, SaveSector(ht->sector)); + WRITEUINT32(save_p, CheckAddNetColormapToList(ht->source_exc)); + WRITEUINT32(save_p, CheckAddNetColormapToList(ht->dest_exc)); + WRITEUINT8(save_p, (UINT8)ht->ticbased); + WRITEINT32(save_p, ht->duration); + WRITEINT32(save_p, ht->timer); +} + +// +// SavePlaneDisplaceThinker +// +// Saves a planedisplace_t thinker +// +static void SavePlaneDisplaceThinker(const thinker_t *th, const UINT8 type) +{ + const planedisplace_t *ht = (const void *)th; + WRITEUINT8(save_p, type); + WRITEINT32(save_p, ht->affectee); + WRITEINT32(save_p, ht->control); + WRITEFIXED(save_p, ht->last_height); + WRITEFIXED(save_p, ht->speed); + WRITEUINT8(save_p, ht->type); +} #ifdef POLYOBJECTS // @@ -1652,6 +2089,31 @@ static void SavePolydisplaceThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->oldHeights); } +static void SavePolyrotdisplaceThinker(const thinker_t *th, const UINT8 type) +{ + const polyrotdisplace_t *ht = (const void *)th; + WRITEUINT8(save_p, type); + WRITEINT32(save_p, ht->polyObjNum); + WRITEUINT32(save_p, SaveSector(ht->controlSector)); + WRITEFIXED(save_p, ht->rotscale); + WRITEUINT8(save_p, ht->turnobjs); + WRITEFIXED(save_p, ht->oldHeights); +} + +static void SavePolyfadeThinker(const thinker_t *th, const UINT8 type) +{ + const polyfade_t *ht = (const void *)th; + WRITEUINT8(save_p, type); + WRITEINT32(save_p, ht->polyObjNum); + WRITEINT32(save_p, ht->sourcevalue); + WRITEINT32(save_p, ht->destvalue); + WRITEUINT8(save_p, (UINT8)ht->docollision); + WRITEUINT8(save_p, (UINT8)ht->doghostfade); + WRITEUINT8(save_p, (UINT8)ht->ticbased); + WRITEINT32(save_p, ht->duration); + WRITEINT32(save_p, ht->timer); +} + #endif /* // @@ -1832,6 +2294,21 @@ static void P_NetArchiveThinkers(void) SaveDisappearThinker(th, tc_disappear); continue; } + else if (th->function.acp1 == (actionf_p1)T_Fade) + { + SaveFadeThinker(th, tc_fade); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_FadeColormap) + { + SaveFadeColormapThinker(th, tc_fadecolormap); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_PlaneDisplace) + { + SavePlaneDisplaceThinker(th, tc_planedisplace); + continue; + } #ifdef POLYOBJECTS else if (th->function.acp1 == (actionf_p1)T_PolyObjRotate) { @@ -1868,6 +2345,16 @@ static void P_NetArchiveThinkers(void) SavePolydisplaceThinker(th, tc_polydisplace); continue; } + else if (th->function.acp1 == (actionf_p1)T_PolyObjRotDisplace) + { + SavePolyrotdisplaceThinker(th, tc_polyrotdisplace); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_PolyObjFade) + { + SavePolyfadeThinker(th, tc_polyfade); + continue; + } #endif #ifdef PARANOIA else if (th->function.acv != P_RemoveThinkerDelayed) // wait garbage collection @@ -1939,6 +2426,7 @@ static void LoadMobjThinker(actionf_p1 thinker) UINT16 diff2; INT32 i; fixed_t z, floorz, ceilingz; + ffloor_t *floorrover = NULL, *ceilingrover = NULL; diff = READUINT32(save_p); if (diff & MD_MORE) @@ -1952,13 +2440,45 @@ static void LoadMobjThinker(actionf_p1 thinker) floorz = READFIXED(save_p); ceilingz = READFIXED(save_p); + if (diff2 & MD2_FLOORROVER) + { + size_t floor_sectornum = (size_t)READUINT32(save_p); + size_t floor_rovernum = (size_t)READUINT32(save_p); + ffloor_t *rover = NULL; + size_t rovernum = 0; + + for (rover = sectors[floor_sectornum].ffloors; rover; rover = rover->next) + { + if (rovernum == floor_rovernum) + break; + rovernum++; + } + floorrover = rover; + } + + if (diff2 & MD2_CEILINGROVER) + { + size_t ceiling_sectornum = (size_t)READUINT32(save_p); + size_t ceiling_rovernum = (size_t)READUINT32(save_p); + ffloor_t *rover = NULL; + size_t rovernum = 0; + + for (rover = sectors[ceiling_sectornum].ffloors; rover; rover = rover->next) + { + if (rovernum == ceiling_rovernum) + break; + rovernum++; + } + ceilingrover = rover; + } + if (diff & MD_SPAWNPOINT) { UINT16 spawnpointnum = READUINT16(save_p); if (mapthings[spawnpointnum].type == 1705 || mapthings[spawnpointnum].type == 1713) // NiGHTS Hoop special case { - P_SpawnHoopsAndRings(&mapthings[spawnpointnum]); + P_SpawnHoopsAndRings(&mapthings[spawnpointnum], false); return; } @@ -1976,6 +2496,8 @@ static void LoadMobjThinker(actionf_p1 thinker) mobj->z = z; mobj->floorz = floorz; mobj->ceilingz = ceilingz; + mobj->floorrover = floorrover; + mobj->ceilingrover = ceilingrover; if (diff & MD_TYPE) mobj->type = READUINT32(save_p); @@ -2045,10 +2567,16 @@ static void LoadMobjThinker(actionf_p1 thinker) mobj->tics = READINT32(save_p); else mobj->tics = mobj->state->tics; - if (diff & MD_SPRITE) + if (diff & MD_SPRITE) { mobj->sprite = READUINT16(save_p); - else + if (mobj->sprite == SPR_PLAY) + mobj->sprite2 = READUINT8(save_p); + } + else { mobj->sprite = mobj->state->sprite; + if (mobj->sprite == SPR_PLAY) + mobj->sprite2 = mobj->state->frame&FF_FRAMEMASK; + } if (diff & MD_FRAME) { mobj->frame = READUINT32(save_p); @@ -2093,7 +2621,7 @@ static void LoadMobjThinker(actionf_p1 thinker) if (diff & MD_MOVEFACTOR) mobj->movefactor = READFIXED(save_p); else - mobj->movefactor = ORIG_FRICTION_FACTOR; + mobj->movefactor = FRACUNIT; if (diff & MD_FUSE) mobj->fuse = READINT32(save_p); if (diff & MD_WATERTOP) @@ -2457,8 +2985,11 @@ static inline void LoadLightlevelThinker(actionf_p1 thinker) lightlevel_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; ht->sector = LoadSector(READUINT32(save_p)); - ht->destlevel = READINT32(save_p); - ht->speed = READINT32(save_p); + ht->sourcelevel = READINT16(save_p); + ht->destlevel = READINT16(save_p); + ht->fixedcurlevel = READFIXED(save_p); + ht->fixedpertic = READFIXED(save_p); + ht->timer = READINT32(save_p); if (ht->sector) ht->sector->lightingdata = ht; P_AddThinker(&ht->thinker); @@ -2499,6 +3030,89 @@ static inline void LoadDisappearThinker(actionf_p1 thinker) P_AddThinker(&ht->thinker); } +// +// LoadFadeThinker +// +// Loads a fade_t thinker +// +static inline void LoadFadeThinker(actionf_p1 thinker) +{ + sector_t *ss; + fade_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->dest_exc = GetNetColormapFromList(READUINT32(save_p)); + ht->sectornum = READUINT32(save_p); + ht->ffloornum = READUINT32(save_p); + ht->alpha = READINT32(save_p); + ht->sourcevalue = READINT16(save_p); + ht->destvalue = READINT16(save_p); + ht->destlightlevel = READINT16(save_p); + ht->speed = READINT16(save_p); + ht->ticbased = (boolean)READUINT8(save_p); + ht->timer = READINT32(save_p); + ht->doexists = READUINT8(save_p); + ht->dotranslucent = READUINT8(save_p); + ht->dolighting = READUINT8(save_p); + ht->docolormap = READUINT8(save_p); + ht->docollision = READUINT8(save_p); + ht->doghostfade = READUINT8(save_p); + ht->exactalpha = READUINT8(save_p); + + ss = LoadSector(ht->sectornum); + if (ss) + { + size_t j = 0; // ss->ffloors is saved as ffloor #0, ss->ffloors->next is #1, etc + ffloor_t *rover; + for (rover = ss->ffloors; rover; rover = rover->next) + { + if (j == ht->ffloornum) + { + ht->rover = rover; + rover->fadingdata = ht; + break; + } + j++; + } + } + P_AddThinker(&ht->thinker); +} + +// LoadFadeColormapThinker +// +// Loads a fadecolormap_t from a save game +// +static inline void LoadFadeColormapThinker(actionf_p1 thinker) +{ + fadecolormap_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->sector = LoadSector(READUINT32(save_p)); + ht->source_exc = GetNetColormapFromList(READUINT32(save_p)); + ht->dest_exc = GetNetColormapFromList(READUINT32(save_p)); + ht->ticbased = (boolean)READUINT8(save_p); + ht->duration = READINT32(save_p); + ht->timer = READINT32(save_p); + if (ht->sector) + ht->sector->fadecolormapdata = ht; + P_AddThinker(&ht->thinker); +} + +// +// LoadPlaneDisplaceThinker +// +// Loads a planedisplace_t thinker +// +static inline void LoadPlaneDisplaceThinker(actionf_p1 thinker) +{ + planedisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->affectee = READINT32(save_p); + ht->control = READINT32(save_p); + ht->last_height = READFIXED(save_p); + ht->speed = READFIXED(save_p); + ht->type = READUINT8(save_p); + P_AddThinker(&ht->thinker); +} + #ifdef POLYOBJECTS // @@ -2619,6 +3233,38 @@ static inline void LoadPolydisplaceThinker(actionf_p1 thinker) ht->oldHeights = READFIXED(save_p); P_AddThinker(&ht->thinker); } + +static inline void LoadPolyrotdisplaceThinker(actionf_p1 thinker) +{ + polyrotdisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->polyObjNum = READINT32(save_p); + ht->controlSector = LoadSector(READUINT32(save_p)); + ht->rotscale = READFIXED(save_p); + ht->turnobjs = READUINT8(save_p); + ht->oldHeights = READFIXED(save_p); + P_AddThinker(&ht->thinker); +} + +// +// LoadPolyfadeThinker +// +// Loads a polyfadet_t thinker +// +static void LoadPolyfadeThinker(actionf_p1 thinker) +{ + polyfade_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->polyObjNum = READINT32(save_p); + ht->sourcevalue = READINT32(save_p); + ht->destvalue = READINT32(save_p); + ht->docollision = (boolean)READUINT8(save_p); + ht->doghostfade = (boolean)READUINT8(save_p); + ht->ticbased = (boolean)READUINT8(save_p); + ht->duration = READINT32(save_p); + ht->timer = READINT32(save_p); + P_AddThinker(&ht->thinker); +} #endif /* @@ -2668,7 +3314,7 @@ static void P_NetUnArchiveThinkers(void) // clear sector thinker pointers so they don't point to non-existant thinkers for all of eternity for (i = 0; i < numsectors; i++) { - sectors[i].floordata = sectors[i].ceilingdata = sectors[i].lightingdata = NULL; + sectors[i].floordata = sectors[i].ceilingdata = sectors[i].lightingdata = sectors[i].fadecolormapdata = NULL; } // read in saved thinkers @@ -2788,6 +3434,18 @@ static void P_NetUnArchiveThinkers(void) case tc_disappear: LoadDisappearThinker((actionf_p1)T_Disappear); break; + + case tc_fade: + LoadFadeThinker((actionf_p1)T_Fade); + break; + + case tc_fadecolormap: + LoadFadeColormapThinker((actionf_p1)T_FadeColormap); + break; + + case tc_planedisplace: + LoadPlaneDisplaceThinker((actionf_p1)T_PlaneDisplace); + break; #ifdef POLYOBJECTS case tc_polyrotate: LoadPolyrotatetThinker((actionf_p1)T_PolyObjRotate); @@ -2816,6 +3474,14 @@ static void P_NetUnArchiveThinkers(void) case tc_polydisplace: LoadPolydisplaceThinker((actionf_p1)T_PolyObjDisplace); break; + + case tc_polyrotdisplace: + LoadPolyrotdisplaceThinker((actionf_p1)T_PolyObjRotDisplace); + break; + + case tc_polyfade: + LoadPolyfadeThinker((actionf_p1)T_PolyObjFade); + break; #endif case tc_scroll: LoadScrollThinker((actionf_p1)T_Scroll); @@ -2872,7 +3538,7 @@ static inline void P_ArchivePolyObj(polyobj_t *po) if (po->flags != po->spawnflags) diff |= PD_FLAGS; - if (po->translucency != 0) + if (po->translucency != po->spawntrans) diff |= PD_TRANS; WRITEUINT8(save_p, diff); @@ -3040,6 +3706,20 @@ static void P_RelinkPointers(void) if (!P_SetTarget(&mobj->player->awayviewmobj, P_FindNewPosition(temp))) CONS_Debug(DBG_GAMELOGIC, "awayviewmobj not found on %d\n", mobj->type); } + if (mobj->player && mobj->player->followmobj) + { + temp = (UINT32)(size_t)mobj->player->followmobj; + mobj->player->followmobj = NULL; + if (!P_SetTarget(&mobj->player->followmobj, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "followmobj not found on %d\n", mobj->type); + } + if (mobj->player && mobj->player->drone) + { + temp = (UINT32)(size_t)mobj->player->drone; + mobj->player->drone = NULL; + if (!P_SetTarget(&mobj->player->drone, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "drone not found on %d\n", mobj->type); + } } } } @@ -3139,9 +3819,10 @@ static inline void P_ArchiveMisc(void) else WRITEINT16(save_p, gamemap); - lastmapsaved = gamemap; + //lastmapsaved = gamemap; + lastmaploaded = gamemap; - WRITEUINT16(save_p, (botskin ? (emeralds|(1<<10)) : emeralds)+357); + WRITEUINT16(save_p, emeralds+357); WRITESTRINGN(save_p, timeattackfolder, sizeof(timeattackfolder)); } @@ -3164,15 +3845,13 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride) if(!mapheaderinfo[gamemap-1]) P_AllocMapHeader(gamemap-1); - lastmapsaved = gamemap; + //lastmapsaved = gamemap; + lastmaploaded = gamemap; tokenlist = 0; token = 0; savedata.emeralds = READUINT16(save_p)-357; - if (savedata.emeralds & (1<<10)) - savedata.botcolor = 0xFF; - savedata.emeralds &= 0xff; READSTRINGN(save_p, testname, sizeof(testname)); @@ -3207,7 +3886,7 @@ static void P_NetArchiveMisc(void) WRITEUINT32(save_p, tokenlist); WRITEUINT32(save_p, leveltime); - WRITEUINT32(save_p, totalrings); + WRITEUINT32(save_p, ssspheres); WRITEINT16(save_p, lastmap); WRITEUINT16(save_p, emeralds); @@ -3284,7 +3963,7 @@ static inline boolean P_NetUnArchiveMisc(void) // get the time leveltime = READUINT32(save_p); - totalrings = READUINT32(save_p); + ssspheres = READUINT32(save_p); lastmap = READINT16(save_p); emeralds = READUINT16(save_p); @@ -3362,6 +4041,7 @@ void P_SaveNetGame(void) #endif P_NetArchiveThinkers(); P_NetArchiveSpecials(); + P_NetArchiveColormaps(); } #ifdef HAVE_BLUA LUA_Archive(); @@ -3404,6 +4084,7 @@ boolean P_LoadNetGame(void) #endif P_NetUnArchiveThinkers(); P_NetUnArchiveSpecials(); + P_NetUnArchiveColormaps(); P_RelinkPointers(); P_FinishMobjs(); } diff --git a/src/p_saveg.h b/src/p_saveg.h index 0992f1185db1fc6c783b909f6c32b142234469d9..2f5e88046a85d22aa84083d92444f2d7996e85ef 100644 --- a/src/p_saveg.h +++ b/src/p_saveg.h @@ -30,14 +30,13 @@ mobj_t *P_FindNewPosition(UINT32 oldposition); typedef struct { - UINT8 skincolor; UINT8 skin; UINT8 botskin; - UINT8 botcolor; INT32 score; INT32 lives; INT32 continues; UINT16 emeralds; + UINT8 numgameovers; } savedata_t; extern savedata_t savedata; diff --git a/src/p_setup.c b/src/p_setup.c index b2636c3505f0efb327c07ff92caf1b3ef8ee2086..9c4ddd87c83704630c5049bc7341b9d2fed07081 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -56,8 +56,11 @@ #include "filesrch.h" // refreshdirmenu -// wipes -#include "f_finale.h" +#ifdef HAVE_BLUA +#include "lua_hud.h" // level title +#endif + +#include "f_finale.h" // wipes #include "md5.h" // map MD5 @@ -65,7 +68,7 @@ #include "lua_script.h" #include "lua_hook.h" -#if defined (_WIN32) || defined (_WIN32_WCE) +#ifdef _WIN32 #include <malloc.h> #include <math.h> #endif @@ -100,6 +103,7 @@ side_t *sides; mapthing_t *mapthings; INT32 numstarposts; boolean levelloading; +UINT8 levelfadecol; // BLOCKMAP // Created from axis aligned bounding box @@ -162,6 +166,33 @@ FUNCNORETURN static ATTRNORETURN void CorruptMapError(const char *msg) I_Error("Invalid or corrupt map.\nLook in log file or text console for technical details."); } +/** Sets a header's flickies to be equivalent to the original Freed Animals + * + * \param i The header to set flickies for + */ +void P_SetDemoFlickies(INT16 i) +{ + mapheaderinfo[i]->numFlickies = 5; + mapheaderinfo[i]->flickies = Z_Realloc(mapheaderinfo[i]->flickies, 5*sizeof(mobjtype_t), PU_STATIC, NULL); + mapheaderinfo[i]->flickies[0] = MT_FLICKY_02/*MT_BUNNY*/; + mapheaderinfo[i]->flickies[1] = MT_FLICKY_01/*MT_BIRD*/; + mapheaderinfo[i]->flickies[2] = MT_FLICKY_12/*MT_MOUSE*/; + mapheaderinfo[i]->flickies[3] = MT_FLICKY_11/*MT_COW*/; + mapheaderinfo[i]->flickies[4] = MT_FLICKY_03/*MT_CHICKEN*/; +} + +/** Clears a header's flickies + * + * \param i The header to clear flickies for + */ +void P_DeleteFlickies(INT16 i) +{ + if (mapheaderinfo[i]->flickies) + Z_Free(mapheaderinfo[i]->flickies); + mapheaderinfo[i]->flickies = NULL; + mapheaderinfo[i]->numFlickies = 0; +} + #define NUMLAPS_DEFAULT 4 /** Clears the data from a single map header. @@ -172,74 +203,47 @@ FUNCNORETURN static ATTRNORETURN void CorruptMapError(const char *msg) static void P_ClearSingleMapHeaderInfo(INT16 i) { const INT16 num = (INT16)(i-1); - DEH_WriteUndoline("LEVELNAME", mapheaderinfo[num]->lvlttl, UNDO_NONE); mapheaderinfo[num]->lvlttl[0] = '\0'; - DEH_WriteUndoline("SUBTITLE", mapheaderinfo[num]->subttl, UNDO_NONE); + mapheaderinfo[num]->selectheading[0] = '\0'; mapheaderinfo[num]->subttl[0] = '\0'; - DEH_WriteUndoline("ACT", va("%d", mapheaderinfo[num]->actnum), UNDO_NONE); mapheaderinfo[num]->actnum = 0; - DEH_WriteUndoline("TYPEOFLEVEL", va("%d", mapheaderinfo[num]->typeoflevel), UNDO_NONE); mapheaderinfo[num]->typeoflevel = 0; - DEH_WriteUndoline("NEXTLEVEL", va("%d", mapheaderinfo[num]->nextlevel), UNDO_NONE); mapheaderinfo[num]->nextlevel = (INT16)(i + 1); - DEH_WriteUndoline("MUSIC", mapheaderinfo[num]->musname, UNDO_NONE); + mapheaderinfo[num]->startrings = 0; snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i)); mapheaderinfo[num]->musname[6] = 0; - DEH_WriteUndoline("MUSICTRACK", va("%d", mapheaderinfo[num]->mustrack), UNDO_NONE); mapheaderinfo[num]->mustrack = 0; - DEH_WriteUndoline("MUSICPOS", va("%d", mapheaderinfo[num]->muspos), UNDO_NONE); mapheaderinfo[num]->muspos = 0; - DEH_WriteUndoline("MUSICINTERFADEOUT", va("%d", mapheaderinfo[num]->musinterfadeout), UNDO_NONE); mapheaderinfo[num]->musinterfadeout = 0; - DEH_WriteUndoline("MUSICINTER", mapheaderinfo[num]->musintername, UNDO_NONE); mapheaderinfo[num]->musintername[0] = '\0'; - DEH_WriteUndoline("FORCECHARACTER", va("%d", mapheaderinfo[num]->forcecharacter), UNDO_NONE); mapheaderinfo[num]->forcecharacter[0] = '\0'; - DEH_WriteUndoline("WEATHER", va("%d", mapheaderinfo[num]->weather), UNDO_NONE); mapheaderinfo[num]->weather = 0; - DEH_WriteUndoline("SKYNUM", va("%d", mapheaderinfo[num]->skynum), UNDO_NONE); mapheaderinfo[num]->skynum = 1; - DEH_WriteUndoline("SKYBOXSCALEX", va("%d", mapheaderinfo[num]->skybox_scalex), UNDO_NONE); mapheaderinfo[num]->skybox_scalex = 16; - DEH_WriteUndoline("SKYBOXSCALEY", va("%d", mapheaderinfo[num]->skybox_scaley), UNDO_NONE); mapheaderinfo[num]->skybox_scaley = 16; - DEH_WriteUndoline("SKYBOXSCALEZ", va("%d", mapheaderinfo[num]->skybox_scalez), UNDO_NONE); mapheaderinfo[num]->skybox_scalez = 16; - DEH_WriteUndoline("INTERSCREEN", mapheaderinfo[num]->interscreen, UNDO_NONE); mapheaderinfo[num]->interscreen[0] = '#'; - DEH_WriteUndoline("RUNSOC", mapheaderinfo[num]->runsoc, UNDO_NONE); mapheaderinfo[num]->runsoc[0] = '#'; - DEH_WriteUndoline("SCRIPTNAME", mapheaderinfo[num]->scriptname, UNDO_NONE); mapheaderinfo[num]->scriptname[0] = '#'; - DEH_WriteUndoline("PRECUTSCENENUM", va("%d", mapheaderinfo[num]->precutscenenum), UNDO_NONE); mapheaderinfo[num]->precutscenenum = 0; - DEH_WriteUndoline("CUTSCENENUM", va("%d", mapheaderinfo[num]->cutscenenum), UNDO_NONE); mapheaderinfo[num]->cutscenenum = 0; - DEH_WriteUndoline("COUNTDOWN", va("%d", mapheaderinfo[num]->countdown), UNDO_NONE); mapheaderinfo[num]->countdown = 0; - DEH_WriteUndoline("PALLETE", va("%u", mapheaderinfo[num]->palette), UNDO_NONE); mapheaderinfo[num]->palette = UINT16_MAX; - DEH_WriteUndoline("NUMLAPS", va("%u", mapheaderinfo[num]->numlaps), UNDO_NONE); mapheaderinfo[num]->numlaps = NUMLAPS_DEFAULT; - DEH_WriteUndoline("UNLOCKABLE", va("%s", mapheaderinfo[num]->unlockrequired), UNDO_NONE); mapheaderinfo[num]->unlockrequired = -1; - DEH_WriteUndoline("LEVELSELECT", va("%d", mapheaderinfo[num]->levelselect), UNDO_NONE); mapheaderinfo[num]->levelselect = 0; - DEH_WriteUndoline("BONUSTYPE", va("%d", mapheaderinfo[num]->bonustype), UNDO_NONE); mapheaderinfo[num]->bonustype = 0; - DEH_WriteUndoline("SAVEOVERRIDE", va("%d", mapheaderinfo[num]->saveoverride), UNDO_NONE); - mapheaderinfo[num]->saveoverride = SAVE_DEFAULT; - DEH_WriteUndoline("LEVELFLAGS", va("%d", mapheaderinfo[num]->levelflags), UNDO_NONE); + mapheaderinfo[num]->maxbonuslives = -1; mapheaderinfo[num]->levelflags = 0; - DEH_WriteUndoline("MENUFLAGS", va("%d", mapheaderinfo[num]->menuflags), UNDO_NONE); mapheaderinfo[num]->menuflags = 0; - // TODO grades support for delfile (pfft yeah right) +#if 1 // equivalent to "FlickyList = DEMO" + P_SetDemoFlickies(num); +#else // equivalent to "FlickyList = NONE" + P_DeleteFlickies(num); +#endif P_DeleteGrades(num); - // an even further impossibility, delfile custom opts support mapheaderinfo[num]->customopts = NULL; mapheaderinfo[num]->numCustomOptions = 0; - - DEH_WriteUndoline(va("# uload for map %d", i), NULL, UNDO_DONE); } /** Allocates a new map-header structure. @@ -251,6 +255,7 @@ void P_AllocMapHeader(INT16 i) if (!mapheaderinfo[i]) { mapheaderinfo[i] = Z_Malloc(sizeof(mapheader_t), PU_STATIC, NULL); + mapheaderinfo[i]->flickies = NULL; mapheaderinfo[i]->grades = NULL; } P_ClearSingleMapHeaderInfo(i + 1); @@ -518,10 +523,6 @@ static void P_LoadSubsectors(lumpnum_t lumpnum) Z_Free(data); } -// -// P_LoadSectors -// - // // levelflats // @@ -547,24 +548,21 @@ size_t P_PrecacheLevelFlats(void) return flatmemory; } -// help function for P_LoadSectors, find a flat in the active wad files, +// Auxiliary function. Find a flat in the active wad files, // allocate an id for it, and set the levelflat (to speedup search) -// INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat) { size_t i; - // - // first scan through the already found flats - // + // Scan through the already found flats, break if it matches. for (i = 0; i < numlevelflats; i++, levelflat++) - if (strnicmp(levelflat->name,flatname,8)==0) + if (strnicmp(levelflat->name, flatname, 8) == 0) break; - // that flat was already found in the level, return the id + // If there is no match, make room for a new flat. if (i == numlevelflats) { - // store the name + // Store the name. strlcpy(levelflat->name, flatname, sizeof (levelflat->name)); strupr(levelflat->name); @@ -684,6 +682,7 @@ static void P_LoadRawSectors(UINT8 *data, size_t i) ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats); ss->lightlevel = SHORT(ms->lightlevel); + ss->spawn_lightlevel = SHORT(ms->lightlevel); ss->special = SHORT(ms->special); ss->tag = SHORT(ms->tag); ss->nexttag = ss->firsttag = -1; @@ -719,12 +718,12 @@ static void P_LoadRawSectors(UINT8 *data, size_t i) ss->moved = true; ss->extra_colormap = NULL; + ss->spawn_extra_colormap = NULL; ss->floor_xoffs = ss->ceiling_xoffs = ss->floor_yoffs = ss->ceiling_yoffs = 0; ss->spawn_flr_xoffs = ss->spawn_ceil_xoffs = ss->spawn_flr_yoffs = ss->spawn_ceil_yoffs = 0; ss->floorpic_angle = ss->ceilingpic_angle = 0; ss->spawn_flrpic_angle = ss->spawn_ceilpic_angle = 0; - ss->bottommap = ss->midmap = ss->topmap = -1; ss->gravity = NULL; ss->cullheight = NULL; ss->verticalflip = false; @@ -815,7 +814,7 @@ void P_ReloadRings(void) mapthing_t *hoopsToRespawn[4096]; mapthing_t *mt = mapthings; - // scan the thinkers to find rings/wings/hoops to unset + // scan the thinkers to find rings/spheres/hoops to unset for (th = thinkercap.next; th != &thinkercap; th = th->next) { if (th->function.acp1 != (actionf_p1)P_MobjThinker) @@ -833,7 +832,9 @@ void P_ReloadRings(void) } continue; } - if (!(mo->type == MT_RING || mo->type == MT_NIGHTSWING || mo->type == MT_COIN || mo->type == MT_BLUEBALL)) + if (!(mo->type == MT_RING || mo->type == MT_COIN + || mo->type == MT_BLUESPHERE || mo->type == MT_BOMBSPHERE + || mo->type == MT_NIGHTSCHIP || mo->type == MT_NIGHTSSTAR)) continue; // Don't auto-disintegrate things being pulled to us @@ -847,9 +848,10 @@ void P_ReloadRings(void) for (i = 0; i < nummapthings; i++, mt++) { // Notice an omission? We handle hoops differently. - if (mt->type == 300 || mt->type == 308 || mt->type == 309 - || mt->type == 1706 || (mt->type >= 600 && mt->type <= 609) - || mt->type == 1800) + if (mt->type == mobjinfo[MT_RING].doomednum || mt->type == mobjinfo[MT_COIN].doomednum + || mt->type == mobjinfo[MT_REDTEAMRING].doomednum || mt->type == mobjinfo[MT_BLUETEAMRING].doomednum + || mt->type == mobjinfo[MT_BLUESPHERE].doomednum || mt->type == mobjinfo[MT_BOMBSPHERE].doomednum + || (mt->type >= 600 && mt->type <= 609)) // circles and diagonals { mt->mobj = NULL; @@ -857,12 +859,46 @@ void P_ReloadRings(void) mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS) ->sector->floorheight>>FRACBITS); - P_SpawnHoopsAndRings (mt); + P_SpawnHoopsAndRings(mt, +#ifdef MANIASPHERES + true); +#else + !G_IsSpecialStage(gamemap)); // prevent flashing spheres in special stages +#endif } } for (i = 0; i < numHoops; i++) { - P_SpawnHoopsAndRings(hoopsToRespawn[i]); + P_SpawnHoopsAndRings(hoopsToRespawn[i], false); + } +} + +void P_SwitchSpheresBonusMode(boolean bonustime) +{ + mobj_t *mo; + thinker_t *th; + +#ifndef MANIASPHERES + if (G_IsSpecialStage(gamemap)) // prevent flashing spheres in special stages + return; +#endif + + // scan the thinkers to find spheres to switch + for (th = thinkercap.next; th != &thinkercap; th = th->next) + { + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; + + mo = (mobj_t *)th; + + if (mo->type != MT_BLUESPHERE && mo->type != MT_NIGHTSCHIP + && mo->type != MT_FLINGBLUESPHERE && mo->type != MT_FLINGNIGHTSCHIP) + continue; + + if (!mo->health) + continue; + + P_SetMobjState(mo, ((bonustime) ? mo->info->raisestate : mo->info->spawnstate)); } } @@ -929,10 +965,6 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum) } #endif -// -// P_LoadThings -// - static void P_PrepareRawThings(UINT8 *data, size_t i) { mapthing_t *mt; @@ -975,7 +1007,7 @@ static void P_PrepareThings(lumpnum_t lumpnum) Z_Free(data); } -static void P_LoadThings(void) +static void P_LoadThings(boolean loademblems) { size_t i; mapthing_t *mt; @@ -1000,6 +1032,9 @@ static void P_LoadThings(void) || mt->type == 1702) // MT_AXISTRANSFERLINE continue; // These were already spawned + if (!loademblems && mt->type == mobjinfo[MT_EMBLEM].doomednum) + continue; + mt->mobj = NULL; P_SpawnMapThing(mt); } @@ -1032,20 +1067,22 @@ static void P_LoadThings(void) } //decrement spawn values to the actual number because zero is valid. - if (emer1) - P_SpawnMobj(huntemeralds[emer1 - 1]->x<<FRACBITS, - huntemeralds[emer1 - 1]->y<<FRACBITS, - huntemeralds[emer1 - 1]->z<<FRACBITS, MT_EMERHUNT); + if (emer1--) + P_SpawnMobj(huntemeralds[emer1]->x<<FRACBITS, + huntemeralds[emer1]->y<<FRACBITS, + huntemeralds[emer1]->z<<FRACBITS, MT_EMERHUNT); - if (emer2) - P_SpawnMobj(huntemeralds[emer2 - 1]->x<<FRACBITS, - huntemeralds[emer2 - 1]->y<<FRACBITS, - huntemeralds[emer2 - 1]->z<<FRACBITS, MT_EMERHUNT); + if (emer2--) + P_SetMobjStateNF(P_SpawnMobj(huntemeralds[emer2]->x<<FRACBITS, + huntemeralds[emer2]->y<<FRACBITS, + huntemeralds[emer2]->z<<FRACBITS, MT_EMERHUNT), + mobjinfo[MT_EMERHUNT].spawnstate+1); - if (emer3) - P_SpawnMobj(huntemeralds[emer3 - 1]->x<<FRACBITS, - huntemeralds[emer3 - 1]->y<<FRACBITS, - huntemeralds[emer3 - 1]->z<<FRACBITS, MT_EMERHUNT); + if (emer3--) + P_SetMobjStateNF(P_SpawnMobj(huntemeralds[emer3]->x<<FRACBITS, + huntemeralds[emer3]->y<<FRACBITS, + huntemeralds[emer3]->z<<FRACBITS, MT_EMERHUNT), + mobjinfo[MT_EMERHUNT].spawnstate+2); } if (metalrecording) // Metal Sonic gets no rings to distract him. @@ -1055,9 +1092,11 @@ static void P_LoadThings(void) mt = mapthings; for (i = 0; i < nummapthings; i++, mt++) { - if (mt->type == 300 || mt->type == 308 || mt->type == 309 - || mt->type == 1706 || (mt->type >= 600 && mt->type <= 609) - || mt->type == 1705 || mt->type == 1713 || mt->type == 1800) + if (mt->type == mobjinfo[MT_RING].doomednum || mt->type == mobjinfo[MT_COIN].doomednum + || mt->type == mobjinfo[MT_REDTEAMRING].doomednum || mt->type == mobjinfo[MT_BLUETEAMRING].doomednum + || mt->type == mobjinfo[MT_BLUESPHERE].doomednum || mt->type == mobjinfo[MT_BOMBSPHERE].doomednum + || (mt->type >= 600 && mt->type <= 609) // circles and diagonals + || mt->type == 1705 || mt->type == 1713) // hoops { mt->mobj = NULL; @@ -1065,57 +1104,11 @@ static void P_LoadThings(void) mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS) ->sector->floorheight>>FRACBITS); - P_SpawnHoopsAndRings (mt); + P_SpawnHoopsAndRings(mt, false); } } } -static inline void P_SpawnEmblems(void) -{ - INT32 i, color; - mobj_t *emblemmobj; - - for (i = 0; i < numemblems; i++) - { - if (emblemlocations[i].level != gamemap || emblemlocations[i].type > ET_SKIN) - continue; - - emblemmobj = P_SpawnMobj(emblemlocations[i].x<<FRACBITS, emblemlocations[i].y<<FRACBITS, - emblemlocations[i].z<<FRACBITS, MT_EMBLEM); - - I_Assert(emblemlocations[i].sprite >= 'A' && emblemlocations[i].sprite <= 'Z'); - P_SetMobjStateNF(emblemmobj, emblemmobj->info->spawnstate + (emblemlocations[i].sprite - 'A')); - - emblemmobj->health = i+1; - color = M_GetEmblemColor(&emblemlocations[i]); - - emblemmobj->color = (UINT8)color; - - if (emblemlocations[i].collected - || (emblemlocations[i].type == ET_SKIN && emblemlocations[i].var != players[0].skin)) - { - P_UnsetThingPosition(emblemmobj); - emblemmobj->flags |= MF_NOCLIP; - emblemmobj->flags &= ~MF_SPECIAL; - emblemmobj->flags |= MF_NOBLOCKMAP; - emblemmobj->frame |= (tr_trans50<<FF_TRANSSHIFT); - P_SetThingPosition(emblemmobj); - } - else - emblemmobj->frame &= ~FF_TRANSMASK; - } -} - -static void P_SpawnSecretItems(boolean loademblems) -{ - // Now let's spawn those funky emblem things! Tails 12-08-2002 - if (netgame || multiplayer || (modifiedgame && !savemoddata)) // No cheating!! - return; - - if (loademblems) - P_SpawnEmblems(); -} - // Experimental groovy write function! void P_WriteThings(lumpnum_t lumpnum) { @@ -1283,7 +1276,8 @@ static void P_LoadLineDefs2(void) ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0; // Repeat count for midtexture - if ((ld->flags & ML_EFFECT5) && (ld->sidenum[1] != 0xffff)) + if ((ld->flags & ML_EFFECT5) && (ld->sidenum[1] != 0xffff) + && !(ld->special >= 300 && ld->special < 500)) // exempt linedef exec specials { sides[ld->sidenum[0]].repeatcnt = (INT16)(((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) >> 12); sides[ld->sidenum[0]].textureoffset = (((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) & 2047) << FRACBITS; @@ -1390,7 +1384,6 @@ static inline void P_LoadSideDefs(lumpnum_t lumpnum) static void P_LoadRawSideDefs2(void *data) { UINT16 i; - INT32 num; for (i = 0; i < numsides; i++) { @@ -1412,117 +1405,23 @@ static void P_LoadRawSideDefs2(void *data) sd->sector = sec = §ors[sector_num]; } - // refined to allow colormaps to work as wall textures if invalid as colormaps - // but valid as textures. - sd->sector = sec = §ors[SHORT(msd->sector)]; + sd->colormap_data = NULL; + // Colormaps! switch (sd->special) { case 63: // variable colormap via 242 linedef case 606: //SoM: 4/4/2000: Just colormap transfer + case 447: // Change colormap of tagged sectors! -- Monster Iestyn 14/06/18 + case 455: // Fade colormaps! mazmazz 9/12/2018 (:flag_us:) // SoM: R_CreateColormap will only create a colormap in software mode... // Perhaps we should just call it instead of doing the calculations here. - if (rendermode == render_soft || rendermode == render_none) - { - if (msd->toptexture[0] == '#' || msd->bottomtexture[0] == '#') - { - sec->midmap = R_CreateColormap(msd->toptexture, msd->midtexture, - msd->bottomtexture); - sd->toptexture = sd->bottomtexture = 0; - } - else - { - if ((num = R_CheckTextureNumForName(msd->toptexture)) == -1) - sd->toptexture = 0; - else - sd->toptexture = num; - if ((num = R_CheckTextureNumForName(msd->midtexture)) == -1) - sd->midtexture = 0; - else - sd->midtexture = num; - if ((num = R_CheckTextureNumForName(msd->bottomtexture)) == -1) - sd->bottomtexture = 0; - else - sd->bottomtexture = num; - } - break; - } -#ifdef HWRENDER - else - { - // for now, full support of toptexture only - if ((msd->toptexture[0] == '#' && msd->toptexture[1] && msd->toptexture[2] && msd->toptexture[3] && msd->toptexture[4] && msd->toptexture[5] && msd->toptexture[6]) - || (msd->bottomtexture[0] == '#' && msd->bottomtexture[1] && msd->bottomtexture[2] && msd->bottomtexture[3] && msd->bottomtexture[4] && msd->bottomtexture[5] && msd->bottomtexture[6])) - { - char *col; - - sec->midmap = R_CreateColormap(msd->toptexture, msd->midtexture, - msd->bottomtexture); - sd->toptexture = sd->bottomtexture = 0; -#define HEX2INT(x) (x >= '0' && x <= '9' ? x - '0' : x >= 'a' && x <= 'f' ? x - 'a' + 10 : x >= 'A' && x <= 'F' ? x - 'A' + 10 : 0) -#define ALPHA2INT(x) (x >= 'a' && x <= 'z' ? x - 'a' : x >= 'A' && x <= 'Z' ? x - 'A' : x >= '0' && x <= '9' ? 25 : 0) - sec->extra_colormap = &extra_colormaps[sec->midmap]; - - if (msd->toptexture[0] == '#' && msd->toptexture[1] && msd->toptexture[2] && msd->toptexture[3] && msd->toptexture[4] && msd->toptexture[5] && msd->toptexture[6]) - { - col = msd->toptexture; - - sec->extra_colormap->rgba = - (HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) + - (HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) + - (HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16); - - // alpha - if (msd->toptexture[7]) - sec->extra_colormap->rgba += (ALPHA2INT(col[7]) << 24); - else - sec->extra_colormap->rgba += (25 << 24); - } - else - sec->extra_colormap->rgba = 0; - - if (msd->bottomtexture[0] == '#' && msd->bottomtexture[1] && msd->bottomtexture[2] && msd->bottomtexture[3] && msd->bottomtexture[4] && msd->bottomtexture[5] && msd->bottomtexture[6]) - { - col = msd->bottomtexture; - - sec->extra_colormap->fadergba = - (HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) + - (HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) + - (HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16); - - // alpha - if (msd->bottomtexture[7]) - sec->extra_colormap->fadergba += (ALPHA2INT(col[7]) << 24); - else - sec->extra_colormap->fadergba += (25 << 24); - } - else - sec->extra_colormap->fadergba = 0x19000000; // default alpha, (25 << 24) -#undef ALPHA2INT -#undef HEX2INT - } - else - { - if ((num = R_CheckTextureNumForName(msd->toptexture)) == -1) - sd->toptexture = 0; - else - sd->toptexture = num; - - if ((num = R_CheckTextureNumForName(msd->midtexture)) == -1) - sd->midtexture = 0; - else - sd->midtexture = num; - - if ((num = R_CheckTextureNumForName(msd->bottomtexture)) == -1) - sd->bottomtexture = 0; - else - sd->bottomtexture = num; - } - break; - } -#endif + sd->colormap_data = R_CreateColormap(msd->toptexture, msd->midtexture, + msd->bottomtexture); + sd->toptexture = sd->midtexture = sd->bottomtexture = 0; + break; case 413: // Change music { @@ -1600,6 +1499,7 @@ static void P_LoadRawSideDefs2(void *data) } case 443: // Calls a named Lua function + case 459: // Control text prompt (named tag) { char process[8*3+1]; memset(process,0,8*3+1); @@ -2265,6 +2165,7 @@ lumpnum_t lastloadedmaplumpnum; // for comparative savegame static void P_LevelInitStuff(void) { INT32 i; + boolean canresetlives = true; leveltime = 0; @@ -2274,14 +2175,26 @@ static void P_LevelInitStuff(void) // special stage tokens, emeralds, and ring total tokenbits = 0; runemeraldmanager = false; - nummaprings = 0; + emeraldspawndelay = 60*TICRATE; + nummaprings = mapheaderinfo[gamemap-1]->startrings; // emerald hunt hunt1 = hunt2 = hunt3 = NULL; // map time limit if (mapheaderinfo[gamemap-1]->countdown) + { + tic_t maxtime = 0; countdowntimer = mapheaderinfo[gamemap-1]->countdown * TICRATE; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + if (players[i].starposttime > maxtime) + maxtime = players[i].starposttime; + } + countdowntimer -= maxtime; + } else countdowntimer = 0; countdowntimeup = false; @@ -2293,7 +2206,7 @@ static void P_LevelInitStuff(void) // circuit, race and competition stuff circuitmap = false; numstarposts = 0; - totalrings = timeinmap = 0; + ssspheres = timeinmap = 0; // special stage stagefailed = false; @@ -2303,49 +2216,63 @@ static void P_LevelInitStuff(void) // earthquake camera memset(&quake,0,sizeof(struct quake)); + if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && players[i].lives > 0) + { + canresetlives = false; + break; + } + } + } + + countdown = countdown2 = exitfadestarted = 0; + for (i = 0; i < MAXPLAYERS; i++) { - if ((netgame || multiplayer) && (gametype == GT_COMPETITION || players[i].lives <= 0)) + if (canresetlives && (netgame || multiplayer) && playeringame[i] && (gametype == GT_COMPETITION || players[i].lives <= 0)) { // In Co-Op, replenish a user's lives if they are depleted. players[i].lives = cv_startinglives.value; } - players[i].realtime = countdown = countdown2 = exitfadestarted = 0; - + // obliteration station... + players[i].rings = players[i].spheres =\ + players[i].xtralife = players[i].deadtimer =\ + players[i].numboxes = players[i].totalring =\ + players[i].laps = players[i].aiming =\ + players[i].losstime = players[i].timeshit =\ + players[i].marescore = players[i].lastmarescore =\ + players[i].maxlink = players[i].startedtime =\ + players[i].finishedtime = players[i].finishedspheres =\ + players[i].finishedrings = players[i].lastmare =\ + players[i].lastmarelap = players[i].lastmarebonuslap =\ + players[i].totalmarelap = players[i].totalmarebonuslap =\ + players[i].marebegunat = players[i].textvar =\ + players[i].texttimer = players[i].linkcount =\ + players[i].linktimer = players[i].flyangle =\ + players[i].anotherflyangle = players[i].nightstime =\ + players[i].oldscale = players[i].mare = players[i].marelap =\ + players[i].marebonuslap = players[i].lapbegunat =\ + players[i].lapstartedtime = players[i].totalmarescore =\ + players[i].realtime = players[i].exiting = 0; + + // i guess this could be part of the above but i feel mildly uncomfortable implicitly casting players[i].gotcontinue = false; - players[i].xtralife = players[i].deadtimer = players[i].numboxes = players[i].totalring = players[i].laps = 0; - players[i].health = 1; - players[i].aiming = 0; - players[i].pflags &= ~PF_TIMEOVER; - - players[i].losstime = 0; - players[i].timeshit = 0; - - players[i].marescore = players[i].lastmarescore = players[i].maxlink = 0; - players[i].startedtime = players[i].finishedtime = players[i].finishedrings = 0; - players[i].lastmare = players[i].marebegunat = 0; - - // Don't show anything - players[i].textvar = players[i].texttimer = 0; - - players[i].linkcount = players[i].linktimer = 0; - players[i].flyangle = players[i].anotherflyangle = 0; - players[i].nightstime = players[i].mare = 0; - P_SetTarget(&players[i].capsule, NULL); + // aha, the first evidence this shouldn't be a memset! players[i].drillmeter = 40*20; - players[i].exiting = 0; P_ResetPlayer(&players[i]); + // hit these too + players[i].pflags &= ~(PF_GAMETYPEOVER|PF_TRANSFERTOCLOSEST); - players[i].mo = NULL; - - // we must unset axis details too - players[i].axis1 = players[i].axis2 = NULL; - - // and this stupid flag as a result - players[i].pflags &= ~PF_TRANSFERTOCLOSEST; + // unset ALL the pointers. P_SetTarget isn't needed here because if this + // function is being called we're just going to clobber the data anyways + players[i].mo = players[i].followmobj = players[i].awayviewmobj =\ + players[i].capsule = players[i].axis1 = players[i].axis2 = players[i].drone = NULL; } } @@ -2359,6 +2286,18 @@ void P_LoadThingsOnly(void) // Search through all the thinkers. mobj_t *mo; thinker_t *think; + INT32 i, viewid = -1, centerid = -1; // for skyboxes + + // check if these are any of the normal viewpoint/centerpoint mobjs in the level or not + if (skyboxmo[0] || skyboxmo[1]) + for (i = 0; i < 16; i++) + { + if (skyboxmo[0] && skyboxmo[0] == skyboxviewpnts[i]) + viewid = i; // save id just in case + if (skyboxmo[1] && skyboxmo[1] == skyboxcenterpnts[i]) + centerid = i; // save id just in case + } + for (think = thinkercap.next; think != &thinkercap; think = think->next) { @@ -2383,9 +2322,11 @@ void P_LoadThingsOnly(void) } else // phew it's just a WAD P_PrepareThings(lastloadedmaplumpnum + ML_THINGS); - P_LoadThings(); + P_LoadThings(true); - P_SpawnSecretItems(true); + // restore skybox viewpoint/centerpoint if necessary, set them to defaults if we can't do that + skyboxmo[0] = skyboxviewpnts[(viewid >= 0) ? viewid : 0]; + skyboxmo[1] = skyboxcenterpnts[(centerid >= 0) ? centerid : 0]; } /** Compute MD5 message digest for bytes read from memory source @@ -2646,26 +2587,19 @@ static void P_SetupCamera(void) } } -static boolean P_CanSave(void) +static boolean CanSaveLevel(INT32 mapnum) { - // Saving is completely ignored under these conditions: - if ((cursaveslot < 0) // Playing without saving - || (modifiedgame && !savemoddata) // Game is modified - || (netgame || multiplayer) // Not in single-player - || (demoplayback || demorecording || metalrecording) // Currently in demo - || (players[consoleplayer].lives <= 0) // Completely dead - || (modeattacking || ultimatemode || G_IsSpecialStage(gamemap))) // Specialized instances + if (ultimatemode) // never save in ultimate (probably redundant with cursaveslot also being checked) return false; - if (mapheaderinfo[gamemap-1]->saveoverride == SAVE_ALWAYS) - return true; // Saving should ALWAYS happen! - else if (mapheaderinfo[gamemap-1]->saveoverride == SAVE_NEVER) - return false; // Saving should NEVER happen! + if (G_IsSpecialStage(mapnum) // don't save in special stages + || mapnum == lastmaploaded) // don't save if the last map loaded was this one + return false; - // Default condition: In a non-hidden map, at the beginning of a zone or on a completed save-file, and not on save reload. - return (!(mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU) - && (mapheaderinfo[gamemap-1]->actnum < 2 || gamecomplete) - && (gamemap != lastmapsaved)); + // Any levels that have the savegame flag can save normally. + // If the game is complete for this save slot, then any level can save! + // On the other side of the spectrum, if lastmaploaded is 0, then the save file has only just been created and needs to save ASAP! + return (mapheaderinfo[mapnum-1]->levelflags & LF_SAVEGAME || gamecomplete || !lastmaploaded); } /** Loads a level from a lump or external wad. @@ -2693,7 +2627,6 @@ boolean P_SetupLevel(boolean skipprecip) CON_Drawer(); // let the user know what we are going to do I_FinishUpdate(); // page flip or blit buffer - // Reset the palette if (rendermode != render_none) V_SetPaletteLump("PLAYPAL"); @@ -2720,8 +2653,7 @@ boolean P_SetupLevel(boolean skipprecip) postimgtype = postimgtype2 = postimg_none; - if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0' - && atoi(mapheaderinfo[gamemap-1]->forcecharacter) != 255) + if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0') P_ForceCharacter(mapheaderinfo[gamemap-1]->forcecharacter); // chasecam on in chaos, race, coop @@ -2747,9 +2679,14 @@ boolean P_SetupLevel(boolean skipprecip) // will be set by player think. players[consoleplayer].viewz = 1; + // Cancel all d_main.c fadeouts (keep fade in though). + wipegamestate = FORCEWIPEOFF; + // Special stage fade to white // This is handled BEFORE sounds are stopped. - if (rendermode != render_none && G_IsSpecialStage(gamemap)) + if (modeattacking && !demoplayback && (pausedelay == INT32_MIN)) + ranspecialwipe = 2; + else if (rendermode != render_none && G_IsSpecialStage(gamemap)) { tic_t starttime = I_GetTime(); tic_t endtime = starttime + (3*TICRATE)/2; @@ -2782,9 +2719,12 @@ boolean P_SetupLevel(boolean skipprecip) S_StopSounds(); S_ClearSfx(); - // As oddly named as this is, this handles music only. - // We should be fine starting it here. - S_Start(); + if (!titlemapinaction) + { + // As oddly named as this is, this handles music only. + // We should be fine starting it here. + S_Start(); + } // Let's fade to black here // But only if we didn't do the special stage wipe @@ -2794,23 +2734,43 @@ boolean P_SetupLevel(boolean skipprecip) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_level_toblack], false); + // for titlemap: run a specific wipe if specified + // needed for exiting time attack + if (wipetypepre != INT16_MAX) + F_RunWipe( + (wipetypepre >= 0 && F_WipeExists(wipetypepre)) ? wipetypepre : wipedefs[wipe_level_toblack], + false); + wipetypepre = -1; } - // Print "SPEEDING OFF TO [ZONE] [ACT 1]..." - if (rendermode != render_none) + if (!titlemapinaction) { - // Don't include these in the fade! - char tx[64]; - V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to...")); - snprintf(tx, 63, "%s%s%s", - mapheaderinfo[gamemap-1]->lvlttl, - (mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE", - (mapheaderinfo[gamemap-1]->actnum > 0) ? va(", Act %d",mapheaderinfo[gamemap-1]->actnum) : ""); - V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx); - I_UpdateNoVsync(); + if (ranspecialwipe == 2) + { + pausedelay = -3; // preticker plus one + S_StartSound(NULL, sfx_s3k73); + } + + // Print "SPEEDING OFF TO [ZONE] [ACT 1]..." + if (rendermode != render_none) + { + // Don't include these in the fade! + char tx[64]; + V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to...")); + snprintf(tx, 63, "%s%s%s", + mapheaderinfo[gamemap-1]->lvlttl, + (mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE", + (mapheaderinfo[gamemap-1]->actnum > 0) ? va(", Act %d",mapheaderinfo[gamemap-1]->actnum) : ""); + V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx); + I_UpdateNoVsync(); + } } + levelfadecol = (ranspecialwipe) ? 0 : 31; + + // Close text prompt before freeing the old level + F_EndTextPrompt(false, true); + #ifdef HAVE_BLUA LUA_InvalidateLevel(); #endif @@ -2908,8 +2868,13 @@ boolean P_SetupLevel(boolean skipprecip) // reset the player starts for (i = 0; i < MAXPLAYERS; i++) playerstarts[i] = NULL; + for (i = 0; i < 2; i++) skyboxmo[i] = NULL; + + for (i = 0; i < 16; i++) + skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL; + P_MapStart(); P_PrepareRawThings(wadData + (fileinfo + ML_THINGS)->filepos, (fileinfo + ML_THINGS)->size); @@ -2932,7 +2897,6 @@ boolean P_SetupLevel(boolean skipprecip) // Important: take care of the ordering of the next functions. if (!loadedbm) P_CreateBlockMap(); // Graue 02-29-2004 - P_LoadLineDefs2(); P_GroupLines(); numdmstarts = numredctfstarts = numbluectfstarts = 0; @@ -2940,19 +2904,29 @@ boolean P_SetupLevel(boolean skipprecip) // reset the player starts for (i = 0; i < MAXPLAYERS; i++) playerstarts[i] = NULL; + for (i = 0; i < 2; i++) skyboxmo[i] = NULL; + + for (i = 0; i < 16; i++) + skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL; + P_MapStart(); + P_PrepareThings(lastloadedmaplumpnum + ML_THINGS); } + // init gravity, tag lists, + // anything that P_ResetDynamicSlopes/P_LoadThings needs to know + P_InitSpecials(); + #ifdef ESLOPE P_ResetDynamicSlopes(); #endif - P_LoadThings(); - - P_SpawnSecretItems(loademblems); + P_LoadThings(loademblems); + skyboxmo[0] = skyboxviewpnts[0]; + skyboxmo[1] = skyboxcenterpnts[0]; for (numcoopstarts = 0; numcoopstarts < MAXPLAYERS; numcoopstarts++) if (!playerstarts[numcoopstarts]) @@ -2964,8 +2938,6 @@ boolean P_SetupLevel(boolean skipprecip) if (loadprecip) // ugly hack for P_NetUnArchiveMisc (and P_LoadNetGame) P_SpawnPrecipitation(); - globalweather = mapheaderinfo[gamemap-1]->weather; - #ifdef HWRENDER // not win32 only 19990829 by Kin if (rendermode != render_soft && rendermode != render_none) { @@ -2991,8 +2963,6 @@ boolean P_SetupLevel(boolean skipprecip) for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i]) { - players[i].pflags &= ~PF_NIGHTSMODE; - // Start players with pity shields if possible players[i].pity = -1; @@ -3015,6 +2985,19 @@ boolean P_SetupLevel(boolean skipprecip) } } + // restore time in netgame (see also g_game.c) + if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2) + { + // is this a hack? maybe + tic_t maxstarposttime = 0; + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && players[i].starposttime > maxstarposttime) + maxstarposttime = players[i].starposttime; + } + leveltime = maxstarposttime; + } + if (modeattacking == ATTACKING_RECORD && !demoplayback) P_LoadRecordGhosts(); else if (modeattacking == ATTACKING_NIGHTS && !demoplayback) @@ -3071,20 +3054,17 @@ boolean P_SetupLevel(boolean skipprecip) // Salt: CV_ClearChangedFlags() messes with your settings :( /*if (!cv_cam_height.changed) CV_Set(&cv_cam_height, cv_cam_height.defaultvalue); - - if (!cv_cam_dist.changed) - CV_Set(&cv_cam_dist, cv_cam_dist.defaultvalue); - if (!cv_cam2_height.changed) CV_Set(&cv_cam2_height, cv_cam2_height.defaultvalue); + if (!cv_cam_dist.changed) + CV_Set(&cv_cam_dist, cv_cam_dist.defaultvalue); if (!cv_cam2_dist.changed) CV_Set(&cv_cam2_dist, cv_cam2_dist.defaultvalue);*/ // Though, I don't think anyone would care about cam_rotate being reset back to the only value that makes sense :P if (!cv_cam_rotate.changed) CV_Set(&cv_cam_rotate, cv_cam_rotate.defaultvalue); - if (!cv_cam2_rotate.changed) CV_Set(&cv_cam2_rotate, cv_cam2_rotate.defaultvalue); @@ -3132,8 +3112,8 @@ boolean P_SetupLevel(boolean skipprecip) P_MapEnd(); // Remove the loading shit from the screen - if (rendermode != render_none) - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (ranspecialwipe) ? 0 : 31); + if (rendermode != render_none && !titlemapinaction) + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); if (precache || dedicated) R_PrecacheLevel(); @@ -3143,27 +3123,31 @@ boolean P_SetupLevel(boolean skipprecip) if (!(netgame || multiplayer) && (!modifiedgame || savemoddata)) mapvisited[gamemap-1] |= MV_VISITED; + else + mapvisited[gamemap-1] |= MV_MP; // you want to record that you've been there this session, but not permanently levelloading = false; P_RunCachedActions(); - if (P_CanSave()) + if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking || players[consoleplayer].lives <= 0) + && (!modifiedgame || savemoddata) && cursaveslot > 0 && CanSaveLevel(gamemap)) G_SaveGame((UINT32)cursaveslot); + lastmaploaded = gamemap; // HAS to be set after saving!! + if (savedata.lives > 0) { + numgameovers = savedata.numgameovers; players[consoleplayer].continues = savedata.continues; players[consoleplayer].lives = savedata.lives; players[consoleplayer].score = savedata.score; - botskin = savedata.botskin; - botcolor = savedata.botcolor; - botingame = (savedata.botskin != 0); + if ((botingame = ((botskin = savedata.botskin) != 0))) + botcolor = skins[botskin-1].prefcolor; emeralds = savedata.emeralds; savedata.lives = 0; } - skyVisible = skyVisible1 = skyVisible2 = true; // assume the skybox is visible on level load. if (loadprecip) // uglier hack { // to make a newly loaded level start on the second frame. INT32 buf = gametic % BACKUPTICS; @@ -3178,6 +3162,45 @@ boolean P_SetupLevel(boolean skipprecip) #endif } + // Stage title! + if (rendermode != render_none + && (!titlemapinaction) + && ranspecialwipe != 2 + && *mapheaderinfo[gamemap-1]->lvlttl != '\0' +#ifdef HAVE_BLUA + && LUA_HudEnabled(hud_stagetitle) +#endif + ) + { + tic_t starttime = I_GetTime(); + tic_t endtime = starttime + (10*NEWTICRATERATIO); + tic_t nowtime = starttime; + tic_t lasttime = starttime; + while (nowtime < endtime) + { + // draw loop + while (!((nowtime = I_GetTime()) - lasttime)) + I_Sleep(); + lasttime = nowtime; + + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); + stplyr = &players[consoleplayer]; + ST_drawLevelTitle(nowtime - starttime); + if (splitscreen) + { + stplyr = &players[secondarydisplayplayer]; + ST_drawLevelTitle(nowtime - starttime); + } + + I_OsPolling(); + I_UpdateNoBlit(); + I_FinishUpdate(); // page flip or blit buffer + + if (moviemode) // make sure we save frames for the white hold too + M_SaveFrame(); + } + } + return true; } @@ -3203,6 +3226,72 @@ boolean P_RunSOC(const char *socfilename) return true; } +// Auxiliary function for PK3 loading - looks for sound replacements. +// NOTE: it does not really add any new sound entry or anything. +void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num) +{ + size_t j; + lumpinfo_t *lumpinfo = wadfiles[wadnum]->lumpinfo + first; + for (; num > 0; num--, lumpinfo++) + { + // Let's check whether it's replacing an existing sound or it's a brand new one. + for (j = 1; j < NUMSFX; j++) + { + if (S_sfx[j].name && !strnicmp(S_sfx[j].name, lumpinfo->name + 2, 6)) + { + // the sound will be reloaded when needed, + // since sfx->data will be NULL + CONS_Debug(DBG_SETUP, "Sound %.8s replaced\n", lumpinfo->name); + + I_FreeSfx(&S_sfx[j]); + break; // there shouldn't be two sounds with the same name, so stop looking + } + } + } +} + +// Auxiliary function for PK3 loading - looks for music and music replacements. +// NOTE: does nothing but print debug messages. The code is handled somewhere else. +void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 num) +{ + lumpinfo_t *lumpinfo = wadfiles[wadnum]->lumpinfo + first; + char *name; + for (; num > 0; num--, lumpinfo++) + { + name = lumpinfo->name; + if (name[0] == 'O' && name[1] == '_') + { + CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name); + } + else if (name[0] == 'D' && name[1] == '_') + { + CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name); + } + } + return; +} + +// Auxiliary function - input a folder name and gives us the resource markers positions. +static lumpinfo_t* FindFolder(const char *folName, UINT16 *start, UINT16 *end, lumpinfo_t *lumpinfo, UINT16 *pnumlumps, size_t *pi) +{ + UINT16 numlumps = *pnumlumps; + size_t i = *pi; + if (!stricmp(lumpinfo->name2, folName)) + { + lumpinfo++; + *start = ++i; + for (; i < numlumps; i++, lumpinfo++) + if (strnicmp(lumpinfo->name2, folName, strlen(folName))) + break; + lumpinfo--; + *end = i-- - *start; + *pi = i; + *pnumlumps = numlumps; + return lumpinfo; + } + return lumpinfo; +} + // // Add a wadfile to the active wad files, // replace sounds, musics, patches, textures, sprites and maps @@ -3213,59 +3302,108 @@ boolean P_AddWadFile(const char *wadfilename) UINT16 numlumps, wadnum; char *name; lumpinfo_t *lumpinfo; - boolean texturechange = false; + + //boolean texturechange = false; ///\todo Useless; broken when back-frontporting PK3 changes? boolean mapsadded = false; boolean replacedcurrentmap = false; - if ((numlumps = W_InitFile(wadfilename)) == INT16_MAX) + // Vars to help us with the position start and amount of each resource type. + // Useful for PK3s since they use folders. + // WADs use markers for some resources, but others such as sounds are checked lump-by-lump anyway. +// UINT16 luaPos, luaNum = 0; +// UINT16 socPos, socNum = 0; + UINT16 sfxPos, sfxNum = 0; + UINT16 musPos = 0, musNum = 0; +// UINT16 sprPos, sprNum = 0; + UINT16 texPos, texNum = 0; +// UINT16 patPos, patNum = 0; +// UINT16 flaPos, flaNum = 0; +// UINT16 mapPos, mapNum = 0; + + // Init file. + if ((numlumps = W_InitFile(wadfilename, false)) == INT16_MAX) { refreshdirmenu |= REFRESHDIR_NOTLOADED; CONS_Printf(M_GetText("Errors occurred while loading %s; not added.\n"), wadfilename); return false; } - else wadnum = (UINT16)(numwadfiles-1); + else + wadnum = (UINT16)(numwadfiles-1); - // - // search for sound replacements - // - lumpinfo = wadfiles[wadnum]->lumpinfo; - for (i = 0; i < numlumps; i++, lumpinfo++) + switch(wadfiles[wadnum]->type) { - name = lumpinfo->name; - if (name[0] == 'D') + case RET_PK3: + // Look for the lumps that act as resource delimitation markers. + lumpinfo = wadfiles[wadnum]->lumpinfo; + for (i = 0; i < numlumps; i++, lumpinfo++) { - if (name[1] == 'S') for (j = 1; j < NUMSFX; j++) +// lumpinfo = FindFolder("Lua/", &luaPos, &luaNum, lumpinfo, &numlumps, &i); +// lumpinfo = FindFolder("SOC/", &socPos, &socNum, lumpinfo, &numlumps, &i); + lumpinfo = FindFolder("Sounds/", &sfxPos, &sfxNum, lumpinfo, &numlumps, &i); + lumpinfo = FindFolder("Music/", &musPos, &musNum, lumpinfo, &numlumps, &i); +// lumpinfo = FindFolder("Sprites/", &sprPos, &sprNum, lumpinfo, &numlumps, &i); + lumpinfo = FindFolder("Textures/", &texPos, &texNum, lumpinfo, &numlumps, &i); +// lumpinfo = FindFolder("Patches/", &patPos, &patNum, lumpinfo, &numlumps, &i); +// lumpinfo = FindFolder("Flats/", &flaPos, &flaNum, lumpinfo, &numlumps, &i); +// lumpinfo = FindFolder("Maps/", &mapPos, &mapNum, lumpinfo, &numlumps, &i); + } + + // Update the detected resources. + // Note: ALWAYS load Lua scripts first, SOCs right after, and the remaining resources afterwards. +#ifdef HAVE_BLUA +// if (luaNum) // Lua scripts. +// P_LoadLuaScrRange(wadnum, luaPos, luaNum); +#endif +// if (socNum) // SOCs. +// P_LoadDehackRange(wadnum, socPos, socNum); + if (sfxNum) // Sounds. TODO: Function currently only updates already existing sounds, the rest is handled somewhere else. + P_LoadSoundsRange(wadnum, sfxPos, sfxNum); + if (musNum) // Music. TODO: Useless function right now. + P_LoadMusicsRange(wadnum, musPos, musNum); +// if (sprNum) // Sprites. +// R_LoadSpritsRange(wadnum, sprPos, sprNum); +// if (texNum) // Textures. TODO: R_LoadTextures() does the folder positioning once again. New function maybe? +// R_LoadTextures(); +// if (mapNum) // Maps. TODO: Actually implement the map WAD loading code, lulz. +// P_LoadWadMapRange(wadnum, mapPos, mapNum); + break; + default: + lumpinfo = wadfiles[wadnum]->lumpinfo; + for (i = 0; i < numlumps; i++, lumpinfo++) + { + name = lumpinfo->name; + if (name[0] == 'D') { - if (S_sfx[j].name && !strnicmp(S_sfx[j].name, name + 2, 6)) + if (name[1] == 'S') { - // the sound will be reloaded when needed, - // since sfx->data will be NULL - CONS_Debug(DBG_SETUP, "Sound %.8s replaced\n", name); + for (j = 1; j < NUMSFX; j++) + { + if (S_sfx[j].name && !strnicmp(S_sfx[j].name, name + 2, 6)) + { + // the sound will be reloaded when needed, + // since sfx->data will be NULL + CONS_Debug(DBG_SETUP, "Sound %.8s replaced\n", name); - I_FreeSfx(&S_sfx[j]); + I_FreeSfx(&S_sfx[j]); - sreplaces++; + sreplaces++; + break; // there shouldn't be two sounds with the same name, so stop looking + } + } + } + else if (name[1] == '_') + { + CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name); + mreplaces++; } } - else if (name[1] == '_') + else if (name[0] == 'O' && name[1] == '_') { CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name); - mreplaces++; + digmreplaces++; } } - else if (name[0] == 'O' && name[1] == '_') - { - CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name); - digmreplaces++; - } -#if 0 - // - // search for texturechange replacements - // - else if (!memcmp(name, "TEXTURE1", 8) || !memcmp(name, "TEXTURE2", 8) - || !memcmp(name, "PNAMES", 6)) -#endif - texturechange = true; + break; } if (!devparm && sreplaces) CONS_Printf(M_GetText("%s sounds replaced\n"), sizeu1(sreplaces)); @@ -3282,13 +3420,10 @@ boolean P_AddWadFile(const char *wadfilename) // Reload it all anyway, just in case they // added some textures but didn't insert a - // TEXTURE1/PNAMES/etc. list. - if (texturechange) // initialized in the sound check - R_LoadTextures(); // numtexture changes - else - R_FlushTextureCache(); // just reload it from file + // TEXTURES/etc. list. + R_LoadTextures(); // numtexture changes - // Reload ANIMATED / ANIMDEFS + // Reload ANIMDEFS P_InitPicAnims(); // Flush and reload HUD graphics @@ -3301,6 +3436,7 @@ boolean P_AddWadFile(const char *wadfilename) // look for skins // R_AddSkins(wadnum); // faB: wadfile index in wadfiles[] + R_PatchSkins(wadnum); // toast: PATCH PATCH // // search for maps @@ -3309,7 +3445,6 @@ boolean P_AddWadFile(const char *wadfilename) for (i = 0; i < numlumps; i++, lumpinfo++) { name = lumpinfo->name; - if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers { INT16 num; @@ -3333,8 +3468,8 @@ boolean P_AddWadFile(const char *wadfilename) ST_Start(); // Prevent savefile cheating - if (cursaveslot >= 0) - cursaveslot = -1; + if (cursaveslot > 0) + cursaveslot = 0; if (replacedcurrentmap && gamestate == GS_LEVEL && (netgame || multiplayer)) { @@ -3345,31 +3480,3 @@ boolean P_AddWadFile(const char *wadfilename) return true; } - -#ifdef DELFILE -boolean P_DelWadFile(void) -{ - sfxenum_t i; - const UINT16 wadnum = (UINT16)(numwadfiles - 1); - const lumpnum_t lumpnum = numwadfiles<<16; - //lumpinfo_t *lumpinfo = wadfiles[wadnum]->lumpinfo; - R_DelSkins(wadnum); // only used by DELFILE - R_DelSpriteDefs(wadnum); // only used by DELFILE - for (i = 0; i < NUMSFX; i++) - { - if (S_sfx[i].lumpnum != LUMPERROR && S_sfx[i].lumpnum >= lumpnum) - { - S_StopSoundByNum(i); - S_RemoveSoundFx(i); - if (S_sfx[i].lumpnum != LUMPERROR) - { - I_FreeSfx(&S_sfx[i]); - S_sfx[i].lumpnum = LUMPERROR; - } - } - } - W_UnloadWadFile(wadnum); // only used by DELFILE - R_LoadTextures(); - return false; -} -#endif diff --git a/src/p_setup.h b/src/p_setup.h index 41c2bf1335fc40f4db383d19fc543f1dc2fbb283..7e8a5d7e6bd31185d48c936eb95e7b33cf847413 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -27,6 +27,7 @@ extern mapthing_t *deathmatchstarts[MAX_DM_STARTS]; extern INT32 numdmstarts, numcoopstarts, numredctfstarts, numbluectfstarts; extern boolean levelloading; +extern UINT8 levelfadecol; extern lumpnum_t lastloadedmaplumpnum; // for comparative savegame // @@ -60,16 +61,19 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum); void P_LoadThingsOnly(void); boolean P_SetupLevel(boolean skipprecip); boolean P_AddWadFile(const char *wadfilename); -#ifdef DELFILE -boolean P_DelWadFile(void); -#endif boolean P_RunSOC(const char *socfilename); +void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num); +void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 num); void P_WriteThings(lumpnum_t lump); size_t P_PrecacheLevelFlats(void); void P_AllocMapHeader(INT16 i); +void P_SetDemoFlickies(INT16 i); +void P_DeleteFlickies(INT16 i); + // Needed for NiGHTS void P_ReloadRings(void); +void P_SwitchSpheresBonusMode(boolean bonustime); void P_DeleteGrades(INT16 i); void P_AddGradesForMare(INT16 i, UINT8 mare, char *gtext); UINT8 P_GetGrade(UINT32 pscore, INT16 map, UINT8 mare); diff --git a/src/p_sight.c b/src/p_sight.c index 626f8bbef331a3ea5f16c90dd3bdde731bd51a14..aa59314f19728b6376d6ceddd2a083e44254142f 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -14,6 +14,7 @@ #include "doomdef.h" #include "doomstat.h" #include "p_local.h" +#include "p_slopes.h" #include "r_main.h" #include "r_state.h" @@ -103,12 +104,20 @@ static fixed_t P_InterceptVector2(divline_t *v2, divline_t *v1) static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los) { size_t i; + sector_t *polysec; + + if (!(po->flags & POF_RENDERALL)) + return true; // the polyobject isn't visible, so we can ignore it + + polysec = po->lines[0]->backsector; for (i = 0; i < po->numLines; ++i) { line_t *line = po->lines[i]; divline_t divl; const vertex_t *v1,*v2; + fixed_t frac; + fixed_t topslope, bottomslope; // already checked other side? if (line->validcount == validcount) @@ -140,7 +149,22 @@ static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los) continue; // stop because it is not two sided - return false; + //if (!(po->flags & POF_TESTHEIGHT)) + //return false; + + frac = P_InterceptVector2(&los->strace, &divl); + + // get slopes of top and bottom of this polyobject line + topslope = FixedDiv(polysec->ceilingheight - los->sightzstart , frac); + bottomslope = FixedDiv(polysec->floorheight - los->sightzstart , frac); + + if (topslope >= los->topslope && bottomslope <= los->bottomslope) + return false; // view completely blocked + + // TODO: figure out if it's worth considering partially blocked cases or not? + // maybe to adjust los's top/bottom slopes if needed + //if (los->topslope <= los->bottomslope) + //return false; } return true; @@ -193,6 +217,10 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) const sector_t *front, *back; const vertex_t *v1,*v2; fixed_t frac; + fixed_t frontf, backf, frontc, backc; +#ifdef ESLOPE + fixed_t fracx, fracy; +#endif // already checked other side? if (line->validcount == validcount) @@ -227,36 +255,51 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) if (!(line->flags & ML_TWOSIDED)) return false; + // calculate fractional intercept (how far along we are divided by how far we are from t2) + frac = P_InterceptVector2(&los->strace, &divl); + + front = seg->frontsector; + back = seg->backsector; +#ifdef ESLOPE + // calculate position at intercept + fracx = los->strace.x + FixedMul(los->strace.dx, frac); + fracy = los->strace.y + FixedMul(los->strace.dy, frac); + // calculate sector heights + frontf = (front->f_slope) ? P_GetZAt(front->f_slope, fracx, fracy) : front->floorheight; + frontc = (front->c_slope) ? P_GetZAt(front->c_slope, fracx, fracy) : front->ceilingheight; + backf = (back->f_slope) ? P_GetZAt(back->f_slope, fracx, fracy) : back->floorheight; + backc = (back->c_slope) ? P_GetZAt(back->c_slope, fracx, fracy) : back->ceilingheight; +#else + frontf = front->floorheight; + frontc = front->ceilingheight; + backf = back->floorheight; + backc = back->ceilingheight; +#endif // crosses a two sided line // no wall to block sight with? - if ((front = seg->frontsector)->floorheight == - (back = seg->backsector)->floorheight && - front->ceilingheight == back->ceilingheight) + if (frontf == backf && frontc == backc + && !front->ffloors & !back->ffloors) // (and no FOFs) continue; // possible occluder // because of ceiling height differences - popentop = front->ceilingheight < back->ceilingheight ? - front->ceilingheight : back->ceilingheight ; + popentop = min(frontc, backc); // because of floor height differences - popenbottom = front->floorheight > back->floorheight ? - front->floorheight : back->floorheight ; + popenbottom = max(frontf, backf); // quick test for totally closed doors if (popenbottom >= popentop) return false; - frac = P_InterceptVector2(&los->strace, &divl); - - if (front->floorheight != back->floorheight) + if (frontf != backf) { fixed_t slope = FixedDiv(popenbottom - los->sightzstart , frac); if (slope > los->bottomslope) los->bottomslope = slope; } - if (front->ceilingheight != back->ceilingheight) + if (frontc != backc) { fixed_t slope = FixedDiv(popentop - los->sightzstart , frac); if (slope < los->topslope) @@ -265,6 +308,58 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) if (los->topslope <= los->bottomslope) return false; + + // Monster Iestyn: check FOFs! + if (front->ffloors || back->ffloors) + { + ffloor_t *rover; + fixed_t topslope, bottomslope; + fixed_t topz, bottomz; + // check front sector's FOFs first + for (rover = front->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) + || !(rover->flags & FF_RENDERSIDES) || rover->flags & FF_TRANSLUCENT) + { + continue; + } + +#ifdef ESLOPE + topz = (*rover->t_slope) ? P_GetZAt(*rover->t_slope, fracx, fracy) : *rover->topheight; + bottomz = (*rover->b_slope) ? P_GetZAt(*rover->b_slope, fracx, fracy) : *rover->bottomheight; +#else + topz = *rover->topheight; + bottomz = *rover->bottomheight; +#endif + topslope = FixedDiv(topz - los->sightzstart , frac); + bottomslope = FixedDiv(bottomz - los->sightzstart , frac); + if (topslope >= los->topslope && bottomslope <= los->bottomslope) + return false; // view completely blocked + } + // check back sector's FOFs as well + for (rover = back->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) + || !(rover->flags & FF_RENDERSIDES) || rover->flags & FF_TRANSLUCENT) + { + continue; + } + +#ifdef ESLOPE + topz = (*rover->t_slope) ? P_GetZAt(*rover->t_slope, fracx, fracy) : *rover->topheight; + bottomz = (*rover->b_slope) ? P_GetZAt(*rover->b_slope, fracx, fracy) : *rover->bottomheight; +#else + topz = *rover->topheight; + bottomz = *rover->bottomheight; +#endif + topslope = FixedDiv(topz - los->sightzstart , frac); + bottomslope = FixedDiv(bottomz - los->sightzstart , frac); + if (topslope >= los->topslope && bottomslope <= los->bottomslope) + return false; // view completely blocked + } + // TODO: figure out if it's worth considering partially blocked cases or not? + // maybe to adjust los's top/bottom slopes if needed + } } // passed the subsector ok @@ -375,6 +470,8 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) if (s1 == s2) // Both sectors are the same. { ffloor_t *rover; + fixed_t topz1, bottomz1; // top, bottom heights at t1's position + fixed_t topz2, bottomz2; // likewise but for t2 for (rover = s1->ffloors; rover; rover = rover->next) { @@ -387,9 +484,30 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) continue; } +#ifdef ESLOPE + if (*rover->t_slope) + { + topz1 = P_GetZAt(*rover->t_slope, t1->x, t1->y); + topz2 = P_GetZAt(*rover->t_slope, t2->x, t2->y); + } + else + topz1 = topz2 = *rover->topheight; + + if (*rover->b_slope) + { + bottomz1 = P_GetZAt(*rover->b_slope, t1->x, t1->y); + bottomz2 = P_GetZAt(*rover->b_slope, t2->x, t2->y); + } + else + bottomz1 = bottomz2 = *rover->bottomheight; +#else + topz1 = topz2 = *rover->topheight; + bottomz1 = bottomz2 = *rover->bottomheight; +#endif + // Check for blocking floors here. - if ((los.sightzstart < *rover->bottomheight && t2->z >= *rover->topheight) - || (los.sightzstart >= *rover->topheight && t2->z + t2->height < *rover->bottomheight)) + if ((los.sightzstart < bottomz1 && t2->z >= topz2) + || (los.sightzstart >= topz1 && t2->z + t2->height < bottomz2)) { // no way to see through that return false; @@ -400,19 +518,19 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) if (!(rover->flags & FF_INVERTPLANES)) { - if (los.sightzstart >= *rover->topheight && t2->z + t2->height < *rover->topheight) + if (los.sightzstart >= topz1 && t2->z + t2->height < topz2) return false; // blocked by upper outside plane - if (los.sightzstart < *rover->bottomheight && t2->z >= *rover->bottomheight) + if (los.sightzstart < bottomz1 && t2->z >= bottomz2) return false; // blocked by lower outside plane } if (rover->flags & FF_INVERTPLANES || rover->flags & FF_BOTHPLANES) { - if (los.sightzstart < *rover->topheight && t2->z >= *rover->topheight) + if (los.sightzstart < topz1 && t2->z >= topz2) return false; // blocked by upper inside plane - if (los.sightzstart >= *rover->bottomheight && t2->z + t2->height < *rover->bottomheight) + if (los.sightzstart >= bottomz1 && t2->z + t2->height < bottomz2) return false; // blocked by lower inside plane } } diff --git a/src/p_slopes.c b/src/p_slopes.c index 19d0bbbb70aa865185b1d116de409e970baca7e3..3cdbd687efefb7cc674cf858468472f5bf9e68cd 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -251,7 +251,7 @@ void P_SpawnSlope_Line(int linenum) UINT8 flags = 0; // Slope flags if (line->flags & ML_NOSONIC) flags |= SL_NOPHYSICS; - if (line->flags & ML_NOTAILS) + if (!(line->flags & ML_NOTAILS)) flags |= SL_NODYNAMIC; if (line->flags & ML_NOKNUX) flags |= SL_ANCHORVERTEX; @@ -809,6 +809,39 @@ void P_SlopeLaunch(mobj_t *mo) mo->standingslope = NULL; } +// +// P_GetWallTransferMomZ +// +// It would be nice to have a single function that does everything necessary for slope-to-wall transfer. +// However, it needs to be seperated out in P_XYMovement to take into account momentum before and after hitting the wall. +// This just performs the necessary calculations for getting the base vertical momentum; the horizontal is already reasonably calculated by P_SlideMove. +fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope) +{ + vector3_t slopemom, axis; + angle_t ang; + + if (mo->standingslope->flags & SL_NOPHYSICS) + return 0; + + // If there's physics, time for launching. + // Doesn't kill the vertical momentum as much as P_SlopeLaunch does. + ang = slope->zangle + ANG15*((slope->zangle > 0) ? 1 : -1); + if (ang > ANGLE_90 && ang < ANGLE_180) + ang = ((slope->zangle > 0) ? ANGLE_90 : InvAngle(ANGLE_90)); // hard cap of directly upwards + + slopemom.x = mo->momx; + slopemom.y = mo->momy; + slopemom.z = 3*(mo->momz/2); + + axis.x = -slope->d.y; + axis.y = slope->d.x; + axis.z = 0; + + FV3_Rotate(&slopemom, &axis, ang >> ANGLETOFINESHIFT); + + return 2*(slopemom.z/3); +} + // Function to help handle landing on slopes void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) { diff --git a/src/p_slopes.h b/src/p_slopes.h index 708a9107d76c0848a0102e6cb49613223672a33e..b802ec25f6a4e5cb820641d58dc85c231d90727f 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -38,6 +38,7 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y); void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope); void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope); void P_SlopeLaunch(mobj_t *mo); +fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope); void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope); void P_ButteredSlope(mobj_t *mo); diff --git a/src/p_spec.c b/src/p_spec.c index d4ead74feb96ada09f84a6160921b1950d40638b..4bb03ca1a20018c143d4df33bc6afa1c0fa94077 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -31,26 +31,29 @@ #include "p_polyobj.h" #include "p_slopes.h" #include "hu_stuff.h" +#include "v_video.h" // V_AUTOFADEOUT|V_ALLOWLOWERCASE #include "m_misc.h" #include "m_cond.h" //unlock triggers #include "lua_hook.h" // LUAh_LinedefExecute +#include "f_finale.h" // control text prompt #ifdef HW3SOUND #include "hardware/hw3sound.h" #endif // Not sure if this is necessary, but it was in w_wad.c, so I'm putting it here too -Shadow Hog -#ifdef _WIN32_WCE -#define AVOID_ERRNO -#else #include <errno.h> -#endif -mobj_t *skyboxmo[2]; +mobj_t *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpoint +mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs +mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs // Amount (dx, dy) vector linedef is shifted right to get scroll amount #define SCROLL_SHIFT 5 +// This must be updated whenever we up the max flat size - quicker to assume rather than figuring out the sqrt of the specific flat's filesize. +#define MAXFLATSIZE (2048<<FRACBITS) + /** Animated texture descriptor * This keeps track of an animated texture or an animated flat. * \sa P_UpdateSpecials, P_InitPicAnims, animdef_t @@ -69,7 +72,7 @@ typedef struct #endif /** Animated texture definition. - * Used for ::harddefs and for loading an ANIMATED lump from a wad. + * Used for loading an ANIMDEFS lump from a wad. * * Animations are defined by the first and last frame (i.e., flat or texture). * The animation sequence uses all flats between the start and end entry, in @@ -101,6 +104,18 @@ static void P_SpawnFriction(void); static void P_SpawnPushers(void); static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, mobj_t *source, INT32 affectee, INT32 referrer, INT32 exclusive, INT32 slider); //SoM: 3/9/2000 static void Add_MasterDisappearer(tic_t appeartime, tic_t disappeartime, tic_t offset, INT32 line, INT32 sourceline); +static void P_ResetFakeFloorFader(ffloor_t *rover, fade_t *data, boolean finalize); +#define P_RemoveFakeFloorFader(l) P_ResetFakeFloorFader(l, NULL, false); +static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destvalue, INT16 speed, boolean ticbased, INT32 *timer, + boolean doexists, boolean dotranslucent, boolean dolighting, boolean docolormap, + boolean docollision, boolean doghostfade, boolean exactalpha); +static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloornum, + INT16 destvalue, INT16 speed, boolean ticbased, boolean relative, + boolean doexists, boolean dotranslucent, boolean dolighting, boolean docolormap, + boolean docollision, boolean doghostfade, boolean exactalpha); +static void P_ResetColormapFader(sector_t *sector); +static void Add_ColormapFader(sector_t *sector, extracolormap_t *source_exc, extracolormap_t *dest_exc, + boolean ticbased, INT32 duration); static void P_AddBlockThinker(sector_t *sec, line_t *sourceline); static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline); //static void P_AddBridgeThinker(line_t *sourceline, sector_t *sec); @@ -108,6 +123,7 @@ static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinker static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec); static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer); static void P_AddSpikeThinker(sector_t *sec, INT32 referrer); +static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee, UINT8 reverse); //SoM: 3/7/2000: New sturcture without limits. @@ -115,104 +131,6 @@ static anim_t *lastanim; static anim_t *anims = NULL; /// \todo free leak static size_t maxanims; -// -// P_InitPicAnims -// -/** Hardcoded animation sequences. - * Used if no ANIMATED lump is found in a loaded wad. - */ -static animdef_t harddefs[] = -{ - // flat animations. - {false, "LITEY3", "LITEY1", 4}, - {false, "FWATER16", "FWATER1", 4}, - {false, "BWATER16", "BWATER01", 4}, - {false, "LWATER16", "LWATER1", 4}, - {false, "WATER7", "WATER0", 4}, - {false, "LAVA4", "LAVA1", 8}, - {false, "DLAVA4", "DLAVA1", 8}, - {false, "RLAVA8", "RLAVA1", 8}, - {false, "LITER3", "LITER1", 8}, - {false, "SURF08", "SURF01", 4}, - - {false, "CHEMG16", "CHEMG01", 4}, // THZ Chemical gunk - {false, "GOOP16", "GOOP01", 4}, // Green chemical gunk - {false, "OIL16", "OIL01", 4}, // Oil - {false, "THZBOXF4", "THZBOXF1", 2}, // Moved up with the flats - {false, "ALTBOXF4", "ALTBOXF1", 2}, - - {false, "LITEB3", "LITEB1", 4}, - {false, "LITEN3", "LITEN1", 4}, - {false, "ACZRFL1H", "ACZRFL1A", 4}, - {false, "ACZRFL2H", "ACZRFL2A", 4}, - {false, "EGRIDF3", "EGRIDF1", 4}, - {false, "ERZFAN4", "ERZFAN1", 1}, - {false, "ERZFANR4", "ERZFANR1", 1}, - {false, "DISCO4", "DISCO1", 15}, - - // animated textures - {true, "GFALL4", "GFALL1", 2}, // Short waterfall - {true, "CFALL4", "CFALL1", 2}, // Long waterfall - {true, "TFALL4", "TFALL1", 2}, // THZ Chemical fall - {true, "AFALL4", "AFALL1", 2}, // Green Chemical fall - {true, "QFALL4", "QFALL1", 2}, // Quicksand fall - {true, "Q2FALL4", "Q2FALL1", 2}, - {true, "Q3FALL4", "Q3FALL1", 2}, - {true, "Q4FALL4", "Q4FALL1", 2}, - {true, "Q5FALL4", "Q5FALL1", 2}, - {true, "Q6FALL4", "Q6FALL1", 2}, - {true, "Q7FALL4", "Q7FALL1", 2}, - {true, "LFALL4", "LFALL1", 2}, - {true, "MFALL4", "MFALL1", 2}, - {true, "OFALL4", "OFALL1", 2}, - {true, "DLAVA4", "DLAVA1", 8}, - {true, "ERZLASA2", "ERZLASA1", 1}, - {true, "ERZLASB4", "ERZLASB1", 1}, - {true, "ERZLASC4", "ERZLASC1", 1}, - {true, "THZBOX04", "THZBOX01", 2}, - {true, "ALTBOX04", "ALTBOX01", 2}, - {true, "SFALL4", "SFALL1", 4}, // Lava fall - {true, "RVZFALL8", "RVZFALL1", 4}, - {true, "BFALL4", "BFALL1", 2}, // HPZ waterfall - {true, "GREYW3", "GREYW1", 4}, - {true, "BLUEW3", "BLUEW1", 4}, - {true, "COMP6", "COMP4", 4}, - {true, "RED3", "RED1", 4}, - {true, "YEL3", "YEL1", 4}, - {true, "ACWRFL1D", "ACWRFL1A", 1}, - {true, "ACWRFL2D", "ACWRFL2A", 1}, - {true, "ACWRFL3D", "ACWRFL3A", 1}, - {true, "ACWRFL4D", "ACWRFL4A", 1}, - {true, "ACWRP1D", "ACWRP1A", 1}, - {true, "ACWRP2D", "ACWRP2A", 1}, - {true, "ACZRP1D", "ACZRP1A", 1}, - {true, "ACZRP2D", "ACZRP2A", 1}, - {true, "OILFALL4", "OILFALL1", 2}, - {true, "SOLFALL4", "SOLFALL1", 2}, - {true, "DOWN1C", "DOWN1A", 4}, - {true, "DOWN2C", "DOWN2A", 4}, - {true, "DOWN3D", "DOWN3A", 4}, - {true, "DOWN4C", "DOWN4A", 4}, - {true, "DOWN5C", "DOWN5A", 4}, - {true, "UP1C", "UP1A", 4}, - {true, "UP2C", "UP2A", 4}, - {true, "UP3D", "UP3A", 4}, - {true, "UP4C", "UP4A", 4}, - {true, "UP5C", "UP5A", 4}, - {true, "EGRID3", "EGRID1", 4}, - {true, "ERFANW4", "ERFANW1", 1}, - {true, "ERFANX4", "ERFANX1", 1}, - {true, "DISCOD4", "DISCOD1", 15}, - {true, "DANCE4", "DANCE1", 8}, - {true, "SKY135", "SKY132", 2}, - {true, "APPLMS4", "APPLMS1", 2}, - {true, "APBOXW3", "APBOXW1", 2}, - {true, "ERZLAZC4", "ERZLAZC1", 4}, - - // End of line - { -1, "", "", 0}, -}; - // Animating line specials // Init animated textures @@ -226,7 +144,7 @@ void P_ParseAnimationDefintion(SINT8 istexture); /** Sets up texture and flat animations. * - * Converts an ::animdef_t array loaded from ::harddefs or a lump into + * Converts an ::animdef_t array loaded from a lump into * ::anim_t format. * * Issues an error if any animation cycles are invalid. @@ -238,73 +156,38 @@ void P_InitPicAnims(void) { // Init animation INT32 w; // WAD - UINT8 *animatedLump; - UINT8 *currentPos; size_t i; I_Assert(animdefs == NULL); - if (W_CheckNumForName("ANIMATED") != LUMPERROR || W_CheckNumForName("ANIMDEFS") != LUMPERROR) - { - for (w = numwadfiles-1, maxanims = 0; w >= 0; w--) - { - UINT16 animatedLumpNum; - UINT16 animdefsLumpNum; - - // Find ANIMATED lump in the WAD - animatedLumpNum = W_CheckNumForNamePwad("ANIMATED", w, 0); - if (animatedLumpNum != INT16_MAX) - { - animatedLump = (UINT8 *)W_CacheLumpNumPwad(w, animatedLumpNum, PU_STATIC); + maxanims = 0; - // Get the number of animations in the file - i = maxanims; - for (currentPos = animatedLump; *currentPos != UINT8_MAX; maxanims++, currentPos+=23); - - // Resize animdefs (or if it hasn't been created, create it) - animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL); - // Sanity check it - if (!animdefs) - I_Error("Not enough free memory for ANIMATED data"); - - // Populate the new array - for (currentPos = animatedLump; *currentPos != UINT8_MAX; i++, currentPos+=23) - { - M_Memcpy(&(animdefs[i].istexture), currentPos, 1); // istexture, 1 byte - M_Memcpy(animdefs[i].endname, (currentPos + 1), 9); // endname, 9 bytes - M_Memcpy(animdefs[i].startname, (currentPos + 10), 9); // startname, 9 bytes - M_Memcpy(&(animdefs[i].speed), (currentPos + 19), 4); // speed, 4 bytes - } + for (w = numwadfiles-1; w >= 0; w--) + { + UINT16 animdefsLumpNum; - Z_Free(animatedLump); - } + // Find ANIMDEFS lump in the WAD + animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0); - // Find ANIMDEFS lump in the WAD - animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0); - while (animdefsLumpNum != INT16_MAX) - { - P_ParseANIMDEFSLump(w, animdefsLumpNum); - animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", (UINT16)w, animdefsLumpNum + 1); - } + while (animdefsLumpNum != INT16_MAX) + { + P_ParseANIMDEFSLump(w, animdefsLumpNum); + animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", (UINT16)w, animdefsLumpNum + 1); } - // Define the last one - animdefs[maxanims].istexture = -1; - strncpy(animdefs[maxanims].endname, "", 9); - strncpy(animdefs[maxanims].startname, "", 9); - animdefs[maxanims].speed = 0; - } - else - { - animdefs = harddefs; - for (maxanims = 0; animdefs[maxanims].istexture != -1; maxanims++); } + // Define the last one + animdefs[maxanims].istexture = -1; + strncpy(animdefs[maxanims].endname, "", 9); + strncpy(animdefs[maxanims].startname, "", 9); + animdefs[maxanims].speed = 0; + if (anims) free(anims); anims = (anim_t *)malloc(sizeof (*anims)*(maxanims + 1)); if (!anims) - I_Error("Not enough free memory for ANIMATED data"); + I_Error("Not enough free memory for ANIMDEFS data"); lastanim = anims; for (i = 0; animdefs[i].istexture != -1; i++) @@ -336,10 +219,7 @@ void P_InitPicAnims(void) animdefs[i].startname, animdefs[i].endname); } - if (animdefs == harddefs) - lastanim->speed = animdefs[i].speed; - else - lastanim->speed = LONG(animdefs[i].speed); + lastanim->speed = LONG(animdefs[i].speed); lastanim++; } lastanim->istexture = -1; @@ -347,8 +227,7 @@ void P_InitPicAnims(void) // Clear animdefs now that we're done with it. // We'll only be using anims from now on. - if (animdefs != harddefs) - Z_Free(animdefs); + Z_Free(animdefs); animdefs = NULL; } @@ -453,7 +332,8 @@ void P_ParseAnimationDefintion(SINT8 istexture) // Search for existing animdef for (i = 0; i < maxanims; i++) - if (stricmp(animdefsToken, animdefs[i].startname) == 0) + if (animdefs[i].istexture == istexture // Check if it's the same type! + && stricmp(animdefsToken, animdefs[i].startname) == 0) { //CONS_Alert(CONS_NOTICE, "Duplicate animation: %s\n", animdefsToken); @@ -1351,7 +1231,7 @@ static void PolyVisible(line_t *line) po->flags |= POF_SOLID; po->flags &= ~POF_NOSPECIALS; - po->flags |= POF_RENDERALL; + po->flags |= (po->spawnflags & POF_RENDERALL); } // @@ -1375,7 +1255,94 @@ static void PolyTranslucency(line_t *line) if (po->isBad) return; - po->translucency = (line->frontsector->floorheight >> FRACBITS) / 100; + // if DONTPEGBOTTOM, specify raw translucency value in Front X Offset + // else, take it out of 1000. If Front X Offset is specified, use that. Else, use floorheight. + if (line->flags & ML_EFFECT3) // relative calc + po->translucency = max(min(po->translucency + ((line->flags & ML_DONTPEGBOTTOM) ? + (sides[line->sidenum[0]].textureoffset ? + max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), -NUMTRANSMAPS) + : max(min(line->frontsector->floorheight>>FRACBITS, NUMTRANSMAPS), -NUMTRANSMAPS)) + : (sides[line->sidenum[0]].textureoffset ? + max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, 1000), -1000) / 100 + : max(min(line->frontsector->floorheight>>FRACBITS, 1000), -1000) / 100)), + NUMTRANSMAPS), 0); + else + po->translucency = (line->flags & ML_DONTPEGBOTTOM) ? + (sides[line->sidenum[0]].textureoffset ? + max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), 0) + : max(min(line->frontsector->floorheight>>FRACBITS, NUMTRANSMAPS), 0)) + : (sides[line->sidenum[0]].textureoffset ? + max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, 1000), 0) / 100 + : max(min(line->frontsector->floorheight>>FRACBITS, 1000), 0) / 100); +} + +// +// PolyFade +// +// Makes a polyobject translucency fade and applies tangibility +// +static boolean PolyFade(line_t *line) +{ + INT32 polyObjNum = line->tag; + polyobj_t *po; + polyfadedata_t pfd; + + if (!(po = Polyobj_GetForNum(polyObjNum))) + { + CONS_Debug(DBG_POLYOBJ, "PolyFade: bad polyobj %d\n", polyObjNum); + return 0; + } + + // don't allow line actions to affect bad polyobjects + if (po->isBad) + return 0; + + // Prevent continuous execs from interfering on an existing fade + if (!(line->flags & ML_EFFECT5) + && po->thinker + && po->thinker->function.acp1 == (actionf_p1)T_PolyObjFade) + { + CONS_Debug(DBG_POLYOBJ, "Line type 492 Executor: Fade PolyObject thinker already exists\n"); + return 0; + } + + pfd.polyObjNum = polyObjNum; + + // if DONTPEGBOTTOM, specify raw translucency value in Front X Offset + // else, take it out of 1000. If Front X Offset is specified, use that. Else, use floorheight. + if (line->flags & ML_EFFECT3) // relative calc + pfd.destvalue = max(min(po->translucency + ((line->flags & ML_DONTPEGBOTTOM) ? + (sides[line->sidenum[0]].textureoffset ? + max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), -NUMTRANSMAPS) + : max(min(line->frontsector->floorheight>>FRACBITS, NUMTRANSMAPS), -NUMTRANSMAPS)) + : (sides[line->sidenum[0]].textureoffset ? + max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, 1000), -1000) / 100 + : max(min(line->frontsector->floorheight>>FRACBITS, 1000), -1000) / 100)), + NUMTRANSMAPS), 0); + else + pfd.destvalue = (line->flags & ML_DONTPEGBOTTOM) ? + (sides[line->sidenum[0]].textureoffset ? + max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), 0) + : max(min(line->frontsector->floorheight>>FRACBITS, NUMTRANSMAPS), 0)) + : (sides[line->sidenum[0]].textureoffset ? + max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, 1000), 0) / 100 + : max(min(line->frontsector->floorheight>>FRACBITS, 1000), 0) / 100); + + // already equal, nothing to do + if (po->translucency == pfd.destvalue) + return 1; + + pfd.docollision = !(line->flags & ML_BOUNCY); // do not handle collision flags + pfd.doghostfade = (line->flags & ML_EFFECT1); // do ghost fade (no collision flags during fade) + pfd.ticbased = (line->flags & ML_EFFECT4); // Speed = Tic Duration + + // allow Back Y Offset to be consistent with other fade specials + pfd.speed = (line->sidenum[1] != 0xFFFF && !sides[line->sidenum[0]].rowoffset) ? + abs(sides[line->sidenum[1]].rowoffset>>FRACBITS) + : abs(sides[line->sidenum[0]].rowoffset>>FRACBITS); + + + return EV_DoPolyObjFade(&pfd); } // @@ -1445,6 +1412,34 @@ static boolean PolyDisplace(line_t *line) return EV_DoPolyObjDisplace(&pdd); } + +/** Similar to PolyDisplace(). + */ +static boolean PolyRotDisplace(line_t *line) +{ + polyrotdisplacedata_t pdd; + fixed_t anginter, distinter; + + pdd.polyObjNum = line->tag; + pdd.controlSector = line->frontsector; + + // Rotate 'anginter' interval for each 'distinter' interval from the control sector. + // Use default values if not provided as fallback. + anginter = sides[line->sidenum[0]].rowoffset ? sides[line->sidenum[0]].rowoffset : 90*FRACUNIT; + distinter = sides[line->sidenum[0]].textureoffset ? sides[line->sidenum[0]].textureoffset : 128*FRACUNIT; + pdd.rotscale = FixedDiv(anginter, distinter); + + // Same behavior as other rotators when carrying things. + if (line->flags & ML_NOCLIMB) + pdd.turnobjs = 0; + else if (line->flags & ML_EFFECT4) + pdd.turnobjs = 2; + else + pdd.turnobjs = 1; + + return EV_DoPolyObjRotDisplace(&pdd); +} + #endif // ifdef POLYOBJECTS /** Changes a sector's tag. @@ -1508,6 +1503,67 @@ void P_ChangeSectorTag(UINT32 sector, INT16 newtag) } } +// +// P_RunNightserizeExecutors +// +void P_RunNightserizeExecutors(mobj_t *actor) +{ + size_t i; + + for (i = 0; i < numlines; i++) + { + if (lines[i].special == 323 || lines[i].special == 324) + P_RunTriggerLinedef(&lines[i], actor, NULL); + } +} + +// +// P_RunDeNightserizeExecutors +// +void P_RunDeNightserizeExecutors(mobj_t *actor) +{ + size_t i; + + for (i = 0; i < numlines; i++) + { + if (lines[i].special == 325 || lines[i].special == 326) + P_RunTriggerLinedef(&lines[i], actor, NULL); + } +} + +// +// P_RunNightsLapExecutors +// +void P_RunNightsLapExecutors(mobj_t *actor) +{ + size_t i; + + for (i = 0; i < numlines; i++) + { + if (lines[i].special == 327 || lines[i].special == 328) + P_RunTriggerLinedef(&lines[i], actor, NULL); + } +} + +// +// P_RunNightsCapsuleTouchExecutors +// +void P_RunNightsCapsuleTouchExecutors(mobj_t *actor, boolean entering, boolean enoughspheres) +{ + size_t i; + + for (i = 0; i < numlines; i++) + { + if ((lines[i].special == 329 || lines[i].special == 330) + && ((entering && (lines[i].flags & ML_TFERLINE)) + || (!entering && !(lines[i].flags & ML_TFERLINE))) + && ((lines[i].flags & ML_DONTPEGTOP) + || (enoughspheres && !(lines[i].flags & ML_BOUNCY)) + || (!enoughspheres && (lines[i].flags & ML_BOUNCY)))) + P_RunTriggerLinedef(&lines[i], actor, NULL); + } +} + /** Hashes the sector tags across the sectors and linedefs. * * \sa P_FindSectorFromTag, P_ChangeSectorTag @@ -1591,6 +1647,146 @@ static void P_AddExecutorDelay(line_t *line, mobj_t *mobj, sector_t *sector) P_AddThinker(&e->thinker); } +/** Used by P_RunTriggerLinedef to check a NiGHTS trigger linedef's conditions + * + * \param triggerline Trigger linedef to check conditions for; should NEVER be NULL. + * \param actor Object initiating the action; should not be NULL. + * \sa P_RunTriggerLinedef + */ +static boolean P_CheckNightsTriggerLine(line_t *triggerline, mobj_t *actor) +{ + INT16 specialtype = triggerline->special; + size_t i; + + UINT8 inputmare = max(0, min(255, sides[triggerline->sidenum[0]].textureoffset>>FRACBITS)); + UINT8 inputlap = max(0, min(255, sides[triggerline->sidenum[0]].rowoffset>>FRACBITS)); + + boolean ltemare = triggerline->flags & ML_NOCLIMB; + boolean gtemare = triggerline->flags & ML_BLOCKMONSTERS; + boolean ltelap = triggerline->flags & ML_EFFECT1; + boolean gtelap = triggerline->flags & ML_EFFECT2; + + boolean lapfrombonustime = triggerline->flags & ML_EFFECT3; + boolean perglobalinverse = triggerline->flags & ML_DONTPEGBOTTOM; + boolean perglobal = !(triggerline->flags & ML_EFFECT4) && !perglobalinverse; + + boolean donomares = triggerline->flags & ML_BOUNCY; // nightserize: run at end of level (no mares) + boolean fromnonights = triggerline->flags & ML_TFERLINE; // nightserize: from non-nights // denightserize: all players no nights + boolean fromnights = triggerline->flags & ML_DONTPEGTOP; // nightserize: from nights // denightserize: >0 players are nights + + UINT8 currentmare = UINT8_MAX; + UINT8 currentlap = UINT8_MAX; + + // Do early returns for Nightserize + if (specialtype >= 323 && specialtype <= 324) + { + // run only when no mares are found + if (donomares && P_FindLowestMare() != UINT8_MAX) + return false; + + // run only if there is a mare present + if (!donomares && P_FindLowestMare() == UINT8_MAX) + return false; + + // run only if player is nightserizing from non-nights + if (fromnonights) + { + if (!actor->player) + return false; + else if (actor->player->powers[pw_carry] == CR_NIGHTSMODE) + return false; + } + // run only if player is nightserizing from nights + else if (fromnights) + { + if (!actor->player) + return false; + else if (actor->player->powers[pw_carry] != CR_NIGHTSMODE) + return false; + } + } + + // Get current mare and lap (and check early return for DeNightserize) + if (perglobal || perglobalinverse + || (specialtype >= 325 && specialtype <= 326 && (fromnonights || fromnights))) + { + UINT8 playersarenights = 0; + + for (i = 0; i < MAXPLAYERS; i++) + { + UINT8 lap; + if (!playeringame[i] || players[i].spectator) + continue; + + // denightserize: run only if all players are not nights + if (specialtype >= 325 && specialtype <= 326 && fromnonights + && players[i].powers[pw_carry] == CR_NIGHTSMODE) + return false; + + // count number of nights players for denightserize return + if (specialtype >= 325 && specialtype <= 326 && fromnights + && players[i].powers[pw_carry] == CR_NIGHTSMODE) + playersarenights++; + + lap = lapfrombonustime ? players[i].marebonuslap : players[i].marelap; + + // get highest mare/lap of players + if (perglobal) + { + if (players[i].mare > currentmare || currentmare == UINT8_MAX) + { + currentmare = players[i].mare; + currentlap = UINT8_MAX; + } + if (players[i].mare == currentmare + && (lap > currentlap || currentlap == UINT8_MAX)) + currentlap = lap; + } + // get lowest mare/lap of players + else if (perglobalinverse) + { + if (players[i].mare < currentmare || currentmare == UINT8_MAX) + { + currentmare = players[i].mare; + currentlap = UINT8_MAX; + } + if (players[i].mare == currentmare + && (lap < currentlap || currentlap == UINT8_MAX)) + currentlap = lap; + } + } + + // denightserize: run only if >0 players are nights + if (specialtype >= 325 && specialtype <= 326 && fromnights + && playersarenights < 1) + return false; + } + // get current mare/lap from triggering player + else if (!perglobal && !perglobalinverse) + { + if (!actor->player) + return false; + currentmare = actor->player->mare; + currentlap = lapfrombonustime ? actor->player->marebonuslap : actor->player->marelap; + } + + if (lapfrombonustime && !currentlap) + return false; // special case: player->marebonuslap is 0 until passing through on bonus time. Don't trigger lines looking for inputlap 0. + + // Compare current mare/lap to input mare/lap based on rules + if (!(specialtype >= 323 && specialtype <= 324 && donomares) // don't return false if donomares and we got this far + && ((ltemare && currentmare > inputmare) + || (gtemare && currentmare < inputmare) + || (!ltemare && !gtemare && currentmare != inputmare) + || (ltelap && currentlap > inputlap) + || (gtelap && currentlap < inputlap) + || (!ltelap && !gtelap && currentlap != inputlap)) + ) + return false; + + return true; +} + /** Used by P_LinedefExecute to check a trigger linedef's conditions * The linedef executor specials in the trigger linedef's sector are run if all conditions are met. * Return false cancels P_LinedefExecute, this happens if a condition is not met. @@ -1626,10 +1822,10 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller if (!playeringame[i] || players[i].spectator) continue; - if (!players[i].mo || players[i].mo->health < 1) + if (!players[i].mo || ((maptol & TOL_NIGHTS) ? players[i].spheres : players[i].rings) <= 0) continue; - rings += players[i].mo->health-1; + rings += (maptol & TOL_NIGHTS) ? players[i].spheres : players[i].rings; } } else @@ -1637,7 +1833,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller if (!(actor && actor->player)) return false; // no player to count rings from here, sorry - rings = actor->health-1; + rings = (maptol & TOL_NIGHTS) ? actor->player->spheres : actor->player->rings; } if (triggerline->flags & ML_NOCLIMB) @@ -1801,6 +1997,18 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller return false; } break; + case 323: // nightserize - each time + case 324: // nightserize - once + case 325: // denightserize - each time + case 326: // denightserize - once + case 327: // nights lap - each time + case 328: // nights lap - once + case 329: // nights egg capsule touch - each time + case 330: // nights egg capsule touch - once + if (!P_CheckNightsTriggerLine(triggerline, actor)) + return false; + break; + default: break; } @@ -1924,10 +2132,15 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller || specialtype == 304 // Ring count - Once || specialtype == 307 // Character ability - Once || specialtype == 308 // Race only - Once + || specialtype == 313 // No More Enemies - Once || specialtype == 315 // No of pushables - Once || specialtype == 318 // Unlockable trigger - Once || specialtype == 320 // Unlockable - Once || specialtype == 321 || specialtype == 322 // Trigger on X calls - Continuous + Each Time + || specialtype == 324 // Nightserize - Once + || specialtype == 326 // DeNightserize - Once + || specialtype == 328 // Nights lap - Once + || specialtype == 330 // Nights Bonus Time - Once || specialtype == 399) // Level Load triggerline->special = 0; // Clear it out @@ -2406,7 +2619,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 413: // Change music // console player only unless NOCLIMB is set - if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player))) + if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player)) || titlemapinaction) { boolean musicsame = (!sides[line->sidenum[0]].text[0] || !strnicmp(sides[line->sidenum[0]].text, S_MusicName(), 7)); UINT16 tracknum = (UINT16)max(sides[line->sidenum[0]].bottomtexture, 0); @@ -2480,7 +2693,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { INT32 sfxnum; - sfxnum = sides[line->sidenum[0]].toptexture; //P_AproxDistance(line->dx, line->dy)>>FRACBITS; + sfxnum = sides[line->sidenum[0]].toptexture; if (sfxnum == sfx_None) return; // Do nothing! @@ -2731,7 +2944,17 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 420: // Fade light levels in tagged sectors to new value - P_FadeLight(line->tag, line->frontsector->lightlevel, P_AproxDistance(line->dx, line->dy)>>FRACBITS); + P_FadeLight(line->tag, + (line->flags & ML_DONTPEGBOTTOM) ? max(sides[line->sidenum[0]].textureoffset>>FRACBITS, 0) : line->frontsector->lightlevel, + // failsafe: if user specifies Back Y Offset and NOT Front Y Offset, use the Back Offset + // to be consistent with other light and fade specials + (line->flags & ML_DONTPEGBOTTOM) ? + ((line->sidenum[1] != 0xFFFF && !(sides[line->sidenum[0]].rowoffset>>FRACBITS)) ? + max(min(sides[line->sidenum[1]].rowoffset>>FRACBITS, 255), 0) + : max(min(sides[line->sidenum[0]].rowoffset>>FRACBITS, 255), 0)) + : abs(P_AproxDistance(line->dx, line->dy))>>FRACBITS, + (line->flags & ML_EFFECT4), + (line->flags & ML_EFFECT5)); break; case 421: // Stop lighting effect in tagged sectors @@ -2747,7 +2970,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { mobj_t *altview; - if (!mo || !mo->player) // only players have views + if ((!mo || !mo->player) && !titlemapinaction) // only players have views, and title screens return; if ((secnum = P_FindSectorFromLineTag(line, -1)) < 0) @@ -2757,6 +2980,14 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (!altview) return; + // If titlemap, set the camera ref for title's thinker + // This is not revoked until overwritten; awayviewtics is ignored + if (titlemapinaction) + { + titlemapcameraref = altview; + return; + } + P_SetTarget(&mo->player->awayviewmobj, altview); mo->player->awayviewtics = P_AproxDistance(line->dx, line->dy)>>FRACBITS; @@ -2935,6 +3166,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in ffloor_t *rover; // FOF that we are going to crumble + boolean foundrover = false; // for debug, "Can't find a FOF" message for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) { @@ -2949,16 +3181,18 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) for (rover = sec->ffloors; rover; rover = rover->next) { if (rover->master->frontsector->tag == foftag) - break; + { + foundrover = true; + + EV_CrumbleChain(sec, rover); + } } - if (!rover) + if (!foundrover) { CONS_Debug(DBG_GAMELOGIC, "Line type 436 Executor: Can't find a FOF control sector with tag %d\n", foftag); return; } - - EV_CrumbleChain(sec, rover); } } break; @@ -3038,7 +3272,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // Unlocked something? if (M_UpdateUnlockablesAndExtraEmblems()) { - S_StartSound(NULL, sfx_ncitem); + S_StartSound(NULL, sfx_s3k68); G_SaveGameData(); // only save if unlocked something } } @@ -3119,6 +3353,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible (or not visible) in ffloor_t *rover; // FOF to vanish/un-vanish + boolean foundrover = false; // for debug, "Can't find a FOF" message ffloortype_e oldflags; // store FOF's old flags for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) @@ -3134,27 +3369,178 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) for (rover = sec->ffloors; rover; rover = rover->next) { if (rover->master->frontsector->tag == foftag) - break; + { + foundrover = true; + + oldflags = rover->flags; + + // Abracadabra! + if (line->flags & ML_NOCLIMB) + rover->flags |= FF_EXISTS; + else + rover->flags &= ~FF_EXISTS; + + // if flags changed, reset sector's light list + if (rover->flags != oldflags) + sec->moved = true; + } } - if (!rover) + if (!foundrover) { CONS_Debug(DBG_GAMELOGIC, "Line type 445 Executor: Can't find a FOF control sector with tag %d\n", foftag); return; } + } + } + break; + + case 446: // Make block fall remotely (acts like FF_CRUMBLE) + { + INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); + INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); + sector_t *sec; // Sector that the FOF is visible in + ffloor_t *rover; // FOF that we are going to make fall down + boolean foundrover = false; // for debug, "Can't find a FOF" message + player_t *player = NULL; // player that caused FOF to fall + boolean respawn = true; // should the fallen FOF respawn? - oldflags = rover->flags; + if (mo) // NULL check + player = mo->player; - // Abracadabra! - if (line->flags & ML_NOCLIMB) - rover->flags |= FF_EXISTS; + if (line->flags & ML_NOCLIMB) // don't respawn! + respawn = false; + + for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) + { + sec = sectors + secnum; + + if (!sec->ffloors) + { + CONS_Debug(DBG_GAMELOGIC, "Line type 446 Executor: Target sector #%d has no FOFs.\n", secnum); + return; + } + + for (rover = sec->ffloors; rover; rover = rover->next) + { + if (rover->master->frontsector->tag == foftag) + { + foundrover = true; + + if (line->flags & ML_BLOCKMONSTERS) // FOF flags determine respawn ability instead? + respawn = !(rover->flags & FF_NORETURN) ^ !!(line->flags & ML_NOCLIMB); // no climb inverts + + EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), player, rover->alpha, respawn); + } + } + + if (!foundrover) + { + CONS_Debug(DBG_GAMELOGIC, "Line type 446 Executor: Can't find a FOF control sector with tag %d\n", foftag); + return; + } + } + } + break; + + case 447: // Change colormap of tagged sectors! + // Basically this special applies a colormap to the tagged sectors, just like 606 (the colormap linedef) + // Except it is activated by linedef executor, not level load + // This could even override existing colormaps I believe + // -- Monster Iestyn 14/06/18 + for (secnum = -1; (secnum = P_FindSectorFromLineTag(line, secnum)) >= 0 ;) + { + P_ResetColormapFader(§ors[secnum]); + + if (line->flags & ML_EFFECT3) // relative calc + { + extracolormap_t *exc = R_AddColormaps( + (line->flags & ML_TFERLINE) && line->sidenum[1] != 0xFFFF ? + sides[line->sidenum[1]].colormap_data : sectors[secnum].extra_colormap, // use back colormap instead of target sector + sides[line->sidenum[0]].colormap_data, + line->flags & ML_EFFECT1, // subtract R + line->flags & ML_NOCLIMB, // subtract G + line->flags & ML_EFFECT2, // subtract B + false, // subtract A (no flag for this, just pass negative alpha) + line->flags & ML_EFFECT1, // subtract FadeR + line->flags & ML_NOCLIMB, // subtract FadeG + line->flags & ML_EFFECT2, // subtract FadeB + false, // subtract FadeA (no flag for this, just pass negative alpha) + false, // subtract FadeStart (we ran out of flags) + false, // subtract FadeEnd (we ran out of flags) + false, // ignore Fog (we ran out of flags) + line->flags & ML_DONTPEGBOTTOM, + (line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].textureoffset >> FRACBITS) : 0, + (line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].rowoffset >> FRACBITS) : 0, + false); + + if (!(sectors[secnum].extra_colormap = R_GetColormapFromList(exc))) + { + exc->colormap = R_CreateLightTable(exc); + R_AddColormapToList(exc); + sectors[secnum].extra_colormap = exc; + } + else + Z_Free(exc); + } + else if (line->flags & ML_DONTPEGBOTTOM) // alternate alpha (by texture offsets) + { + extracolormap_t *exc = R_CopyColormap(sides[line->sidenum[0]].colormap_data, false); + exc->rgba = R_GetRgbaRGB(exc->rgba) + R_PutRgbaA(max(min(sides[line->sidenum[0]].textureoffset >> FRACBITS, 25), 0)); + exc->fadergba = R_GetRgbaRGB(exc->fadergba) + R_PutRgbaA(max(min(sides[line->sidenum[0]].rowoffset >> FRACBITS, 25), 0)); + + if (!(sectors[secnum].extra_colormap = R_GetColormapFromList(exc))) + { + exc->colormap = R_CreateLightTable(exc); + R_AddColormapToList(exc); + sectors[secnum].extra_colormap = exc; + } else - rover->flags &= ~FF_EXISTS; + Z_Free(exc); + } + else + sectors[secnum].extra_colormap = sides[line->sidenum[0]].colormap_data; + } + break; + + case 448: // Change skybox viewpoint/centerpoint + if ((mo && mo->player && P_IsLocalPlayer(mo->player)) || (line->flags & ML_NOCLIMB)) + { + INT32 viewid = sides[line->sidenum[0]].textureoffset>>FRACBITS; + INT32 centerid = sides[line->sidenum[0]].rowoffset>>FRACBITS; + + if ((line->flags & (ML_EFFECT4|ML_BLOCKMONSTERS)) == ML_EFFECT4) // Solid Midtexture is on but Block Enemies is off? + { + CONS_Alert(CONS_WARNING, + M_GetText("Skybox switch linedef (tag %d) doesn't have anything to do.\nConsider changing the linedef's flag configuration or removing it entirely.\n"), + line->tag); + } + else + { + // set viewpoint mobj + if (!(line->flags & ML_EFFECT4)) // Solid Midtexture turns off viewpoint setting + { + if (viewid >= 0 && viewid < 16) + skyboxmo[0] = skyboxviewpnts[viewid]; + else + skyboxmo[0] = NULL; + } - // if flags changed, reset sector's light list - if (rover->flags != oldflags) - sec->moved = true; + // set centerpoint mobj + if (line->flags & ML_BLOCKMONSTERS) // Block Enemies turns ON centerpoint setting + { + if (centerid >= 0 && centerid < 16) + skyboxmo[1] = skyboxcenterpnts[centerid]; + else + skyboxmo[1] = NULL; + } } + + CONS_Debug(DBG_GAMELOGIC, "Line type 448 Executor: viewid = %d, centerid = %d, viewpoint? = %s, centerpoint? = %s\n", + viewid, + centerid, + ((line->flags & ML_EFFECT4) ? "no" : "yes"), + ((line->flags & ML_BLOCKMONSTERS) ? "yes" : "no")); } break; @@ -3177,15 +3563,360 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; } -#ifdef POLYOBJECTS - case 480: // Polyobj_DoorSlide - case 481: // Polyobj_DoorSwing - PolyDoor(line); - break; - case 482: // Polyobj_Move - case 483: // Polyobj_OR_Move - PolyMove(line); - break; + case 452: // Set FOF alpha + { + INT16 destvalue = line->sidenum[1] != 0xffff ? + (INT16)(sides[line->sidenum[1]].textureoffset>>FRACBITS) : (INT16)(P_AproxDistance(line->dx, line->dy)>>FRACBITS); + INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); + INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); + sector_t *sec; // Sector that the FOF is visible in + ffloor_t *rover; // FOF that we are going to operate + boolean foundrover = false; // for debug, "Can't find a FOF" message + + for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) + { + sec = sectors + secnum; + + if (!sec->ffloors) + { + CONS_Debug(DBG_GAMELOGIC, "Line type 452 Executor: Target sector #%d has no FOFs.\n", secnum); + return; + } + + for (rover = sec->ffloors; rover; rover = rover->next) + { + if (rover->master->frontsector->tag == foftag) + { + foundrover = true; + + // If fading an invisible FOF whose render flags we did not yet set, + // initialize its alpha to 1 + // for relative alpha calc + if (!(line->flags & ML_NOCLIMB) && // do translucent + (rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE + !(rover->spawnflags & FF_RENDERSIDES) && + !(rover->spawnflags & FF_RENDERPLANES) && + !(rover->flags & FF_RENDERALL)) + rover->alpha = 1; + + P_RemoveFakeFloorFader(rover); + P_FadeFakeFloor(rover, + rover->alpha, + max(1, min(256, (line->flags & ML_EFFECT3) ? rover->alpha + destvalue : destvalue)), + 0, // set alpha immediately + false, NULL, // tic-based logic + false, // do not handle FF_EXISTS + !(line->flags & ML_NOCLIMB), // handle FF_TRANSLUCENT + false, // do not handle lighting + false, // do not handle colormap + false, // do not handle collision + false, // do not do ghost fade (no collision during fade) + true); // use exact alpha values (for opengl) + } + } + + if (!foundrover) + { + CONS_Debug(DBG_GAMELOGIC, "Line type 452 Executor: Can't find a FOF control sector with tag %d\n", foftag); + return; + } + } + break; + } + + case 453: // Fade FOF + { + INT16 destvalue = line->sidenum[1] != 0xffff ? + (INT16)(sides[line->sidenum[1]].textureoffset>>FRACBITS) : (INT16)(line->dx>>FRACBITS); + INT16 speed = line->sidenum[1] != 0xffff ? + (INT16)(abs(sides[line->sidenum[1]].rowoffset>>FRACBITS)) : (INT16)(abs(line->dy)>>FRACBITS); + INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); + INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); + sector_t *sec; // Sector that the FOF is visible in + ffloor_t *rover; // FOF that we are going to operate + boolean foundrover = false; // for debug, "Can't find a FOF" message + size_t j = 0; // sec->ffloors is saved as ffloor #0, ss->ffloors->next is #1, etc + + for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) + { + sec = sectors + secnum; + + if (!sec->ffloors) + { + CONS_Debug(DBG_GAMELOGIC, "Line type 453 Executor: Target sector #%d has no FOFs.\n", secnum); + return; + } + + for (rover = sec->ffloors; rover; rover = rover->next) + { + if (rover->master->frontsector->tag == foftag) + { + foundrover = true; + + // Prevent continuous execs from interfering on an existing fade + if (!(line->flags & ML_EFFECT5) + && rover->fadingdata) + //&& ((fade_t*)rover->fadingdata)->timer > (ticbased ? 2 : speed*2)) + { + CONS_Debug(DBG_GAMELOGIC, "Line type 453 Executor: Fade FOF thinker already exists, timer: %d\n", ((fade_t*)rover->fadingdata)->timer); + continue; + } + + if (speed > 0) + P_AddFakeFloorFader(rover, secnum, j, + destvalue, + speed, + (line->flags & ML_EFFECT4), // tic-based logic + (line->flags & ML_EFFECT3), // Relative destvalue + !(line->flags & ML_BLOCKMONSTERS), // do not handle FF_EXISTS + !(line->flags & ML_NOCLIMB), // do not handle FF_TRANSLUCENT + !(line->flags & ML_EFFECT2), // do not handle lighting + !(line->flags & ML_EFFECT2), // do not handle colormap (ran out of flags) + !(line->flags & ML_BOUNCY), // do not handle collision + (line->flags & ML_EFFECT1), // do ghost fade (no collision during fade) + (line->flags & ML_TFERLINE)); // use exact alpha values (for opengl) + else + { + // If fading an invisible FOF whose render flags we did not yet set, + // initialize its alpha to 1 + // for relative alpha calc + if (!(line->flags & ML_NOCLIMB) && // do translucent + (rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE + !(rover->spawnflags & FF_RENDERSIDES) && + !(rover->spawnflags & FF_RENDERPLANES) && + !(rover->flags & FF_RENDERALL)) + rover->alpha = 1; + + P_RemoveFakeFloorFader(rover); + P_FadeFakeFloor(rover, + rover->alpha, + max(1, min(256, (line->flags & ML_EFFECT3) ? rover->alpha + destvalue : destvalue)), + 0, // set alpha immediately + false, NULL, // tic-based logic + !(line->flags & ML_BLOCKMONSTERS), // do not handle FF_EXISTS + !(line->flags & ML_NOCLIMB), // do not handle FF_TRANSLUCENT + !(line->flags & ML_EFFECT2), // do not handle lighting + !(line->flags & ML_EFFECT2), // do not handle colormap (ran out of flags) + !(line->flags & ML_BOUNCY), // do not handle collision + (line->flags & ML_EFFECT1), // do ghost fade (no collision during fade) + (line->flags & ML_TFERLINE)); // use exact alpha values (for opengl) + } + } + j++; + } + + if (!foundrover) + { + CONS_Debug(DBG_GAMELOGIC, "Line type 453 Executor: Can't find a FOF control sector with tag %d\n", foftag); + return; + } + } + break; + } + + case 454: // Stop fading FOF + { + INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); + INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); + sector_t *sec; // Sector that the FOF is visible in + ffloor_t *rover; // FOF that we are going to operate + boolean foundrover = false; // for debug, "Can't find a FOF" message + + for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) + { + sec = sectors + secnum; + + if (!sec->ffloors) + { + CONS_Debug(DBG_GAMELOGIC, "Line type 454 Executor: Target sector #%d has no FOFs.\n", secnum); + return; + } + + for (rover = sec->ffloors; rover; rover = rover->next) + { + if (rover->master->frontsector->tag == foftag) + { + foundrover = true; + + P_ResetFakeFloorFader(rover, NULL, + !(line->flags & ML_BLOCKMONSTERS)); // do not finalize collision flags + } + } + + if (!foundrover) + { + CONS_Debug(DBG_GAMELOGIC, "Line type 454 Executor: Can't find a FOF control sector with tag %d\n", foftag); + return; + } + } + break; + } + + case 455: // Fade colormap + for (secnum = -1; (secnum = P_FindSectorFromLineTag(line, secnum)) >= 0 ;) + { + extracolormap_t *source_exc, *dest_exc, *exc; + INT32 speed = (INT32)((line->flags & ML_DONTPEGBOTTOM) || !sides[line->sidenum[0]].rowoffset) && line->sidenum[1] != 0xFFFF ? + abs(sides[line->sidenum[1]].rowoffset >> FRACBITS) + : abs(sides[line->sidenum[0]].rowoffset >> FRACBITS); + + // Prevent continuous execs from interfering on an existing fade + if (!(line->flags & ML_EFFECT5) + && sectors[secnum].fadecolormapdata) + //&& ((fadecolormap_t*)sectors[secnum].fadecolormapdata)->timer > (ticbased ? 2 : speed*2)) + { + CONS_Debug(DBG_GAMELOGIC, "Line type 455 Executor: Fade color thinker already exists, timer: %d\n", ((fadecolormap_t*)sectors[secnum].fadecolormapdata)->timer); + continue; + } + + if (line->flags & ML_TFERLINE) // use back colormap instead of target sector + sectors[secnum].extra_colormap = (line->sidenum[1] != 0xFFFF) ? + sides[line->sidenum[1]].colormap_data : NULL; + + exc = sectors[secnum].extra_colormap; + + if (!(line->flags & ML_BOUNCY) // BOUNCY: Do not override fade from default rgba + && !R_CheckDefaultColormap(sides[line->sidenum[0]].colormap_data, true, false, false) + && R_CheckDefaultColormap(exc, true, false, false)) + { + exc = R_CopyColormap(exc, false); + exc->rgba = R_GetRgbaRGB(sides[line->sidenum[0]].colormap_data->rgba) + R_PutRgbaA(R_GetRgbaA(exc->rgba)); + //exc->fadergba = R_GetRgbaRGB(sides[line->sidenum[0]].colormap_data->rgba) + R_PutRgbaA(R_GetRgbaA(exc->fadergba)); + + if (!(source_exc = R_GetColormapFromList(exc))) + { + exc->colormap = R_CreateLightTable(exc); + R_AddColormapToList(exc); + source_exc = exc; + } + else + Z_Free(exc); + + sectors[secnum].extra_colormap = source_exc; + } + else + source_exc = exc ? exc : R_GetDefaultColormap(); + + if (line->flags & ML_EFFECT3) // relative calc + { + exc = R_AddColormaps( + source_exc, + sides[line->sidenum[0]].colormap_data, + line->flags & ML_EFFECT1, // subtract R + line->flags & ML_NOCLIMB, // subtract G + line->flags & ML_EFFECT2, // subtract B + false, // subtract A (no flag for this, just pass negative alpha) + line->flags & ML_EFFECT1, // subtract FadeR + line->flags & ML_NOCLIMB, // subtract FadeG + line->flags & ML_EFFECT2, // subtract FadeB + false, // subtract FadeA (no flag for this, just pass negative alpha) + false, // subtract FadeStart (we ran out of flags) + false, // subtract FadeEnd (we ran out of flags) + false, // ignore Fog (we ran out of flags) + line->flags & ML_DONTPEGBOTTOM, + (line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].textureoffset >> FRACBITS) : 0, + (line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].rowoffset >> FRACBITS) : 0, + false); + } + else if (line->flags & ML_DONTPEGBOTTOM) // alternate alpha (by texture offsets) + { + exc = R_CopyColormap(sides[line->sidenum[0]].colormap_data, false); + exc->rgba = R_GetRgbaRGB(exc->rgba) + R_PutRgbaA(max(min(sides[line->sidenum[0]].textureoffset >> FRACBITS, 25), 0)); + exc->fadergba = R_GetRgbaRGB(exc->fadergba) + R_PutRgbaA(max(min(sides[line->sidenum[0]].rowoffset >> FRACBITS, 25), 0)); + } + else + exc = R_CopyColormap(sides[line->sidenum[0]].colormap_data, false); + + if (!(dest_exc = R_GetColormapFromList(exc))) + { + exc->colormap = R_CreateLightTable(exc); + R_AddColormapToList(exc); + dest_exc = exc; + } + else + Z_Free(exc); + + Add_ColormapFader(§ors[secnum], source_exc, dest_exc, (line->flags & ML_EFFECT4), // tic-based timing + speed); + } + break; + + case 456: // Stop fade colormap + for (secnum = -1; (secnum = P_FindSectorFromLineTag(line, secnum)) >= 0 ;) + P_ResetColormapFader(§ors[secnum]); + break; + + case 457: // Track mobj angle to point + if (mo) + { + INT32 failureangle = FixedAngle((min(max(abs(sides[line->sidenum[0]].textureoffset>>FRACBITS), 0), 360))*FRACUNIT); + INT32 failuredelay = abs(sides[line->sidenum[0]].rowoffset>>FRACBITS); + INT32 failureexectag = line->sidenum[1] != 0xffff ? + (INT32)(sides[line->sidenum[1]].textureoffset>>FRACBITS) : 0; + boolean persist = (line->flags & ML_EFFECT2); + mobj_t *anchormo; + + if ((secnum = P_FindSectorFromLineTag(line, -1)) < 0) + return; + + anchormo = P_GetObjectTypeInSectorNum(MT_ANGLEMAN, secnum); + if (!anchormo) + return; + + mo->eflags |= MFE_TRACERANGLE; + P_SetTarget(&mo->tracer, anchormo); + mo->lastlook = persist; // don't disable behavior after first failure + mo->extravalue1 = failureangle; // angle to exceed for failure state + mo->extravalue2 = failureexectag; // exec tag for failure state (angle is not within range) + mo->cusval = mo->cvmem = failuredelay; // cusval = tics to allow failure before line trigger; cvmem = decrement timer + } + break; + + case 458: // Stop tracking mobj angle to point + if (mo && (mo->eflags & MFE_TRACERANGLE)) + { + mo->eflags &= ~MFE_TRACERANGLE; + P_SetTarget(&mo->tracer, NULL); + mo->lastlook = mo->cvmem = mo->cusval = mo->extravalue1 = mo->extravalue2 = 0; + } + break; + + case 459: // Control Text Prompt + // console player only unless NOCLIMB is set + if (mo && mo->player && P_IsLocalPlayer(mo->player) && (!bot || bot != mo)) + { + INT32 promptnum = max(0, (sides[line->sidenum[0]].textureoffset>>FRACBITS)-1); + INT32 pagenum = max(0, (sides[line->sidenum[0]].rowoffset>>FRACBITS)-1); + INT32 postexectag = abs((line->sidenum[1] != 0xFFFF) ? sides[line->sidenum[1]].textureoffset>>FRACBITS : line->tag); + + boolean closetextprompt = (line->flags & ML_BLOCKMONSTERS); + //boolean allplayers = (line->flags & ML_NOCLIMB); + boolean runpostexec = (line->flags & ML_EFFECT1); + boolean blockcontrols = !(line->flags & ML_EFFECT2); + boolean freezerealtime = !(line->flags & ML_EFFECT3); + //boolean freezethinkers = (line->flags & ML_EFFECT4); + boolean callbynamedtag = (line->flags & ML_TFERLINE); + + if (closetextprompt) + F_EndTextPrompt(false, false); + else + { + if (callbynamedtag && sides[line->sidenum[0]].text && sides[line->sidenum[0]].text[0]) + F_GetPromptPageByNamedTag(sides[line->sidenum[0]].text, &promptnum, &pagenum); + F_StartTextPrompt(promptnum, pagenum, mo, runpostexec ? postexectag : 0, blockcontrols, freezerealtime); + } + } + break; + +#ifdef POLYOBJECTS + case 480: // Polyobj_DoorSlide + case 481: // Polyobj_DoorSwing + PolyDoor(line); + break; + case 482: // Polyobj_Move + case 483: // Polyobj_OR_Move + PolyMove(line); + break; case 484: // Polyobj_RotateRight case 485: // Polyobj_OR_RotateRight case 486: // Polyobj_RotateLeft @@ -3204,6 +3935,9 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 491: PolyTranslucency(line); break; + case 492: + PolyFade(line); + break; #endif default: @@ -3574,19 +4308,19 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers { case 1: // Damage (Generic) if (roversector || P_MobjReadyToTrigger(player->mo, sector)) - P_DamageMobj(player->mo, NULL, NULL, 1); + P_DamageMobj(player->mo, NULL, NULL, 1, 0); break; case 2: // Damage (Water) - if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_underwater] || player->pflags & PF_NIGHTSMODE) && (player->powers[pw_shield] & SH_NOSTACK) != SH_ELEMENTAL) - P_DamageMobj(player->mo, NULL, NULL, 1); + if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_underwater] || player->powers[pw_carry] == CR_NIGHTSMODE)) + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_WATER); break; case 3: // Damage (Fire) - if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_shield] & SH_NOSTACK) != SH_ELEMENTAL) - P_DamageMobj(player->mo, NULL, NULL, 1); + if (roversector || P_MobjReadyToTrigger(player->mo, sector)) + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_FIRE); break; case 4: // Damage (Electrical) - if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_shield] & SH_NOSTACK) != SH_ATTRACT) - P_DamageMobj(player->mo, NULL, NULL, 1); + if (roversector || P_MobjReadyToTrigger(player->mo, sector)) + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_ELECTRIC); break; case 5: // Spikes // Don't do anything. In Soviet Russia, spikes find you. @@ -3594,49 +4328,30 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers case 6: // Death Pit (Camera Mod) case 7: // Death Pit (No Camera Mod) if (roversector || P_MobjReadyToTrigger(player->mo, sector)) - P_DamageMobj(player->mo, NULL, NULL, 10000); + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DEATHPIT); break; case 8: // Instant Kill - P_DamageMobj(player->mo, NULL, NULL, 10000); + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL); break; case 9: // Ring Drainer (Floor Touch) case 10: // Ring Drainer (No Floor Touch) - if (leveltime % (TICRATE/2) == 0 && player->mo->health > 1) + if (leveltime % (TICRATE/2) == 0 && player->rings > 0) { - player->mo->health--; - player->health--; + player->rings--; S_StartSound(player->mo, sfx_itemup); } break; - case 11: // Special Stage Damage - Kind of like a mini-P_DamageMobj() - if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super] || player->exiting || player->bot) + case 11: // Special Stage Damage + if (player->exiting || player->bot) // Don't do anything for bots or players who have just finished break; - if (!(player->powers[pw_shield] || player->mo->health > 1)) // Don't do anything if no shield or rings anyway + if (!(player->powers[pw_shield] || player->spheres > 0)) // Don't do anything if no shield or spheres anyway break; - if (player->powers[pw_shield]) - { - P_RemoveShield(player); - S_StartSound(player->mo, sfx_shldls); // Ba-Dum! Shield loss. - } - else if (player->mo->health > 1) - { - P_PlayRinglossSound(player->mo); - if (player->mo->health > 10) - player->mo->health -= 10; - else - player->mo->health = 1; - player->health = player->mo->health; - } - - P_DoPlayerPain(player, NULL, NULL); // this does basically everything that was here before - - if (gametype == GT_CTF && player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)) - P_PlayerFlagBurst(player, false); + P_SpecialStageDamage(player, NULL, NULL); break; case 12: // Space Countdown - if ((player->powers[pw_shield] & SH_NOSTACK) != SH_ELEMENTAL && !player->powers[pw_spacetime]) + if (!(player->powers[pw_shield] & SH_PROTECTWATER) && !player->powers[pw_spacetime]) player->powers[pw_spacetime] = spacetimetics + 1; break; case 13: // Ramp Sector (Increase step-up/down) @@ -3737,7 +4452,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers mo2 = (mobj_t *)th; if (mo2->type == MT_EGGTRAP) - P_KillMobj(mo2, NULL, player->mo); + P_KillMobj(mo2, NULL, player->mo, 0); } // clear the special so you can't push the button twice. @@ -3772,14 +4487,13 @@ DoneSection2: // Process Section 3 switch (special) { - case 1: // Ice/Sludge + case 1: // Unused case 2: // Wind/Current - case 3: // Ice/Sludge and Wind/Current + case 3: // Unused case 4: // Conveyor Belt break; - case 5: // Speed pad w/o spin - case 6: // Speed pad w/ spin + case 5: // Speed pad if (player->powers[pw_flashing] != 0 && player->powers[pw_flashing] < TICRATE/2) break; @@ -3789,11 +4503,18 @@ DoneSection2: { angle_t lineangle; fixed_t linespeed; + fixed_t sfxnum; lineangle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y); - linespeed = P_AproxDistance(lines[i].v2->x-lines[i].v1->x, lines[i].v2->y-lines[i].v1->y); + linespeed = sides[lines[i].sidenum[0]].textureoffset; - player->mo->angle = lineangle; + if (linespeed == 0) + { + CONS_Debug(DBG_GAMELOGIC, "ERROR: Speed pad (tag %d) at zero speed.\n", sector->tag); + break; + } + + player->mo->angle = player->drawangle = lineangle; if (!demoplayback || P_AnalogMove(player)) { @@ -3821,28 +4542,35 @@ DoneSection2: P_InstaThrust(player->mo, player->mo->angle, linespeed); - if (GETSECSPECIAL(sector->special, 3) == 6 && (player->charability2 == CA2_SPINDASH)) + if ((lines[i].flags & ML_EFFECT5) && (player->charability2 == CA2_SPINDASH)) // Roll! { if (!(player->pflags & PF_SPINNING)) player->pflags |= PF_SPINNING; - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); } player->powers[pw_flashing] = TICRATE/3; - S_StartSound(player->mo, sfx_spdpad); + + sfxnum = sides[lines[i].sidenum[0]].toptexture; + + if (!sfxnum) + sfxnum = sfx_spdpad; + + S_StartSound(player->mo, sfxnum); } break; - case 7: // Bustable block sprite parameter - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: + case 6: // Unused + case 7: // Unused + case 8: // Unused + case 9: // Unused + case 10: // Unused + case 11: // Unused + case 12: // Unused + case 13: // Unused + case 14: // Unused + case 15: // Unused break; } @@ -3865,8 +4593,8 @@ DoneSection2: case 2: // Special stage GOAL sector / Exit Sector / CTF Flag Return if (player->bot) break; - if (!useNightsSS && G_IsSpecialStage(gamemap) && sstimer > 6) - sstimer = 6; // Just let P_Ticker take care of the rest. + if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap) && player->nightstime > 6) + player->nightstime = 6; // Just let P_Ticker take care of the rest. // Exit (for FOF exits; others are handled in P_PlayerThink in p_user.c) { @@ -3906,9 +4634,9 @@ DoneSection2: if (!P_IsFlagAtBase(MT_REDFLAG)) break; - HU_SetCEchoFlags(0); + HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE); HU_SetCEchoDuration(5); - HU_DoCEcho(va(M_GetText("%s\\captured the blue flag.\\\\\\\\"), player_names[player-players])); + HU_DoCEcho(va(M_GetText("%s%s%s\\CAPTURED THE %sBLUE FLAG%s.\\\\\\\\"), "\x85", player_names[player-players], "\x80", "\x84", "\x80")); if (splitscreen || players[consoleplayer].ctfteam == 1) S_StartSound(NULL, sfx_flgcap); @@ -3939,9 +4667,9 @@ DoneSection2: if (!P_IsFlagAtBase(MT_BLUEFLAG)) break; - HU_SetCEchoFlags(0); + HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE); HU_SetCEchoDuration(5); - HU_DoCEcho(va(M_GetText("%s\\captured the red flag.\\\\\\\\"), player_names[player-players])); + HU_DoCEcho(va(M_GetText("%s%s%s\\CAPTURED THE %sRED FLAG%s.\\\\\\\\"), "\x84", player_names[player-players], "\x80", "\x85", "\x80")); if (splitscreen || players[consoleplayer].ctfteam == 2) S_StartSound(NULL, sfx_flgcap); @@ -3968,7 +4696,7 @@ DoneSection2: P_ResetPlayer(player); if (player->panim != PA_FALL) - P_SetPlayerMobjState(player->mo, S_PLAY_FALL1); + P_SetPlayerMobjState(player->mo, S_PLAY_FALL); break; case 6: // Super Sonic transformer @@ -3980,7 +4708,7 @@ DoneSection2: if (!(player->pflags & PF_SPINNING) && P_IsObjectOnGround(player->mo) && (player->charability2 == CA2_SPINDASH)) { player->pflags |= PF_SPINNING; - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); S_StartAttackSound(player->mo, sfx_spin); if (abs(player->rmomx) < FixedMul(5*FRACUNIT, player->mo->scale) @@ -3999,7 +4727,7 @@ DoneSection2: mobj_t *mo2; angle_t an; - if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT) + if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE) break; // Find line #3 tagged to this sector @@ -4012,8 +4740,14 @@ DoneSection2: } // Grab speed and sequence values - speed = abs(lines[lineindex].dx)/8; - sequence = abs(lines[lineindex].dy)>>FRACBITS; + speed = abs(sides[lines[lineindex].sidenum[0]].textureoffset)/8; + sequence = abs(sides[lines[lineindex].sidenum[0]].rowoffset)>>FRACBITS; + + if (speed == 0) + { + CONS_Debug(DBG_GAMELOGIC, "ERROR: Waypoint sequence %d at zero speed.\n", sequence); + break; + } // scan the thinkers // to find the first waypoint @@ -4048,15 +4782,15 @@ DoneSection2: break; // behind back P_SetTarget(&player->mo->tracer, waypoint); + player->powers[pw_carry] = CR_ZOOMTUBE; player->speed = speed; player->pflags |= PF_SPINNING; - player->pflags &= ~PF_JUMPED; - player->pflags &= ~PF_GLIDING; + player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_BOUNCING|PF_SLIDING|PF_CANCARRY); player->climbing = 0; - if (!(player->mo->state >= &states[S_PLAY_ATK1] && player->mo->state <= &states[S_PLAY_ATK4])) + if (player->mo->state-states != S_PLAY_ROLL) { - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); S_StartSound(player->mo, sfx_spin); } } @@ -4072,7 +4806,7 @@ DoneSection2: mobj_t *mo2; angle_t an; - if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT) + if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE) break; // Find line #3 tagged to this sector @@ -4085,8 +4819,14 @@ DoneSection2: } // Grab speed and sequence values - speed = -(abs(lines[lineindex].dx)/8); // Negative means reverse - sequence = abs(lines[lineindex].dy)>>FRACBITS; + speed = -abs(sides[lines[lineindex].sidenum[0]].textureoffset)/8; // Negative means reverse + sequence = abs(sides[lines[lineindex].sidenum[0]].rowoffset)>>FRACBITS; + + if (speed == 0) + { + CONS_Debug(DBG_GAMELOGIC, "ERROR: Waypoint sequence %d at zero speed.\n", sequence); + break; + } // scan the thinkers // to find the last waypoint @@ -4122,13 +4862,15 @@ DoneSection2: break; // behind back P_SetTarget(&player->mo->tracer, waypoint); + player->powers[pw_carry] = CR_ZOOMTUBE; player->speed = speed; player->pflags |= PF_SPINNING; - player->pflags &= ~PF_JUMPED; + player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_BOUNCING|PF_SLIDING|PF_CANCARRY); + player->climbing = 0; - if (!(player->mo->state >= &states[S_PLAY_ATK1] && player->mo->state <= &states[S_PLAY_ATK4])) + if (player->mo->state-states != S_PLAY_ROLL) { - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); S_StartSound(player->mo, sfx_spin); } } @@ -4141,7 +4883,7 @@ DoneSection2: { player->laps++; - if (player->pflags & PF_NIGHTSMODE) + if (player->powers[pw_carry] == CR_NIGHTSMODE) player->drillmeter += 48*20; if (player->laps >= (UINT8)cv_numlaps.value) @@ -4194,7 +4936,7 @@ DoneSection2: vertex_t v1, v2, resulthigh, resultlow; mobj_t *highest = NULL; - if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT) + if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ROPEHANG) break; if (player->mo->momz > 0) @@ -4223,8 +4965,14 @@ DoneSection2: } // Grab speed and sequence values - speed = abs(lines[lineindex].dx)/8; - sequence = abs(lines[lineindex].dy)>>FRACBITS; + speed = abs(sides[lines[lineindex].sidenum[0]].textureoffset)/8; + sequence = abs(sides[lines[lineindex].sidenum[0]].rowoffset)>>FRACBITS; + + if (speed == 0) + { + CONS_Debug(DBG_GAMELOGIC, "ERROR: Waypoint sequence %d at zero speed.\n", sequence); + break; + } // Find the closest waypoint // Find the preceding waypoint @@ -4415,6 +5163,7 @@ DoneSection2: } P_SetTarget(&player->mo->tracer, closest); + player->powers[pw_carry] = CR_ROPEHANG; // Option for static ropes. if (lines[lineindex].flags & ML_NOCLIMB) @@ -4422,16 +5171,12 @@ DoneSection2: else player->speed = speed; - player->pflags |= PF_ROPEHANG; - S_StartSound(player->mo, sfx_s3k4a); - player->pflags &= ~PF_JUMPED; - player->pflags &= ~PF_GLIDING; - player->pflags &= ~PF_SLIDING; + player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_BOUNCING|PF_SLIDING|PF_CANCARRY); player->climbing = 0; P_SetThingPosition(player->mo); - P_SetPlayerMobjState(player->mo, S_PLAY_CARRY); + P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); } break; case 12: // Camera noclip @@ -4716,7 +5461,7 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector) switch(GETSECSPECIAL(sector->special, 4)) { case 2: // Level Exit / GOAL Sector / Flag Return - if (!useNightsSS && G_IsSpecialStage(gamemap)) + if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap)) { // Special stage GOAL sector // requires touching floor. @@ -4853,6 +5598,13 @@ void P_UpdateSpecials(void) } } +/** Gets a 3Dfloor by control sector. + * + * \param sec Target sector. + * \param sec2 Control sector. + * \return Pointer to found 3Dfloor, or NULL. + * \sa P_GetFFloorByID + */ static inline ffloor_t *P_GetFFloorBySec(sector_t *sec, sector_t *sec2) { ffloor_t *rover; @@ -4865,6 +5617,26 @@ static inline ffloor_t *P_GetFFloorBySec(sector_t *sec, sector_t *sec2) return NULL; } +/** Gets a 3Dfloor by ID number. + * + * \param sec Target sector. + * \param id ID of 3Dfloor in target sector. Note that the first FOF's ID is 0. + * \return Pointer to found 3Dfloor, or NULL. + * \sa P_GetFFloorBySec + */ +ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id) +{ + ffloor_t *rover; + UINT16 i = 0; + + if (!sec->ffloors) + return NULL; + for (rover = sec->ffloors; rover; rover = rover->next) + if (i++ == id) + return rover; + return NULL; +} + /** Adds a newly formed 3Dfloor structure to a sector's ffloors list. * * \param sec Target sector. @@ -4988,7 +5760,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f ffloor->spawnflags = ffloor->flags = flags; ffloor->master = master; ffloor->norender = INFTICS; - + ffloor->fadingdata = NULL; // Scan the thinkers to check for special conditions applying to this FOF. // If we have thinkers sorted by sector, just check the relevant ones; @@ -5061,7 +5833,8 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f if ((flags & FF_MARIO)) { - P_AddBlockThinker(sec2, master); + if (!(flags & FF_SHATTERBOTTOM)) // Don't change the textures of a brick block, just a question block + P_AddBlockThinker(sec2, master); CheckForMarioBlocks = true; } @@ -5161,6 +5934,35 @@ static inline void P_AddBridgeThinker(line_t *sourceline, sector_t *sec) } */ +/** + * Adds a plane displacement thinker. + * Whenever the "control" sector moves, + * the "affectee" sector's floor or ceiling plane moves too! + * + * \param speed Rate of movement relative to control sector + * \param control Control sector. + * \param affectee Target sector. + * \param reverse Reverse direction? + * \sa P_SpawnSpecials, T_PlaneDisplace + * \author Monster Iestyn + */ +static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee, UINT8 reverse) +{ + planedisplace_t *displace; + + // create and initialize new displacement thinker + displace = Z_Calloc(sizeof (*displace), PU_LEVSPEC, NULL); + P_AddThinker(&displace->thinker); + + displace->thinker.function.acp1 = (actionf_p1)T_PlaneDisplace; + displace->affectee = affectee; + displace->control = control; + displace->last_height = sectors[control].floorheight; + displace->speed = speed; + displace->type = type; + displace->reverse = reverse; +} + /** Adds a Mario block thinker, which changes the block's texture between blank * and ? depending on whether it has contents. * Needed in case objects respawn inside. @@ -5397,7 +6199,7 @@ static inline void P_AddCameraScanner(sector_t *sourcesec, sector_t *actionsecto elevator->distance = FixedInt(AngleFixed(angle)); } -static const ffloortype_e laserflags = FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA; +static const ffloortype_e laserflags = FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA|FF_TRANSLUCENT; /** Flashes a laser block. * @@ -5417,10 +6219,12 @@ void T_LaserFlash(laserthink_t *flash) if (!ffloor || !(ffloor->flags & FF_EXISTS)) return; - if (leveltime & 1) - ffloor->flags |= FF_RENDERALL; + if (leveltime & 2) + //ffloor->flags |= FF_RENDERALL; + ffloor->alpha = 0xB0; else - ffloor->flags &= ~FF_RENDERALL; + //ffloor->flags &= ~FF_RENDERALL; + ffloor->alpha = 0x90; sourcesec = ffloor->master->frontsector; // Less to type! @@ -5456,9 +6260,9 @@ void T_LaserFlash(laserthink_t *flash) continue; if (thing->flags & MF_SHOOTABLE) - P_DamageMobj(thing, NULL, NULL, 1); + P_DamageMobj(thing, NULL, NULL, 1, 0); else if (thing->type == MT_EGGSHIELD) - P_KillMobj(thing, NULL, NULL); + P_KillMobj(thing, NULL, NULL, 0); } } @@ -5506,6 +6310,69 @@ static void P_RunLevelLoadExecutors(void) } } +/** Before things are loaded, initialises certain stuff in case they're needed + * by P_ResetDynamicSlopes or P_LoadThings. This was split off from + * P_SpawnSpecials, in case you couldn't tell. + * + * \sa P_SpawnSpecials, P_InitTagLists + * \author Monster Iestyn + */ +void P_InitSpecials(void) +{ + // Set the default gravity. Custom gravity overrides this setting. + gravity = FRACUNIT/2; + + // Defaults in case levels don't have them set. + sstimer = 90*TICRATE + 6; + ssspheres = 1; + + CheckForBustableBlocks = CheckForBouncySector = CheckForQuicksand = CheckForMarioBlocks = CheckForFloatBob = CheckForReverseGravity = false; + + // Set curWeather + switch (mapheaderinfo[gamemap-1]->weather) + { + case PRECIP_SNOW: // snow + case PRECIP_RAIN: // rain + case PRECIP_STORM: // storm + case PRECIP_STORM_NORAIN: // storm w/o rain + case PRECIP_STORM_NOSTRIKES: // storm w/o lightning + curWeather = mapheaderinfo[gamemap-1]->weather; + break; + default: // blank/none + curWeather = PRECIP_NONE; + break; + } + + // Set globalweather + globalweather = mapheaderinfo[gamemap-1]->weather; + + P_InitTagLists(); // Create xref tables for tags +} + +static void P_ApplyFlatAlignment(line_t *master, sector_t *sector, angle_t flatangle, fixed_t xoffs, fixed_t yoffs) +{ + if (!(master->flags & ML_NOSONIC)) // Modify floor flat alignment unless NOSONIC flag is set + { + sector->spawn_flrpic_angle = sector->floorpic_angle = flatangle; + sector->floor_xoffs += xoffs; + sector->floor_yoffs += yoffs; + // saved for netgames + sector->spawn_flr_xoffs = sector->floor_xoffs; + sector->spawn_flr_yoffs = sector->floor_yoffs; + } + + if (!(master->flags & ML_NOTAILS)) // Modify ceiling flat alignment unless NOTAILS flag is set + { + sector->spawn_ceilpic_angle = sector->ceilingpic_angle = flatangle; + sector->ceiling_xoffs += xoffs; + sector->ceiling_yoffs += yoffs; + // saved for netgames + sector->spawn_ceil_xoffs = sector->ceiling_xoffs; + sector->spawn_ceil_yoffs = sector->ceiling_yoffs; + } + +} + /** After the map has loaded, scans for specials that spawn 3Dfloors and * thinkers. * @@ -5527,15 +6394,6 @@ void P_SpawnSpecials(INT32 fromnetsave) // but currently isn't. (void)fromnetsave; - // Set the default gravity. Custom gravity overrides this setting. - gravity = FRACUNIT/2; - - // Defaults in case levels don't have them set. - sstimer = 90*TICRATE + 6; - totalrings = 1; - - CheckForBustableBlocks = CheckForBouncySector = CheckForQuicksand = CheckForMarioBlocks = CheckForFloatBob = CheckForReverseGravity = false; - // Init special SECTORs. sector = sectors; for (i = 0; i < numsectors; i++, sector++) @@ -5560,7 +6418,7 @@ void P_SpawnSpecials(INT32 fromnetsave) { case 10: // Time for special stage sstimer = (sector->floorheight>>FRACBITS) * TICRATE + 6; // Time to finish - totalrings = sector->ceilingheight>>FRACBITS; // Ring count for special stage + ssspheres = sector->ceilingheight>>FRACBITS; // Ring count for special stage break; case 11: // Custom global gravity! @@ -5584,20 +6442,6 @@ void P_SpawnSpecials(INT32 fromnetsave) } } - if (mapheaderinfo[gamemap-1]->weather == 2) // snow - curWeather = PRECIP_SNOW; - else if (mapheaderinfo[gamemap-1]->weather == 3) // rain - curWeather = PRECIP_RAIN; - else if (mapheaderinfo[gamemap-1]->weather == 1) // storm - curWeather = PRECIP_STORM; - else if (mapheaderinfo[gamemap-1]->weather == 5) // storm w/o rain - curWeather = PRECIP_STORM_NORAIN; - else if (mapheaderinfo[gamemap-1]->weather == 6) // storm w/o lightning - curWeather = PRECIP_STORM_NOSTRIKES; - else - curWeather = PRECIP_NONE; - - P_InitTagLists(); // Create xref tables for tags P_SearchForDisableLinedefs(); // Disable linedefs are now allowed to disable *any* line P_SpawnScrollers(); // Add generalized scrollers @@ -5648,32 +6492,27 @@ void P_SpawnSpecials(INT32 fromnetsave) // Init line EFFECTs for (i = 0; i < numlines; i++) { - // set line specials to 0 here too, same reason as above - if (netgame || multiplayer) + if (lines[i].special != 7) // This is a hack. I can at least hope nobody wants to prevent flat alignment with arbitrary skin setups... { - // future: nonet flag? - } - else if ((lines[i].flags & ML_NETONLY) == ML_NETONLY) - { - lines[i].special = 0; - continue; - } - else - { - if (players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC)) + // set line specials to 0 here too, same reason as above + if (netgame || multiplayer) { - lines[i].special = 0; - continue; + // future: nonet flag? } - if (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS)) + else if ((lines[i].flags & ML_NETONLY) == ML_NETONLY) { lines[i].special = 0; continue; } - if (players[consoleplayer].charability == CA_GLIDEANDCLIMB && (lines[i].flags & ML_NOKNUX)) + else { - lines[i].special = 0; - continue; + if ((players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC)) + || (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS)) + || (players[consoleplayer].charability == CA_GLIDEANDCLIMB && (lines[i].flags & ML_NOKNUX))) + { + lines[i].special = 0; + continue; + } } } @@ -5719,47 +6558,37 @@ void P_SpawnSpecials(INT32 fromnetsave) break; #endif - case 7: // Flat alignment - if (lines[i].flags & ML_EFFECT4) // Align angle + case 7: // Flat alignment - redone by toast + if ((lines[i].flags & (ML_NOSONIC|ML_NOTAILS)) != (ML_NOSONIC|ML_NOTAILS)) // If you can do something... { - if (!(lines[i].flags & ML_EFFECT5)) // Align floor unless ALLTRIGGER flag is set - { - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) - sectors[s].spawn_flrpic_angle = sectors[s].floorpic_angle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y); - } + angle_t flatangle = InvAngle(R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y)); + fixed_t xoffs; + fixed_t yoffs; - if (!(lines[i].flags & ML_BOUNCY)) // Align ceiling unless BOUNCY flag is set + if (lines[i].flags & ML_NOKNUX) // Set offset through x and y texture offsets if NOKNUX flag is set { - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) - sectors[s].spawn_ceilpic_angle = sectors[s].ceilingpic_angle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y); + xoffs = sides[lines[i].sidenum[0]].textureoffset; + yoffs = sides[lines[i].sidenum[0]].rowoffset; } - } - else // Do offsets - { - if (!(lines[i].flags & ML_BLOCKMONSTERS)) // Align floor unless BLOCKMONSTERS flag is set + else // Otherwise, set calculated offsets such that line's v1 is the apparent origin { - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) - { - sectors[s].floor_xoffs += lines[i].dx; - sectors[s].floor_yoffs += lines[i].dy; - // saved for netgames - sectors[s].spawn_flr_xoffs = sectors[s].floor_xoffs; - sectors[s].spawn_flr_yoffs = sectors[s].floor_yoffs; - } + xoffs = -lines[i].v1->x; + yoffs = lines[i].v1->y; } - if (!(lines[i].flags & ML_NOCLIMB)) // Align ceiling unless NOCLIMB flag is set + //If no tag is given, apply to front sector + if (lines[i].tag == 0) + P_ApplyFlatAlignment(lines + i, lines[i].frontsector, flatangle, xoffs, yoffs); + else { - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) - { - sectors[s].ceiling_xoffs += lines[i].dx; - sectors[s].ceiling_yoffs += lines[i].dy; - // saved for netgames - sectors[s].spawn_ceil_xoffs = sectors[s].ceiling_xoffs; - sectors[s].spawn_ceil_yoffs = sectors[s].ceiling_yoffs; - } + for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0;) + P_ApplyFlatAlignment(lines + i, sectors + s, flatangle, xoffs, yoffs); } } + else // Otherwise, print a helpful warning. Can I do no less? + CONS_Alert(CONS_WARNING, + M_GetText("Flat alignment linedef (tag %d) doesn't have anything to do.\nConsider changing the linedef's flag configuration or removing it entirely.\n"), + lines[i].tag); break; case 8: // Sector Parameters @@ -5874,6 +6703,19 @@ void P_SpawnSpecials(INT32 fromnetsave) P_AddBridgeThinker(&lines[i], §ors[s]);*/ break; + case 66: // Displace floor by front sector + for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + P_AddPlaneDisplaceThinker(pd_floor, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); + break; + case 67: // Displace ceiling by front sector + for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + P_AddPlaneDisplaceThinker(pd_ceiling, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); + break; + case 68: // Displace both floor AND ceiling by front sector + for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + P_AddPlaneDisplaceThinker(pd_both, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); + break; + case 100: // FOF (solid, opaque, shadows) P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); break; @@ -5888,11 +6730,8 @@ void P_SpawnSpecials(INT32 fromnetsave) // Draw the 'insides' of the block too if (lines[i].flags & ML_NOCLIMB) { - ffloorflags |= FF_CUTLEVEL; - ffloorflags |= FF_BOTHPLANES; - ffloorflags |= FF_ALLSIDES; - ffloorflags &= ~FF_EXTRA; - ffloorflags &= ~FF_CUTEXTRA; + ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES; + ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA); } P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); @@ -5999,11 +6838,8 @@ void P_SpawnSpecials(INT32 fromnetsave) // Draw the 'insides' of the block too if (lines[i].flags & ML_EFFECT2) { - ffloorflags |= FF_CUTLEVEL; - ffloorflags |= FF_BOTHPLANES; - ffloorflags |= FF_ALLSIDES; - ffloorflags &= ~FF_EXTRA; - ffloorflags &= ~FF_CUTEXTRA; + ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES; + ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA); } P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); @@ -6017,11 +6853,8 @@ void P_SpawnSpecials(INT32 fromnetsave) // Draw the 'insides' of the block too if (lines[i].flags & ML_EFFECT2) { - ffloorflags |= FF_CUTLEVEL; - ffloorflags |= FF_BOTHPLANES; - ffloorflags |= FF_ALLSIDES; - ffloorflags &= ~FF_EXTRA; - ffloorflags &= ~FF_CUTEXTRA; + ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES; + ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA); } P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); @@ -6045,11 +6878,8 @@ void P_SpawnSpecials(INT32 fromnetsave) // Draw the 'insides' of the block too if (lines[i].flags & ML_EFFECT2) { - ffloorflags |= FF_CUTLEVEL; - ffloorflags |= FF_BOTHPLANES; - ffloorflags |= FF_ALLSIDES; - ffloorflags &= ~FF_EXTRA; - ffloorflags &= ~FF_CUTEXTRA; + ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES; + ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA); } P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); @@ -6063,11 +6893,8 @@ void P_SpawnSpecials(INT32 fromnetsave) // Draw the 'insides' of the block too if (lines[i].flags & ML_EFFECT2) { - ffloorflags |= FF_CUTLEVEL; - ffloorflags |= FF_BOTHPLANES; - ffloorflags |= FF_ALLSIDES; - ffloorflags &= ~FF_EXTRA; - ffloorflags &= ~FF_CUTEXTRA; + ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES; + ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA); } P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); @@ -6245,7 +7072,13 @@ void P_SpawnSpecials(INT32 fromnetsave) break; case 250: // Mario Block - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_MARIO, secthinkers); + ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_MARIO; + if (lines[i].flags & ML_NOCLIMB) + ffloorflags |= FF_SHATTERBOTTOM; + if (lines[i].flags & ML_EFFECT1) + ffloorflags &= ~(FF_SOLID|FF_RENDERALL|FF_CUTLEVEL); + + P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); break; case 251: // A THWOMP! @@ -6259,10 +7092,11 @@ void P_SpawnSpecials(INT32 fromnetsave) break; case 252: // Shatter block (breaks when touched) + ffloorflags = FF_EXISTS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER; if (lines[i].flags & ML_NOCLIMB) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP|FF_SHATTER|FF_SHATTERBOTTOM, secthinkers); - else - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER, secthinkers); + ffloorflags |= FF_SOLID|FF_SHATTERBOTTOM; + + P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); break; case 253: // Translucent shatter block (see 76) @@ -6270,10 +7104,11 @@ void P_SpawnSpecials(INT32 fromnetsave) break; case 254: // Bustable block + ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP; if (lines[i].flags & ML_NOCLIMB) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP|FF_ONLYKNUX, secthinkers); - else - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP, secthinkers); + ffloorflags |= FF_ONLYKNUX; + + P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); break; case 255: // Spin bust block (breaks when jumped or spun downwards onto) @@ -6285,10 +7120,11 @@ void P_SpawnSpecials(INT32 fromnetsave) break; case 257: // Quicksand + ffloorflags = FF_EXISTS|FF_QUICKSAND|FF_RENDERALL|FF_ALLSIDES|FF_CUTSPRITES; if (lines[i].flags & ML_EFFECT5) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_QUICKSAND|FF_RENDERALL|FF_ALLSIDES|FF_CUTSPRITES|FF_RIPPLE, secthinkers); - else - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_QUICKSAND|FF_RENDERALL|FF_ALLSIDES|FF_CUTSPRITES, secthinkers); + ffloorflags |= FF_RIPPLE; + + P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); break; case 258: // Laser block @@ -6405,6 +7241,17 @@ void P_SpawnSpecials(INT32 fromnetsave) } break; + // NiGHTS trigger executors + case 323: + case 324: + case 325: + case 326: + case 327: + case 328: + case 329: + case 330: + break; + case 399: // Linedef execute on map load // This is handled in P_RunLevelLoadExecutors. break; @@ -6518,7 +7365,7 @@ void P_SpawnSpecials(INT32 fromnetsave) case 606: // HACK! Copy colormaps. Just plain colormaps. for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) - sectors[s].midmap = lines[i].frontsector->midmap; + sectors[s].extra_colormap = sectors[s].spawn_extra_colormap = sides[lines[i].sidenum[0]].colormap_data; break; #ifdef ESLOPE // Slope copy specials. Handled here for sanity. @@ -6556,6 +7403,10 @@ void P_SpawnSpecials(INT32 fromnetsave) case 31: // Polyobj_Displace PolyDisplace(&lines[i]); break; + + case 32: // Polyobj_RotDisplace + PolyRotDisplace(&lines[i]); + break; } } #endif @@ -6626,7 +7477,7 @@ static void P_DoScrollMove(mobj_t *thing, fixed_t dx, fixed_t dy, INT32 exclusiv thing->momy += dy; if (exclusive) - thing->flags2 |= MF2_PUSHED; + thing->eflags |= MFE_PUSHED; } /** Processes an active scroller. @@ -6744,7 +7595,7 @@ void T_Scroll(scroll_t *s) { thing = node->m_thing; - if (thing->flags2 & MF2_PUSHED) // Already pushed this tic by an exclusive pusher. + if (thing->eflags & MFE_PUSHED) // Already pushed this tic by an exclusive pusher. continue; height = P_GetSpecialBottomZ(thing, sec, psec); @@ -6766,7 +7617,7 @@ void T_Scroll(scroll_t *s) { thing = node->m_thing; - if (thing->flags2 & MF2_PUSHED) + if (thing->eflags & MFE_PUSHED) continue; height = P_GetSpecialBottomZ(thing, sec, sec); @@ -6820,7 +7671,7 @@ void T_Scroll(scroll_t *s) { thing = node->m_thing; - if (thing->flags2 & MF2_PUSHED) + if (thing->eflags & MFE_PUSHED) continue; height = P_GetSpecialTopZ(thing, sec, psec); @@ -6842,7 +7693,7 @@ void T_Scroll(scroll_t *s) { thing = node->m_thing; - if (thing->flags2 & MF2_PUSHED) + if (thing->eflags & MFE_PUSHED) continue; height = P_GetSpecialTopZ(thing, sec, sec); @@ -6887,31 +7738,6 @@ static void Add_Scroller(INT32 type, fixed_t dx, fixed_t dy, INT32 control, INT3 P_AddThinker(&s->thinker); } -/** Adds a wall scroller. - * Scroll amount is rotated with respect to wall's linedef first, so that - * scrolling towards the wall in a perpendicular direction is translated into - * vertical motion, while scrolling along the wall in a parallel direction is - * translated into horizontal motion. - * - * \param dx x speed of scrolling or its acceleration. - * \param dy y speed of scrolling or its acceleration. - * \param l Line whose front side will scroll. - * \param control Sector whose heights control this scroller's effect - * remotely, or -1 if there is no control sector. - * \param accel Nonzero for an accelerative effect. - * \sa Add_Scroller, P_SpawnScrollers - */ -static void Add_WallScroller(fixed_t dx, fixed_t dy, const line_t *l, INT32 control, INT32 accel) -{ - fixed_t x = abs(l->dx), y = abs(l->dy), d; - if (y > x) - d = x, x = y, y = d; - d = FixedDiv(x, FINESINE((tantoangle[FixedDiv(y, x) >> DBITS] + ANGLE_90) >> ANGLETOFINESHIFT)); - x = -FixedDiv(FixedMul(dy, l->dy) + FixedMul(dx, l->dx), d); - y = -FixedDiv(FixedMul(dx, l->dy) - FixedMul(dy, l->dx), d); - Add_Scroller(sc_side, x, y, control, *l->sidenum, accel, 0); -} - /** Initializes the scrollers. * * \todo Get rid of all the magic numbers. @@ -6996,7 +7822,7 @@ static void P_SpawnScrollers(void) case 502: for (s = -1; (s = P_FindLineFromLineTag(l, s)) >= 0 ;) if (s != (INT32)i) - Add_WallScroller(dx, dy, lines+s, control, accel); + Add_Scroller(sc_side, dx, dy, control, lines[s].sidenum[0], accel, 0); break; case 505: @@ -7105,6 +7931,591 @@ void T_Disappear(disappear_t *d) } } +/** Removes fadingdata from FOF control sector + * + * \param line line to search for target faders + * \param data pointer to set new fadingdata to. Can be NULL to erase. + */ +static void P_ResetFakeFloorFader(ffloor_t *rover, fade_t *data, boolean finalize) +{ + fade_t *fadingdata = (fade_t *)rover->fadingdata; + // find any existing thinkers and remove them, then replace with new data + if (fadingdata != data) + { + if (fadingdata) + { + if (finalize) + P_FadeFakeFloor(rover, + fadingdata->sourcevalue, + fadingdata->alpha >= fadingdata->destvalue ? + fadingdata->alpha - 1 : // trigger fade-out finish + fadingdata->alpha + 1, // trigger fade-in finish + 0, + fadingdata->ticbased, + &fadingdata->timer, + fadingdata->doexists, + fadingdata->dotranslucent, + fadingdata->dolighting, + fadingdata->docolormap, + fadingdata->docollision, + fadingdata->doghostfade, + fadingdata->exactalpha); + rover->alpha = fadingdata->alpha; + + if (fadingdata->dolighting) + P_RemoveLighting(§ors[rover->secnum]); + + if (fadingdata->docolormap) + P_ResetColormapFader(§ors[rover->secnum]); + + P_RemoveThinker(&fadingdata->thinker); + } + + rover->fadingdata = data; + } +} + +static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destvalue, INT16 speed, boolean ticbased, INT32 *timer, + boolean doexists, boolean dotranslucent, boolean dolighting, boolean docolormap, + boolean docollision, boolean doghostfade, boolean exactalpha) +{ + boolean stillfading = false; + INT32 alpha; + fade_t *fadingdata = (fade_t *)rover->fadingdata; + (void)docolormap; // *shrug* maybe we can use this in the future. For now, let's be consistent with our other function params + + 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 (dotranslucent && + (rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE + !(rover->flags & FF_FOG) && // do not include fog + !(rover->spawnflags & FF_RENDERSIDES) && + !(rover->spawnflags & FF_RENDERPLANES) && + !(rover->flags & FF_RENDERALL)) + rover->alpha = 1; + + if (fadingdata) + alpha = fadingdata->alpha; + else + alpha = rover->alpha; + + // routines specific to fade in and fade out + if (!ticbased && alpha == destvalue) + return stillfading; + else if (alpha > destvalue) // fade out + { + // finish fading out + if (speed < 1 || (!ticbased && alpha - speed <= destvalue + speed) || + (ticbased && (--(*timer) <= 0 || alpha <= destvalue))) + { + alpha = destvalue; + + if (docollision) + { + if (rover->spawnflags & FF_SOLID) + rover->flags &= ~FF_SOLID; + if (rover->spawnflags & FF_SWIMMABLE) + rover->flags &= ~FF_SWIMMABLE; + if (rover->spawnflags & FF_QUICKSAND) + rover->flags &= ~FF_QUICKSAND; + if (rover->spawnflags & FF_BUSTUP) + rover->flags &= ~FF_BUSTUP; + if (rover->spawnflags & FF_MARIO) + rover->flags &= ~FF_MARIO; + } + } + else // continue fading out + { + if (!ticbased) + alpha -= speed; + else + { + INT16 delta = abs(destvalue - sourcevalue); + fixed_t factor = min(FixedDiv(speed - (*timer), speed), 1*FRACUNIT); + alpha = max(min(alpha, sourcevalue - (INT16)FixedMul(delta, factor)), destvalue); + } + stillfading = true; + } + } + else // fade in + { + // finish fading in + if (speed < 1 || (!ticbased && alpha + speed >= destvalue - speed) || + (ticbased && (--(*timer) <= 0 || alpha >= destvalue))) + { + alpha = destvalue; + + if (docollision) + { + if (rover->spawnflags & FF_SOLID) + rover->flags |= FF_SOLID; + if (rover->spawnflags & FF_SWIMMABLE) + rover->flags |= FF_SWIMMABLE; + if (rover->spawnflags & FF_QUICKSAND) + rover->flags |= FF_QUICKSAND; + if (rover->spawnflags & FF_BUSTUP) + rover->flags |= FF_BUSTUP; + if (rover->spawnflags & FF_MARIO) + rover->flags |= FF_MARIO; + } + } + else // continue fading in + { + if (!ticbased) + alpha += speed; + else + { + INT16 delta = abs(destvalue - sourcevalue); + fixed_t factor = min(FixedDiv(speed - (*timer), speed), 1*FRACUNIT); + alpha = min(max(alpha, sourcevalue + (INT16)FixedMul(delta, factor)), destvalue); + } + stillfading = true; + } + } + + // routines common to both fade in and fade out + if (!stillfading) + { + if (doexists && !(rover->spawnflags & FF_BUSTUP)) + { + if (alpha <= 1) + rover->flags &= ~FF_EXISTS; + else + rover->flags |= FF_EXISTS; + + // Re-render lighting at end of fade + if (dolighting && !(rover->spawnflags & FF_NOSHADE) && !(rover->flags & FF_EXISTS)) + rover->target->moved = true; + } + + if (dotranslucent && !(rover->flags & FF_FOG)) + { + if (alpha >= 256) + { + if (!(rover->flags & FF_CUTSOLIDS) && + (rover->spawnflags & FF_CUTSOLIDS)) + { + rover->flags |= FF_CUTSOLIDS; + rover->target->moved = true; + } + + rover->flags &= ~FF_TRANSLUCENT; + } + else + { + rover->flags |= FF_TRANSLUCENT; + + if ((rover->flags & FF_CUTSOLIDS) && + (rover->spawnflags & FF_CUTSOLIDS)) + { + rover->flags &= ~FF_CUTSOLIDS; + rover->target->moved = true; + } + } + + if ((rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE + !(rover->spawnflags & FF_RENDERSIDES) && + !(rover->spawnflags & FF_RENDERPLANES)) + { + if (rover->alpha > 1) + rover->flags |= FF_RENDERALL; + else + rover->flags &= ~FF_RENDERALL; + } + } + } + else + { + if (doexists && !(rover->spawnflags & FF_BUSTUP)) + { + // Re-render lighting if we haven't yet set FF_EXISTS (beginning of fade) + if (dolighting && !(rover->spawnflags & FF_NOSHADE) && !(rover->flags & FF_EXISTS)) + rover->target->moved = true; + + rover->flags |= FF_EXISTS; + } + + if (dotranslucent && !(rover->flags & FF_FOG)) + { + rover->flags |= FF_TRANSLUCENT; + + if ((rover->flags & FF_CUTSOLIDS) && + (rover->spawnflags & FF_CUTSOLIDS)) + { + rover->flags &= ~FF_CUTSOLIDS; + rover->target->moved = true; + } + + if ((rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE + !(rover->spawnflags & FF_RENDERSIDES) && + !(rover->spawnflags & FF_RENDERPLANES)) + rover->flags |= FF_RENDERALL; + } + + if (docollision) + { + if (doghostfade) // remove collision flags during fade + { + if (rover->spawnflags & FF_SOLID) + rover->flags &= ~FF_SOLID; + if (rover->spawnflags & FF_SWIMMABLE) + rover->flags &= ~FF_SWIMMABLE; + if (rover->spawnflags & FF_QUICKSAND) + rover->flags &= ~FF_QUICKSAND; + if (rover->spawnflags & FF_BUSTUP) + rover->flags &= ~FF_BUSTUP; + if (rover->spawnflags & FF_MARIO) + rover->flags &= ~FF_MARIO; + } + else // keep collision during fade + { + if (rover->spawnflags & FF_SOLID) + rover->flags |= FF_SOLID; + if (rover->spawnflags & FF_SWIMMABLE) + rover->flags |= FF_SWIMMABLE; + if (rover->spawnflags & FF_QUICKSAND) + rover->flags |= FF_QUICKSAND; + if (rover->spawnflags & FF_BUSTUP) + rover->flags |= FF_BUSTUP; + if (rover->spawnflags & FF_MARIO) + rover->flags |= FF_MARIO; + } + } + } + + if (!(rover->flags & FF_FOG)) // don't set FOG alpha + { + if (!stillfading || exactalpha) + rover->alpha = alpha; + else // clamp fadingdata->alpha to software's alpha levels + { + if (alpha < 12) + rover->alpha = destvalue < 12 ? destvalue : 1; // 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; + else if (alpha < 89) + rover->alpha = destvalue >= 64 && destvalue < 89 ? destvalue : 76; + else if (alpha < 115) + rover->alpha = destvalue >= 89 && destvalue < 115 ? destvalue : 102; + else if (alpha < 140) + rover->alpha = destvalue >= 115 && destvalue < 140 ? destvalue : 128; + else if (alpha < 166) + rover->alpha = destvalue >= 140 && destvalue < 166 ? destvalue : 154; + else if (alpha < 192) + rover->alpha = destvalue >= 166 && destvalue < 192 ? destvalue : 179; + else if (alpha < 217) + rover->alpha = destvalue >= 192 && destvalue < 217 ? destvalue : 204; + else if (alpha < 243) + rover->alpha = destvalue >= 217 && destvalue < 243 ? destvalue : 230; + else // Opaque + rover->alpha = destvalue >= 243 ? destvalue : 256; + } + } + + if (fadingdata) + fadingdata->alpha = alpha; + + return stillfading; +} + +/** Adds fake floor fader thinker. + * + * \param destvalue transparency value to fade to + * \param speed speed to fade by + * \param ticbased tic-based logic, speed = duration + * \param relative Destvalue is relative to rover->alpha + * \param doexists handle FF_EXISTS + * \param dotranslucent handle FF_TRANSLUCENT + * \param dolighting fade FOF light + * \param docollision handle interactive flags + * \param doghostfade no interactive flags during fading + * \param exactalpha use exact alpha values (opengl) + */ +static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloornum, + INT16 destvalue, INT16 speed, boolean ticbased, boolean relative, + boolean doexists, boolean dotranslucent, boolean dolighting, boolean docolormap, + boolean docollision, boolean doghostfade, boolean exactalpha) +{ + fade_t *d; + + // If fading an invisible FOF whose render flags we did not yet set, + // initialize its alpha to 1 + if (dotranslucent && + (rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE + !(rover->spawnflags & FF_RENDERSIDES) && + !(rover->spawnflags & FF_RENDERPLANES) && + !(rover->flags & FF_RENDERALL)) + rover->alpha = 1; + + // already equal, nothing to do + if (rover->alpha == max(1, min(256, relative ? rover->alpha + destvalue : destvalue))) + return; + + d = Z_Malloc(sizeof *d, PU_LEVSPEC, NULL); + + d->thinker.function.acp1 = (actionf_p1)T_Fade; + d->rover = rover; + d->sectornum = (UINT32)sectornum; + d->ffloornum = (UINT32)ffloornum; + + d->alpha = d->sourcevalue = rover->alpha; + d->destvalue = max(1, min(256, relative ? rover->alpha + destvalue : destvalue)); // ffloor->alpha is 1-256 + + if (ticbased) + { + d->ticbased = true; + d->timer = d->speed = abs(speed); // use d->speed as total duration + } + else + { + d->ticbased = false; + d->speed = max(1, speed); // minimum speed 1/tic // if speed < 1, alpha is set immediately in thinker + d->timer = -1; + } + + d->doexists = doexists; + d->dotranslucent = dotranslucent; + d->dolighting = dolighting; + d->docolormap = docolormap; + d->docollision = docollision; + d->doghostfade = doghostfade; + d->exactalpha = exactalpha; + + // find any existing thinkers and remove them, then replace with new data + P_ResetFakeFloorFader(rover, d, false); + + // Set a separate thinker for shadow fading + if (dolighting && !(rover->flags & FF_NOSHADE)) + { + UINT16 lightdelta = abs(sectors[rover->secnum].spawn_lightlevel - rover->target->lightlevel); + fixed_t alphapercent = min(FixedDiv(d->destvalue, rover->spawnalpha), 1*FRACUNIT); // don't make darker than spawn_lightlevel + fixed_t adjustedlightdelta = FixedMul(lightdelta, alphapercent); + + if (rover->target->lightlevel >= sectors[rover->secnum].spawn_lightlevel) // fading out, get lighter + d->destlightlevel = rover->target->lightlevel - adjustedlightdelta; + else // fading in, get darker + d->destlightlevel = rover->target->lightlevel + adjustedlightdelta; + + P_FadeLightBySector(§ors[rover->secnum], + d->destlightlevel, + ticbased ? d->timer : + FixedFloor(FixedDiv(abs(d->destvalue - d->alpha), d->speed))/FRACUNIT, + true); + } + else + d->destlightlevel = -1; + + // Set a separate thinker for colormap fading + if (docolormap && !(rover->flags & FF_NOSHADE) && sectors[rover->secnum].spawn_extra_colormap) + { + extracolormap_t *dest_exc, + *source_exc = sectors[rover->secnum].extra_colormap ? sectors[rover->secnum].extra_colormap : R_GetDefaultColormap(); + + INT32 colordelta = R_GetRgbaA(sectors[rover->secnum].spawn_extra_colormap->rgba); // alpha is from 0 + fixed_t alphapercent = min(FixedDiv(d->destvalue, rover->spawnalpha), 1*FRACUNIT); // don't make darker than spawn_lightlevel + fixed_t adjustedcolordelta = FixedMul(colordelta, alphapercent); + INT32 coloralpha; + + coloralpha = adjustedcolordelta; + + dest_exc = R_CopyColormap(sectors[rover->secnum].spawn_extra_colormap, false); + dest_exc->rgba = R_GetRgbaRGB(dest_exc->rgba) + R_PutRgbaA(coloralpha); + + if (!(d->dest_exc = R_GetColormapFromList(dest_exc))) + { + dest_exc->colormap = R_CreateLightTable(dest_exc); + R_AddColormapToList(dest_exc); + d->dest_exc = dest_exc; + } + else + Z_Free(dest_exc); + + // If fading from 0, set source_exc rgb same to dest_exc + if (!R_CheckDefaultColormap(d->dest_exc, true, false, false) + && R_CheckDefaultColormap(source_exc, true, false, false)) + { + extracolormap_t *exc = R_CopyColormap(source_exc, false); + exc->rgba = R_GetRgbaRGB(d->dest_exc->rgba) + R_PutRgbaA(R_GetRgbaA(source_exc->rgba)); + exc->fadergba = R_GetRgbaRGB(d->dest_exc->rgba) + R_PutRgbaA(R_GetRgbaA(source_exc->fadergba)); + + if (!(source_exc = R_GetColormapFromList(exc))) + { + exc->colormap = R_CreateLightTable(exc); + R_AddColormapToList(exc); + source_exc = exc; + } + else + Z_Free(exc); + } + + Add_ColormapFader(§ors[rover->secnum], source_exc, d->dest_exc, true, + ticbased ? d->timer : + FixedFloor(FixedDiv(abs(d->destvalue - d->alpha), d->speed))/FRACUNIT); + } + + P_AddThinker(&d->thinker); +} + +/** Makes a FOF fade + * + * \param d Fade thinker. + * \sa P_AddFakeFloorFader + */ +void T_Fade(fade_t *d) +{ + if (d->rover && !P_FadeFakeFloor(d->rover, d->sourcevalue, d->destvalue, d->speed, d->ticbased, &d->timer, + d->doexists, d->dotranslucent, d->dolighting, d->docolormap, d->docollision, d->doghostfade, d->exactalpha)) + { + // Finalize lighting, copypasta from P_AddFakeFloorFader + if (d->dolighting && !(d->rover->flags & FF_NOSHADE) && d->destlightlevel > -1) + sectors[d->rover->secnum].lightlevel = d->destlightlevel; + + // Finalize colormap + if (d->docolormap && !(d->rover->flags & FF_NOSHADE) && sectors[d->rover->secnum].spawn_extra_colormap) + sectors[d->rover->secnum].extra_colormap = d->dest_exc; + + P_RemoveFakeFloorFader(d->rover); + } +} + +static void P_ResetColormapFader(sector_t *sector) +{ + if (sector->fadecolormapdata) + { + // The thinker is the first member in all the action structs, + // so just let the thinker get freed, and that will free the whole + // structure. + P_RemoveThinker(&((elevator_t *)sector->fadecolormapdata)->thinker); + sector->fadecolormapdata = NULL; + } +} + +static void Add_ColormapFader(sector_t *sector, extracolormap_t *source_exc, extracolormap_t *dest_exc, + boolean ticbased, INT32 duration) +{ + fadecolormap_t *d; + + P_ResetColormapFader(sector); + + // nothing to do, set immediately + if (!duration || R_CheckEqualColormaps(source_exc, dest_exc, true, true, true)) + { + sector->extra_colormap = dest_exc; + return; + } + + d = Z_Malloc(sizeof *d, PU_LEVSPEC, NULL); + d->thinker.function.acp1 = (actionf_p1)T_FadeColormap; + d->sector = sector; + d->source_exc = source_exc; + d->dest_exc = dest_exc; + + if (ticbased) + { + d->ticbased = true; + d->duration = d->timer = duration; + } + else + { + d->ticbased = false; + d->timer = 256; + d->duration = duration; // use as speed + } + + sector->fadecolormapdata = d; + P_AddThinker(&d->thinker); // add thinker +} + +void T_FadeColormap(fadecolormap_t *d) +{ + if ((d->ticbased && --d->timer <= 0) + || (!d->ticbased && (d->timer -= d->duration) <= 0)) // d->duration used as speed decrement + { + d->sector->extra_colormap = d->dest_exc; + P_ResetColormapFader(d->sector); + } + else + { + extracolormap_t *exc; + INT32 duration = d->ticbased ? d->duration : 256; + fixed_t factor = min(FixedDiv(duration - d->timer, duration), 1*FRACUNIT); + INT16 cr, cg, cb, ca, fadestart, fadeend, fog; + INT32 rgba, fadergba; + + // NULL failsafes (or intentionally set to signify default) + if (!d->sector->extra_colormap) + d->sector->extra_colormap = R_GetDefaultColormap(); + + if (!d->source_exc) + d->source_exc = R_GetDefaultColormap(); + + if (!d->dest_exc) + d->dest_exc = R_GetDefaultColormap(); + + // For each var (rgba + fadergba + params = 11 vars), we apply + // percentage fading: currentval = sourceval + (delta * percent of duration elapsed) + // delta is negative when fading out (destval is lower) + // max/min are used to ensure progressive calcs don't go backwards and to cap values to dest. + +#define APPLYFADE(dest, src, cur) (\ +(dest-src < 0) ? \ + max(\ + min(cur,\ + src + (INT16)FixedMul(dest-src, factor)),\ + dest)\ +: (dest-src > 0) ? \ + min(\ + max(cur,\ + src + (INT16)FixedMul(dest-src, factor)),\ + dest)\ +: \ + dest\ +) + + cr = APPLYFADE(R_GetRgbaR(d->dest_exc->rgba), R_GetRgbaR(d->source_exc->rgba), R_GetRgbaR(d->sector->extra_colormap->rgba)); + cg = APPLYFADE(R_GetRgbaG(d->dest_exc->rgba), R_GetRgbaG(d->source_exc->rgba), R_GetRgbaG(d->sector->extra_colormap->rgba)); + cb = APPLYFADE(R_GetRgbaB(d->dest_exc->rgba), R_GetRgbaB(d->source_exc->rgba), R_GetRgbaB(d->sector->extra_colormap->rgba)); + ca = APPLYFADE(R_GetRgbaA(d->dest_exc->rgba), R_GetRgbaA(d->source_exc->rgba), R_GetRgbaA(d->sector->extra_colormap->rgba)); + + rgba = R_PutRgbaRGBA(cr, cg, cb, ca); + + cr = APPLYFADE(R_GetRgbaR(d->dest_exc->fadergba), R_GetRgbaR(d->source_exc->fadergba), R_GetRgbaR(d->sector->extra_colormap->fadergba)); + cg = APPLYFADE(R_GetRgbaG(d->dest_exc->fadergba), R_GetRgbaG(d->source_exc->fadergba), R_GetRgbaG(d->sector->extra_colormap->fadergba)); + cb = APPLYFADE(R_GetRgbaB(d->dest_exc->fadergba), R_GetRgbaB(d->source_exc->fadergba), R_GetRgbaB(d->sector->extra_colormap->fadergba)); + ca = APPLYFADE(R_GetRgbaA(d->dest_exc->fadergba), R_GetRgbaA(d->source_exc->fadergba), R_GetRgbaA(d->sector->extra_colormap->fadergba)); + + fadergba = R_PutRgbaRGBA(cr, cg, cb, ca); + + fadestart = APPLYFADE(d->dest_exc->fadestart, d->source_exc->fadestart, d->sector->extra_colormap->fadestart); + fadeend = APPLYFADE(d->dest_exc->fadeend, d->source_exc->fadeend, d->sector->extra_colormap->fadeend); + fog = abs(factor) > FRACUNIT/2 ? d->dest_exc->fog : d->source_exc->fog; // set new fog flag halfway through fade + +#undef APPLYFADE + + ////////////////// + // setup new colormap + ////////////////// + + if (!(d->sector->extra_colormap = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, fog))) + { + exc = R_CreateDefaultColormap(false); + exc->fadestart = fadestart; + exc->fadeend = fadeend; + exc->fog = (boolean)fog; + exc->rgba = rgba; + exc->fadergba = fadergba; + exc->colormap = R_CreateLightTable(exc); + R_AddColormapToList(exc); + d->sector->extra_colormap = exc; + } + } +} + /* SoM: 3/8/2000: Friction functions start. Add_Friction, @@ -7115,7 +8526,6 @@ void T_Disappear(disappear_t *d) /** Adds friction thinker. * * \param friction Friction value, 0xe800 is normal. - * \param movefactor Inertia factor. * \param affectee Target sector. * \param roverfriction FOF or not * \sa T_Friction, P_SpawnFriction @@ -7153,22 +8563,10 @@ void T_Friction(friction_t *f) sec = sectors + f->affectee; - // Make sure the sector type hasn't changed + // Get FOF control sector if (f->roverfriction) - { referrer = sectors + f->referrer; - if (!(GETSECSPECIAL(referrer->special, 3) == 1 - || GETSECSPECIAL(referrer->special, 3) == 3)) - return; - } - else - { - if (!(GETSECSPECIAL(sec->special, 3) == 1 - || GETSECSPECIAL(sec->special, 3) == 3)) - return; - } - // Assign the friction value to players on the floor, non-floating, // and clipped. Normally the object's friction value is kept at // ORIG_FRICTION and this thinker changes it for icy or muddy floors. @@ -7198,14 +8596,16 @@ void T_Friction(friction_t *f) || (f->friction < thing->friction)) { thing->friction = f->friction; - thing->movefactor = f->movefactor; + if (thing->player) + thing->movefactor = f->movefactor; } } else if (P_GetSpecialBottomZ(thing, sec, sec) == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction? || f->friction < thing->friction)) { thing->friction = f->friction; - thing->movefactor = f->movefactor; + if (thing->player) + thing->movefactor = f->movefactor; } } node = node->m_thinglist_next; @@ -7221,33 +8621,32 @@ static void P_SpawnFriction(void) size_t i; line_t *l = lines; register INT32 s; - fixed_t length; // line length controls magnitude + fixed_t strength; // frontside texture offset controls magnitude fixed_t friction; // friction value to be applied during movement INT32 movefactor; // applied to each player move to simulate inertia for (i = 0; i < numlines; i++, l++) if (l->special == 540) { - length = P_AproxDistance(l->dx, l->dy)>>FRACBITS; - friction = (0x1EB8*length)/0x80 + 0xD000; + strength = sides[l->sidenum[0]].textureoffset>>FRACBITS; + if (strength > 0) // sludge + strength = strength*2; // otherwise, the maximum sludginess value is +967... + + // The following might seem odd. At the time of movement, + // the move distance is multiplied by 'friction/0x10000', so a + // higher friction value actually means 'less friction'. + friction = ORIG_FRICTION - (0x1EB8*strength)/0x80; // ORIG_FRICTION is 0xE800 if (friction > FRACUNIT) friction = FRACUNIT; if (friction < 0) friction = 0; - // The following check might seem odd. At the time of movement, - // the move distance is multiplied by 'friction/0x10000', so a - // higher friction value actually means 'less friction'. - - if (friction > ORIG_FRICTION) // ice - movefactor = ((0x10092 - friction)*(0x70))/0x158; + movefactor = FixedDiv(ORIG_FRICTION, friction); + if (movefactor < FRACUNIT) + movefactor = 8*movefactor - 7*FRACUNIT; else - movefactor = ((friction - 0xDB34)*(0xA))/0x80; - - // killough 8/28/98: prevent odd situations - if (movefactor < 32) - movefactor = 32; + movefactor = FRACUNIT; for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) Add_Friction(friction, movefactor, s, -1); @@ -7332,14 +8731,14 @@ static pusher_t *tmpusher; // pusher structure for blockmap searches */ static inline boolean PIT_PushThing(mobj_t *thing) { - if (thing->flags2 & MF2_PUSHED) + if (thing->eflags & MFE_PUSHED) return false; - if (thing->player && thing->player->pflags & PF_ROPEHANG) + if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG) return false; // Allow this to affect pushable objects at some point? - if (thing->player && (!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) || thing->player->pflags & PF_NIGHTSMODE)) + if (thing->player && (!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) || thing->player->powers[pw_carry] == CR_NIGHTSMODE)) { INT32 dist; INT32 speed; @@ -7370,7 +8769,7 @@ static inline boolean PIT_PushThing(mobj_t *thing) // Written with bits and pieces of P_HomingAttack if ((speed > 0) && (P_CheckSight(thing, tmpusher->source))) { - if (!(thing->player->pflags & PF_NIGHTSMODE)) + if (thing->player->powers[pw_carry] != CR_NIGHTSMODE) { // only push wrt Z if health & 1 (mapthing has ambush flag) if (tmpusher->source->health & 1) @@ -7462,7 +8861,7 @@ static inline boolean PIT_PushThing(mobj_t *thing) } if (tmpusher->exclusive) - thing->flags2 |= MF2_PUSHED; + thing->eflags |= MFE_PUSHED; return true; } @@ -7497,12 +8896,10 @@ void T_Pusher(pusher_t *p) { referrer = §ors[p->referrer]; - if (!(GETSECSPECIAL(referrer->special, 3) == 2 - || GETSECSPECIAL(referrer->special, 3) == 3)) + if (GETSECSPECIAL(referrer->special, 3) != 2) return; } - else if (!(GETSECSPECIAL(sec->special, 3) == 2 - || GETSECSPECIAL(sec->special, 3) == 3)) + else if (GETSECSPECIAL(sec->special, 3) != 2) return; // For constant pushers (wind/current) there are 3 situations: @@ -7565,10 +8962,10 @@ void T_Pusher(pusher_t *p) || thing->type == MT_BIGTUMBLEWEED)) continue; - if (thing->flags2 & MF2_PUSHED) + if (thing->eflags & MFE_PUSHED) continue; - if (thing->player && thing->player->pflags & PF_ROPEHANG) + if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG) continue; if (thing->player && (thing->state == &states[thing->info->painstate]) && (thing->player->powers[pw_flashing] > (flashingtics/4)*3 && thing->player->powers[pw_flashing] <= flashingtics)) @@ -7701,14 +9098,13 @@ void T_Pusher(pusher_t *p) { if (p->slider && thing->player) { - boolean jumped = (thing->player->pflags & PF_JUMPED); + pflags_t jumped = (thing->player->pflags & (PF_JUMPED|PF_NOJUMPDAMAGE)); P_ResetPlayer (thing->player); if (jumped) - thing->player->pflags |= PF_JUMPED; + thing->player->pflags |= jumped; thing->player->pflags |= PF_SLIDING; - P_SetPlayerMobjState (thing, thing->info->painstate); // Whee! thing->angle = R_PointToAngle2 (0, 0, xspeed<<(FRACBITS-PUSH_FACTOR), yspeed<<(FRACBITS-PUSH_FACTOR)); if (!demoplayback || P_AnalogMove(thing->player)) @@ -7735,7 +9131,7 @@ void T_Pusher(pusher_t *p) } if (p->exclusive) - thing->flags2 |= MF2_PUSHED; + thing->eflags |= MFE_PUSHED; } } } diff --git a/src/p_spec.h b/src/p_spec.h index 17d9c7bd276334d129872b498b5cda5b96e0cf12..d7176afee73e7b4bb3a8356744c6633f60070cdc 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -17,7 +17,9 @@ #ifndef __P_SPEC__ #define __P_SPEC__ -extern mobj_t *skyboxmo[2]; +extern mobj_t *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpoint +extern mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs +extern mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs // GETSECSPECIAL (specialval, section) // @@ -32,6 +34,7 @@ void P_InitPicAnims(void); void P_SetupLevelFlatAnims(void); // at map load +void P_InitSpecials(void); void P_SpawnSpecials(INT32 fromnetsave); // every tic @@ -63,6 +66,12 @@ void P_SwitchWeather(INT32 weathernum); boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller); void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller); void P_ChangeSectorTag(UINT32 sector, INT16 newtag); +void P_RunNightserizeExecutors(mobj_t *actor); +void P_RunDeNightserizeExecutors(mobj_t *actor); +void P_RunNightsLapExecutors(mobj_t *actor); +void P_RunNightsCapsuleTouchExecutors(mobj_t *actor, boolean entering, boolean enoughspheres); + +ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id); // // P_LIGHTS @@ -125,10 +134,15 @@ typedef struct */ typedef struct { - thinker_t thinker; ///< Thinker in use for the effect. - sector_t *sector; ///< Sector where action is taking place. - INT32 destlevel; ///< Light level we're fading to. - INT32 speed; ///< Speed at which to change light level. + thinker_t thinker; ///< Thinker in use for the effect. + sector_t *sector; ///< Sector where action is taking place. + INT16 sourcelevel; ///< Light level we're fading from. + INT16 destlevel; ///< Light level we're fading to. + + fixed_t fixedcurlevel; ///< Fixed point for current light level. + fixed_t fixedpertic; ///< Fixed point for increment per tic. + // The reason for those two above to be fixed point is to deal with decimal values that would otherwise get trimmed away. + INT32 timer; ///< Internal timer. } lightlevel_t; #define GLOWSPEED 8 @@ -136,6 +150,8 @@ typedef struct #define FASTDARK 15 #define SLOWDARK 35 +void P_RemoveLighting(sector_t *sector); + void T_FireFlicker(fireflicker_t *flick); fireflicker_t *P_SpawnAdjustableFireFlicker(sector_t *minsector, sector_t *maxsector, INT32 length); void T_LightningFlash(lightflash_t *flash); @@ -147,7 +163,8 @@ strobe_t * P_SpawnAdjustableStrobeFlash(sector_t *minsector, sector_t *maxsector void T_Glow(glow_t *g); glow_t *P_SpawnAdjustableGlowingLight(sector_t *minsector, sector_t *maxsector, INT32 length); -void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed); +void P_FadeLightBySector(sector_t *sector, INT32 destvalue, INT32 speed, boolean ticbased); +void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased, boolean force); void T_LightFade(lightlevel_t *ll); typedef enum @@ -323,7 +340,7 @@ INT32 EV_StartCrumble(sector_t *sector, ffloor_t *rover, INT32 EV_DoContinuousFall(sector_t *sec, sector_t *pbacksector, fixed_t spd, boolean backwards); -INT32 EV_MarioBlock(sector_t *sector, sector_t *roversector, fixed_t topheight, mobj_t *puncher); +INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher); void T_MoveFloor(floormove_t *movefloor); @@ -386,7 +403,7 @@ typedef struct { thinker_t thinker; ///< Thinker structure for friction. INT32 friction; ///< Friction value, 0xe800 = normal. - INT32 movefactor; ///< Inertia factor when adding to momentum. + INT32 movefactor; ///< Inertia factor when adding to momentum, FRACUNIT = normal. INT32 affectee; ///< Number of affected sector. INT32 referrer; ///< If roverfriction == true, then this will contain the sector # of the control sector where the effect was applied. UINT8 roverfriction; ///< flag for whether friction originated from a FOF or not @@ -444,10 +461,72 @@ typedef struct void T_Disappear(disappear_t *d); +// Model for fading FOFs +typedef struct +{ + thinker_t thinker; ///< Thinker structure for effect. + ffloor_t *rover; ///< Target ffloor + extracolormap_t *dest_exc; ///< Colormap to fade to + UINT32 sectornum; ///< Number of ffloor target sector + UINT32 ffloornum; ///< Number of ffloor of target sector + INT32 alpha; ///< Internal alpha counter + INT16 sourcevalue; ///< Transparency value to fade from + INT16 destvalue; ///< Transparency value to fade to + INT16 destlightlevel; ///< Light level to fade to + INT16 speed; ///< Speed to fade by + boolean ticbased; ///< Tic-based logic toggle + INT32 timer; ///< Timer for tic-based logic + boolean doexists; ///< Handle FF_EXISTS + boolean dotranslucent; ///< Handle FF_TRANSLUCENT + boolean dolighting; ///< Handle shadows and light blocks + boolean docolormap; ///< Handle colormaps + boolean docollision; ///< Handle interactive flags + boolean doghostfade; ///< No interactive flags during fading + boolean exactalpha; ///< Use exact alpha values (opengl) +} fade_t; + +void T_Fade(fade_t *d); + +// Model for fading colormaps + +typedef struct +{ + thinker_t thinker; ///< Thinker structure for effect. + sector_t *sector; ///< Sector where action is taking place. + extracolormap_t *source_exc; + extracolormap_t *dest_exc; + boolean ticbased; ///< Tic-based timing + INT32 duration; ///< Total duration for tic-based logic (OR: speed increment) + INT32 timer; ///< Timer for tic-based logic (OR: internal speed counter) +} fadecolormap_t; + +void T_FadeColormap(fadecolormap_t *d); + // Prototype functions for pushers void T_Pusher(pusher_t *p); mobj_t *P_GetPushThing(UINT32 s); +// Plane displacement +typedef struct +{ + thinker_t thinker; ///< Thinker structure for plane displacement effect. + INT32 affectee; ///< Number of affected sector. + INT32 control; ///< Control sector used to control plane positions. + fixed_t last_height; ///< Last known height of control sector. + fixed_t speed; ///< Plane movement speed. + UINT8 reverse; ///< Move in reverse direction to control sector? + /** Types of plane displacement effects. + */ + enum + { + pd_floor, ///< Displace floor. + pd_ceiling, ///< Displace ceiling. + pd_both, ///< Displace both floor AND ceiling. + } type; +} planedisplace_t; + +void T_PlaneDisplace(planedisplace_t *pd); + void P_CalcHeight(player_t *player); sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo); diff --git a/src/p_telept.c b/src/p_telept.c index 4ca54a8f24315ef9b073520f4247c206bd6d8c37..e80dd04284778301e8210e45349be8d66a2e8a3d 100644 --- a/src/p_telept.c +++ b/src/p_telept.c @@ -125,12 +125,10 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle if (!P_TeleportMove(thing, x, y, z)) return false; - thing->angle = angle; - if (!dontstopmove) thing->momx = thing->momy = thing->momz = 0; else // Change speed to match direction - P_InstaThrust(thing, thing->angle, P_AproxDistance(thing->momx, thing->momy)); + P_InstaThrust(thing, angle, FixedHypot(thing->momx, thing->momy)); if (thing->player) { @@ -139,30 +137,16 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle else thing->player->viewz = thing->z + thing->player->viewheight; - if (!dontstopmove) - thing->reactiontime = TICRATE/2; // don't move for about half a second - - // absolute angle position - if (thing->player == &players[consoleplayer]) - localangle = angle; - if (thing->player == &players[secondarydisplayplayer]) - localangle2 = angle; - - // move chasecam at new player location - if (splitscreen && camera2.chase && thing->player == &players[secondarydisplayplayer]) - P_ResetCamera(thing->player, &camera2); - else if (camera.chase && thing->player == &players[displayplayer]) - P_ResetCamera(thing->player, &camera); - // don't run in place after a teleport if (!dontstopmove) { INT32 p; // Search for any players you might be carrying, so you can get them off before they end up being taken with you! for (p = 0; p < MAXPLAYERS; p++) - if (playeringame[p] && players[p].mo && players[p].pflags & PF_CARRIED && players[p].mo->tracer == thing) + if (playeringame[p] && players[p].mo && players[p].powers[pw_carry] == CR_PLAYER && players[p].mo->tracer == thing) { - players[p].pflags &= ~PF_CARRIED; + players[p].powers[pw_carry] = CR_NONE; + P_SetTarget(&players[p].mo->tracer, NULL); break; } thing->player->cmomx = thing->player->cmomy = 0; @@ -170,11 +154,30 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle thing->player->speed = 0; P_ResetPlayer(thing->player); P_SetPlayerMobjState(thing, S_PLAY_STND); + + thing->reactiontime = TICRATE/2; // don't move for about half a second + thing->player->drawangle = angle; } + else + thing->player->drawangle += (angle - thing->angle); + + // absolute angle position + if (thing->player == &players[consoleplayer]) + localangle = angle; + if (thing->player == &players[secondarydisplayplayer]) + localangle2 = angle; + + // move chasecam at new player location + if (splitscreen && camera2.chase && thing->player == &players[secondarydisplayplayer]) + P_ResetCamera(thing->player, &camera2); + else if (camera.chase && thing->player == &players[displayplayer]) + P_ResetCamera(thing->player, &camera); if (flash) P_FlashPal(thing->player, PAL_MIXUP, 10); } + thing->angle = angle; + return true; } diff --git a/src/p_tick.c b/src/p_tick.c index 75844b55e2336af5f294939ab2212fb2b23cb235..6f7c96ead28bf5a7ca1061345959ba46d874ddd3 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -359,7 +359,7 @@ static void P_DoAutobalanceTeams(void) totalred = red + redflagcarrier; totalblue = blue + blueflagcarrier; - if ((abs(totalred - totalblue) > cv_autobalance.value)) + if ((abs(totalred - totalblue) > max(1, (totalred + totalblue) / 8))) { if (totalred > totalblue) { @@ -372,8 +372,7 @@ static void P_DoAutobalanceTeams(void) usvalue = SHORT(NetPacket.value.l|NetPacket.value.b); SendNetXCmd(XD_TEAMCHANGE, &usvalue, sizeof(usvalue)); } - - if (totalblue > totalred) + else //if (totalblue > totalred) { i = M_RandomKey(blue); NetPacket.packet.newteam = 1; @@ -425,7 +424,7 @@ void P_DoTeamscrambling(void) static inline void P_DoSpecialStageStuff(void) { - boolean inwater = false; + boolean stillalive = false; INT32 i; // Can't drown in a special stage @@ -437,68 +436,60 @@ static inline void P_DoSpecialStageStuff(void) players[i].powers[pw_underwater] = players[i].powers[pw_spacetime] = 0; } - if (sstimer < 15*TICRATE+6 && sstimer > 7 && (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC)) - S_SpeedMusic(1.4f); + //if (sstimer < 15*TICRATE+6 && sstimer > 7 && (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC)) + //S_SpeedMusic(1.4f); - if (sstimer < 7 && sstimer > 0) // The special stage time is up! + if (sstimer && !objectplacing) { - sstimer = 0; - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i]) - { - players[i].exiting = (14*TICRATE)/5 + 1; - players[i].pflags &= ~PF_GLIDING; - } - - if (i == consoleplayer) - S_StartSound(NULL, sfx_lose); - } - - if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC) - S_SpeedMusic(1.0f); - - stagefailed = true; - } - - if (sstimer > 1) // As long as time isn't up... - { - UINT32 ssrings = 0; + UINT16 countspheres = 0; // Count up the rings of all the players and see if // they've collected the required amount. for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i]) { - ssrings += (players[i].mo->health-1); + tic_t oldnightstime = players[i].nightstime; + countspheres += players[i].spheres; // If in water, deplete timer 6x as fast. - if ((players[i].mo->eflags & MFE_TOUCHWATER) - || (players[i].mo->eflags & MFE_UNDERWATER)) - inwater = true; - } - - if (ssrings >= totalrings && totalrings > 0) - { - // Halt all the players - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i]) + if (players[i].mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) + players[i].nightstime -= 5; + if (--players[i].nightstime > 6) + { + if (P_IsLocalPlayer(&players[i]) && oldnightstime > 10*TICRATE && players[i].nightstime <= 10*TICRATE) + S_ChangeMusicInternal("_drown", false); + stillalive = true; + } + else if (!players[i].exiting) { - players[i].mo->momx = players[i].mo->momy = 0; players[i].exiting = (14*TICRATE)/5 + 1; + players[i].pflags &= ~(PF_GLIDING|PF_BOUNCING); + players[i].nightstime = 0; + if (P_IsLocalPlayer(&players[i])) + S_StartSound(NULL, sfx_s3k66); } + } - sstimer = 0; - - P_GiveEmerald(true); + if (stillalive) + { + if (countspheres >= ssspheres) + { + // Halt all the players + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i]) + { + players[i].mo->momx = players[i].mo->momy = 0; + players[i].exiting = (14*TICRATE)/5 + 1; + } + + sstimer = 0; + P_GiveEmerald(true); + P_RestoreMusic(&players[consoleplayer]); + } } - - // Decrement the timer - if (!objectplacing) + else { - if (inwater) - sstimer -= 6; - else - sstimer--; + sstimer = 0; + stagefailed = true; } } } @@ -534,7 +525,7 @@ static inline void P_DoTagStuff(void) for (i=0; i < MAXPLAYERS; i++) { if (playeringame[i] && !players[i].spectator && players[i].playerstate == PST_LIVE - && !(players[i].pflags & (PF_TAGIT|PF_TAGGED))) + && !(players[i].pflags & (PF_TAGIT|PF_GAMETYPEOVER))) //points given is the number of participating players divided by two. P_AddPlayerScore(&players[i], participants/2); } @@ -610,7 +601,7 @@ void P_Ticker(boolean run) if (!demoplayback) // Don't increment if a demo is playing. totalplaytime++; - if (!useNightsSS && G_IsSpecialStage(gamemap)) + if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap)) P_DoSpecialStageStuff(); if (runemeraldmanager) @@ -652,7 +643,7 @@ void P_Ticker(boolean run) if (run) { - if (countdowntimer && --countdowntimer <= 0) + if (countdowntimer && G_PlatformGametype() && (gametype == GT_COOP || leveltime >= 4*TICRATE) && --countdowntimer <= 0) { countdowntimer = 0; countdowntimeup = true; @@ -664,7 +655,9 @@ void P_Ticker(boolean run) if (!players[i].mo) continue; - P_DamageMobj(players[i].mo, NULL, NULL, 10000); + if (multiplayer || netgame) + players[i].exiting = 0; + P_DamageMobj(players[i].mo, NULL, NULL, 1, DMG_INSTAKILL); } } diff --git a/src/p_user.c b/src/p_user.c index 03e1e4e23605efd0a04d7d430765fc5b6443b5b8..ce2d90455433b557ee309f1feda4ee163596543f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -165,7 +165,7 @@ fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move) boolean P_AutoPause(void) { // Don't pause even on menu-up or focus-lost in netgames or record attack - if (netgame || modeattacking) + if (netgame || modeattacking || gamestate == GS_TITLESCREEN) return false; return (menuactive || window_notinfocus); @@ -188,11 +188,12 @@ void P_CalcHeight(player_t *player) // Note: a LUT allows for effects // like a ramp with low health. - player->bob = (FixedMul(player->rmomx,player->rmomx) - + FixedMul(player->rmomy,player->rmomy))>>2; + player->bob = FixedMul(cv_movebob.value, + (FixedMul(player->rmomx,player->rmomx) + + FixedMul(player->rmomy,player->rmomy))>>2); - if (player->bob > FixedMul(MAXBOB, mo->scale)) - player->bob = FixedMul(MAXBOB, mo->scale); + if (player->bob > FixedMul(cv_movebob.value, FixedMul(MAXBOB, mo->scale))) + player->bob = FixedMul(cv_movebob.value, FixedMul(MAXBOB, mo->scale)); if (!P_IsObjectOnGround(mo)) { @@ -215,7 +216,7 @@ void P_CalcHeight(player_t *player) bob = FixedMul(player->bob/2, FINESINE(angle)); // move viewheight - pviewheight = FixedMul(cv_viewheight.value << FRACBITS, mo->scale); // default eye view height + pviewheight = FixedMul(41*player->height/48, mo->scale); // default eye view height if (player->playerstate == PST_LIVE) { @@ -282,22 +283,11 @@ boolean P_PlayerMoving(INT32 pnum) // UINT8 P_GetNextEmerald(void) { - if (!useNightsSS) // In order - { - if (!(emeralds & EMERALD1)) return 0; - if (!(emeralds & EMERALD2)) return 1; - if (!(emeralds & EMERALD3)) return 2; - if (!(emeralds & EMERALD4)) return 3; - if (!(emeralds & EMERALD5)) return 4; - if (!(emeralds & EMERALD6)) return 5; - return 6; - } - else // Depends on stage - { - if (gamemap < sstage_start || gamemap > sstage_end) - return 0; + if (gamemap >= sstage_start && gamemap <= sstage_end) return (UINT8)(gamemap - sstage_start); - } + if (gamemap >= smpstage_start || gamemap <= smpstage_end) + return (UINT8)(gamemap - smpstage_start); + return 0; } // @@ -308,23 +298,23 @@ UINT8 P_GetNextEmerald(void) // void P_GiveEmerald(boolean spawnObj) { - INT32 i; - UINT8 em; + UINT8 em = P_GetNextEmerald(); S_StartSound(NULL, sfx_cgot); // Got the emerald! - em = P_GetNextEmerald(); emeralds |= (1 << em); - if (spawnObj) + if (spawnObj && playeringame[consoleplayer]) { - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i]) - P_SetMobjState(P_SpawnMobj(players[i].mo->x, players[i].mo->y, players[i].mo->z + players[i].mo->info->height, MT_GOTEMERALD), - mobjinfo[MT_GOTEMERALD].spawnstate + em); - + // The Chaos Emerald begins to orbit us! + // Only give it to ONE person! + mobj_t *emmo = P_SpawnMobjFromMobj(players[consoleplayer].mo, 0, 0, players[consoleplayer].mo->height, MT_GOTEMERALD); + P_SetTarget(&emmo->target, players[consoleplayer].mo); + P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); + P_SetTarget(&players[consoleplayer].mo->tracer, emmo); } } +#if 0 // // P_ResetScore // @@ -335,6 +325,7 @@ void P_ResetScore(player_t *player) player->scoreadd = 0; } +#endif // // P_FindLowestMare @@ -396,6 +387,8 @@ boolean P_TransferToNextMare(player_t *player) CONS_Debug(DBG_NIGHTS, "Mare is %d\n", mare); player->mare = mare; + player->marelap = 0; + player->marebonuslap = 0; // scan the thinkers // to find the closest axis point @@ -574,25 +567,28 @@ static void P_DeNightserizePlayer(player_t *player) thinker_t *th; mobj_t *mo2; - player->pflags &= ~PF_NIGHTSMODE; - - //if (player->mo->tracer) - //P_RemoveMobj(player->mo->tracer); + player->powers[pw_carry] = CR_NIGHTSFALL; player->powers[pw_underwater] = 0; - player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST); + player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST); player->secondjump = 0; - player->jumping = 0; player->homing = 0; player->climbing = 0; player->mo->fuse = 0; player->speed = 0; + player->marelap = 0; + player->marebonuslap = 0; + player->flyangle = 0; + player->anotherflyangle = 0; P_SetTarget(&player->mo->target, NULL); P_SetTarget(&player->axis1, P_SetTarget(&player->axis2, NULL)); player->mo->flags &= ~MF_NOGRAVITY; - player->mo->flags2 &= ~MF2_DONTDRAW; + player->mo->skin = &skins[player->skin]; + player->followitem = skins[player->skin].followitem; + player->mo->color = player->skincolor; + G_GhostAddColor(GHC_NORMAL); // Restore aiming angle if (player == &players[consoleplayer]) @@ -600,23 +596,22 @@ static void P_DeNightserizePlayer(player_t *player) else if (player == &players[secondarydisplayplayer]) localaiming2 = 0; - // If you screwed up, kiss your score goodbye. - player->marescore = 0; - - if (player->mo->tracer) - P_RemoveMobj(player->mo->tracer); - P_SetPlayerMobjState(player->mo, S_PLAY_FALL1); - player->pflags |= PF_NIGHTSFALL; + P_SetPlayerMobjState(player->mo, S_PLAY_FALL); // If in a special stage, add some preliminary exit time. if (G_IsSpecialStage(gamemap)) { INT32 i; for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE) + if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE) players[i].nightstime = 1; // force everyone else to fall too. player->exiting = 3*TICRATE; stagefailed = true; // NIGHT OVER + + // If you screwed up, kiss your score and ring bonus goodbye. + // But only do this in special stage (and instakill!) In regular stages, wait til we hit the ground. + player->marescore = player->spheres =\ + player->rings = 0; } // Check to see if the player should be killed. @@ -629,54 +624,105 @@ static void P_DeNightserizePlayer(player_t *player) if (!(mo2->type == MT_NIGHTSDRONE)) continue; - if (mo2->flags & MF_AMBUSH) - P_DamageMobj(player->mo, NULL, NULL, 10000); + if (mo2->flags2 & MF2_AMBUSH) + { + player->marescore = player->spheres =\ + player->rings = 0; + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL); + + // Reset music to beginning if MIXNIGHTSCOUNTDOWN + if ((mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN) +#ifdef _WIN32 + && S_MusicType() != MU_MID +#endif + ) + S_SetMusicPosition(0); + } break; } + if (player->mo->scale != player->oldscale) + player->mo->destscale = player->oldscale; + player->oldscale = 0; + // Restore from drowning music - P_RestoreMusic(player); + if ((mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN) +#ifdef _WIN32 + && S_MusicType() != MU_MID +#endif + ) + { + S_StopSoundByNum(sfx_timeup); + S_StopFadingMusic(); + S_SetInternalMusicVolume(100); + + // Reset the music if you did not destroy all the capsules, because you failed. + // Why make the all-capsules exception: because it's your reward for nearly finishing the level! + // (unless the player auto-loses upon denightserizing; for death case, see above.) + if (P_FindLowestMare() != UINT8_MAX || G_IsSpecialStage(gamemap)) + S_SetMusicPosition(0); + } + else + P_RestoreMusic(player); + + P_RunDeNightserizeExecutors(player->mo); } + // // P_NightserizePlayer // // NiGHTS Time! void P_NightserizePlayer(player_t *player, INT32 nighttime) { - INT32 oldmare; + UINT8 oldmare, oldmarelap, oldmarebonuslap; - // Bots can't be super, silly!1 :P + // Bots can't be NiGHTSerized, silly!1 :P if (player->bot) return; - if (!(player->pflags & PF_NIGHTSMODE)) + if (player->powers[pw_carry] != CR_NIGHTSMODE) { - P_SetTarget(&player->mo->tracer, P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_NIGHTSCHAR)); - player->mo->tracer->destscale = player->mo->scale; - P_SetScale(player->mo->tracer, player->mo->scale); - player->mo->tracer->eflags = (player->mo->tracer->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); - player->mo->height = player->mo->tracer->height; + player->mo->height = P_GetPlayerHeight(player); // Just to make sure jumping into the drone doesn't result in a squashed hitbox. + player->oldscale = player->mo->scale; } - player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_THOKKED|PF_SPINNING|PF_DRILLING); + player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SHIELDABILITY|PF_SPINNING|PF_DRILLING); player->homing = 0; player->mo->fuse = 0; player->speed = 0; player->climbing = 0; player->secondjump = 0; + player->flyangle = 0; + player->anotherflyangle = 0; player->powers[pw_shield] = SH_NONE; + player->powers[pw_super] = 0; player->mo->flags |= MF_NOGRAVITY; - player->mo->flags2 |= MF2_DONTDRAW; + if (skins[player->skin].sprites[SPR2_NGT0].numframes == 0) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin. + { + player->mo->skin = &skins[DEFAULTNIGHTSSKIN]; + if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback)) + player->mo->color = skins[DEFAULTNIGHTSSKIN].prefcolor; + player->followitem = skins[DEFAULTNIGHTSSKIN].followitem; + } - player->nightstime = player->startedtime = nighttime*TICRATE; + player->nightstime = player->startedtime = player->lapstartedtime = nighttime*TICRATE; player->bonustime = false; - P_RestoreMusic(player); - P_SetMobjState(player->mo->tracer, S_SUPERTRANS1); + // Restore from drowning music + if (mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN) + { + S_StopSoundByNum(sfx_timeup); + S_StopFadingMusic(); + S_SetInternalMusicVolume(100); + } + else + P_RestoreMusic(player); + + P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_TRANS1); if (gametype == GT_RACE || gametype == GT_COMPETITION) { @@ -690,10 +736,13 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) } oldmare = player->mare; + oldmarelap = player->marelap; + oldmarebonuslap = player->marebonuslap; - if (P_TransferToNextMare(player) == false) + if (!P_TransferToNextMare(player)) { INT32 i; + INT32 total_spheres = 0; INT32 total_rings = 0; P_SetTarget(&player->mo->target, NULL); @@ -701,8 +750,11 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) if (G_IsSpecialStage(gamemap)) { for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i]/* && players[i].pflags & PF_NIGHTSMODE*/) - total_rings += players[i].health-1; + if (playeringame[i]/* && players[i].powers[pw_carry] == CR_NIGHTSMODE*/) + { + total_spheres += players[i].spheres; + total_rings += players[i].rings; + } } for (i = 0; i < MAXPLAYERS; i++) @@ -713,15 +765,19 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) players[i].texttimer = (3 * TICRATE) - 10; players[i].textvar = 4; // Score and grades players[i].lastmare = players[i].mare; + players[i].lastmarelap = players[i].marelap; + players[i].lastmarebonuslap = players[i].marebonuslap; if (G_IsSpecialStage(gamemap)) { + players[i].finishedspheres = (INT16)total_spheres; players[i].finishedrings = (INT16)total_rings; - P_AddPlayerScore(player, total_rings * 50); + P_AddPlayerScore(player, total_spheres * 50); } else { - players[i].finishedrings = (INT16)(players[i].health - 1); - P_AddPlayerScore(&players[i], (players[i].health - 1) * 50); + players[i].finishedspheres = (INT16)(players[i].spheres); + players[i].finishedrings = (INT16)(players[i].rings); + P_AddPlayerScore(&players[i], (players[i].spheres) * 50); } // Add score to leaderboards now @@ -729,34 +785,40 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) G_AddTempNightsRecords(players[i].marescore, leveltime - player->marebegunat, players[i].mare + 1); // transfer scores anyway + players[i].totalmarescore += players[i].marescore; players[i].lastmarescore = players[i].marescore; players[i].marescore = 0; - players[i].mo->health = players[i].health = 1; + players[i].spheres = players[i].rings = 0; P_DoPlayerExit(&players[i]); } } else if (oldmare != player->mare) { /// \todo Handle multi-mare special stages. - // Ring bonus - P_AddPlayerScore(player, (player->health - 1) * 50); + // Spheres bonus + P_AddPlayerScore(player, (player->spheres) * 50); - player->lastmare = (UINT8)oldmare; + player->lastmare = oldmare; + player->lastmarelap = oldmarelap; + player->lastmarebonuslap = oldmarebonuslap; player->texttimer = 4*TICRATE; player->textvar = 4; // Score and grades - player->finishedrings = (INT16)(player->health - 1); + player->finishedspheres = (INT16)(player->spheres); + player->finishedrings = (INT16)(player->rings); // Add score to temp leaderboards if (!(netgame||multiplayer) && P_IsLocalPlayer(player)) G_AddTempNightsRecords(player->marescore, leveltime - player->marebegunat, (UINT8)(oldmare + 1)); // Starting a new mare, transfer scores + player->totalmarescore += player->marescore; player->lastmarescore = player->marescore; player->marescore = 0; player->marebegunat = leveltime; + player->lapbegunat = leveltime; - player->mo->health = player->health = 1; + player->spheres = player->rings = 0; } else { @@ -765,11 +827,31 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) // Don't show before title card // Not consistency safe, but this only affects drawing - if (timeinmap + 40 < 110) - player->texttimer = (UINT8)(110 - timeinmap); + if (timeinmap + 40 < (110 - 70)) + player->texttimer = (UINT8)((110 - 70) - timeinmap); } - player->pflags |= PF_NIGHTSMODE; + if (player->drone && player->drone->scale != player->mo->scale) + player->mo->destscale = player->drone->scale; + + // force NiGHTS to face forward or backward + if (player->mo->target) + player->mo->angle = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y) // player->angle_pos, won't be set on first instance + + ((player->mo->target->flags2 & MF2_AMBUSH) ? // if axis is invert, take the opposite right angle + (player->flyangle > 90 && player->flyangle < 270 ? ANGLE_90 : -ANGLE_90) + : (player->flyangle > 90 && player->flyangle < 270 ? -ANGLE_90 : ANGLE_90)); + + // Do this before setting CR_NIGHTSMODE so we can tell if player was non-NiGHTS + P_RunNightserizeExecutors(player->mo); + + player->powers[pw_carry] = CR_NIGHTSMODE; +} + +pflags_t P_GetJumpFlags(player_t *player) +{ + if (player->charflags & SF_NOJUMPDAMAGE) + return (PF_JUMPED|PF_NOJUMPDAMAGE); + return PF_JUMPED; } // @@ -795,62 +877,71 @@ boolean P_PlayerInPain(player_t *player) // void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) { - angle_t ang; - fixed_t fallbackspeed; + if (player->powers[pw_carry] == CR_ROPEHANG) + P_SetTarget(&player->mo->tracer, NULL); - if (player->mo->eflags & MFE_VERTICALFLIP) - player->mo->z--; - else - player->mo->z++; + { + angle_t ang; + fixed_t fallbackspeed; - if (player->mo->eflags & MFE_UNDERWATER) - P_SetObjectMomZ(player->mo, FixedDiv(10511*FRACUNIT,2600*FRACUNIT), false); - else - P_SetObjectMomZ(player->mo, FixedDiv(69*FRACUNIT,10*FRACUNIT), false); + P_ResetPlayer(player); + P_SetPlayerMobjState(player->mo, player->mo->info->painstate); - if (inflictor) - { - ang = R_PointToAngle2(inflictor->x-inflictor->momx, inflictor->y - inflictor->momy, player->mo->x - player->mo->momx, player->mo->y - player->mo->momy); + if (player->mo->eflags & MFE_VERTICALFLIP) + player->mo->z--; + else + player->mo->z++; + + if (player->mo->eflags & MFE_UNDERWATER) + P_SetObjectMomZ(player->mo, FixedDiv(10511*FRACUNIT,2600*FRACUNIT), false); + else + P_SetObjectMomZ(player->mo, FixedDiv(69*FRACUNIT,10*FRACUNIT), false); - // explosion and rail rings send you farther back, making it more difficult - // to recover - if ((inflictor->flags2 & MF2_SCATTER) && source) + if (inflictor) { - fixed_t dist = P_AproxDistance(P_AproxDistance(source->x-player->mo->x, source->y-player->mo->y), source->z-player->mo->z); + if (inflictor->type == MT_WALLSPIKE) + ang = inflictor->angle; + else + ang = R_PointToAngle2(inflictor->x-inflictor->momx, inflictor->y - inflictor->momy, player->mo->x - player->mo->momx, player->mo->y - player->mo->momy); - dist = FixedMul(128*FRACUNIT, inflictor->scale) - dist/4; + // explosion and rail rings send you farther back, making it more difficult + // to recover + if ((inflictor->flags2 & MF2_SCATTER) && source) + { + fixed_t dist = P_AproxDistance(P_AproxDistance(source->x-player->mo->x, source->y-player->mo->y), source->z-player->mo->z); - if (dist < FixedMul(4*FRACUNIT, inflictor->scale)) - dist = FixedMul(4*FRACUNIT, inflictor->scale); + dist = FixedMul(128*FRACUNIT, inflictor->scale) - dist/4; - fallbackspeed = dist; - } - else if (inflictor->flags2 & MF2_EXPLOSION) - { - if (inflictor->flags2 & MF2_RAILRING) - fallbackspeed = FixedMul(38*FRACUNIT, inflictor->scale); // 7x + if (dist < FixedMul(4*FRACUNIT, inflictor->scale)) + dist = FixedMul(4*FRACUNIT, inflictor->scale); + + fallbackspeed = dist; + } + else if (inflictor->flags2 & MF2_EXPLOSION) + { + if (inflictor->flags2 & MF2_RAILRING) + fallbackspeed = FixedMul(38*FRACUNIT, inflictor->scale); // 7x + else + fallbackspeed = FixedMul(30*FRACUNIT, inflictor->scale); // 5x + } + else if (inflictor->flags2 & MF2_RAILRING) + fallbackspeed = FixedMul(45*FRACUNIT, inflictor->scale); // 4x else - fallbackspeed = FixedMul(30*FRACUNIT, inflictor->scale); // 5x + fallbackspeed = FixedMul(4*FRACUNIT, inflictor->scale); // the usual amount of force } - else if (inflictor->flags2 & MF2_RAILRING) - fallbackspeed = FixedMul(45*FRACUNIT, inflictor->scale); // 4x else - fallbackspeed = FixedMul(4*FRACUNIT, inflictor->scale); // the usual amount of force - } - else - { - ang = R_PointToAngle2(player->mo->momx, player->mo->momy, 0, 0); - fallbackspeed = FixedMul(4*FRACUNIT, player->mo->scale); - } - - P_InstaThrust(player->mo, ang, fallbackspeed); + { + ang = ((player->mo->momx || player->mo->momy) ? R_PointToAngle2(player->mo->momx, player->mo->momy, 0, 0) : player->drawangle); + fallbackspeed = FixedMul(4*FRACUNIT, player->mo->scale); + } - if (player->pflags & PF_ROPEHANG) - P_SetTarget(&player->mo->tracer, NULL); + player->drawangle = ang + ANGLE_180; + P_InstaThrust(player->mo, ang, fallbackspeed); + } // Point penalty for hitting a hazard during tag. // Discourages players from intentionally hurting themselves to avoid being tagged. - if (gametype == GT_TAG && (!(player->pflags & PF_TAGGED) && !(player->pflags & PF_TAGIT))) + if (gametype == GT_TAG && (!(player->pflags & PF_GAMETYPEOVER) && !(player->pflags & PF_TAGIT))) { if (player->score >= 50) player->score -= 50; @@ -858,8 +949,6 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) player->score = 0; } - P_ResetPlayer(player); - P_SetPlayerMobjState(player->mo, player->mo->info->painstate); player->powers[pw_flashing] = flashingtics; if (player->timeshit != UINT8_MAX) @@ -872,8 +961,11 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) // Useful when you want to kill everything the player is doing. void P_ResetPlayer(player_t *player) { - player->pflags &= ~(PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN|PF_SPINNING|PF_JUMPED|PF_GLIDING|PF_THOKKED|PF_CARRIED); - player->jumping = 0; + player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_THOKKED|PF_CANCARRY|PF_SHIELDABILITY|PF_BOUNCING); + + if (!(player->powers[pw_carry] == CR_NIGHTSMODE || player->powers[pw_carry] == CR_NIGHTSFALL || player->powers[pw_carry] == CR_BRAKGOOP || player->powers[pw_carry] == CR_MINECART)) + player->powers[pw_carry] = CR_NONE; + player->secondjump = 0; player->glidetime = 0; player->homing = 0; @@ -891,38 +983,34 @@ void P_ResetPlayer(player_t *player) // Gives rings to the player, and does any special things required. // Call this function when you want to increment the player's health. // + void P_GivePlayerRings(player_t *player, INT32 num_rings) { + if (!player) + return; + if (player->bot) player = &players[consoleplayer]; if (!player->mo) return; - player->mo->health += num_rings; - player->health += num_rings; + player->rings += num_rings; - if (!G_IsSpecialStage(gamemap) || !useNightsSS) - player->totalring += num_rings; + player->totalring += num_rings; // Can only get up to 9999 rings, sorry! - if (player->mo->health > 10000) - { - player->mo->health = 10000; - player->health = 10000; - } - else if (player->mo->health < 1) - { - player->mo->health = 1; - player->health = 1; - } + if (player->rings > 9999) + player->rings = 9999; + else if (player->rings < 0) + player->rings = 0; // Now extra life bonuses are handled here instead of in P_MovePlayer, since why not? - if (!ultimatemode && !modeattacking && !G_IsSpecialStage(gamemap) && G_GametypeUsesLives()) + if (!ultimatemode && !modeattacking && !G_IsSpecialStage(gamemap) && G_GametypeUsesLives() && player->lives != INFLIVES) { INT32 gainlives = 0; - while (player->xtralife < maxXtraLife && player->health > 100 * (player->xtralife+1)) + while (player->xtralife < maxXtraLife && player->rings >= 100 * (player->xtralife+1)) { ++gainlives; ++player->xtralife; @@ -930,12 +1018,37 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) if (gainlives) { - P_GivePlayerLives(player, gainlives); + player->lives += gainlives; + if (player->lives > 99) + player->lives = 99; + else if (player->lives < 1) + player->lives = 1; + P_PlayLivesJingle(player); } } } +void P_GivePlayerSpheres(player_t *player, INT32 num_spheres) +{ + if (!player) + return; + + if (player->bot) + player = &players[consoleplayer]; + + if (!player->mo) + return; + + player->spheres += num_spheres; + + // Can only get up to 9999 spheres, sorry! + if (player->spheres > 9999) + player->spheres = 9999; + else if (player->spheres < 0) + player->spheres = 0; +} + // // P_GivePlayerLives // @@ -944,6 +1057,31 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) // void P_GivePlayerLives(player_t *player, INT32 numlives) { + if (!player) + return; + + if (player->bot) + player = &players[consoleplayer]; + + if (gamestate == GS_LEVEL) + { + if (player->lives == INFLIVES || (gametype != GT_COOP && gametype != GT_COMPETITION)) + { + P_GivePlayerRings(player, 100*numlives); + return; + } + + if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) + { + UINT8 prevlives = player->lives; + P_GivePlayerRings(player, 100*numlives); + if (player->lives - prevlives >= numlives) + return; + + numlives = (numlives + prevlives - player->lives); + } + } + player->lives += numlives; if (player->lives > 99) @@ -952,6 +1090,29 @@ void P_GivePlayerLives(player_t *player, INT32 numlives) player->lives = 1; } +void P_GiveCoopLives(player_t *player, INT32 numlives, boolean sound) +{ + if (!((netgame || multiplayer) && gametype == GT_COOP)) + { + P_GivePlayerLives(player, numlives); + if (sound) + P_PlayLivesJingle(player); + } + else + { + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + P_GivePlayerLives(&players[i], numlives); + if (sound) + P_PlayLivesJingle(&players[i]); + } + } +} + // // P_DoSuperTransformation // @@ -962,21 +1123,18 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player)) { S_StopMusic(); - S_ChangeMusicInternal("supers", true); + S_ChangeMusicInternal("_super", true); } S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi - // Transformation animation - P_SetPlayerMobjState(player->mo, S_PLAY_SUPERTRANS1); + player->mo->momx = player->mo->momy = player->mo->momz = player->cmomx = player->cmomy = player->rmomx = player->rmomy = 0; - player->mo->momx = player->mo->momy = player->mo->momz = 0; + // Transformation animation + P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_TRANS1); if (giverings) - { - player->mo->health = 51; - player->health = player->mo->health; - } + player->rings = 50; // Just in case. if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC)) @@ -995,6 +1153,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) P_PlayerFlagBurst(player, false); } + // Adds to the player's score void P_AddPlayerScore(player_t *player, UINT32 amount) { @@ -1010,7 +1169,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) { // Pseudo-shared score for multiplayer special stages. INT32 i; for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE) + if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE) { oldscore = players[i].marescore; @@ -1028,7 +1187,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) players[i].continues += 1; players[i].gotcontinue = true; if (P_IsLocalPlayer(player)) - S_StartSound(NULL, sfx_flgcap); + S_StartSound(NULL, sfx_s3kac); } */ } } @@ -1048,7 +1207,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) player->continues += 1; player->gotcontinue = true; if (P_IsLocalPlayer(player)) - S_StartSound(NULL, sfx_flgcap); + S_StartSound(NULL, sfx_s3kac); } } @@ -1059,9 +1218,8 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) oldscore = player->score; // Don't go above MAXSCORE. - if (player->score + amount < MAXSCORE) - player->score += amount; - else + player->score += amount; + if (player->score > MAXSCORE) player->score = MAXSCORE; // check for extra lives every 50000 pts @@ -1081,6 +1239,42 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) } } +// Steals from every enemy's score. +void P_StealPlayerScore(player_t *player, UINT32 amount) +{ + boolean teams = G_GametypeHasTeams(); + UINT32 stolen = 0; + int i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (&players[i] == player + || (teams && players[i].ctfteam == player->ctfteam)) + continue; + if (players[i].score >= amount) + { + stolen += amount; + players[i].score -= amount; + } + else + { + stolen += players[i].score; + players[i].score = 0; + } + } + if (stolen > 0) + { + // In team match, all stolen points are removed from the enemy team's running score. + if (gametype == GT_TEAMMATCH) + { + if (player->ctfteam == 1) + bluescore -= amount; + else if (player->ctfteam == 2) + redscore -= amount; + } + P_AddPlayerScore(player, stolen); + } +} + // // P_PlayLivesJingle // @@ -1096,9 +1290,11 @@ void P_PlayLivesJingle(player_t *player) else { if (player) - player->powers[pw_extralife] = extralifetics + 1; + player->powers[pw_extralife] = extralifetics+1; S_StopMusic(); // otherwise it won't restart if this is done twice in a row - S_ChangeMusicInternal("xtlife", false); + strlcpy(S_sfx[sfx_None].caption, "One-up", 7); + S_StartCaption(sfx_None, -1, extralifetics+1); + S_ChangeMusicInternal("_1up", false); } } @@ -1116,18 +1312,24 @@ void P_RestoreMusic(player_t *player) return; S_SpeedMusic(1.0f); if (player->powers[pw_super] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC)) - S_ChangeMusicInternal("supers", true); + S_ChangeMusicInternal("_super", true); else if (player->powers[pw_invulnerability] > 1) - S_ChangeMusicInternal((mariomode) ? "minvnc" : "invinc", false); + { + strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14); + S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]); + S_ChangeMusicInternal((mariomode) ? "_minv" : "_inv", false); + } else if (player->powers[pw_sneakers] > 1 && !player->powers[pw_super]) { + strlcpy(S_sfx[sfx_None].caption, "Speed shoes", 12); + S_StartCaption(sfx_None, -1, player->powers[pw_sneakers]); if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC) { S_SpeedMusic(1.4f); S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0); } else - S_ChangeMusicInternal("shoes", true); + S_ChangeMusicInternal("_shoes", true); } else S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0); @@ -1159,7 +1361,7 @@ boolean P_IsObjectInGoop(mobj_t *mo) // boolean P_IsObjectOnGround(mobj_t *mo) { - if (P_IsObjectInGoop(mo)) + if (P_IsObjectInGoop(mo) && !(mo->player && mo->player->pflags & PF_BOUNCING)) { /* // It's a crazy hack that checking if you're on the ground @@ -1298,28 +1500,6 @@ void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative) mo->momz = value; } -// -// P_GetPlayerHeight -// -// Returns the height -// of the player. -// -fixed_t P_GetPlayerHeight(player_t *player) -{ - return FixedMul(player->mo->info->height, player->mo->scale); -} - -// -// P_GetPlayerSpinHeight -// -// Returns the 'spin height' -// of the player. -// -fixed_t P_GetPlayerSpinHeight(player_t *player) -{ - return FixedMul(FixedMul(player->mo->info->height, player->mo->scale),2*FRACUNIT/3); -} - // // P_IsLocalPlayer // @@ -1349,24 +1529,38 @@ void P_SpawnShieldOrb(player_t *player) I_Error("P_SpawnShieldOrb: player->mo is NULL!\n"); #endif +#ifdef HAVE_BLUA + if (LUAh_ShieldSpawn(player)) + return; +#endif + if (player->powers[pw_shield] & SH_FORCE) - orbtype = MT_BLUEORB; + orbtype = MT_FORCE_ORB; else switch (player->powers[pw_shield] & SH_NOSTACK) { - case SH_JUMP: - orbtype = MT_WHITEORB; + case SH_WHIRLWIND: + orbtype = MT_WHIRLWIND_ORB; break; case SH_ATTRACT: - orbtype = MT_YELLOWORB; + orbtype = MT_ATTRACT_ORB; break; case SH_ELEMENTAL: - orbtype = MT_GREENORB; + orbtype = MT_ELEMENTAL_ORB; break; - case SH_BOMB: - orbtype = MT_BLACKORB; + case SH_ARMAGEDDON: + orbtype = MT_ARMAGEDDON_ORB; break; case SH_PITY: - orbtype = MT_PITYORB; + orbtype = MT_PITY_ORB; + break; + case SH_FLAMEAURA: + orbtype = MT_FLAMEAURA_ORB; + break; + case SH_BUBBLEWRAP: + orbtype = MT_BUBBLEWRAP_ORB; + break; + case SH_THUNDERCOIN: + orbtype = MT_THUNDERCOIN_ORB; break; default: return; @@ -1385,14 +1579,17 @@ void P_SpawnShieldOrb(player_t *player) } shieldobj = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, orbtype); + shieldobj->flags2 |= MF2_SHIELD; P_SetTarget(&shieldobj->target, player->mo); shieldobj->color = (UINT8)shieldobj->info->painchance; + shieldobj->threshold = (player->powers[pw_shield] & SH_FORCE) ? SH_FORCE : (player->powers[pw_shield] & SH_NOSTACK); if (shieldobj->info->seestate) { ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY); P_SetTarget(&ov->target, shieldobj); P_SetMobjState(ov, shieldobj->info->seestate); + P_SetTarget(&shieldobj->tracer, ov); } if (shieldobj->info->meleestate) { @@ -1409,7 +1606,7 @@ void P_SpawnShieldOrb(player_t *player) if (player->powers[pw_shield] & SH_FORCE) { //Copy and pasted from P_ShieldLook in p_mobj.c - shieldobj->movecount = (player->powers[pw_shield] & 0xFF); + shieldobj->movecount = (player->powers[pw_shield] & SH_FORCEHP); if (shieldobj->movecount < 1) { if (shieldobj->info->painstate) @@ -1420,6 +1617,57 @@ void P_SpawnShieldOrb(player_t *player) } } +// +// P_SwitchShield +// +// Handles the possibility of switching between +// the non-stack layer of shields thoroughly, +// then adds the desired one. +// +void P_SwitchShield(player_t *player, UINT16 shieldtype) +{ + boolean donthavealready; + + // If you already have a bomb shield, use it! + if ((shieldtype == SH_ARMAGEDDON) && (player->powers[pw_shield] & SH_NOSTACK) == SH_ARMAGEDDON) + P_BlackOw(player); + + donthavealready = (shieldtype & SH_FORCE) + ? (!(player->powers[pw_shield] & SH_FORCE) || (player->powers[pw_shield] & SH_FORCEHP) < (shieldtype & ~SH_FORCE)) + : ((player->powers[pw_shield] & SH_NOSTACK) != shieldtype); + + if (donthavealready) + { + boolean stopshieldability = (shieldtype & SH_FORCE) + ? (!(player->powers[pw_shield] & SH_FORCE)) + : true; + + // Just in case. + if (stopshieldability && player->pflags & PF_SHIELDABILITY) + { + player->pflags &= ~(PF_SPINNING|PF_SHIELDABILITY); // They'll still have PF_THOKKED... + player->homing = 0; + } + + player->powers[pw_shield] = shieldtype|(player->powers[pw_shield] & SH_STACK); + P_SpawnShieldOrb(player); + + if (shieldtype & SH_PROTECTWATER) + { + if (player->powers[pw_underwater] && player->powers[pw_underwater] <= 12*TICRATE + 1) + P_RestoreMusic(player); + + player->powers[pw_underwater] = 0; + + if (player->powers[pw_spacetime] > 1) + { + player->powers[pw_spacetime] = 0; + P_RestoreMusic(player); + } + } + } +} + // // P_SpawnGhostMobj // @@ -1427,9 +1675,7 @@ void P_SpawnShieldOrb(player_t *player) // mobj_t *P_SpawnGhostMobj(mobj_t *mobj) { - mobj_t *ghost; - - ghost = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_GHOST); + mobj_t *ghost = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_GHOST); P_SetScale(ghost, mobj->scale); ghost->destscale = mobj->scale; @@ -1442,8 +1688,9 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->color = mobj->color; - ghost->angle = mobj->angle; + ghost->angle = (mobj->player ? mobj->player->drawangle : mobj->angle); ghost->sprite = mobj->sprite; + ghost->sprite2 = mobj->sprite2; ghost->frame = mobj->frame; ghost->tics = -1; ghost->frame &= ~FF_TRANSMASK; @@ -1454,6 +1701,14 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) if (mobj->flags2 & MF2_OBJECTFLIP) ghost->flags |= 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); + ghost2->flags2 |= MF2_LINKDRAW; + } + return ghost; } @@ -1491,7 +1746,7 @@ void P_SpawnThokMobj(player_t *player) mobj = P_SpawnMobj(player->mo->x, player->mo->y, zheight, type); // set to player's angle, just in case - mobj->angle = player->mo->angle; + mobj->angle = player->drawangle; // color and skin mobj->color = player->mo->color; @@ -1505,6 +1760,12 @@ void P_SpawnThokMobj(player_t *player) // scale P_SetScale(mobj, player->mo->scale); mobj->destscale = player->mo->scale; + + if (type == MT_THOK) // spintrail-specific modification for MT_THOK + { + mobj->frame = FF_TRANS70; + mobj->fuse = mobj->tics; + } } P_SetTarget(&mobj->target, player->mo); // the one thing P_SpawnGhostMobj doesn't do @@ -1545,7 +1806,7 @@ void P_SpawnSpinMobj(player_t *player, mobjtype_t type) mobj = P_SpawnMobj(player->mo->x, player->mo->y, zheight, type); // set to player's angle, just in case - mobj->angle = player->mo->angle; + mobj->angle = player->drawangle; // color and skin mobj->color = player->mo->color; @@ -1559,6 +1820,12 @@ void P_SpawnSpinMobj(player_t *player, mobjtype_t type) // scale P_SetScale(mobj, player->mo->scale); mobj->destscale = player->mo->scale; + + if (type == MT_THOK) // spintrail-specific modification for MT_THOK + { + mobj->frame = FF_TRANS70; + mobj->fuse = mobj->tics; + } } P_SetTarget(&mobj->target, player->mo); // the one thing P_SpawnGhostMobj doesn't do @@ -1578,7 +1845,7 @@ void P_DoPlayerExit(player_t *player) else if (gametype == GT_RACE || gametype == GT_COMPETITION) // If in Race Mode, allow { if (!countdown) // a 60-second wait ala Sonic 2. - countdown = cv_countdowntime.value*TICRATE + 1; // Use cv_countdowntime + countdown = (cv_countdowntime.value - 1)*TICRATE + 1; // Use cv_countdowntime player->exiting = 3*TICRATE; @@ -1595,8 +1862,8 @@ void P_DoPlayerExit(player_t *player) if (player->climbing) { player->climbing = 0; - player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + player->pflags |= P_GetJumpFlags(player); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } player->powers[pw_underwater] = 0; player->powers[pw_spacetime] = 0; @@ -1647,45 +1914,163 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space return false; // No vacuum here, Captain! } -boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand +// +// P_PlayerHitFloor +// +// Handles player hitting floor surface. +// Returns whether to clip momz. +boolean P_PlayerHitFloor(player_t *player) { - sector_t *sector = mo->subsector->sector; - fixed_t topheight, bottomheight; + boolean clipmomz; - fixed_t flipoffset = ((mo->eflags & MFE_VERTICALFLIP) ? (mo->height/2) : 0); + I_Assert(player->mo != NULL); - if (sector->ffloors) + if ((clipmomz = !(P_CheckDeathPitCollide(player->mo))) && player->mo->health && !player->spectator) { - ffloor_t *rover; - - for (rover = sector->ffloors; rover; rover = rover->next) + if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_THOKKED) && (player->cmd.buttons & BT_USE) && (FixedHypot(player->mo->momx, player->mo->momy) > (5*player->mo->scale))) { - if (!(rover->flags & FF_EXISTS)) - continue; - - if (!(rover->flags & FF_QUICKSAND)) - continue; - -#ifdef ESLOPE - topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) : *rover->topheight; - bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) : *rover->bottomheight; -#else - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; -#endif - - if (mo->z + flipoffset > topheight) - continue; - - if (mo->z + (mo->height/2) + flipoffset < bottomheight) - continue; - - return true; + player->pflags |= PF_SPINNING; + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + S_StartSound(player->mo, sfx_spin); } - } + else + { + player->pflags &= ~PF_SPINNING; - return false; // No sand here, Captain! -} + if (player->pflags & PF_GLIDING) // ground gliding + { + player->skidtime = TICRATE; + player->mo->tics = -1; + } + else if (player->charability2 == CA2_MELEE && (player->panim == PA_ABILITY2 && player->mo->state-states != S_PLAY_MELEE_LANDING)) + { + P_SetPlayerMobjState(player->mo, S_PLAY_MELEE_LANDING); + player->mo->tics = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; + S_StartSound(player->mo, sfx_s3k8b); + player->pflags |= PF_FULLSTASIS; + } + else if (player->pflags & PF_JUMPED || !(player->pflags & PF_SPINNING) + || player->powers[pw_tailsfly] || player->mo->state-states == S_PLAY_FLY_TIRED) + { + if (player->cmomx || player->cmomy) + { + if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH) + P_SetPlayerMobjState(player->mo, S_PLAY_DASH); + else if (player->speed >= FixedMul(player->runspeed, player->mo->scale) + && (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN)) + P_SetPlayerMobjState(player->mo, S_PLAY_RUN); + else if ((player->rmomx || player->rmomy) + && (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT)) + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + else if (!player->rmomx && !player->rmomy && player->panim != PA_IDLE) + P_SetPlayerMobjState(player->mo, S_PLAY_STND); + } + else + { + if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH) + P_SetPlayerMobjState(player->mo, S_PLAY_DASH); + else if (player->speed >= FixedMul(player->runspeed, player->mo->scale) + && (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN)) + P_SetPlayerMobjState(player->mo, S_PLAY_RUN); + else if ((player->mo->momx || player->mo->momy) + && (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT)) + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + else if (!player->mo->momx && !player->mo->momy && player->panim != PA_IDLE) + P_SetPlayerMobjState(player->mo, S_PLAY_STND); + } + } + } + + if (!(player->pflags & PF_GLIDING)) + player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE); + player->pflags &= ~(PF_STARTJUMP|PF_THOKKED|PF_CANCARRY/*|PF_GLIDING*/); + player->secondjump = 0; + player->glidetime = 0; + player->climbing = 0; + player->powers[pw_tailsfly] = 0; + + if (player->pflags & PF_SHIELDABILITY) + { + player->pflags &= ~PF_SHIELDABILITY; + + if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) // Elemental shield's stomp attack. + { + if (player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) // play a blunt sound + S_StartSound(player->mo, sfx_s3k4c); + else // create a fire pattern on the ground + { + S_StartSound(player->mo, sfx_s3k47); + P_ElementalFire(player, true); + } + P_SetObjectMomZ(player->mo, + (player->mo->eflags & MFE_UNDERWATER) + ? 6*FRACUNIT/5 + : 5*FRACUNIT/2, + false); + P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + player->mo->momx = player->mo->momy = 0; + clipmomz = false; + } + else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) // Bubble shield's bounce attack. + { + P_DoBubbleBounce(player); + clipmomz = false; + } + } + + if (player->pflags & PF_BOUNCING) + { + P_MobjCheckWater(player->mo); + player->mo->momz *= -1; + P_DoAbilityBounce(player, true); + if (player->scoreadd) + player->scoreadd--; + clipmomz = false; + } + } + + return clipmomz; +} + +boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand +{ + sector_t *sector = mo->subsector->sector; + fixed_t topheight, bottomheight; + + fixed_t flipoffset = ((mo->eflags & MFE_VERTICALFLIP) ? (mo->height/2) : 0); + + if (sector->ffloors) + { + ffloor_t *rover; + + for (rover = sector->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS)) + continue; + + if (!(rover->flags & FF_QUICKSAND)) + continue; + +#ifdef ESLOPE + topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) : *rover->topheight; + bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) : *rover->bottomheight; +#else + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; +#endif + + if (mo->z + flipoffset > topheight) + continue; + + if (mo->z + (mo->height/2) + flipoffset < bottomheight) + continue; + + return true; + } + } + + return false; // No sand here, Captain! +} static void P_CheckBustableBlocks(player_t *player) { @@ -1699,10 +2084,13 @@ static void P_CheckBustableBlocks(player_t *player) oldx = player->mo->x; oldy = player->mo->y; - P_UnsetThingPosition(player->mo); - player->mo->x += player->mo->momx; - player->mo->y += player->mo->momy; - P_SetThingPosition(player->mo); + if (!(player->pflags & PF_BOUNCING)) // Bouncers only get to break downwards, not sideways + { + P_UnsetThingPosition(player->mo); + player->mo->x += player->mo->momx; + player->mo->y += player->mo->momy; + P_SetThingPosition(player->mo); + } for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next) { @@ -1722,25 +2110,47 @@ static void P_CheckBustableBlocks(player_t *player) { // If it's an FF_SPINBUST, you have to either be jumping, or coming down // onto the top from a spin. - if (rover->flags & FF_SPINBUST && ((!(player->pflags & PF_JUMPED) && !(player->pflags & PF_SPINNING)) || (player->pflags & PF_STARTDASH))) + if (rover->flags & FF_SPINBUST && ((!(player->pflags & PF_JUMPED) && !(player->pflags & PF_SPINNING) && !(player->pflags & PF_BOUNCING)) || (player->pflags & PF_STARTDASH))) continue; // if it's not an FF_SHATTER, you must be spinning (and not jumping) - // or have Knuckles's abilities (or Super Sonic) - // ...or are drilling in NiGHTS (or Metal Sonic) + // or be super + // or have CA_GLIDEANDCLIMB + // or be in dashmode with SF_DASHMODE + // or be using CA_TWINSPIN + // or be using CA2_MELEE + // or are drilling in NiGHTS + // or are recording for Metal Sonic if (!(rover->flags & FF_SHATTER) && !(rover->flags & FF_SPINBUST) && !((player->pflags & PF_SPINNING) && !(player->pflags & PF_JUMPED)) - && (player->charability != CA_GLIDEANDCLIMB && !player->powers[pw_super]) - && !(player->pflags & PF_DRILLING) && !metalrecording) + && !(player->powers[pw_super]) + && !(player->charability == CA_GLIDEANDCLIMB) + && !(player->pflags & PF_BOUNCING) + && !((player->charflags & SF_DASHMODE) && (player->dashmode >= 3*TICRATE)) + && !((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)) + && !(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2) + && !(player->pflags & PF_DRILLING) + && !metalrecording) continue; - // Only Knuckles can break this rock... - if (!(rover->flags & FF_SHATTER) && (rover->flags & FF_ONLYKNUX) && !(player->charability == CA_GLIDEANDCLIMB)) + // Only players with CA_GLIDEANDCLIMB, or CA_TWINSPIN/CA2_MELEE users can break this rock... + if (!(rover->flags & FF_SHATTER) && (rover->flags & FF_ONLYKNUX) + && !(player->charability == CA_GLIDEANDCLIMB + || (player->pflags & PF_BOUNCING) + || ((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)) + || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2))) continue; topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + if (((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)) + || ((P_MobjFlip(player->mo)*player->mo->momz < 0) && (player->pflags & PF_BOUNCING || ((player->charability2 == CA2_MELEE) && (player->panim == PA_ABILITY2))))) + { + topheight -= player->mo->momz; + bottomheight -= player->mo->momz; + } + // Height checks if (rover->flags & FF_SHATTERBOTTOM) { @@ -1799,10 +2209,13 @@ static void P_CheckBustableBlocks(player_t *player) } } bustupdone: - P_UnsetThingPosition(player->mo); - player->mo->x = oldx; - player->mo->y = oldy; - P_SetThingPosition(player->mo); + if (!(player->pflags & PF_BOUNCING)) + { + P_UnsetThingPosition(player->mo); + player->mo->x = oldx; + player->mo->y = oldy; + P_SetThingPosition(player->mo); + } } static void P_CheckBouncySectors(player_t *player) @@ -1925,7 +2338,7 @@ static void P_CheckBouncySectors(player_t *player) if (player->pflags & PF_SPINNING) { player->pflags &= ~PF_SPINNING; - player->pflags |= PF_JUMPED; + player->pflags |= P_GetJumpFlags(player); player->pflags |= PF_THOKKED; } } @@ -1937,7 +2350,7 @@ static void P_CheckBouncySectors(player_t *player) if (player->pflags & PF_SPINNING) { player->pflags &= ~PF_SPINNING; - player->pflags |= PF_JUMPED; + player->pflags |= P_GetJumpFlags(player); player->pflags |= PF_THOKKED; } } @@ -1945,7 +2358,7 @@ static void P_CheckBouncySectors(player_t *player) if ((player->pflags & PF_SPINNING) && player->speed < FixedMul(1<<FRACBITS, player->mo->scale) && player->mo->momz) { player->pflags &= ~PF_SPINNING; - player->pflags |= PF_JUMPED; + player->pflags |= P_GetJumpFlags(player); } goto bouncydone; @@ -1999,6 +2412,9 @@ static void P_CheckQuicksand(player_t *player) if (player->mo->z + player->mo->height >= ceilingheight) player->mo->z = ceilingheight - player->mo->height; + + if (player->mo->momz <= 0) + P_PlayerHitFloor(player); } else { @@ -2008,6 +2424,9 @@ static void P_CheckQuicksand(player_t *player) if (player->mo->z <= floorheight) player->mo->z = floorheight; + + if (player->mo->momz >= 0) + P_PlayerHitFloor(player); } friction = abs(rover->master->v1->y - rover->master->v2->y)>>6; @@ -2043,72 +2462,55 @@ static void P_CheckSneakerAndLivesTimer(player_t *player) // static void P_CheckUnderwaterAndSpaceTimer(player_t *player) { - fixed_t height; - mobj_t *numbermobj = NULL; + tic_t timeleft = (player->powers[pw_spacetime]) ? player->powers[pw_spacetime] : player->powers[pw_underwater]; - if (player->mo->eflags & MFE_VERTICALFLIP) - height = player->mo->z - FixedMul(8*FRACUNIT - mobjinfo[MT_DROWNNUMBERS].height, player->mo->scale); - else - height = player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale); + if (player->exiting) + player->powers[pw_underwater] = player->powers[pw_spacetime] = 0; - if (player->powers[pw_underwater] == 11*TICRATE + 1 || player->powers[pw_spacetime] == 11*TICRATE + 1) - { - numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); - P_SetMobjState(numbermobj, numbermobj->info->spawnstate+5); - } - else if (player->powers[pw_underwater] == 9*TICRATE + 1 || player->powers[pw_spacetime] == 9*TICRATE + 1) - { - numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); - P_SetMobjState(numbermobj, numbermobj->info->spawnstate+4); - } - else if (player->powers[pw_underwater] == 7*TICRATE + 1 || player->powers[pw_spacetime] == 7*TICRATE + 1) - { - numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); - P_SetMobjState(numbermobj, numbermobj->info->spawnstate+3); - } - else if (player->powers[pw_underwater] == 5*TICRATE + 1 || player->powers[pw_spacetime] == 5*TICRATE + 1) - { - numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); - P_SetMobjState(numbermobj, numbermobj->info->spawnstate+2); - } - else if (player->powers[pw_underwater] == 3*TICRATE + 1 || player->powers[pw_spacetime] == 3*TICRATE + 1) - { - numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); - P_SetMobjState(numbermobj, numbermobj->info->spawnstate+1); - } - else if (player->powers[pw_underwater] == 1*TICRATE + 1 || player->powers[pw_spacetime] == 1*TICRATE + 1) - { - numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); - //P_SetMobjState(numbermobj, numbermobj->info->spawnstate+0); - } - // Underwater timer runs out - else if (player->powers[pw_underwater] == 1) - { - mobj_t *killer; + timeleft--; // The original code was all n*TICRATE + 1, so let's remove 1 tic for simplicity - if ((netgame || multiplayer) && P_IsLocalPlayer(player)) - S_ChangeMusic(mapmusname, mapmusflags, true); + if ((timeleft == 11*TICRATE) // 5 + || (timeleft == 9*TICRATE) // 4 + || (timeleft == 7*TICRATE) // 3 + || (timeleft == 5*TICRATE) // 2 + || (timeleft == 3*TICRATE) // 1 + || (timeleft == 1*TICRATE) // 0 + ) { + fixed_t height = (player->mo->eflags & MFE_VERTICALFLIP) + ? player->mo->z - FixedMul(8*FRACUNIT + mobjinfo[MT_DROWNNUMBERS].height, FixedMul(player->mo->scale, player->shieldscale)) + : player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, FixedMul(player->mo->scale, player->shieldscale)); - killer = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_NULL); - killer->threshold = 42; // Special flag that it was drowning which killed you. - P_DamageMobj(player->mo, killer, killer, 10000); - } - else if (player->powers[pw_spacetime] == 1) - { - if ((netgame || multiplayer) && P_IsLocalPlayer(player)) - S_ChangeMusic(mapmusname, mapmusflags, true); + mobj_t *numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); - P_DamageMobj(player->mo, NULL, NULL, 10000); - } + timeleft /= (2*TICRATE); // To be strictly accurate it'd need to be ((timeleft/TICRATE) - 1)/2, but integer division rounds down for us + + if (player->charflags & SF_MACHINE) + { + S_StartSound(player->mo, sfx_buzz1); + timeleft += 6; + } + else + S_StartSound(player->mo, sfx_dwnind); + + if (timeleft) // Don't waste time setting the state if the time is 0. + P_SetMobjState(numbermobj, numbermobj->info->spawnstate+timeleft); - if (numbermobj) - { P_SetTarget(&numbermobj->target, player->mo); numbermobj->threshold = 40; - S_StartSound(player->mo, sfx_dwnind); numbermobj->destscale = player->mo->scale; P_SetScale(numbermobj, player->mo->scale); } + // Underwater timer runs out + else if (timeleft == 1) + { + if ((netgame || multiplayer) && P_IsLocalPlayer(player)) + S_ChangeMusic(mapmusname, mapmusflags, true); + + if (player->powers[pw_spacetime] == 1) + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPACEDROWN); + else + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DROWNED); + } if (!(player->mo->eflags & MFE_UNDERWATER) && player->powers[pw_underwater]) { @@ -2127,27 +2529,17 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) // Underwater audio cues if (P_IsLocalPlayer(player) && !player->bot) { + if ((player->powers[pw_underwater] == 25*TICRATE + 1) + || (player->powers[pw_underwater] == 20*TICRATE + 1) + || (player->powers[pw_underwater] == 15*TICRATE + 1)) + S_StartSound(NULL, sfx_wtrdng); + if (player->powers[pw_underwater] == 11*TICRATE + 1 && player == &players[consoleplayer]) { S_StopMusic(); - S_ChangeMusicInternal("drown", false); + S_ChangeMusicInternal("_drown", false); } - - if (player->powers[pw_underwater] == 25*TICRATE + 1) - S_StartSound(NULL, sfx_wtrdng); - else if (player->powers[pw_underwater] == 20*TICRATE + 1) - S_StartSound(NULL, sfx_wtrdng); - else if (player->powers[pw_underwater] == 15*TICRATE + 1) - S_StartSound(NULL, sfx_wtrdng); - } - - if (player->exiting) - { - if (player->powers[pw_underwater] > 1) - player->powers[pw_underwater] = 0; - - player->powers[pw_spacetime] = 0; } } @@ -2162,7 +2554,7 @@ static void P_CheckInvincibilityTimer(player_t *player) return; if (mariomode && !player->powers[pw_super]) - player->mo->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))); + player->mo->color = (UINT8)(SKINCOLOR_RUBY + (leveltime % (MAXSKINCOLORS - SKINCOLOR_RUBY))); // Passes through all saturated colours else if (leveltime % (TICRATE/7) == 0) { mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP); @@ -2177,7 +2569,7 @@ static void P_CheckInvincibilityTimer(player_t *player) { if (mariomode) { - if (player->powers[pw_shield] & SH_FIREFLOWER) + if ((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) { player->mo->color = SKINCOLOR_WHITE; G_GhostAddColor(GHC_FIREFLOWER); @@ -2209,21 +2601,39 @@ static void P_CheckInvincibilityTimer(player_t *player) // static void P_DoBubbleBreath(player_t *player) { - fixed_t zh; + fixed_t x = player->mo->x; + fixed_t y = player->mo->y; + fixed_t z = player->mo->z; mobj_t *bubble = NULL; - if (player->mo->eflags & MFE_VERTICALFLIP) - zh = player->mo->z + player->mo->height - FixedDiv(player->mo->height,5*(FRACUNIT/4)); + if (!(player->mo->eflags & MFE_UNDERWATER) || ((player->powers[pw_shield] & SH_PROTECTWATER) && !(player->powers[pw_carry] == CR_NIGHTSMODE)) || player->spectator) + return; + + if (player->charflags & SF_MACHINE) + { + if (player->powers[pw_underwater] && P_RandomChance((128-(player->powers[pw_underwater]/4))*FRACUNIT/256)) + { + fixed_t r = player->mo->radius>>FRACBITS; + x += (P_RandomRange(r, -r)<<FRACBITS); + y += (P_RandomRange(r, -r)<<FRACBITS); + z += (P_RandomKey(player->mo->height>>FRACBITS)<<FRACBITS); + bubble = P_SpawnMobj(x, y, z, MT_WATERZAP); + S_StartSound(bubble, sfx_beelec); + } + } else - zh = player->mo->z + FixedDiv(player->mo->height,5*(FRACUNIT/4)); + { + if (player->mo->eflags & MFE_VERTICALFLIP) + z += player->mo->height - FixedDiv(player->mo->height,5*(FRACUNIT/4)); + else + z += FixedDiv(player->mo->height,5*(FRACUNIT/4)); - if (!(player->mo->eflags & MFE_UNDERWATER) || ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && !(player->pflags & PF_NIGHTSMODE)) || player->spectator) - return; + if (P_RandomChance(FRACUNIT/16)) + bubble = P_SpawnMobj(x, y, z, MT_SMALLBUBBLE); + else if (P_RandomChance(3*FRACUNIT/256)) + bubble = P_SpawnMobj(x, y, z, MT_MEDIUMBUBBLE); + } - if (P_RandomChance(FRACUNIT/16)) - bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_SMALLBUBBLE); - else if (P_RandomChance(3*FRACUNIT/256)) - bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_MEDIUMBUBBLE); if (bubble) { bubble->threshold = 42; @@ -2231,7 +2641,7 @@ static void P_DoBubbleBreath(player_t *player) P_SetScale(bubble, bubble->destscale); } - if (player->pflags & PF_NIGHTSMODE) // NiGHTS Super doesn't spawn flight bubbles + if (player->powers[pw_carry] == CR_NIGHTSMODE) // NiGHTS Super doesn't spawn flight bubbles return; // Tails stirs up the water while flying in it @@ -2276,7 +2686,7 @@ static void P_DoPlayerHeadSigns(player_t *player) // If you're "IT", show a big "IT" over your head for others to see. if (player->pflags & PF_TAGIT) { - if (!(player == &players[consoleplayer] || player == &players[secondarydisplayplayer] || player == &players[displayplayer])) // Don't display it on your own view. + if (!P_IsLocalPlayer(player)) // Don't display it on your own view. { if (!(player->mo->eflags & MFE_VERTICALFLIP)) P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height, MT_TAG); @@ -2285,33 +2695,26 @@ static void P_DoPlayerHeadSigns(player_t *player) } } } - else if (gametype == GT_CTF) + else if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) // If you have the flag (duh). { - if (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)) // If you have the flag (duh). + // Spawn a got-flag message over the head of the player that + // has it (but not on your own screen if you have the flag). + if (splitscreen || player != &players[consoleplayer]) { - // Spawn a got-flag message over the head of the player that - // has it (but not on your own screen if you have the flag). - if (splitscreen || player != &players[consoleplayer]) + mobj_t *sign = P_SpawnMobj(player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, + player->mo->z+player->mo->momz, MT_GOTFLAG); + if (player->mo->eflags & MFE_VERTICALFLIP) { - if (player->gotflag & GF_REDFLAG) - { - if (!(player->mo->eflags & MFE_VERTICALFLIP)) - P_SpawnMobj(player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, - player->mo->z+P_GetPlayerHeight(player)+FixedMul(16*FRACUNIT, player->mo->scale)+player->mo->momz, MT_GOTFLAG); - else - P_SpawnMobj(player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, - player->mo->z+player->mo->height-P_GetPlayerHeight(player)-mobjinfo[MT_GOTFLAG].height-FixedMul(16*FRACUNIT, player->mo->scale)+player->mo->momz, MT_GOTFLAG)->eflags |= MFE_VERTICALFLIP; - } - if (player->gotflag & GF_BLUEFLAG) - { - if (!(player->mo->eflags & MFE_VERTICALFLIP)) - P_SpawnMobj(player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, - player->mo->z+P_GetPlayerHeight(player)+FixedMul(16*FRACUNIT, player->mo->scale)+player->mo->momz, MT_GOTFLAG2); - else - P_SpawnMobj(player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, - player->mo->z+player->mo->height-P_GetPlayerHeight(player)-mobjinfo[MT_GOTFLAG2].height-FixedMul(16*FRACUNIT, player->mo->scale)+player->mo->momz, MT_GOTFLAG2)->eflags |= MFE_VERTICALFLIP; - } + sign->z += player->mo->height-P_GetPlayerHeight(player)-mobjinfo[MT_GOTFLAG].height-FixedMul(16*FRACUNIT, player->mo->scale); + sign->eflags |= MFE_VERTICALFLIP; } + else + sign->z += P_GetPlayerHeight(player)+FixedMul(16*FRACUNIT, player->mo->scale); + + if (player->gotflag & GF_REDFLAG) + sign->frame = 1|FF_FULLBRIGHT; + else //if (player->gotflag & GF_BLUEFLAG) + sign->frame = 2|FF_FULLBRIGHT; } } } @@ -2710,10 +3113,10 @@ static void P_DoClimbing(player_t *player) climb = false; if (player->climbing && climb && (player->mo->momx || player->mo->momy || player->mo->momz) - && !(player->mo->state >= &states[S_PLAY_CLIMB2] && player->mo->state <= &states[S_PLAY_CLIMB5])) - P_SetPlayerMobjState(player->mo, S_PLAY_CLIMB2); - else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && player->mo->state != &states[S_PLAY_CLIMB1]) - P_SetPlayerMobjState(player->mo, S_PLAY_CLIMB1); + && player->mo->state-states != S_PLAY_CLIMB) + P_SetPlayerMobjState(player->mo, S_PLAY_CLIMB); + else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && player->mo->state-states != S_PLAY_CLING) + P_SetPlayerMobjState(player->mo, S_PLAY_CLING); if (!floorclimb) { @@ -2723,22 +3126,22 @@ static void P_DoClimbing(player_t *player) P_InstaThrust(player->mo, player->mo->angle, FixedMul(4*FRACUNIT, player->mo->scale)); // Lil' boost up. player->climbing = 0; - player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + player->pflags |= P_GetJumpFlags(player); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } if (skyclimber) { player->climbing = 0; - player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + player->pflags |= P_GetJumpFlags(player); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } } else { player->climbing = 0; - player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + player->pflags |= P_GetJumpFlags(player); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } if (cmd->sidemove != 0 || cmd->forwardmove != 0) @@ -2747,16 +3150,16 @@ static void P_DoClimbing(player_t *player) climb = false; if (player->climbing && climb && (player->mo->momx || player->mo->momy || player->mo->momz) - && !(player->mo->state >= &states[S_PLAY_CLIMB2] && player->mo->state <= &states[S_PLAY_CLIMB5])) - P_SetPlayerMobjState(player->mo, S_PLAY_CLIMB2); - else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && player->mo->state != &states[S_PLAY_CLIMB1]) - P_SetPlayerMobjState(player->mo, S_PLAY_CLIMB1); + && player->mo->state-states != S_PLAY_CLIMB) + P_SetPlayerMobjState(player->mo, S_PLAY_CLIMB); + else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && player->mo->state-states != S_PLAY_CLING) + P_SetPlayerMobjState(player->mo, S_PLAY_CLING); if (cmd->buttons & BT_USE && !(player->pflags & PF_JUMPSTASIS)) { player->climbing = 0; - player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + player->pflags |= P_GetJumpFlags(player); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); P_SetObjectMomZ(player->mo, 4*FRACUNIT, false); P_InstaThrust(player->mo, player->mo->angle, FixedMul(-4*FRACUNIT, player->mo->scale)); } @@ -2770,7 +3173,7 @@ static void P_DoClimbing(player_t *player) } if (player->climbing == 0) - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); if (player->climbing && P_IsObjectOnGround(player->mo)) { @@ -3148,10 +3551,10 @@ teeterdone: } if (teeter) { - if ((player->mo->state == &states[S_PLAY_STND] || player->mo->state == &states[S_PLAY_TAP1] || player->mo->state == &states[S_PLAY_TAP2] || player->mo->state == &states[S_PLAY_SUPERSTAND])) - P_SetPlayerMobjState(player->mo, S_PLAY_TEETER1); + if (player->panim == PA_IDLE) + P_SetPlayerMobjState(player->mo, S_PLAY_EDGE); } - else if ((player->mo->state == &states[S_PLAY_TEETER1] || player->mo->state == &states[S_PLAY_TEETER2] || player->mo->state == &states[S_PLAY_SUPERTEETER])) + else if (player->panim == PA_EDGE) P_SetPlayerMobjState(player->mo, S_PLAY_STND); } @@ -3181,213 +3584,198 @@ static void P_SetWeaponDelay(player_t *player, INT32 delay) static void P_DoFiring(player_t *player, ticcmd_t *cmd) { INT32 i; + mobj_t *mo = NULL; I_Assert(player != NULL); I_Assert(!P_MobjWasRemoved(player->mo)); - if (cmd->buttons & BT_ATTACK || cmd->buttons & BT_FIRENORMAL) + if (!(cmd->buttons & (BT_ATTACK|BT_FIRENORMAL))) { - if (!(player->pflags & PF_ATTACKDOWN) && player->powers[pw_shield] & SH_FIREFLOWER && !player->climbing) - { - player->pflags |= PF_ATTACKDOWN; - P_SpawnPlayerMissile(player->mo, MT_FIREBALL, 0); - S_StartSound(player->mo, sfx_mario7); - } - else if (G_RingSlingerGametype() && (!G_TagGametype() || player->pflags & PF_TAGIT) - && !player->weapondelay && !player->climbing - && !(player->pflags & PF_ATTACKDOWN)) - { - mobj_t *mo = NULL; - player->pflags |= PF_ATTACKDOWN; - - if (cmd->buttons & BT_FIRENORMAL) // No powers, just a regular ring. - goto firenormal; //code repetition sucks. - // Bounce ring - else if (player->currentweapon == WEP_BOUNCE && player->powers[pw_bouncering]) - { - if (player->health <= 1) - return; - P_SetWeaponDelay(player, TICRATE/4); + // Not holding any firing buttons anymore. + // Release the grenade / whatever. + player->pflags &= ~PF_ATTACKDOWN; + return; + } - mo = P_SpawnPlayerMissile(player->mo, MT_THROWNBOUNCE, MF2_BOUNCERING); + if (player->pflags & PF_ATTACKDOWN || player->climbing || (G_TagGametype() && !(player->pflags & PF_TAGIT))) + return; - if (mo) - mo->fuse = 3*TICRATE; // Bounce Ring time + if ((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) + { + player->pflags |= PF_ATTACKDOWN; + mo = P_SpawnPlayerMissile(player->mo, MT_FIREBALL, 0); + P_InstaThrust(mo, player->mo->angle, ((mo->info->speed>>FRACBITS)*player->mo->scale) + player->speed); + S_StartSound(player->mo, sfx_mario7); + return; + } - player->powers[pw_bouncering]--; - player->mo->health--; - player->health--; - } - // Rail ring - else if (player->currentweapon == WEP_RAIL && player->powers[pw_railring]) - { - if (player->health <= 1) - return; - P_SetWeaponDelay(player, (3*TICRATE)/2); + if (!G_RingSlingerGametype() || player->weapondelay) + return; - mo = P_SpawnPlayerMissile(player->mo, MT_REDRING, MF2_RAILRING|MF2_DONTDRAW); + player->pflags |= PF_ATTACKDOWN; - // Rail has no unique thrown object, therefore its sound plays here. - S_StartSound(player->mo, sfx_rail1); +#define TAKE_AMMO(player, power) \ + player->powers[power]--; \ + if (player->rings < 1) \ + { \ + if (player->powers[power] > 0) \ + player->powers[power]--; \ + } \ + else \ + player->rings--; - player->powers[pw_railring]--; - player->mo->health--; - player->health--; - } - // Automatic - else if (player->currentweapon == WEP_AUTO && player->powers[pw_automaticring]) - { - if (player->health <= 1) - return; - player->pflags &= ~PF_ATTACKDOWN; - P_SetWeaponDelay(player, 2); + if (cmd->buttons & BT_FIRENORMAL) // No powers, just a regular ring. + goto firenormal; //code repetition sucks. + // Bounce ring + else if (player->currentweapon == WEP_BOUNCE && player->powers[pw_bouncering]) + { + TAKE_AMMO(player, pw_bouncering); + P_SetWeaponDelay(player, TICRATE/4); - mo = P_SpawnPlayerMissile(player->mo, MT_THROWNAUTOMATIC, MF2_AUTOMATIC); + mo = P_SpawnPlayerMissile(player->mo, MT_THROWNBOUNCE, MF2_BOUNCERING); - player->powers[pw_automaticring]--; - player->mo->health--; - player->health--; - } - // Explosion - else if (player->currentweapon == WEP_EXPLODE && player->powers[pw_explosionring]) - { - if (player->health <= 1) - return; - P_SetWeaponDelay(player, (3*TICRATE)/2); + if (mo) + mo->fuse = 3*TICRATE; // Bounce Ring time + } + // Rail ring + else if (player->currentweapon == WEP_RAIL && player->powers[pw_railring]) + { + TAKE_AMMO(player, pw_railring); + P_SetWeaponDelay(player, (3*TICRATE)/2); - mo = P_SpawnPlayerMissile(player->mo, MT_THROWNEXPLOSION, MF2_EXPLOSION); + mo = P_SpawnPlayerMissile(player->mo, MT_REDRING, MF2_RAILRING|MF2_DONTDRAW); - player->powers[pw_explosionring]--; - player->mo->health--; - player->health--; - } - // Grenade - else if (player->currentweapon == WEP_GRENADE && player->powers[pw_grenadering]) - { - if (player->health <= 1) - return; - P_SetWeaponDelay(player, TICRATE/3); + // Rail has no unique thrown object, therefore its sound plays here. + S_StartSound(player->mo, sfx_rail1); + } + // Automatic + else if (player->currentweapon == WEP_AUTO && player->powers[pw_automaticring]) + { + TAKE_AMMO(player, pw_automaticring); + player->pflags &= ~PF_ATTACKDOWN; + P_SetWeaponDelay(player, 2); - mo = P_SpawnPlayerMissile(player->mo, MT_THROWNGRENADE, MF2_EXPLOSION); + mo = P_SpawnPlayerMissile(player->mo, MT_THROWNAUTOMATIC, MF2_AUTOMATIC); + } + // Explosion + else if (player->currentweapon == WEP_EXPLODE && player->powers[pw_explosionring]) + { + TAKE_AMMO(player, pw_explosionring); + P_SetWeaponDelay(player, (3*TICRATE)/2); - if (mo) - { - //P_InstaThrust(mo, player->mo->angle, FixedMul(mo->info->speed, player->mo->scale)); - mo->fuse = mo->info->mass; - } + mo = P_SpawnPlayerMissile(player->mo, MT_THROWNEXPLOSION, MF2_EXPLOSION); + } + // Grenade + else if (player->currentweapon == WEP_GRENADE && player->powers[pw_grenadering]) + { + TAKE_AMMO(player, pw_grenadering); + P_SetWeaponDelay(player, TICRATE/3); - player->powers[pw_grenadering]--; - player->mo->health--; - player->health--; - } - // Scatter - // Note: Ignores MF2_RAILRING - else if (player->currentweapon == WEP_SCATTER && player->powers[pw_scatterring]) - { - fixed_t oldz = player->mo->z; - angle_t shotangle = player->mo->angle; - angle_t oldaiming = player->aiming; + mo = P_SpawnPlayerMissile(player->mo, MT_THROWNGRENADE, MF2_EXPLOSION); - if (player->health <= 1) - return; - P_SetWeaponDelay(player, (2*TICRATE)/3); + if (mo) + { + //P_InstaThrust(mo, player->mo->angle, FixedMul(mo->info->speed, player->mo->scale)); + mo->fuse = mo->info->reactiontime; + } + } + // Scatter + // Note: Ignores MF2_RAILRING + else if (player->currentweapon == WEP_SCATTER && player->powers[pw_scatterring]) + { + fixed_t oldz = player->mo->z; + angle_t shotangle = player->mo->angle; + angle_t oldaiming = player->aiming; - // Center - mo = P_SpawnPlayerMissile(player->mo, MT_THROWNSCATTER, MF2_SCATTER); - if (mo) - shotangle = R_PointToAngle2(player->mo->x, player->mo->y, mo->x, mo->y); + TAKE_AMMO(player, pw_scatterring); + P_SetWeaponDelay(player, (2*TICRATE)/3); - // Left - mo = P_SPMAngle(player->mo, MT_THROWNSCATTER, shotangle-ANG2, true, MF2_SCATTER); + // Center + mo = P_SpawnPlayerMissile(player->mo, MT_THROWNSCATTER, MF2_SCATTER); + if (mo) + shotangle = R_PointToAngle2(player->mo->x, player->mo->y, mo->x, mo->y); - // Right - mo = P_SPMAngle(player->mo, MT_THROWNSCATTER, shotangle+ANG2, true, MF2_SCATTER); + // Left + mo = P_SPMAngle(player->mo, MT_THROWNSCATTER, shotangle-ANG2, true, MF2_SCATTER); - // Down - player->mo->z += FixedMul(12*FRACUNIT, player->mo->scale); - player->aiming += ANG1; - mo = P_SPMAngle(player->mo, MT_THROWNSCATTER, shotangle, true, MF2_SCATTER); + // Right + mo = P_SPMAngle(player->mo, MT_THROWNSCATTER, shotangle+ANG2, true, MF2_SCATTER); - // Up - player->mo->z -= FixedMul(24*FRACUNIT, player->mo->scale); - player->aiming -= ANG2; - mo = P_SPMAngle(player->mo, MT_THROWNSCATTER, shotangle, true, MF2_SCATTER); + // Down + player->mo->z += FixedMul(12*FRACUNIT, player->mo->scale); + player->aiming += ANG1; + mo = P_SPMAngle(player->mo, MT_THROWNSCATTER, shotangle, true, MF2_SCATTER); - player->mo->z = oldz; - player->aiming = oldaiming; + // Up + player->mo->z -= FixedMul(24*FRACUNIT, player->mo->scale); + player->aiming -= ANG2; + mo = P_SPMAngle(player->mo, MT_THROWNSCATTER, shotangle, true, MF2_SCATTER); - player->powers[pw_scatterring]--; - player->mo->health--; - player->health--; - return; - } - // No powers, just a regular ring. - else - { + player->mo->z = oldz; + player->aiming = oldaiming; + return; + } + // No powers, just a regular ring. + else + { firenormal: - // Infinity ring was selected. - // Mystic wants this ONLY to happen specifically if it's selected, - // and to not be able to get around it EITHER WAY with firenormal. + // Infinity ring was selected. + // Mystic wants this ONLY to happen specifically if it's selected, + // and to not be able to get around it EITHER WAY with firenormal. - // Infinity Ring - if (player->currentweapon == 0 - && player->powers[pw_infinityring]) - { - P_SetWeaponDelay(player, TICRATE/4); + // Infinity Ring + if (player->currentweapon == 0 + && player->powers[pw_infinityring]) + { + P_SetWeaponDelay(player, TICRATE/4); - mo = P_SpawnPlayerMissile(player->mo, MT_THROWNINFINITY, 0); + mo = P_SpawnPlayerMissile(player->mo, MT_THROWNINFINITY, 0); - player->powers[pw_infinityring]--; - } - // Red Ring - else - { - if (player->health <= 1) - return; - P_SetWeaponDelay(player, TICRATE/4); + player->powers[pw_infinityring]--; + } + // Red Ring + else + { + if (player->rings <= 0) + return; + P_SetWeaponDelay(player, TICRATE/4); - mo = P_SpawnPlayerMissile(player->mo, MT_REDRING, 0); + mo = P_SpawnPlayerMissile(player->mo, MT_REDRING, 0); - if (mo) - P_ColorTeamMissile(mo, player); + if (mo) + P_ColorTeamMissile(mo, player); - player->mo->health--; - player->health--; - } - } + player->rings--; + } + } - if (mo) + #undef TAKE_AMMO + + if (mo) + { + if (mo->flags & MF_MISSILE && mo->flags2 & MF2_RAILRING) + { + const boolean nblockmap = !(mo->flags & MF_NOBLOCKMAP); + for (i = 0; i < 256; i++) { - if (mo->flags & MF_MISSILE && mo->flags2 & MF2_RAILRING) + if (nblockmap) { - const boolean nblockmap = !(mo->flags & MF_NOBLOCKMAP); - for (i = 0; i < 256; i++) - { - if (nblockmap) - { - P_UnsetThingPosition(mo); - mo->flags |= MF_NOBLOCKMAP; - P_SetThingPosition(mo); - } - - if (i&1) - P_SpawnMobj(mo->x, mo->y, mo->z, MT_SPARK); + P_UnsetThingPosition(mo); + mo->flags |= MF_NOBLOCKMAP; + P_SetThingPosition(mo); + } - if (P_RailThinker(mo)) - break; // mobj was removed (missile hit a wall) or couldn't move - } + if (i&1) + P_SpawnMobj(mo->x, mo->y, mo->z, MT_SPARK); - // Other rail sound plays at contact point. - S_StartSound(mo, sfx_rail2); - } + if (P_RailThinker(mo)) + break; // mobj was removed (missile hit a wall) or couldn't move } + + // Other rail sound plays at contact point. + S_StartSound(mo, sfx_rail2); } - return; } - - // Not holding any firing buttons anymore. - // Release the grenade / whatever. - player->pflags &= ~PF_ATTACKDOWN; } // @@ -3399,22 +3787,17 @@ static void P_DoSuperStuff(player_t *player) { mobj_t *spark; ticcmd_t *cmd = &player->cmd; - if (player->mo->state >= &states[S_PLAY_SUPERTRANS1] && player->mo->state <= &states[S_PLAY_SUPERTRANS9]) + if (player->mo->state >= &states[S_PLAY_SUPER_TRANS1] + && player->mo->state < &states[S_PLAY_SUPER_TRANS6]) return; // don't do anything right now, we're in the middle of transforming! - if (player->pflags & PF_NIGHTSMODE) + if (player->powers[pw_carry] == CR_NIGHTSMODE) return; // NiGHTS Super doesn't mix with normal super - // Does player have all emeralds? If so, flag the "Ready For Super!" - if ((ALL7EMERALDS(emeralds) || ALL7EMERALDS(player->powers[pw_emeralds])) && player->health > 50) - player->pflags |= PF_SUPERREADY; - else - player->pflags &= ~PF_SUPERREADY; - if (player->powers[pw_super]) { // If you're super and not Sonic, de-superize! - if (!((ALL7EMERALDS(emeralds)) && (player->charflags & SF_SUPER)) && !(ALL7EMERALDS(player->powers[pw_emeralds]))) + if (!(ALL7EMERALDS(emeralds) && player->charflags & SF_SUPER)) { player->powers[pw_super] = 0; P_SetPlayerMobjState(player->mo, S_PLAY_STND); @@ -3422,7 +3805,7 @@ static void P_DoSuperStuff(player_t *player) P_SpawnShieldOrb(player); // Restore color - if (player->powers[pw_shield] & SH_FIREFLOWER) + if ((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) { player->mo->color = SKINCOLOR_WHITE; G_GhostAddColor(GHC_FIREFLOWER); @@ -3442,23 +3825,20 @@ static void P_DoSuperStuff(player_t *player) return; } + player->mo->color = (player->pflags & PF_GODMODE && cv_debug == 0) + ? (SKINCOLOR_SUPERSILVER1 + 5*(((signed)leveltime >> 1) % 7)) // A wholesome easter egg. + : skins[player->skin].supercolor + abs( ( (player->powers[pw_super] >> 1) % 9) - 4); // This is where super flashing is handled. + + G_GhostAddColor(GHC_SUPER); + + if (player->mo->state == &states[S_PLAY_SUPER_TRANS6]) // stop here for now + return; + // Deplete one ring every second while super if ((leveltime % TICRATE == 0) && !(player->exiting)) - { - player->health--; - player->mo->health--; - } + player->rings--; - // future todo: a skin option for this, and possibly more colors - switch (player->skin) - { - case 1: /* Tails */ player->mo->color = SKINCOLOR_TSUPER1; break; - case 2: /* Knux */ player->mo->color = SKINCOLOR_KSUPER1; break; - default: /* everyone */ player->mo->color = SKINCOLOR_SUPER1; break; - } - player->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); - - if ((cmd->forwardmove != 0 || cmd->sidemove != 0 || player->pflags & (PF_CARRIED|PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN)) + if ((cmd->forwardmove != 0 || cmd->sidemove != 0 || player->powers[pw_carry]) && !(leveltime % TICRATE) && (player->mo->momx || player->mo->momy)) { spark = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SUPERSPARK); @@ -3466,10 +3846,8 @@ static void P_DoSuperStuff(player_t *player) P_SetScale(spark, player->mo->scale); } - G_GhostAddColor(GHC_SUPER); - // Ran out of rings while super! - if (player->health <= 1 || player->exiting) + if (player->rings <= 0 || player->exiting) { player->powers[pw_emeralds] = 0; // lost the power stones P_SpawnGhostMobj(player->mo); @@ -3477,7 +3855,7 @@ static void P_DoSuperStuff(player_t *player) player->powers[pw_super] = 0; // Restore color - if (player->powers[pw_shield] & SH_FIREFLOWER) + if ((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) { player->mo->color = SKINCOLOR_WHITE; G_GhostAddColor(GHC_FIREFLOWER); @@ -3491,23 +3869,8 @@ static void P_DoSuperStuff(player_t *player) if (gametype != GT_COOP) player->powers[pw_flashing] = flashingtics-1; - if (player->mo->health > 0) - { - if ((player->pflags & PF_JUMPED) || (player->pflags & PF_SPINNING)) - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); - else if (player->panim == PA_RUN) - P_SetPlayerMobjState(player->mo, S_PLAY_SPD1); - else if (player->panim == PA_WALK) - P_SetPlayerMobjState(player->mo, S_PLAY_RUN1); - else - P_SetPlayerMobjState(player->mo, S_PLAY_STND); - - if (!player->exiting) - { - player->health = 1; - player->mo->health = 1; - } - } + if ((player->mo->health > 0) && (player->mo->sprite2 & FF_SPR2SUPER)) + P_SetPlayerMobjState(player->mo, player->mo->state-states); // Inform the netgame that the champion has fallen in the heat of battle. if (gametype != GT_COOP) @@ -3534,12 +3897,15 @@ static void P_DoSuperStuff(player_t *player) // boolean P_SuperReady(player_t *player) { - if ((player->pflags & PF_SUPERREADY) && !player->powers[pw_super] && !player->powers[pw_tailsfly] - && !(player->powers[pw_shield] & SH_NOSTACK) + if (!player->powers[pw_super] && !player->powers[pw_invulnerability] - && !(maptol & TOL_NIGHTS) // don't turn 'regular super' in nights levels - && player->pflags & PF_JUMPED - && ((player->charflags & SF_SUPER) || ALL7EMERALDS(player->powers[pw_emeralds]))) + && !player->powers[pw_tailsfly] + && (player->charflags & SF_SUPER) + && (player->pflags & PF_JUMPED) + && !(player->powers[pw_shield] & SH_NOSTACK) + && !(maptol & TOL_NIGHTS) + && ALL7EMERALDS(emeralds) + && (player->rings >= 50)) return true; return false; @@ -3571,7 +3937,7 @@ void P_DoJump(player_t *player, boolean soundandstate) else player->mo->momz = 15*(FRACUNIT/4); - player->mo->angle = player->mo->angle - ANGLE_180; // Turn around from the wall you were climbing. + player->drawangle = player->mo->angle = player->mo->angle - ANGLE_180; // Turn around from the wall you were climbing. if (!demoplayback || P_AnalogMove(player)) { @@ -3595,28 +3961,30 @@ void P_DoJump(player_t *player, boolean soundandstate) else if (player->mo->momz < 0) // still descending? player->mo->momz = (39*(FRACUNIT/4))>>1; // just default to the jump height. } - else if (!(player->pflags & PF_JUMPED)) // Spin Attack + else if (!(player->pflags & PF_JUMPED)) // Jump { if (player->mo->ceilingz-player->mo->floorz <= player->mo->height-1) return; // Jump this high. - if (player->pflags & PF_CARRIED) + if (player->powers[pw_carry] == CR_PLAYER) { player->mo->momz = 9*FRACUNIT; - player->pflags &= ~PF_CARRIED; + player->powers[pw_carry] = CR_NONE; + P_SetTarget(&player->mo->tracer, NULL); if (player-players == consoleplayer && botingame) CV_SetValue(&cv_analog2, true); } - else if (player->pflags & PF_ITEMHANG) + else if (player->powers[pw_carry] == CR_GENERIC) { player->mo->momz = 9*FRACUNIT; - player->pflags &= ~PF_ITEMHANG; + player->powers[pw_carry] = CR_NONE; + P_SetTarget(&player->mo->tracer, NULL); } - else if (player->pflags & PF_ROPEHANG) + else if (player->powers[pw_carry] == CR_ROPEHANG) { player->mo->momz = 12*FRACUNIT; - player->pflags &= ~PF_ROPEHANG; + player->powers[pw_carry] = CR_NONE; P_SetTarget(&player->mo->tracer, NULL); } else if (player->mo->eflags & MFE_GOOWATER) @@ -3624,50 +3992,33 @@ void P_DoJump(player_t *player, boolean soundandstate) player->mo->momz = 7*FRACUNIT; if (player->charability == CA_JUMPBOOST && onground) { - if (player->charability2 == CA2_MULTIABILITY) + if (player->charflags & SF_MULTIABILITY) player->mo->momz += FixedMul(FRACUNIT/4, dist6); else player->mo->momz += FixedMul(FRACUNIT/8, dist6); } } else if (maptol & TOL_NIGHTS) - player->mo->momz = 24*FRACUNIT; + player->mo->momz = 18*FRACUNIT; else if (player->powers[pw_super]) { - if (player->charability == CA_FLOAT) - player->mo->momz = 28*FRACUNIT; //Obscene jump height anyone? - else if (player->charability == CA_SLOWFALL) - player->mo->momz = 37*(FRACUNIT/2); //Less obscene because during super, floating propells oneself upward. - else // Default super jump momentum. - player->mo->momz = 13*FRACUNIT; + player->mo->momz = 13*FRACUNIT; // Add a boost for super characters with float/slowfall and multiability. - if (player->charability2 == CA2_MULTIABILITY && - (player->charability == CA_FLOAT || player->charability == CA_SLOWFALL)) - player->mo->momz += 2*FRACUNIT; - else if (player->charability == CA_JUMPBOOST) + if (player->charability == CA_JUMPBOOST) { - if (player->charability2 == CA2_MULTIABILITY) + if (player->charflags & SF_MULTIABILITY) player->mo->momz += FixedMul(FRACUNIT/4, dist6); else player->mo->momz += FixedMul(FRACUNIT/8, dist6); } } - else if (player->charability2 == CA2_MULTIABILITY && - (player->charability == CA_DOUBLEJUMP || player->charability == CA_FLOAT || player->charability == CA_SLOWFALL)) - { - // Multiability exceptions, since some abilities cannot effectively use it and need a boost. - if (player->charability == CA_DOUBLEJUMP) - player->mo->momz = 23*(FRACUNIT/2); // Increased jump height instead of infinite jumps. - else if (player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) - player->mo->momz = 12*FRACUNIT; // Increased jump height due to ineffective repeat. - } else { player->mo->momz = 39*(FRACUNIT/4); // Default jump momentum. if (player->charability == CA_JUMPBOOST && onground) { - if (player->charability2 == CA2_MULTIABILITY) + if (player->charflags & SF_MULTIABILITY) player->mo->momz += FixedMul(FRACUNIT/4, dist6); else player->mo->momz += FixedMul(FRACUNIT/8, dist6); @@ -3678,7 +4029,7 @@ void P_DoJump(player_t *player, boolean soundandstate) if (player->mo->eflags & MFE_UNDERWATER) player->mo->momz = FixedMul(player->mo->momz, FixedDiv(117*FRACUNIT, 200*FRACUNIT)); - player->jumping = 1; + player->pflags |= PF_STARTJUMP; } factor = player->jumpfactor; @@ -3686,6 +4037,12 @@ void P_DoJump(player_t *player, boolean soundandstate) if (twodlevel || (player->mo->flags2 & MF2_TWOD)) factor += player->jumpfactor / 10; + if (player->charflags & SF_MULTIABILITY && player->charability == CA_DOUBLEJUMP) + factor -= max(0, player->secondjump * player->jumpfactor / ((player->actionspd >> FRACBITS) + 1)); // Reduce the jump height each time + + //if (maptol & TOL_NIGHTS) + // factor = player->jumpfactor; // all skins jump the same. if you nerf jumping abilities, you may want this. + P_SetObjectMomZ(player->mo, FixedMul(factor, player->mo->momz), false); // Custom height // set just an eensy above the ground @@ -3707,27 +4064,54 @@ void P_DoJump(player_t *player, boolean soundandstate) } player->mo->eflags &= ~MFE_APPLYPMOMZ; - player->pflags |= PF_JUMPED; + player->pflags |= P_GetJumpFlags(player);; if (soundandstate) { if (!player->spectator) S_StartSound(player->mo, sfx_jump); // Play jump sound! - if (!(player->charability2 == CA2_SPINDASH)) - P_SetPlayerMobjState(player->mo, S_PLAY_SPRING); - else - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + } +} + +static void P_DoSpinDashDust(player_t *player) +{ + UINT32 i; + mobj_t *particle; + INT32 prandom[3]; + for (i = 0; i <= (leveltime%7)/2; i++) { // 1, 2, 3 or 4 particles + particle = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_SPINDUST); + + if (player->mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) // overrides fire version + P_SetMobjState(particle, S_SPINDUST_BUBBLE1); + else if (player->powers[pw_shield] == SH_ELEMENTAL) + P_SetMobjState(particle, S_SPINDUST_FIRE1); + + P_SetTarget(&particle->target, player->mo); + particle->destscale = (2*player->mo->scale)/3; + P_SetScale(particle, particle->destscale); + if (player->mo->eflags & MFE_VERTICALFLIP) // readjust z position if needed + particle->z = player->mo->z + player->mo->height - particle->height; + prandom[0] = P_RandomFixed()<<2; // P_RandomByte()<<10 + prandom[1] = P_RandomRange(-30, 30); // P_RandomRange(-ANG30/FRACUNIT, ANG30/FRACUNIT)*FRACUNIT + prandom[2] = P_RandomFixed()<<3; // P_RandomByte()<<11 + P_SetObjectMomZ(particle, player->dashspeed/50 + prandom[0], false); + P_InstaThrust(particle, + player->drawangle + (prandom[1]*ANG1), + -FixedMul(player->dashspeed/12 + FRACUNIT + prandom[2], player->mo->scale)); + P_TryMove(particle, particle->x+particle->momx, particle->y+particle->momy, true); } } // -// P_DoSpinDash +// P_DoSpinAbility // // Player spindash handling // -static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) +static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) { + boolean canstand = true; // can we stand on the ground? (mostly relevant for slopes) if (player->pflags & PF_STASIS) return; @@ -3739,64 +4123,194 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) } #endif - // Spinning and Spindashing - if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_SLIDING) && !player->exiting - && !P_PlayerInPain(player)) // subsequent revs - { - if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<<FRACBITS, player->mo->scale) && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING) #ifdef ESLOPE - && (!player->mo->standingslope || (player->mo->standingslope->flags & SL_NOPHYSICS) || abs(player->mo->standingslope->zdelta) < FRACUNIT/2) + canstand = (!player->mo->standingslope || (player->mo->standingslope->flags & SL_NOPHYSICS) || abs(player->mo->standingslope->zdelta) < FRACUNIT/2); #endif - ) - { - player->mo->momx = player->cmomx; - player->mo->momy = player->cmomy; - player->pflags |= PF_STARTDASH|PF_SPINNING; - player->dashspeed = FixedMul(FRACUNIT, player->mo->scale); - player->dashtime = 0; - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); - player->pflags |= PF_USEDOWN; - } - else if ((cmd->buttons & BT_USE) && (player->pflags & PF_STARTDASH)) + + /////////////////////////////// + // ability-specific behavior // + /////////////////////////////// + if (!(player->pflags & PF_SLIDING) && !player->exiting && !P_PlayerInPain(player)) + { + switch (player->charability2) { - player->dashspeed += FixedMul(FRACUNIT, player->mo->scale); + case CA2_SPINDASH: // Spinning and Spindashing + // Start revving + if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<<FRACBITS, player->mo->scale) + && !player->mo->momz && onground && !(player->pflags & (PF_USEDOWN|PF_SPINNING)) + && canstand) + { + player->mo->momx = player->cmomx; + player->mo->momy = player->cmomy; + player->pflags |= (PF_USEDOWN|PF_STARTDASH|PF_SPINNING); + player->dashspeed = player->mindash; + P_SetPlayerMobjState(player->mo, S_PLAY_SPINDASH); + if (!player->spectator) + S_StartSound(player->mo, sfx_s3kab); // Make the rev sound! Previously sfx_spndsh. + } + // Revving + else if ((cmd->buttons & BT_USE) && (player->pflags & PF_STARTDASH)) + { + if (player->dashspeed < player->maxdash) + { +#define chargecalculation (6*(player->dashspeed - player->mindash))/(player->maxdash - player->mindash) + fixed_t soundcalculation = chargecalculation; + player->dashspeed += FRACUNIT; + if (!player->spectator && soundcalculation != chargecalculation) + S_StartSound(player->mo, sfx_s3kab); // Make the rev sound! Previously sfx_spndsh. +#undef chargecalculation + } + if (player->revitem && !(leveltime % 5)) // Now spawn the color thok circle. + { + P_SpawnSpinMobj(player, player->revitem); + if (demorecording) + G_GhostAddRev(); + } + } - if (!(player->dashtime++ % 5)) - { - if (!player->spectator && player->dashspeed < FixedMul(player->maxdash, player->mo->scale)) - S_StartSound(player->mo, sfx_spndsh); // Make the rev sound! + // If not moving up or down, and travelling faster than a speed of five while not holding + // down the spin button and not spinning. + // AKA Just go into a spin on the ground, you idiot. ;) + else if ((cmd->buttons & BT_USE || ((twodlevel || (player->mo->flags2 & MF2_TWOD)) && cmd->forwardmove < -20)) + && !player->climbing && !player->mo->momz && onground && (player->speed > FixedMul(5<<FRACBITS, player->mo->scale) + || !canstand) && !(player->pflags & (PF_USEDOWN|PF_SPINNING))) + { + player->pflags |= (PF_USEDOWN|PF_SPINNING); + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + if (!player->spectator) + S_StartSound(player->mo, sfx_spin); + } + else + // Catapult the player from a spindash rev! + if (onground && !(player->pflags & PF_USEDOWN) && (player->pflags & PF_STARTDASH) && (player->pflags & PF_SPINNING)) + { + player->pflags &= ~PF_STARTDASH; + if (player->powers[pw_carry] == CR_BRAKGOOP) + player->dashspeed = 0; - // Now spawn the color thok circle. - P_SpawnSpinMobj(player, player->revitem); - if (demorecording) - G_GhostAddRev(); - } - } - // If not moving up or down, and travelling faster than a speed of four while not holding - // down the spin button and not spinning. - // AKA Just go into a spin on the ground, you idiot. ;) - else if ((cmd->buttons & BT_USE || ((twodlevel || (player->mo->flags2 & MF2_TWOD)) && cmd->forwardmove < -20)) - && !player->climbing && !player->mo->momz && onground && (player->speed > FixedMul(5<<FRACBITS, player->mo->scale) -#ifdef ESLOPE - || (player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2) + if (!((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE)) + { + if (player->dashspeed) + { + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + P_InstaThrust(player->mo, player->mo->angle, (player->speed = FixedMul(player->dashspeed, player->mo->scale))); // catapult forward ho!! + } + else + { + P_SetPlayerMobjState(player->mo, S_PLAY_STND); + player->pflags &= ~PF_SPINNING; + } + + if (!player->spectator) + S_StartSound(player->mo, sfx_zoom); + } + + player->dashspeed = 0; + } + break; + case CA2_GUNSLINGER: + if (!player->mo->momz && onground && !player->weapondelay && canstand) + { + if (player->speed > FixedMul(10<<FRACBITS, player->mo->scale)) + {} + else + { + mobj_t *lockon = P_LookForEnemies(player, false, true); + if (lockon) + { + if (P_IsLocalPlayer(player)) // Only display it on your own view. + { + mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker + visual->target = lockon; + } + } + if ((cmd->buttons & BT_USE) && !(player->pflags & PF_USEDOWN)) + { + mobj_t *bullet; + + P_SetPlayerMobjState(player->mo, S_PLAY_FIRE); + +#define zpos(posmo) (posmo->z + (posmo->height - mobjinfo[player->revitem].height)/2) + if (lockon) + { + player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockon->x, lockon->y); + bullet = P_SpawnPointMissile(player->mo, lockon->x, lockon->y, zpos(lockon), player->revitem, player->mo->x, player->mo->y, zpos(player->mo)); + if (!demoplayback || P_AnalogMove(player)) + { + if (player == &players[consoleplayer]) + localangle = player->mo->angle; + else if (player == &players[secondarydisplayplayer]) + localangle2 = player->mo->angle; + } + } + else + { + bullet = P_SpawnPointMissile(player->mo, player->mo->x + P_ReturnThrustX(NULL, player->mo->angle, FRACUNIT), player->mo->y + P_ReturnThrustY(NULL, player->mo->angle, FRACUNIT), zpos(player->mo), player->revitem, player->mo->x, player->mo->y, zpos(player->mo)); + if (bullet) + { + bullet->flags &= ~MF_NOGRAVITY; + bullet->momx >>= 1; + bullet->momy >>= 1; + } + } + player->drawangle = player->mo->angle; +#undef zpos + + P_SetTarget(&player->mo->tracer, NULL); + player->mo->momx >>= 1; + player->mo->momy >>= 1; + player->pflags |= PF_USEDOWN; + P_SetWeaponDelay(player, TICRATE/2); + } + } + } + break; + case CA2_MELEE: // Melee attack + if (player->panim != PA_ABILITY2 && (cmd->buttons & BT_USE) + && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) + && canstand) + { + P_ResetPlayer(player); + player->pflags |= PF_THOKKED; +#if 0 + if ((player->charability == CA_TWINSPIN) && (player->speed > FixedMul(player->runspeed, player->mo->scale))) + { + P_DoJump(player, false); + player->pflags &= ~PF_STARTJUMP; + player->mo->momz = FixedMul(player->mo->momz, 3*FRACUNIT/2); // NOT 1.5 times the jump height, but 2.25 times. + P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN); + S_StartSound(player->mo, sfx_s3k8b); + } + else #endif - ) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)) - { - player->pflags |= PF_SPINNING; - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); - if (!player->spectator) - S_StartSound(player->mo, sfx_spin); - player->pflags |= PF_USEDOWN; + { + player->mo->z += P_MobjFlip(player->mo); + P_SetObjectMomZ(player->mo, player->mindash, false); + if (player->mo->eflags & MFE_UNDERWATER) + player->mo->momz >>= 1; + if (FixedMul(player->speed, FINECOSINE(((player->mo->angle - R_PointToAngle2(0, 0, player->rmomx, player->rmomy)) >> ANGLETOFINESHIFT) & FINEMASK)) < FixedMul(player->maxdash, player->mo->scale)) + { + player->drawangle = player->mo->angle; + P_InstaThrust(player->mo, player->mo->angle, FixedMul(player->maxdash, player->mo->scale)); + } + player->mo->momx += player->cmomx; + player->mo->momy += player->cmomy; + P_SetPlayerMobjState(player->mo, S_PLAY_MELEE); + S_StartSound(player->mo, sfx_s3k42); + } + player->pflags |= PF_USEDOWN; + } + break; } } + /////////////////////////////// + // general spinning behavior // + /////////////////////////////// + // Rolling normally if (onground && player->pflags & PF_SPINNING && !(player->pflags & PF_STARTDASH) - && player->speed < FixedMul(5*FRACUNIT,player->mo->scale) -#ifdef ESLOPE - && (!player->mo->standingslope || (player->mo->standingslope->flags & SL_NOPHYSICS) || abs(player->mo->standingslope->zdelta) < FRACUNIT/2) -#endif - ) + && player->speed < FixedMul(5*FRACUNIT,player->mo->scale) && canstand) { if (GETSECSPECIAL(player->mo->subsector->sector->special, 4) == 7 || (player->mo->ceilingz - player->mo->floorz < P_GetPlayerHeight(player))) P_InstaThrust(player->mo, player->mo->angle, FixedMul(10*FRACUNIT, player->mo->scale)); @@ -3810,24 +4324,12 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) } } - // Catapult the player from a spindash rev! - if (onground && !(player->pflags & PF_USEDOWN) && player->dashspeed && (player->pflags & PF_STARTDASH) && (player->pflags & PF_SPINNING)) + if (onground && player->pflags & PF_STARTDASH) { - if (player->powers[pw_ingoop]) - player->dashspeed = 0; - - player->pflags &= ~PF_STARTDASH; - if (!((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE)) - { - P_InstaThrust(player->mo, player->mo->angle, player->dashspeed); // catapult forward ho!! - if (!player->spectator) - S_StartSound(player->mo, sfx_zoom); - } - player->dashspeed = 0; + // Spawn spin dash dust + if (!(player->charflags & SF_NOSPINDASHDUST) && !(player->mo->eflags & MFE_GOOWATER)) + P_DoSpinDashDust(player); } - - if (onground && (player->pflags & PF_SPINNING) && !(player->panim == PA_ROLL)) - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); } // @@ -3837,18 +4339,87 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) // void P_DoJumpShield(player_t *player) { + boolean electric = ((player->powers[pw_shield] & SH_PROTECTELECTRIC) == SH_PROTECTELECTRIC); + if (player->pflags & PF_THOKKED) return; player->pflags &= ~PF_JUMPED; P_DoJump(player, false); - player->pflags &= ~PF_JUMPED; player->secondjump = 0; - player->jumping = 0; + player->pflags |= PF_THOKKED|PF_SHIELDABILITY; + player->pflags &= ~(PF_STARTJUMP|PF_SPINNING|PF_BOUNCING); + if (electric) + { + mobj_t *spark; + INT32 i; +#define numangles 6 +#define limitangle (360/numangles) + const angle_t travelangle = player->mo->angle + P_RandomRange(-limitangle, limitangle)*ANG1; + for (i = 0; i < numangles; i++) + { + spark = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_THUNDERCOIN_SPARK); + P_InstaThrust(spark, travelangle + i*(ANGLE_MAX/numangles), FixedMul(4*FRACUNIT, spark->scale)); + if (i % 2) + P_SetObjectMomZ(spark, -4*FRACUNIT, false); + } +#undef limitangle +#undef numangles + S_StartSound(player->mo, sfx_s3k45); + } + else + { + player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE); + P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + S_StartSound(player->mo, sfx_wdjump); + } +} + +// +// P_DoBubbleBounce +// +// Bubblewrap shield landing handling +// +void P_DoBubbleBounce(player_t *player) +{ + player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_SHIELDABILITY); + S_StartSound(player->mo, sfx_s3k44); + P_MobjCheckWater(player->mo); + P_DoJump(player, false); + if (player->charflags & SF_NOJUMPSPIN) + P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + else + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); player->pflags |= PF_THOKKED; - player->pflags &= ~PF_SPINNING; - P_SetPlayerMobjState(player->mo, S_PLAY_FALL1); - S_StartSound(player->mo, sfx_wdjump); + player->pflags &= ~PF_STARTJUMP; + player->secondjump = UINT8_MAX; + player->mo->momz = FixedMul(player->mo->momz, 5*FRACUNIT/4); +} + +// +// P_DoAbilityBounce +// +// CA_BOUNCE landing handling +// +void P_DoAbilityBounce(player_t *player, boolean changemomz) +{ + fixed_t prevmomz; + if (player->mo->state-states == S_PLAY_BOUNCE_LANDING) + return; + if (changemomz) + { + prevmomz = player->mo->momz; + if (P_MobjFlip(player->mo)*prevmomz < 0) + prevmomz = 0; + else if (player->mo->eflags & MFE_UNDERWATER) + prevmomz /= 2; + P_DoJump(player, false); + player->pflags &= ~(PF_STARTJUMP|PF_JUMPED); + player->mo->momz = (FixedMul(player->mo->momz, 3*FRACUNIT/2) + prevmomz)/2; + } + S_StartSound(player->mo, sfx_boingf); + P_SetPlayerMobjState(player->mo, S_PLAY_BOUNCE_LANDING); + player->pflags |= PF_BOUNCING|PF_THOKKED; } // @@ -3910,15 +4481,30 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range) // static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) { + mobj_t *lockon = NULL; + if (player->pflags & PF_JUMPSTASIS) return; + if ((player->charability == CA_HOMINGTHOK) && !player->homing && (player->pflags & PF_JUMPED) && (!(player->pflags & PF_THOKKED) || (player->charflags & SF_MULTIABILITY)) && (lockon = P_LookForEnemies(player, true, false))) + { + if (P_IsLocalPlayer(player)) // Only display it on your own view. + { + mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker + visual->target = lockon; + } + } + if (cmd->buttons & BT_USE && !(player->pflags & PF_JUMPDOWN) && !player->exiting && !P_PlayerInPain(player)) { - if (onground || player->climbing || player->pflags & (PF_CARRIED|PF_ITEMHANG|PF_ROPEHANG)) + if (player->mo->tracer && player->powers[pw_carry] == CR_MACESPIN) {} - else if (player->pflags & PF_MACESPIN && player->mo->tracer) + else if (onground || player->climbing || (player->mo->tracer && player->powers[pw_carry])) {} + else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND + && !(player->pflags & PF_JUMPED) + && !(player->pflags & PF_USEDOWN)) + P_DoJumpShield(player); else if (!(player->pflags & PF_SLIDING) && ((gametype != GT_CTF) || (!player->gotflag))) { #ifdef HAVE_BLUA @@ -3929,7 +4515,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) case CA_TELEKINESIS: if (player->pflags & PF_JUMPED) { - if (!(player->pflags & PF_THOKKED) || (player->charability2 == CA2_MULTIABILITY)) + if (!(player->pflags & PF_THOKKED) || (player->charflags & SF_MULTIABILITY)) { P_Telekinesis(player, -FixedMul(player->actionspd, player->mo->scale), // -ve thrust (pulling towards player) @@ -3969,6 +4555,8 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) P_InstaThrust(player->mo, player->mo->angle, FixedMul(player->normalspeed, player->mo->scale)*(80-player->flyangle - (player->actionspd>>FRACBITS)/2)/80); else P_InstaThrust(player->mo, player->mo->angle, ((FixedMul(player->normalspeed - player->actionspd/4, player->mo->scale))*2)/3); + + player->drawangle = player->mo->angle; } } } @@ -3990,27 +4578,28 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->secondjump = 0; player->pflags &= ~PF_THOKKED; } + else if (player->powers[pw_carry] == CR_MACESPIN && player->mo->tracer) + { + player->powers[pw_carry] = CR_NONE; + P_SetTarget(&player->mo->tracer, NULL); + player->powers[pw_flashing] = TICRATE/4; + } else // can't jump while in air, can't jump while jumping - if (onground || player->climbing || player->pflags & (PF_CARRIED|PF_ITEMHANG|PF_ROPEHANG)) + if (onground || player->climbing || player->powers[pw_carry]) { P_DoJump(player, true); player->secondjump = 0; player->pflags &= ~PF_THOKKED; } - else if (player->pflags & PF_MACESPIN && player->mo->tracer) - { - player->pflags &= ~PF_MACESPIN; - player->powers[pw_flashing] = TICRATE/4; - } else if (player->pflags & PF_SLIDING || (gametype == GT_CTF && player->gotflag)) ; - else if (P_SuperReady(player)) + /*else if (P_SuperReady(player)) { // If you can turn super and aren't already, // and you don't have a shield, do it! P_DoSuperTransformation(player, false); - } + }*/ else if (player->pflags & PF_JUMPED) { #ifdef HAVE_BLUA @@ -4023,18 +4612,25 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) case CA_JUMPTHOK: // Credit goes to CZ64 and Sryder13 for the original // Now it's Sonic's abilities turn! // THOK! - if (!(player->pflags & PF_THOKKED) || (player->charability2 == CA2_MULTIABILITY)) + if (!(player->pflags & PF_THOKKED) || (player->charflags & SF_MULTIABILITY)) { // Catapult the player fixed_t actionspd = player->actionspd; + + if (player->charflags & SF_DASHMODE) + actionspd = max(player->normalspeed, FixedDiv(player->speed, player->mo->scale)); + if (player->mo->eflags & MFE_UNDERWATER) actionspd >>= 1; + if ((player->charability == CA_JUMPTHOK) && !(player->pflags & PF_THOKKED)) { player->pflags &= ~PF_JUMPED; P_DoJump(player, false); } + P_InstaThrust(player->mo, player->mo->angle, FixedMul(actionspd, player->mo->scale)); + player->drawangle = player->mo->angle; if (maptol & TOL_2D) { @@ -4047,82 +4643,90 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->mo->momy /= 3; } - if (player->mo->info->attacksound && !player->spectator) - S_StartSound(player->mo, player->mo->info->attacksound); // Play the THOK sound - - P_SpawnThokMobj(player); - - if (player->charability == CA_HOMINGTHOK && !player->homing) + if (player->charability == CA_HOMINGTHOK) { - if (P_LookForEnemies(player)) + P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, lockon)); + if (lockon) { - if (player->mo->tracer) - player->homing = 3*TICRATE; + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockon->x, lockon->y); + player->homing = 3*TICRATE; + } + else + { + P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + player->pflags &= ~PF_JUMPED; + player->mo->height = P_GetPlayerHeight(player); } + player->pflags &= ~PF_NOJUMPDAMAGE; } + if (player->mo->info->attacksound && !player->spectator) + S_StartSound(player->mo, player->mo->info->attacksound); // Play the THOK sound + + P_SpawnThokMobj(player); + player->pflags &= ~(PF_SPINNING|PF_STARTDASH); player->pflags |= PF_THOKKED; } break; case CA_FLY: - case CA_SWIM: // Swim + case CA_SWIM: // If currently in the air from a jump, and you pressed the // button again and have the ability to fly, do so! if (player->charability == CA_SWIM && !(player->mo->eflags & MFE_UNDERWATER)) ; // Can't do anything if you're a fish out of water! else if (!(player->pflags & PF_THOKKED) && !(player->powers[pw_tailsfly])) { - P_SetPlayerMobjState(player->mo, S_PLAY_ABL1); // Change to the flying animation + P_SetPlayerMobjState(player->mo, S_PLAY_FLY); // Change to the flying animation player->powers[pw_tailsfly] = tailsflytics + 1; // Set the fly timer - player->pflags &= ~(PF_JUMPED|PF_SPINNING|PF_STARTDASH); - player->pflags |= PF_THOKKED; + player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_STARTDASH); + player->pflags |= (PF_THOKKED|PF_CANCARRY); } break; case CA_GLIDEANDCLIMB: // Now Knuckles-type abilities are checked. - // If you can turn super and aren't already, - // and you don't have a shield, do it! - if (!(player->pflags & PF_THOKKED) || player->charability2 == CA2_MULTIABILITY) + if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY) { INT32 glidespeed = player->actionspd; player->pflags |= PF_GLIDING|PF_THOKKED; player->glidetime = 0; - if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - { - // Glide at double speed while super. - glidespeed *= 2; - player->pflags &= ~PF_THOKKED; - } - - P_SetPlayerMobjState(player->mo, S_PLAY_ABL1); + P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE); P_InstaThrust(player->mo, player->mo->angle, FixedMul(glidespeed, player->mo->scale)); player->pflags &= ~(PF_SPINNING|PF_STARTDASH); } break; case CA_DOUBLEJUMP: // Double-Jump - if (!(player->pflags & PF_THOKKED)) + if (!(player->pflags & PF_THOKKED) || ((player->charflags & SF_MULTIABILITY) && (player->secondjump < (player->actionspd >> FRACBITS)))) { + player->pflags |= PF_THOKKED; player->pflags &= ~PF_JUMPED; P_DoJump(player, true); - - // Allow infinite double jumping if super. - if (!player->powers[pw_super]) - player->pflags |= PF_THOKKED; + player->secondjump++; } break; case CA_FLOAT: // Float case CA_SLOWFALL: // Slow descent hover - if (!player->secondjump) + if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY) + { + if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE) + P_SetPlayerMobjState(player->mo, S_PLAY_DASH); + else if (player->speed >= FixedMul(player->runspeed, player->mo->scale)) + P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT_RUN); + else + P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT); + player->pflags |= PF_THOKKED; + player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING); player->secondjump = 1; + } break; case CA_TELEKINESIS: - if (!(player->pflags & PF_THOKKED) || player->charability2 == CA2_MULTIABILITY) + if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY) { P_Telekinesis(player, FixedMul(player->actionspd, player->mo->scale), // +ve thrust (pushing away from player) @@ -4130,22 +4734,41 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) } break; case CA_FALLSWITCH: - if (!(player->pflags & PF_THOKKED) || player->charability2 == CA2_MULTIABILITY) + if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY) { player->mo->momz = -player->mo->momz; P_SpawnThokMobj(player); player->pflags |= PF_THOKKED; } break; - case CA_AIRDRILL: - if (!(player->pflags & PF_THOKKED) || player->charability2 == CA2_MULTIABILITY) + if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY) { player->flyangle = 56 + (60-(player->actionspd>>FRACBITS))/3; player->pflags |= PF_THOKKED; S_StartSound(player->mo, sfx_spndsh); } break; + case CA_BOUNCE: + if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY) + { + P_SetPlayerMobjState(player->mo, S_PLAY_BOUNCE); + player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE); + player->pflags |= PF_THOKKED|PF_BOUNCING; + player->mo->momx >>= 1; + player->mo->momy >>= 1; + player->mo->momz >>= 1; + } + break; + case CA_TWINSPIN: + if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY) + { + player->pflags |= PF_THOKKED; + S_StartSound(player->mo, sfx_s3k42); + player->mo->frame = 0; + P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN); + } + break; default: break; } @@ -4180,7 +4803,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) break; } } - else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_JUMP && !player->powers[pw_super]) + else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND && !player->powers[pw_super]) P_DoJumpShield(player); } @@ -4190,20 +4813,17 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) if ((gametype != GT_CTF || !player->gotflag) && !player->exiting) { - if (player->secondjump == 1) + if (player->secondjump == 1 && player->charability != CA_DOUBLEJUMP) { - if (player->charability == CA_FLOAT) - player->mo->momz = 0; - else if (player->charability == CA_SLOWFALL) - { - if (player->powers[pw_super]) - { - if (P_MobjFlip(player->mo)*player->mo->momz < gravity*16) - player->mo->momz = P_MobjFlip(player->mo)*gravity*16; //Float upward 4x as fast while super. - } - else if (P_MobjFlip(player->mo)*player->mo->momz < -gravity*4) - player->mo->momz = P_MobjFlip(player->mo)*-gravity*4; - } + fixed_t potentialmomz; + if (player->charability == CA_SLOWFALL) + potentialmomz = -gravity*4; + else + potentialmomz = ((player->speed < 10*player->mo->scale) + ? (player->speed - 10*player->mo->scale)/5 + : 0); + if (P_MobjFlip(player->mo)*player->mo->momz < potentialmomz) + player->mo->momz = P_MobjFlip(player->mo)*potentialmomz; player->pflags &= ~PF_SPINNING; } } @@ -4213,26 +4833,34 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->pflags &= ~PF_JUMPDOWN; // Repeat abilities, but not double jump! - if ((player->charability2 == CA2_MULTIABILITY && player->charability != CA_DOUBLEJUMP) - || (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) - player->secondjump = 0; - else if (player->charability == CA_FLOAT && player->secondjump == 1) - player->secondjump = 2; + if (player->secondjump == 1 && player->charability != CA_DOUBLEJUMP) + { + if (player->charflags & SF_MULTIABILITY) + { + player->pflags |= (PF_JUMPED|PF_NOJUMPDAMAGE); + player->secondjump = 0; + } + else + player->secondjump = 2; + P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + } // If letting go of the jump button while still on ascent, cut the jump height. - if (player->pflags & PF_JUMPED && P_MobjFlip(player->mo)*player->mo->momz > 0 && player->jumping == 1) + if (((player->pflags & (PF_JUMPED|PF_STARTJUMP)) == (PF_JUMPED|PF_STARTJUMP)) && (P_MobjFlip(player->mo)*player->mo->momz > 0)) { player->mo->momz >>= 1; - player->jumping = 0; + player->pflags &= ~PF_STARTJUMP; } } } +#if 0 boolean P_AnalogMove(player_t *player) { return player->pflags & PF_ANALOGMODE; } +#endif // // P_GetPlayerControlDirection @@ -4334,10 +4962,12 @@ static void P_2dMovement(player_t *player) else if (player->exiting) { player->pflags &= ~PF_GLIDING; - P_SetPlayerMobjState(player->mo, S_PLAY_RUN1); + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); player->skidtime = 0; } } + if (player->pflags & PF_BOUNCING) + player->pflags &= ~PF_BOUNCING; if (player->pflags & PF_SPINNING && !player->exiting) { player->pflags &= ~PF_SPINNING; @@ -4458,9 +5088,6 @@ static void P_2dMovement(player_t *player) if (cmd->forwardmove != 0) P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT,10*FRACUNIT), false); - if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - player->mo->momz *= 2; - player->mo->momx = 0; } else if (cmd->sidemove != 0 && !(player->pflags & PF_GLIDING || player->exiting @@ -4500,6 +5127,7 @@ static void P_3dMovement(player_t *player) angle_t dangle; // replaces old quadrants bits fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale); boolean analogmove = false; + boolean spin = ((onground = P_IsObjectOnGround(player->mo)) && player->pflags & PF_SPINNING && (player->rmomx || player->rmomy) && !(player->pflags & PF_STARTDASH)); fixed_t oldMagnitude, newMagnitude; #ifdef ESLOPE vector3_t totalthrust; @@ -4525,10 +5153,12 @@ static void P_3dMovement(player_t *player) else if (player->exiting) { player->pflags &= ~PF_GLIDING; - P_SetPlayerMobjState(player->mo, S_PLAY_RUN1); + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); player->skidtime = 0; } } + if (player->pflags & PF_BOUNCING) + player->pflags &= ~PF_BOUNCING; if (player->pflags & PF_SPINNING && !player->exiting) { player->pflags &= ~PF_SPINNING; @@ -4587,9 +5217,6 @@ static void P_3dMovement(player_t *player) if (player->pflags & PF_SLIDING) cmd->forwardmove = 0; - // Do not let the player control movement if not onground. - onground = P_IsObjectOnGround(player->mo); - player->aiming = cmd->aiming<<FRACBITS; // Set the player speeds. @@ -4647,22 +5274,43 @@ static void P_3dMovement(player_t *player) topspeed = normalspd; } + if (spin) // Prevent gaining speed whilst rolling! + { + const fixed_t ns = FixedDiv(549*ORIG_FRICTION,500*FRACUNIT); // P_XYFriction + topspeed = FixedMul(oldMagnitude, ns); + } + // Better maneuverability while flying - if(player->powers[pw_tailsfly]) + if (player->powers[pw_tailsfly]) { thrustfactor = player->thrustfactor*2; acceleration = player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration; } + else + { + if (player->pflags & PF_BOUNCING) + { + if (player->mo->state-states == S_PLAY_BOUNCE_LANDING) + { + thrustfactor = player->thrustfactor*8; + acceleration = player->accelstart/8 + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration/8; + } + else + { + thrustfactor = (3*player->thrustfactor)/4; + acceleration = player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration; + } + } + + if (player->mo->movefactor != FRACUNIT) // Friction-scaled acceleration... + acceleration = FixedMul(acceleration<<FRACBITS, player->mo->movefactor)>>FRACBITS; + } // Forward movement if (player->climbing) { if (cmd->forwardmove) - { P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 10*FRACUNIT), false); - if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - player->mo->momz *= 2; - } } else if (!analogmove && cmd->forwardmove != 0 && !(player->pflags & PF_GLIDING || player->exiting @@ -4670,20 +5318,20 @@ static void P_3dMovement(player_t *player) { movepushforward = cmd->forwardmove * (thrustfactor * acceleration); - // allow very small movement while in air for gameplay - if (!onground) - movepushforward >>= 2; // proper air movement - // Allow a bit of movement while spinning if (player->pflags & PF_SPINNING) { - if ((mforward && cmd->forwardmove > 0) || (mbackward && cmd->forwardmove < 0)) + if ((mforward && cmd->forwardmove > 0) || (mbackward && cmd->forwardmove < 0) + || (player->pflags & PF_STARTDASH)) movepushforward = 0; - else if (!(player->pflags & PF_STARTDASH)) - movepushforward = FixedDiv(movepushforward, 16*FRACUNIT); + else if (onground) + movepushforward >>= 4; else - movepushforward = 0; + movepushforward >>= 3; } + // allow very small movement while in air for gameplay + else if (!onground) + movepushforward >>= 2; // proper air movement movepushforward = FixedMul(movepushforward, player->mo->scale); @@ -4696,12 +5344,7 @@ static void P_3dMovement(player_t *player) } // Sideways movement if (player->climbing) - { - if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedMul(FixedDiv(cmd->sidemove*FRACUNIT, 5*FRACUNIT), player->mo->scale)); - else - P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedMul(FixedDiv(cmd->sidemove*FRACUNIT, 10*FRACUNIT), player->mo->scale)); - } + P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedMul(FixedDiv(cmd->sidemove*FRACUNIT, 10*FRACUNIT), player->mo->scale)); // Analog movement control else if (analogmove) { @@ -4716,22 +5359,20 @@ static void P_3dMovement(player_t *player) movepushforward = max(abs(cmd->sidemove), abs(cmd->forwardmove)) * (thrustfactor * acceleration); - // allow very small movement while in air for gameplay - if (!onground) - movepushforward >>= 2; // proper air movement - // Allow a bit of movement while spinning if (player->pflags & PF_SPINNING) { - // Stupid little movement prohibitor hack - // that REALLY shouldn't belong in analog code. - if ((mforward && cmd->forwardmove > 0) || (mbackward && cmd->forwardmove < 0)) + if ((mforward && cmd->forwardmove > 0) || (mbackward && cmd->forwardmove < 0) + || (player->pflags & PF_STARTDASH)) movepushforward = 0; - else if (!(player->pflags & PF_STARTDASH)) - movepushforward = FixedDiv(movepushforward, 16*FRACUNIT); + else if (onground) + movepushforward >>= 4; else - movepushforward = 0; + movepushforward >>= 3; } + // allow very small movement while in air for gameplay + else if (!onground) + movepushforward >>= 2; // proper air movement movepushsideangle = controldirection; @@ -4749,25 +5390,26 @@ static void P_3dMovement(player_t *player) { movepushside = cmd->sidemove * (thrustfactor * acceleration); + // allow very small movement while in air for gameplay if (!onground) { - movepushside >>= 2; - + movepushside >>= 2; // proper air movement // Reduce movepushslide even more if over "max" flight speed - if (player->powers[pw_tailsfly] && player->speed > topspeed) + if ((player->pflags & PF_SPINNING) || (player->powers[pw_tailsfly] && player->speed > topspeed)) movepushside >>= 2; } - // Allow a bit of movement while spinning - if (player->pflags & PF_SPINNING) + else if (player->pflags & PF_SPINNING) { - if (!(player->pflags & PF_STARTDASH)) - movepushside = FixedDiv(movepushside,16*FRACUNIT); - else + if (player->pflags & PF_STARTDASH) movepushside = 0; + else if (onground) + movepushside >>= 4; + else + movepushside >>= 3; } - // Finally move the player now that his speed/direction has been decided. + // Finally move the player now that their speed/direction has been decided. movepushside = FixedMul(movepushside, player->mo->scale); #ifdef ESLOPE @@ -4814,7 +5456,7 @@ static void P_3dMovement(player_t *player) if (newMagnitude > topspeed) { fixed_t tempmomx, tempmomy; - if (oldMagnitude > topspeed) + if (oldMagnitude > topspeed && !spin) { if (newMagnitude > oldMagnitude) { @@ -4850,16 +5492,16 @@ static void P_SpectatorMovement(player_t *player) if (!(cmd->angleturn & TICCMD_RECEIVED)) ticmiss++; - if (player->mo->z > player->mo->ceilingz - player->mo->height) - player->mo->z = player->mo->ceilingz - player->mo->height; - if (player->mo->z < player->mo->floorz) - player->mo->z = player->mo->floorz; - if (cmd->buttons & BT_JUMP) player->mo->z += FRACUNIT*16; else if (cmd->buttons & BT_USE) player->mo->z -= FRACUNIT*16; + if (player->mo->z > player->mo->ceilingz - player->mo->height) + player->mo->z = player->mo->ceilingz - player->mo->height; + if (player->mo->z < player->mo->floorz) + player->mo->z = player->mo->floorz; + // Aiming needed for SEENAMES, etc. // We may not need to fire as a spectator, but this is still handy! player->aiming = cmd->aiming<<FRACBITS; @@ -4964,14 +5606,20 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad if (player->exiting) return; - // You're welcome, Rob. (Now with slightly less horrendous hacking -Red - player->mo->tracer->flags &= ~MF_NOCLIP; - player->mo->tracer->z = player->mo->z; - if (!P_TryMove(player->mo->tracer, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, true)) { - player->mo->tracer->flags |= MF_NOCLIP; - return; + { + boolean notallowed; + mobj_t *hack = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_NULL); + hack->flags = MF_NOGRAVITY; + hack->radius = player->mo->radius; + hack->height = player->mo->height; + hack->z = player->mo->z; + P_SetThingPosition(hack); + notallowed = (!(P_TryMove(hack, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, true))); + P_RemoveMobj(hack); + if (notallowed) + return; } - player->mo->tracer->flags |= MF_NOCLIP; + { const INT32 sequence = player->mo->target->threshold; mobj_t *transfer1 = NULL; @@ -4984,7 +5632,7 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad boolean transfer1last = false; boolean transfer2last = false; vertex_t vertices[4]; - fixed_t truexspeed = xspeed*(!(player->pflags & PF_TRANSFERTOCLOSEST) && player->mo->target->flags & MF_AMBUSH ? -1 : 1); + fixed_t truexspeed = xspeed*(!(player->pflags & PF_TRANSFERTOCLOSEST) && player->mo->target->flags2 & MF2_AMBUSH ? -1 : 1); // Find next waypoint for (th = thinkercap.next; th != &thinkercap; th = th->next) @@ -5359,13 +6007,10 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad // static void P_DoNiGHTSCapsule(player_t *player) { - INT32 i; - - if ((player->pflags & PF_NIGHTSMODE) && (player->mo->tracer->state < &states[S_NIGHTSHURT1] - || player->mo->tracer->state > &states[S_NIGHTSHURT32])) - P_SetMobjState(player->mo->tracer, S_NIGHTSHURT1); + INT32 i, spherecount, totalduration, popduration, deductinterval, deductquantity, sphereresult, firstpoptic, startingspheres; + INT32 tictimer = ++player->capsule->extravalue2; - if (abs(player->mo->x-player->capsule->x) <= 2*FRACUNIT) + if (abs(player->mo->x-player->capsule->x) <= 3*FRACUNIT) { P_UnsetThingPosition(player->mo); player->mo->x = player->capsule->x; @@ -5373,7 +6018,7 @@ static void P_DoNiGHTSCapsule(player_t *player) player->mo->momx = 0; } - if (abs(player->mo->y-player->capsule->y) <= 2*FRACUNIT) + if (abs(player->mo->y-player->capsule->y) <= 3*FRACUNIT) { P_UnsetThingPosition(player->mo); player->mo->y = player->capsule->y; @@ -5381,64 +6026,142 @@ static void P_DoNiGHTSCapsule(player_t *player) player->mo->momy = 0; } - if (abs(player->mo->z - (player->capsule->z+(player->capsule->height/3))) <= 2*FRACUNIT) + if (abs(player->mo->z - (player->capsule->z+(player->capsule->height/3))) <= 3*FRACUNIT) { player->mo->z = player->capsule->z+(player->capsule->height/3); player->mo->momz = 0; } if (player->mo->x > player->capsule->x) - player->mo->momx = -2*FRACUNIT; + player->mo->momx = -3*FRACUNIT; else if (player->mo->x < player->capsule->x) - player->mo->momx = 2*FRACUNIT; + player->mo->momx = 3*FRACUNIT; if (player->mo->y > player->capsule->y) - player->mo->momy = -2*FRACUNIT; + player->mo->momy = -3*FRACUNIT; else if (player->mo->y < player->capsule->y) - player->mo->momy = 2*FRACUNIT; + player->mo->momy = 3*FRACUNIT; if (player->mo->z > player->capsule->z+(player->capsule->height/3)) - player->mo->momz = -2*FRACUNIT; + player->mo->momz = -3*FRACUNIT; else if (player->mo->z < player->capsule->z+(player->capsule->height/3)) - player->mo->momz = 2*FRACUNIT; + player->mo->momz = 3*FRACUNIT; + + if (player->powers[pw_carry] == CR_NIGHTSMODE) + { + if (player->mo->momx || player->mo->momy || player->mo->momz) + { + if (player->mo->state != &states[S_PLAY_NIGHTS_PULL]) + P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_PULL); + } + else if (player->mo->state != &states[S_PLAY_NIGHTS_ATTACK]) + { + S_StartSound(player->mo, sfx_spin); + P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_ATTACK); + } + } + else + { + if (!(player->pflags & PF_JUMPED) && !(player->pflags & PF_SPINNING)) + player->pflags |= PF_JUMPED; + if (player->panim != PA_ROLL) + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + } if (G_IsSpecialStage(gamemap)) { // In special stages, share rings. Everyone gives up theirs to the capsule player always, because we can't have any individualism here! for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && (&players[i] != player) && players[i].mo->health > 1) + if (playeringame[i] && (&players[i] != player) && players[i].spheres > 0) { - player->mo->health += players[i].mo->health-1; - player->health = player->mo->health; - players[i].mo->health = 1; - players[i].health = players[i].mo->health; + player->spheres += players[i].spheres; + players[i].spheres = 0; } } + if (player->capsule->extravalue2 <= 0 && player->capsule->health > 0) + P_RunNightsCapsuleTouchExecutors(player->mo, true, player->spheres >= player->capsule->health); // run capsule entrance executors + // Time to blow it up! if (player->mo->x == player->capsule->x && player->mo->y == player->capsule->y && player->mo->z == player->capsule->z+(player->capsule->height/3)) { - if (player->mo->health > 1) + if (player->capsule->lastlook < 0) + { + // Stretch the sphere deduction across the capsule time! + // 1. Force the remaining capsule time to `popduration` + // 2. Given `popduration` and `spherecount`, at what tic interval do we deduct spheres? `deductinterval` + // 3. And on each deduction, how many spheres do we deduct? `deductquantity` + // 4. Store the expected capsule health upon completion: `sphereresult` + spherecount = min(player->spheres, player->capsule->health); + totalduration = min(40 + spherecount, 60); + + popduration = player->capsule->extravalue1 = max(totalduration - tictimer, 1); + deductinterval = player->capsule->cvmem = max(FixedFloor(FixedDiv(popduration, spherecount))/FRACUNIT, 1); + deductquantity = player->capsule->cusval = max(FixedRound(FixedDiv(spherecount, popduration))/FRACUNIT, 1); + sphereresult = player->capsule->movecount = player->capsule->health - spherecount; + firstpoptic = player->capsule->lastlook = tictimer; + } + else { - player->mo->health--; - player->health--; - player->capsule->health--; - player->capsule->extravalue1++; + popduration = player->capsule->extravalue1; + deductinterval = player->capsule->cvmem; + deductquantity = player->capsule->cusval; + sphereresult = player->capsule->movecount; + firstpoptic = player->capsule->lastlook; + } + + if (tictimer - firstpoptic < popduration) + { + if (!((tictimer - firstpoptic) % deductinterval)) + { + // Did you somehow get more spheres during destruct? + if (player->capsule->health <= sphereresult && player->spheres > 0 && player->capsule->health > 0) + sphereresult = max(sphereresult - player->spheres, 0); + + if (player->capsule->health > sphereresult && player->spheres > 0) + { + player->spheres -= deductquantity; + player->capsule->health -= deductquantity; + } + + if (player->spheres < 0) + player->spheres = 0; - // Spawn a 'pop' for every 5 rings you deposit - if (!(player->capsule->extravalue1 % 5)) + if (player->capsule->health < sphereresult) + player->capsule->health = sphereresult; + } + + // Spawn a 'pop' for every 5 tics + if (!((tictimer - firstpoptic) % 5)) S_StartSound(P_SpawnMobj(player->capsule->x + ((P_SignedRandom()/2)<<FRACBITS), player->capsule->y + ((P_SignedRandom()/2)<<FRACBITS), player->capsule->z + (player->capsule->height/2) + ((P_SignedRandom()/2)<<FRACBITS), - MT_EXPLODE),sfx_pop); + MT_BOSSEXPLODE),sfx_cybdth); + } + else + { + if (player->spheres != 0 && player->capsule->health > 0) + { + if (player->spheres < player->capsule->health) + { + player->capsule->health -= player->spheres; + player->spheres = 0; + } + else + { + startingspheres = player->spheres - player->capsule->health; + player->capsule->health = 0; + player->spheres = startingspheres; + } + } if (player->capsule->health <= 0) { player->capsule->flags &= ~MF_NOGRAVITY; player->capsule->momz = 5*FRACUNIT; player->capsule->reactiontime = 0; - player->capsule->extravalue1 = -1; + tictimer = -1; for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && !player->exiting && players[i].mare == player->mare) @@ -5454,9 +6177,6 @@ static void P_DoNiGHTSCapsule(player_t *player) if (G_IsSpecialStage(gamemap)) { - // The Chaos Emerald begins to orbit us! - mobj_t *emmo; - UINT8 em = P_GetNextEmerald(); tic_t lowest_time; /*for (i = 0; i < MAXPLAYERS; i++) @@ -5469,13 +6189,16 @@ static void P_DoNiGHTSCapsule(player_t *player) P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); }*/ - if (player->mo->tracer) + if (player->powers[pw_carry] == CR_NIGHTSMODE) { + // The Chaos Emerald begins to orbit us! + UINT8 em = P_GetNextEmerald(); // Only give it to ONE person, and THAT player has to get to the goal! - emmo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->info->height, MT_GOTEMERALD); + mobj_t *emmo = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height, MT_GOTEMERALD); + emmo->health = em; // for identification P_SetTarget(&emmo->target, player->mo); P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); - P_SetTarget(&player->mo->tracer->target, emmo); + P_SetTarget(&player->mo->tracer, emmo); } // Okay, we're doing this down here because we're handling time weirdly for co-op special stages @@ -5483,36 +6206,106 @@ static void P_DoNiGHTSCapsule(player_t *player) // Find the player with the lowest time remaining and award points based on that time instead. lowest_time = player->finishedtime; for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE) + if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE) if (players[i].finishedtime < lowest_time) lowest_time = players[i].finishedtime; P_AddPlayerScore(player, (lowest_time/TICRATE) * 100); } else { - fixed_t z; + /*for (i = 0; i < 16; i++) + { + mobj_t *flicky = P_InternalFlickySpawn(player->capsule, 0, ((i%4) + 1)*2*FRACUNIT, true); + flicky->z += player->capsule->height/2; + flicky->angle = (i*(ANGLE_MAX/16)); + P_InstaThrust(flicky, flicky->angle, 8*FRACUNIT); + }*/ + mobj_t *idya = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height, MT_GOTEMERALD); + idya->extravalue2 = player->mare/5; + idya->health = player->mare + 1; // for identification + P_SetTarget(&idya->target, player->mo); + P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate + ((player->mare + 1) % 5)); - z = player->capsule->z + player->capsule->height/2; - for (i = 0; i < 16; i++) - P_SpawnMobj(player->capsule->x, player->capsule->y, z, MT_BIRD); + if (player->mo->tracer) + { + P_SetTarget(&idya->hnext, player->mo->tracer); + idya->extravalue1 = (angle_t)(player->mo->tracer->extravalue1 - 72*ANG1); + if (idya->extravalue1 > player->mo->tracer->extravalue1) + idya->extravalue1 -= (72*ANG1)/idya->extravalue1; + } + P_SetTarget(&player->mo->tracer, idya); } for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mare == player->mare) P_SetTarget(&players[i].capsule, NULL); // Remove capsule from everyone now that it is dead! S_StartScreamSound(player->mo, sfx_ngdone); + P_SwitchSpheresBonusMode(true); + P_RunNightsCapsuleTouchExecutors(player->mo, false, true); // run capsule exit executors, and we destroyed it + } + else + { + S_StartScreamSound(player->mo, sfx_lose); + player->texttimer = 4*TICRATE; + player->textvar = 3; // Get more rings! + player->capsule->reactiontime = 0; + player->capsule->extravalue1 = player->capsule->cvmem =\ + player->capsule->cusval = player->capsule->movecount =\ + player->capsule->lastlook = player->capsule->extravalue2 = -1; + P_RunNightsCapsuleTouchExecutors(player->mo, false, false); // run capsule exit executors, and we lacked rings } } + } + else if (player->capsule->lastlook > -1) + // We somehow moved out of the capsule (OBJECTPLACE?) + // So recalculate all the timings + player->capsule->lastlook = player->capsule->extravalue2 = -1; +} + +// +// P_MoveNiGHTSToDrone +// +// Pull NiGHTS to the drone during Nightserizing +// +static void P_MoveNiGHTSToDrone(player_t *player) +{ + boolean flip, topaligned, middlealigned, bottomoffsetted; + fixed_t droneboxmandiff, zofs; + + if (!player->drone) + return; + + flip = player->drone->flags2 & MF2_OBJECTFLIP; + topaligned = (player->drone->flags & MF_SLIDEME) && !(player->drone->flags & MF_GRENADEBOUNCE); + middlealigned = (player->drone->flags & MF_GRENADEBOUNCE) && !(player->drone->flags & MF_SLIDEME); + bottomoffsetted = !(player->drone->flags & MF_SLIDEME) && !(player->drone->flags & MF_GRENADEBOUNCE); + droneboxmandiff = max(player->drone->height - player->mo->height, 0); + + if (!flip) + { + if (topaligned) + zofs = droneboxmandiff; + else if (middlealigned) + zofs = droneboxmandiff / 2; + else if (bottomoffsetted) + zofs = FixedMul(24*FRACUNIT, player->drone->scale); else - { - S_StartScreamSound(player->mo, sfx_lose); - player->texttimer = 4*TICRATE; - player->textvar = 3; // Get more rings! - player->capsule->reactiontime = 0; - player->capsule->extravalue1 = -1; - } + zofs = 0; } else - player->capsule->extravalue1 = -1; + { + if (topaligned) + zofs = 0; + else if (middlealigned) + zofs = droneboxmandiff / 2; + else if (bottomoffsetted) + zofs = droneboxmandiff - FixedMul(24*FRACUNIT, player->drone->scale); + else + zofs = droneboxmandiff; + } + + player->mo->momx = player->mo->momy = player->mo->momz = 0; + P_TeleportMove(player->mo, player->drone->x, player->drone->y, player->drone->z + zofs); + P_SetTarget(&player->drone, NULL); } // @@ -5534,7 +6327,8 @@ static void P_NiGHTSMovement(player_t *player) ticcmd_t *cmd = &player->cmd; INT32 thrustfactor; INT32 i; - statenum_t flystate = S_NIGHTSFLY1A; + statenum_t flystate; + UINT16 visangle; player->pflags &= ~PF_DRILLING; @@ -5553,7 +6347,7 @@ static void P_NiGHTSMovement(player_t *player) player->drillmeter = TICRATE/10; } - if (!player->mo->tracer) + if (!(player->powers[pw_carry] == CR_NIGHTSMODE)) { P_DeNightserizePlayer(player); return; @@ -5564,17 +6358,18 @@ static void P_NiGHTSMovement(player_t *player) boolean capsule = false; // NiGHTS special stages have a pseudo-shared timer, so check if ANYONE is feeding the capsule. for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] /*&& players[i].pflags & PF_NIGHTSMODE*/ + if (playeringame[i] /*&& players[i].powers[pw_carry] == CR_NIGHTSMODE*/ && (players[i].capsule && players[i].capsule->reactiontime)) capsule = true; if (!capsule - && !(player->mo->tracer->state >= &states[S_SUPERTRANS1] - && player->mo->tracer->state <= &states[S_SUPERTRANS9]) + && !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1] + && player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6]) && !player->exiting) player->nightstime--; } else if (gametype != GT_RACE && gametype != GT_COMPETITION - && !(player->mo->tracer->state >= &states[S_SUPERTRANS1] && player->mo->tracer->state <= &states[S_SUPERTRANS9]) + && !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1] + && player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6]) && !(player->capsule && player->capsule->reactiontime) && !player->exiting) player->nightstime--; @@ -5583,15 +6378,18 @@ static void P_NiGHTSMovement(player_t *player) { P_DeNightserizePlayer(player); S_StartScreamSound(player->mo, sfx_s3k66); -// S_StopSoundByNum(sfx_timeup); // Kill the "out of time" music, if it's playing. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH - P_RestoreMusic(player); // I have my doubts that this is the right place for this... - return; } else if (P_IsLocalPlayer(player) && player->nightstime == 10*TICRATE) -// S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH - S_ChangeMusicInternal("drown",false); - + { + if (mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN) + { + S_FadeMusic(0, 10*MUSICRATE); + S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. + } + else + S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false); + } if (player->mo->z < player->mo->floorz) player->mo->z = player->mo->floorz; @@ -5649,7 +6447,7 @@ static void P_NiGHTSMovement(player_t *player) // The 'ambush' flag says you should rotate // the other way around the axis. - if (player->mo->target->flags & MF_AMBUSH) + if (player->mo->target->flags2 & MF2_AMBUSH) backwardaxis = true; player->angle_pos = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y); @@ -5659,8 +6457,6 @@ static void P_NiGHTSMovement(player_t *player) radius = player->mo->target->radius; player->mo->flags |= MF_NOGRAVITY; - player->mo->flags2 |= MF2_DONTDRAW; - P_SetScale(player->mo->tracer, player->mo->scale); if (player->mo->eflags & MFE_VERTICALFLIP) cmd->forwardmove = (SINT8)(-cmd->forwardmove); @@ -5715,28 +6511,25 @@ static void P_NiGHTSMovement(player_t *player) return; } - if (player->mo->tracer->state >= &states[S_SUPERTRANS1] - && player->mo->tracer->state <= &states[S_SUPERTRANS9]) + if (player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1] + && player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6]) { player->mo->momx = player->mo->momy = player->mo->momz = 0; return; } - if (player->exiting > 0 && player->exiting < 2*TICRATE) + if (player->exiting > 0) // && player->exiting < 2*TICRATE) { player->mo->momx = player->mo->momy = 0; if (gametype != GT_RACE && gametype != GT_COMPETITION) - P_SetObjectMomZ(player->mo, 30*FRACUNIT, false); - - player->mo->tracer->angle += ANGLE_11hh; + P_SetObjectMomZ(player->mo, FRACUNIT/2, true); - if (!(player->mo->tracer->state >= &states[S_NIGHTSDRONE1] - && player->mo->tracer->state <= &states[S_NIGHTSDRONE2])) - P_SetMobjState(player->mo->tracer, S_NIGHTSDRONE1); + if (player->mo->state != &states[S_PLAY_NIGHTS_DRILL6]) + P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_DRILL6); - player->mo->tracer->flags |= MF_NOCLIPHEIGHT; player->mo->flags |= MF_NOCLIPHEIGHT; + return; } @@ -5779,21 +6572,19 @@ static void P_NiGHTSMovement(player_t *player) if (player->bumpertime) { - player->jumping = 1; - player->pflags |= PF_DRILLING; + player->pflags |= (PF_STARTJUMP|PF_DRILLING); newangle = (INT16)player->flyangle; } else if (cmd->buttons & BT_JUMP && player->drillmeter && player->drilldelay == 0) { - if (!player->jumping) + if (!(player->pflags & PF_STARTJUMP)) firstdrill = true; - player->jumping = 1; - player->pflags |= PF_DRILLING; + player->pflags |= (PF_STARTJUMP|PF_DRILLING); } else { - player->jumping = 0; + player->pflags &= ~PF_STARTJUMP; if (cmd->sidemove != 0) moved = true; @@ -5901,7 +6692,7 @@ static void P_NiGHTSMovement(player_t *player) && ((cmd->buttons & (BT_CAMLEFT|BT_CAMRIGHT)) == (BT_CAMLEFT|BT_CAMRIGHT) || (cmd->buttons & BT_USE))) { - if (!(player->pflags & PF_SKIDDOWN)) + if (!(player->pflags & PF_STARTDASH)) S_StartSound(player->mo, sfx_ngskid); // You can tap the button to only slow down a bit, @@ -5919,10 +6710,10 @@ static void P_NiGHTSMovement(player_t *player) } } - player->pflags |= PF_SKIDDOWN; + player->pflags |= PF_STARTDASH; } else - player->pflags &= ~PF_SKIDDOWN; + player->pflags &= ~PF_STARTDASH; { const angle_t fa = (FixedAngle(player->flyangle*FRACUNIT)>>ANGLETOFINESHIFT) & FINEMASK; @@ -6002,74 +6793,41 @@ static void P_NiGHTSMovement(player_t *player) // NiGHTS flying state // Yep, I just ripped out almost 1000 lines of code. - if ((player->anotherflyangle >= 12 && player->anotherflyangle <= 33) // +x +y - || (player->anotherflyangle >= 147 && player->anotherflyangle <= 168)) // -x +y - flystate = S_NIGHTSFLY2A; - else if ((player->anotherflyangle >= 34 && player->anotherflyangle <= 56) // +x +y - || (player->anotherflyangle >= 124 && player->anotherflyangle <= 146)) // -x +y - flystate = S_NIGHTSFLY3A; - else if ((player->anotherflyangle >= 57 && player->anotherflyangle <= 79) // +x +y - || (player->anotherflyangle >= 102 && player->anotherflyangle <= 123)) // -x +y - flystate = S_NIGHTSFLY4A; - else if (player->anotherflyangle >= 80 && player->anotherflyangle <= 101) - flystate = S_NIGHTSFLY5A; - else if ((player->anotherflyangle >= 192 && player->anotherflyangle <= 213) // -x -y - || (player->anotherflyangle >= 327 && player->anotherflyangle <= 348)) // +x -y - flystate = S_NIGHTSFLY6A; - else if ((player->anotherflyangle >= 214 && player->anotherflyangle <= 236) // -x -y - || (player->anotherflyangle >= 305 && player->anotherflyangle <= 326)) // +x -y - flystate = S_NIGHTSFLY7A; - else if ((player->anotherflyangle >= 237 && player->anotherflyangle <= 258) // -x -y - || (player->anotherflyangle >= 282 && player->anotherflyangle <= 304)) // +x -y - flystate = S_NIGHTSFLY8A; - else if (player->anotherflyangle >= 259 && player->anotherflyangle <= 281) - flystate = S_NIGHTSFLY9A; + // (and then toast revamped the entire thing again to be better, but not by much) + if (still) + flystate = (P_IsObjectOnGround(player->mo)) ? S_PLAY_NIGHTS_STAND : S_PLAY_NIGHTS_FLOAT; else - flystate = S_NIGHTSFLY1A; - - if (player->mo->eflags & MFE_VERTICALFLIP) - { - if (flystate >= S_NIGHTSFLY2A && flystate <= S_NIGHTSFLY5A) - flystate += 24; // shift to S_NIGHTSFLY6A - else if (flystate >= S_NIGHTSFLY6A && flystate <= S_NIGHTSFLY9A) - flystate -= 24; // shift to S_NIGHTSFLY2A - } - - if (player->pflags & PF_DRILLING) { - const statenum_t drillstate = flystate + 2; + visangle = ((player->anotherflyangle + 7) % 360)/15; + if (visangle > 18) // Over 270 degrees. + visangle = 30 - visangle; + else if (visangle > 12) // Over 180 degrees. + visangle -= 6; + else if (visangle > 6) // Over 90 degrees. + visangle = 12 - visangle; - if (!(player->mo->tracer->state >= &states[drillstate] - && player->mo->tracer->state <= &states[drillstate+4])) + if (player->mo->eflags & MFE_VERTICALFLIP && visangle) // S_PLAY_NIGHTS_FLY0 stays the same, even in reverse gravity { - if (!(player->mo->tracer->state >= &states[S_NIGHTSFLY1A] - && player->mo->tracer->state <= &states[S_NIGHTSFLY9B])) - { - const INT32 framenum = player->mo->tracer->state->frame & 3; - - if (framenum == 3) // Drilld special case - P_SetMobjStateNF(player->mo->tracer, drillstate); - else - P_SetMobjStateNF(player->mo->tracer, drillstate+framenum+1); - } + if (visangle > 6) + visangle -= 6; // shift to S_PLAY_NIGHTS_FLY1-6 else - P_SetMobjStateNF(player->mo->tracer, drillstate); + visangle += 6; // shift to S_PLAY_NIGHTS_FLY7-C } + + flystate = S_PLAY_NIGHTS_FLY0 + (visangle*2); // S_PLAY_FLY0-C - the *2 is to skip over drill states + + if (player->pflags & PF_DRILLING) + flystate++; // shift to S_PLAY_NIGHTS_DRILL0-C } - else - P_SetMobjStateNF(player->mo->tracer, leveltime & 1 ? flystate : flystate+1); + + if (player->mo->state != &states[flystate]) + P_SetPlayerMobjState(player->mo, flystate); if (player == &players[consoleplayer]) localangle = player->mo->angle; else if (player == &players[secondarydisplayplayer]) localangle2 = player->mo->angle; - if (still) - { - P_SetMobjStateNF(player->mo->tracer, S_NIGHTSDRONE1); - player->mo->tracer->angle = player->mo->angle; - } - // Check for crushing in our new location if ((player->mo->ceilingz - player->mo->floorz < player->mo->height) && !(player->mo->flags & MF_NOCLIP)) @@ -6078,7 +6836,7 @@ static void P_NiGHTSMovement(player_t *player) if (player->powers[pw_flashing] == 1) player->powers[pw_flashing] = 3; else - P_DamageMobj(player->mo, NULL, NULL, 1); + P_DamageMobj(player->mo, NULL, NULL, 1, 0); } if (movingangle >= ANGLE_90 && movingangle <= ANGLE_180) @@ -6093,8 +6851,6 @@ static void P_NiGHTSMovement(player_t *player) else if (player == &players[secondarydisplayplayer]) localaiming2 = movingangle; - player->mo->tracer->angle = player->mo->angle; - if ((player->pflags & PF_DRILLING) && !player->bumpertime) { if (firstdrill) @@ -6102,7 +6858,18 @@ static void P_NiGHTSMovement(player_t *player) S_StartSound(player->mo, sfx_drill1); player->drilltimer = 32; } - else if (--player->drilltimer <= 0) + else if (player->drilltimer == 32) + { + // drill mash penalty + player->drilltimer = 31; + player->drillmeter -= TICRATE/2; + if (player->drillmeter <= 0) + player->drillmeter = TICRATE/10; + } + else if (--player->drilltimer == 11) + // give that drill mash penalty back (after 0.6 seconds) + player->drillmeter += TICRATE/2; + else if (player->drilltimer <= 0) { player->drilltimer = 10; S_StartSound(player->mo, sfx_drill2); @@ -6152,7 +6919,7 @@ static void P_PlayerDropWeapon(player_t *player) if (mo) { - player->mo->health--; + player->rings--; P_InstaThrust(mo, player->mo->angle-ANGLE_180, 8*FRACUNIT); P_SetObjectMomZ(mo, 4*FRACUNIT, false); mo->flags2 |= MF2_DONTRESPAWN; @@ -6177,7 +6944,7 @@ void P_BlackOw(player_t *player) player->powers[pw_shield] = player->powers[pw_shield] & SH_STACK; } -void P_ElementalFireTrail(player_t *player) +void P_ElementalFire(player_t *player, boolean cropcircle) { fixed_t newx; fixed_t newy; @@ -6195,40 +6962,65 @@ void P_ElementalFireTrail(player_t *player) else ground = player->mo->floorz; - travelangle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy); - - for (i = 0; i < 2; i++) + if (cropcircle) { - newx = player->mo->x + P_ReturnThrustX(player->mo, travelangle + ((i&1) ? -1 : 1)*ANGLE_135, FixedMul(24*FRACUNIT, player->mo->scale)); - newy = player->mo->y + P_ReturnThrustY(player->mo, travelangle + ((i&1) ? -1 : 1)*ANGLE_135, FixedMul(24*FRACUNIT, player->mo->scale)); -#ifdef ESLOPE - if (player->mo->standingslope) +#define numangles 8 +#define limitangle (180/numangles) + travelangle = player->mo->angle + P_RandomRange(-limitangle, limitangle)*ANG1; + for (i = 0; i < numangles; i++) { - ground = P_GetZAt(player->mo->standingslope, newx, newy); - if (player->mo->eflags & MFE_VERTICALFLIP) - ground -= FixedMul(mobjinfo[MT_SPINFIRE].height, player->mo->scale); + flame = P_SpawnMobj(player->mo->x, player->mo->y, ground, MT_SPINFIRE); + flame->flags &= ~MF_NOGRAVITY; + P_SetTarget(&flame->target, player->mo); + flame->angle = travelangle + i*(ANGLE_MAX/numangles); + flame->fuse = TICRATE*7; // takes about an extra second to hit the ground + flame->destscale = player->mo->scale; + P_SetScale(flame, player->mo->scale); + flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); + P_InstaThrust(flame, flame->angle, FixedMul(3*FRACUNIT, flame->scale)); + P_SetObjectMomZ(flame, 3*FRACUNIT, false); } +#undef limitangle +#undef numangles + } + else + { + travelangle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy); + for (i = 0; i < 2; i++) + { + + newx = player->mo->x + P_ReturnThrustX(player->mo, (travelangle + ((i&1) ? -1 : 1)*ANGLE_135), FixedMul(24*FRACUNIT, player->mo->scale)); + newy = player->mo->y + P_ReturnThrustY(player->mo, (travelangle + ((i&1) ? -1 : 1)*ANGLE_135), FixedMul(24*FRACUNIT, player->mo->scale)); + +#ifdef ESLOPE + if (player->mo->standingslope) + { + ground = P_GetZAt(player->mo->standingslope, newx, newy); + if (player->mo->eflags & MFE_VERTICALFLIP) + ground -= FixedMul(mobjinfo[MT_SPINFIRE].height, player->mo->scale); + } #endif - flame = P_SpawnMobj(newx, newy, ground, MT_SPINFIRE); - P_SetTarget(&flame->target, player->mo); - flame->angle = travelangle; - flame->fuse = TICRATE*6; - flame->destscale = player->mo->scale; - P_SetScale(flame, player->mo->scale); - flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); - - flame->momx = 8; - P_XYMovement(flame); - if (P_MobjWasRemoved(flame)) - continue; + flame = P_SpawnMobj(newx, newy, ground, MT_SPINFIRE); + P_SetTarget(&flame->target, player->mo); + flame->angle = travelangle; + flame->fuse = TICRATE*6; + flame->destscale = player->mo->scale; + P_SetScale(flame, player->mo->scale); + flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); + + flame->momx = 8; // this is a hack which is used to ensure it still behaves as a missile and can damage others + P_XYMovement(flame); + if (P_MobjWasRemoved(flame)) + continue; - if (player->mo->eflags & MFE_VERTICALFLIP) - { - if (flame->z + flame->height < flame->ceilingz) + if (player->mo->eflags & MFE_VERTICALFLIP) + { + if (flame->z + flame->height < flame->ceilingz) + P_RemoveMobj(flame); + } + else if (flame->z > flame->floorz) P_RemoveMobj(flame); } - else if (flame->z > flame->floorz) - P_RemoveMobj(flame); } } @@ -6244,8 +7036,8 @@ static void P_SkidStuff(player_t *player) if (!onground) { player->skidtime = 0; - player->pflags &= ~(PF_GLIDING|PF_JUMPED); - P_SetPlayerMobjState(player->mo, S_PLAY_FALL1); + player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); + P_SetPlayerMobjState(player->mo, S_PLAY_FALL); } // Get up and brush yourself off, idiot. else if (player->glidetime > 15) @@ -6261,16 +7053,18 @@ static void P_SkidStuff(player_t *player) // Spawn a particle every 3 tics. else if (!(player->skidtime % 3)) { - mobj_t *particle = P_SpawnMobj(player->mo->x + P_RandomRange(-player->mo->radius, player->mo->radius), player->mo->y + P_RandomRange(-player->mo->radius, player->mo->radius), - player->mo->z + (player->mo->eflags & MFE_VERTICALFLIP ? player->mo->height - mobjinfo[MT_PARTICLE].height : 0), - MT_PARTICLE); + mobj_t *particle = P_SpawnMobjFromMobj(player->mo, P_RandomRange(-player->mo->radius, player->mo->radius), P_RandomRange(-player->mo->radius, player->mo->radius), 0, MT_SPINDUST); particle->tics = 10; - particle->eflags |= player->mo->eflags & MFE_VERTICALFLIP; - P_SetScale(particle, player->mo->scale >> 2); - particle->destscale = player->mo->scale << 2; - particle->scalespeed = FixedMul(particle->scalespeed, player->mo->scale); // scale the scaling speed! + particle->destscale = (2*player->mo->scale)/3; + P_SetScale(particle, particle->destscale); P_SetObjectMomZ(particle, FRACUNIT, false); + + if (player->mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) // overrides fire version + P_SetMobjState(particle, S_SPINDUST_BUBBLE1); + else if (player->powers[pw_shield] == SH_ELEMENTAL) + P_SetMobjState(particle, S_SPINDUST_FIRE1); + S_StartSound(player->mo, sfx_s3k7e); // the proper "Knuckles eats dirt" sfx. } } @@ -6282,16 +7076,17 @@ static void P_SkidStuff(player_t *player) // Spawn a particle every 3 tics. if (!(player->skidtime % 3)) { - mobj_t *particle = P_SpawnMobj(player->mo->x, player->mo->y, - player->mo->z + (player->mo->eflags & MFE_VERTICALFLIP ? player->mo->height - mobjinfo[MT_PARTICLE].height : 0), - MT_PARTICLE); + mobj_t *particle = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_SPINDUST); particle->tics = 10; - particle->eflags |= player->mo->eflags & MFE_VERTICALFLIP; - P_SetScale(particle, player->mo->scale >> 2); - particle->destscale = player->mo->scale << 2; - particle->scalespeed = FixedMul(particle->scalespeed, player->mo->scale); // scale the scaling speed! + particle->destscale = (2*player->mo->scale)/3; + P_SetScale(particle, particle->destscale); P_SetObjectMomZ(particle, FRACUNIT, false); + + if (player->mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) // overrides fire version + P_SetMobjState(particle, S_SPINDUST_BUBBLE1); + else if (player->powers[pw_shield] == SH_ELEMENTAL) + P_SetMobjState(particle, S_SPINDUST_FIRE1); } } else if (P_AproxDistance(pmx, pmy) >= FixedMul(player->runspeed/2, player->mo->scale) // if you were moving faster than half your run speed last frame @@ -6308,11 +7103,10 @@ static void P_SkidStuff(player_t *player) // If your push angle is more than this close to a full 180 degrees, trigger a skid. if (dang > ANGLE_157h) { - player->skidtime = TICRATE/2; + if (player->mo->state-states != S_PLAY_SKID) + P_SetPlayerMobjState(player->mo, S_PLAY_SKID); + player->mo->tics = player->skidtime = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; S_StartSound(player->mo, sfx_skid); - if (player->panim != PA_WALK) - P_SetPlayerMobjState(player->mo, S_PLAY_RUN4); // this switches to S_PLAY_SUPERWALK1 for superanims - player->mo->tics = player->skidtime; } } } @@ -6333,10 +7127,7 @@ static void P_MovePlayer(player_t *player) fixed_t runspd; - if (countdowntimeup) - return; - - if (player->mo->state >= &states[S_PLAY_SUPERTRANS1] && player->mo->state <= &states[S_PLAY_SUPERTRANS9]) + if (player->mo->state >= &states[S_PLAY_SUPER_TRANS1] && player->mo->state <= &states[S_PLAY_SUPER_TRANS6]) { player->mo->momx = player->mo->momy = player->mo->momz = 0; return; @@ -6345,10 +7136,14 @@ static void P_MovePlayer(player_t *player) cmd = &player->cmd; runspd = FixedMul(player->runspeed, player->mo->scale); + // Let's have some movement speed fun on low-friction surfaces, JUST for players... (high friction surfaces shouldn't have any adjustment, since the acceleration in this game is super high and that ends up cheesing high-friction surfaces.) + runspd = FixedMul(runspd, player->mo->movefactor); + // Control relinquishing stuff! - if (player->powers[pw_ingoop]) - player->pflags |= PF_FULLSTASIS; - else if (player->pflags & PF_GLIDING && player->skidtime) + if ((player->powers[pw_carry] == CR_BRAKGOOP) + || (player->pflags & PF_GLIDING && player->skidtime) + || (player->charability2 == CA2_GUNSLINGER && player->panim == PA_ABILITY2) + || (player->charability2 == CA2_MELEE && player->mo->state-states == S_PLAY_MELEE_LANDING)) player->pflags |= PF_FULLSTASIS; else if (player->powers[pw_nocontrol]) { @@ -6375,7 +7170,7 @@ static void P_MovePlayer(player_t *player) if (!(player->pflags & PF_TAGIT)) { forcestasis = true; - if (player->pflags & PF_TAGGED) // Already hit. + if (player->pflags & PF_GAMETYPEOVER) // Already hit. player->powers[pw_flashing] = 5; } } @@ -6392,6 +7187,7 @@ static void P_MovePlayer(player_t *player) if (player->spectator) { + player->mo->eflags &= ~MFE_VERTICALFLIP; // deflip... P_SpectatorMovement(player); return; } @@ -6399,6 +7195,22 @@ static void P_MovePlayer(player_t *player) // Locate the capsule for this mare. else if (maptol & TOL_NIGHTS) { + if ((player->powers[pw_carry] == CR_NIGHTSMODE) + && (player->exiting + || !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1] + && player->mo->state < &states[S_PLAY_NIGHTS_TRANS6]))) // Note the < instead of <= + { + skin_t *skin = ((skin_t *)(player->mo->skin)); + if (skin->flags & SF_SUPER) + { + player->mo->color = skin->supercolor + + ((player->nightstime == player->startedtime) + ? 4 + : abs((((signed)leveltime >> 1) % 9) - 4)); // This is where super flashing is handled. + G_GhostAddColor(GHC_SUPER); + } + } + if (!player->capsule && !player->bonustime) { thinker_t *th; @@ -6422,8 +7234,15 @@ static void P_MovePlayer(player_t *player) return; } + // Suck player into their drone + if (player->drone) + { + P_MoveNiGHTSToDrone(player); + return; + } + // Test revamped NiGHTS movement. - if (player->pflags & PF_NIGHTSMODE) + if (player->powers[pw_carry] == CR_NIGHTSMODE) { P_NiGHTSMovement(player); // No more goto blockchecking, let's just do all that here =D @@ -6435,8 +7254,7 @@ static void P_MovePlayer(player_t *player) P_CheckQuicksand(player); return; } - - if (player->pflags & PF_NIGHTSFALL && P_IsObjectOnGround(player->mo)) + else if (player->powers[pw_carry] == CR_NIGHTSFALL && P_IsObjectOnGround(player->mo)) { if (G_IsSpecialStage(gamemap)) { @@ -6446,9 +7264,15 @@ static void P_MovePlayer(player_t *player) if (playeringame[i]) players[i].exiting = (14*TICRATE)/5 + 1; } - else if (player->health > 1) - P_DamageMobj(player->mo, NULL, NULL, 1); - player->pflags &= ~PF_NIGHTSFALL; + else { + // Damage whether or not we have spheres, as player should recoil upon losing points + P_DamageMobj(player->mo, NULL, NULL, 1, 0); + + // Now deduct our mare score! + player->marescore = player->spheres =\ + player->rings = 0; + } + player->powers[pw_carry] = CR_NONE; } } @@ -6479,35 +7303,68 @@ static void P_MovePlayer(player_t *player) // MOVEMENT ANIMATIONS // ///////////////////////// - if ((cmd->forwardmove != 0 || cmd->sidemove != 0) || (player->powers[pw_super] && player->mo->z > player->mo->floorz)) + if ((cmd->forwardmove != 0 || cmd->sidemove != 0) || (player->powers[pw_super] && !onground)) { + // If the player is in dashmode, here's their peelout. + if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim == PA_RUN && !player->skidtime && (onground || ((player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super])) + P_SetPlayerMobjState (player->mo, S_PLAY_DASH); // If the player is moving fast enough, // break into a run! - if (player->speed >= runspd && player->panim == PA_WALK && !player->skidtime && (onground || player->powers[pw_super])) - P_SetPlayerMobjState (player->mo, S_PLAY_SPD1); + else if (player->speed >= runspd && player->panim == PA_WALK && !player->skidtime + && (onground || ((player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super])) + { + if (!onground) + P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT_RUN); + else + P_SetPlayerMobjState(player->mo, S_PLAY_RUN); + } + + // Floating at slow speeds has its own special animation. + else if ((((player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super]) && player->panim == PA_IDLE && !onground) + P_SetPlayerMobjState (player->mo, S_PLAY_FLOAT); // Otherwise, just walk. else if ((player->rmomx || player->rmomy) && player->panim == PA_IDLE) - P_SetPlayerMobjState (player->mo, S_PLAY_RUN1); + P_SetPlayerMobjState (player->mo, S_PLAY_WALK); } + // If your peelout animation is playing, and you're + // going too slow, switch back to the run. + if (player->charflags & SF_DASHMODE && player->panim == PA_DASH && player->dashmode < 3*TICRATE) + P_SetPlayerMobjState(player->mo, S_PLAY_RUN); + // If your running animation is playing, and you're // going too slow, switch back to the walking frames. if (player->panim == PA_RUN && player->speed < runspd) - P_SetPlayerMobjState(player->mo, S_PLAY_RUN1); + { + if (!onground && (((player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super])) + P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT); + else + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + } + + // Correct floating when ending up on the ground. + if (onground) + { + if (player->mo->state-states == S_PLAY_FLOAT) + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + else if (player->mo->state-states == S_PLAY_FLOAT_RUN) + P_SetPlayerMobjState(player->mo, S_PLAY_RUN); + } - // If Springing, but travelling DOWNWARD, change back! - if (player->mo->state == &states[S_PLAY_SPRING] && P_MobjFlip(player->mo)*player->mo->momz < 0) - P_SetPlayerMobjState(player->mo, S_PLAY_FALL1); - // If Springing but on the ground, change back! - else if (onground && (player->mo->state == &states[S_PLAY_SPRING] || player->panim == PA_FALL || player->mo->state == &states[S_PLAY_CARRY]) && !player->mo->momz) + // If Springing (or nojumpspinning), but travelling DOWNWARD, change back! + if ((player->panim == PA_SPRING && P_MobjFlip(player->mo)*player->mo->momz < 0) + || ((((player->charflags & SF_NOJUMPSPIN) && (player->pflags & PF_JUMPED) && player->panim == PA_JUMP)) + && (P_MobjFlip(player->mo)*player->mo->momz < 0))) + P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + // If doing an air animation but on the ground, change back! + else if (onground && (player->panim == PA_SPRING || player->panim == PA_FALL || player->panim == PA_RIDE || player->panim == PA_JUMP) && !player->mo->momz) P_SetPlayerMobjState(player->mo, S_PLAY_STND); // If you are stopped and are still walking, stand still! if (!player->mo->momx && !player->mo->momy && !player->mo->momz && player->panim == PA_WALK) P_SetPlayerMobjState(player->mo, S_PLAY_STND); - ////////////////// //GAMEPLAY STUFF// ////////////////// @@ -6516,37 +7373,39 @@ static void P_MovePlayer(player_t *player) if (onground && player->pflags & PF_JUMPED && !(player->pflags & PF_GLIDING) && P_MobjFlip(player->mo)*player->mo->momz < 0) { - player->pflags &= ~PF_JUMPED; - player->jumping = 0; + player->pflags &= ~(PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SHIELDABILITY); player->secondjump = 0; - player->pflags &= ~PF_THOKKED; P_SetPlayerMobjState(player->mo, S_PLAY_STND); } - // Cap the speed limit on a spindash - // Up the 60*FRACUNIT number to boost faster, you speed demon you! - if (player->dashspeed > FixedMul(player->maxdash, player->mo->scale)) - player->dashspeed = FixedMul(player->maxdash, player->mo->scale); - else if (player->dashspeed > 0 && player->dashspeed < FixedMul(player->mindash, player->mo->scale)) - player->dashspeed = FixedMul(player->mindash, player->mo->scale); - - if (!(player->charability == CA_GLIDEANDCLIMB) || player->gotflag) // If you can't glide, then why the heck would you be gliding? + if ((!(player->charability == CA_GLIDEANDCLIMB) || player->gotflag) // If you can't glide, then why the heck would you be gliding? + && (player->pflags & PF_GLIDING || player->climbing)) { - if (player->pflags & PF_GLIDING || player->climbing) + if (onground) + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + else { - if (onground) - P_SetPlayerMobjState(player->mo, S_PLAY_RUN1); - else - { - player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); - } + player->pflags |= P_GetJumpFlags(player); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } player->pflags &= ~PF_GLIDING; player->glidetime = 0; player->climbing = 0; } + if ((!(player->charability == CA_BOUNCE) || player->gotflag) // If you can't bounce, then why the heck would you be bouncing? + && (player->pflags & PF_BOUNCING)) + { + if (onground) + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + else + { + player->pflags |= P_GetJumpFlags(player); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + } + player->pflags &= ~PF_BOUNCING; + } + // Glide MOMZ // AKA my own gravity. =) if (player->pflags & PF_GLIDING) @@ -6592,19 +7451,18 @@ static void P_MovePlayer(player_t *player) { P_ResetPlayer(player); // down, stop gliding. if (onground) - P_SetPlayerMobjState(player->mo, S_PLAY_RUN1); - else if ((player->charability2 == CA2_MULTIABILITY) - || (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]) && player->charability == CA_GLIDEANDCLIMB)) + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + else if (player->charflags & SF_MULTIABILITY) { - player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + player->pflags |= P_GetJumpFlags(player); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } else { player->pflags |= PF_THOKKED; player->mo->momx >>= 1; player->mo->momy >>= 1; - P_SetPlayerMobjState(player->mo, S_PLAY_FALL1); + P_SetPlayerMobjState(player->mo, S_PLAY_FALL); } } } @@ -6623,6 +7481,30 @@ static void P_MovePlayer(player_t *player) player->mo->momz = 0; } } + else if (player->pflags & PF_BOUNCING) + { + if (!(player->pflags & PF_JUMPDOWN) || (onground && P_MobjFlip(player->mo)*player->mo->momz <= 0)) // If not holding the jump button OR on flat ground + { + P_ResetPlayer(player); // down, stop bouncing. + player->pflags |= PF_THOKKED; + if (onground) + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + else if (player->charflags & SF_MULTIABILITY) + { + player->pflags |= P_GetJumpFlags(player); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + } + else + { + player->mo->momx >>= 1; + player->mo->momy >>= 1; + player->mo->momz >>= 1; + P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + } + } + } + else if (player->mo->state-states == S_PLAY_BOUNCE) + P_SetPlayerMobjState(player->mo, S_PLAY_FALL); // If you're running fast enough, you can create splashes as you run in shallow water. if (!player->climbing @@ -6631,7 +7513,7 @@ static void P_MovePlayer(player_t *player) && (player->speed > runspd || (player->pflags & PF_STARTDASH)) && leveltime % (TICRATE/7) == 0 && player->mo->momz == 0 && !(player->pflags & PF_SLIDING) && !player->spectator) { - mobj_t *water = P_SpawnMobj(player->mo->x, player->mo->y, + mobj_t *water = P_SpawnMobj(player->mo->x - P_ReturnThrustX(NULL, player->mo->angle, player->mo->radius), player->mo->y - P_ReturnThrustY(NULL, player->mo->angle, player->mo->radius), ((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_SPLISH].height, player->mo->scale) : player->mo->watertop), MT_SPLISH); if (player->mo->eflags & MFE_GOOWATER) S_StartSound(water, sfx_ghit); @@ -6660,14 +7542,14 @@ static void P_MovePlayer(player_t *player) if (!(player->charability == CA_FLY || player->charability == CA_SWIM)) // why are you flying when you cannot fly?! { if (player->powers[pw_tailsfly] - || (player->mo->state >= &states[S_PLAY_SPC1] && player->mo->state <= &states[S_PLAY_SPC4])) + || player->mo->state-states == S_PLAY_FLY_TIRED) { if (onground) - P_SetPlayerMobjState(player->mo, S_PLAY_RUN1); + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); else { - player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + player->pflags |= P_GetJumpFlags(player); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } } player->powers[pw_tailsfly] = 0; @@ -6687,7 +7569,7 @@ static void P_MovePlayer(player_t *player) { const fixed_t actionspd = player->actionspd/100; - if (player->charability2 == CA2_MULTIABILITY) + if (player->charflags & SF_MULTIABILITY) { // Adventure-style flying by just holding the button down if (cmd->buttons & BT_JUMP && !(player->pflags & PF_STASIS) && !player->exiting) @@ -6719,11 +7601,10 @@ static void P_MovePlayer(player_t *player) { // Tails-gets-tired Stuff if (player->panim == PA_ABILITY) - P_SetPlayerMobjState(player->mo, S_PLAY_SPC4); + P_SetPlayerMobjState(player->mo, S_PLAY_FLY_TIRED); if (player->charability == CA_FLY && (leveltime % 10 == 0) - && player->mo->state >= &states[S_PLAY_SPC1] - && player->mo->state <= &states[S_PLAY_SPC4] + && player->mo->state-states == S_PLAY_FLY_TIRED && !player->spectator) S_StartSound(player->mo, sfx_pudpud); } @@ -6738,7 +7619,7 @@ static void P_MovePlayer(player_t *player) P_ResetScore(player); // Show the "THOK!" graphic when spinning quickly across the ground. (even applies to non-spinners, in the case of zoom tubes) - if (player->pflags & PF_SPINNING && player->speed > FixedMul(15<<FRACBITS, player->mo->scale) && !(player->pflags & PF_JUMPED)) + if (player->pflags & PF_SPINNING && P_AproxDistance(player->speed, player->mo->momz) > FixedMul(15<<FRACBITS, player->mo->scale) && !(player->pflags & PF_JUMPED)) { P_SpawnSpinMobj(player, player->spinitem); if (demorecording) @@ -6751,7 +7632,7 @@ static void P_MovePlayer(player_t *player) //////////////////////////// // If the player isn't on the ground, make sure they aren't in a "starting dash" position. - if (!onground) + if (!onground && player->powers[pw_carry] != CR_NIGHTSMODE) { player->pflags &= ~PF_STARTDASH; player->dashspeed = 0; @@ -6760,15 +7641,15 @@ static void P_MovePlayer(player_t *player) if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && (player->pflags & PF_SPINNING) && player->speed > FixedMul(4<<FRACBITS, player->mo->scale) && onground && (leveltime & 1) && !(player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) - P_ElementalFireTrail(player); + P_ElementalFire(player, false); - P_DoSpinDash(player, cmd); + P_DoSpinAbility(player, cmd); // jumping P_DoJumpStuff(player, cmd); // If you're not spinning, you'd better not be spindashing! - if (!(player->pflags & PF_SPINNING)) + if (!(player->pflags & PF_SPINNING) && player->powers[pw_carry] != CR_NIGHTSMODE) player->pflags &= ~PF_STARTDASH; ////////////////// @@ -6817,8 +7698,8 @@ static void P_MovePlayer(player_t *player) #endif } // Otherwise, face the direction you're travelling. - else if (player->panim == PA_WALK || player->panim == PA_RUN || player->panim == PA_ROLL - || ((player->mo->state >= &states[S_PLAY_ABL1] && player->mo->state <= &states[S_PLAY_SPC4]) && player->charability == CA_FLY)) + else if (player->panim == PA_WALK || player->panim == PA_RUN || player->panim == PA_DASH || player->panim == PA_ROLL || player->panim == PA_JUMP + || (player->panim == PA_ABILITY && player->mo->state-states == S_PLAY_GLIDE)) player->mo->angle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy); // Update the local angle control. @@ -6828,56 +7709,145 @@ static void P_MovePlayer(player_t *player) localangle2 = player->mo->angle; } - /////////////////////////// - //BOMB SHIELD ACTIVATION,// - //HOMING, AND OTHER COOL // - //STUFF! // - /////////////////////////// + ////////////////// + //SHIELD ACTIVES// + //& SUPER FLOAT!// + ////////////////// - if (cmd->buttons & BT_USE) // Spin button effects + if (player->pflags & PF_JUMPED && !player->exiting && player->mo->health) { - if (player->pflags & PF_JUMPED) // If the player is jumping + mobj_t *lockon = NULL; + if (!player->powers[pw_super] && player->powers[pw_shield] == SH_ATTRACT && !(player->pflags & PF_THOKKED)) { - if (!(player->pflags & PF_USEDOWN)) // If the player is not holding down BT_USE + if ((lockon = P_LookForEnemies(player, false, false))) { - // Jump shield activation - if (!P_PlayerInPain(player) // If the player is not in pain - && !player->climbing // If the player is not climbing - && !(player->pflags & (PF_GLIDING|PF_SLIDING|PF_THOKKED)) // If the player is not gliding or sliding and hasn't used their ability - && !onground) // If the player isn't on the ground + if (P_IsLocalPlayer(player)) // Only display it on your own view. { - if ((player->powers[pw_shield] & SH_NOSTACK) == SH_JUMP && !player->powers[pw_super]) - P_DoJumpShield(player); - else if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]) && player->charability == CA_FLY) - { - P_DoJumpShield(player); - player->mo->momz *= 2; - } + mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker + visual->target = lockon; + P_SetMobjStateNF(visual, visual->info->spawnstate+1); } - // Bomb shield activation - if ((player->powers[pw_shield] & SH_NOSTACK) == SH_BOMB) + } + } + if (cmd->buttons & BT_USE) // Spin button effects + { + if (player->powers[pw_super]) // Super can't use shield actives, only passives + { + if ((player->charability == CA_THOK) // Super Sonic float + && (player->speed > 5*player->mo->scale) // FixedMul(5<<FRACBITS, player->mo->scale), but scale is FRACUNIT-based + && (P_MobjFlip(player->mo)*player->mo->momz <= 0)) { - // Don't let Super Sonic or invincibility use it - if (!(player->powers[pw_super] || player->powers[pw_invulnerability])) - P_BlackOw(player); + if (player->panim != PA_RUN && player->panim != PA_WALK) + { + if (player->speed >= FixedMul(player->runspeed, player->mo->scale)) + P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT_RUN); + else + P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT); + } + + player->mo->momz = 0; + player->pflags &= ~(PF_STARTJUMP|PF_SPINNING); } } - // Super Sonic move - if (player->skin == 0 && player->powers[pw_super] && player->speed > FixedMul(5<<FRACBITS, player->mo->scale) - && P_MobjFlip(player->mo)*player->mo->momz <= 0) + else +#ifdef HAVE_BLUA + if (!LUAh_ShieldSpecial(player)) +#endif { - if (player->panim == PA_ROLL || player->mo->state == &states[S_PLAY_PAIN]) - P_SetPlayerMobjState(player->mo, S_PLAY_SUPERWALK1); - - player->mo->momz = 0; - player->pflags &= ~PF_SPINNING; - player->jumping = 0; // don't cut jump height after bouncing off something + if (!(player->pflags & (PF_USEDOWN|PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY)) // If the player is not holding down BT_USE, or having used an ability previously + && (!(player->powers[pw_shield] & SH_NOSTACK) || !(player->pflags & PF_THOKKED) || ((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP && player->secondjump == UINT8_MAX))) // thokked is optional if you're bubblewrapped/turning super + { + // Force shield activation + if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE) + { + player->pflags |= PF_THOKKED|PF_SHIELDABILITY; + player->mo->momx = player->mo->momy = player->mo->momz = 0; + S_StartSound(player->mo, sfx_ngskid); + } + else + { + switch (player->powers[pw_shield] & SH_NOSTACK) + { + // Super! + case SH_NONE: + if (P_SuperReady(player)) + P_DoSuperTransformation(player, false); + break; + // Whirlwind/Thundercoin shield activation + case SH_WHIRLWIND: + case SH_THUNDERCOIN: + P_DoJumpShield(player); + break; + // Armageddon shield activation + case SH_ARMAGEDDON: + player->pflags |= PF_THOKKED|PF_SHIELDABILITY; + P_BlackOw(player); + break; + // Attract shield activation + case SH_ATTRACT: + player->pflags |= PF_THOKKED|PF_SHIELDABILITY; + player->homing = 2; + P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, lockon)); + if (lockon) + { + player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockon->x, lockon->y); + player->pflags &= ~PF_NOJUMPDAMAGE; + S_StartSound(player->mo, sfx_s3k40); + player->homing = 3*TICRATE; + } + else + S_StartSound(player->mo, sfx_s3ka6); + break; + // Elemental/Bubblewrap shield activation + case SH_ELEMENTAL: + case SH_BUBBLEWRAP: + player->pflags |= PF_THOKKED|PF_SHIELDABILITY; + player->pflags &= ~PF_NOJUMPDAMAGE; + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + player->secondjump = 0; + player->mo->momx = player->mo->momy = 0; + P_SetObjectMomZ(player->mo, -24*FRACUNIT, false); + S_StartSound(player->mo, + ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) + ? sfx_s3k43 + : sfx_s3k44); + break; + // Flame shield activation + case SH_FLAMEAURA: + player->pflags |= PF_THOKKED|PF_SHIELDABILITY; + P_Thrust(player->mo, player->mo->angle, FixedMul(30*FRACUNIT - FixedSqrt(FixedDiv(player->speed, player->mo->scale)), player->mo->scale)); + player->drawangle = player->mo->angle; + S_StartSound(player->mo, sfx_s3k43); + default: + break; + } + } + } } } } // HOMING option. - if (player->charability == CA_HOMINGTHOK) + if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT // Sonic 3D Blast. + && player->pflags & PF_SHIELDABILITY) + { + if (player->homing && player->mo->tracer) + { + P_HomingAttack(player->mo, player->mo->tracer); + if (player->mo->tracer->health <= 0 || (player->mo->tracer->flags2 & MF2_FRET)) + { + P_SetObjectMomZ(player->mo, 6*FRACUNIT, false); + if (player->mo->eflags & MFE_UNDERWATER) + player->mo->momz = FixedMul(player->mo->momz, FRACUNIT/3); + player->homing = 0; + } + } + + // If you're not jumping, then you obviously wouldn't be homing. + if (!(player->pflags & PF_JUMPED)) + player->homing = 0; + } + else if (player->charability == CA_HOMINGTHOK) // Sonic Adventure. { // If you've got a target, chase after it! if (player->homing && player->mo->tracer) @@ -6900,6 +7870,8 @@ static void P_MovePlayer(player_t *player) if (!(player->mo->tracer->flags & MF_BOSS)) player->pflags &= ~PF_THOKKED; + + // P_SetPlayerMobjState(player->mo, S_PLAY_SPRING); -- Speed didn't like it, RIP } } @@ -6926,13 +7898,13 @@ static void P_MovePlayer(player_t *player) } // Make sure you're not teetering when you shouldn't be. - if ((player->mo->state == &states[S_PLAY_TEETER1] || player->mo->state == &states[S_PLAY_TEETER2] || player->mo->state == &states[S_PLAY_SUPERTEETER]) + if (player->panim == PA_EDGE && (player->mo->momx || player->mo->momy || player->mo->momz)) P_SetPlayerMobjState(player->mo, S_PLAY_STND); // Check for teeter! if (!(player->mo->momz || player->mo->momx || player->mo->momy) && !(player->mo->eflags & MFE_GOOWATER) - && player->panim == PA_IDLE && !(player->pflags & (PF_CARRIED|PF_ITEMHANG|PF_ROPEHANG))) + && player->panim == PA_IDLE && !(player->powers[pw_carry])) P_DoTeeter(player); // Toss a flag @@ -6952,10 +7924,11 @@ static void P_MovePlayer(player_t *player) fixed_t oldheight = player->mo->height; // Less height while spinning. Good for spinning under things...? - if ((player->mo->state == &states[player->mo->info->painstate] || player->mo->state == &states[S_PLAY_SUPERHIT]) - || (player->charability2 == CA2_SPINDASH && (player->pflags & (PF_SPINNING|PF_JUMPED))) + if ((player->mo->state == &states[player->mo->info->painstate]) + || ((player->pflags & PF_JUMPED) && !(player->pflags & PF_NOJUMPDAMAGE && player->charflags & SF_NOJUMPSPIN)) + || (player->pflags & PF_SPINNING) || player->powers[pw_tailsfly] || player->pflags & PF_GLIDING - || (player->charability == CA_FLY && (player->mo->state >= &states[S_PLAY_SPC1] && player->mo->state <= &states[S_PLAY_SPC4]))) + || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) player->mo->height = P_GetPlayerSpinHeight(player); else player->mo->height = P_GetPlayerHeight(player); @@ -6971,18 +7944,14 @@ static void P_MovePlayer(player_t *player) if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_SPINNING)) { player->pflags |= PF_SPINNING; - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); } else if (player->mo->ceilingz - player->mo->floorz < player->mo->height) { if ((netgame || multiplayer) && player->spectator) - P_DamageMobj(player->mo, NULL, NULL, 42000); // Respawn crushed spectators + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators else - { - mobj_t *killer = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_NULL); - killer->threshold = 44; // Special flag that it was crushing which killed you. - P_DamageMobj(player->mo, killer, killer, 10000); - } + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_CRUSHED); if (player->playerstate == PST_DEAD) return; @@ -7197,6 +8166,7 @@ static void P_DoZoomTube(player_t *player) else { P_SetTarget(&player->mo->tracer, NULL); // Else, we just let them fly. + player->powers[pw_carry] = CR_NONE; CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found, releasing from track...\n"); } @@ -7254,17 +8224,18 @@ static void P_DoRopeHang(player_t *player) if (player->cmd.buttons & BT_USE && !(player->pflags & PF_STASIS)) // Drop off of the rope { - P_SetTarget(&player->mo->tracer, NULL); + player->pflags |= P_GetJumpFlags(player); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); - player->pflags |= PF_JUMPED; - player->pflags &= ~PF_ROPEHANG; + P_SetTarget(&player->mo->tracer, NULL); + player->powers[pw_carry] = CR_NONE; - if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED) - && !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH) - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); return; } + if (player->mo->state-states != S_PLAY_RIDE) + P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); + // If not allowed to move, we're done here. if (!speed) return; @@ -7354,15 +8325,12 @@ static void P_DoRopeHang(player_t *player) { if (player->mo->tracer->flags & MF_SLIDEME) { - player->pflags |= PF_JUMPED; - player->pflags &= ~PF_ROPEHANG; - - if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED) - && !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH) - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + player->pflags |= P_GetJumpFlags(player); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } P_SetTarget(&player->mo->tracer, NULL); + player->powers[pw_carry] = CR_NONE; CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found!\n"); } @@ -7397,7 +8365,7 @@ static void P_NukeAllPlayers(player_t *player) if (mo == player->mo) continue; - P_DamageMobj(mo, player->mo, player->mo, 1); + P_DamageMobj(mo, player->mo, player->mo, 1, 0); } CONS_Printf(M_GetText("%s caused a world of pain.\n"), player_names[player-players]); @@ -7455,26 +8423,30 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) mo->flags |= MF_SPECIAL|MF_SHOOTABLE; if (mo->type == MT_EGGGUARD && mo->tracer) //nuke Egg Guard's shield! - P_KillMobj(mo->tracer, inflictor, source); + P_KillMobj(mo->tracer, inflictor, source, DMG_NUKE); if (mo->flags & MF_BOSS || mo->type == MT_PLAYER) //don't OHKO bosses nor players! - P_DamageMobj(mo, inflictor, source, 1); + P_DamageMobj(mo, inflictor, source, 1, DMG_NUKE); else - P_DamageMobj(mo, inflictor, source, 1000); + P_DamageMobj(mo, inflictor, source, 1000, DMG_NUKE); } } // // P_LookForEnemies // Looks for something you can hit - Used for homing attack -// Includes monitors and springs! +// If nonenemies is true, includes monitors and springs! +// If bullet is true, you can look up and the distance is further, +// but your total angle span you can look is limited to compensate. // -boolean P_LookForEnemies(player_t *player) +mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet) { mobj_t *mo; thinker_t *think; mobj_t *closestmo = NULL; - angle_t an; + const fixed_t maxdist = FixedMul((bullet ? RING_DIST*2 : RING_DIST), player->mo->scale); + const angle_t span = (bullet ? ANG30 : ANGLE_90); + fixed_t dist, closestdist = 0; for (think = thinkercap.next; think != &thinkercap; think = think->next) { @@ -7482,8 +8454,8 @@ boolean P_LookForEnemies(player_t *player) continue; // not a mobj thinker mo = (mobj_t *)think; - if (!(mo->flags & (MF_ENEMY|MF_BOSS|MF_MONITOR|MF_SPRING))) - continue; // not a valid enemy + if (!(mo->flags & (MF_ENEMY|MF_BOSS|MF_MONITOR|MF_SPRING)) == !(mo->flags2 & MF2_INVERTAIMABLE)) // allows if it has the flags desired XOR it has the invert aimable flag + continue; // not a valid target if (mo->health <= 0) // dead continue; @@ -7497,53 +8469,62 @@ boolean P_LookForEnemies(player_t *player) if ((mo->flags & (MF_ENEMY|MF_BOSS)) && !(mo->flags & MF_SHOOTABLE)) // don't aim at something you can't shoot at anyway (see Egg Guard or Minus) continue; - if (mo->type == MT_DETON) // Don't be STUPID, Sonic! + if (!nonenemies && mo->flags & (MF_MONITOR|MF_SPRING)) continue; - if (((mo->z > player->mo->z+FixedMul(MAXSTEPMOVE, player->mo->scale)) && !(player->mo->eflags & MFE_VERTICALFLIP)) - || ((mo->z+mo->height < player->mo->z+player->mo->height-FixedMul(MAXSTEPMOVE, player->mo->scale)) && (player->mo->eflags & MFE_VERTICALFLIP))) // Reverse gravity check - Flame. - continue; // Don't home upwards! - - if (P_AproxDistance(P_AproxDistance(player->mo->x-mo->x, player->mo->y-mo->y), - player->mo->z-mo->z) > FixedMul(RING_DIST, player->mo->scale)) - continue; // out of range - - if ((twodlevel || player->mo->flags2 & MF2_TWOD) - && abs(player->mo->y-mo->y) > player->mo->radius) - continue; // not in your 2d plane + if (!bullet && mo->type == MT_DETON) // Don't be STUPID, Sonic! + continue; + + { + 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); + if (bullet) + { + if ((R_PointToAngle2(0, 0, dist, zdist) + span) > span*2) + continue; // Don't home outside of desired angle! + } + else // Don't home upwards! + { + if (player->mo->eflags & MFE_VERTICALFLIP) + { + if (mo->z+mo->height < player->mo->z+player->mo->height-FixedMul(MAXSTEPMOVE, player->mo->scale)) + continue; + } + else if (mo->z > player->mo->z+FixedMul(MAXSTEPMOVE, player->mo->scale)) + continue; + } + + dist = P_AproxDistance(dist, zdist); + if (dist > maxdist) + continue; // out of range + } + + if ((twodlevel || player->mo->flags2 & MF2_TWOD) + && abs(player->mo->y-mo->y) > player->mo->radius) + continue; // not in your 2d plane if (mo->type == MT_PLAYER) // Don't chase after other players! continue; - if (closestmo && P_AproxDistance(P_AproxDistance(player->mo->x-mo->x, player->mo->y-mo->y), - player->mo->z-mo->z) > P_AproxDistance(P_AproxDistance(player->mo->x-closestmo->x, - player->mo->y-closestmo->y), player->mo->z-closestmo->z)) + if (closestmo && dist > closestdist) continue; - an = R_PointToAngle2(player->mo->x, player->mo->y, mo->x, mo->y) - player->mo->angle; - - if (an > ANGLE_90 && an < ANGLE_270) + if ((R_PointToAngle2(player->mo->x + P_ReturnThrustX(player->mo, player->mo->angle, player->mo->radius), player->mo->y + P_ReturnThrustY(player->mo, player->mo->angle, player->mo->radius), mo->x, mo->y) - player->mo->angle + span) > span*2) continue; // behind back if (!P_CheckSight(player->mo, mo)) continue; // out of sight closestmo = mo; + closestdist = dist; } - if (closestmo) - { - // Found a target monster - P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, closestmo)); - player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, closestmo->x, closestmo->y); - return true; - } - - return false; + return closestmo; } void P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target { + fixed_t zdist; fixed_t dist; fixed_t ns = 0; @@ -7555,17 +8536,21 @@ void P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target // change angle source->angle = R_PointToAngle2(source->x, source->y, enemy->x, enemy->y); - if (source->player && (!demoplayback || P_AnalogMove(source->player))) + if (source->player) { - if (source->player == &players[consoleplayer]) - localangle = source->angle; - else if (source->player == &players[secondarydisplayplayer]) - localangle2 = source->angle; + source->player->drawangle = source->angle; + if (!demoplayback || P_AnalogMove(source->player)) + { + if (source->player == &players[consoleplayer]) + localangle = source->angle; + else if (source->player == &players[secondarydisplayplayer]) + localangle2 = source->angle; + } } // change slope - dist = P_AproxDistance(P_AproxDistance(enemy->x - source->x, enemy->y - source->y), - enemy->z - source->z); + zdist = ((P_MobjFlip(source) == -1) ? (enemy->z + enemy->height) - (source->z + source->height) : (enemy->z - source->z)); + dist = P_AproxDistance(P_AproxDistance(enemy->x - source->x, enemy->y - source->y), zdist); if (dist < 1) dist = 1; @@ -7580,11 +8565,16 @@ void P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target ns = FixedMul(source->info->speed, source->scale); } else if (source->player) - ns = FixedDiv(FixedMul(source->player->actionspd, source->scale), 3*FRACUNIT/2); + { + if (source->player->charability == CA_HOMINGTHOK && !(source->player->pflags & PF_SHIELDABILITY)) + ns = FixedDiv(FixedMul(source->player->actionspd, source->scale), 3*FRACUNIT/2); + else + ns = FixedMul(45*FRACUNIT, source->scale); + } source->momx = FixedMul(FixedDiv(enemy->x - source->x, dist), ns); source->momy = FixedMul(FixedDiv(enemy->y - source->y, dist), ns); - source->momz = FixedMul(FixedDiv(enemy->z - source->z, dist), ns); + source->momz = FixedMul(FixedDiv(zdist, dist), ns); } // Search for emeralds @@ -7616,6 +8606,113 @@ void P_FindEmerald(void) return; } +// +// P_GetLives +// Get extra lives in new co-op if you're allowed to. +// + +boolean P_GetLives(player_t *player) +{ + INT32 i, maxlivesplayer = -1, livescheck = 1; + if (!(netgame || multiplayer) + || (gametype != GT_COOP) + || (cv_cooplives.value == 1) + || (player->lives == INFLIVES)) + return true; + + if ((cv_cooplives.value == 2 || cv_cooplives.value == 0) && player->lives > 0) + return true; + + if (cv_cooplives.value == 0) // infinite lives + { + player->lives++; + return true; + } + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].lives > livescheck) + { + maxlivesplayer = i; + livescheck = players[i].lives; + } + } + if (maxlivesplayer != -1 && &players[maxlivesplayer] != player) + { + if (cv_cooplives.value == 2 && (P_IsLocalPlayer(player) || P_IsLocalPlayer(&players[maxlivesplayer]))) + S_StartSound(NULL, sfx_jshard); // placeholder + if (players[maxlivesplayer].lives != INFLIVES) + players[maxlivesplayer].lives--; + player->lives++; + if (player->lives < 1) + player->lives = 1; + return true; + } + return (player->lives > 0); +} + +// +// P_ConsiderAllGone +// Shamelessly lifted from TD. Thanks, Sryder! +// + +static void P_ConsiderAllGone(void) +{ + INT32 i, lastdeadplayer = -1, deadtimercheck = INT32_MAX; + + if (countdown2) + return; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].playerstate != PST_DEAD && !players[i].spectator && players[i].mo && players[i].mo->health) + break; + + if (players[i].spectator) + { + if (lastdeadplayer == -1) + lastdeadplayer = i; + } + else if (players[i].lives > 0) + { + lastdeadplayer = i; + if (players[i].deadtimer < deadtimercheck) + deadtimercheck = players[i].deadtimer; + } + } + + if (i == MAXPLAYERS && lastdeadplayer != -1 && deadtimercheck > 2*TICRATE) // the last killed player will reset the level in G_DoReborn + { + //players[lastdeadplayer].spectator = true; + players[lastdeadplayer].outofcoop = true; + players[lastdeadplayer].playerstate = PST_REBORN; + } +} + +void P_RestoreMultiMusic(player_t *player) +{ + if (netgame) + { + if (P_IsLocalPlayer(player)) + S_ChangeMusic(mapmusname, mapmusflags, true); + } + else if (multiplayer) // local multiplayer only + { + // Restore the other player's music once we're dead for long enough + // -- that is, as long as they aren't dead too + if (player == &players[displayplayer] && players[secondarydisplayplayer].lives > 0) + P_RestoreMusic(&players[secondarydisplayplayer]); + else if (player == &players[secondarydisplayplayer] && players[displayplayer].lives > 0) + P_RestoreMusic(&players[displayplayer]); + } +} + // // P_DeathThink // Fall on your face when dying. @@ -7624,6 +8721,8 @@ void P_FindEmerald(void) static void P_DeathThink(player_t *player) { + INT32 j = MAXPLAYERS; + ticcmd_t *cmd = &player->cmd; player->deltaviewheight = 0; @@ -7642,82 +8741,106 @@ static void P_DeathThink(player_t *player) G_UseContinue(); // Even if we don't have one this handles ending the game } + if ((cv_cooplives.value != 1) + && (gametype == GT_COOP) + && (netgame || multiplayer) + && (player->lives <= 0)) + { + for (j = 0; j < MAXPLAYERS; j++) + { + if (!playeringame[j]) + continue; + + if (players[j].lives > 1) + break; + } + } + // Force respawn if idle for more than 30 seconds in shooter modes. if (player->deadtimer > 30*TICRATE && !G_PlatformGametype()) player->playerstate = PST_REBORN; - else if (player->lives > 0 && !G_IsSpecialStage(gamemap)) // Don't allow "click to respawn" in special stages! + else if ((player->lives > 0 || j != MAXPLAYERS) && !G_IsSpecialStage(gamemap)) // Don't allow "click to respawn" in special stages! { - // Respawn with jump button, force respawn time (3 second default, cheat protected) in shooter modes. - if ((cmd->buttons & BT_JUMP) && player->deadtimer > cv_respawntime.value*TICRATE - && gametype != GT_RACE && gametype != GT_COOP) - player->playerstate = PST_REBORN; - - // Instant respawn in race or if you're spectating. - if ((cmd->buttons & BT_JUMP) && (gametype == GT_RACE || player->spectator)) - player->playerstate = PST_REBORN; - - // One second respawn in coop. - if ((cmd->buttons & BT_JUMP) && player->deadtimer > TICRATE && (gametype == GT_COOP || gametype == GT_COMPETITION)) - player->playerstate = PST_REBORN; + if (gametype == GT_COOP && (netgame || multiplayer) && cv_coopstarposts.value == 2) + { + P_ConsiderAllGone(); + if ((player->deadtimer > 5*TICRATE) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE))) + { + //player->spectator = true; + player->outofcoop = true; + player->playerstate = PST_REBORN; + } + } + else + { + // Respawn with jump button, force respawn time (3 second default, cheat protected) in shooter modes. + if (cmd->buttons & BT_JUMP) + { + if (gametype != GT_COOP && player->spectator) + player->playerstate = PST_REBORN; + else switch(gametype) { + case GT_COOP: + if (player->deadtimer > TICRATE) + player->playerstate = PST_REBORN; + break; + case GT_COMPETITION: + if (player->deadtimer > TICRATE) + player->playerstate = PST_REBORN; + break; + case GT_RACE: + player->playerstate = PST_REBORN; + break; + default: + if (player->deadtimer > cv_respawntime.value*TICRATE) + player->playerstate = PST_REBORN; + break; + } + } - // Single player auto respawn - if (!(netgame || multiplayer) && player->deadtimer > 5*TICRATE) - player->playerstate = PST_REBORN; + // Single player auto respawn + if (!(netgame || multiplayer) && player->deadtimer > 5*TICRATE) + player->playerstate = PST_REBORN; + } } - else if ((netgame || multiplayer) && player->deadtimer == 8*TICRATE) + else if ((netgame || multiplayer) && player->deadtimer >= 8*TICRATE) { + + INT32 i, deadtimercheck = INT32_MAX; + // In a net/multiplayer game, and out of lives if (gametype == GT_COMPETITION) { - INT32 i; - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && !players[i].exiting && players[i].lives > 0) + { + if (!playeringame[i]) + continue; + if (!players[i].exiting && players[i].lives) break; + if (players[i].deadtimer < deadtimercheck) + deadtimercheck = players[i].deadtimer; + } - if (i == MAXPLAYERS) + if (i == MAXPLAYERS && deadtimercheck == 8*TICRATE) { // Everyone's either done with the race, or dead. if (!countdown2 || countdown2 > 1*TICRATE) countdown2 = 1*TICRATE; } } + //else if (gametype == GT_COOP) -- moved to G_DoReborn + } - // In a coop game, and out of lives - if (gametype == GT_COOP) - { - INT32 i; - - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && (players[i].exiting || players[i].lives > 0)) - break; - - if (i == MAXPLAYERS) - { - // They're dead, Jim. - //nextmapoverride = spstage_start; - nextmapoverride = gamemap; - countdown2 = 1*TICRATE; - skipstats = true; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i]) - players[i].score = 0; - } - - //emeralds = 0; - tokenbits = 0; - tokenlist = 0; - token = 0; - } - } + if (gametype == GT_COOP && (multiplayer || netgame) && (player->lives <= 0) && (player->deadtimer >= 8*TICRATE || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))) + { + //player->spectator = true; + player->outofcoop = true; + player->playerstate = PST_REBORN; } if (gametype == GT_RACE || gametype == GT_COMPETITION || (gametype == GT_COOP && (multiplayer || netgame))) { // Keep time rolling in race mode - if (!(countdown2 && !countdown) && !player->exiting && !(player->pflags & PF_TIMEOVER)) + if (!(countdown2 && !countdown) && !player->exiting && !(player->pflags & PF_GAMETYPEOVER)) { if (gametype == GT_RACE || gametype == GT_COMPETITION) { @@ -7731,25 +8854,8 @@ static void P_DeathThink(player_t *player) } // Return to level music - if (player->lives <= 0) - { - if (netgame) - { - if (player->deadtimer == gameovertics && P_IsLocalPlayer(player)) - S_ChangeMusic(mapmusname, mapmusflags, true); - } - else if (multiplayer) // local multiplayer only - { - if (player->deadtimer != gameovertics) - ; - // Restore the other player's music once we're dead for long enough - // -- that is, as long as they aren't dead too - else if (player == &players[displayplayer] && players[secondarydisplayplayer].lives > 0) - P_RestoreMusic(&players[secondarydisplayplayer]); - else if (player == &players[secondarydisplayplayer] && players[displayplayer].lives > 0) - P_RestoreMusic(&players[displayplayer]); - } - } + if (gametype != GT_COOP && player->lives <= 0 && player->deadtimer == gameovertics) + P_RestoreMultiMusic(player); } notrealplayer: @@ -7823,9 +8929,9 @@ void P_ResetCamera(player_t *player, camera_t *thiscam) x = player->mo->x - P_ReturnThrustX(player->mo, thiscam->angle, player->mo->radius); y = player->mo->y - P_ReturnThrustY(player->mo, thiscam->angle, player->mo->radius); if (player->mo->eflags & MFE_VERTICALFLIP) - z = player->mo->z + player->mo->height - (cv_viewheight.value<<FRACBITS) - 16*FRACUNIT; + z = player->mo->z + player->mo->height - (41*player->height/48) - 16*FRACUNIT; else - z = player->mo->z + (cv_viewheight.value<<FRACBITS); + z = player->mo->z + (41*player->height/48); // set bits for the camera thiscam->x = x; @@ -7864,9 +8970,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall mo = player->mo; - cameranoclip = (player->pflags & (PF_NOCLIP|PF_NIGHTSMODE)) || (mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!! + cameranoclip = (player->powers[pw_carry] == CR_NIGHTSMODE || player->pflags & PF_NOCLIP) || (mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!! - if (!(player->climbing || (player->pflags & PF_NIGHTSMODE) || player->playerstate == PST_DEAD)) + if (!(player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || tutorialmode)) { if (player->spectator) // force cam off for spectators return true; @@ -7905,7 +9011,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall // if (leveltime > 0 && timeinmap <= 0) // return true; - if (player->pflags & PF_NIGHTSMODE) + if (player->powers[pw_carry] == CR_NIGHTSMODE) { focusangle = mo->angle; focusaiming = 0; @@ -7929,13 +9035,22 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (P_CameraThinker(player, thiscam, resetcalled)) return true; - if (thiscam == &camera) + if (tutorialmode) + { + // force defaults because we have a camera look section + camspeed = (INT32)(atof(cv_cam_speed.defaultvalue) * FRACUNIT); + camstill = (!stricmp(cv_cam_still.defaultvalue, "off")) ? false : true; + camrotate = atoi(cv_cam_rotate.defaultvalue); + camdist = FixedMul((INT32)(atof(cv_cam_dist.defaultvalue) * FRACUNIT), mo->scale); + camheight = FixedMul((INT32)(atof(cv_cam_height.defaultvalue) * FRACUNIT), FixedMul(player->camerascale, mo->scale)); + } + else if (thiscam == &camera) { camspeed = cv_cam_speed.value; camstill = cv_cam_still.value; camrotate = cv_cam_rotate.value; camdist = FixedMul(cv_cam_dist.value, mo->scale); - camheight = FixedMul(cv_cam_height.value, mo->scale); + camheight = FixedMul(cv_cam_height.value, FixedMul(player->camerascale, mo->scale)); } else // Camera 2 { @@ -7943,7 +9058,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall camstill = cv_cam2_still.value; camrotate = cv_cam2_rotate.value; camdist = FixedMul(cv_cam2_dist.value, mo->scale); - camheight = FixedMul(cv_cam2_height.value, mo->scale); + camheight = FixedMul(cv_cam2_height.value, FixedMul(player->camerascale, mo->scale)); } #ifdef REDSANALOG @@ -7962,7 +9077,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall angle = ANGLE_90; else if (camstill || resetcalled || player->playerstate == PST_DEAD) angle = thiscam->angle; - else if (player->pflags & PF_NIGHTSMODE) // NiGHTS Level + else if (player->powers[pw_carry] == CR_NIGHTSMODE) // NiGHTS Level { if ((player->pflags & PF_TRANSFERTOCLOSEST) && player->axis1 && player->axis2) { @@ -7971,7 +9086,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } else if (mo->target) { - if (mo->target->flags & MF_AMBUSH) + if (mo->target->flags2 & MF2_AMBUSH) angle = R_PointToAngle2(mo->target->x, mo->target->y, mo->x, mo->y); else angle = R_PointToAngle2(mo->x, mo->y, mo->target->x, mo->target->y); @@ -8001,53 +9116,32 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall thiscam->angle = angle; } - if (!objectplacing && !(twodlevel || (mo->flags2 & MF2_TWOD)) && !(player->pflags & PF_NIGHTSMODE) && displayplayer == consoleplayer) + if ((((thiscam == &camera) && cv_analog.value) || ((thiscam != &camera) && cv_analog2.value) || demoplayback) && !objectplacing && !(twodlevel || (mo->flags2 & MF2_TWOD)) && (player->powers[pw_carry] != CR_NIGHTSMODE) && displayplayer == consoleplayer) { #ifdef REDSANALOG if ((player->cmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) == (BT_CAMLEFT|BT_CAMRIGHT)); else #endif - if (player->cmd.buttons & BT_CAMLEFT) + if (player->cmd.buttons & BT_CAMRIGHT) { if (thiscam == &camera) - { - if (cv_analog.value || demoplayback) - angle -= FixedAngle(cv_cam_rotspeed.value*FRACUNIT); - else - CV_SetValue(&cv_cam_rotate, camrotate == 0 ? 358 - : camrotate - 2); - } + angle -= FixedAngle(cv_cam_rotspeed.value*FRACUNIT); else - { - if (cv_analog2.value) - angle -= FixedAngle(cv_cam2_rotspeed.value*FRACUNIT); - else - CV_SetValue(&cv_cam2_rotate, camrotate == 0 ? 358 - : camrotate - 2); - } + angle -= FixedAngle(cv_cam2_rotspeed.value*FRACUNIT); } - else if (player->cmd.buttons & BT_CAMRIGHT) + else if (player->cmd.buttons & BT_CAMLEFT) { if (thiscam == &camera) - { - if (cv_analog.value || demoplayback) - angle += FixedAngle(cv_cam_rotspeed.value*FRACUNIT); - else - CV_SetValue(&cv_cam_rotate, camrotate + 2); - } + angle += FixedAngle(cv_cam_rotspeed.value*FRACUNIT); else - { - if (cv_analog2.value) - angle += FixedAngle(cv_cam2_rotspeed.value*FRACUNIT); - else - CV_SetValue(&cv_cam2_rotate, camrotate + 2); - } + angle += FixedAngle(cv_cam2_rotspeed.value*FRACUNIT); } } // sets ideal cam pos if (twodlevel || (mo->flags2 & MF2_TWOD)) dist = 480<<FRACBITS; - else if (player->pflags & PF_NIGHTSMODE) + else if (player->powers[pw_carry] == CR_NIGHTSMODE + || ((maptol & TOL_NIGHTS) && player->capsule && player->capsule->reactiontime > 0 && player == &players[player->capsule->reactiontime-1])) dist = 320<<FRACBITS; else { @@ -8067,11 +9161,11 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall camheight = FixedMul(camheight, 6*FRACUNIT/5); } - if (player->climbing || player->exiting || player->playerstate == PST_DEAD || (player->pflags & (PF_MACESPIN|PF_ITEMHANG|PF_ROPEHANG))) + if (player->climbing || player->exiting || player->playerstate == PST_DEAD || (player->powers[pw_carry] == CR_ROPEHANG || player->powers[pw_carry] == CR_GENERIC || player->powers[pw_carry] == CR_MACESPIN)) dist <<= 1; } - checkdist = dist; + checkdist = (dist = FixedMul(dist, player->camerascale)); if (checkdist < 128*FRACUNIT) checkdist = 128*FRACUNIT; @@ -8111,7 +9205,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } #endif // bad 2D camera code - pviewheight = FixedMul(cv_viewheight.value<<FRACBITS, mo->scale); + pviewheight = FixedMul(41*player->height/48, mo->scale); if (mo->eflags & MFE_VERTICALFLIP) z = mo->z + mo->height - pviewheight - camheight; @@ -8377,7 +9471,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall angle = R_PointToAngle2(0, thiscam->z + thiscam->height, dist, mo->z + mo->height - P_GetPlayerHeight(player)); else angle = R_PointToAngle2(0, thiscam->z, dist, mo->z + P_GetPlayerHeight(player)); - if (player->playerstate != PST_DEAD && !(player->pflags & PF_NIGHTSMODE && player->exiting)) + if (player->playerstate != PST_DEAD) angle += (focusaiming < ANGLE_180 ? focusaiming/2 : InvAngle(InvAngle(focusaiming)/2)); // overcomplicated version of '((signed)focusaiming)/2;' if (twodlevel || (mo->flags2 & MF2_TWOD) || !camstill) // Keep the view still... @@ -8405,7 +9499,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall else mo->flags2 &= ~MF2_SHADOW; -/* if (!resetcalled && (player->pflags & PF_NIGHTSMODE && player->exiting)) +/* if (!resetcalled && (player->powers[pw_carry] == CR_NIGHTSMODE && player->exiting)) { // Don't let the camera match your movement. thiscam->momz = 0; @@ -8431,16 +9525,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall return (x == thiscam->x && y == thiscam->y && z == thiscam->z && angle == thiscam->aiming); } -static boolean P_SpectatorJoinGame(player_t *player) +boolean P_SpectatorJoinGame(player_t *player) { - if (!G_GametypeHasSpectators() && G_IsSpecialStage(gamemap) && useNightsSS) // Special Stage spectators should NEVER be allowed to rejoin the game - { - if (P_IsLocalPlayer(player)) - CONS_Printf(M_GetText("You cannot enter the game while a special stage is in progress.\n")); - player->powers[pw_flashing] += 2*TICRATE; //to prevent message spam. - } - - else if (!cv_allowteamchange.value) + if (gametype != GT_COOP && !cv_allowteamchange.value) { if (P_IsLocalPlayer(player)) CONS_Printf(M_GetText("Server does not allow team change.\n")); @@ -8509,7 +9596,7 @@ static boolean P_SpectatorJoinGame(player_t *player) P_RemoveMobj(player->mo); player->mo = NULL; } - player->spectator = false; + player->spectator = player->outofcoop = false; player->playerstate = PST_REBORN; if (gametype == GT_TAG) @@ -8528,7 +9615,8 @@ static boolean P_SpectatorJoinGame(player_t *player) if (P_IsLocalPlayer(player) && displayplayer != consoleplayer) displayplayer = consoleplayer; - CONS_Printf(M_GetText("%s entered the game.\n"), player_names[player-players]); + if (gametype != GT_COOP) + CONS_Printf(M_GetText("%s entered the game.\n"), player_names[player-players]); return true; // no more player->mo, cannot continue. } else @@ -8657,7 +9745,7 @@ void P_DoPityCheck(player_t *player) if ((player->pity >= 3 || player->pity < 0) && player->powers[pw_shield] == SH_NONE) { if (player->pity > 0) - S_StartSound(player->mo, mobjinfo[MT_PITYSHIELDICO].seesound); + S_StartSound(player->mo, mobjinfo[MT_PITY_ICON].seesound); player->pity = 0; player->powers[pw_shield] = SH_PITY; @@ -8665,81 +9753,484 @@ void P_DoPityCheck(player_t *player) } } -// -// P_PlayerThink -// - -void P_PlayerThink(player_t *player) +static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z, fixed_t *nz) { - ticcmd_t *cmd; - const size_t playeri = (size_t)(player - players); + sector_t *sec = R_PointInSubsector(x, y)->sector; -#ifdef PARANOIA - if (!player->mo) - I_Error("p_playerthink: players[%s].mo == NULL", sizeu1(playeri)); -#endif + if ((sec->ceilingheight - sec->floorheight) < 64*FRACUNIT) + return NULL; - // todo: Figure out what is actually causing these problems in the first place... - if ((player->health <= 0 || player->mo->health <= 0) && player->playerstate == PST_LIVE) //you should be DEAD! + if (sec->ffloors) { - CONS_Debug(DBG_GAMELOGIC, "P_PlayerThink: Player %s in PST_LIVE with 0 health. (\"Zombie bug\")\n", sizeu1(playeri)); - player->playerstate = PST_DEAD; + ffloor_t *rover; + for (rover = sec->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS)) + continue; + + *nz = *rover->t_slope ? P_GetZAt(*rover->t_slope, x, y) : *rover->topheight; + if (abs(z - *nz) <= 56*FRACUNIT) + { + sec = §ors[rover->secnum]; + return sec; + } + } + } - if (player->bot) + *nz = sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : sec->floorheight; + if (abs(z - *nz) > 56*FRACUNIT) + return NULL; + + return sec; +} + +static INT32 P_GetMinecartSpecialLine(sector_t *sec) +{ + INT32 line = -1; + + if (!sec) + return line; + + if (sec->tag != 0) + line = P_FindSpecialLineFromTag(16, sec->tag, -1); + + // Also try for lines facing the sector itself, with tag 0. { - if (player->playerstate == PST_LIVE || player->playerstate == PST_DEAD) + UINT32 i; + for (i = 0; i < sec->linecount; i++) { - if (B_CheckRespawn(player)) - player->playerstate = PST_REBORN; + line_t *li = sec->lines[i]; + if (li->tag == 0 && li->special == 16 && li->frontsector == sec) + line = li - lines; } - if (player->playerstate == PST_REBORN) - return; } -#ifdef SEENAMES - if (netgame && player == &players[displayplayer] && !(leveltime % (TICRATE/5))) + return line; +} + +// Get an axis of a certain ID number +static mobj_t *P_GetAxis(INT32 num) +{ + thinker_t *th; + mobj_t *mobj; + + for (th = thinkercap.next; th != &thinkercap; th = th->next) { - seenplayer = NULL; + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; - if (cv_seenames.value && cv_allowseenames.value && - !(G_TagGametype() && (player->pflags & PF_TAGIT))) - { - mobj_t *mo = P_SpawnNameFinder(player->mo, MT_NAMECHECK); + mobj = (mobj_t *)th; - if (mo) - { - short int i; - mo->flags |= MF_NOCLIPHEIGHT; - for (i = 0; i < 32; i++) - { - // Debug drawing -// if (i&1) -// P_SpawnMobj(mo->x, mo->y, mo->z, MT_SPARK); - if (P_RailThinker(mo)) - break; // mobj was removed (missile hit a wall) or couldn't move - } - } - } + // NiGHTS axes spawn before anything else. If this mobj doesn't have MF2_AXIS, it means we reached the axes' end. + if (!(mobj->flags2 & MF2_AXIS)) + break; + + // Skip if this axis isn't the one we want. + if (mobj->health != num) + continue; + + return mobj; } -#endif + CONS_Alert(CONS_WARNING, "P_GetAxis: Track segment %d is missing!\n", num); + return NULL; +} - if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj)) +// Auxiliary function. For a given position and axis, it calculates the nearest "valid" snap-on position. +static void P_GetAxisPosition(fixed_t x, fixed_t y, mobj_t *amo, fixed_t *newx, fixed_t *newy, angle_t *targetangle, angle_t *grind) +{ + fixed_t ax = amo->x; + fixed_t ay = amo->y; + angle_t ang; + angle_t gr = 0; + + if (amo->type == MT_AXISTRANSFERLINE) { - P_SetTarget(&player->awayviewmobj, NULL); // remove awayviewmobj asap if invalid - player->awayviewtics = 0; // reset to zero + ang = amo->angle; + // Extra security for cardinal directions. + if (ang == ANGLE_90 || ang == ANGLE_270) // Vertical lines + x = ax; + else if (ang == 0 || ang == ANGLE_180) // Horizontal lines + y = ay; + else // Diagonal lines + { + fixed_t distance = R_PointToDist2(ax, ay, x, y); + angle_t fad = ((R_PointToAngle2(ax, ay, x, y) - ang) >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t cosine = FINECOSINE(fad); + angle_t fa = (ang >> ANGLETOFINESHIFT) & FINEMASK; + distance = FixedMul(distance, cosine); + x = ax + FixedMul(distance, FINECOSINE(fa)); + y = ay + FixedMul(distance, FINESINE(fa)); + } } - - if (player->pflags & PF_GLIDING) + else // Keep minecart to circle { - if (player->panim != PA_ABILITY) - P_SetPlayerMobjState(player->mo, S_PLAY_ABL1); + fixed_t rad = amo->radius; + fixed_t distfactor = FixedDiv(rad, R_PointToDist2(ax, ay, x, y)); + + gr = R_PointToAngle2(ax, ay, x, y); + ang = gr + ANGLE_90; + x = ax + FixedMul(x - ax, distfactor); + y = ay + FixedMul(y - ay, distfactor); } - else if ((player->pflags & PF_JUMPED) && !player->powers[pw_super] && player->panim != PA_ROLL && player->charability2 == CA2_SPINDASH) - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); - if (player->flashcount) - player->flashcount--; + *newx = x; + *newy = y; + *targetangle = ang; + *grind = gr; +} + +static void P_SpawnSparks(mobj_t *mo, angle_t maindir) +{ + angle_t fa = (mo->angle >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t c = FixedMul(FINECOSINE(fa), mo->radius); + fixed_t s = FixedMul(FINESINE(fa), mo->radius); + mobj_t *spark; + SINT8 b1 = (leveltime & 1) ? 1 : -1; + SINT8 b2 = (leveltime & 2) ? 1 : -1; + fixed_t r1 = FRACUNIT*P_RandomRange(-1, 1); + fixed_t r2 = FRACUNIT*P_RandomRange(-1, 1); + fixed_t r3 = FRACUNIT*P_RandomRange(-1, 1); + fixed_t fm = (maindir >> ANGLETOFINESHIFT) & FINEMASK; + + spark = P_SpawnMobj(mo->x - b2*s + b1*c, mo->y + b2*c + b1*s, mo->z, MT_MINECARTSPARK); + spark->momx = mo->momx + r1 + 8*FINECOSINE(fm); + spark->momy = mo->momy + r2 + 8*FINESINE(fm); + spark->momz = mo->momz + r3; + + P_Thrust(spark, R_PointToAngle2(mo->x, mo->y, spark->x, spark->y), 8*FRACUNIT); + P_SetScale(spark, FRACUNIT/4); + spark->destscale = spark->scale; + spark->fuse = TICRATE/3; +} + +// Performs a proximity check on a given direction looking for rails. +static mobj_t *P_LookForRails(mobj_t* mobj, fixed_t c, fixed_t s, angle_t targetangle, fixed_t xcom, fixed_t ycom) +{ + INT16 interval = 16; + INT16 fwooffset = FixedHypot(mobj->momx, mobj->momy) >> FRACBITS; + fixed_t x = mobj->x; + fixed_t y = mobj->y; + fixed_t z = mobj->z; + UINT8 i; + + for (i = 4; i <= 10; i++) + { + fixed_t nz; + INT32 lline; + + x += interval*xcom*i + fwooffset*c*i; + y += interval*ycom*i + fwooffset*s*i; + + lline = P_GetMinecartSpecialLine(P_GetMinecartSector(x, y, z, &nz)); + if (lline != -1) + { + fixed_t nx, ny; + angle_t nang, dummy, angdiff; + mobj_t *mark; + mobj_t *snax = P_GetAxis(sides[lines[lline].sidenum[0]].textureoffset >> FRACBITS); + if (!snax) + return NULL; + P_GetAxisPosition(x, y, snax, &nx, &ny, &nang, &dummy); + angdiff = ((nang - targetangle) + ANG10/2) & ~ANGLE_180; + //Axes must be directly parallel or antiparallel, give or take 5 degrees. + if (angdiff < ANG10) + { + mark = P_SpawnMobj(nx, ny, nz, mobj->info->raisestate); + return mark; + } + } + } + return NULL; +} + +static void P_ParabolicMove(mobj_t *mo, fixed_t x, fixed_t y, fixed_t z, fixed_t g, fixed_t speed) +{ + fixed_t dx = x - mo->x; + fixed_t dy = y - mo->y; + fixed_t dz = z - mo->z; + fixed_t dh = P_AproxDistance(dx, dy); + fixed_t c = FixedDiv(dx, dh); + fixed_t s = FixedDiv(dy, dh); + fixed_t fixConst = FixedDiv(speed, g); + + mo->momx = FixedMul(c, speed); + mo->momy = FixedMul(s, speed); + mo->momz = FixedDiv(dh, 2*fixConst) + FixedDiv(dz, FixedDiv(dh, fixConst/2)); +} + +static void P_MinecartThink(player_t *player) +{ + mobj_t *minecart = player->mo->tracer; + angle_t fa; + + if (!minecart || P_MobjWasRemoved(minecart) || !minecart->health) + { + // Minecart died on you, so kill yourself. + P_KillMobj(player->mo, NULL, NULL, 0); + return; + } + + //Limit player's angle to a cone. +#define MINECARTCONEMAX FixedAngle(20*FRACUNIT) + { + angle_t angdiff = player->mo->angle - minecart->angle; + if (angdiff < ANGLE_180 && angdiff > MINECARTCONEMAX) + player->mo->angle = minecart->angle + MINECARTCONEMAX; + else if (angdiff > ANGLE_180 && angdiff < InvAngle(MINECARTCONEMAX)) + player->mo->angle = minecart->angle - MINECARTCONEMAX; + + if (angdiff + minecart->angle != player->mo->angle && (!demoplayback || P_AnalogMove(player))) + { + if (player == &players[consoleplayer]) + localangle = player->mo->angle; + else if (player == &players[secondarydisplayplayer]) + localangle2 = player->mo->angle; + } + } + + // Player holding jump? + if (!(player->cmd.buttons & BT_JUMP)) + player->pflags &= ~PF_JUMPDOWN; + + // Handle segments. + P_HandleMinecartSegments(minecart); + + // Force 0 friction. + minecart->friction = FRACUNIT; + + fa = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK; + if (!P_TryMove(minecart, minecart->x + FINECOSINE(fa), minecart->y + FINESINE(fa), true)) + { + P_KillMobj(minecart, NULL, NULL, 0); + return; + } + + if (P_IsObjectOnGround(minecart)) + { + sector_t *sec; + INT32 lnum; + fixed_t dummy; + + // Just hit floor. + if (minecart->eflags & MFE_JUSTHITFLOOR) + { + S_StopSound(minecart); + S_StartSound(minecart, sfx_s3k96); + } + + sec = P_GetMinecartSector(minecart->x, minecart->y, minecart->z, &dummy); + + if (sec) + lnum = P_GetMinecartSpecialLine(sec); + + // Update axis if the cart is standing on a rail. + if (sec && lnum != -1) + { + mobj_t *axis = P_GetAxis(sides[lines[lnum].sidenum[0]].textureoffset >> FRACBITS); + fixed_t newx, newy; + angle_t targetangle, grind; + angle_t prevangle, angdiff; + mobj_t *detleft = NULL; + mobj_t *detright = NULL; + mobj_t *sidelock = NULL; + boolean jumped = false; + fixed_t currentSpeed; + + if (!axis) + { + P_KillMobj(minecart, NULL, NULL, 0); + return; + } + + minecart->movefactor = 0; + P_ResetScore(player); + // Handle angle and position + P_GetAxisPosition(minecart->x, minecart->y, axis, &newx, &newy, &targetangle, &grind); + if (axis->type != MT_AXISTRANSFERLINE) + P_SpawnSparks(minecart, grind); + P_TryMove(minecart, newx, newy, true); + + // Set angle based on target + prevangle = minecart->angle; + angdiff = targetangle - minecart->angle; + if (angdiff < ANGLE_90 + ANG2 || angdiff > ANGLE_270 - ANG2) + minecart->angle = targetangle; + else + minecart->angle = targetangle + ANGLE_180; + angdiff = (minecart->angle - prevangle); + if (angdiff && (!demoplayback || P_AnalogMove(player))) // maintain relative angle on turns + { + player->mo->angle += angdiff; + if (player == &players[consoleplayer]) + localangle += angdiff; + else if (player == &players[secondarydisplayplayer]) + localangle2 += angdiff; + } + + // Sideways detection + if (minecart->flags2 & MF2_AMBUSH) + { + angle_t fa2 = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t c = FINECOSINE(fa2); + fixed_t s = FINESINE(fa2); + + detleft = P_LookForRails(minecart, c, s, targetangle, -s, c); + detright = P_LookForRails(minecart, c, s, targetangle, s, -c); + } + + // How fast are we going? + currentSpeed = FixedHypot(minecart->momx, minecart->momy); + angdiff = R_PointToAngle2(0, 0, minecart->momx, minecart->momy) - minecart->angle; + if (angdiff > ANGLE_90 && angdiff < ANGLE_270) + currentSpeed *= -1; + + // Player-specific behavior. + if (detleft && player->cmd.sidemove < 0) + sidelock = detleft; + else if (detright && player->cmd.sidemove > 0) + sidelock = detright; + + //if (player->cmd.buttons & BT_USE && currentSpeed > 4*FRACUNIT) + // currentSpeed -= FRACUNIT/8; + + // Jumping + if (sidelock || ((player->cmd.buttons & BT_JUMP) && !(player->pflags & PF_JUMPDOWN))) + { + player->pflags |= PF_JUMPDOWN; + + if (minecart->eflags & MFE_ONGROUND) + minecart->eflags &= ~MFE_ONGROUND; + minecart->z += P_MobjFlip(minecart); + if (sidelock) + P_ParabolicMove(minecart, sidelock->x, sidelock->y, sidelock->z, gravity, max(currentSpeed, 10 * FRACUNIT)); + else + minecart->momz = 10 * FRACUNIT; + + S_StartSound(minecart, sfx_s3k51); + jumped = true; + } + + if (!jumped) + { + // Natural acceleration and boosters + if (currentSpeed < minecart->info->speed) + currentSpeed += FRACUNIT/4; + + if (minecart->standingslope) + { + fixed_t fa2 = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t front = P_GetZAt(minecart->standingslope, minecart->x, minecart->y); + fixed_t back = P_GetZAt(minecart->standingslope, minecart->x - FINECOSINE(fa2), minecart->y - FINESINE(fa2)); + + if (abs(front - back) < 3*FRACUNIT) + currentSpeed += (back - front)/3; + } + + // Go forward at our current speed + P_InstaThrust(minecart, minecart->angle, currentSpeed); + + // On-track ka-klong sound FX. + minecart->movecount += abs(currentSpeed); + if (minecart->movecount > 128*FRACUNIT) + { + minecart->movecount %= 128*FRACUNIT; + S_StartSound(minecart, minecart->info->activesound); + } + } + } + else + { + minecart->movefactor++; + if ((P_IsObjectOnGround(minecart) && minecart->movefactor >= 5) // off rail + || (abs(minecart->momx) < minecart->scale/2 && abs(minecart->momy) < minecart->scale/2)) // hit a wall + { + P_KillMobj(minecart, NULL, NULL, 0); + return; + } + } + } + + P_SetPlayerMobjState(player->mo, S_PLAY_STND); + + // Move player to minecart. + P_TeleportMove(player->mo, minecart->x - minecart->momx, minecart->y - minecart->momy, minecart->z + max(minecart->momz, 0) + 8*FRACUNIT); + if (player->powers[pw_carry] != CR_MINECART) + return; + player->mo->momx = player->mo->momy = player->mo->momz = 0; + P_TryMove(player->mo, player->mo->x + minecart->momx, player->mo->y + minecart->momy, true); + + if (player->powers[pw_flashing] == flashingtics) + player->powers[pw_flashing]--; +} + +// +// P_PlayerThink +// + +void P_PlayerThink(player_t *player) +{ + ticcmd_t *cmd; + const size_t playeri = (size_t)(player - players); + +#ifdef PARANOIA + if (!player->mo) + I_Error("p_playerthink: players[%s].mo == NULL", sizeu1(playeri)); +#endif + + // todo: Figure out what is actually causing these problems in the first place... + if (player->mo->health <= 0 && player->playerstate == PST_LIVE) //you should be DEAD! + { + CONS_Debug(DBG_GAMELOGIC, "P_PlayerThink: Player %s in PST_LIVE with 0 health. (\"Zombie bug\")\n", sizeu1(playeri)); + player->playerstate = PST_DEAD; + } + + if (player->bot) + { + if (player->playerstate == PST_LIVE || player->playerstate == PST_DEAD) + { + if (B_CheckRespawn(player)) + player->playerstate = PST_REBORN; + } + if (player->playerstate == PST_REBORN) + return; + } + +#ifdef SEENAMES + if (netgame && player == &players[displayplayer] && !(leveltime % (TICRATE/5))) + { + seenplayer = NULL; + + if (cv_seenames.value && cv_allowseenames.value && + !(G_TagGametype() && (player->pflags & PF_TAGIT))) + { + mobj_t *mo = P_SpawnNameFinder(player->mo, MT_NAMECHECK); + + if (mo) + { + short int i; + mo->flags |= MF_NOCLIPHEIGHT; + for (i = 0; i < 32; i++) + { + // Debug drawing +// if (i&1) +// P_SpawnMobj(mo->x, mo->y, mo->z, MT_SPARK); + if (P_RailThinker(mo)) + break; // mobj was removed (missile hit a wall) or couldn't move + } + } + } + } +#endif + + if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj)) + { + P_SetTarget(&player->awayviewmobj, NULL); // remove awayviewmobj asap if invalid + player->awayviewtics = 0; // reset to zero + } + + if (player->flashcount) + player->flashcount--; if (player->awayviewtics && player->awayviewtics != -1) player->awayviewtics--; @@ -8778,31 +10269,28 @@ void P_PlayerThink(player_t *player) if (i == MAXPLAYERS && player->exiting == 3*TICRATE) // finished player->exiting = (14*TICRATE)/5 + 1; - // If 10 seconds are left on the timer, + // If 11 seconds are left on the timer, // begin the drown music for countdown! - if (countdown == 11*TICRATE - 1) - { - if (P_IsLocalPlayer(player)) - S_ChangeMusicInternal("drown", false); - } + if (countdown == 11*TICRATE - 1 && P_IsLocalPlayer(player)) + S_ChangeMusicInternal("_drown", false); // If you've hit the countdown and you haven't made // it to the exit, you're a goner! else if (countdown == 1 && !player->exiting && player->lives > 0) { - if (netgame && player->health > 0) + if (netgame && player->mo->health > 0) CONS_Printf(M_GetText("%s ran out of time.\n"), player_names[player-players]); - player->pflags |= PF_TIMEOVER; + player->pflags |= PF_GAMETYPEOVER; - if (player->pflags & PF_NIGHTSMODE) + if (player->powers[pw_carry] == CR_NIGHTSMODE) { P_DeNightserizePlayer(player); S_StartScreamSound(player->mo, sfx_s3k66); } player->lives = 2; // Don't start the game over music! - P_DamageMobj(player->mo, NULL, NULL, 10000); + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL); player->lives = 0; if (player->playerstate == PST_DEAD) @@ -8860,7 +10348,7 @@ void P_PlayerThink(player_t *player) { if (cv_playersforexit.value) // Count to be sure everyone's exited { - INT32 i; + INT32 i, total = 0, exiting = 0; for (i = 0; i < MAXPLAYERS; i++) { @@ -8869,11 +10357,12 @@ void P_PlayerThink(player_t *player) if (players[i].lives <= 0) continue; - if (!players[i].exiting || players[i].exiting > 3) - break; + total++; + if (players[i].exiting && players[i].exiting < 4) + exiting++; } - if (i == MAXPLAYERS) + if (!total || ((4*exiting)/total) >= cv_playersforexit.value) { if (server) SendNetXCmd(XD_EXITLEVEL, NULL, 0); @@ -8900,7 +10389,12 @@ void P_PlayerThink(player_t *player) if (!player->spectator) P_PlayerInSpecialSector(player); + else if ( +#else + if (player->spectator && #endif + gametype == GT_COOP && (netgame || multiplayer) && cv_coopstarposts.value == 2) + P_ConsiderAllGone(); if (player->playerstate == PST_DEAD) { @@ -8913,14 +10407,14 @@ void P_PlayerThink(player_t *player) // Make sure spectators always have a score and ring count of 0. if (player->spectator) { - player->score = 0; + if (gametype != GT_COOP) + player->score = 0; player->mo->health = 1; - player->health = 1; + player->rings = player->spheres = 0; } - - if ((netgame || multiplayer) && player->lives <= 0) + else if ((netgame || multiplayer) && player->lives <= 0 && gametype != GT_COOP) { - // In Co-Op, replenish a user's lives if they are depleted. + // Outside of Co-Op, replenish a user's lives if they are depleted. // of course, this is just a cheap hack, meh... player->lives = cv_startinglives.value; } @@ -8946,7 +10440,7 @@ void P_PlayerThink(player_t *player) player->realtime = leveltime; } - if ((netgame || splitscreen) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing]) + if (player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing] && G_GametypeHasSpectators()) { if (P_SpectatorJoinGame(player)) return; // player->mo was removed. @@ -8954,7 +10448,7 @@ void P_PlayerThink(player_t *player) // Even if not NiGHTS, pull in nearby objects when walking around as John Q. Elliot. if (!objectplacing && !((netgame || multiplayer) && player->spectator) - && maptol & TOL_NIGHTS && (!(player->pflags & PF_NIGHTSMODE) || player->powers[pw_nights_helper])) + && maptol & TOL_NIGHTS && (player->powers[pw_carry] != CR_NIGHTSMODE || player->powers[pw_nights_helper])) { thinker_t *th; mobj_t *mo2; @@ -8969,8 +10463,12 @@ void P_PlayerThink(player_t *player) mo2 = (mobj_t *)th; - if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN - || mo2->type == MT_BLUEBALL)) + 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)) + continue; + + if (mo2->flags2 & MF2_NIGHTSPULL) continue; if (P_AproxDistance(P_AproxDistance(mo2->x - x, mo2->y - y), mo2->z - z) > FixedMul(128*FRACUNIT, player->mo->scale)) @@ -8979,6 +10477,9 @@ void P_PlayerThink(player_t *player) // Yay! The thing's in reach! Pull it in! mo2->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT; mo2->flags2 |= MF2_NIGHTSPULL; + // New NiGHTS attract speed dummied out because the older behavior + // is exploited as a mechanic. Uncomment to enable. + mo2->movefactor = 0; // 40*FRACUNIT; // initialize the NightsItemChase timer P_SetTarget(&mo2->tracer, player->mo); } } @@ -8994,9 +10495,20 @@ void P_PlayerThink(player_t *player) // for a bit after a teleport. if (player->mo->reactiontime) player->mo->reactiontime--; - else if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT) + else if (player->powers[pw_carry] == CR_MINECART) + { + if (!P_AnalogMove(player)) + player->mo->angle = (cmd->angleturn << 16 /* not FRACBITS */); + + ticruned++; + if ((cmd->angleturn & TICCMD_RECEIVED) == 0) + ticmiss++; + + P_MinecartThink(player); + } + else if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && (player->powers[pw_carry] == CR_ROPEHANG || player->powers[pw_carry] == CR_ZOOMTUBE)) { - if (player->pflags & PF_ROPEHANG) + if (player->powers[pw_carry] == CR_ROPEHANG) { if (!P_AnalogMove(player)) player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */); @@ -9006,24 +10518,175 @@ void P_PlayerThink(player_t *player) ticmiss++; P_DoRopeHang(player); - P_SetPlayerMobjState(player->mo, S_PLAY_CARRY); P_DoJumpStuff(player, &player->cmd); } - else + else //if (player->powers[pw_carry] == CR_ZOOMTUBE) { P_DoZoomTube(player); - if (!(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH) - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); + if (!(player->panim == PA_ROLL)) + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); } player->rmomx = player->rmomy = 0; // no actual momentum from your controls P_ResetScore(player); } else + { + if (player->bumpertime == TICRATE/2 && player->mo->hnext) + { + // Center player to NiGHTS bumper here because if you try to set player's position in + // P_TouchSpecialThing case MT_NIGHTSBUMPER, that position is fudged in the time + // between that routine in the previous tic + // and reaching here in the current tic + P_TeleportMove(player->mo, player->mo->hnext->x, player->mo->hnext->y + , player->mo->hnext->z + FixedMul(player->mo->hnext->height/4, player->mo->hnext->scale)); + P_SetTarget(&player->mo->hnext, NULL); + } P_MovePlayer(player); + } if (!player->mo) return; // P_MovePlayer removed player->mo. + // deez New User eXperiences. + { + // Directionchar! + // Camera angle stuff. + if (player->exiting) // no control, no modification + ; + else if (!(player->pflags & PF_DIRECTIONCHAR) + || (player->climbing // stuff where the direction is forced at all times + || (player->pflags & PF_GLIDING)) + || (player->powers[pw_carry] == CR_NIGHTSMODE) + || (P_AnalogMove(player) || twodlevel || player->mo->flags2 & MF2_TWOD) // keep things synchronised up there, since the camera IS seperate from player motion when that happens + || G_RingSlingerGametype()) // no firing rings in directions your player isn't aiming + player->drawangle = player->mo->angle; + else if (P_PlayerInPain(player)) + ; + else if (player->powers[pw_carry] && player->mo->tracer) // carry + { + switch (player->powers[pw_carry]) + { + case CR_PLAYER: + if (player->mo->tracer->player) + { + player->drawangle = player->mo->tracer->player->drawangle; + break; + } + /* FALLTHRU */ + case CR_MINECART: + case CR_GENERIC: + player->drawangle = player->mo->tracer->angle; + break; + /* -- in case we wanted to have the camera freely movable during zoom tubes + case CR_ZOOMTUBE:*/ + case CR_ROPEHANG: + if (player->mo->momx || player->mo->momy) + { + player->drawangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); + break; + } + /* FALLTHRU */ + default: + player->drawangle = player->mo->angle; + break; + } + } + else if ((player->skidtime > (TICRATE/2 - 2) || ((player->pflags & (PF_SPINNING|PF_STARTDASH)) == PF_SPINNING)) && (abs(player->rmomx) > 5*player->mo->scale || abs(player->rmomy) > 5*player->mo->scale)) // spin/skid force + player->drawangle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy); + else if (((player->charability2 == CA2_GUNSLINGER || player->charability2 == CA2_MELEE) && player->panim == PA_ABILITY2) || player->pflags & PF_STASIS || player->skidtime) + ; + else + { + angle_t diff; + UINT8 factor; + + if (player->pflags & PF_SLIDING) + { +#if 0 // fun hydrocity style horizontal spin + if (player->mo->eflags & MFE_TOUCHWATER || player->powers[pw_flashing] > (flashingtics/4)*3) + { + diff = (player->mo->angle - player->drawangle); + factor = 4; + } + else + { + diff = factor = 0; + player->drawangle += ANGLE_22h; + } +#else + diff = (player->mo->angle - player->drawangle); + factor = 4; +#endif + } + else if (player->pflags & PF_STARTDASH) + { + diff = (player->mo->angle - player->drawangle); + factor = 4; + } + else if (cmd->forwardmove || cmd->sidemove) // only when you're pressing movement keys + { + diff = ((player->mo->angle + R_PointToAngle2(0, 0, cmd->forwardmove<<FRACBITS, -cmd->sidemove<<FRACBITS)) - player->drawangle); + factor = 4; + } + else if (player->rmomx || player->rmomy) + diff = factor = 0; + else + { + diff = (player->mo->angle - player->drawangle); + factor = 8; + } + + if (diff) + { + if (diff > ANGLE_180) + diff = InvAngle(InvAngle(diff)/factor); + else + diff /= factor; + player->drawangle += diff; + } + } + + // Autobrake! check ST_drawInput if you modify this + { + boolean currentlyonground = P_IsObjectOnGround(player->mo); + + if (!player->powers[pw_carry] + && ((player->pflags & (PF_AUTOBRAKE|PF_APPLYAUTOBRAKE)) == (PF_AUTOBRAKE|PF_APPLYAUTOBRAKE)) + && !(cmd->forwardmove || cmd->sidemove) + && (player->rmomx || player->rmomy) + && (!player->capsule || (player->capsule->reactiontime != (player-players)+1))) + { + fixed_t acceleration = (player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration) * player->thrustfactor * 20; + angle_t moveAngle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy); + + if (!currentlyonground) + acceleration /= 2; + + if (player->mo->movefactor != FRACUNIT) // Friction-scaled acceleration... + acceleration = FixedMul(acceleration<<FRACBITS, player->mo->movefactor)>>FRACBITS; + + P_Thrust(player->mo, moveAngle, -acceleration); + } + + if (!(player->pflags & PF_AUTOBRAKE) + || player->powers[pw_carry] + || player->panim == PA_SPRING + || player->panim == PA_PAIN + || !player->mo->health + || player->climbing + || player->pflags & (PF_SPINNING|PF_SLIDING) + || player->bumpertime) + player->pflags &= ~PF_APPLYAUTOBRAKE; + else if (currentlyonground || player->powers[pw_tailsfly]) + player->pflags |= PF_APPLYAUTOBRAKE; + } + } + + if (player->powers[pw_pushing]) + player->powers[pw_pushing]--; + + player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame. + // Unset statis flags after moving. // In other words, if you manually set stasis via code, // it lasts for one tic. @@ -9047,10 +10710,17 @@ void P_PlayerThink(player_t *player) { mobj_t *gmobj = P_SpawnGhostMobj(player->mo); gmobj->fuse = 2; + if (gmobj->tracer) + gmobj->tracer->fuse = 2; if (leveltime & 1) { gmobj->frame &= ~FF_TRANSMASK; gmobj->frame |= tr_trans70<<FF_TRANSSHIFT; + if (gmobj->tracer) + { + gmobj->tracer->frame &= ~FF_TRANSMASK; + gmobj->tracer->frame |= tr_trans70<<FF_TRANSSHIFT; + } } // Hide the mobj from our sights if we're the displayplayer and chasecam is off, @@ -9064,26 +10734,13 @@ void P_PlayerThink(player_t *player) #endif // check for use - if (!(player->pflags & PF_NIGHTSMODE)) + if (player->powers[pw_carry] != CR_NIGHTSMODE) { if (cmd->buttons & BT_USE) player->pflags |= PF_USEDOWN; else player->pflags &= ~PF_USEDOWN; } - else if (player->mo->tracer) // match tracer's position with yours when NiGHTS - { - P_UnsetThingPosition(player->mo->tracer); - player->mo->tracer->x = player->mo->x; - player->mo->tracer->y = player->mo->y; - if (player->mo->eflags & MFE_VERTICALFLIP) - player->mo->tracer->z = player->mo->z + player->mo->height - player->mo->tracer->height; - else - player->mo->tracer->z = player->mo->z; - player->mo->tracer->floorz = player->mo->floorz; - player->mo->tracer->ceilingz = player->mo->ceilingz; - P_SetThingPosition(player->mo->tracer); - } // Counters, time dependent power ups. // Time Bonus & Ring Bonus count settings @@ -9095,13 +10752,13 @@ void P_PlayerThink(player_t *player) if (player->powers[pw_invulnerability] && player->powers[pw_invulnerability] < UINT16_MAX) player->powers[pw_invulnerability]--; - if (player->powers[pw_flashing] && player->powers[pw_flashing] < UINT16_MAX && ((player->pflags & PF_NIGHTSMODE) || player->powers[pw_flashing] < flashingtics)) + if (player->powers[pw_flashing] && player->powers[pw_flashing] < UINT16_MAX && ((player->powers[pw_carry] == CR_NIGHTSMODE) || player->powers[pw_flashing] < flashingtics)) player->powers[pw_flashing]--; - if (player->powers[pw_tailsfly] && player->powers[pw_tailsfly] < UINT16_MAX && player->charability != CA_SWIM && !(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) // tails fly counter + if (player->powers[pw_tailsfly] && player->powers[pw_tailsfly] < UINT16_MAX && player->charability != CA_SWIM) // tails fly counter player->powers[pw_tailsfly]--; - if (player->powers[pw_underwater] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)) + if (player->powers[pw_underwater] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_PROTECTWATER))) { if (player->powers[pw_underwater] <= 12*TICRATE+1) P_RestoreMusic(player); //incase they were about to drown @@ -9111,7 +10768,7 @@ void P_PlayerThink(player_t *player) else if (player->powers[pw_underwater] && !(maptol & TOL_NIGHTS) && !((netgame || multiplayer) && player->spectator)) // underwater timer player->powers[pw_underwater]--; - if (player->powers[pw_spacetime] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)) + if (player->powers[pw_spacetime] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_PROTECTWATER))) player->powers[pw_spacetime] = 0; else if (player->powers[pw_spacetime] && !(maptol & TOL_NIGHTS) && !((netgame || multiplayer) && player->spectator)) // underwater timer player->powers[pw_spacetime]--; @@ -9137,15 +10794,25 @@ void P_PlayerThink(player_t *player) player->powers[pw_nocontrol] = 0; //pw_super acts as a timer now - if (player->powers[pw_super]) + if (player->powers[pw_super] + && (player->mo->state < &states[S_PLAY_SUPER_TRANS1] + || player->mo->state > &states[S_PLAY_SUPER_TRANS6])) player->powers[pw_super]++; - if (player->powers[pw_ingoop]) + if (player->powers[pw_carry] == CR_BRAKGOOP) { - if (player->mo->state == &states[S_PLAY_STND]) - player->mo->tics = 2; + if (!player->powers[pw_flashing]) + { + if (player->mo->state != &states[S_PLAY_STND]) + P_SetPlayerMobjState(player->mo, S_PLAY_STND); + else + player->mo->tics = 2; + } + else + P_SetTarget(&player->mo->tracer, NULL); - player->powers[pw_ingoop]--; + if (!player->mo->tracer) + player->powers[pw_carry] = CR_NONE; } if (player->bumpertime) @@ -9180,23 +10847,65 @@ void P_PlayerThink(player_t *player) player->losstime--; // Flash player after being hit. - if (!(player->pflags & PF_NIGHTSMODE)) + if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < flashingtics && (leveltime & 1)) + player->mo->flags2 |= MF2_DONTDRAW; + else + player->mo->flags2 &= ~MF2_DONTDRAW; + + player->pflags &= ~PF_SLIDING; + +#define dashmode player->dashmode + // Dash mode - thanks be to Iceman404 + if ((player->charflags & SF_DASHMODE) && !(player->gotflag) && !(maptol & TOL_NIGHTS)) // woo, dashmode! no nights tho. { - if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < flashingtics && (leveltime & 1)) - player->mo->flags2 |= MF2_DONTDRAW; - else - player->mo->flags2 &= ~MF2_DONTDRAW; + boolean totallyradical = player->speed >= FixedMul(player->runspeed, player->mo->scale); + boolean floating = (player->secondjump == 1); + + if ((totallyradical && !floating) || (player->pflags & PF_STARTDASH)) + { + if (dashmode < 3*TICRATE + 3) + dashmode++; // Counter. Adds 1 to dash mode per tic in top speed. + if (dashmode == 3*TICRATE) // This isn't in the ">=" equation because it'd cause the sound to play infinitely. + S_StartSound(player->mo, sfx_s3ka2); // If the player enters dashmode, play this sound on the the tic it starts. + } + else if ((!totallyradical || !floating) && !(player->pflags & PF_SPINNING)) + { + if (dashmode > 3) + dashmode -= 3; // Rather than lose it all, it gently counts back down! + else + dashmode = 0; + } + + if (dashmode < 3*TICRATE) // Exits Dash Mode if you drop below speed/dash counter tics. Not in the above block so it doesn't keep disabling in midair. + { + player->normalspeed = skins[player->skin].normalspeed; // Reset to default if not capable of entering dash mode. + player->jumpfactor = skins[player->skin].jumpfactor; + } + else if (P_IsObjectOnGround(player->mo)) // Activate dash mode if we're on the ground. + { + if (player->normalspeed < skins[player->skin].normalspeed*2) // If the player normalspeed is not currently at normalspeed*2 in dash mode, add speed each tic + player->normalspeed += FRACUNIT/5; // Enter Dash Mode smoothly. + + if (player->jumpfactor < FixedMul(skins[player->skin].jumpfactor, 5*FRACUNIT/4)) // Boost jump height. + player->jumpfactor += FRACUNIT/300; + } + + if (player->normalspeed >= skins[player->skin].normalspeed*2) + { + mobj_t *ghost = P_SpawnGhostMobj(player->mo); // Spawns afterimages + ghost->fuse = 2; // Makes the images fade quickly + } } - else if (player->mo->tracer) + else if (dashmode) { - if (player->powers[pw_flashing] & 1) - player->mo->tracer->flags2 |= MF2_DONTDRAW; - else - player->mo->tracer->flags2 &= ~MF2_DONTDRAW; + if (dashmode >= 3*TICRATE) // catch getting the flag! + { + player->normalspeed = skins[player->skin].normalspeed; + player->jumpfactor = skins[player->skin].jumpfactor; + } + dashmode = 0; } - - player->pflags &= ~PF_SLIDING; - +#undef dashmode /* // Colormap verification { @@ -9279,10 +10988,15 @@ void P_PlayerAfterThink(player_t *player) if (thiscam && thiscam->chase) P_MoveChaseCamera(player, thiscam, false); } + if (player->followmobj) + { + P_RemoveMobj(player->followmobj); + P_SetTarget(&player->followmobj, NULL); + } return; } - if (player->pflags & PF_NIGHTSMODE) + if (player->powers[pw_carry] == CR_NIGHTSMODE) { player->powers[pw_gravityboots] = 0; //player->mo->eflags &= ~MFE_VERTICALFLIP; @@ -9392,36 +11106,21 @@ void P_PlayerAfterThink(player_t *player) if (player->currentweapon == WEP_RAIL && (!(player->ringweapons & RW_RAIL) || !player->powers[pw_railring])) player->currentweapon = 0; - // If you're out of rings, but have Infinity Rings left, switch to that. - if (player->currentweapon != 0 && player->health <= 1 && player->powers[pw_infinityring]) - player->currentweapon = 0; - if (P_IsLocalPlayer(player) && (player->pflags & PF_WPNDOWN) && player->currentweapon != oldweapon) S_StartSound(NULL, sfx_wepchg); - if (player->pflags & PF_GLIDING) - { - if (player->panim != PA_ABILITY) - P_SetPlayerMobjState(player->mo, S_PLAY_ABL1); - } - else if (player->pflags & PF_SLIDING) + if ((player->pflags & PF_SLIDING) && ((player->pflags & (PF_JUMPED|PF_NOJUMPDAMAGE)) != PF_JUMPED)) P_SetPlayerMobjState(player->mo, player->mo->info->painstate); - else if (player->pflags & PF_JUMPED - && ((!player->powers[pw_super] && player->panim != PA_ROLL) - || player->mo->state == &states[player->mo->info->painstate]) - && player->charability2 == CA2_SPINDASH) - P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); - if (player->pflags & PF_CARRIED && player->mo->tracer) + /* if (player->powers[pw_carry] == CR_NONE && player->mo->tracer && !player->homing) + P_SetTarget(&player->mo->tracer, NULL); + else */ + if (player->powers[pw_carry] == CR_PLAYER && player->mo->tracer) { player->mo->height = FixedDiv(P_GetPlayerHeight(player), FixedDiv(14*FRACUNIT,10*FRACUNIT)); - // State check for the carrier - Flame - // You are an IDIOT, those aren't even the right frames! >_> - JTE - if (player->mo->tracer->player - && !(player->mo->tracer->state >= &states[S_PLAY_ABL1] - && player->mo->tracer->state <= &states[S_PLAY_SPC4])) - player->pflags &= ~PF_CARRIED; + if (player->mo->tracer->player && !(player->mo->tracer->player->pflags & PF_CANCARRY)) + player->powers[pw_carry] = CR_NONE; if (player->mo->eflags & MFE_VERTICALFLIP) { @@ -9429,7 +11128,7 @@ void P_PlayerAfterThink(player_t *player) && (player->mo->tracer->eflags & MFE_VERTICALFLIP)) // Reverse gravity check for the carrier - Flame player->mo->z = player->mo->tracer->z + player->mo->tracer->height + FixedMul(FRACUNIT, player->mo->scale); else - player->pflags &= ~PF_CARRIED; + player->powers[pw_carry] = CR_NONE; } else { @@ -9437,11 +11136,11 @@ void P_PlayerAfterThink(player_t *player) && !(player->mo->tracer->eflags & MFE_VERTICALFLIP)) // Correct gravity check for the carrier - Flame player->mo->z = player->mo->tracer->z - player->mo->height - FixedMul(FRACUNIT, player->mo->scale); else - player->pflags &= ~PF_CARRIED; + player->powers[pw_carry] = CR_NONE; } if (player->mo->tracer->health <= 0) - player->pflags &= ~PF_CARRIED; + player->powers[pw_carry] = CR_NONE; else { P_TryMove(player->mo, player->mo->tracer->x, player->mo->tracer->y, true); @@ -9464,14 +11163,20 @@ void P_PlayerAfterThink(player_t *player) } if (P_AproxDistance(player->mo->x - player->mo->tracer->x, player->mo->y - player->mo->tracer->y) > player->mo->radius) - player->pflags &= ~PF_CARRIED; + player->powers[pw_carry] = CR_NONE; - P_SetPlayerMobjState(player->mo, S_PLAY_CARRY); + if (player->powers[pw_carry] != CR_NONE) + { + if (player->mo->state-states != S_PLAY_RIDE) + P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); + } + else + P_SetTarget(&player->mo->tracer, NULL); if (player-players == consoleplayer && botingame) - CV_SetValue(&cv_analog2, !(player->pflags & PF_CARRIED)); + CV_SetValue(&cv_analog2, (player->powers[pw_carry] != CR_PLAYER)); } - else if (player->pflags & PF_ITEMHANG && player->mo->tracer) + else if (player->powers[pw_carry] == CR_GENERIC && player->mo->tracer) { // tracer is what you're hanging onto P_UnsetThingPosition(player->mo); @@ -9483,7 +11188,8 @@ void P_PlayerAfterThink(player_t *player) player->mo->z = player->mo->tracer->z - FixedDiv(player->mo->height, 3*FRACUNIT/2); player->mo->momx = player->mo->momy = player->mo->momz = 0; P_SetThingPosition(player->mo); - P_SetPlayerMobjState(player->mo, S_PLAY_CARRY); + if (player->mo->state-states != S_PLAY_RIDE) + P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); // Controllable missile if (player->mo->tracer->type == MT_BLACKEGGMAN_MISSILE) @@ -9499,12 +11205,12 @@ void P_PlayerAfterThink(player_t *player) if (player->mo->z <= player->mo->floorz || player->mo->tracer->health <= 0) { - player->pflags &= ~PF_ITEMHANG; + player->powers[pw_carry] = CR_NONE; P_SetTarget(&player->mo->tracer, NULL); } } } - else if (player->pflags & PF_MACESPIN && player->mo->tracer && player->mo->tracer->target) + else if (player->powers[pw_carry] == CR_MACESPIN && player->mo->tracer && player->mo->tracer->tracer) { player->mo->height = P_GetPlayerSpinHeight(player); // tracer is what you're hanging onto.... @@ -9512,27 +11218,26 @@ void P_PlayerAfterThink(player_t *player) player->mo->momy = (player->mo->tracer->y - player->mo->y)*2; player->mo->momz = (player->mo->tracer->z - (player->mo->height-player->mo->tracer->height/2) - player->mo->z)*2; P_TeleportMove(player->mo, player->mo->tracer->x, player->mo->tracer->y, player->mo->tracer->z - (player->mo->height-player->mo->tracer->height/2)); - player->pflags |= PF_JUMPED; - player->secondjump = 0; - player->pflags &= ~PF_THOKKED; - - if (cmd->forwardmove > 0) - player->mo->tracer->target->lastlook += 2; - else if (cmd->forwardmove < 0 && player->mo->tracer->target->lastlook > player->mo->tracer->target->movecount) - player->mo->tracer->target->lastlook -= 2; - - if (!(player->mo->tracer->target->flags & MF_SLIDEME) // Noclimb on chain parameters gives this - && !(twodlevel || player->mo->flags2 & MF2_TWOD)) // why on earth would you want to turn them in 2D mode? + if (!player->powers[pw_flashing]) // handle getting hurt { - player->mo->tracer->target->health += cmd->sidemove; - player->mo->angle += cmd->sidemove<<ANGLETOFINESHIFT; // 2048 --> ANGLE_MAX + player->pflags |= PF_JUMPED; + player->pflags &= ~PF_NOJUMPDAMAGE; + player->secondjump = 0; + player->pflags &= ~PF_THOKKED; - if (!demoplayback || P_AnalogMove(player)) + if ((player->mo->tracer->tracer->flags & MF_SLIDEME) // Noclimb on chain parameters gives this + && !(twodlevel || player->mo->flags2 & MF2_TWOD)) // why on earth would you want to turn them in 2D mode? { - if (player == &players[consoleplayer]) - localangle = player->mo->angle; // Adjust the local control angle. - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; + player->mo->tracer->tracer->angle += cmd->sidemove<<ANGLETOFINESHIFT; + player->mo->angle += cmd->sidemove<<ANGLETOFINESHIFT; // 2048 --> ANGLE_MAX + + if (!demoplayback || P_AnalogMove(player)) + { + if (player == &players[consoleplayer]) + localangle = player->mo->angle; // Adjust the local control angle. + else if (player == &players[secondarydisplayplayer]) + localangle2 = player->mo->angle; + } } } } @@ -9548,7 +11253,7 @@ void P_PlayerAfterThink(player_t *player) { // defaults to make sure 1st person cam doesn't do anything weird on startup player->deltaviewheight = 0; - player->viewheight = FixedMul(cv_viewheight.value << FRACBITS, player->mo->scale); + player->viewheight = FixedMul(41*player->height/48, player->mo->scale); if (player->mo->eflags & MFE_VERTICALFLIP) player->viewz = player->mo->z + player->mo->height - player->viewheight; else @@ -9567,4 +11272,224 @@ void P_PlayerAfterThink(player_t *player) if (P_IsObjectOnGround(player->mo)) player->mo->pmomz = 0; + + if (player->followmobj && (player->spectator || player->mo->health <= 0 || player->followmobj->type != player->followitem)) + { + P_RemoveMobj(player->followmobj); + P_SetTarget(&player->followmobj, NULL); + } + + if (!player->spectator && player->mo->health && player->followitem) + { + if (!player->followmobj || P_MobjWasRemoved(player->followmobj)) + { + P_SetTarget(&player->followmobj, P_SpawnMobjFromMobj(player->mo, 0, 0, 0, player->followitem)); + P_SetTarget(&player->followmobj->tracer, player->mo); + player->followmobj->flags2 |= MF2_LINKDRAW; + } + + if (player->followmobj) + { +#ifdef HAVE_BLUA + if (LUAh_FollowMobj(player, player->followmobj) || P_MobjWasRemoved(player->followmobj)) + {;} + else +#endif + { + switch (player->followmobj->type) + { + case MT_TAILSOVERLAY: // c: + { + // init... + boolean smilesonground = P_IsObjectOnGround(player->mo); + angle_t horizangle = player->drawangle; + fixed_t zoffs = 0; + fixed_t backwards = -1*FRACUNIT; + boolean doroll = (player->panim == PA_ROLL || player->panim == PA_JUMP); + angle_t rollangle; + boolean panimchange; + INT32 ticnum = 0; + statenum_t chosenstate; + + if (!player->followmobj->skin) + { + player->followmobj->skin = player->mo->skin; + P_SetMobjState(player->followmobj, S_TAILSOVERLAY_STAND); + player->followmobj->movecount = -1; + } + + panimchange = (player->followmobj->movecount != (INT32)player->panim); + + // initial position... + if (doroll) + { + fixed_t testval, zdist; + if (player->speed < FRACUNIT) + testval = FRACUNIT; + else + { + testval = (FixedMul(player->speed, FINECOSINE((horizangle - R_PointToAngle2(0, 0, player->rmomx, player->rmomy)) >> ANGLETOFINESHIFT))); + if (testval < FRACUNIT) + testval = FRACUNIT; + } + if (smilesonground && !player->mo->reactiontime) + zdist = (player->mo->z - player->followmobj->threshold); + else + zdist = player->mo->momz; + rollangle = R_PointToAngle2(0, 0, testval, -P_MobjFlip(player->mo)*zdist); + zoffs = 3*FRACUNIT + 12*FINESINE(rollangle >> ANGLETOFINESHIFT); + backwards = -12*FINECOSINE(rollangle >> ANGLETOFINESHIFT); + } + else if (player->panim == PA_RUN) + backwards = -5*FRACUNIT; + else if (player->panim == PA_SPRING) + { + zoffs += 4*FRACUNIT; + backwards /= 2; + } + else if (player->panim == PA_PAIN) + backwards /= 16; + else if (player->mo->state-states == S_PLAY_GASP) + { + backwards /= 16; + zoffs += 12*FRACUNIT; + } + else if (player->mo->state-states == S_PLAY_EDGE) + { + backwards /= 16; + zoffs = 3*FRACUNIT; + } + else if (player->panim == PA_ABILITY2) + { + zoffs = -7*FRACUNIT; + backwards = -9*FRACUNIT; + } + else if (player->mo->sprite2 == SPR2_FLY || player->mo->sprite2 == SPR2_TIRE) + backwards = -5*FRACUNIT; + + // sprite... + if (doroll) + { + statenum_t add = ((rollangle > ANGLE_180) ? 2 : 0); + if (add) + rollangle = InvAngle(rollangle); + rollangle += ANG15; // modify the thresholds to be nice clean numbers + if (rollangle > ANG60) + chosenstate = S_TAILSOVERLAY_PLUS60DEGREES + add; + else if (rollangle > ANG30) + chosenstate = S_TAILSOVERLAY_PLUS30DEGREES + add; + else + chosenstate = S_TAILSOVERLAY_0DEGREES; + } + else if (player->panim == PA_SPRING) + chosenstate = S_TAILSOVERLAY_MINUS60DEGREES; + else if (player->panim == PA_FALL || player->mo->state-states == S_PLAY_RIDE) + chosenstate = S_TAILSOVERLAY_PLUS60DEGREES; + else if (player->panim == PA_PAIN) + chosenstate = S_TAILSOVERLAY_PAIN; + else if (player->mo->state-states == S_PLAY_GASP) + chosenstate = S_TAILSOVERLAY_GASP; + else if (player->mo->state-states == S_PLAY_EDGE) + chosenstate = S_TAILSOVERLAY_EDGE; + else if (player->panim == PA_RUN) + chosenstate = S_TAILSOVERLAY_RUN; + else if (player->panim == PA_WALK) + { + if (!smilesonground || player->mo->state-states == S_PLAY_SKID) + chosenstate = S_TAILSOVERLAY_PLUS30DEGREES; + else if (player->speed >= FixedMul(player->runspeed/2, player->mo->scale)) + chosenstate = S_TAILSOVERLAY_0DEGREES; + else + chosenstate = S_TAILSOVERLAY_MINUS30DEGREES; + } + else if (player->mo->sprite2 == SPR2_FLY) + chosenstate = S_TAILSOVERLAY_FLY; + else if (player->mo->sprite2 == SPR2_TIRE) + chosenstate = S_TAILSOVERLAY_TIRE; + else if (player->panim == PA_ABILITY2) + chosenstate = S_TAILSOVERLAY_PLUS30DEGREES; + else if (player->panim == PA_IDLE) + chosenstate = S_TAILSOVERLAY_STAND; + else + chosenstate = S_INVISIBLE; + + // state... + if (panimchange) + { + player->followmobj->sprite2 = -1; + P_SetMobjState(player->followmobj, chosenstate); + } + else + { + if (player->followmobj->state != states+chosenstate) + { + if (states[chosenstate].sprite == SPR_PLAY) + player->followmobj->sprite2 = P_GetSkinSprite2(((skin_t *)player->followmobj->skin), (states[chosenstate].frame & FF_FRAMEMASK), player); + P_SetMobjState(player->followmobj, chosenstate); + } + } + + if (player->fly1 != 0 && player->powers[pw_tailsfly] != 0 && !smilesonground) + P_SetMobjState(player->followmobj, chosenstate); + + // animation... + if (player->panim == PA_SPRING || player->panim == PA_FALL || player->mo->state-states == S_PLAY_RIDE) + { + if (FixedDiv(abs(player->mo->momz), player->mo->scale) < 20<<FRACBITS) + ticnum = 2; + else + ticnum = 1; + } + else if (player->panim == PA_PAIN) + ticnum = 2; + else if (player->mo->state-states == S_PLAY_GASP) + player->followmobj->tics = -1; + else if (player->mo->sprite2 == SPR2_TIRE) + ticnum = 4; + else if (player->panim != PA_IDLE) + ticnum = player->mo->tics; + + if (ticnum && player->followmobj->tics > ticnum) + player->followmobj->tics = ticnum; + + // final handling... + player->followmobj->color = player->mo->color; + player->followmobj->threshold = player->mo->z; + player->followmobj->movecount = player->panim; + player->followmobj->angle = horizangle; + player->followmobj->scale = player->mo->scale; + P_SetScale(player->followmobj, player->mo->scale); + player->followmobj->destscale = player->mo->destscale; + player->followmobj->radius = player->mo->radius; + player->followmobj->height = player->mo->height; + zoffs = FixedMul(zoffs, player->followmobj->scale); + + if (player->mo->eflags & MFE_VERTICALFLIP) + { + player->followmobj->eflags |= MFE_VERTICALFLIP; + player->followmobj->flags2 |= MF2_OBJECTFLIP; + zoffs = player->mo->height - player->followmobj->height - zoffs; + } + else + { + player->followmobj->eflags &= ~MFE_VERTICALFLIP; + player->followmobj->flags2 &= ~MF2_OBJECTFLIP; + } + + P_UnsetThingPosition(player->followmobj); + player->followmobj->x = player->mo->x + P_ReturnThrustX(player->followmobj, player->followmobj->angle, FixedMul(backwards, player->followmobj->scale)); + player->followmobj->y = player->mo->y + P_ReturnThrustY(player->followmobj, player->followmobj->angle, FixedMul(backwards, player->followmobj->scale)); + player->followmobj->z = player->mo->z + zoffs; + P_SetThingPosition(player->followmobj); + } + break; + default: + var1 = 1; + var2 = 0; + A_CapeChase(player->followmobj); + break; + } + } + } + } } diff --git a/src/r_bsp.c b/src/r_bsp.c index a6e54182ba2c15e0604b71d1fbacb4fc6976a96a..d521d9f4d4943a6ea5e341738a20e2100dadb91b 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -15,6 +15,7 @@ #include "g_game.h" #include "r_local.h" #include "r_state.h" +#include "r_portal.h" // Add seg portals #include "r_splats.h" #include "p_local.h" // camera @@ -26,11 +27,11 @@ side_t *sidedef; line_t *linedef; sector_t *frontsector; sector_t *backsector; -boolean portalline; // is curline a portal seg? // very ugly realloc() of drawsegs at run-time, I upped it to 512 // instead of 256.. and someone managed to send me a level with // 896 drawsegs! So too bad here's a limit removal a-la-Boom +drawseg_t *curdrawsegs = NULL; /**< This is used to handle multiple lists for masked drawsegs. */ drawseg_t *drawsegs = NULL; drawseg_t *ds_p = NULL; @@ -220,10 +221,7 @@ static INT32 R_DoorClosed(void) // preserve a kind of transparent door/lift special effect: && (backsector->ceilingheight >= frontsector->ceilingheight || curline->sidedef->toptexture) - && (backsector->floorheight <= frontsector->floorheight || curline->sidedef->bottomtexture) - - // properly render skies (consider door "open" if both ceilings are sky): - && (backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum); + && (backsector->floorheight <= frontsector->floorheight || curline->sidedef->bottomtexture); } // @@ -237,8 +235,6 @@ static INT32 R_DoorClosed(void) sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, INT32 *ceilinglightlevel, boolean back) { - INT32 mapnum = -1; - if (floorlightlevel) *floorlightlevel = sec->floorlightsec == -1 ? sec->lightlevel : sectors[sec->floorlightsec].lightlevel; @@ -247,10 +243,10 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, *ceilinglightlevel = sec->ceilinglightsec == -1 ? sec->lightlevel : sectors[sec->ceilinglightsec].lightlevel; - // If the sector has a midmap, it's probably from 280 type - if (sec->midmap != -1) - mapnum = sec->midmap; - else if (sec->heightsec != -1) + // if (sec->midmap != -1) + // mapnum = sec->midmap; + // In original colormap code, this block did not run if sec->midmap was set + if (!sec->extra_colormap && sec->heightsec != -1) { const sector_t *s = §ors[sec->heightsec]; mobj_t *viewmobj = viewplayer->mo; @@ -274,8 +270,6 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, tempsec->floorheight = s->floorheight; tempsec->ceilingheight = s->ceilingheight; - mapnum = s->midmap; - if ((underwater && (tempsec-> floorheight = sec->floorheight, tempsec->ceilingheight = s->floorheight - 1, !back)) || viewz <= s->floorheight) { // head-below-floor hack @@ -301,7 +295,6 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, tempsec->ceiling_yoffs = s->ceiling_yoffs; tempsec->ceilingpic_angle = s->ceilingpic_angle; } - mapnum = s->bottommap; } tempsec->lightlevel = s->lightlevel; @@ -325,8 +318,6 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, tempsec->floor_yoffs = tempsec->ceiling_yoffs = s->ceiling_yoffs; tempsec->floorpic_angle = tempsec->ceilingpic_angle = s->ceilingpic_angle; - mapnum = s->topmap; - if (s->floorpic == skyflatnum) // SKYFIX? { tempsec->ceilingheight = tempsec->floorheight-1; @@ -357,11 +348,6 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, sec = tempsec; } - if (mapnum >= 0 && (size_t)mapnum < num_extra_colormaps) - sec->extra_colormap = &extra_colormaps[mapnum]; - else - sec->extra_colormap = NULL; - return sec; } @@ -404,6 +390,7 @@ static void R_AddLine(seg_t *line) INT32 x1, x2; angle_t angle1, angle2, span, tspan; static sector_t tempsec; + boolean bothceilingssky = false, bothfloorssky = false; portalline = false; @@ -473,7 +460,7 @@ static void R_AddLine(seg_t *line) line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, line2); if (line2 >= 0) // found it! { - R_AddPortal(line->linedef-lines, line2, x1, x2); // Remember the lines for later rendering + Portal_Add2Lines(line->linedef-lines, line2, x1, x2); // Remember the lines for later rendering //return; // Don't fill in that space now! goto clipsolid; } @@ -490,6 +477,25 @@ static void R_AddLine(seg_t *line) doorclosed = 0; + if (backsector->ceilingpic == skyflatnum && frontsector->ceilingpic == skyflatnum) + bothceilingssky = true; + if (backsector->floorpic == skyflatnum && frontsector->floorpic == skyflatnum) + bothfloorssky = true; + + if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then + { + if ( +#ifdef POLYOBJECTS + !line->polyseg && +#endif + !line->sidedef->midtexture + && ((!frontsector->ffloors && !backsector->ffloors) + || (frontsector->tag == backsector->tag))) + return; // line is empty, don't even bother + + goto clippass; // treat like wide open window instead + } + // Closed door. #ifdef ESLOPE if (frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope) @@ -508,48 +514,59 @@ static void R_AddLine(seg_t *line) SLOPEPARAMS( backsector->f_slope, backf1, backf2, backsector->floorheight) SLOPEPARAMS( backsector->c_slope, backc1, backc2, backsector->ceilingheight) #undef SLOPEPARAMS - if ((backc1 <= frontf1 && backc2 <= frontf2) - || (backf1 >= frontc1 && backf2 >= frontc2)) + // if both ceilings are skies, consider it always "open" + // same for floors + if (!bothceilingssky && !bothfloorssky) { - goto clipsolid; - } + if ((backc1 <= frontf1 && backc2 <= frontf2) + || (backf1 >= frontc1 && backf2 >= frontc2)) + { + goto clipsolid; + } - // Check for automap fix. Store in doorclosed for r_segs.c - doorclosed = (backc1 <= backf1 && backc2 <= backf2 - && ((backc1 >= frontc1 && backc2 >= frontc2) || curline->sidedef->toptexture) - && ((backf1 <= frontf1 && backf2 >= frontf2) || curline->sidedef->bottomtexture) - && (backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum)); + // Check for automap fix. Store in doorclosed for r_segs.c + doorclosed = (backc1 <= backf1 && backc2 <= backf2 + && ((backc1 >= frontc1 && backc2 >= frontc2) || curline->sidedef->toptexture) + && ((backf1 <= frontf1 && backf2 >= frontf2) || curline->sidedef->bottomtexture)); - if (doorclosed) - goto clipsolid; + if (doorclosed) + goto clipsolid; + } // Window. - if (backc1 != frontc1 || backc2 != frontc2 - || backf1 != frontf1 || backf2 != frontf2) - { - goto clippass; - } + if (!bothceilingssky) // ceilings are always the "same" when sky + if (backc1 != frontc1 || backc2 != frontc2) + goto clippass; + if (!bothfloorssky) // floors are always the "same" when sky + if (backf1 != frontf1 || backf2 != frontf2) + goto clippass; } else #endif { - if (backsector->ceilingheight <= frontsector->floorheight - || backsector->floorheight >= frontsector->ceilingheight) + // if both ceilings are skies, consider it always "open" + // same for floors + if (!bothceilingssky && !bothfloorssky) { - goto clipsolid; - } + if (backsector->ceilingheight <= frontsector->floorheight + || backsector->floorheight >= frontsector->ceilingheight) + { + goto clipsolid; + } - // Check for automap fix. Store in doorclosed for r_segs.c - doorclosed = R_DoorClosed(); - if (doorclosed) - goto clipsolid; + // Check for automap fix. Store in doorclosed for r_segs.c + doorclosed = R_DoorClosed(); + if (doorclosed) + goto clipsolid; + } // Window. - if (backsector->ceilingheight != frontsector->ceilingheight - || backsector->floorheight != frontsector->floorheight) - { - goto clippass; - } + if (!bothceilingssky) // ceilings are always the "same" when sky + if (backsector->ceilingheight != frontsector->ceilingheight) + goto clippass; + if (!bothfloorssky) // floors are always the "same" when sky + if (backsector->floorheight != frontsector->floorheight) + goto clippass; } // Reject empty lines used for triggers and special events. @@ -873,11 +890,11 @@ static void R_Subsector(size_t num) light = R_GetPlaneLight(frontsector, floorcenterz, false); if (frontsector->floorlightsec == -1) floorlightlevel = *frontsector->lightlist[light].lightlevel; - floorcolormap = frontsector->lightlist[light].extra_colormap; + floorcolormap = *frontsector->lightlist[light].extra_colormap; light = R_GetPlaneLight(frontsector, ceilingcenterz, false); if (frontsector->ceilinglightsec == -1) ceilinglightlevel = *frontsector->lightlist[light].lightlevel; - ceilingcolormap = frontsector->lightlist[light].extra_colormap; + ceilingcolormap = *frontsector->lightlist[light].extra_colormap; } sub->sector->extra_colormap = frontsector->extra_colormap; @@ -886,7 +903,8 @@ static void R_Subsector(size_t num) #ifdef ESLOPE frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : #endif - frontsector->floorheight) < viewz || (frontsector->heightsec != -1 + frontsector->floorheight) < viewz || frontsector->floorpic == skyflatnum + || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum))) { floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, @@ -973,7 +991,7 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, - *rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover + *rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover #ifdef POLYOBJECTS_PLANES , NULL #endif @@ -1019,7 +1037,7 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, - frontsector->lightlist[light].extra_colormap, rover + *frontsector->lightlist[light].extra_colormap, rover #ifdef POLYOBJECTS_PLANES , NULL #endif @@ -1068,29 +1086,11 @@ static void R_Subsector(size_t num) && polysec->floorheight >= floorcenterz && (viewz < polysec->floorheight)) { - fixed_t xoff, yoff; - xoff = polysec->floor_xoffs; - yoff = polysec->floor_yoffs; - - if (po->angle != 0) { - angle_t fineshift = po->angle >> ANGLETOFINESHIFT; - - xoff -= FixedMul(FINECOSINE(fineshift), po->centerPt.x)+FixedMul(FINESINE(fineshift), po->centerPt.y); - yoff -= FixedMul(FINESINE(fineshift), po->centerPt.x)-FixedMul(FINECOSINE(fineshift), po->centerPt.y); - } else { - xoff -= po->centerPt.x; - yoff += po->centerPt.y; - } - light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight); ffloor[numffloors].plane = R_FindPlane(polysec->floorheight, polysec->floorpic, - polysec->lightlevel, xoff, yoff, - polysec->floorpic_angle-po->angle, - NULL, - NULL -#ifdef POLYOBJECTS_PLANES - , po -#endif + polysec->lightlevel, polysec->floor_xoffs, polysec->floor_yoffs, + polysec->floorpic_angle-po->angle, + NULL, NULL, po #ifdef ESLOPE , NULL // will ffloors be slopable eventually? #endif @@ -1115,27 +1115,10 @@ static void R_Subsector(size_t num) && polysec->ceilingheight <= ceilingcenterz && (viewz > polysec->ceilingheight)) { - fixed_t xoff, yoff; - xoff = polysec->ceiling_xoffs; - yoff = polysec->ceiling_yoffs; - - if (po->angle != 0) { - angle_t fineshift = po->angle >> ANGLETOFINESHIFT; - - xoff -= FixedMul(FINECOSINE(fineshift), po->centerPt.x)+FixedMul(FINESINE(fineshift), po->centerPt.y); - yoff -= FixedMul(FINESINE(fineshift), po->centerPt.x)-FixedMul(FINECOSINE(fineshift), po->centerPt.y); - } else { - xoff -= po->centerPt.x; - yoff += po->centerPt.y; - } - light = R_GetPlaneLight(frontsector, polysec->ceilingheight, viewz < polysec->ceilingheight); ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic, - polysec->lightlevel, xoff, yoff, polysec->ceilingpic_angle-po->angle, - NULL, NULL -#ifdef POLYOBJECTS_PLANES - , po -#endif + polysec->lightlevel, polysec->ceiling_xoffs, polysec->ceiling_yoffs, polysec->ceilingpic_angle-po->angle, + NULL, NULL, po #ifdef ESLOPE , NULL // will ffloors be slopable eventually? #endif @@ -1205,7 +1188,7 @@ void R_Prep3DFloors(sector_t *sector) ffloor_t *rover; ffloor_t *best; fixed_t bestheight, maxheight; - INT32 count, i, mapnum; + INT32 count, i; sector_t *sec; #ifdef ESLOPE pslope_t *bestslope = NULL; @@ -1244,7 +1227,7 @@ void R_Prep3DFloors(sector_t *sector) #endif sector->lightlist[0].lightlevel = §or->lightlevel; sector->lightlist[0].caster = NULL; - sector->lightlist[0].extra_colormap = sector->extra_colormap; + sector->lightlist[0].extra_colormap = §or->extra_colormap; sector->lightlist[0].flags = 0; maxheight = INT32_MAX; @@ -1310,11 +1293,6 @@ void R_Prep3DFloors(sector_t *sector) sector->lightlist[i].slope = bestslope; #endif sec = §ors[best->secnum]; - mapnum = sec->midmap; - if (mapnum >= 0 && (size_t)mapnum < num_extra_colormaps) - sec->extra_colormap = &extra_colormaps[mapnum]; - else - sec->extra_colormap = NULL; if (best->flags & FF_NOSHADE) { @@ -1324,12 +1302,12 @@ void R_Prep3DFloors(sector_t *sector) else if (best->flags & FF_COLORMAPONLY) { sector->lightlist[i].lightlevel = sector->lightlist[i-1].lightlevel; - sector->lightlist[i].extra_colormap = sec->extra_colormap; + sector->lightlist[i].extra_colormap = &sec->extra_colormap; } else { sector->lightlist[i].lightlevel = best->toplightlevel; - sector->lightlist[i].extra_colormap = sec->extra_colormap; + sector->lightlist[i].extra_colormap = &sec->extra_colormap; } if (best->flags & FF_DOUBLESHADOW) @@ -1400,13 +1378,5 @@ void R_RenderBSPNode(INT32 bspnum) bspnum = bsp->children[side^1]; } - // PORTAL CULLING - if (portalcullsector) { - sector_t *sect = subsectors[bspnum & ~NF_SUBSECTOR].sector; - if (sect != portalcullsector) - return; - portalcullsector = NULL; - } - R_Subsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR); } diff --git a/src/r_bsp.h b/src/r_bsp.h index e3662e2e6ad23f6c25efed2ceb44f861a2dd15eb..825be6064b078ba0f5c0966b1d726c72e2546c07 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -29,6 +29,7 @@ extern boolean portalline; // is curline a portal seg? extern INT32 checkcoord[12][4]; +extern drawseg_t *curdrawsegs; extern drawseg_t *drawsegs; extern drawseg_t *ds_p; extern INT32 doorclosed; @@ -38,7 +39,6 @@ void R_ClearClipSegs(void); void R_PortalClearClipSegs(INT32 start, INT32 end); void R_ClearDrawSegs(void); void R_RenderBSPNode(INT32 bspnum); -void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2); #ifdef POLYOBJECTS void R_SortPolyObjects(subsector_t *sub); diff --git a/src/r_data.c b/src/r_data.c index bd12eb248012b2bbee3649a783b4799cf3a54a61..6e2dfa0cf3967d13c27b34165787ec8b0d68b1ca 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -22,10 +22,10 @@ #include "w_wad.h" #include "z_zone.h" #include "p_setup.h" // levelflats -#include "v_video.h" // pLocalPalette +#include "v_video.h" // pMasterPalette #include "dehacked.h" -#if defined (_WIN32) || defined (_WIN32_WCE) +#ifdef _WIN32 #include <malloc.h> // alloca(sizeof) #endif @@ -141,11 +141,14 @@ static INT32 tidcachelen = 0; // R_DrawColumnInCache // Clip and draw a column from a patch into a cached post. // -static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, INT32 originy, INT32 cacheheight) +static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight) { INT32 count, position; UINT8 *source; INT32 topdelta, prevdelta = -1; + INT32 originy = originPatch->originy; + + (void)patchheight; // This parameter is unused while (patch->topdelta != 0xff) { @@ -160,6 +163,7 @@ static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, INT32 orig if (position < 0) { count += position; + source -= position; // start further down the column position = 0; } @@ -173,6 +177,138 @@ static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, INT32 orig } } +// +// R_DrawFlippedColumnInCache +// Similar to R_DrawColumnInCache; it draws the column inverted, however. +// +static inline void R_DrawFlippedColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight) +{ + INT32 count, position; + UINT8 *source, *dest; + INT32 topdelta, prevdelta = -1; + INT32 originy = originPatch->originy; + + while (patch->topdelta != 0xff) + { + topdelta = patch->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + topdelta = patchheight-patch->length-topdelta; + source = (UINT8 *)patch + 2 + patch->length; // patch + 3 + (patch->length-1) + count = patch->length; + position = originy + topdelta; + + if (position < 0) + { + count += position; + source += position; // start further UP the column + position = 0; + } + + if (position + count > cacheheight) + count = cacheheight - position; + + dest = cache + position; + if (count > 0) + { + for (; dest < cache + position + count; --source) + *dest++ = *source; + } + + patch = (column_t *)((UINT8 *)patch + patch->length + 4); + } +} + +// +// R_DrawTransColumnInCache +// Draws a translucent column into the cache, applying a half-cooked equation to get a proper translucency value (Needs code in R_GenerateTexture()). +// +static inline void R_DrawTransColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight) +{ + INT32 count, position; + UINT8 *source, *dest; + UINT8 *mytransmap = transtables + ((8*(originPatch->alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT); // The equation's not exact but it works as intended. I'll call it a day for now. + INT32 topdelta, prevdelta = -1; + INT32 originy = originPatch->originy; + + (void)patchheight; // This parameter is unused + + while (patch->topdelta != 0xff) + { + topdelta = patch->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + source = (UINT8 *)patch + 3; + count = patch->length; + position = originy + topdelta; + + if (position < 0) + { + count += position; + source -= position; // start further down the column + position = 0; + } + + if (position + count > cacheheight) + count = cacheheight - position; + + dest = cache + position; + if (count > 0) + { + for (; dest < cache + position + count; source++, dest++) + if (*dest != 0xFF) *dest = *(mytransmap + ((*dest)<<8) + (*source)); + } + + patch = (column_t *)((UINT8 *)patch + patch->length + 4); + } +} + +// +// R_DrawTransColumnInCache +// Similar to the one above except that the column is inverted. +// +static inline void R_DrawTransFlippedColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight) +{ + INT32 count, position; + UINT8 *source, *dest; + UINT8 *mytransmap = transtables + ((8*(originPatch->alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT); // The equation's not exact but it works as intended. I'll call it a day for now. + INT32 topdelta, prevdelta = -1; + INT32 originy = originPatch->originy; + + while (patch->topdelta != 0xff) + { + topdelta = patch->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + topdelta = patchheight-patch->length-topdelta; + source = (UINT8 *)patch + 2 + patch->length; // patch + 3 + (patch->length-1) + count = patch->length; + position = originy + topdelta; + + if (position < 0) + { + count += position; + source += position; // start further UP the column + position = 0; + } + + if (position + count > cacheheight) + count = cacheheight - position; + + dest = cache + position; + if (count > 0) + { + for (; dest < cache + position + count; --source, dest++) + if (*dest != 0xFF) *dest = *(mytransmap + ((*dest)<<8) + (*source)); + } + + patch = (column_t *)((UINT8 *)patch + patch->length + 4); + } +} + // // R_GenerateTexture // @@ -191,7 +327,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) texture_t *texture; texpatch_t *patch; patch_t *realpatch; - int x, x1, x2, i; + int x, x1, x2, i, width, height; size_t blocksize; column_t *patchcol; UINT32 *colofs; @@ -239,6 +375,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) if (holey) { texture->holes = true; + texture->flip = patch->flip; blocksize = W_LumpLengthPwad(patch->wad, patch->lump); block = Z_Calloc(blocksize, PU_STATIC, // will change tag at end of this function &texturecache[texnum]); @@ -249,6 +386,14 @@ static UINT8 *R_GenerateTexture(size_t texnum) colofs = (UINT32 *)(void *)(block + 8); texturecolumnofs[texnum] = colofs; blocktex = block; + if (patch->flip & 1) // flip the patch horizontally + { + UINT32 *realcolofs = (UINT32 *)realpatch->columnofs; + for (x = 0; x < texture->width; x++) + colofs[x] = realcolofs[texture->width-1-x]; // swap with the offset of the other side of the texture + } + // we can't as easily flip the patch vertically sadly though, + // we have wait until the texture itself is drawn to do that for (x = 0; x < texture->width; x++) colofs[x] = LONG(LONG(colofs[x]) + 3); goto done; @@ -259,11 +404,12 @@ static UINT8 *R_GenerateTexture(size_t texnum) // multi-patch textures (or 'composite') texture->holes = false; + texture->flip = 0; blocksize = (texture->width * 4) + (texture->width * texture->height); texturememory += blocksize; block = Z_Malloc(blocksize+1, PU_STATIC, &texturecache[texnum]); - memset(block, 0xF7, blocksize+1); // Transparency hack + memset(block, 0xFF, blocksize+1); // Transparency hack // columns lookup table colofs = (UINT32 *)(void *)block; @@ -275,25 +421,53 @@ static UINT8 *R_GenerateTexture(size_t texnum) // Composite the columns together. for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) { + static void (*ColumnDrawerPointer)(column_t *, UINT8 *, texpatch_t *, INT32, INT32); // Column drawing function pointer. + if ((patch->style == AST_TRANSLUCENT) && (patch->alpha <= (10*255/11))) // Alpha style set to translucent? Is the alpha small enough for translucency? + { + if (patch->alpha < 255/11) // Is the patch way too translucent? Don't render then. + continue; + ColumnDrawerPointer = (patch->flip & 2) ? R_DrawTransFlippedColumnInCache : R_DrawTransColumnInCache; + } + else + { + ColumnDrawerPointer = (patch->flip & 2) ? R_DrawFlippedColumnInCache : R_DrawColumnInCache; + } + realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); x1 = patch->originx; - x2 = x1 + SHORT(realpatch->width); + width = SHORT(realpatch->width); + height = SHORT(realpatch->height); + x2 = x1 + width; + + if (x1 > texture->width || x2 < 0) + continue; // patch not located within texture's x bounds, ignore + if (patch->originy > texture->height || (patch->originy + height) < 0) + continue; // patch not located within texture's y bounds, ignore + + // patch is actually inside the texture! + // now check if texture is partly off-screen and adjust accordingly + + // left edge if (x1 < 0) x = 0; else x = x1; + // right edge if (x2 > texture->width) x2 = texture->width; for (; x < x2; x++) { - patchcol = (column_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[x-x1])); + if (patch->flip & 1) + patchcol = (column_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[(x1+width-1)-x])); + else + patchcol = (column_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[x-x1])); // generate column ofset lookup colofs[x] = LONG((x * texture->height) + (texture->width*4)); - R_DrawColumnInCache(patchcol, block + LONG(colofs[x]), patch->originy, texture->height); + ColumnDrawerPointer(patchcol, block + LONG(colofs[x]), patch, texture->height, height); } } @@ -457,11 +631,11 @@ void R_LoadTextures(void) // Allocate texture column offset table. texturecolumnofs = (void *)((UINT8 *)textures + (numtextures * sizeof(void *))); // Allocate texture referencing cache. - texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2)); + texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2)); // Allocate texture width mask table. texturewidthmask = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 3)); // Allocate texture height mask table. - textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4)); + textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4)); // Create translation table for global animation. texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, NULL); @@ -515,6 +689,7 @@ void R_LoadTextures(void) texture->height = SHORT(patchlump->height); texture->patchcount = 1; texture->holes = false; + texture->flip = 0; // Allocate information for the texture's patches. patch = &texture->patches[0]; @@ -522,12 +697,14 @@ void R_LoadTextures(void) patch->originx = patch->originy = 0; patch->wad = (UINT16)w; patch->lump = texstart + j; + patch->flip = 0; Z_Unlock(patchlump); k = 1; while (k << 1 <= texture->width) k <<= 1; + texturewidthmask[i] = k - 1; textureheight[i] = texture->height << FRACBITS; i++; @@ -543,6 +720,9 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch) char *patchName = NULL; INT16 patchXPos; INT16 patchYPos; + UINT8 flip = 0; + UINT8 alpha = 255; + enum patchalphastyle style = AST_COPY; texpatch_t *resultPatch = NULL; lumpnum_t patchLumpNum; @@ -639,6 +819,60 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch) } Z_Free(texturesToken); + // Patch parameters block (OPTIONAL) + // added by Monster Iestyn (22/10/16) + + // Left Curly Brace + texturesToken = M_GetToken(NULL); + if (texturesToken == NULL) + ; // move on and ignore, R_ParseTextures will deal with this + else + { + if (strcmp(texturesToken,"{")==0) + { + Z_Free(texturesToken); + texturesToken = M_GetToken(NULL); + if (texturesToken == NULL) + { + I_Error("Error parsing TEXTURES lump: Unexpected end of file where patch \"%s\"'s parameters should be",patchName); + } + while (strcmp(texturesToken,"}")!=0) + { + if (stricmp(texturesToken, "ALPHA")==0) + { + Z_Free(texturesToken); + texturesToken = M_GetToken(NULL); + alpha = 255*strtof(texturesToken, NULL); + } + else if (stricmp(texturesToken, "STYLE")==0) + { + Z_Free(texturesToken); + texturesToken = M_GetToken(NULL); + if(stricmp(texturesToken, "TRANSLUCENT")==0) + style = AST_TRANSLUCENT; + } + else if (stricmp(texturesToken, "FLIPX")==0) + flip |= 1; + else if (stricmp(texturesToken, "FLIPY")==0) + flip |= 2; + Z_Free(texturesToken); + + texturesToken = M_GetToken(NULL); + if (texturesToken == NULL) + { + I_Error("Error parsing TEXTURES lump: Unexpected end of file where patch \"%s\"'s parameters or right curly brace should be",patchName); + } + } + } + else + { + // this is not what we wanted... + // undo last read so R_ParseTextures can re-get the token for its own purposes + M_UnGetToken(); + } + Z_Free(texturesToken); + } + if (actuallyLoadPatch == true) { // Check lump exists @@ -649,6 +883,9 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch) resultPatch->originy = patchYPos; resultPatch->lump = patchLumpNum & 65535; resultPatch->wad = patchLumpNum>>16; + resultPatch->flip = flip; + resultPatch->alpha = alpha; + resultPatch->style = style; // Clean up a little after ourselves Z_Free(patchName); // Then return it @@ -931,6 +1168,10 @@ void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *texindex) Z_Free((void *)texturesText); } +#ifdef EXTRACOLORMAPLUMPS +static lumplist_t *colormaplumps = NULL; ///\todo free leak +static size_t numcolormaplumps = 0; + static inline lumpnum_t R_CheckNumForNameList(const char *name, lumplist_t *list, size_t listsize) { size_t i; @@ -947,9 +1188,6 @@ static inline lumpnum_t R_CheckNumForNameList(const char *name, lumplist_t *list return LUMPERROR; } -static lumplist_t *colormaplumps = NULL; ///\todo free leak -static size_t numcolormaplumps = 0; - static void R_InitExtraColormaps(void) { lumpnum_t startnum, endnum; @@ -982,6 +1220,7 @@ static void R_InitExtraColormaps(void) } CONS_Printf(M_GetText("Number of Extra Colormaps: %s\n"), sizeu1(numcolormaplumps)); } +#endif // Search for flat name. lumpnum_t R_GetFlatNumForName(const char *name) @@ -1069,7 +1308,9 @@ static void R_InitColormaps(void) // Init Boom colormaps. R_ClearColormaps(); +#ifdef EXTRACOLORMAPLUMPS R_InitExtraColormaps(); +#endif } void R_ReInitColormaps(UINT16 num) @@ -1077,7 +1318,6 @@ void R_ReInitColormaps(UINT16 num) char colormap[9] = "COLORMAP"; lumpnum_t lump; const lumpnum_t basecolormaplump = W_GetNumForName(colormap); - if (num > 0 && num <= 10000) snprintf(colormap, 8, "CLM%04u", num-1); @@ -1099,8 +1339,6 @@ void R_ReInitColormaps(UINT16 num) R_ClearColormaps(); } -static lumpnum_t foundcolormaps[MAXCOLORMAPS]; - // // R_ClearColormaps // @@ -1108,49 +1346,264 @@ static lumpnum_t foundcolormaps[MAXCOLORMAPS]; // void R_ClearColormaps(void) { - size_t i; + // Purged by PU_LEVEL, just overwrite the pointer + extra_colormaps = R_CreateDefaultColormap(true); +} + +// +// R_CreateDefaultColormap() +// NOTE: The result colormap is not added to the extra_colormaps chain. You must do that yourself! +// +extracolormap_t *R_CreateDefaultColormap(boolean lighttable) +{ + extracolormap_t *exc = Z_Calloc(sizeof (*exc), PU_LEVEL, NULL); + exc->fadestart = 0; + exc->fadeend = 31; + exc->fog = 0; + exc->rgba = 0; + exc->fadergba = 0x19000000; + exc->colormap = lighttable ? R_CreateLightTable(exc) : NULL; +#ifdef EXTRACOLORMAPLUMPS + exc->lump = LUMPERROR; + exc->lumpname[0] = 0; +#endif + exc->next = exc->prev = NULL; + return exc; +} + +// +// R_GetDefaultColormap() +// +extracolormap_t *R_GetDefaultColormap(void) +{ +#ifdef COLORMAPREVERSELIST + extracolormap_t *exc; +#endif + + if (!extra_colormaps) + return (extra_colormaps = R_CreateDefaultColormap(true)); + +#ifdef COLORMAPREVERSELIST + for (exc = extra_colormaps; exc->next; exc = exc->next); + return exc; +#else + return extra_colormaps; +#endif +} + +// +// R_CopyColormap() +// NOTE: The result colormap is not added to the extra_colormaps chain. You must do that yourself! +// +extracolormap_t *R_CopyColormap(extracolormap_t *extra_colormap, boolean lighttable) +{ + extracolormap_t *exc = Z_Calloc(sizeof (*exc), PU_LEVEL, NULL); + + if (!extra_colormap) + extra_colormap = R_GetDefaultColormap(); + + *exc = *extra_colormap; + exc->next = exc->prev = NULL; + +#ifdef EXTRACOLORMAPLUMPS + strncpy(exc->lumpname, extra_colormap->lumpname, 9); + + if (exc->lump != LUMPERROR && lighttable) + { + // aligned on 8 bit for asm code + exc->colormap = Z_MallocAlign(W_LumpLength(lump), PU_LEVEL, NULL, 16); + W_ReadLump(lump, exc->colormap); + } + else +#endif + if (lighttable) + exc->colormap = R_CreateLightTable(exc); + else + exc->colormap = NULL; + + return exc; +} + +// +// R_AddColormapToList +// +// Sets prev/next chain for extra_colormaps var +// Copypasta from P_AddFFloorToList +// +void R_AddColormapToList(extracolormap_t *extra_colormap) +{ +#ifndef COLORMAPREVERSELIST + extracolormap_t *exc; +#endif + + if (!extra_colormaps) + { + extra_colormaps = extra_colormap; + extra_colormap->next = 0; + extra_colormap->prev = 0; + return; + } - num_extra_colormaps = 0; +#ifdef COLORMAPREVERSELIST + extra_colormaps->prev = extra_colormap; + extra_colormap->next = extra_colormaps; + extra_colormaps = extra_colormap; + extra_colormap->prev = 0; +#else + for (exc = extra_colormaps; exc->next; exc = exc->next); + + exc->next = extra_colormap; + extra_colormap->prev = exc; + extra_colormap->next = 0; +#endif +} + +// +// R_CheckDefaultColormapByValues() +// +#ifdef EXTRACOLORMAPLUMPS +boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba, boolean checkparams, + INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog, lumpnum_t lump) +#else +boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba, boolean checkparams, + INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog) +#endif +{ + return ( + (!checkparams ? true : + (fadestart == 0 + && fadeend == 31 + && !fog) + ) + && (!checkrgba ? true : rgba == 0) + && (!checkfadergba ? true : fadergba == 0x19000000) +#ifdef EXTRACOLORMAPLUMPS + && lump == LUMPERROR + && extra_colormap->lumpname[0] == 0 +#endif + ); +} - for (i = 0; i < MAXCOLORMAPS; i++) - foundcolormaps[i] = LUMPERROR; +boolean R_CheckDefaultColormap(extracolormap_t *extra_colormap, boolean checkrgba, boolean checkfadergba, boolean checkparams) +{ + if (!extra_colormap) + return true; - memset(extra_colormaps, 0, sizeof (extra_colormaps)); +#ifdef EXTRACOLORMAPLUMPS + return R_CheckDefaultColormapByValues(checkrgba, checkfadergba, checkparams, extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->fog, extra_colormap->lump); +#else + return R_CheckDefaultColormapByValues(checkrgba, checkfadergba, checkparams, extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->fog); +#endif } -INT32 R_ColormapNumForName(char *name) +boolean R_CheckEqualColormaps(extracolormap_t *exc_a, extracolormap_t *exc_b, boolean checkrgba, boolean checkfadergba, boolean checkparams) { - lumpnum_t lump, i; + // Treat NULL as default colormap + // We need this because what if one exc is a default colormap, and the other is NULL? They're really both equal. + if (!exc_a) + exc_a = R_GetDefaultColormap(); + if (!exc_b) + exc_b = R_GetDefaultColormap(); + + if (exc_a == exc_b) + return true; + + return ( + (!checkparams ? true : + (exc_a->fadestart == exc_b->fadestart + && exc_a->fadeend == exc_b->fadeend + && exc_a->fog == exc_b->fog) + ) + && (!checkrgba ? true : exc_a->rgba == exc_b->rgba) + && (!checkfadergba ? true : exc_a->fadergba == exc_b->fadergba) +#ifdef EXTRACOLORMAPLUMPS + && exc_a->lump == exc_b->lump + && !strncmp(exc_a->lumpname, exc_b->lumpname, 9) +#endif + ); +} - if (num_extra_colormaps == MAXCOLORMAPS) - I_Error("R_ColormapNumForName: Too many colormaps! the limit is %d\n", MAXCOLORMAPS); +// +// R_GetColormapFromListByValues() +// NOTE: Returns NULL if no match is found +// +#ifdef EXTRACOLORMAPLUMPS +extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog, lumpnum_t lump) +#else +extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog) +#endif +{ + extracolormap_t *exc; + UINT32 dbg_i = 0; + + for (exc = extra_colormaps; exc; exc = exc->next) + { + if (rgba == exc->rgba + && fadergba == exc->fadergba + && fadestart == exc->fadestart + && fadeend == exc->fadeend + && fog == exc->fog +#ifdef EXTRACOLORMAPLUMPS + && (lump != LUMPERROR && lump == exc->lump) +#endif + ) + { + CONS_Debug(DBG_RENDER, "Found Colormap %d: rgba(%d,%d,%d,%d) fadergba(%d,%d,%d,%d)\n", + dbg_i, R_GetRgbaR(rgba), R_GetRgbaG(rgba), R_GetRgbaB(rgba), R_GetRgbaA(rgba), + R_GetRgbaR(fadergba), R_GetRgbaG(fadergba), R_GetRgbaB(fadergba), R_GetRgbaA(fadergba)); + return exc; + } + dbg_i++; + } + return NULL; +} + +extracolormap_t *R_GetColormapFromList(extracolormap_t *extra_colormap) +{ +#ifdef EXTRACOLORMAPLUMPS + return R_GetColormapFromListByValues(extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->fog, extra_colormap->lump); +#else + return R_GetColormapFromListByValues(extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->fog); +#endif +} + +#ifdef EXTRACOLORMAPLUMPS +extracolormap_t *R_ColormapForName(char *name) +{ + lumpnum_t lump; + extracolormap_t *exc; lump = R_CheckNumForNameList(name, colormaplumps, numcolormaplumps); if (lump == LUMPERROR) - I_Error("R_ColormapNumForName: Cannot find colormap lump %.8s\n", name); + I_Error("R_ColormapForName: Cannot find colormap lump %.8s\n", name); - for (i = 0; i < num_extra_colormaps; i++) - if (lump == foundcolormaps[i]) - return i; + exc = R_GetColormapFromListByValues(0, 0x19000000, 0, 31, 0, lump); + if (exc) + return exc; - foundcolormaps[num_extra_colormaps] = lump; + exc = Z_Calloc(sizeof (*exc), PU_LEVEL, NULL); + + exc->lump = lump; + strncpy(exc->lumpname, name, 9); + exc->lumpname[8] = 0; // aligned on 8 bit for asm code - extra_colormaps[num_extra_colormaps].colormap = Z_MallocAlign(W_LumpLength(lump), PU_LEVEL, NULL, 16); - W_ReadLump(lump, extra_colormaps[num_extra_colormaps].colormap); + exc->colormap = Z_MallocAlign(W_LumpLength(lump), PU_LEVEL, NULL, 16); + W_ReadLump(lump, exc->colormap); // We set all params of the colormap to normal because there // is no real way to tell how GL should handle a colormap lump anyway.. - extra_colormaps[num_extra_colormaps].maskcolor = 0xffff; - extra_colormaps[num_extra_colormaps].fadecolor = 0x0; - extra_colormaps[num_extra_colormaps].maskamt = 0x0; - extra_colormaps[num_extra_colormaps].fadestart = 0; - extra_colormaps[num_extra_colormaps].fadeend = 31; - extra_colormaps[num_extra_colormaps].fog = 0; - - num_extra_colormaps++; - return (INT32)num_extra_colormaps - 1; + exc->fadestart = 0; + exc->fadeend = 31; + exc->fog = 0; + exc->rgba = 0; + exc->fadergba = 0x19000000; + + R_AddColormapToList(exc); + + return exc; } +#endif // // R_CreateColormap @@ -1165,107 +1618,60 @@ static double deltas[256][3], map[256][3]; static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); static int RoundUp(double number); -INT32 R_CreateColormap(char *p1, char *p2, char *p3) +lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) { double cmaskr, cmaskg, cmaskb, cdestr, cdestg, cdestb; double maskamt = 0, othermask = 0; - int mask, fog = 0; - size_t mapnum = num_extra_colormaps; - size_t i; - UINT32 cr, cg, cb, maskcolor, fadecolor; - UINT32 fadestart = 0, fadeend = 31, fadedist = 31; -#define HEX2INT(x) (UINT32)(x >= '0' && x <= '9' ? x - '0' : x >= 'a' && x <= 'f' ? x - 'a' + 10 : x >= 'A' && x <= 'F' ? x - 'A' + 10 : 0) - if (p1[0] == '#') - { - cr = ((HEX2INT(p1[1]) * 16) + HEX2INT(p1[2])); - cmaskr = cr; - cg = ((HEX2INT(p1[3]) * 16) + HEX2INT(p1[4])); - cmaskg = cg; - cb = ((HEX2INT(p1[5]) * 16) + HEX2INT(p1[6])); - cmaskb = cb; - // Create a rough approximation of the color (a 16 bit color) - maskcolor = ((cb) >> 3) + (((cg) >> 2) << 5) + (((cr) >> 3) << 11); - if (p1[7] >= 'a' && p1[7] <= 'z') - mask = (p1[7] - 'a'); - else if (p1[7] >= 'A' && p1[7] <= 'Z') - mask = (p1[7] - 'A'); - else - mask = 24; + UINT8 cr = R_GetRgbaR(extra_colormap->rgba), + cg = R_GetRgbaG(extra_colormap->rgba), + cb = R_GetRgbaB(extra_colormap->rgba), + ca = R_GetRgbaA(extra_colormap->rgba), + cfr = R_GetRgbaR(extra_colormap->fadergba), + cfg = R_GetRgbaG(extra_colormap->fadergba), + cfb = R_GetRgbaB(extra_colormap->fadergba); +// cfa = R_GetRgbaA(extra_colormap->fadergba); // unused in software - maskamt = (double)(mask/24.0l); + UINT8 fadestart = extra_colormap->fadestart, + fadedist = extra_colormap->fadeend - extra_colormap->fadestart; - othermask = 1 - maskamt; - maskamt /= 0xff; - cmaskr *= maskamt; - cmaskg *= maskamt; - cmaskb *= maskamt; - } - else - { - cmaskr = cmaskg = cmaskb = 0xff; - maskamt = 0; - maskcolor = ((0xff) >> 3) + (((0xff) >> 2) << 5) + (((0xff) >> 3) << 11); - } - -#define NUMFROMCHAR(c) (c >= '0' && c <= '9' ? c - '0' : 0) - if (p2[0] == '#') - { - // Get parameters like fadestart, fadeend, and the fogflag - fadestart = NUMFROMCHAR(p2[3]) + (NUMFROMCHAR(p2[2]) * 10); - fadeend = NUMFROMCHAR(p2[5]) + (NUMFROMCHAR(p2[4]) * 10); - if (fadestart > 30) - fadestart = 0; - if (fadeend > 31 || fadeend < 1) - fadeend = 31; - fadedist = fadeend - fadestart; - fog = NUMFROMCHAR(p2[1]); - } -#undef NUMFROMCHAR - - if (p3[0] == '#') - { - cdestr = cr = ((HEX2INT(p3[1]) * 16) + HEX2INT(p3[2])); - cdestg = cg = ((HEX2INT(p3[3]) * 16) + HEX2INT(p3[4])); - cdestb = cb = ((HEX2INT(p3[5]) * 16) + HEX2INT(p3[6])); - fadecolor = (((cb) >> 3) + (((cg) >> 2) << 5) + (((cr) >> 3) << 11)); - } - else - cdestr = cdestg = cdestb = fadecolor = 0; -#undef HEX2INT - - for (i = 0; i < num_extra_colormaps; i++) - { - if (foundcolormaps[i] != LUMPERROR) - continue; - if (maskcolor == extra_colormaps[i].maskcolor - && fadecolor == extra_colormaps[i].fadecolor - && fabs(maskamt - extra_colormaps[i].maskamt) < DBL_EPSILON - && fadestart == extra_colormaps[i].fadestart - && fadeend == extra_colormaps[i].fadeend - && fog == extra_colormaps[i].fog) - { - return (INT32)i; - } - } - - if (num_extra_colormaps == MAXCOLORMAPS) - I_Error("R_CreateColormap: Too many colormaps! the limit is %d\n", MAXCOLORMAPS); - - num_extra_colormaps++; - - foundcolormaps[mapnum] = LUMPERROR; - - // aligned on 8 bit for asm code - extra_colormaps[mapnum].colormap = NULL; - extra_colormaps[mapnum].maskcolor = (UINT16)maskcolor; - extra_colormaps[mapnum].fadecolor = (UINT16)fadecolor; - extra_colormaps[mapnum].maskamt = maskamt; - extra_colormaps[mapnum].fadestart = (UINT16)fadestart; - extra_colormaps[mapnum].fadeend = (UINT16)fadeend; - extra_colormaps[mapnum].fog = fog; + lighttable_t *lighttable = NULL; + size_t i; + ///////////////////// + // Calc the RGBA mask + ///////////////////// + cmaskr = cr; + cmaskg = cg; + cmaskb = cb; + + maskamt = (double)(ca/24.0l); + othermask = 1 - maskamt; + maskamt /= 0xff; + + cmaskr *= maskamt; + cmaskg *= maskamt; + cmaskb *= maskamt; + + ///////////////////// + // Calc the RGBA fade mask + ///////////////////// + cdestr = cfr; + cdestg = cfg; + cdestb = cfb; + + // fade alpha unused in software + // maskamt = (double)(cfa/24.0l); + // othermask = 1 - maskamt; + // maskamt /= 0xff; + + // cdestr *= maskamt; + // cdestg *= maskamt; + // cdestb *= maskamt; + + ///////////////////// // This code creates the colormap array used by software renderer + ///////////////////// if (rendermode == render_soft) { double r, g, b, cbrightness; @@ -1279,9 +1685,9 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3) // map[i]'s values are decremented by after each use for (i = 0; i < 256; i++) { - r = pLocalPalette[i].s.red; - g = pLocalPalette[i].s.green; - b = pLocalPalette[i].s.blue; + r = pMasterPalette[i].s.red; + g = pMasterPalette[i].s.green; + b = pMasterPalette[i].s.blue; cbrightness = sqrt((r*r) + (g*g) + (b*b)); map[i][0] = (cbrightness * cmaskr) + (r * othermask); @@ -1301,8 +1707,9 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3) } // Now allocate memory for the actual colormap array itself! + // aligned on 8 bit for asm code colormap_p = Z_MallocAlign((256 * 34) + 10, PU_LEVEL, NULL, 8); - extra_colormaps[mapnum].colormap = (UINT8 *)colormap_p; + lighttable = (UINT8 *)colormap_p; // Calculate the palette index for each palette index, for each light level // (as well as the two unused colormap lines we inherited from Doom) @@ -1337,7 +1744,285 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3) } } - return (INT32)mapnum; + return lighttable; +} + +extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3) +{ + extracolormap_t *extra_colormap, *exc; + + // default values + UINT8 cr = 0, cg = 0, cb = 0, ca = 0, cfr = 0, cfg = 0, cfb = 0, cfa = 25; + UINT32 fadestart = 0, fadeend = 31; + UINT8 fog = 0; + INT32 rgba = 0, fadergba = 0x19000000; + +#define HEX2INT(x) (UINT32)(x >= '0' && x <= '9' ? x - '0' : x >= 'a' && x <= 'f' ? x - 'a' + 10 : x >= 'A' && x <= 'F' ? x - 'A' + 10 : 0) +#define ALPHA2INT(x) (x >= 'a' && x <= 'z' ? x - 'a' : x >= 'A' && x <= 'Z' ? x - 'A' : x >= '0' && x <= '9' ? 25 : 0) + + // Get base colormap value + // First alpha-only, then full value + if (p1[0] >= 'a' && p1[0] <= 'z' && !p1[1]) + ca = (p1[0] - 'a'); + else if (p1[0] == '#' && p1[1] >= 'a' && p1[1] <= 'z' && !p1[2]) + ca = (p1[1] - 'a'); + else if (p1[0] >= 'A' && p1[0] <= 'Z' && !p1[1]) + ca = (p1[0] - 'A'); + else if (p1[0] == '#' && p1[1] >= 'A' && p1[1] <= 'Z' && !p1[2]) + ca = (p1[1] - 'A'); + else if (p1[0] == '#') + { + // For each subsequent value, the value before it must exist + // If we don't get every value, then set alpha to max + if (p1[1] && p1[2]) + { + cr = ((HEX2INT(p1[1]) * 16) + HEX2INT(p1[2])); + if (p1[3] && p1[4]) + { + cg = ((HEX2INT(p1[3]) * 16) + HEX2INT(p1[4])); + if (p1[5] && p1[6]) + { + cb = ((HEX2INT(p1[5]) * 16) + HEX2INT(p1[6])); + + if (p1[7] >= 'a' && p1[7] <= 'z') + ca = (p1[7] - 'a'); + else if (p1[7] >= 'A' && p1[7] <= 'Z') + ca = (p1[7] - 'A'); + else + ca = 25; + } + else + ca = 25; + } + else + ca = 25; + } + else + ca = 25; + } + +#define NUMFROMCHAR(c) (c >= '0' && c <= '9' ? c - '0' : 0) + + // Get parameters like fadestart, fadeend, and the fogflag + if (p2[0] == '#') + { + if (p2[1]) + { + fog = NUMFROMCHAR(p2[1]); + if (p2[2] && p2[3]) + { + fadestart = NUMFROMCHAR(p2[3]) + (NUMFROMCHAR(p2[2]) * 10); + if (p2[4] && p2[5]) + fadeend = NUMFROMCHAR(p2[5]) + (NUMFROMCHAR(p2[4]) * 10); + } + } + + if (fadestart > 30) + fadestart = 0; + if (fadeend > 31 || fadeend < 1) + fadeend = 31; + } + +#undef NUMFROMCHAR + + // Get fade (dark) colormap value + // First alpha-only, then full value + if (p3[0] >= 'a' && p3[0] <= 'z' && !p3[1]) + cfa = (p3[0] - 'a'); + else if (p3[0] == '#' && p3[1] >= 'a' && p3[1] <= 'z' && !p3[2]) + cfa = (p3[1] - 'a'); + else if (p3[0] >= 'A' && p3[0] <= 'Z' && !p3[1]) + cfa = (p3[0] - 'A'); + else if (p3[0] == '#' && p3[1] >= 'A' && p3[1] <= 'Z' && !p3[2]) + cfa = (p3[1] - 'A'); + else if (p3[0] == '#') + { + // For each subsequent value, the value before it must exist + // If we don't get every value, then set alpha to max + if (p3[1] && p3[2]) + { + cfr = ((HEX2INT(p3[1]) * 16) + HEX2INT(p3[2])); + if (p3[3] && p3[4]) + { + cfg = ((HEX2INT(p3[3]) * 16) + HEX2INT(p3[4])); + if (p3[5] && p3[6]) + { + cfb = ((HEX2INT(p3[5]) * 16) + HEX2INT(p3[6])); + + if (p3[7] >= 'a' && p3[7] <= 'z') + cfa = (p3[7] - 'a'); + else if (p3[7] >= 'A' && p3[7] <= 'Z') + cfa = (p3[7] - 'A'); + else + cfa = 25; + } + else + cfa = 25; + } + else + cfa = 25; + } + else + cfa = 25; + } +#undef ALPHA2INT +#undef HEX2INT + + // Pack rgba values into combined var + // OpenGL also uses this instead of lighttables for rendering + rgba = R_PutRgbaRGBA(cr, cg, cb, ca); + fadergba = R_PutRgbaRGBA(cfr, cfg, cfb, cfa); + + // Did we just make a default colormap? +#ifdef EXTRACOLORMAPLUMPS + if (R_CheckDefaultColormapByValues(true, true, true, rgba, fadergba, fadestart, fadeend, fog, LUMPERROR)) + return NULL; +#else + if (R_CheckDefaultColormapByValues(true, true, true, rgba, fadergba, fadestart, fadeend, fog)) + return NULL; +#endif + + // Look for existing colormaps +#ifdef EXTRACOLORMAPLUMPS + exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, fog, LUMPERROR); +#else + exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, fog); +#endif + if (exc) + return exc; + + CONS_Debug(DBG_RENDER, "Creating Colormap: rgba(%d,%d,%d,%d) fadergba(%d,%d,%d,%d)\n", + cr, cg, cb, ca, cfr, cfg, cfb, cfa); + + extra_colormap = Z_Calloc(sizeof (*extra_colormap), PU_LEVEL, NULL); + + extra_colormap->fadestart = (UINT16)fadestart; + extra_colormap->fadeend = (UINT16)fadeend; + extra_colormap->fog = fog; + + extra_colormap->rgba = rgba; + extra_colormap->fadergba = fadergba; + +#ifdef EXTRACOLORMAPLUMPS + extra_colormap->lump = LUMPERROR; + extra_colormap->lumpname[0] = 0; +#endif + + // Having lighttables for alpha-only entries is kind of pointless, + // but if there happens to be a matching rgba entry that is NOT alpha-only (but has same rgb values), + // then it needs this lighttable because we share matching entries. + extra_colormap->colormap = R_CreateLightTable(extra_colormap); + + R_AddColormapToList(extra_colormap); + + return extra_colormap; +} + +// +// R_AddColormaps() +// NOTE: The result colormap is not added to the extra_colormaps chain. You must do that yourself! +// +extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *exc_addend, + boolean subR, boolean subG, boolean subB, boolean subA, + boolean subFadeR, boolean subFadeG, boolean subFadeB, boolean subFadeA, + boolean subFadeStart, boolean subFadeEnd, boolean ignoreFog, + boolean useAltAlpha, INT16 altAlpha, INT16 altFadeAlpha, + boolean lighttable) +{ + INT16 red, green, blue, alpha; + + // exc_augend is added (or subtracted) onto by exc_addend + // In Rennaisance times, the first number was considered the augend, the second number the addend + // But since the commutative property was discovered, today they're both called addends! + // So let's be Olde English for a hot second. + + exc_augend = R_CopyColormap(exc_augend, false); + if(!exc_addend) + exc_addend = R_GetDefaultColormap(); + + /////////////////// + // base rgba + /////////////////// + + red = max(min( + R_GetRgbaR(exc_augend->rgba) + + (subR ? -1 : 1) // subtract R + * R_GetRgbaR(exc_addend->rgba) + , 255), 0); + + green = max(min( + R_GetRgbaG(exc_augend->rgba) + + (subG ? -1 : 1) // subtract G + * R_GetRgbaG(exc_addend->rgba) + , 255), 0); + + blue = max(min( + R_GetRgbaB(exc_augend->rgba) + + (subB ? -1 : 1) // subtract B + * R_GetRgbaB(exc_addend->rgba) + , 255), 0); + + alpha = useAltAlpha ? altAlpha : R_GetRgbaA(exc_addend->rgba); + alpha = max(min(R_GetRgbaA(exc_augend->rgba) + (subA ? -1 : 1) * alpha, 25), 0); + + exc_augend->rgba = R_PutRgbaRGBA(red, green, blue, alpha); + + /////////////////// + // fade/dark rgba + /////////////////// + + red = max(min( + R_GetRgbaR(exc_augend->fadergba) + + (subFadeR ? -1 : 1) // subtract R + * R_GetRgbaR(exc_addend->fadergba) + , 255), 0); + + green = max(min( + R_GetRgbaG(exc_augend->fadergba) + + (subFadeG ? -1 : 1) // subtract G + * R_GetRgbaG(exc_addend->fadergba) + , 255), 0); + + blue = max(min( + R_GetRgbaB(exc_augend->fadergba) + + (subFadeB ? -1 : 1) // subtract B + * R_GetRgbaB(exc_addend->fadergba) + , 255), 0); + + alpha = useAltAlpha ? altFadeAlpha : R_GetRgbaA(exc_addend->fadergba); + if (alpha == 25 && !useAltAlpha && !R_GetRgbaRGB(exc_addend->fadergba)) + alpha = 0; // HACK: fadergba A defaults at 25, so don't add anything in this case + alpha = max(min(R_GetRgbaA(exc_augend->fadergba) + (subFadeA ? -1 : 1) * alpha, 25), 0); + + exc_augend->fadergba = R_PutRgbaRGBA(red, green, blue, alpha); + + /////////////////// + // parameters + /////////////////// + + exc_augend->fadestart = max(min( + exc_augend->fadestart + + (subFadeStart ? -1 : 1) // subtract fadestart + * exc_addend->fadestart + , 31), 0); + + exc_augend->fadeend = max(min( + exc_augend->fadeend + + (subFadeEnd ? -1 : 1) // subtract fadeend + * (exc_addend->fadeend == 31 && !exc_addend->fadestart ? 0 : exc_addend->fadeend) + // HACK: fadeend defaults to 31, so don't add anything in this case + , 31), 0); + + if (!ignoreFog) // overwrite fog with new value + exc_augend->fog = exc_addend->fog; + + /////////////////// + // put it together + /////////////////// + + exc_augend->colormap = lighttable ? R_CreateLightTable(exc_augend) : NULL; + exc_augend->next = exc_augend->prev = NULL; + return exc_augend; } // Thanks to quake2 source! @@ -1349,9 +2034,9 @@ static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b) for (i = 0; i < 256; i++) { - dr = r - pLocalPalette[i].s.red; - dg = g - pLocalPalette[i].s.green; - db = b - pLocalPalette[i].s.blue; + dr = r - pMasterPalette[i].s.red; + dg = g - pMasterPalette[i].s.green; + db = b - pMasterPalette[i].s.blue; distortion = dr*dr + dg*dg + db*db; if (distortion < bestdistortion) { @@ -1380,20 +2065,18 @@ static int RoundUp(double number) return (int)number; } -const char *R_ColormapNameForNum(INT32 num) +#ifdef EXTRACOLORMAPLUMPS +const char *R_NameForColormap(extracolormap_t *extra_colormap) { - if (num == -1) + if (!extra_colormap) return "NONE"; - if (num < 0 || num > MAXCOLORMAPS) - I_Error("R_ColormapNameForNum: num %d is invalid!\n", num); - - if (foundcolormaps[num] == LUMPERROR) + if (extra_colormap->lump == LUMPERROR) return "INLEVEL"; - return W_CheckNameForNum(foundcolormaps[num]); + return extra_colormap->lumpname; } - +#endif // // build a table for quick conversion from 8bpp to 15bpp diff --git a/src/r_data.h b/src/r_data.h index 5de51ccd4981708b77614c6af9cb699644dc10ec..b6b0a16a15fad21fb90aa0325721d177a1c6eccc 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -21,6 +21,9 @@ #pragma interface #endif +// Possible alpha types for a patch. +enum patchalphastyle {AST_COPY, AST_TRANSLUCENT}; // , AST_ADD, AST_SUBTRACT, AST_REVERSESUBTRACT, AST_MODULATE, AST_OVERLAY}; + // moved here for r_sky.c (texpatch_t is used) // A single patch from a texture definition, @@ -31,6 +34,9 @@ typedef struct // Block origin (always UL), which has already accounted for the internal origin of the patch. INT16 originx, originy; UINT16 wad, lump; + UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both + UINT8 alpha; // Translucency value + enum patchalphastyle style; } texpatch_t; // A maptexturedef_t describes a rectangular texture, @@ -42,6 +48,7 @@ typedef struct char name[8]; INT16 width, height; boolean holes; + UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both // All the patches[patchcount] are drawn back to front into the cached texture. INT16 patchcount; @@ -61,7 +68,7 @@ extern INT16 *hicolormaps; // remap high colors to high colors.. extern CV_PossibleValue_t Color_cons_t[]; -// Load TEXTURE1/TEXTURE2/PNAMES definitions, create lookup tables +// Load TEXTURES definitions, create lookup tables void R_LoadTextures(void); void R_FlushTextureCache(void); @@ -89,11 +96,57 @@ void R_ClearTextureNumCache(boolean btell); INT32 R_TextureNumForName(const char *name); INT32 R_CheckTextureNumForName(const char *name); +// Extra Colormap lumps (C_START/C_END) are not used anywhere +// Uncomment to enable +//#define EXTRACOLORMAPLUMPS + +// Uncomment to make extra_colormaps order Newest -> Oldest +//#define COLORMAPREVERSELIST + void R_ReInitColormaps(UINT16 num); void R_ClearColormaps(void); -INT32 R_ColormapNumForName(char *name); -INT32 R_CreateColormap(char *p1, char *p2, char *p3); -const char *R_ColormapNameForNum(INT32 num); +extracolormap_t *R_CreateDefaultColormap(boolean lighttable); +extracolormap_t *R_GetDefaultColormap(void); +extracolormap_t *R_CopyColormap(extracolormap_t *extra_colormap, boolean lighttable); +void R_AddColormapToList(extracolormap_t *extra_colormap); + +#ifdef EXTRACOLORMAPLUMPS +boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba, boolean checkparams, + INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog, lumpnum_t lump); +extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog, lumpnum_t lump); +#else +boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba, boolean checkparams, + INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog); +extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog); +#endif +boolean R_CheckDefaultColormap(extracolormap_t *extra_colormap, boolean checkrgba, boolean checkfadergba, boolean checkparams); +boolean R_CheckEqualColormaps(extracolormap_t *exc_a, extracolormap_t *exc_b, boolean checkrgba, boolean checkfadergba, boolean checkparams); +extracolormap_t *R_GetColormapFromList(extracolormap_t *extra_colormap); + +lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap); +extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3); +extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *exc_addend, + boolean subR, boolean subG, boolean subB, boolean subA, + boolean subFadeR, boolean subFadeG, boolean subFadeB, boolean subFadeA, + boolean subFadeStart, boolean subFadeEnd, boolean ignoreFog, + boolean useAltAlpha, INT16 altAlpha, INT16 altFadeAlpha, + boolean lighttable); +#ifdef EXTRACOLORMAPLUMPS +extracolormap_t *R_ColormapForName(char *name); +const char *R_NameForColormap(extracolormap_t *extra_colormap); +#endif + +#define R_GetRgbaR(rgba) (rgba & 0xFF) +#define R_GetRgbaG(rgba) ((rgba >> 8) & 0xFF) +#define R_GetRgbaB(rgba) ((rgba >> 16) & 0xFF) +#define R_GetRgbaA(rgba) ((rgba >> 24) & 0xFF) +#define R_GetRgbaRGB(rgba) (rgba & 0xFFFFFF) +#define R_PutRgbaR(r) (r) +#define R_PutRgbaG(g) (g << 8) +#define R_PutRgbaB(b) (b << 16) +#define R_PutRgbaA(a) (a << 24) +#define R_PutRgbaRGB(r, g, b) (R_PutRgbaR(r) + R_PutRgbaG(g) + R_PutRgbaB(b)) +#define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a)) extern INT32 numtextures; diff --git a/src/r_defs.h b/src/r_defs.h index 1cb4e0815a85ac9b2965b5c037819b9f71362a35..e7315b35cc1f698d3a9dd88692eb31c872937b5a 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -50,18 +50,25 @@ typedef struct typedef UINT8 lighttable_t; // ExtraColormap type. Use for extra_colormaps from now on. -typedef struct +typedef struct extracolormap_s { - UINT16 maskcolor, fadecolor; - double maskamt; - UINT16 fadestart, fadeend; - INT32 fog; + UINT8 fadestart, fadeend; + UINT8 fog; // categorical value, not boolean - // rgba is used in hw mode for colored sector lighting + // store rgba values in combined bitwise + // also used in OpenGL instead lighttables INT32 rgba; // similar to maskcolor in sw mode INT32 fadergba; // The colour the colourmaps fade to lighttable_t *colormap; + +#ifdef EXTRACOLORMAPLUMPS + lumpnum_t lump; // for colormap lump matching, init to LUMPERROR + char lumpname[9]; // for netsyncing +#endif + + struct extracolormap_s *next; + struct extracolormap_s *prev; } extracolormap_t; // @@ -177,6 +184,8 @@ typedef struct ffloor_s // these are saved for netgames, so do not let Lua touch these! ffloortype_e spawnflags; // flags the 3D floor spawned with INT32 spawnalpha; // alpha the 3D floor spawned with + + void *fadingdata; // fading FOF thinker } ffloor_t; @@ -187,7 +196,7 @@ typedef struct lightlist_s { fixed_t height; INT16 *lightlevel; - extracolormap_t *extra_colormap; + extracolormap_t **extra_colormap; // pointer-to-a-pointer, so we can react to colormap changes INT32 flags; ffloor_t *caster; #ifdef ESLOPE @@ -308,6 +317,7 @@ typedef struct sector_s void *floordata; // floor move thinker void *ceilingdata; // ceiling move thinker void *lightingdata; // lighting change thinker + void *fadecolormapdata; // fade colormap thinker // floor and ceiling texture offsets fixed_t floor_xoffs, floor_yoffs; @@ -323,8 +333,6 @@ typedef struct sector_s INT32 floorlightsec, ceilinglightsec; INT32 crumblestate; // used for crumbling and bobbing - INT32 bottommap, midmap, topmap; // dynamic colormaps - // list of mobjs that are at least partially in the sector // thinglist is a subset of touching_thinglist struct msecnode_s *touching_thinglist; @@ -383,6 +391,9 @@ typedef struct sector_s boolean hasslope; // The sector, or one of its visible FOFs, contains a slope #endif + // for fade thinker + INT16 spawn_lightlevel; + // these are saved for netgames, so do not let Lua touch these! INT32 spawn_nexttag, spawn_firsttag; // the actual nexttag/firsttag values may differ if the sector's tag was changed @@ -393,6 +404,9 @@ typedef struct sector_s // flag angles sector spawned with (via linedef type 7) angle_t spawn_flrpic_angle; angle_t spawn_ceilpic_angle; + + // colormap structure + extracolormap_t *spawn_extra_colormap; } sector_t; // @@ -468,6 +482,8 @@ typedef struct INT16 repeatcnt; // # of times to repeat midtexture char *text; // a concatination of all top, bottom, and mid texture names, for linedef specials that require a string. + + extracolormap_t *colormap_data; // storage for colormaps; not applied to sectors. } side_t; // @@ -689,7 +705,7 @@ typedef enum // Patches. // A patch holds one or more columns. // Patches are used for sprites and all masked pictures, and we compose -// textures from the TEXTURE1 list of patches. +// textures from the TEXTURES list of patches. // // WARNING: this structure is cloned in GLPatch_t typedef struct @@ -726,23 +742,36 @@ typedef struct #pragma pack() #endif +typedef enum +{ + SRF_SINGLE = 0, // 0-angle for all rotations + SRF_3D = 1, // Angles 1-8 + SRF_LEFT = 2, // Left side uses single patch + SRF_RIGHT = 4, // Right side uses single patch + SRF_2D = SRF_LEFT|SRF_RIGHT, // 6 + SRF_NONE = 0xff // Initial value +} spriterotateflags_t; // SRF's up! + // // Sprites are patches with a special naming convention so they can be // recognized by R_InitSprites. // The base name is NNNNFx or NNNNFxFx, with x indicating the rotation, -// x = 0, 1-7. +// x = 0, 1-8, L/R // The sprite and frame specified by a thing_t is range checked at run time. // A sprite is a patch_t that is assumed to represent a three dimensional // object and may have multiple rotations predrawn. // Horizontal flipping is used to save space, thus NNNNF2F5 defines a mirrored patch. // Some sprites will only have one picture used for all views: NNNNF0 +// Some sprites will take the entirety of the left side: NNNNFL +// Or the right side: NNNNFR +// Or both, mirrored: NNNNFLFR // typedef struct { // If false use 0 for any position. // Note: as eight entries are available, we might as well insert the same // name eight times. - UINT8 rotate; + UINT8 rotate; // see spriterotateflags_t above // Lump to use for view angles 0-7. lumpnum_t lumppat[8]; // lump number 16 : 16 wad : lump diff --git a/src/r_draw.c b/src/r_draw.c index bbc9a79b08b1a679833a92b800c59f0937f3bf1d..13ac691d5f9c63dbb8d5689cb08d170097d4031d 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -126,73 +126,301 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask; #define BOSS_TT_CACHE_INDEX (MAXSKINS + 1) #define METALSONIC_TT_CACHE_INDEX (MAXSKINS + 2) #define ALLWHITE_TT_CACHE_INDEX (MAXSKINS + 3) -#define SKIN_RAMP_LENGTH 16 -#define DEFAULT_STARTTRANSCOLOR 160 +#define DEFAULT_STARTTRANSCOLOR 96 #define NUM_PALETTE_ENTRIES 256 static UINT8** translationtablecache[MAXSKINS + 4] = {NULL}; +const UINT8 Color_Index[MAXTRANSLATIONS-1][16] = { + // {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // SKINCOLOR_NONE + + // Greyscale ranges + {0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x11}, // SKINCOLOR_WHITE + {0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x11, 0x12}, // SKINCOLOR_BONE + {0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14}, // SKINCOLOR_CLOUDY + {0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}, // SKINCOLOR_GREY + {0x02, 0x03, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f}, // SKINCOLOR_SILVER + {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x16, 0x17, 0x17, 0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1c, 0x1d}, // SKINCOLOR_CARBON + {0x00, 0x05, 0x0a, 0x0f, 0x14, 0x19, 0x1a, 0x1b, 0x1c, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f}, // SKINCOLOR_JET + {0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f, 0x1f}, // SKINCOLOR_BLACK + + // Desaturated + {0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x91, 0x91, 0x91, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf}, // SKINCOLOR_AETHER + {0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0xaa, 0xaa, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xad, 0xae, 0xaf}, // SKINCOLOR_SLATE + {0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x2b, 0x2c, 0x2e}, // SKINCOLOR_PINK + {0xd0, 0x30, 0xd8, 0xd9, 0xda, 0xdb, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe3, 0xe6, 0xe8, 0xe9}, // SKINCOLOR_YOGURT + {0xdf, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef}, // SKINCOLOR_BROWN + {0x51, 0x51, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0xf5, 0xf5, 0xf9, 0xf9, 0xed, 0xed}, // SKINCOLOR_TAN + {0x54, 0x55, 0x56, 0x56, 0xf2, 0xf3, 0xf3, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfb, 0xed, 0xed}, // SKINCOLOR_BEIGE + {0x58, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f}, // SKINCOLOR_MOSS + {0x90, 0x90, 0x91, 0x91, 0xaa, 0xaa, 0xab, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf}, // SKINCOLOR_AZURE + {0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7}, // SKINCOLOR_LAVENDER + + // Viv's vivid colours (toast 21/07/17) + {0xb0, 0xb0, 0xc9, 0xca, 0xcc, 0x26, 0x27, 0x28, 0x29, 0x2a, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfd}, // SKINCOLOR_RUBY + {0xd0, 0xd0, 0xd1, 0xd2, 0x20, 0x21, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e}, // SKINCOLOR_SALMON + {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x47, 0x2e, 0x2f}, // SKINCOLOR_RED + {0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2b, 0x2c, 0x2d, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x1f}, // SKINCOLOR_CRIMSON + {0x31, 0x32, 0x33, 0x36, 0x22, 0x22, 0x25, 0x25, 0x25, 0xcd, 0xcf, 0xcf, 0xc5, 0xc5, 0xc7, 0xc7}, // SKINCOLOR_FLAME + {0xd0, 0x30, 0x31, 0x31, 0x32, 0x32, 0xdc, 0xdc, 0xdc, 0xd3, 0xd4, 0xd4, 0xcc, 0xcd, 0xce, 0xcf}, // SKINCOLOR_PEACHY + {0xd8, 0xd9, 0xdb, 0xdc, 0xde, 0xdf, 0xd5, 0xd5, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0x1d, 0x1f}, // SKINCOLOR_QUAIL + {0x51, 0x52, 0x40, 0x40, 0x34, 0x36, 0xd5, 0xd5, 0xd6, 0xd7, 0xcf, 0xcf, 0xc6, 0xc6, 0xc7, 0xfe}, // SKINCOLOR_SUNSET + {0x00, 0xd8, 0xd9, 0xda, 0xdb, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e}, // SKINCOLOR_APRICOT + {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x2c}, // SKINCOLOR_ORANGE + {0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3f, 0x2c, 0x2d, 0x47, 0x2e, 0x2f, 0x2f}, // SKINCOLOR_RUST + {0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, // SKINCOLOR_GOLD + {0x53, 0x40, 0x41, 0x42, 0x43, 0xe6, 0xe9, 0xe9, 0xea, 0xec, 0xec, 0xc6, 0xc6, 0xc7, 0xc7, 0xfe}, // SKINCOLOR_SANDY + {0x52, 0x53, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4f, 0xed}, // SKINCOLOR_YELLOW + {0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4e, 0xe7, 0xe7, 0xe9, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7, 0xfd}, // SKINCOLOR_OLIVE + {0x50, 0x51, 0x52, 0x53, 0x48, 0xbc, 0xbd, 0xbe, 0xbe, 0xbf, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, // SKINCOLOR_LIME + {0x58, 0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, 0x5e, 0x5e, 0x5f, 0x5f, 0x77, 0x77}, // SKINCOLOR_PERIDOT + {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, // SKINCOLOR_GREEN + {0x65, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f}, // SKINCOLOR_FOREST + {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, // SKINCOLOR_EMERALD + {0x00, 0x00, 0x58, 0x58, 0x59, 0x62, 0x62, 0x62, 0x64, 0x67, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a}, // SKINCOLOR_MINT + {0x01, 0x58, 0x59, 0x5a, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0xfd, 0xfd}, // SKINCOLOR_SEAFOAM + {0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, // SKINCOLOR_AQUA + {0x78, 0x78, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0x8a}, // SKINCOLOR_TEAL + {0x00, 0x78, 0x78, 0x79, 0x8d, 0x87, 0x88, 0x89, 0x89, 0xae, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfd}, // SKINCOLOR_WAVE + {0x80, 0x81, 0xff, 0xff, 0x83, 0x83, 0x8d, 0x8d, 0x8d, 0x8e, 0x7e, 0x7f, 0x76, 0x76, 0x77, 0x6e}, // SKINCOLOR_CYAN + {0x80, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x85, 0x85, 0x86, 0x87, 0x88, 0x89, 0x89, 0x8a, 0x8b}, // SKINCOLOR_SKY + {0x85, 0x86, 0x87, 0x88, 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0xfd, 0xfd, 0xfd, 0x1f, 0x1f, 0x1f}, // SKINCOLOR_CERULEAN + {0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83, 0x83, 0x86, 0x87, 0x95, 0x95, 0xad, 0xad, 0xae, 0xaf}, // SKINCOLOR_ICY + {0x80, 0x83, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, // SKINCOLOR_SAPPHIRE + {0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x9a, 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e}, // SKINCOLOR_CORNFLOWER + {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, // SKINCOLOR_BLUE + {0x93, 0x94, 0x95, 0x96, 0x98, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfd, 0xfe, 0xfe}, // SKINCOLOR_COBALT + {0x80, 0x81, 0x83, 0x86, 0x94, 0x94, 0xa3, 0xa3, 0xa4, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa9, 0xa9}, // SKINCOLOR_VAPOR + {0x92, 0x93, 0x94, 0x94, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xa9, 0xa9, 0xfd, 0xfd}, // SKINCOLOR_DUSK + {0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, // SKINCOLOR_PASTEL + {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa8, 0xa9, 0xa9}, // SKINCOLOR_PURPLE + {0x00, 0xd0, 0xd0, 0xc8, 0xc8, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, // SKINCOLOR_BUBBLEGUM + {0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb}, // SKINCOLOR_MAGENTA + {0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb, 0xc7, 0xc7, 0x1d, 0x1d, 0x1e}, // SKINCOLOR_NEON + {0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, // SKINCOLOR_VIOLET + {0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, // SKINCOLOR_LILAC + {0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, // SKINCOLOR_PLUM + {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, // SKINCOLOR_ROSY + + // {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // SKINCOLOR_? + + // super + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03}, // SKINCOLOR_SUPERSILVER1 + {0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07}, // SKINCOLOR_SUPERSILVER2 + {0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b}, // SKINCOLOR_SUPERSILVER3 + {0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11}, // SKINCOLOR_SUPERSILVER4 + {0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13}, // SKINCOLOR_SUPERSILVER5 + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2}, // SKINCOLOR_SUPERRED1 + {0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd2, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21}, // SKINCOLOR_SUPERRED2 + {0x00, 0x00, 0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23}, // SKINCOLOR_SUPERRED3 + {0x00, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24}, // SKINCOLOR_SUPERRED4 + {0xd0, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25}, // SKINCOLOR_SUPERRED5 + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34}, // SKINCOLOR_SUPERORANGE1 + {0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34}, // SKINCOLOR_SUPERORANGE2 + {0x00, 0x00, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x35}, // SKINCOLOR_SUPERORANGE3 + {0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46}, // SKINCOLOR_SUPERORANGE4 + {0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46, 0x47}, // SKINCOLOR_SUPERORANGE5 + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x52, 0x53, 0x48}, // SKINCOLOR_SUPERGOLD1 + {0x00, 0x50, 0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41}, // SKINCOLOR_SUPERGOLD2 + {0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43}, // SKINCOLOR_SUPERGOLD3 + {0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}, // SKINCOLOR_SUPERGOLD4 + {0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47}, // SKINCOLOR_SUPERGOLD5 + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc}, // SKINCOLOR_SUPERPERIDOT1 + {0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe}, // SKINCOLOR_SUPERPERIDOT2 + {0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf}, // SKINCOLOR_SUPERPERIDOT3 + {0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f}, // SKINCOLOR_SUPERPERIDOT4 + {0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f, 0x77}, // SKINCOLOR_SUPERPERIDOT5 + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x81, 0x82, 0x83, 0x84}, // SKINCOLOR_SUPERSKY1 + {0x00, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86}, // SKINCOLOR_SUPERSKY2 + {0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87}, // SKINCOLOR_SUPERSKY3 + {0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a}, // SKINCOLOR_SUPERSKY4 + {0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a, 0x8b}, // SKINCOLOR_SUPERSKY5 + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa2}, // SKINCOLOR_SUPERPURPLE1 + {0x00, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5}, // SKINCOLOR_SUPERPURPLE2 + {0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6}, // SKINCOLOR_SUPERPURPLE3 + {0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9}, // SKINCOLOR_SUPERPURPLE4 + {0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9, 0xfd}, // SKINCOLOR_SUPERPURPLE5 + + {0x00, 0xd0, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x32, 0x33, 0x37, 0x3a, 0x44, 0x45, 0x46, 0x47, 0x2e}, // SKINCOLOR_SUPERRUST1 + {0x30, 0x31, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x38, 0x3a, 0x44, 0x45, 0x46, 0x47, 0x47, 0x2e}, // SKINCOLOR_SUPERRUST2 + {0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x3a, 0x44, 0x45, 0x45, 0x46, 0x46, 0x47, 0x2e, 0x2e}, // SKINCOLOR_SUPERRUST3 + {0x48, 0x40, 0x41, 0x42, 0x43, 0x44, 0x44, 0x45, 0x45, 0x46, 0x46, 0x47, 0x47, 0x2e, 0x2e, 0x2e}, // SKINCOLOR_SUPERRUST4 + {0x41, 0x42, 0x43, 0x43, 0x44, 0x44, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xed, 0xee, 0xee, 0xef, 0xef}, // SKINCOLOR_SUPERRUST5 + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52}, // SKINCOLOR_SUPERTAN1 + {0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5}, // SKINCOLOR_SUPERTAN2 + {0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9}, // SKINCOLOR_SUPERTAN3 + {0x51, 0x52, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed}, // SKINCOLOR_SUPERTAN4 + {0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed, 0xee, 0xef, 0xef} // SKINCOLOR_SUPERTAN5 +}; // See also the enum skincolors_t // TODO Callum: Can this be translated? -const char *Color_Names[MAXSKINCOLORS] = +const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS] = { - "None", // SKINCOLOR_NONE - "White", // SKINCOLOR_WHITE - "Silver", // SKINCOLOR_SILVER - "Grey", // SKINCOLOR_GREY - "Black", // SKINCOLOR_BLACK - "Cyan", // SKINCOLOR_CYAN - "Teal", // SKINCOLOR_TEAL - "Steel_Blue",// SKINCOLOR_STEELBLUE - "Blue", // SKINCOLOR_BLUE - "Peach", // SKINCOLOR_PEACH - "Tan", // SKINCOLOR_TAN - "Pink", // SKINCOLOR_PINK - "Lavender", // SKINCOLOR_LAVENDER - "Purple", // SKINCOLOR_PURPLE - "Orange", // SKINCOLOR_ORANGE - "Rosewood", // SKINCOLOR_ROSEWOOD - "Beige", // SKINCOLOR_BEIGE - "Brown", // SKINCOLOR_BROWN - "Red", // SKINCOLOR_RED - "Dark_Red", // SKINCOLOR_DARKRED - "Neon_Green",// SKINCOLOR_NEONGREEN - "Green", // SKINCOLOR_GREEN - "Zim", // SKINCOLOR_ZIM - "Olive", // SKINCOLOR_OLIVE - "Yellow", // SKINCOLOR_YELLOW - "Gold" // SKINCOLOR_GOLD + "None", // SKINCOLOR_NONE, + + // Greyscale ranges + "White", // SKINCOLOR_WHITE, + "Bone", // SKINCOLOR_BONE, + "Cloudy", // SKINCOLOR_CLOUDY, + "Grey", // SKINCOLOR_GREY, + "Silver", // SKINCOLOR_SILVER, + "Carbon", // SKINCOLOR_CARBON, + "Jet", // SKINCOLOR_JET, + "Black", // SKINCOLOR_BLACK, + + // Desaturated + "Aether", // SKINCOLOR_AETHER, + "Slate", // SKINCOLOR_SLATE, + "Pink", // SKINCOLOR_PINK, + "Yogurt", // SKINCOLOR_YOGURT, + "Brown", // SKINCOLOR_BROWN, + "Tan", // SKINCOLOR_TAN, + "Beige", // SKINCOLOR_BEIGE, + "Moss", // SKINCOLOR_MOSS, + "Azure", // SKINCOLOR_AZURE, + "Lavender", // SKINCOLOR_LAVENDER, + + // Viv's vivid colours (toast 21/07/17) + "Ruby", // SKINCOLOR_RUBY, + "Salmon", // SKINCOLOR_SALMON, + "Red", // SKINCOLOR_RED, + "Crimson", // SKINCOLOR_CRIMSON, + "Flame", // SKINCOLOR_FLAME, + "Peachy", // SKINCOLOR_PEACHY, + "Quail", // SKINCOLOR_QUAIL, + "Sunset", // SKINCOLOR_SUNSET, + "Apricot", // SKINCOLOR_APRICOT, + "Orange", // SKINCOLOR_ORANGE, + "Rust", // SKINCOLOR_RUST, + "Gold", // SKINCOLOR_GOLD, + "Sandy", // SKINCOLOR_SANDY, + "Yellow", // SKINCOLOR_YELLOW, + "Olive", // SKINCOLOR_OLIVE, + "Lime", // SKINCOLOR_LIME, + "Peridot", // SKINCOLOR_PERIDOT, + "Green", // SKINCOLOR_GREEN, + "Forest", // SKINCOLOR_FOREST, + "Emerald", // SKINCOLOR_EMERALD, + "Mint", // SKINCOLOR_MINT, + "Seafoam", // SKINCOLOR_SEAFOAM, + "Aqua", // SKINCOLOR_AQUA, + "Teal", // SKINCOLOR_TEAL, + "Wave", // SKINCOLOR_WAVE, + "Cyan", // SKINCOLOR_CYAN, + "Sky", // SKINCOLOR_SKY, + "Cerulean", // SKINCOLOR_CERULEAN, + "Icy", // SKINCOLOR_ICY, + "Sapphire", // SKINCOLOR_SAPPHIRE, + "Cornflower", // SKINCOLOR_CORNFLOWER, + "Blue", // SKINCOLOR_BLUE, + "Cobalt", // SKINCOLOR_COBALT, + "Vapor", // SKINCOLOR_VAPOR, + "Dusk", // SKINCOLOR_DUSK, + "Pastel", // SKINCOLOR_PASTEL, + "Purple", // SKINCOLOR_PURPLE, + "Bubblegum", // SKINCOLOR_BUBBLEGUM, + "Magenta", // SKINCOLOR_MAGENTA, + "Neon", // SKINCOLOR_NEON, + "Violet", // SKINCOLOR_VIOLET, + "Lilac", // SKINCOLOR_LILAC, + "Plum", // SKINCOLOR_PLUM, + "Rosy", // SKINCOLOR_ROSY, + + // Super behaves by different rules (one name per 5 colours), and will be accessed exclusively via R_GetSuperColorByName instead of R_GetColorByName. + "Silver", // SKINCOLOR_SUPERSILVER1, + "Red", // SKINCOLOR_SUPERRED1, + "Orange", // SKINCOLOR_SUPERORANGE1, + "Gold", // SKINCOLOR_SUPERGOLD1, + "Peridot", // SKINCOLOR_SUPERPERIDOT1, + "Sky", // SKINCOLOR_SUPERSKY1, + "Purple", // SKINCOLOR_SUPERPURPLE1, + "Rust", // SKINCOLOR_SUPERRUST1, + "Tan" // SKINCOLOR_SUPERTAN1, }; -const UINT8 Color_Opposite[MAXSKINCOLORS*2] = +/* +A word of warning: If the following array is non-symmetrical, +A_SignPlayer's prefoppositecolor behaviour will break. +*/ +const UINT8 Color_Opposite[(MAXSKINCOLORS - 1)*2] = { - SKINCOLOR_NONE,8, // SKINCOLOR_NONE - SKINCOLOR_BLACK,10, // SKINCOLOR_WHITE - SKINCOLOR_GREY,4, // SKINCOLOR_SILVER - SKINCOLOR_SILVER,12,// SKINCOLOR_GREY - SKINCOLOR_WHITE,8, // SKINCOLOR_BLACK - SKINCOLOR_NONE,8, // SKINCOLOR_CYAN - SKINCOLOR_NONE,8, // SKINCOLOR_TEAL - SKINCOLOR_NONE,8, // SKINCOLOR_STEELBLUE - SKINCOLOR_ORANGE,9, // SKINCOLOR_BLUE - SKINCOLOR_NONE,8, // SKINCOLOR_PEACH - SKINCOLOR_NONE,8, // SKINCOLOR_TAN - SKINCOLOR_NONE,8, // SKINCOLOR_PINK - SKINCOLOR_NONE,8, // SKINCOLOR_LAVENDER - SKINCOLOR_NONE,8, // SKINCOLOR_PURPLE - SKINCOLOR_BLUE,12, // SKINCOLOR_ORANGE - SKINCOLOR_NONE,8, // SKINCOLOR_ROSEWOOD - SKINCOLOR_NONE,8, // SKINCOLOR_BEIGE - SKINCOLOR_NONE,8, // SKINCOLOR_BROWN - SKINCOLOR_GREEN,5, // SKINCOLOR_RED - SKINCOLOR_NONE,8, // SKINCOLOR_DARKRED - SKINCOLOR_NONE,8, // SKINCOLOR_NEONGREEN - SKINCOLOR_RED,11, // SKINCOLOR_GREEN - SKINCOLOR_PURPLE,3, // SKINCOLOR_ZIM - SKINCOLOR_NONE,8, // SKINCOLOR_OLIVE - SKINCOLOR_NONE,8, // SKINCOLOR_YELLOW - SKINCOLOR_NONE,8 // SKINCOLOR_GOLD + // SKINCOLOR_NONE,8, // SKINCOLOR_NONE + + // Greyscale ranges + SKINCOLOR_BLACK,5, // SKINCOLOR_WHITE, + SKINCOLOR_JET,7, // SKINCOLOR_BONE, + SKINCOLOR_CARBON,7, // SKINCOLOR_CLOUDY, + SKINCOLOR_AETHER,12, // SKINCOLOR_GREY, + SKINCOLOR_SLATE,12, // SKINCOLOR_SILVER, + SKINCOLOR_CLOUDY,7, // SKINCOLOR_CARBON, + SKINCOLOR_BONE,7, // SKINCOLOR_JET, + SKINCOLOR_WHITE,7, // SKINCOLOR_BLACK, + + // Desaturated + SKINCOLOR_GREY,15, // SKINCOLOR_AETHER, + SKINCOLOR_SILVER,12, // SKINCOLOR_SLATE, + SKINCOLOR_AZURE,9, // SKINCOLOR_PINK, + SKINCOLOR_RUST,7, // SKINCOLOR_YOGURT, + SKINCOLOR_TAN,2, // SKINCOLOR_BROWN, + SKINCOLOR_BROWN,12, // SKINCOLOR_TAN, + SKINCOLOR_MOSS,5, // SKINCOLOR_BEIGE, + SKINCOLOR_BEIGE,13, // SKINCOLOR_MOSS, + SKINCOLOR_PINK,5, // SKINCOLOR_AZURE, + SKINCOLOR_GOLD,4, // SKINCOLOR_LAVENDER, + + // Viv's vivid colours (toast 21/07/17) + SKINCOLOR_EMERALD,10, // SKINCOLOR_RUBY, + SKINCOLOR_FOREST,6, // SKINCOLOR_SALMON, + SKINCOLOR_GREEN,10, // SKINCOLOR_RED, + SKINCOLOR_ICY,10, // SKINCOLOR_CRIMSON, + SKINCOLOR_PURPLE,8, // SKINCOLOR_FLAME, + SKINCOLOR_TEAL,7, // SKINCOLOR_PEACHY, + SKINCOLOR_WAVE,5, // SKINCOLOR_QUAIL, + SKINCOLOR_SAPPHIRE,5, // SKINCOLOR_SUNSET, + SKINCOLOR_CYAN,4, // SKINCOLOR_APRICOT, + SKINCOLOR_BLUE,4, // SKINCOLOR_ORANGE, + SKINCOLOR_YOGURT,8, // SKINCOLOR_RUST, + SKINCOLOR_LAVENDER,10, // SKINCOLOR_GOLD, + SKINCOLOR_SKY,8, // SKINCOLOR_SANDY, + SKINCOLOR_CORNFLOWER,8, // SKINCOLOR_YELLOW, + SKINCOLOR_DUSK,3, // SKINCOLOR_OLIVE, + SKINCOLOR_MAGENTA,9, // SKINCOLOR_LIME, + SKINCOLOR_COBALT,2, // SKINCOLOR_PERIDOT, + SKINCOLOR_RED,6, // SKINCOLOR_GREEN, + SKINCOLOR_SALMON,9, // SKINCOLOR_FOREST, + SKINCOLOR_RUBY,4, // SKINCOLOR_EMERALD, + SKINCOLOR_VIOLET,5, // SKINCOLOR_MINT, + SKINCOLOR_PLUM,6, // SKINCOLOR_SEAFOAM, + SKINCOLOR_ROSY,7, // SKINCOLOR_AQUA, + SKINCOLOR_PEACHY,7, // SKINCOLOR_TEAL, + SKINCOLOR_QUAIL,5, // SKINCOLOR_WAVE, + SKINCOLOR_APRICOT,6, // SKINCOLOR_CYAN, + SKINCOLOR_SANDY,1, // SKINCOLOR_SKY, + SKINCOLOR_NEON,4, // SKINCOLOR_CERULEAN, + SKINCOLOR_CRIMSON,0, // SKINCOLOR_ICY, + SKINCOLOR_SUNSET,5, // SKINCOLOR_SAPPHIRE, + SKINCOLOR_YELLOW,4, // SKINCOLOR_CORNFLOWER, + SKINCOLOR_ORANGE,5, // SKINCOLOR_BLUE, + SKINCOLOR_PERIDOT,5, // SKINCOLOR_COBALT, + SKINCOLOR_LILAC,4, // SKINCOLOR_VAPOR, + SKINCOLOR_OLIVE,0, // SKINCOLOR_DUSK, + SKINCOLOR_BUBBLEGUM,9, // SKINCOLOR_PASTEL, + SKINCOLOR_FLAME,7, // SKINCOLOR_PURPLE, + SKINCOLOR_PASTEL,8, // SKINCOLOR_BUBBLEGUM, + SKINCOLOR_LIME,6, // SKINCOLOR_MAGENTA, + SKINCOLOR_CERULEAN,2, // SKINCOLOR_NEON, + SKINCOLOR_MINT,6, // SKINCOLOR_VIOLET, + SKINCOLOR_VAPOR,4, // SKINCOLOR_LILAC, + SKINCOLOR_MINT,7, // SKINCOLOR_PLUM, + SKINCOLOR_AQUA,1 // SKINCOLOR_ROSY, }; CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1]; @@ -203,10 +431,6 @@ CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1]; */ void R_InitTranslationTables(void) { -#ifdef _NDS - // Ugly temporary NDS hack. - transtables = (UINT8*)0x2000000; -#else // Load here the transparency lookup tables 'TINTTAB' // NOTE: the TINTTAB resource MUST BE aligned on 64k for the asm // optimised code (in other words, transtables pointer low word is 0) @@ -222,7 +446,6 @@ void R_InitTranslationTables(void) W_ReadLump(W_GetNumForName("TRANS70"), transtables+0x60000); W_ReadLump(W_GetNumForName("TRANS80"), transtables+0x70000); W_ReadLump(W_GetNumForName("TRANS90"), transtables+0x80000); -#endif } @@ -236,36 +459,7 @@ void R_InitTranslationTables(void) */ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color) { - // Table of indices into the palette of the first entries of each translated ramp - const UINT8 skinbasecolors[] = { - 0x00, // SKINCOLOR_WHITE - 0x03, // SKINCOLOR_SILVER - 0x08, // SKINCOLOR_GREY - 0x18, // SKINCOLOR_BLACK - 0xd0, // SKINCOLOR_CYAN - 0xdc, // SKINCOLOR_TEAL - 0xc8, // SKINCOLOR_STEELBLUE - 0xe2, // SKINCOLOR_BLUE - 0x40, // SKINCOLOR_PEACH - 0x48, // SKINCOLOR_TAN - 0x90, // SKINCOLOR_PINK - 0xf8, // SKINCOLOR_LAVENDER - 0xc0, // SKINCOLOR_PURPLE - 0x52, // SKINCOLOR_ORANGE - 0x5c, // SKINCOLOR_ROSEWOOD - 0x20, // SKINCOLOR_BEIGE - 0x30, // SKINCOLOR_BROWN - 0x7d, // SKINCOLOR_RED - 0x85, // SKINCOLOR_DARKRED - 0xb8, // SKINCOLOR_NEONGREEN - 0xa0, // SKINCOLOR_GREEN - 0xb0, // SKINCOLOR_ZIM - 0x69, // SKINCOLOR_OLIVE - 0x67, // SKINCOLOR_YELLOW - 0x70, // SKINCOLOR_GOLD - }; - INT32 i; - INT32 starttranscolor; + INT32 i, starttranscolor, skinramplength; // Handle a couple of simple special cases if (skinnum == TC_BOSS || skinnum == TC_ALLWHITE || skinnum == TC_METALSONIC || color == SKINCOLOR_NONE) @@ -280,221 +474,33 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U if (skinnum == TC_BOSS) dest_colormap[31] = 0; else if (skinnum == TC_METALSONIC) - dest_colormap[239] = 0; + dest_colormap[159] = 0; return; } + if (color >= MAXTRANSLATIONS) + I_Error("Invalid skin color #%hu.", (UINT16)color); + starttranscolor = (skinnum != TC_DEFAULT) ? skins[skinnum].starttranscolor : DEFAULT_STARTTRANSCOLOR; // Fill in the entries of the palette that are fixed for (i = 0; i < starttranscolor; i++) dest_colormap[i] = (UINT8)i; - for (i = (UINT8)(starttranscolor + 16); i < NUM_PALETTE_ENTRIES; i++) - dest_colormap[i] = (UINT8)i; - - // Build the translated ramp - switch (color) + i = starttranscolor + 16; + if (i < NUM_PALETTE_ENTRIES) { - case SKINCOLOR_SILVER: - case SKINCOLOR_GREY: - case SKINCOLOR_PEACH: - case SKINCOLOR_BEIGE: - case SKINCOLOR_BROWN: - case SKINCOLOR_RED: - case SKINCOLOR_GREEN: - case SKINCOLOR_BLUE: - // 16 color ramp - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i); - break; - - case SKINCOLOR_ORANGE: - // 14 colors of orange + brown - for (i = 0; i < SKIN_RAMP_LENGTH-2; i++) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i); - for (i = 0; i < 2; i++) - dest_colormap[starttranscolor + (i+SKIN_RAMP_LENGTH-2)] = (UINT8)(152 + i); - break; - - case SKINCOLOR_CYAN: - // 12 color ramp - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (12*i/SKIN_RAMP_LENGTH)); - break; - - case SKINCOLOR_WHITE: - case SKINCOLOR_BLACK: - case SKINCOLOR_STEELBLUE: - case SKINCOLOR_PINK: - case SKINCOLOR_LAVENDER: - case SKINCOLOR_PURPLE: - case SKINCOLOR_DARKRED: - case SKINCOLOR_ZIM: - case SKINCOLOR_YELLOW: - case SKINCOLOR_GOLD: - // 8 color ramp - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1)); - break; - - case SKINCOLOR_TEAL: - // 5 color ramp - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (5*i/16 == 0) - dest_colormap[starttranscolor + i] = 0xf7; - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (5*i/SKIN_RAMP_LENGTH) - 1); - } - break; - - case SKINCOLOR_OLIVE: - // 7 color ramp - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (7*i/SKIN_RAMP_LENGTH)); - break; - - case SKINCOLOR_TAN: - // 16 color ramp, from two color ranges - for (i = 0; i < SKIN_RAMP_LENGTH/2; i++) // Peach half - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i); - for (i = 0; i < SKIN_RAMP_LENGTH/2; i++) // Brown half - dest_colormap[starttranscolor + (i+8)] = (UINT8)(48 + i); - break; - - case SKINCOLOR_ROSEWOOD: - // 12 color ramp, from two color ranges! - for (i = 0; i < 6; i++) // Orange ...third? - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (12*i/SKIN_RAMP_LENGTH)); - for (i = 0; i < 10; i++) // Rosewood two-thirds-ish - dest_colormap[starttranscolor + (i+6)] = (UINT8)(152 + (12*i/SKIN_RAMP_LENGTH)); - break; - - case SKINCOLOR_NEONGREEN: - // Multi-color ramp - dest_colormap[starttranscolor] = 0xA0; // Brighter green - for (i = 0; i < SKIN_RAMP_LENGTH-1; i++) // Neon Green - dest_colormap[starttranscolor + (i+1)] = (UINT8)(skinbasecolors[color - 1] + (6*i/(SKIN_RAMP_LENGTH-1))); - break; - - // Super colors, from lightest to darkest! - case SKINCOLOR_SUPER1: - // Super White - for (i = 0; i < 10; i++) - dest_colormap[starttranscolor + i] = 120; // True white - for (; i < SKIN_RAMP_LENGTH; i++) // White-yellow fade - dest_colormap[starttranscolor + i] = (UINT8)(96 + (i-10)); - break; - - case SKINCOLOR_SUPER2: - // Super Bright - for (i = 0; i < 5; i++) // White-yellow fade - dest_colormap[starttranscolor + i] = (UINT8)(96 + i); - dest_colormap[starttranscolor + 5] = 112; // Golden shine - for (i = 0; i < 8; i++) // Yellow - dest_colormap[starttranscolor + (i+6)] = (UINT8)(101 + (i>>1)); - for (i = 0; i < 2; i++) // With a fine golden finish! :3 - dest_colormap[starttranscolor + (i+14)] = (UINT8)(113 + i); - break; - - case SKINCOLOR_SUPER3: - // Super Yellow - for (i = 0; i < 3; i++) // White-yellow fade - dest_colormap[starttranscolor + i] = (UINT8)(98 + i); - dest_colormap[starttranscolor + 3] = 112; // Golden shine - for (i = 0; i < 8; i++) // Yellow - dest_colormap[starttranscolor + (i+4)] = (UINT8)(101 + (i>>1)); - for (i = 0; i < 4; i++) // With a fine golden finish! :3 - dest_colormap[starttranscolor + (i+12)] = (UINT8)(113 + i); - break; - - case SKINCOLOR_SUPER4: - // "The SSNTails" - dest_colormap[starttranscolor] = 112; // Golden shine - for (i = 0; i < 8; i++) // Yellow - dest_colormap[starttranscolor + (i+1)] = (UINT8)(101 + (i>>1)); - for (i = 0; i < 7; i++) // With a fine golden finish! :3 - dest_colormap[starttranscolor + (i+9)] = (UINT8)(113 + i); - break; - - case SKINCOLOR_SUPER5: - // Golden Delicious - for (i = 0; i < 8; i++) // Yellow - dest_colormap[starttranscolor + i] = (UINT8)(101 + (i>>1)); - for (i = 0; i < 7; i++) // With a fine golden finish! :3 - dest_colormap[starttranscolor + (i+8)] = (UINT8)(113 + i); - dest_colormap[starttranscolor + 15] = 155; - break; - - // Super Tails - case SKINCOLOR_TSUPER1: - for (i = 0; i < 10; i++) // white - dest_colormap[starttranscolor + i] = 120; - for (; i < SKIN_RAMP_LENGTH; i++) // orange - dest_colormap[starttranscolor + i] = (UINT8)(80 + (i-10)); - break; - - case SKINCOLOR_TSUPER2: - for (i = 0; i < 4; i++) // white - dest_colormap[starttranscolor + i] = 120; - for (; i < SKIN_RAMP_LENGTH; i++) // orange - dest_colormap[starttranscolor + i] = (UINT8)(80 + ((i-4)>>1)); - break; - - case SKINCOLOR_TSUPER3: - dest_colormap[starttranscolor] = 120; // pure white - dest_colormap[starttranscolor+1] = 120; - for (i = 2; i < SKIN_RAMP_LENGTH; i++) // orange - dest_colormap[starttranscolor + i] = (UINT8)(80 + ((i-2)>>1)); - break; - - case SKINCOLOR_TSUPER4: - dest_colormap[starttranscolor] = 120; // pure white - for (i = 1; i < 9; i++) // orange - dest_colormap[starttranscolor + i] = (UINT8)(80 + (i-1)); - for (; i < SKIN_RAMP_LENGTH; i++) // gold - dest_colormap[starttranscolor + i] = (UINT8)(115 + (5*(i-9)/7)); - break; - - case SKINCOLOR_TSUPER5: - for (i = 0; i < 8; i++) // orange - dest_colormap[starttranscolor + i] = (UINT8)(80 + i); - for (; i < SKIN_RAMP_LENGTH; i++) // gold - dest_colormap[starttranscolor + i] = (UINT8)(115 + (5*(i-8)/8)); - break; - - // Super Knuckles - case SKINCOLOR_KSUPER1: - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(120 + (i >> 2)); - break; - - case SKINCOLOR_KSUPER2: - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(120 + (6*i/SKIN_RAMP_LENGTH)); - break; - - case SKINCOLOR_KSUPER3: - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(120 + (i >> 1)); - break; - - case SKINCOLOR_KSUPER4: - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(121 + (i >> 1)); - break; - - case SKINCOLOR_KSUPER5: - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(122 + (i >> 1)); - break; - - default: - I_Error("Invalid skin color #%hu.", (UINT16)color); - break; + for (i = (UINT8)i; i < NUM_PALETTE_ENTRIES; i++) + dest_colormap[i] = (UINT8)i; + skinramplength = 16; } + else + skinramplength = i - NUM_PALETTE_ENTRIES; + + // Build the translated ramp + for (i = 0; i < skinramplength; i++) + dest_colormap[starttranscolor + i] = (UINT8)Color_Index[color-1][i]; } @@ -569,7 +575,18 @@ UINT8 R_GetColorByName(const char *name) for (color = 1; color < MAXSKINCOLORS; color++) if (!stricmp(Color_Names[color], name)) return color; - return 0; + return SKINCOLOR_GREEN; +} + +UINT8 R_GetSuperColorByName(const char *name) +{ + UINT8 color; /* = (UINT8)atoi(name); -- This isn't relevant to S_SKIN, which is the only way it's accessible right now. Let's simplify things. + if (color > MAXSKINCOLORS && color < MAXTRANSLATIONS && !((color - MAXSKINCOLORS) % 5)) + return color;*/ + for (color = 0; color < NUMSUPERCOLORS; color++) + if (!stricmp(Color_Names[color + MAXSKINCOLORS], name)) + return ((color*5) + MAXSKINCOLORS); + return SKINCOLOR_SUPERGOLD1; } // ========================================================================== diff --git a/src/r_draw.h b/src/r_draw.h index 12f556b7ab41ef37097cd403c4d3f7e748074c44..0c04fee2a76e9e1cac286cdaf8cc82a0d7fa8c2d 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -111,6 +111,7 @@ void R_InitTranslationTables(void); UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags); void R_FlushTranslationColormapCache(void); UINT8 R_GetColorByName(const char *name); +UINT8 R_GetSuperColorByName(const char *name); // Custom player skin translation void R_InitViewBuffer(INT32 width, INT32 height); diff --git a/src/r_draw8.c b/src/r_draw8.c index 886b72daeb71832fdb345ca3e7e32e5a519f506c..8a2d37fb3d796d81b7bf1a470d8bfa93971f3d0e 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -105,7 +105,7 @@ void R_DrawColumn_8(void) } } -#define TRANSPARENTPIXEL 247 +#define TRANSPARENTPIXEL 255 void R_Draw2sMultiPatchColumn_8(void) { diff --git a/src/r_main.c b/src/r_main.c index 3e477690897568b59ab008fda8a54f9cd624a649..703993fc9edf34cd18d2a9e40d5181172dfaa812 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -30,6 +30,7 @@ #include "p_spec.h" // skyboxmo #include "z_zone.h" #include "m_random.h" // quake camera shake +#include "r_portal.h" #ifdef HWRENDER #include "hardware/hw_main.h" @@ -65,37 +66,9 @@ size_t loopcount; fixed_t viewx, viewy, viewz; angle_t viewangle, aimingangle; fixed_t viewcos, viewsin; -boolean viewsky, skyVisible; -boolean skyVisible1, skyVisible2; // saved values of skyVisible for P1 and P2, for splitscreen sector_t *viewsector; player_t *viewplayer; -// PORTALS! -// You can thank and/or curse JTE for these. -UINT8 portalrender; -sector_t *portalcullsector; -typedef struct portal_pair -{ - INT32 line1; - INT32 line2; - UINT8 pass; - struct portal_pair *next; - - fixed_t viewx; - fixed_t viewy; - fixed_t viewz; - angle_t viewangle; - - INT32 start; - INT32 end; - INT16 *ceilingclip; - INT16 *floorclip; - fixed_t *frontscale; -} portal_pair; -portal_pair *portal_base, *portal_cap; -line_t *portalclipline; -INT32 portalclipstart, portalclipend; - // // precalculated math tables // @@ -118,15 +91,21 @@ lighttable_t *scalelightfixed[MAXLIGHTSCALE]; lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; // Hack to support extra boom colormaps. -size_t num_extra_colormaps; -extracolormap_t extra_colormaps[MAXCOLORMAPS]; +extracolormap_t *extra_colormaps = NULL; static CV_PossibleValue_t drawdist_cons_t[] = { {256, "256"}, {512, "512"}, {768, "768"}, {1024, "1024"}, {1536, "1536"}, {2048, "2048"}, {3072, "3072"}, {4096, "4096"}, {6144, "6144"}, {8192, "8192"}, {0, "Infinite"}, {0, NULL}}; -static CV_PossibleValue_t precipdensity_cons_t[] = {{0, "None"}, {1, "Light"}, {2, "Moderate"}, {4, "Heavy"}, {6, "Thick"}, {8, "V.Thick"}, {0, NULL}}; + +//static CV_PossibleValue_t precipdensity_cons_t[] = {{0, "None"}, {1, "Light"}, {2, "Moderate"}, {4, "Heavy"}, {6, "Thick"}, {8, "V.Thick"}, {0, NULL}}; + +static CV_PossibleValue_t drawdist_precip_cons_t[] = { + {256, "256"}, {512, "512"}, {768, "768"}, + {1024, "1024"}, {1536, "1536"}, {2048, "2048"}, + {0, "None"}, {0, NULL}}; + static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}}; static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}}; // lmao rendering 32 portals, you're a card static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}}; @@ -147,7 +126,6 @@ consvar_t cv_flipcam2 = {"flipcam2", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, consvar_t cv_shadow = {"shadow", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_shadowoffs = {"offsetshadows", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_skybox = {"skybox", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_soniccd = {"soniccd", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_allowmlook = {"allowmlook", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_showhud = {"showhud", "Yes", CV_CALL, CV_YesNo, R_SetViewSize, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_translucenthud = {"translucenthud", "10", CV_SAVE, translucenthud_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -155,8 +133,8 @@ consvar_t cv_translucenthud = {"translucenthud", "10", CV_SAVE, translucenthud_c consvar_t cv_translucency = {"translucency", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_drawdist = {"drawdist", "Infinite", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_drawdist_nights = {"drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_precipdensity = {"precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +//consvar_t cv_precipdensity = {"precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // Okay, whoever said homremoval causes a performance hit should be shot. consvar_t cv_homremoval = {"homremoval", "No", CV_SAVE, homremoval_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -766,7 +744,7 @@ static void R_SetupFreelook(void) #undef AIMINGTODY -void R_SetupFrame(player_t *player, boolean skybox) +void R_SetupFrame(player_t *player) { camera_t *thiscam; boolean chasecam = false; @@ -783,7 +761,7 @@ void R_SetupFrame(player_t *player, boolean skybox) chasecam = (cv_chasecam.value != 0); } - if (player->climbing || (player->pflags & PF_NIGHTSMODE) || player->playerstate == PST_DEAD) + if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN || tutorialmode) chasecam = true; // force chasecam on else if (player->spectator) // no spectator chasecam chasecam = false; // force chasecam off @@ -796,7 +774,6 @@ void R_SetupFrame(player_t *player, boolean skybox) else if (!chasecam) thiscam->chase = false; - viewsky = !skybox; if (player->awayviewtics) { // cut-away view stuff @@ -885,7 +862,6 @@ void R_SkyboxFrame(player_t *player) thiscam = &camera; // cut-away view stuff - viewsky = true; viewmobj = skyboxmo[0]; #ifdef PARANOIA if (!viewmobj) @@ -928,157 +904,77 @@ void R_SkyboxFrame(player_t *player) viewx = viewmobj->x; viewy = viewmobj->y; - viewz = 0; - if (viewmobj->spawnpoint) - viewz = ((fixed_t)viewmobj->spawnpoint->angle)<<FRACBITS; - - viewx += quake.x; - viewy += quake.y; - viewz += quake.z; + viewz = viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle! if (mapheaderinfo[gamemap-1]) { mapheader_t *mh = mapheaderinfo[gamemap-1]; - if (player->awayviewtics) + vector3_t campos = {0,0,0}; // Position of player's actual view point + + if (player->awayviewtics) { + campos.x = player->awayviewmobj->x; + campos.y = player->awayviewmobj->y; + campos.z = player->awayviewmobj->z + 20*FRACUNIT; + } else if (thiscam->chase) { + campos.x = thiscam->x; + campos.y = thiscam->y; + campos.z = thiscam->z + (thiscam->height>>1); + } else { + campos.x = player->mo->x; + campos.y = player->mo->y; + campos.z = player->viewz; + } + + // Earthquake effects should be scaled in the skybox + // (if an axis isn't used, the skybox won't shake in that direction) + campos.x += quake.x; + campos.y += quake.y; + campos.z += quake.z; + + if (skyboxmo[1]) // Is there a viewpoint? { - if (skyboxmo[1]) + fixed_t x = 0, y = 0; + if (mh->skybox_scalex > 0) + x = (campos.x - skyboxmo[1]->x) / mh->skybox_scalex; + else if (mh->skybox_scalex < 0) + x = (campos.x - skyboxmo[1]->x) * -mh->skybox_scalex; + + if (mh->skybox_scaley > 0) + y = (campos.y - skyboxmo[1]->y) / mh->skybox_scaley; + else if (mh->skybox_scaley < 0) + y = (campos.y - skyboxmo[1]->y) * -mh->skybox_scaley; + + if (viewmobj->angle == 0) { - fixed_t x = 0, y = 0; - if (mh->skybox_scalex > 0) - x = (player->awayviewmobj->x - skyboxmo[1]->x) / mh->skybox_scalex; - else if (mh->skybox_scalex < 0) - x = (player->awayviewmobj->x - skyboxmo[1]->x) * -mh->skybox_scalex; - - if (mh->skybox_scaley > 0) - y = (player->awayviewmobj->y - skyboxmo[1]->y) / mh->skybox_scaley; - else if (mh->skybox_scaley < 0) - y = (player->awayviewmobj->y - skyboxmo[1]->y) * -mh->skybox_scaley; - - if (viewmobj->angle == 0) - { - viewx += x; - viewy += y; - } - else if (viewmobj->angle == ANGLE_90) - { - viewx -= y; - viewy += x; - } - else if (viewmobj->angle == ANGLE_180) - { - viewx -= x; - viewy -= y; - } - else if (viewmobj->angle == ANGLE_270) - { - viewx += y; - viewy -= x; - } - else - { - angle_t ang = viewmobj->angle>>ANGLETOFINESHIFT; - viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang)); - viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang)); - } + viewx += x; + viewy += y; } - if (mh->skybox_scalez > 0) - viewz += (player->awayviewmobj->z + 20*FRACUNIT) / mh->skybox_scalez; - else if (mh->skybox_scalez < 0) - viewz += (player->awayviewmobj->z + 20*FRACUNIT) * -mh->skybox_scalez; - } - else if (thiscam->chase) - { - if (skyboxmo[1]) + else if (viewmobj->angle == ANGLE_90) { - fixed_t x = 0, y = 0; - if (mh->skybox_scalex > 0) - x = (thiscam->x - skyboxmo[1]->x) / mh->skybox_scalex; - else if (mh->skybox_scalex < 0) - x = (thiscam->x - skyboxmo[1]->x) * -mh->skybox_scalex; - - if (mh->skybox_scaley > 0) - y = (thiscam->y - skyboxmo[1]->y) / mh->skybox_scaley; - else if (mh->skybox_scaley < 0) - y = (thiscam->y - skyboxmo[1]->y) * -mh->skybox_scaley; - - if (viewmobj->angle == 0) - { - viewx += x; - viewy += y; - } - else if (viewmobj->angle == ANGLE_90) - { - viewx -= y; - viewy += x; - } - else if (viewmobj->angle == ANGLE_180) - { - viewx -= x; - viewy -= y; - } - else if (viewmobj->angle == ANGLE_270) - { - viewx += y; - viewy -= x; - } - else - { - angle_t ang = viewmobj->angle>>ANGLETOFINESHIFT; - viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang)); - viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang)); - } + viewx -= y; + viewy += x; } - if (mh->skybox_scalez > 0) - viewz += (thiscam->z + (thiscam->height>>1)) / mh->skybox_scalez; - else if (mh->skybox_scalez < 0) - viewz += (thiscam->z + (thiscam->height>>1)) * -mh->skybox_scalez; - } - else - { - if (skyboxmo[1]) + else if (viewmobj->angle == ANGLE_180) + { + viewx -= x; + viewy -= y; + } + else if (viewmobj->angle == ANGLE_270) + { + viewx += y; + viewy -= x; + } + else { - fixed_t x = 0, y = 0; - if (mh->skybox_scalex > 0) - x = (player->mo->x - skyboxmo[1]->x) / mh->skybox_scalex; - else if (mh->skybox_scalex < 0) - x = (player->mo->x - skyboxmo[1]->x) * -mh->skybox_scalex; - if (mh->skybox_scaley > 0) - y = (player->mo->y - skyboxmo[1]->y) / mh->skybox_scaley; - else if (mh->skybox_scaley < 0) - y = (player->mo->y - skyboxmo[1]->y) * -mh->skybox_scaley; - - if (viewmobj->angle == 0) - { - viewx += x; - viewy += y; - } - else if (viewmobj->angle == ANGLE_90) - { - viewx -= y; - viewy += x; - } - else if (viewmobj->angle == ANGLE_180) - { - viewx -= x; - viewy -= y; - } - else if (viewmobj->angle == ANGLE_270) - { - viewx += y; - viewy -= x; - } - else - { - angle_t ang = viewmobj->angle>>ANGLETOFINESHIFT; - viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang)); - viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang)); - } + angle_t ang = viewmobj->angle>>ANGLETOFINESHIFT; + viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang)); + viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang)); } - if (mh->skybox_scalez > 0) - viewz += player->viewz / mh->skybox_scalez; - else if (mh->skybox_scalez < 0) - viewz += player->viewz * -mh->skybox_scalez; } + if (mh->skybox_scalez > 0) + viewz += campos.z / mh->skybox_scalez; + else if (mh->skybox_scalez < 0) + viewz += campos.z * -mh->skybox_scalez; } if (viewmobj->subsector) @@ -1092,17 +988,8 @@ void R_SkyboxFrame(player_t *player) R_SetupFreelook(); } -#define ANGLED_PORTALS - -static void R_PortalFrame(line_t *start, line_t *dest, portal_pair *portal) +static void R_PortalFrame(portal_t *portal) { - vertex_t dest_c, start_c; -#ifdef ANGLED_PORTALS - // delta angle - angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0); -#endif - - //R_SetupFrame(player, false); viewx = portal->viewx; viewy = portal->viewy; viewz = portal->viewz; @@ -1111,94 +998,35 @@ static void R_PortalFrame(line_t *start, line_t *dest, portal_pair *portal) viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); - portalcullsector = dest->frontsector; - viewsector = dest->frontsector; - portalclipline = dest; portalclipstart = portal->start; portalclipend = portal->end; - // Offset the portal view by the linedef centers - - // looking glass center - start_c.x = (start->v1->x + start->v2->x) / 2; - start_c.y = (start->v1->y + start->v2->y) / 2; - - // other side center - dest_c.x = (dest->v1->x + dest->v2->x) / 2; - dest_c.y = (dest->v1->y + dest->v2->y) / 2; - - // Heights! - viewz += dest->frontsector->floorheight - start->frontsector->floorheight; - - // calculate the difference in position and rotation! -#ifdef ANGLED_PORTALS - if (dangle == 0) -#endif - { // the entrance goes straight opposite the exit, so we just need to mess with the offset. - viewx += dest_c.x - start_c.x; - viewy += dest_c.y - start_c.y; - return; + if (portal->clipline != -1) + { + portalclipline = &lines[portal->clipline]; + viewsector = portalclipline->frontsector; } - -#ifdef ANGLED_PORTALS - viewangle += dangle; - viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); - viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); - //CONS_Printf("dangle == %u\n", AngleFixed(dangle)>>FRACBITS); - - // ???? + else { - fixed_t disttopoint; - angle_t angtopoint; - - disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy); - angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy); - angtopoint += dangle; - - viewx = dest_c.x+FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); - viewy = dest_c.y+FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); + portalclipline = NULL; + viewsector = R_PointInSubsector(viewx, viewy)->sector; } -#endif } -void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2) +static void Mask_Pre (maskcount_t* m) { - portal_pair *portal = Z_Malloc(sizeof(portal_pair), PU_LEVEL, NULL); - INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL); - INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL); - fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1), PU_LEVEL, NULL); - - portal->line1 = line1; - portal->line2 = line2; - portal->pass = portalrender+1; - portal->next = NULL; - - R_PortalStoreClipValues(x1, x2, ceilingclipsave, floorclipsave, frontscalesave); - - portal->ceilingclip = ceilingclipsave; - portal->floorclip = floorclipsave; - portal->frontscale = frontscalesave; - - portal->start = x1; - portal->end = x2; - - portalline = true; // this tells R_StoreWallRange that curline is a portal seg - - portal->viewx = viewx; - portal->viewy = viewy; - portal->viewz = viewz; - portal->viewangle = viewangle; + m->drawsegs[0] = ds_p - drawsegs; + m->vissprites[0] = visspritecount; + m->viewx = viewx; + m->viewy = viewy; + m->viewz = viewz; + m->viewsector = viewsector; +} - if (!portal_base) - { - portal_base = portal; - portal_cap = portal; - } - else - { - portal_cap->next = portal; - portal_cap = portal; - } +static void Mask_Post (maskcount_t* m) +{ + m->drawsegs[1] = ds_p - drawsegs; + m->vissprites[1] = visspritecount; } // ================ @@ -1213,49 +1041,18 @@ void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2) void R_RenderPlayerView(player_t *player) { - portal_pair *portal; - const boolean skybox = (skyboxmo[0] && cv_skybox.value); + UINT8 nummasks = 1; + maskcount_t* masks = malloc(sizeof(maskcount_t)); if (cv_homremoval.value && player == &players[displayplayer]) // if this is display player 1 { if (cv_homremoval.value == 1) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // No HOM effect! else //'development' HOM removal -- makes it blindingly obvious if HOM is spotted. - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 128+(timeinmap&15)); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 32+(timeinmap&15)); } - // load previous saved value of skyVisible for the player - if (splitscreen && player == &players[secondarydisplayplayer]) - skyVisible = skyVisible2; - else - skyVisible = skyVisible1; - - portalrender = 0; - portal_base = portal_cap = NULL; - - if (skybox && skyVisible) - { - R_SkyboxFrame(player); - - R_ClearClipSegs(); - R_ClearDrawSegs(); - R_ClearPlanes(); - R_ClearSprites(); -#ifdef FLOORSPLATS - R_ClearVisibleFloorSplats(); -#endif - - R_RenderBSPNode((INT32)numnodes - 1); - R_ClipSprites(); - R_DrawPlanes(); -#ifdef FLOORSPLATS - R_DrawVisibleFloorSplats(); -#endif - R_DrawMasked(); - } - - R_SetupFrame(player, skybox); - skyVisible = false; + R_SetupFrame(player); framecount++; validcount++; @@ -1267,19 +1064,21 @@ void R_RenderPlayerView(player_t *player) #ifdef FLOORSPLATS R_ClearVisibleFloorSplats(); #endif + Portal_InitList(); // check for new console commands. NetUpdate(); // The head node is the last node output. + Mask_Pre(&masks[nummasks - 1]); + curdrawsegs = ds_p; //profile stuff --------------------------------------------------------- #ifdef TIMING mytotal = 0; ProfZeroTimer(); #endif R_RenderBSPNode((INT32)numnodes - 1); - R_ClipSprites(); #ifdef TIMING RDMSR(0x10, &mycount); mytotal += mycount; // 64bit add @@ -1287,54 +1086,66 @@ void R_RenderPlayerView(player_t *player) CONS_Debug(DBG_RENDER, "RenderBSPNode: 0x%d %d\n", *((INT32 *)&mytotal + 1), (INT32)mytotal); #endif //profile stuff --------------------------------------------------------- + Mask_Post(&masks[nummasks - 1]); - // PORTAL RENDERING - for(portal = portal_base; portal; portal = portal_base) + R_ClipSprites(drawsegs, NULL); + + + // Add skybox portals caused by sky visplanes. + if (cv_skybox.value && skyboxmo[0]) + Portal_AddSkyboxPortals(); + + // Portal rendering. Hijacks the BSP traversal. + if (portal_base) { - // render the portal - CONS_Debug(DBG_RENDER, "Rendering portal from line %d to %d\n", portal->line1, portal->line2); - portalrender = portal->pass; + portal_t *portal; + + for(portal = portal_base; portal; portal = portal_base) + { + portalrender = portal->pass; // Recursiveness depth. - R_PortalFrame(&lines[portal->line1], &lines[portal->line2], portal); + R_ClearFFloorClips(); - R_PortalClearClipSegs(portal->start, portal->end); + // Apply the viewpoint stored for the portal. + R_PortalFrame(portal); - R_PortalRestoreClipValues(portal->start, portal->end, portal->ceilingclip, portal->floorclip, portal->frontscale); + // Hack in the clipsegs to delimit the starting + // clipping for sprites and possibly other similar + // future items. + R_PortalClearClipSegs(portal->start, portal->end); - validcount++; + // Hack in the top/bottom clip values for the window + // that were previously stored. + Portal_ClipApply(portal); - R_RenderBSPNode((INT32)numnodes - 1); - R_ClipSprites(); - //R_DrawPlanes(); - //R_DrawMasked(); + validcount++; - // okay done. free it. - portalcullsector = NULL; // Just in case... - portal_base = portal->next; - Z_Free(portal->ceilingclip); - Z_Free(portal->floorclip); - Z_Free(portal->frontscale); - Z_Free(portal); + masks = realloc(masks, (++nummasks)*sizeof(maskcount_t)); + + Mask_Pre(&masks[nummasks - 1]); + curdrawsegs = ds_p; + + // Render the BSP from the new viewpoint, and clip + // any sprites with the new clipsegs and window. + R_RenderBSPNode((INT32)numnodes - 1); + Mask_Post(&masks[nummasks - 1]); + + R_ClipSprites(ds_p - (masks[nummasks - 1].drawsegs[1] - masks[nummasks - 1].drawsegs[0]), portal); + + Portal_Remove(portal); + } } - // END PORTAL RENDERING R_DrawPlanes(); #ifdef FLOORSPLATS R_DrawVisibleFloorSplats(); #endif + // draw mid texture and sprite // And now 3D floors/sides! - R_DrawMasked(); - - // Check for new console commands. - NetUpdate(); + R_DrawMasked(masks, nummasks); - // save value to skyVisible1 or skyVisible2 - // this is so that P1 can't affect whether P2 can see a skybox or not, or vice versa - if (splitscreen && player == &players[secondarydisplayplayer]) - skyVisible2 = skyVisible; - else - skyVisible1 = skyVisible; + free(masks); } // ========================================================================= @@ -1345,7 +1156,6 @@ void R_RegisterEngineStuff(void) { CV_RegisterVar(&cv_gravity); CV_RegisterVar(&cv_tailspickup); - CV_RegisterVar(&cv_soniccd); CV_RegisterVar(&cv_allowmlook); CV_RegisterVar(&cv_homremoval); CV_RegisterVar(&cv_flipcam); @@ -1355,7 +1165,6 @@ void R_RegisterEngineStuff(void) if (dedicated) return; - CV_RegisterVar(&cv_precipdensity); CV_RegisterVar(&cv_translucency); CV_RegisterVar(&cv_drawdist); CV_RegisterVar(&cv_drawdist_nights); @@ -1386,9 +1195,7 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_maxportals); - // Default viewheight is changeable, - // initialized to standard viewheight - CV_RegisterVar(&cv_viewheight); + CV_RegisterVar(&cv_movebob); #ifdef HWRENDER // GL-specific Commands diff --git a/src/r_main.h b/src/r_main.h index 6ae5aa221667569b4b59987b37c4002219958f0c..2c9b5cc3d536aa5a53404b7dbf72d3b4464ffd7c 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -78,7 +78,7 @@ extern consvar_t cv_chasecam, cv_chasecam2; extern consvar_t cv_flipcam, cv_flipcam2; extern consvar_t cv_shadow, cv_shadowoffs; extern consvar_t cv_translucency; -extern consvar_t cv_precipdensity, cv_drawdist, cv_drawdist_nights, cv_drawdist_precip; +extern consvar_t cv_drawdist, cv_drawdist_nights, cv_drawdist_precip; extern consvar_t cv_skybox; extern consvar_t cv_tailspickup; @@ -94,7 +94,7 @@ void R_ExecuteSetViewSize(void); void R_SkyboxFrame(player_t *player); -void R_SetupFrame(player_t *player, boolean skybox); +void R_SetupFrame(player_t *player); // Called by G_Drawer. void R_RenderPlayerView(player_t *player); diff --git a/src/r_plane.c b/src/r_plane.c index 5cb53a5306b88d12db093a19d222689bd0bf56f1..2f6f97240a0418f3608d1901a8406b80716cf10f 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -23,6 +23,8 @@ #include "r_state.h" #include "r_splats.h" // faB(21jan):testing #include "r_sky.h" +#include "r_portal.h" + #include "v_video.h" #include "w_wad.h" #include "z_zone.h" @@ -42,13 +44,9 @@ // Quincunx antialiasing of flats! //#define QUINCUNX -// good night sweet prince -#define SHITPLANESPARENCY - //SoM: 3/23/2000: Use Boom visplane hashing. -#define MAXVISPLANES 512 -static visplane_t *visplanes[MAXVISPLANES]; +visplane_t *visplanes[MAXVISPLANES]; static visplane_t *freetail; static visplane_t **freehead = &freetail; @@ -115,50 +113,6 @@ void R_InitPlanes(void) // FIXME: unused } -// R_PortalStoreClipValues -// Saves clipping values for later. -Red -void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale) -{ - INT32 i; - for (i = 0; i < end-start; i++) - { - *ceil = ceilingclip[start+i]; - ceil++; - *floor = floorclip[start+i]; - floor++; - *scale = frontscale[start+i]; - scale++; - } -} - -// R_PortalRestoreClipValues -// Inverse of the above. Restores the old value! -void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale) -{ - INT32 i; - for (i = 0; i < end-start; i++) - { - ceilingclip[start+i] = *ceil; - ceil++; - floorclip[start+i] = *floor; - floor++; - frontscale[start+i] = *scale; - scale++; - } - - // HACKS FOLLOW - for (i = 0; i < start; i++) - { - floorclip[i] = -1; - ceilingclip[i] = (INT16)viewheight; - } - for (i = end; i < vid.width; i++) - { - floorclip[i] = -1; - ceilingclip[i] = (INT16)viewheight; - } -} - // // R_MapPlane // @@ -351,6 +305,23 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2) #endif } +void R_ClearFFloorClips (void) +{ + INT32 i, p; + + // opening / clipping determination + for (i = 0; i < viewwidth; i++) + { + for (p = 0; p < MAXFFLOORS; p++) + { + ffloor[p].f_clip[i] = (INT16)viewheight; + ffloor[p].c_clip[i] = -1; + } + } + + numffloors = 0; +} + // // R_ClearPlanes // At begining of frame. @@ -373,8 +344,6 @@ void R_ClearPlanes(void) } } - numffloors = 0; - for (i = 0; i < MAXVISPLANES; i++) for (*freehead = visplanes[i], visplanes[i] = NULL; freehead && *freehead ;) @@ -436,18 +405,36 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, #ifdef ESLOPE if (slope); else // Don't mess with this right now if a slope is involved #endif - if (plangle != 0) - { - // Add the view offset, rotated by the plane angle. - angle_t angle = plangle>>ANGLETOFINESHIFT; - xoff += FixedMul(viewx,FINECOSINE(angle))-FixedMul(viewy,FINESINE(angle)); - yoff += -FixedMul(viewx,FINESINE(angle))-FixedMul(viewy,FINECOSINE(angle)); - } - else { xoff += viewx; yoff -= viewy; + if (plangle != 0) + { + // Add the view offset, rotated by the plane angle. + fixed_t cosinecomponent = FINECOSINE(plangle>>ANGLETOFINESHIFT); + fixed_t sinecomponent = FINESINE(plangle>>ANGLETOFINESHIFT); + fixed_t oldxoff = xoff; + xoff = FixedMul(xoff,cosinecomponent)+FixedMul(yoff,sinecomponent); + yoff = -FixedMul(oldxoff,sinecomponent)+FixedMul(yoff,cosinecomponent); + } + } + +#ifdef POLYOBJECTS_PLANES + if (polyobj) + { + if (polyobj->angle != 0) + { + angle_t fineshift = polyobj->angle >> ANGLETOFINESHIFT; + xoff -= FixedMul(FINECOSINE(fineshift), polyobj->centerPt.x)+FixedMul(FINESINE(fineshift), polyobj->centerPt.y); + yoff -= FixedMul(FINESINE(fineshift), polyobj->centerPt.x)-FixedMul(FINECOSINE(fineshift), polyobj->centerPt.y); + } + else + { + xoff -= polyobj->centerPt.x; + yoff += polyobj->centerPt.y; + } } +#endif // This appears to fix the Nimbus Ruins sky bug. if (picnum == skyflatnum && pfloor) @@ -474,6 +461,7 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, && !pfloor && !check->ffloor && check->viewx == viewx && check->viewy == viewy && check->viewz == viewz && check->viewangle == viewangle + && check->plangle == plangle #ifdef ESLOPE && check->slope == slope #endif @@ -597,7 +585,7 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop) // overlap. void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop) { - INT32 unionl, unionh; +// INT32 unionl, unionh; // INT32 x; #ifdef POLYOBJECTS_PLANES @@ -606,6 +594,9 @@ void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop) return; #endif + if (pl->minx > start) pl->minx = start; + if (pl->maxx < stop) pl->maxx = stop; +/* if (start < pl->minx) { unionl = start; @@ -623,15 +614,16 @@ void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop) { unionh = pl->maxx; } -/* for (x = start; x <= stop; x++) if (pl->top[x] != 0xffff || pl->bottom[x] != 0x0000) break; if (x <= stop) I_Error("R_ExpandPlane: planes in same subsector overlap?!\nminx: %d, maxx: %d, start: %d, stop: %d\n", pl->minx, pl->maxx, start, stop); -*/ + pl->minx = unionl, pl->maxx = unionh; +*/ + } // @@ -666,10 +658,10 @@ void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2) void R_DrawPlanes(void) { visplane_t *pl; - INT32 x; - INT32 angle; INT32 i; + // Note: are these two lines really needed? + // R_DrawSinglePlane and R_DrawSkyPlane do span/column drawer resets themselves anyway spanfunc = basespanfunc; wallcolfunc = walldrawerfunc; @@ -677,44 +669,6 @@ void R_DrawPlanes(void) { for (pl = visplanes[i]; pl; pl = pl->next) { - // sky flat - if (pl->picnum == skyflatnum) - { - if (!viewsky) - { - skyVisible = true; - continue; - } - - // use correct aspect ratio scale - dc_iscale = skyscale; - - // Sky is always drawn full bright, - // i.e. colormaps[0] is used. - // Because of this hack, sky is not affected - // by INVUL inverse mapping. - dc_colormap = colormaps; - dc_texturemid = skytexturemid; - dc_texheight = textureheight[skytexture] - >>FRACBITS; - for (x = pl->minx; x <= pl->maxx; x++) - { - dc_yl = pl->top[x]; - dc_yh = pl->bottom[x]; - - if (dc_yl <= dc_yh) - { - angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT; - dc_x = x; - dc_source = - R_GetColumn(skytexture, - angle); - wallcolfunc(); - } - } - continue; - } - if (pl->ffloor != NULL #ifdef POLYOBJECTS_PLANES || pl->polyobj != NULL @@ -731,6 +685,49 @@ void R_DrawPlanes(void) #endif } +// R_DrawSkyPlane +// +// Draws the sky within the plane's top/bottom bounds +// Note: this uses column drawers instead of span drawers, since the sky is always a texture +// +static void R_DrawSkyPlane(visplane_t *pl) +{ + INT32 x; + INT32 angle; + + // Reset column drawer function (note: couldn't we just call walldrawerfunc directly?) + // (that is, unless we'll need to switch drawers in future for some reason) + wallcolfunc = walldrawerfunc; + + // use correct aspect ratio scale + dc_iscale = skyscale; + + // Sky is always drawn full bright, + // i.e. colormaps[0] is used. + // Because of this hack, sky is not affected + // by sector colormaps (INVUL inverse mapping is not implemented in SRB2 so is irrelevant). + dc_colormap = colormaps; + dc_texturemid = skytexturemid; + dc_texheight = textureheight[skytexture] + >>FRACBITS; + for (x = pl->minx; x <= pl->maxx; x++) + { + dc_yl = pl->top[x]; + dc_yh = pl->bottom[x]; + + if (dc_yl <= dc_yh) + { + angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT; + dc_iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT)); + dc_x = x; + dc_source = + R_GetColumn(texturetranslation[skytexture], + -angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18 + wallcolfunc(); + } + } +} + void R_DrawSinglePlane(visplane_t *pl) { INT32 light = 0; @@ -742,6 +739,13 @@ void R_DrawSinglePlane(visplane_t *pl) if (!(pl->minx <= pl->maxx)) return; + // sky flat + if (pl->picnum == skyflatnum) + { + R_DrawSkyPlane(pl); + return; + } + #ifndef NOWATER itswater = false; #endif @@ -759,11 +763,7 @@ void R_DrawSinglePlane(visplane_t *pl) else // Opaque, but allow transparent flat pixels spanfunc = splatfunc; -#ifdef SHITPLANESPARENCY - if (spanfunc == splatfunc || (pl->extra_colormap && pl->extra_colormap->fog)) -#else if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2)) -#endif light = (pl->lightlevel >> LIGHTSEGSHIFT); else light = LIGHTLEVELS-1; @@ -817,11 +817,7 @@ void R_DrawSinglePlane(visplane_t *pl) else // Opaque, but allow transparent flat pixels spanfunc = splatfunc; -#ifdef SHITPLANESPARENCY - if (spanfunc == splatfunc || (pl->extra_colormap && pl->extra_colormap->fog)) -#else if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2)) -#endif light = (pl->lightlevel >> LIGHTSEGSHIFT); else light = LIGHTLEVELS-1; @@ -949,19 +945,57 @@ void R_DrawSinglePlane(visplane_t *pl) floatv3_t p, m, n; float ang; float vx, vy, vz; - float fudge; // compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly // use this as a temp var to store P_GetZAt's return value each time fixed_t temp; + // Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red + const float fudge = ((1<<nflatshiftup)+1.0f)/(1<<nflatshiftup); - xoffs &= ((1 << (32-nflatshiftup))-1); - yoffs &= ((1 << (32-nflatshiftup))-1); + angle_t hack = (pl->plangle & (ANGLE_90-1)); - xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); - yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); + yoffs *= 1; - // Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red - fudge = ((1<<nflatshiftup)+1.0f)/(1<<nflatshiftup); + if (hack) + { + /* + Essentially: We can't & the components along the regular axes when the plane is rotated. + This is because the distance on each regular axis in order to loop is different. + We rotate them, & the components, add them together, & them again, and then rotate them back. + These three seperate & operations are done per axis in order to prevent overflows. + toast 10/04/17 + */ + const fixed_t cosinecomponent = FINECOSINE(hack>>ANGLETOFINESHIFT); + const fixed_t sinecomponent = FINESINE(hack>>ANGLETOFINESHIFT); + + const fixed_t modmask = ((1 << (32-nflatshiftup)) - 1); + + fixed_t ox = (FixedMul(pl->slope->o.x,cosinecomponent) & modmask) - (FixedMul(pl->slope->o.y,sinecomponent) & modmask); + fixed_t oy = (-FixedMul(pl->slope->o.x,sinecomponent) & modmask) - (FixedMul(pl->slope->o.y,cosinecomponent) & modmask); + + temp = ox & modmask; + oy &= modmask; + ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction + oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent); + + temp = xoffs; + xoffs = (FixedMul(temp,cosinecomponent) & modmask) + (FixedMul(yoffs,sinecomponent) & modmask); + yoffs = (-FixedMul(temp,sinecomponent) & modmask) + (FixedMul(yoffs,cosinecomponent) & modmask); + + temp = xoffs & modmask; + yoffs &= modmask; + xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto + yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); + + xoffs -= (pl->slope->o.x - ox); + yoffs += (pl->slope->o.y + oy); + } + else + { + xoffs &= ((1 << (32-nflatshiftup))-1); + yoffs &= ((1 << (32-nflatshiftup))-1); + xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); + yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); + } xoffs = (fixed_t)(xoffs*fudge); yoffs = (fixed_t)(yoffs/fudge); diff --git a/src/r_plane.h b/src/r_plane.h index 6e6a6d49d0522a6aa6b0d9facd35754f5744af14..238fde1827846f0be8278f6ee6a78e21aaf2c52b 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -18,6 +18,8 @@ #include "r_data.h" #include "p_polyobj.h" +#define MAXVISPLANES 512 + // // Now what is a visplane, anyway? // Simple: kinda floor/ceiling polygon optimised for SRB2 rendering. @@ -53,6 +55,7 @@ typedef struct visplane_s #endif } visplane_t; +extern visplane_t *visplanes[MAXVISPLANES]; extern visplane_t *floorplane; extern visplane_t *ceilingplane; @@ -72,9 +75,8 @@ extern fixed_t *yslope; extern lighttable_t **planezlight; void R_InitPlanes(void); -void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale); -void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale); void R_ClearPlanes(void); +void R_ClearFFloorClips (void); void R_MapPlane(INT32 y, INT32 x1, INT32 x2); void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2); @@ -122,4 +124,6 @@ typedef struct planemgr_s extern visffloor_t ffloor[MAXFFLOORS]; extern INT32 numffloors; + +void Portal_AddSkyboxPortals (void); #endif diff --git a/src/r_portal.c b/src/r_portal.c new file mode 100644 index 0000000000000000000000000000000000000000..ea24cd91c49b420df663e847cdbebb651a3f36db --- /dev/null +++ b/src/r_portal.c @@ -0,0 +1,333 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2018 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 r_portal.c +/// \brief Software renderer portals. + +#include "r_portal.h" +#include "r_plane.h" +#include "r_main.h" +#include "doomstat.h" +#include "p_spec.h" // Skybox viewpoints +#include "z_zone.h" +#include "r_things.h" +#include "r_sky.h" + +UINT8 portalrender; /**< When rendering a portal, it establishes the depth of the current BSP traversal. */ + +// Linked list for portals. +portal_t *portal_base, *portal_cap; + +line_t *portalclipline; +INT32 portalclipstart, portalclipend; + +boolean portalline; // is curline a portal seg? + +void Portal_InitList (void) +{ + portalrender = 0; + portal_base = portal_cap = NULL; +} + +/** Store the clipping window for a portal in its given range. + * + * The window is copied from the current window at the time + * the function is called, so it is useful for converting one-sided + * lines into portals. + */ +void Portal_ClipRange (portal_t* portal) +{ + INT32 start = portal->start; + INT32 end = portal->end; + INT16 *ceil = portal->ceilingclip; + INT16 *floor = portal->floorclip; + fixed_t *scale = portal->frontscale; + + INT32 i; + for (i = 0; i < end-start; i++) + { + *ceil = ceilingclip[start+i]; + ceil++; + *floor = floorclip[start+i]; + floor++; + *scale = frontscale[start+i]; + scale++; + } +} + +/** Apply the clipping window from a portal. + */ +void Portal_ClipApply (const portal_t* portal) +{ + INT32 i; + INT32 start = portal->start; + INT32 end = portal->end; + INT16 *ceil = portal->ceilingclip; + INT16 *floor = portal->floorclip; + fixed_t *scale = portal->frontscale; + + for (i = 0; i < end-start; i++) + { + ceilingclip[start+i] = *ceil; + ceil++; + floorclip[start+i] = *floor; + floor++; + frontscale[start+i] = *scale; + scale++; + } + + // HACKS FOLLOW + for (i = 0; i < start; i++) + { + floorclip[i] = -1; + ceilingclip[i] = (INT16)viewheight; + } + for (i = end; i < vid.width; i++) + { + floorclip[i] = -1; + ceilingclip[i] = (INT16)viewheight; + } +} + +static portal_t* Portal_Add (const INT16 x1, const INT16 x2) +{ + portal_t *portal = Z_Malloc(sizeof(portal_t), PU_LEVEL, NULL); + INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL); + INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL); + fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1 + 1), PU_LEVEL, NULL); + + // Linked list. + if (!portal_base) + { + portal_base = portal; + portal_cap = portal; + } + else + { + portal_cap->next = portal; + portal_cap = portal; + } + portal->next = NULL; + + // Store clipping values so they can be restored once the portal is rendered. + portal->ceilingclip = ceilingclipsave; + portal->floorclip = floorclipsave; + portal->frontscale = frontscalesave; + portal->start = x1; + portal->end = x2; + + // Increase recursion level. + portal->pass = portalrender+1; + + return portal; +} + +void Portal_Remove (portal_t* portal) +{ + portal_base = portal->next; + Z_Free(portal->ceilingclip); + Z_Free(portal->floorclip); + Z_Free(portal->frontscale); + Z_Free(portal); +} + +/** Creates a portal out of two lines and a determined screen range. + * + * line1 determines the entrance, and line2 the exit. + * x1 and x2 determine the screen's column bounds. + + * The view's offset from the entry line center is obtained, + * and then rotated&translated to the exit line's center. + * When the portal renders, it will create the illusion of + * the two lines being seamed together. + */ +void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2) +{ + portal_t* portal = Portal_Add(x1, x2); + + // Offset the portal view by the linedef centers + line_t* start = &lines[line1]; + line_t* dest = &lines[line2]; + + angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0); + + fixed_t disttopoint; + angle_t angtopoint; + + vertex_t dest_c, start_c; + + // looking glass center + start_c.x = (start->v1->x + start->v2->x) / 2; + start_c.y = (start->v1->y + start->v2->y) / 2; + + // other side center + dest_c.x = (dest->v1->x + dest->v2->x) / 2; + dest_c.y = (dest->v1->y + dest->v2->y) / 2; + + disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy); + angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy); + angtopoint += dangle; + + portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); + portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); + portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight; + portal->viewangle = viewangle + dangle; + + portal->clipline = line2; + + Portal_ClipRange(portal); + + portalline = true; // this tells R_StoreWallRange that curline is a portal seg +} + +/** Store the clipping window for a portal using a visplane. + * + * Since visplanes top/bottom windows work in an identical way, + * it can just be copied almost directly. + */ +static void Portal_ClipVisplane (const visplane_t* plane, portal_t* portal) +{ + INT16 start = portal->start; + INT16 end = portal->end; + INT32 i; + + for (i = 0; i < end - start; i++) + { + // Invalid column. + if (plane->top[i + start] == 65535) + { + portal->ceilingclip[i] = -1; + portal->floorclip[i] = -1; + continue; + } + portal->ceilingclip[i] = plane->top[i + start] - 1; + portal->floorclip[i] = plane->bottom[i + start] + 1; + portal->frontscale[i] = INT32_MAX; + } +} + +extern INT32 viewwidth; + +static boolean TrimVisplaneBounds (const visplane_t* plane, INT16* start, INT16* end) +{ + *start = plane->minx; + *end = plane->maxx + 1; + + // Visplanes have 1-px pads on their sides (extra columns). + // Trim them, else it may render out of bounds. + if (*end > viewwidth) + *end = viewwidth; + + if (!(*start < *end)) + return true; + + + /** Trims a visplane's horizontal gap to match its render area. + * + * Visplanes' minx/maxx may sometimes exceed the area they're + * covering. This merely adjusts the boundaries to the next + * valid area. + */ + + while (plane->bottom[*start] == 0 && plane->top[*start] == 65535 && *start < *end) + { + (*start)++; + } + + + while (plane->bottom[*end - 1] == 0 && plane->top[*start] == 65535 && *end > *start) + { + (*end)--; + } + + return false; +} + +/** Creates a skybox portal out of a visplane. + * + * Applies the necessary offsets and rotation to give + * a depth illusion to the skybox. + */ +void Portal_AddSkybox (const visplane_t* plane) +{ + INT16 start, end; + mapheader_t *mh; + portal_t* portal; + + if (TrimVisplaneBounds(plane, &start, &end)) + return; + + portal = Portal_Add(start, end); + + Portal_ClipVisplane(plane, portal); + + portal->viewx = skyboxmo[0]->x; + portal->viewy = skyboxmo[0]->y; + portal->viewz = skyboxmo[0]->z; + portal->viewangle = viewangle + skyboxmo[0]->angle; + + mh = mapheaderinfo[gamemap-1]; + + // If a relative viewpoint exists, offset the viewpoint. + if (skyboxmo[1]) + { + fixed_t x = 0, y = 0; + angle_t ang = skyboxmo[0]->angle>>ANGLETOFINESHIFT; + + if (mh->skybox_scalex > 0) + x = (viewx - skyboxmo[1]->x) / mh->skybox_scalex; + else if (mh->skybox_scalex < 0) + x = (viewx - skyboxmo[1]->x) * -mh->skybox_scalex; + + if (mh->skybox_scaley > 0) + y = (viewy - skyboxmo[1]->y) / mh->skybox_scaley; + else if (mh->skybox_scaley < 0) + y = (viewy - skyboxmo[1]->y) * -mh->skybox_scaley; + + // Apply transform to account for the skybox viewport angle. + portal->viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang)); + portal->viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang)); + } + + if (mh->skybox_scalez > 0) + portal->viewz += viewz / mh->skybox_scalez; + else if (mh->skybox_scalez < 0) + portal->viewz += viewz * -mh->skybox_scalez; + + portal->clipline = -1; +} + +/** Creates portals for the currently existing sky visplanes. + * The visplanes are also removed and cleared from the list. + */ +void Portal_AddSkyboxPortals (void) +{ + visplane_t *pl; + INT32 i; + UINT16 count = 0; + + for (i = 0; i < MAXVISPLANES; i++, pl++) + { + for (pl = visplanes[i]; pl; pl = pl->next) + { + if (pl->picnum == skyflatnum) + { + Portal_AddSkybox(pl); + + pl->minx = 0; + pl->maxx = -1; + + count++; + } + } + } + + CONS_Debug(DBG_RENDER, "Skybox portals: %d\n", count); +} diff --git a/src/r_portal.h b/src/r_portal.h new file mode 100644 index 0000000000000000000000000000000000000000..e8f9119e84a6eddc41e2bf651cf1ac408772bc2d --- /dev/null +++ b/src/r_portal.h @@ -0,0 +1,59 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2018 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 r_portal.h +/// \brief Software renderer portal struct, functions, linked list extern. + +#ifndef __R_PORTAL__ +#define __R_PORTAL__ + +#include "r_data.h" +#include "r_plane.h" // visplanes + +/** Portal structure for the software renderer. + */ +typedef struct portal_s +{ + struct portal_s *next; + + // Viewport. + fixed_t viewx; + fixed_t viewy; + fixed_t viewz; + angle_t viewangle; + + UINT8 pass; /**< Keeps track of the portal's recursion depth. */ + INT32 clipline; /**< Optional clipline for line-based portals. */ + + // Clipping information. + INT32 start; /**< First horizontal pixel coordinate to draw at. */ + INT32 end; /**< Last horizontal pixel coordinate to draw at. */ + INT16 *ceilingclip; /**< Temporary screen top clipping array. */ + INT16 *floorclip; /**< Temporary screen bottom clipping array. */ + fixed_t *frontscale;/**< Temporary screen bottom clipping array. */ +} portal_t; + +extern portal_t* portal_base; +extern portal_t* portal_cap; +extern UINT8 portalrender; + +extern line_t *portalclipline; +extern INT32 portalclipstart, portalclipend; + +void Portal_InitList (void); +void Portal_Remove (portal_t* portal); +void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2); +void Portal_AddSkybox (const visplane_t* plane); + +void Portal_ClipRange (portal_t* portal); +void Portal_ClipApply (const portal_t* portal); + +void Portal_AddSkyboxPortals (void); +#endif diff --git a/src/r_segs.c b/src/r_segs.c index c82554ac865d0edac67b35a7cf212de82d48f53e..6eb81ce7a4a64a78a3cda0765bd64149fc0eb280 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -15,6 +15,7 @@ #include "r_local.h" #include "r_sky.h" +#include "r_portal.h" #include "r_splats.h" #include "w_wad.h" @@ -278,6 +279,13 @@ static void R_Render2sidedMultiPatchColumn(column_t *column) } } +// quick wrapper for R_DrawFlippedMaskedColumn so it can be set as a colfunc_2s value +// uses column2s_length for texture->height as above +static void R_DrawFlippedMaskedSegColumn(column_t *column) +{ + R_DrawFlippedMaskedColumn(column, column2s_length); +} + void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { size_t pindex; @@ -352,7 +360,15 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures // are not stored per-column with post info in SRB2 if (textures[texnum]->holes) - colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture + { + if (textures[texnum]->flip & 2) // vertically flipped? + { + colfunc_2s = R_DrawFlippedMaskedSegColumn; + column2s_length = textures[texnum]->height; + } + else + colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture + } else { colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) @@ -398,7 +414,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) #endif rlight->startheight = rlight->height; // keep starting value here to reset for each repeat rlight->lightlevel = *light->lightlevel; - rlight->extra_colormap = light->extra_colormap; + rlight->extra_colormap = *light->extra_colormap; rlight->flags = light->flags; if (rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog)) @@ -717,6 +733,14 @@ static void R_DrawRepeatMaskedColumn(column_t *col) } } +static void R_DrawRepeatFlippedMaskedColumn(column_t *col) +{ + do { + R_DrawFlippedMaskedColumn(col, column2s_length); + sprtopscreen += dc_texheight*spryscale; + } while (sprtopscreen < sprbotscreen); +} + // // R_RenderThickSideRange // Renders all the thick sides in the given range. @@ -914,7 +938,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) } rlight->lightlevel = *light->lightlevel; - rlight->extra_colormap = light->extra_colormap; + rlight->extra_colormap = *light->extra_colormap; // Check if the current light effects the colormap/lightlevel if (pfloor->flags & FF_FOG) @@ -1040,7 +1064,15 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) //faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures // are not stored per-column with post info anymore in Doom Legacy if (textures[texnum]->holes) - colfunc_2s = R_DrawRepeatMaskedColumn; //render the usual 2sided single-patch packed texture + { + if (textures[texnum]->flip & 2) // vertically flipped? + { + colfunc_2s = R_DrawRepeatFlippedMaskedColumn; + column2s_length = textures[texnum]->height; + } + else + colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture + } else { colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info) @@ -1271,6 +1303,18 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) #undef CLAMPMIN } +// R_ExpandPlaneY +// +// A simple function to modify a vsplane's top and bottom for a particular column +// Sort of like R_ExpandPlane in r_plane.c, except this is vertical expansion +static inline void R_ExpandPlaneY(visplane_t *pl, INT32 x, INT16 top, INT16 bottom) +{ + // Expand the plane, don't shrink it! + // note: top and bottom default to 0xFFFF and 0x0000 respectively, which is totally compatible with this + if (pl->top[x] > top) pl->top[x] = top; + if (pl->bottom[x] < bottom) pl->bottom[x] = bottom; +} + // // R_RenderSegLoop // Draws zero, one, or two textures (and possibly a masked @@ -1294,7 +1338,6 @@ UINT32 nombre = 100000; #endif //profile stuff --------------------------------------------------------- - static void R_RenderSegLoop (void) { angle_t angle; @@ -1316,7 +1359,6 @@ static void R_RenderSegLoop (void) // mark floor / ceiling areas yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS; - // no space above wall? top = ceilingclip[rw_x]+1; // no space above wall? @@ -1325,16 +1367,19 @@ static void R_RenderSegLoop (void) if (markceiling) { +#if 0 bottom = yl-1; if (bottom >= floorclip[rw_x]) bottom = floorclip[rw_x]-1; if (top <= bottom) - { - ceilingplane->top[rw_x] = (INT16)top; - ceilingplane->bottom[rw_x] = (INT16)bottom; - } +#else + bottom = yl > floorclip[rw_x] ? floorclip[rw_x] : yl; + + if (top <= --bottom && ceilingplane) +#endif + R_ExpandPlaneY(ceilingplane, rw_x, top, bottom); } @@ -1348,11 +1393,9 @@ static void R_RenderSegLoop (void) if (markfloor) { top = yh < ceilingclip[rw_x] ? ceilingclip[rw_x] : yh; + if (++top <= bottom && floorplane) - { - floorplane->top[rw_x] = (INT16)top; - floorplane->bottom[rw_x] = (INT16)bottom; - } + R_ExpandPlaneY(floorplane, rw_x, top, bottom); } if (numffloors) @@ -1366,14 +1409,6 @@ static void R_RenderSegLoop (void) #ifdef POLYOBJECTS_PLANES if (ffloor[i].polyobj && (!curline->polyseg || ffloor[i].polyobj != curline->polyseg)) continue; - - // FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red - if (curline->polyseg) { - if (ffloor[i].plane->minx > rw_x) - ffloor[i].plane->minx = rw_x; - else if (ffloor[i].plane->maxx < rw_x) - ffloor[i].plane->maxx = rw_x; - } #endif if (ffloor[i].height < viewz) @@ -1389,8 +1424,9 @@ static void R_RenderSegLoop (void) #ifdef POLYOBJECTS_PLANES // Polyobject-specific hack to fix plane leaking -Red - if (curline->polyseg && ffloor[i].polyobj && ffloor[i].polyobj == curline->polyseg && top_w >= bottom_w) { - ffloor[i].plane->top[rw_x] = ffloor[i].plane->bottom[rw_x] = 0xFFFF; + if (ffloor[i].polyobj && top_w >= bottom_w) { + ffloor[i].plane->top[rw_x] = 0xFFFF; + ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 } else #endif @@ -1413,8 +1449,9 @@ static void R_RenderSegLoop (void) #ifdef POLYOBJECTS_PLANES // Polyobject-specific hack to fix plane leaking -Red - if (curline->polyseg && ffloor[i].polyobj && ffloor[i].polyobj == curline->polyseg && top_w >= bottom_w) { - ffloor[i].plane->top[rw_x] = ffloor[i].plane->bottom[rw_x] = 0xFFFF; + if (ffloor[i].polyobj && top_w >= bottom_w) { + ffloor[i].plane->top[rw_x] = 0xFFFF; + ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 } else #endif @@ -1701,6 +1738,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (ds_p == drawsegs+maxdrawsegs) { + size_t curpos = curdrawsegs - drawsegs; size_t pos = ds_p - drawsegs; size_t newmax = maxdrawsegs ? maxdrawsegs*2 : 128; if (firstseg) @@ -1708,6 +1746,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) drawsegs = Z_Realloc(drawsegs, newmax*sizeof (*drawsegs), PU_STATIC, NULL); ds_p = drawsegs + pos; maxdrawsegs = newmax; + curdrawsegs = drawsegs + curpos; if (firstseg) firstseg = drawsegs + (size_t)firstseg; } @@ -1854,29 +1893,26 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } - if (frontsector->c_slope) { - worldtop = P_GetZAt(frontsector->c_slope, segleft.x, segleft.y) - viewz; - worldtopslope = P_GetZAt(frontsector->c_slope, segright.x, segright.y) - viewz; - } else { - worldtopslope = -#else - { -#endif - worldtop = frontsector->ceilingheight - viewz; - } +#define SLOPEPARAMS(slope, end1, end2, normalheight) \ + if (slope) { \ + end1 = P_GetZAt(slope, segleft.x, segleft.y); \ + end2 = P_GetZAt(slope, segright.x, segright.y); \ + } else \ + end1 = end2 = normalheight; -#ifdef ESLOPE - if (frontsector->f_slope) { - worldbottom = P_GetZAt(frontsector->f_slope, segleft.x, segleft.y) - viewz; - worldbottomslope = P_GetZAt(frontsector->f_slope, segright.x, segright.y) - viewz; - } else { - worldbottomslope = + SLOPEPARAMS(frontsector->c_slope, worldtop, worldtopslope, frontsector->ceilingheight) + SLOPEPARAMS(frontsector->f_slope, worldbottom, worldbottomslope, frontsector->floorheight) + // subtract viewz from these to turn them into + // positions relative to the camera's z position + worldtop -= viewz; + worldtopslope -= viewz; + worldbottom -= viewz; + worldbottomslope -= viewz; #else - { + worldtop = frontsector->ceilingheight - viewz; + worldbottom = frontsector->floorheight - viewz; #endif - worldbottom = frontsector->floorheight - viewz; - } midtexture = toptexture = bottomtexture = maskedtexture = 0; ds_p->maskedtexturecol = NULL; @@ -1978,125 +2014,128 @@ void R_StoreWallRange(INT32 start, INT32 stop) else { // two sided line + boolean bothceilingssky = false; // turned on if both back and front ceilings are sky + boolean bothfloorssky = false; // likewise, but for floors #ifdef ESLOPE - if (backsector->c_slope) { - worldhigh = P_GetZAt(backsector->c_slope, segleft.x, segleft.y) - viewz; - worldhighslope = P_GetZAt(backsector->c_slope, segright.x, segright.y) - viewz; - } else { - worldhighslope = + SLOPEPARAMS(backsector->c_slope, worldhigh, worldhighslope, backsector->ceilingheight) + SLOPEPARAMS(backsector->f_slope, worldlow, worldlowslope, backsector->floorheight) + worldhigh -= viewz; + worldhighslope -= viewz; + worldlow -= viewz; + worldlowslope -= viewz; #else - { + worldhigh = backsector->ceilingheight - viewz; + worldlow = backsector->floorheight - viewz; #endif - worldhigh = backsector->ceilingheight - viewz; - } - - -#ifdef ESLOPE - if (backsector->f_slope) { - worldlow = P_GetZAt(backsector->f_slope, segleft.x, segleft.y) - viewz; - worldlowslope = P_GetZAt(backsector->f_slope, segright.x, segright.y) - viewz; - } else { - worldlowslope = -#else - { -#endif - worldlow = backsector->floorheight - viewz; - } - // hack to allow height changes in outdoor areas + // This is what gets rid of the upper textures if there should be sky if (frontsector->ceilingpic == skyflatnum && backsector->ceilingpic == skyflatnum) { -#ifdef ESLOPE - worldtopslope = worldhighslope = -#endif - worldtop = worldhigh; + bothceilingssky = true; + } + + // likewise, but for floors and upper textures + if (frontsector->floorpic == skyflatnum + && backsector->floorpic == skyflatnum) + { + bothfloorssky = true; } ds_p->sprtopclip = ds_p->sprbottomclip = NULL; ds_p->silhouette = 0; - if ( + if (!bothfloorssky) + { + if ( #ifdef ESLOPE - worldbottomslope > worldlowslope || + worldbottomslope > worldlowslope || #endif - worldbottom > worldlow) - { - ds_p->silhouette = SIL_BOTTOM; + worldbottom > worldlow) + { + ds_p->silhouette = SIL_BOTTOM; #ifdef ESLOPE - if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) - ds_p->bsilheight = INT32_MAX; - else - ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight); + if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) + ds_p->bsilheight = INT32_MAX; + else + ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight); #else - ds_p->bsilheight = frontsector->floorheight; + ds_p->bsilheight = frontsector->floorheight; #endif - } + } #ifdef ESLOPE - else if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) + else if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) #else - else if (backsector->floorheight > viewz) + else if (backsector->floorheight > viewz) #endif - { - ds_p->silhouette = SIL_BOTTOM; - ds_p->bsilheight = INT32_MAX; - // ds_p->sprbottomclip = negonearray; + { + ds_p->silhouette = SIL_BOTTOM; + ds_p->bsilheight = INT32_MAX; + // ds_p->sprbottomclip = negonearray; + } } - if ( + if (!bothceilingssky) + { + if ( #ifdef ESLOPE - worldtopslope < worldhighslope || + worldtopslope < worldhighslope || #endif - worldtop < worldhigh) - { - ds_p->silhouette |= SIL_TOP; + worldtop < worldhigh) + { + ds_p->silhouette |= SIL_TOP; #ifdef ESLOPE - if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) - ds_p->tsilheight = INT32_MIN; - else - ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight); + if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) + ds_p->tsilheight = INT32_MIN; + else + ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight); #else - ds_p->tsilheight = frontsector->ceilingheight; + ds_p->tsilheight = frontsector->ceilingheight; #endif - } + } #ifdef ESLOPE - else if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) + else if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) #else - else if (backsector->ceilingheight < viewz) + else if (backsector->ceilingheight < viewz) #endif - { - ds_p->silhouette |= SIL_TOP; - ds_p->tsilheight = INT32_MIN; - // ds_p->sprtopclip = screenheightarray; + { + ds_p->silhouette |= SIL_TOP; + ds_p->tsilheight = INT32_MIN; + // ds_p->sprtopclip = screenheightarray; + } } + if (!bothceilingssky && !bothfloorssky) + { #ifdef ESLOPE - if (worldhigh <= worldbottom && worldhighslope <= worldbottomslope) + if (worldhigh <= worldbottom && worldhighslope <= worldbottomslope) #else - if (worldhigh <= worldbottom) + if (worldhigh <= worldbottom) #endif - { - ds_p->sprbottomclip = negonearray; - ds_p->bsilheight = INT32_MAX; - ds_p->silhouette |= SIL_BOTTOM; - } + { + ds_p->sprbottomclip = negonearray; + ds_p->bsilheight = INT32_MAX; + ds_p->silhouette |= SIL_BOTTOM; + } #ifdef ESLOPE - if (worldlow >= worldtop && worldlowslope >= worldtopslope) + if (worldlow >= worldtop && worldlowslope >= worldtopslope) #else - if (worldlow >= worldtop) + if (worldlow >= worldtop) #endif - { - ds_p->sprtopclip = screenheightarray; - ds_p->tsilheight = INT32_MIN; - ds_p->silhouette |= SIL_TOP; + { + ds_p->sprtopclip = screenheightarray; + ds_p->tsilheight = INT32_MIN; + ds_p->silhouette |= SIL_TOP; + } } //SoM: 3/25/2000: This code fixes an automap bug that didn't check // frontsector->ceiling and backsector->floor to see if a door was closed. // Without the following code, sprites get displayed behind closed doors. + if (!bothceilingssky && !bothfloorssky) { #ifdef ESLOPE if (doorclosed || (worldhigh <= worldbottom && worldhighslope <= worldbottomslope)) @@ -2120,7 +2159,13 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } - if (worldlow != worldbottom + if (bothfloorssky) + { + // see double ceiling skies comment + // this is the same but for upside down thok barriers where the floor is sky and the ceiling is normal + markfloor = false; + } + else if (worldlow != worldbottom #ifdef ESLOPE || worldlowslope != worldbottomslope || backsector->f_slope != frontsector->f_slope @@ -2132,7 +2177,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) || backsector->floor_yoffs != frontsector->floor_yoffs || backsector->floorpic_angle != frontsector->floorpic_angle //SoM: 3/22/2000: Prevents bleeding. - || frontsector->heightsec != -1 + || (frontsector->heightsec != -1 && frontsector->floorpic != skyflatnum) || backsector->floorlightsec != frontsector->floorlightsec //SoM: 4/3/2000: Check for colormaps || frontsector->extra_colormap != backsector->extra_colormap @@ -2146,7 +2191,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) markfloor = false; } - if (worldhigh != worldtop + if (bothceilingssky) + { + // double ceiling skies are special + // we don't want to lower the ceiling clipping, (no new plane is drawn anyway) + // so we can see the floor of thok barriers always regardless of sector properties + markceiling = false; + } + else if (worldhigh != worldtop #ifdef ESLOPE || worldhighslope != worldtopslope || backsector->c_slope != frontsector->c_slope @@ -2172,19 +2224,28 @@ void R_StoreWallRange(INT32 start, INT32 stop) markceiling = false; } - if (backsector->ceilingheight <= frontsector->floorheight || - backsector->floorheight >= frontsector->ceilingheight) + if (!bothceilingssky && !bothfloorssky) { - // closed door - markceiling = markfloor = true; +#ifdef ESLOPE + if ((worldhigh <= worldbottom && worldhighslope <= worldbottomslope) + || (worldlow >= worldtop && worldlowslope >= worldtopslope)) +#else + if (backsector->ceilingheight <= frontsector->floorheight + || backsector->floorheight >= frontsector->ceilingheight) +#endif + { + // closed door + markceiling = markfloor = true; + } } // check TOP TEXTURE - if (worldhigh < worldtop + if (!bothceilingssky // never draw the top texture if on + && (worldhigh < worldtop #ifdef ESLOPE || worldhighslope < worldtopslope #endif - ) + )) { fixed_t texheight; // top texture @@ -2233,11 +2294,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } // check BOTTOM TEXTURE - if (worldlow > worldbottom + if (!bothfloorssky // never draw the bottom texture if on + && (worldlow > worldbottom #ifdef ESLOPE || worldlowslope > worldbottomslope #endif - ) //seulement si VISIBLE!!! + )) //seulement si VISIBLE!!! { // bottom texture bottomtexture = R_GetTextureNum(sidedef->bottomtexture); @@ -2310,16 +2372,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; #ifdef ESLOPE - if (*rover->t_slope) { - high1 = P_GetZAt(*rover->t_slope, segleft.x, segleft.y); - highslope1 = P_GetZAt(*rover->t_slope, segright.x, segright.y); - } else - high1 = highslope1 = *rover->topheight; - if (*rover->b_slope) { - low1 = P_GetZAt(*rover->b_slope, segleft.x, segleft.y); - lowslope1 = P_GetZAt(*rover->b_slope, segright.x, segright.y); - } else - low1 = lowslope1 = *rover->bottomheight; + SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) + SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) continue; @@ -2351,16 +2405,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) } #ifdef ESLOPE - if (*r2->t_slope) { - high2 = P_GetZAt(*r2->t_slope, segleft.x, segleft.y); - highslope2 = P_GetZAt(*r2->t_slope, segright.x, segright.y); - } else - high2 = highslope2 = *r2->topheight; - if (*r2->b_slope) { - low2 = P_GetZAt(*r2->b_slope, segleft.x, segleft.y); - lowslope2 = P_GetZAt(*r2->b_slope, segright.x, segright.y); - } else - low2 = lowslope2 = *r2->bottomheight; + SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) + SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) continue; @@ -2393,16 +2439,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; #ifdef ESLOPE - if (*rover->t_slope) { - high1 = P_GetZAt(*rover->t_slope, segleft.x, segleft.y); - highslope1 = P_GetZAt(*rover->t_slope, segright.x, segright.y); - } else - high1 = highslope1 = *rover->topheight; - if (*rover->b_slope) { - low1 = P_GetZAt(*rover->b_slope, segleft.x, segleft.y); - lowslope1 = P_GetZAt(*rover->b_slope, segright.x, segright.y); - } else - low1 = lowslope1 = *rover->bottomheight; + SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) + SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) continue; @@ -2434,17 +2472,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) } #ifdef ESLOPE - if (*r2->t_slope) { - high2 = P_GetZAt(*r2->t_slope, segleft.x, segleft.y); - highslope2 = P_GetZAt(*r2->t_slope, segright.x, segright.y); - } else - high2 = highslope2 = *r2->topheight; - if (*r2->b_slope) { - low2 = P_GetZAt(*r2->b_slope, segleft.x, segleft.y); - lowslope2 = P_GetZAt(*r2->b_slope, segright.x, segright.y); - } else - low2 = lowslope2 = *r2->bottomheight; - + SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) + SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) +#undef SLOPEPARAMS if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) continue; if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) @@ -2633,7 +2663,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) // and doesn't need to be marked. if (frontsector->heightsec == -1) { - if (( + if (frontsector->floorpic != skyflatnum + && ( #ifdef ESLOPE frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : #endif @@ -2643,12 +2674,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) markfloor = false; } - if (( + if (frontsector->ceilingpic != skyflatnum + && ( #ifdef ESLOPE frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : #endif - frontsector->ceilingheight) <= viewz && - frontsector->ceilingpic != skyflatnum) + frontsector->ceilingheight) <= viewz) { // below view plane markceiling = false; @@ -2663,22 +2694,28 @@ void R_StoreWallRange(INT32 start, INT32 stop) worldbottomslope >>= 4; #endif - topstep = -FixedMul (rw_scalestep, worldtop); - topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale); + if (linedef->special == 41) { // HORIZON LINES + topstep = bottomstep = 0; + topfrac = bottomfrac = (centeryfrac>>4); + topfrac++; // Prevent 1px HOM + } else { + topstep = -FixedMul (rw_scalestep, worldtop); + topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale); - bottomstep = -FixedMul (rw_scalestep,worldbottom); - bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale); + bottomstep = -FixedMul (rw_scalestep,worldbottom); + bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale); #ifdef ESLOPE - if (frontsector->c_slope) { - fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldtopslope, ds_p->scale2); - topstep = (topfracend-topfrac)/(range); - } - if (frontsector->f_slope) { - fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldbottomslope, ds_p->scale2); - bottomstep = (bottomfracend-bottomfrac)/(range); - } + if (frontsector->c_slope) { + fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldtopslope, ds_p->scale2); + topstep = (topfracend-topfrac)/(range); + } + if (frontsector->f_slope) { + fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldbottomslope, ds_p->scale2); + bottomstep = (bottomfracend-bottomfrac)/(range); + } #endif + } dc_numlights = 0; @@ -2773,7 +2810,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) } rlight->lightlevel = *light->lightlevel; - rlight->extra_colormap = light->extra_colormap; + rlight->extra_colormap = *light->extra_colormap; p++; } @@ -2787,12 +2824,23 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].f_pos >>= 4; #ifdef ESLOPE ffloor[i].f_pos_slope >>= 4; - ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); - ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(range); +#endif + if (linedef->special == 41) // Horizon lines extend FOFs in contact with them too. + { + ffloor[i].f_step = 0; + ffloor[i].f_frac = (centeryfrac>>4); + topfrac++; // Prevent 1px HOM + } + else + { +#ifdef ESLOPE + ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); + ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(range); #else - ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos); - ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); + ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos); + ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); #endif + } } } @@ -3106,6 +3154,22 @@ void R_StoreWallRange(INT32 start, INT32 stop) for (i = 0; i < numffloors; i++) R_ExpandPlane(ffloor[i].plane, rw_x, rw_stopx - 1); } +#ifdef POLYOBJECTS_PLANES + // FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red + if (curline->polyseg) + { + for (i = 0; i < numffloors; i++) + { + if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) + continue; + if (ffloor[i].plane->minx > rw_x) + ffloor[i].plane->minx = rw_x; + + if (ffloor[i].plane->maxx < rw_stopx - 1) + ffloor[i].plane->maxx = rw_stopx - 1; + } + } +#endif } #ifdef WALLSPLATS diff --git a/src/r_sky.c b/src/r_sky.c index 2df6e4cd8780cac71687eeab2c169808739bd1f9..817e8368a722b2cd81a2328a4b11f3e1ff3b77dd 100644 --- a/src/r_sky.c +++ b/src/r_sky.c @@ -64,10 +64,6 @@ void R_SetupSkyDraw(void) // the horizon line in a 256x128 sky texture skytexturemid = (textures[skytexture]->height/2)<<FRACBITS; - // get the right drawer, it was set by screen.c, depending on the - // current video mode bytes per pixel (quick fix) - wallcolfunc = walldrawerfunc; - R_SetSkyScale(); } diff --git a/src/r_state.h b/src/r_state.h index 3675d7f2ea7934be2fc755f5fd21e09d9df401ec..da9425bdf0405160810e7102a4d53ce1241eb881 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -40,11 +40,7 @@ extern sprcache_t *spritecachedinfo; extern lighttable_t *colormaps; // Boom colormaps. -// Had to put a limit on colormaps :( -#define MAXCOLORMAPS 60 - -extern size_t num_extra_colormaps; -extern extracolormap_t extra_colormaps[MAXCOLORMAPS]; +extern extracolormap_t *extra_colormaps; // for global animation extern INT32 *texturetranslation; @@ -84,14 +80,8 @@ extern side_t *sides; // extern fixed_t viewx, viewy, viewz; extern angle_t viewangle, aimingangle; -extern boolean viewsky, skyVisible; -extern boolean skyVisible1, skyVisible2; // saved values of skyVisible for P1 and P2, for splitscreen extern sector_t *viewsector; extern player_t *viewplayer; -extern UINT8 portalrender; -extern sector_t *portalcullsector; -extern line_t *portalclipline; -extern INT32 portalclipstart, portalclipend; extern consvar_t cv_allowmlook; extern consvar_t cv_maxportals; diff --git a/src/r_things.c b/src/r_things.c index 0382596f16bc5f1c17b84d5d2e6ae8ad9f259f3b..50ee8e6ef598f62be38644e9ea4dab7cf8e12e8c 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -18,16 +18,21 @@ #include "st_stuff.h" #include "w_wad.h" #include "z_zone.h" +#include "m_menu.h" // character select #include "m_misc.h" +#include "info.h" // spr2names #include "i_video.h" // rendermode #include "r_things.h" #include "r_plane.h" +#include "r_portal.h" #include "p_tick.h" #include "p_local.h" #include "p_slopes.h" #include "dehacked.h" // get_number (for thok) #include "d_netfil.h" // blargh. for nameonly(). #include "m_cheat.h" // objectplace +#include "m_cond.h" +#include "fastcmp.h" #ifdef HWRENDER #include "hardware/hw_md2.h" #endif @@ -100,7 +105,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch lumppat <<= 16; lumppat += lump; - if (frame >= 64 || rotation > 8) + if (frame >= 64 || !(R_ValidSpriteAngle(rotation))) I_Error("R_InstallSpriteLump: Bad frame characters in lump %s", W_CheckNameForNum(lumppat)); if (maxframe ==(size_t)-1 || frame > maxframe) @@ -109,31 +114,72 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch if (rotation == 0) { // the lump should be used for all rotations - if (sprtemp[frame].rotate == 0) + if (sprtemp[frame].rotate == SRF_SINGLE) CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple rot = 0 lump\n", spritename, cn); - - if (sprtemp[frame].rotate == 1) + else if (sprtemp[frame].rotate != SRF_NONE) // Let's bundle 1-8 and L/R rotations into one debug message. CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has rotations and a rot = 0 lump\n", spritename, cn); - sprtemp[frame].rotate = 0; + sprtemp[frame].rotate = SRF_SINGLE; for (r = 0; r < 8; r++) { sprtemp[frame].lumppat[r] = lumppat; sprtemp[frame].lumpid[r] = lumpid; } - sprtemp[frame].flip = flipped ? UINT8_MAX : 0; + sprtemp[frame].flip = flipped ? 0xFF : 0; // 11111111 in binary return; } - // the lump is only used for one rotation - if (sprtemp[frame].rotate == 0) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has rotations and a rot = 0 lump\n", spritename, cn); + if (rotation == ROT_L || rotation == ROT_R) + { + UINT8 rightfactor = ((rotation == ROT_R) ? 4 : 0); + + // the lump should be used for half of all rotations + if (sprtemp[frame].rotate == SRF_SINGLE) + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has L/R rotations and a rot = 0 lump\n", spritename, cn); + else if (sprtemp[frame].rotate == SRF_3D) + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8 rotations\n", spritename, cn); + else if ((sprtemp[frame].rotate & SRF_LEFT) && (rotation == ROT_L)) + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple L rotations\n", spritename, cn); + else if ((sprtemp[frame].rotate & SRF_RIGHT) && (rotation == ROT_R)) + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple R rotations\n", spritename, cn); + + if (sprtemp[frame].rotate == SRF_NONE) + sprtemp[frame].rotate = SRF_SINGLE; + + sprtemp[frame].rotate |= ((rotation == ROT_R) ? SRF_RIGHT : SRF_LEFT); + if (sprtemp[frame].rotate == (SRF_3D|SRF_2D)) + sprtemp[frame].rotate = SRF_2D; // SRF_3D|SRF_2D being enabled at the same time doesn't HURT in the current sprite angle implementation, but it DOES mean more to check in some of the helper functions. Let's not allow this scenario to happen. + + for (r = 0; r < 4; r++) // Thanks to R_PrecacheLevel, we can't leave sprtemp[*].lumppat[*] == LUMPERROR... so we load into the front/back angle too. + { + sprtemp[frame].lumppat[r + rightfactor] = lumppat; + sprtemp[frame].lumpid[r + rightfactor] = lumpid; + } + + if (flipped) + sprtemp[frame].flip |= (0x0F<<rightfactor); // 00001111 or 11110000 in binary, depending on rotation being ROT_L or ROT_R + else + sprtemp[frame].flip &= ~(0x0F<<rightfactor); // ditto + + return; + } - sprtemp[frame].rotate = 1; + // the lump is only used for one rotation + if (sprtemp[frame].rotate == SRF_SINGLE) + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has 1-8 rotations and a rot = 0 lump\n", spritename, cn); + else if ((sprtemp[frame].rotate != SRF_3D) && (sprtemp[frame].rotate != SRF_NONE)) + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8 rotations\n", spritename, cn); // make 0 based rotation--; + if (rotation == 0 || rotation == 4) // Front or back... + sprtemp[frame].rotate = SRF_3D; // Prevent L and R changeover + else if (rotation > 3) // Right side + sprtemp[frame].rotate = (SRF_3D | (sprtemp[frame].rotate & SRF_LEFT)); // Continue allowing L frame changeover + else // if (rotation <= 3) // Left side + sprtemp[frame].rotate = (SRF_3D | (sprtemp[frame].rotate & SRF_RIGHT)); // Continue allowing R frame changeover + if (sprtemp[frame].lumppat[rotation] != LUMPERROR) CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s: %c%c has two lumps mapped to it\n", spritename, cn, '1'+rotation); @@ -195,7 +241,7 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, frame = R_Char2Frame(lumpinfo[l].name[4]); rotation = (UINT8)(lumpinfo[l].name[5] - '0'); - if (frame >= 64 || rotation > 8) // Give an actual NAME error -_-... + if (frame >= 64 || !(R_ValidSpriteAngle(rotation))) // Give an actual NAME error -_-... { CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum,l)); continue; @@ -278,16 +324,23 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, { switch (sprtemp[frame].rotate) { - case 0xff: + case SRF_NONE: // no rotations were found for that frame at all I_Error("R_AddSingleSpriteDef: No patches found for %.4s frame %c", sprname, R_Frame2Char(frame)); break; - case 0: + case SRF_SINGLE: // only the first rotation is needed break; - case 1: + case SRF_2D: // both Left and Right rotations + // we test to see whether the left and right slots are present + if ((sprtemp[frame].lumppat[2] == LUMPERROR) || (sprtemp[frame].lumppat[6] == LUMPERROR)) + I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations", + sprname, R_Frame2Char(frame)); + break; + + default: // must have all 8 frames for (rotation = 0; rotation < 8; rotation++) // we test the patch lump, or the id lump whatever @@ -327,6 +380,7 @@ void R_AddSpriteDefs(UINT16 wadnum) UINT16 start, end; char wadname[MAX_WADPATH]; + // Find the sprites section in this resource file. switch (wadfiles[wadnum]->type) { case RET_WAD: @@ -337,6 +391,7 @@ void R_AddSpriteDefs(UINT16 wadnum) start = 0; //let say S_START is lump 0 else start++; // just after S_START + end = W_CheckNumForNamePwad("S_END",wadnum,start); if (end == INT16_MAX) end = W_CheckNumForNamePwad("SS_END",wadnum,start); //deutex compatib. @@ -349,12 +404,17 @@ void R_AddSpriteDefs(UINT16 wadnum) return; } + // ignore skin wads (we don't want skin sprites interfering with vanilla sprites) + if (start == 0 && W_CheckNumForNamePwad("S_SKIN", wadnum, 0) != UINT16_MAX) + return; + if (end == INT16_MAX) { CONS_Debug(DBG_SETUP, "no sprites in pwad %d\n", wadnum); return; } + // // scan through lumps, for each sprite, find all the sprite frames // @@ -382,121 +442,10 @@ void R_AddSpriteDefs(UINT16 wadnum) CONS_Printf(M_GetText("%s added %d frames in %s sprites\n"), wadname, end-start, sizeu1(addsprites)); } -#ifdef DELFILE -static void R_RemoveSpriteLump(UINT16 wad, // graphics patch - UINT16 lump, - size_t lumpid, // identifier - UINT8 frame, - UINT8 rotation, - UINT8 flipped) -{ - (void)wad; /// \todo: how do I remove sprites? - (void)lump; - (void)lumpid; - (void)frame; - (void)rotation; - (void)flipped; -} - -static boolean R_DelSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 wadnum, UINT16 startlump, UINT16 endlump) -{ - UINT16 l; - UINT8 frame; - UINT8 rotation; - lumpinfo_t *lumpinfo; - - maxframe = (size_t)-1; - - // scan the lumps, - // filling in the frames for whatever is found - lumpinfo = wadfiles[wadnum]->lumpinfo; - if (endlump > wadfiles[wadnum]->numlumps) - endlump = wadfiles[wadnum]->numlumps; - - for (l = startlump; l < endlump; l++) - { - if (memcmp(lumpinfo[l].name,sprname,4)==0) - { - frame = (UINT8)(lumpinfo[l].name[4] - 'A'); - rotation = (UINT8)(lumpinfo[l].name[5] - '0'); - - // skip NULL sprites from very old dmadds pwads - if (W_LumpLengthPwad(wadnum,l)<=8) - continue; - - //---------------------------------------------------- - - R_RemoveSpriteLump(wadnum, l, numspritelumps, frame, rotation, 0); - - if (lumpinfo[l].name[6]) - { - frame = (UINT8)(lumpinfo[l].name[6] - 'A'); - rotation = (UINT8)(lumpinfo[l].name[7] - '0'); - R_RemoveSpriteLump(wadnum, l, numspritelumps, frame, rotation, 1); - } - } - } - - if (maxframe == (size_t)-1) - return false; - - spritedef->numframes = 0; - Z_Free(spritedef->spriteframes); - spritedef->spriteframes = NULL; - return true; -} - -void R_DelSpriteDefs(UINT16 wadnum) -{ - size_t i, delsprites = 0; - UINT16 start, end; - - // find the sprites section in this pwad - // we need at least the S_END - // (not really, but for speedup) - - start = W_CheckNumForNamePwad("S_START", wadnum, 0); - if (start == INT16_MAX) - start = W_CheckNumForNamePwad("SS_START", wadnum, 0); //deutex compatib. - if (start == INT16_MAX) - start = 0; //let say S_START is lump 0 - else - start++; // just after S_START - - end = W_CheckNumForNamePwad("S_END",wadnum,start); - if (end == INT16_MAX) - end = W_CheckNumForNamePwad("SS_END",wadnum,start); //deutex compatib. - if (end == INT16_MAX) - { - CONS_Debug(DBG_SETUP, "no sprites in pwad %d\n", wadnum); - return; - //I_Error("R_DelSpriteDefs: S_END, or SS_END missing for sprites " - // "in pwad %d\n",wadnum); - } - - // - // scan through lumps, for each sprite, find all the sprite frames - // - for (i = 0; i < numsprites; i++) - { - spritename = sprnames[i]; - - if (R_DelSingleSpriteDef(spritename, &sprites[i], wadnum, start, end)) - { - // if a new sprite was removed (not just replaced) - delsprites++; - CONS_Debug(DBG_SETUP, "sprite %s set in pwad %d\n", spritename, wadnum); - } - } - - CONS_Printf(M_GetText("%s sprites removed from file %s\n"), sizeu1(delsprites), wadfiles[wadnum]->filename); -} -#endif - // // GAME FUNCTIONS // -static UINT32 visspritecount; +UINT32 visspritecount; static UINT32 clippedvissprites; static vissprite_t *visspritechunks[MAXVISSPRITES >> VISSPRITECHUNKBITS] = {NULL}; @@ -665,7 +614,7 @@ void R_DrawMaskedColumn(column_t *column) dc_texturemid = basetexturemid; } -static void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight) +void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight) { INT32 topscreen; INT32 bottomscreen; @@ -761,11 +710,18 @@ static void R_DrawVisSprite(vissprite_t *vis) if (overflow_test < 0) overflow_test = -overflow_test; if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // fixed point mult would overflow + if (vis->scalestep) // handles right edge too + { + overflow_test = (INT64)centeryfrac - (((INT64)vis->texturemid*(vis->scale + (vis->scalestep*(vis->x2 - vis->x1))))>>FRACBITS); + if (overflow_test < 0) overflow_test = -overflow_test; + if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // ditto + } + colfunc = basecolfunc; // hack: this isn't resetting properly somewhere. dc_colormap = vis->colormap; - if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash" + if (!(vis->cut & SC_PRECIP) && (vis->mobj->flags & (MF_ENEMY|MF_BOSS)) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash" { - // translate green skin to another color + // translate certain pixels to white colfunc = transcolfunc; if (vis->mobj->type == MT_CYBRAKDEMON) dc_translation = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE); @@ -778,7 +734,7 @@ static void R_DrawVisSprite(vissprite_t *vis) { colfunc = transtransfunc; dc_transmap = vis->transmap; - if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // MT_GHOST LOOKS LIKE A PLAYER SO USE THE PLAYER TRANSLATION TABLES. >_> + if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // MT_GHOST LOOKS LIKE A PLAYER SO USE THE PLAYER TRANSLATION TABLES. >_> { size_t skinnum = (skin_t*)vis->mobj->skin-skins; dc_translation = R_GetTranslationColormap((INT32)skinnum, vis->mobj->color, GTC_CACHE); @@ -797,7 +753,7 @@ static void R_DrawVisSprite(vissprite_t *vis) colfunc = transcolfunc; // New colormap stuff for skins Tails 06-07-2002 - if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player! + if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player! { size_t skinnum = (skin_t*)vis->mobj->skin-skins; dc_translation = R_GetTranslationColormap((INT32)skinnum, vis->mobj->color, GTC_CACHE); @@ -821,46 +777,44 @@ static void R_DrawVisSprite(vissprite_t *vis) if (!dc_colormap) dc_colormap = colormaps; - dc_iscale = FixedDiv(FRACUNIT, vis->scale); dc_texturemid = vis->texturemid; dc_texheight = 0; frac = vis->startfrac; - spryscale = vis->scale; - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); windowtop = windowbottom = sprbotscreen = INT32_MAX; - if (vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES) + if (!(vis->cut & SC_PRECIP) && 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; if (this_scale != FRACUNIT) { - if (!vis->isScaled) + if (!(vis->cut & SC_ISSCALED)) { vis->scale = FixedMul(vis->scale, this_scale); - spryscale = vis->scale; - dc_iscale = FixedDiv(FRACUNIT, vis->scale); + vis->scalestep = FixedMul(vis->scalestep, this_scale); vis->xiscale = FixedDiv(vis->xiscale,this_scale); - vis->isScaled = true; + vis->cut |= SC_ISSCALED; } dc_texturemid = FixedDiv(dc_texturemid,this_scale); + } - //Oh lordy, mercy me. Don't freak out if sprites go offscreen! - /*if (vis->xiscale > 0) - frac = FixedDiv(frac, this_scale); - else if (vis->x1 <= 0) - frac = (vis->x1 - vis->x2) * vis->xiscale;*/ + spryscale = vis->scale; + if (!(vis->scalestep)) + { sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - //dc_hires = 1; + dc_iscale = FixedDiv(FRACUNIT, vis->scale); } x1 = vis->x1; x2 = vis->x2; if (vis->x1 < 0) + { + spryscale += vis->scalestep*(-vis->x1); vis->x1 = 0; + } if (vis->x2 >= vid.width) vis->x2 = vid.width-1; @@ -868,18 +822,25 @@ static void R_DrawVisSprite(vissprite_t *vis) for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) { #ifdef RANGECHECK + texturecolumn = frac>>FRACBITS; if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) - I_Error("R_DrawSpriteRange: bad texturecolumn"); + I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x); column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); #else column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS])); #endif - if (vis->vflip) + if (vis->scalestep) + { + sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); + dc_iscale = (0xffffffffu / (unsigned)spryscale); + } + if (vis->cut & SC_VFLIP) R_DrawFlippedMaskedColumn(column, patch->height); else R_DrawMaskedColumn(column); + spryscale += vis->scalestep; } colfunc = basecolfunc; @@ -954,7 +915,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) // // R_SplitSprite // runs through a sector's lightlist and -static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) +static void R_SplitSprite(vissprite_t *sprite) { INT32 i, lightnum, lindex; INT16 cutfrac; @@ -980,7 +941,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) if (testheight <= sprite->gz) return; - cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->scale))>>FRACBITS); + cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->sortscale))>>FRACBITS); if (cutfrac < 0) continue; if (cutfrac > viewheight) @@ -990,6 +951,8 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) // adjust the heights. newsprite = M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t)); + newsprite->cut |= (sprite->cut & SC_FLAGMASK); + sprite->cut |= SC_BOTTOM; sprite->gz = testheight; @@ -1020,16 +983,9 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) else spritelights = scalelight[lightnum]; - newsprite->extra_colormap = sector->lightlist[i].extra_colormap; + newsprite->extra_colormap = *sector->lightlist[i].extra_colormap; -/* - if (thing->frame & FF_TRANSMASK) - ; - else if (thing->flags2 & MF2_SHADOW) - ; - else -*/ - if (!((thing->frame & (FF_FULLBRIGHT|FF_TRANSMASK) || thing->flags2 & MF2_SHADOW) + if (!((newsprite->cut & SC_FULLBRIGHT) && (!newsprite->extra_colormap || !(newsprite->extra_colormap->fog & 1)))) { lindex = FixedMul(sprite->xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT); @@ -1050,10 +1006,11 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) // static void R_ProjectSprite(mobj_t *thing) { + mobj_t *oldthing = thing; fixed_t tr_x, tr_y; fixed_t gxt, gyt; fixed_t tx, tz; - fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! + fixed_t xscale, yscale, sortscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! INT32 x1, x2; @@ -1063,13 +1020,21 @@ static void R_ProjectSprite(mobj_t *thing) size_t rot; UINT8 flip; + boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP)); INT32 lindex; vissprite_t *vis; - angle_t ang; + spritecut_e cut = SC_NONE; + + angle_t ang = 0; // compiler complaints fixed_t iscale; + fixed_t scalestep; + fixed_t offset, offset2; + boolean papersprite = !!(thing->frame & FF_PAPERSPRITE); + + INT32 dispoffset = thing->info->dispoffset; //SoM: 3/17/2000 fixed_t gz, gzt; @@ -1077,6 +1042,8 @@ static void R_ProjectSprite(mobj_t *thing) INT32 light = 0; fixed_t this_scale = thing->scale; + fixed_t ang_scale = FRACUNIT; + // transform the origin point tr_x = thing->x - viewx; tr_y = thing->y - viewy; @@ -1087,7 +1054,7 @@ static void R_ProjectSprite(mobj_t *thing) tz = gxt-gyt; // thing is behind view plane? - if (tz < FixedMul(MINZ, this_scale)) + if (!(papersprite) && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later return; gxt = -FixedMul(tr_x, viewsin); @@ -1100,7 +1067,7 @@ static void R_ProjectSprite(mobj_t *thing) // aspect ratio stuff xscale = FixedDiv(projection, tz); - yscale = FixedDiv(projectiony, tz); + sortscale = FixedDiv(projectiony, tz); // decide which patch to use for sprite relative to player #ifdef RANGECHECK @@ -1113,9 +1080,14 @@ static void R_ProjectSprite(mobj_t *thing) //Fab : 02-08-98: 'skin' override spritedef currently used for skin if (thing->skin && thing->sprite == SPR_PLAY) { - sprdef = &((skin_t *)thing->skin)->spritedef; - if (rot >= sprdef->numframes) + sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2]; + if (rot >= sprdef->numframes) { + CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[%sSPR2_%s] frame %s\n"), ((skin_t *)thing->skin)->name, ((thing->sprite2 & FF_SPR2SUPER) ? "FF_SPR2SUPER|": ""), spr2names[(thing->sprite2 & ~FF_SPR2SUPER)], sizeu5(rot)); + thing->sprite = states[S_UNKNOWN].sprite; + thing->frame = states[S_UNKNOWN].frame; sprdef = &sprites[thing->sprite]; + rot = thing->frame&FF_FRAMEMASK; + } } else sprdef = &sprites[thing->sprite]; @@ -1142,22 +1114,36 @@ static void R_ProjectSprite(mobj_t *thing) I_Error("R_ProjectSprite: sprframes NULL for sprite %d\n", thing->sprite); #endif - if (sprframe->rotate) + if (sprframe->rotate != SRF_SINGLE || papersprite) { - // choose a different rotation based on player view - ang = R_PointToAngle (thing->x, thing->y); - rot = (ang-thing->angle+ANGLE_202h)>>29; - //Fab: lumpid is the index for spritewidth,spriteoffset... tables - lump = sprframe->lumpid[rot]; - flip = sprframe->flip & (1<<rot); + ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle); + if (papersprite) + ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT)); } - else + + if (sprframe->rotate == SRF_SINGLE) { // use single rotation for all views rot = 0; //Fab: for vis->patch below lump = sprframe->lumpid[0]; //Fab: see note above flip = sprframe->flip; // Will only be 0x00 or 0xFF } + else + { + // choose a different rotation based on player view + //ang = R_PointToAngle (thing->x, thing->y) - thing->angle; + + if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right + rot = 6; // F7 slot + else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left + rot = 2; // F3 slot + else // Normal behaviour + rot = (ang+ANGLE_202h)>>29; + + //Fab: lumpid is the index for spritewidth,spriteoffset... tables + lump = sprframe->lumpid[rot]; + flip = sprframe->flip & (1<<rot); + } I_Assert(lump < max_spritelumps); @@ -1166,24 +1152,105 @@ static void R_ProjectSprite(mobj_t *thing) // calculate edges of the shape if (flip) - tx -= FixedMul(spritecachedinfo[lump].width-spritecachedinfo[lump].offset, this_scale); + offset = spritecachedinfo[lump].offset - spritecachedinfo[lump].width; else - tx -= FixedMul(spritecachedinfo[lump].offset, this_scale); + offset = -spritecachedinfo[lump].offset; + offset = FixedMul(offset, this_scale); + tx += FixedMul(offset, ang_scale); x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS; // off the right side? if (x1 > viewwidth) return; - tx += FixedMul(spritecachedinfo[lump].width, this_scale); - x2 = ((centerxfrac + FixedMul (tx,xscale)) >>FRACBITS) - 1; + offset2 = FixedMul(spritecachedinfo[lump].width, this_scale); + tx += FixedMul(offset2, ang_scale); + x2 = ((centerxfrac + FixedMul (tx,xscale)) >> FRACBITS) - (papersprite ? 2 : 1); // off the left side if (x2 < 0) return; + if (papersprite) + { + fixed_t yscale2, cosmul, sinmul, tz2; + INT32 range; + + if (ang >= ANGLE_180) + { + offset *= -1; + offset2 *= -1; + } + + cosmul = FINECOSINE(thing->angle>>ANGLETOFINESHIFT); + sinmul = FINESINE(thing->angle>>ANGLETOFINESHIFT); + + tr_x += FixedMul(offset, cosmul); + tr_y += FixedMul(offset, sinmul); + gxt = FixedMul(tr_x, viewcos); + gyt = -FixedMul(tr_y, viewsin); + tz = gxt-gyt; + yscale = FixedDiv(projectiony, tz); + if (yscale < 64) return; // Fix some funky visuals + + tr_x += FixedMul(offset2, cosmul); + tr_y += FixedMul(offset2, sinmul); + gxt = FixedMul(tr_x, viewcos); + gyt = -FixedMul(tr_y, viewsin); + tz2 = gxt-gyt; + yscale2 = FixedDiv(projectiony, tz2); + if (yscale2 < 64) return; // ditto + + if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier + return; + + if (x2 > x1) + range = (x2 - x1); + else + range = 1; + + scalestep = (yscale2 - yscale)/range; + + // The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2? + // sortscale = max(yscale, yscale2); + // sortscale = min(yscale, yscale2); + } + else + { + scalestep = 0; + yscale = sortscale; + } + + xscale = FixedMul(xscale, ang_scale); + + if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY) + { + fixed_t linkscale; + + thing = thing->tracer; + + if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW) + return; + + tr_x = thing->x - viewx; + tr_y = thing->y - viewy; + gxt = FixedMul(tr_x, viewcos); + gyt = -FixedMul(tr_y, viewsin); + tz = gxt-gyt; + linkscale = FixedDiv(projectiony, tz); + + if (tz < FixedMul(MINZ, this_scale)) + return; + + if (sortscale < linkscale) + dispoffset *= -1; // if it's physically behind, make sure it's ordered behind (if dispoffset > 0) + + sortscale = linkscale; // now make sure it's linked + cut = SC_LINKDRAW; + } + // PORTAL SPRITE CLIPPING - if (portalrender) + if (portalrender && portalclipline) { if (x2 < portalclipstart || x1 > portalclipend) return; @@ -1193,17 +1260,17 @@ static void R_ProjectSprite(mobj_t *thing) } //SoM: 3/17/2000: Disregard sprites that are out of view.. - if (thing->eflags & MFE_VERTICALFLIP) + if (vflip) { // 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 = thing->z + thing->height - FixedMul(spritecachedinfo[lump].topoffset, this_scale); + gz = oldthing->z + oldthing->height - FixedMul(spritecachedinfo[lump].topoffset, this_scale); gzt = gz + FixedMul(spritecachedinfo[lump].height, this_scale); } else { - gzt = thing->z + FixedMul(spritecachedinfo[lump].topoffset, this_scale); + gzt = oldthing->z + FixedMul(spritecachedinfo[lump].topoffset, this_scale); gz = gzt - FixedMul(spritecachedinfo[lump].height, this_scale); } @@ -1263,7 +1330,8 @@ static void R_ProjectSprite(mobj_t *thing) vis->heightsec = heightsec; //SoM: 3/17/2000 vis->mobjflags = thing->flags; vis->scale = yscale; //<<detailshift; - vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15 + vis->sortscale = sortscale; + vis->dispoffset = dispoffset; // Monster Iestyn: 23/11/15 vis->gx = thing->x; vis->gy = thing->y; vis->gz = gz; @@ -1272,6 +1340,7 @@ static void R_ProjectSprite(mobj_t *thing) vis->pz = thing->z; vis->pzt = vis->pz + vis->thingheight; vis->texturemid = vis->gzt - viewz; + vis->scalestep = scalestep; vis->mobj = thing; // Easy access! Tails 06-07-2002 @@ -1283,17 +1352,17 @@ static void R_ProjectSprite(mobj_t *thing) { if (vis->x1 < portalclipstart) vis->x1 = portalclipstart; - if (vis->x2 > portalclipend) - vis->x2 = portalclipend; + if (vis->x2 >= portalclipend) + vis->x2 = portalclipend-1; } vis->xscale = xscale; //SoM: 4/17/2000 vis->sector = thing->subsector->sector; - vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, yscale))>>FRACBITS); - vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, yscale))>>FRACBITS); - vis->cut = SC_NONE; + vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS); + vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS); + vis->cut = cut; if (thing->subsector->sector->numlights) - vis->extra_colormap = thing->subsector->sector->lightlist[light].extra_colormap; + vis->extra_colormap = *thing->subsector->sector->lightlist[light].extra_colormap; else vis->extra_colormap = thing->subsector->sector->extra_colormap; @@ -1311,7 +1380,10 @@ static void R_ProjectSprite(mobj_t *thing) } if (vis->x1 > x1) + { vis->startfrac += FixedDiv(vis->xiscale, this_scale)*(vis->x1-x1); + vis->scale += scalestep*(vis->x1 - x1); + } //Fab: lumppat is the lump number of the patch to use, this is different // than lumpid for sprites-in-pwad : the graphics are patched @@ -1325,12 +1397,15 @@ static void R_ProjectSprite(mobj_t *thing) // specific translucency if (!cv_translucency.value) ; // no translucency - else if (thing->flags2 & MF2_SHADOW) // actually only the player should use this (temporary invisibility) + else if (oldthing->flags2 & MF2_SHADOW || thing->flags2 & MF2_SHADOW) // actually only the player should use this (temporary invisibility) vis->transmap = transtables + ((tr_trans80-1)<<FF_TRANSSHIFT); // because now the translucency is set through FF_TRANSMASK - else if (thing->frame & FF_TRANSMASK) - vis->transmap = transtables + (thing->frame & FF_TRANSMASK) - 0x10000; + else if (oldthing->frame & FF_TRANSMASK) + vis->transmap = transtables + (oldthing->frame & FF_TRANSMASK) - 0x10000; + + if (oldthing->frame & FF_FULLBRIGHT || oldthing->flags2 & MF2_SHADOW || thing->flags2 & MF2_SHADOW) + vis->cut |= SC_FULLBRIGHT; - if (((thing->frame & FF_FULLBRIGHT) || (thing->flags2 & MF2_SHADOW)) + if (vis->cut & SC_FULLBRIGHT && (!vis->extra_colormap || !(vis->extra_colormap->fog & 1))) { // full bright: goggles @@ -1347,17 +1422,11 @@ static void R_ProjectSprite(mobj_t *thing) vis->colormap = spritelights[lindex]; } - vis->precip = false; - - if (thing->eflags & MFE_VERTICALFLIP) - vis->vflip = true; - else - vis->vflip = false; - - vis->isScaled = false; + if (vflip) + vis->cut |= SC_VFLIP; if (thing->subsector->sector->numlights) - R_SplitSprite(vis, thing); + R_SplitSprite(vis); // Debug ++objectsdrawn; @@ -1381,7 +1450,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) fixed_t iscale; //SoM: 3/17/2000 - fixed_t gz ,gzt; + fixed_t gz, gzt; // transform the origin point tr_x = thing->x - viewx; @@ -1449,7 +1518,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) return; // PORTAL SPRITE CLIPPING - if (portalrender) + if (portalrender && portalclipline) { if (x2 < portalclipstart || x1 > portalclipend) return; @@ -1458,16 +1527,6 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) return; } - // okay, we can't return now except for vertical clipping... this is a hack, but weather isn't networked, so it should be ok - if (!(thing->precipflags & PCF_THUNK)) - { - if (thing->precipflags & PCF_RAIN) - P_RainThinker(thing); - else - P_SnowThinker(thing); - thing->precipflags |= PCF_THUNK; - } - //SoM: 3/17/2000: Disregard sprites that are out of view.. gzt = thing->z + spritecachedinfo[lump].topoffset; @@ -1476,12 +1535,12 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) if (thing->subsector->sector->cullheight) { if (R_DoCulling(thing->subsector->sector->cullheight, viewsector->cullheight, viewz, gz, gzt)) - return; + goto weatherthink; } // store information in a vissprite vis = R_NewVisSprite(); - vis->scale = yscale; //<<detailshift; + vis->scale = vis->sortscale = yscale; //<<detailshift; vis->dispoffset = 0; // Monster Iestyn: 23/11/15 vis->gx = thing->x; vis->gy = thing->y; @@ -1491,6 +1550,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) vis->pz = thing->z; vis->pzt = vis->pz + vis->thingheight; vis->texturemid = vis->gzt - viewz; + vis->scalestep = 0; vis->x1 = x1 < 0 ? 0 : x1; vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; @@ -1500,8 +1560,8 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) { if (vis->x1 < portalclipstart) vis->x1 = portalclipstart; - if (vis->x2 > portalclipend) - vis->x2 = portalclipend; + if (vis->x2 >= portalclipend) + vis->x2 = portalclipend-1; } vis->xscale = xscale; //SoM: 4/17/2000 @@ -1527,16 +1587,25 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) else vis->transmap = NULL; + vis->mobj = (mobj_t *)thing; vis->mobjflags = 0; - vis->cut = SC_NONE; + vis->cut = SC_PRECIP; vis->extra_colormap = thing->subsector->sector->extra_colormap; vis->heightsec = thing->subsector->sector->heightsec; // Fullbright vis->colormap = colormaps; - vis->precip = true; - vis->vflip = false; - vis->isScaled = false; + +weatherthink: + // okay... this is a hack, but weather isn't networked, so it should be ok + if (!(thing->precipflags & PCF_THUNK)) + { + if (thing->precipflags & PCF_RAIN) + P_RainThinker(thing); + else + P_SnowThinker(thing); + thing->precipflags |= PCF_THUNK; + } } // R_AddSprites @@ -1601,7 +1670,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) R_ProjectSprite(thing); } - // Someone seriously wants infinite draw distance for precipitation? + // no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off if ((limit_dist = (fixed_t)cv_drawdist_precip.value << FRACBITS)) { for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext) @@ -1617,70 +1686,127 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) R_ProjectPrecipitationSprite(precipthing); } } - else - { - // Draw everything in sector, no checks - for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext) - if (!(precipthing->precipflags & PCF_INVISIBLE)) - R_ProjectPrecipitationSprite(precipthing); - } } // // R_SortVisSprites // -static vissprite_t vsprsortedhead; - -void R_SortVisSprites(void) +static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 end) { - UINT32 i; + UINT32 i, linkedvissprites = 0; vissprite_t *ds, *dsprev, *dsnext, *dsfirst; vissprite_t *best = NULL; vissprite_t unsorted; fixed_t bestscale; INT32 bestdispoffset; - if (!visspritecount) - return; - unsorted.next = unsorted.prev = &unsorted; - dsfirst = R_GetVisSprite(0); + dsfirst = R_GetVisSprite(start); // The first's prev and last's next will be set to // nonsense, but are fixed in a moment - for (i = 0, dsnext = dsfirst, ds = NULL; i < visspritecount; i++) + for (i = start, dsnext = dsfirst, ds = NULL; i < end; i++) { dsprev = ds; ds = dsnext; - if (i < visspritecount - 1) dsnext = R_GetVisSprite(i + 1); + if (i < end - 1) dsnext = R_GetVisSprite(i + 1); ds->next = dsnext; ds->prev = dsprev; + ds->linkdraw = NULL; } // Fix first and last. ds still points to the last one after the loop dsfirst->prev = &unsorted; unsorted.next = dsfirst; if (ds) + { ds->next = &unsorted; + ds->linkdraw = NULL; + } unsorted.prev = ds; + // bundle linkdraw + for (ds = unsorted.prev; ds != &unsorted; ds = ds->prev) + { + if (!(ds->cut & SC_LINKDRAW)) + continue; + + // reuse dsfirst... + for (dsfirst = unsorted.prev; dsfirst != &unsorted; dsfirst = dsfirst->prev) + { + // don't connect if it's also a link + if (dsfirst->cut & SC_LINKDRAW) + continue; + + // don't connect if it's not the tracer + if (dsfirst->mobj != ds->mobj) + 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) + 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) + continue; + + break; + } + + // remove from chain + ds->next->prev = ds->prev; + ds->prev->next = ds->next; + linkedvissprites++; + + if (dsfirst != &unsorted) + { + if (!(ds->cut & SC_FULLBRIGHT)) + ds->colormap = dsfirst->colormap; + ds->extra_colormap = dsfirst->extra_colormap; + + // reusing dsnext... + dsnext = dsfirst->linkdraw; + + if (!dsnext || ds->dispoffset < dsnext->dispoffset) + { + ds->next = dsnext; + dsfirst->linkdraw = ds; + } + else + { + for (; dsnext->next != NULL; dsnext = dsnext->next) + if (ds->dispoffset < dsnext->next->dispoffset) + break; + ds->next = dsnext->next; + dsnext->next = ds; + } + } + } + // pull the vissprites out by scale - vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead; - for (i = 0; i < visspritecount; i++) + vsprsortedhead->next = vsprsortedhead->prev = vsprsortedhead; + for (i = start; i < end-linkedvissprites; i++) { bestscale = bestdispoffset = INT32_MAX; for (ds = unsorted.next; ds != &unsorted; ds = ds->next) { - if (ds->scale < bestscale) +#ifdef PARANOIA + if (ds->cut & SC_LINKDRAW) + I_Error("R_SortVisSprites: no link or discardal made for linkdraw!"); +#endif + + if (ds->sortscale < bestscale) { - bestscale = ds->scale; + bestscale = ds->sortscale; bestdispoffset = ds->dispoffset; best = ds; } // order visprites of same scale by dispoffset, smallest first - else if (ds->scale == bestscale && ds->dispoffset < bestdispoffset) + else if (ds->sortscale == bestscale && ds->dispoffset < bestdispoffset) { bestdispoffset = ds->dispoffset; best = ds; @@ -1688,10 +1814,10 @@ void R_SortVisSprites(void) } best->next->prev = best->prev; best->prev->next = best->next; - best->next = &vsprsortedhead; - best->prev = vsprsortedhead.prev; - vsprsortedhead.prev->next = best; - vsprsortedhead.prev = best; + best->next = vsprsortedhead; + best->prev = vsprsortedhead->prev; + vsprsortedhead->prev->next = best; + vsprsortedhead->prev = best; } } @@ -1701,28 +1827,28 @@ void R_SortVisSprites(void) static drawnode_t *R_CreateDrawNode(drawnode_t *link); static drawnode_t nodebankhead; -static drawnode_t nodehead; -static void R_CreateDrawNodes(void) +static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean tempskip) { drawnode_t *entry; drawseg_t *ds; INT32 i, p, best, x1, x2; fixed_t bestdelta, delta; vissprite_t *rover; + static vissprite_t vsprsortedhead; drawnode_t *r2; visplane_t *plane; INT32 sintersect; fixed_t scale = 0; // Add the 3D floors, thicksides, and masked textures... - for (ds = ds_p; ds-- > drawsegs ;) + for (ds = drawsegs + mask->drawsegs[1]; ds-- > drawsegs + mask->drawsegs[0];) { if (ds->numthicksides) { for (i = 0; i < ds->numthicksides; i++) { - entry = R_CreateDrawNode(&nodehead); + entry = R_CreateDrawNode(head); entry->thickseg = ds; entry->ffloor = ds->thicksides[i]; } @@ -1737,7 +1863,7 @@ static void R_CreateDrawNodes(void) ; else { // Put it in! - entry = R_CreateDrawNode(&nodehead); + entry = R_CreateDrawNode(head); entry->plane = plane; entry->seg = ds; } @@ -1746,7 +1872,7 @@ static void R_CreateDrawNodes(void) #endif if (ds->maskedtexturecol) { - entry = R_CreateDrawNode(&nodehead); + entry = R_CreateDrawNode(head); entry->seg = ds; } if (ds->numffloorplanes) @@ -1777,7 +1903,7 @@ static void R_CreateDrawNodes(void) } if (best != -1) { - entry = R_CreateDrawNode(&nodehead); + entry = R_CreateDrawNode(head); entry->plane = ds->ffloorplanes[best]; entry->seg = ds; ds->ffloorplanes[best] = NULL; @@ -1788,6 +1914,9 @@ static void R_CreateDrawNodes(void) } } + if (tempskip) + return; + #ifdef POLYOBJECTS_PLANES // find all the remaining polyobject planes and add them on the end of the list // probably this is a terrible idea if we wanted them to be sorted properly @@ -1804,17 +1933,19 @@ static void R_CreateDrawNodes(void) PolyObjects[i].visplane = NULL; continue; } - entry = R_CreateDrawNode(&nodehead); + entry = R_CreateDrawNode(head); entry->plane = plane; // note: no seg is set, for what should be obvious reasons PolyObjects[i].visplane = NULL; } #endif - if (visspritecount == 0) + // No vissprites in this mask? + if (mask->vissprites[1] - mask->vissprites[0] == 0) return; - R_SortVisSprites(); + R_SortVisSprites(&vsprsortedhead, mask->vissprites[0], mask->vissprites[1]); + for (rover = vsprsortedhead.prev; rover != &vsprsortedhead; rover = rover->prev) { if (rover->szt > vid.height || rover->sz < 0) @@ -1822,7 +1953,7 @@ static void R_CreateDrawNodes(void) sintersect = (rover->x1 + rover->x2) / 2; - for (r2 = nodehead.next; r2 != &nodehead; r2 = r2->next) + for (r2 = head->next; r2 != head; r2 = r2->next) { if (r2->plane) { @@ -1871,7 +2002,7 @@ static void R_CreateDrawNodes(void) { for (i = x1; i <= x2; i++) { - if (r2->seg->frontscale[i] > rover->scale) + if (r2->seg->frontscale[i] > rover->sortscale) break; } if (i > x2) @@ -1891,10 +2022,10 @@ static void R_CreateDrawNodes(void) continue; scale = r2->thickseg->scale1 > r2->thickseg->scale2 ? r2->thickseg->scale1 : r2->thickseg->scale2; - if (scale <= rover->scale) + if (scale <= rover->sortscale) continue; scale = r2->thickseg->scale1 + (r2->thickseg->scalestep * (sintersect - r2->thickseg->x1)); - if (scale <= rover->scale) + if (scale <= rover->sortscale) continue; #ifdef ESLOPE @@ -1926,29 +2057,15 @@ static void R_CreateDrawNodes(void) } else if (r2->seg) { -#if 0 //#ifdef POLYOBJECTS_PLANES - if (r2->seg->curline->polyseg && rover->mobj && P_MobjInsidePolyobj(r2->seg->curline->polyseg, rover->mobj)) { - // Determine if we need to sort in front of the polyobj, based on the planes. This fixes the issue where - // polyobject planes render above the object standing on them. (A bit hacky... but it works.) -Red - mobj_t *mo = rover->mobj; - sector_t *po = r2->seg->curline->backsector; - - if (po->ceilingheight < viewz && mo->z+mo->height > po->ceilingheight) - continue; - - if (po->floorheight > viewz && mo->z < po->floorheight) - continue; - } -#endif if (rover->x1 > r2->seg->x2 || rover->x2 < r2->seg->x1) continue; scale = r2->seg->scale1 > r2->seg->scale2 ? r2->seg->scale1 : r2->seg->scale2; - if (scale <= rover->scale) + if (scale <= rover->sortscale) continue; scale = r2->seg->scale1 + (r2->seg->scalestep * (sintersect - r2->seg->x1)); - if (rover->scale < scale) + if (rover->sortscale < scale) { entry = R_CreateDrawNode(NULL); (entry->prev = r2->prev)->next = entry; @@ -1964,8 +2081,8 @@ static void R_CreateDrawNodes(void) if (r2->sprite->szt > rover->sz || r2->sprite->sz < rover->szt) continue; - if (r2->sprite->scale > rover->scale - || (r2->sprite->scale == rover->scale && r2->sprite->dispoffset > rover->dispoffset)) + if (r2->sprite->sortscale > rover->sortscale + || (r2->sprite->sortscale == rover->sortscale && r2->sprite->dispoffset > rover->dispoffset)) { entry = R_CreateDrawNode(NULL); (entry->prev = r2->prev)->next = entry; @@ -1975,9 +2092,9 @@ static void R_CreateDrawNodes(void) } } } - if (r2 == &nodehead) + if (r2 == head) { - entry = R_CreateDrawNode(&nodehead); + entry = R_CreateDrawNode(head); entry->sprite = rover; } } @@ -2019,25 +2136,24 @@ static void R_DoneWithNode(drawnode_t *node) (node->prev = &nodebankhead)->next = node; } -static void R_ClearDrawNodes(void) +static void R_ClearDrawNodes(drawnode_t* head) { drawnode_t *rover; drawnode_t *next; - for (rover = nodehead.next; rover != &nodehead ;) + for (rover = head->next; rover != head;) { next = rover->next; R_DoneWithNode(rover); rover = next; } - nodehead.next = nodehead.prev = &nodehead; + head->next = head->prev = head; } void R_InitDrawNodes(void) { nodebankhead.next = nodebankhead.prev = &nodebankhead; - nodehead.next = nodehead.prev = &nodehead; } // @@ -2063,10 +2179,10 @@ static void R_DrawPrecipitationSprite(vissprite_t *spr) // R_ClipSprites // Clips vissprites without drawing, so that portals can work. -Red -void R_ClipSprites(void) +void R_ClipSprites(drawseg_t* dsstart, portal_t* portal) { vissprite_t *spr; - for (;clippedvissprites < visspritecount; clippedvissprites++) + for (; clippedvissprites < visspritecount; clippedvissprites++) { drawseg_t *ds; INT32 x; @@ -2089,7 +2205,7 @@ void R_ClipSprites(void) // 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-- > drawsegs ;) + for (ds = ds_p; ds-- > dsstart;) { // determine if the drawseg obscures the sprite if (ds->x1 > spr->x2 || @@ -2101,33 +2217,36 @@ void R_ClipSprites(void) continue; } - if (ds->portalpass > 0 && ds->portalpass <= portalrender) - continue; // is a portal + if (ds->portalpass != 66) + { + if (ds->portalpass > 0 && ds->portalpass <= portalrender) + continue; // is a portal - r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1; - r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2; + if (ds->scale1 > ds->scale2) + { + lowscale = ds->scale2; + scale = ds->scale1; + } + else + { + lowscale = ds->scale1; + scale = ds->scale2; + } - if (ds->scale1 > ds->scale2) - { - lowscale = ds->scale2; - scale = ds->scale1; - } - else - { - lowscale = ds->scale1; - scale = ds->scale2; + if (scale < spr->sortscale || + (lowscale < spr->sortscale && + !R_PointOnSegSide (spr->gx, spr->gy, ds->curline))) + { + // masked mid texture? + /*if (ds->maskedtexturecol) + R_RenderMaskedSegRange (ds, r1, r2);*/ + // seg is behind sprite + continue; + } } - if (scale < spr->scale || - (lowscale < spr->scale && - !R_PointOnSegSide (spr->gx, spr->gy, ds->curline))) - { - // masked mid texture? - /*if (ds->maskedtexturecol) - R_RenderMaskedSegRange (ds, r1, r2);*/ - // seg is behind sprite - continue; - } + r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1; + r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2; // clip this piece of the sprite silhouette = ds->silhouette; @@ -2170,7 +2289,7 @@ void R_ClipSprites(void) fixed_t mh, h; INT32 phs = viewplayer->mo->subsector->sector->heightsec; if ((mh = sectors[spr->heightsec].floorheight) > spr->gz && - (h = centeryfrac - FixedMul(mh -= viewz, spr->scale)) >= 0 && + (h = centeryfrac - FixedMul(mh -= viewz, spr->sortscale)) >= 0 && (h >>= FRACBITS) < viewheight) { if (mh <= 0 || (phs != -1 && viewz > sectors[phs].floorheight)) @@ -2188,7 +2307,7 @@ void R_ClipSprites(void) } if ((mh = sectors[spr->heightsec].ceilingheight) < spr->gzt && - (h = centeryfrac - FixedMul(mh-viewz, spr->scale)) >= 0 && + (h = centeryfrac - FixedMul(mh-viewz, spr->sortscale)) >= 0 && (h >>= FRACBITS) < viewheight) { if (phs != -1 && viewz >= sectors[phs].ceilingheight) @@ -2245,20 +2364,29 @@ void R_ClipSprites(void) //Fab : 26-04-98: was -1, now clips against console bottom spr->cliptop[x] = (INT16)con_clipviewtop; } + + if (portal) + { + for (x = spr->x1; x <= spr->x2; x++) + { + if (spr->clipbot[x] > portal->floorclip[x - portal->start]) + spr->clipbot[x] = portal->floorclip[x - portal->start]; + if (spr->cliptop[x] < portal->ceilingclip[x - portal->start]) + spr->cliptop[x] = portal->ceilingclip[x - portal->start]; + } + } } } // // R_DrawMasked // -void R_DrawMasked(void) +static void R_DrawMaskedList (drawnode_t* head) { drawnode_t *r2; drawnode_t *next; - R_CreateDrawNodes(); - - for (r2 = nodehead.next; r2 != &nodehead; r2 = r2->next) + for (r2 = head->next; r2 != head; r2 = r2->next) { if (r2->plane) { @@ -2287,16 +2415,61 @@ void R_DrawMasked(void) next = r2->prev; // Tails 08-18-2002 - if (r2->sprite->precip == true) + if (r2->sprite->cut & SC_PRECIP) R_DrawPrecipitationSprite(r2->sprite); - else + else if (!r2->sprite->linkdraw) + R_DrawSprite(r2->sprite); + else // unbundle linkdraw + { + vissprite_t *ds = r2->sprite->linkdraw; + + for (; + (ds != NULL && r2->sprite->dispoffset > ds->dispoffset); + ds = ds->next) + R_DrawSprite(ds); + R_DrawSprite(r2->sprite); + for (; ds != NULL; ds = ds->next) + R_DrawSprite(ds); + } + R_DoneWithNode(r2); r2 = next; } } - R_ClearDrawNodes(); +} + +void R_DrawMasked(maskcount_t* masks, UINT8 nummasks) +{ + drawnode_t heads[nummasks]; /**< Drawnode lists; as many as number of views/portals. */ + INT8 i; + + for (i = 0; i < nummasks; i++) + { + heads[i].next = heads[i].prev = &heads[i]; + + viewx = masks[i].viewx; + viewy = masks[i].viewy; + viewz = masks[i].viewz; + viewsector = masks[i].viewsector; + + R_CreateDrawNodes(&masks[i], &heads[i], false); + } + + //for (i = 0; i < nummasks; i++) + // CONS_Printf("Mask no.%d:\ndrawsegs: %d\n vissprites: %d\n\n", i, masks[i].drawsegs[1] - masks[i].drawsegs[0], masks[i].vissprites[1] - masks[i].vissprites[0]); + + for (; nummasks > 0; nummasks--) + { + viewx = masks[nummasks - 1].viewx; + viewy = masks[nummasks - 1].viewy; + viewz = masks[nummasks - 1].viewz; + viewsector = masks[nummasks - 1].viewsector; + + R_DrawMaskedList(&heads[nummasks - 1]); + R_ClearDrawNodes(&heads[nummasks - 1]); + } } // ========================================================================== @@ -2313,6 +2486,56 @@ skin_t skins[MAXSKINS]; CV_PossibleValue_t skin_cons_t[MAXSKINS+1]; #endif +// +// P_GetSkinSprite2 +// For non-super players, tries each sprite2's immediate predecessor until it finds one with a number of frames or ends up at standing. +// For super players, does the same as above - but tries the super equivalent for each sprite2 before the non-super version. +// + +UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player) +{ + UINT8 super = 0, i = 0; + + if (!skin) + return 0; + + while (!(skin->sprites[spr2].numframes) + && spr2 != SPR2_STND + && ++i < 32) // recursion limiter + { + if (spr2 & FF_SPR2SUPER) + { + super = FF_SPR2SUPER; + spr2 &= ~FF_SPR2SUPER; + continue; + } + + switch(spr2) + { + + // Normal special cases. + case SPR2_JUMP: + spr2 = ((player + ? player->charflags + : skin->flags) + & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL; + break; + case SPR2_TIRE: + spr2 = (player && player->charability == CA_SWIM) ? SPR2_SWIM : SPR2_FLY; + break; + + // Use the handy list, that's what it's there for! + default: + spr2 = spr2defaults[spr2]; + break; + } + + spr2 |= super; + } + + return spr2; +} + static void Sk_SetDefaultValue(skin_t *skin) { INT32 i; @@ -2324,7 +2547,6 @@ static void Sk_SetDefaultValue(skin_t *skin) sizeof skin->name, "skin %u", (UINT32)(skin-skins)); skin->name[sizeof skin->name - 1] = '\0'; skin->wadnum = INT16_MAX; - strcpy(skin->sprite, ""); skin->flags = 0; @@ -2334,8 +2556,10 @@ static void Sk_SetDefaultValue(skin_t *skin) strncpy(skin->face, "MISSING", 8); strncpy(skin->superface, "MISSING", 8); - skin->starttranscolor = 160; + skin->starttranscolor = 96; skin->prefcolor = SKINCOLOR_GREEN; + skin->supercolor = SKINCOLOR_SUPERGOLD1; + skin->prefoppositecolor = 0; // use tables skin->normalspeed = 36<<FRACBITS; skin->runspeed = 28<<FRACBITS; @@ -2348,13 +2572,23 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->jumpfactor = FRACUNIT; skin->actionspd = 30<<FRACBITS; skin->mindash = 15<<FRACBITS; - skin->maxdash = 90<<FRACBITS; + skin->maxdash = 70<<FRACBITS; + + skin->radius = mobjinfo[MT_PLAYER].radius; + skin->height = mobjinfo[MT_PLAYER].height; + skin->spinheight = FixedMul(skin->height, 2*FRACUNIT/3); + + skin->shieldscale = FRACUNIT; + skin->camerascale = FRACUNIT; skin->thokitem = -1; skin->spinitem = -1; skin->revitem = -1; + skin->followitem = 0; - skin->highresscale = FRACUNIT>>1; + skin->highresscale = FRACUNIT; + + skin->availability = 0; for (i = 0; i < sfx_skinsoundslot0; i++) if (S_sfx[i].skinsound != -1) @@ -2366,7 +2600,6 @@ static void Sk_SetDefaultValue(skin_t *skin) // void R_InitSkins(void) { - skin_t *skin; #ifdef SKINVALUES INT32 i; @@ -2377,43 +2610,34 @@ void R_InitSkins(void) } #endif - // skin[0] = Sonic skin - skin = &skins[0]; - numskins = 1; - Sk_SetDefaultValue(skin); + // no default skin! + numskins = 0; +} - // Hardcoded S_SKIN customizations for Sonic. - strcpy(skin->name, DEFAULTSKIN); -#ifdef SKINVALUES - skin_cons_t[0].strvalue = skins[0].name; -#endif - skin->flags = SF_SUPER|SF_SUPERANIMS|SF_SUPERSPIN; - strcpy(skin->realname, "Sonic"); - strcpy(skin->hudname, "SONIC"); - - strncpy(skin->charsel, "CHRSONIC", 9); - strncpy(skin->face, "LIVSONIC", 9); - strncpy(skin->superface, "LIVSUPER", 9); - skin->prefcolor = SKINCOLOR_BLUE; - - skin->ability = CA_THOK; - skin->actionspd = 60<<FRACBITS; - - skin->normalspeed = 36<<FRACBITS; - skin->runspeed = 28<<FRACBITS; - skin->thrustfactor = 5; - skin->accelstart = 96; - skin->acceleration = 40; +UINT32 R_GetSkinAvailabilities(void) +{ + INT32 s; + UINT32 response = 0; - skin->spritedef.numframes = sprites[SPR_PLAY].numframes; - skin->spritedef.spriteframes = sprites[SPR_PLAY].spriteframes; - ST_LoadFaceGraphics(skin->face, skin->superface, 0); + for (s = 0; s < MAXSKINS; s++) + { + if (skins[s].availability && unlockables[skins[s].availability - 1].unlocked) + response |= (1 << s); + } + return response; +} - //MD2 for sonic doesn't want to load in Linux. -#ifdef HWRENDER - if (rendermode == render_opengl) - HWR_AddPlayerMD2(0); -#endif +// returns true if available in circumstances, otherwise nope +// warning don't use with an invalid skinnum other than -1 which always returns true +boolean R_SkinUsable(INT32 playernum, INT32 skinnum) +{ + return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0... + || (!skins[skinnum].availability) + || ((playernum != -1) ? (players[playernum].availabilities & (1 << skinnum)) : (unlockables[skins[skinnum].availability - 1].unlocked)) + || (modeattacking) // If you have someone else's run you might as well take a look + || (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1. + || (netgame && (cv_forceskin.value == skinnum)) // Force 2. + ); } // returns true if the skin name is found (loaded from pwad) @@ -2424,6 +2648,7 @@ INT32 R_SkinAvailable(const char *name) for (i = 0; i < numskins; i++) { + // search in the skin list if (stricmp(skins[i].name,name)==0) return i; } @@ -2433,17 +2658,13 @@ INT32 R_SkinAvailable(const char *name) // network code calls this when a 'skin change' is received void SetPlayerSkin(INT32 playernum, const char *skinname) { - INT32 i; + INT32 i = R_SkinAvailable(skinname); player_t *player = &players[playernum]; - for (i = 0; i < numskins; i++) + if ((i != -1) && R_SkinUsable(playernum, i)) { - // search in the skin list - if (stricmp(skins[i].name, skinname) == 0) - { - SetPlayerSkinByNum(playernum, i); - return; - } + SetPlayerSkinByNum(playernum, i); + return; } if (P_IsLocalPlayer(player)) @@ -2460,12 +2681,14 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) { player_t *player = &players[playernum]; skin_t *skin = &skins[skinnum]; + UINT8 newcolor = 0; - if (skinnum >= 0 && skinnum < numskins) // Make sure it exists! + if (skinnum >= 0 && skinnum < numskins && R_SkinUsable(playernum, skinnum)) // Make sure it exists! { player->skin = skinnum; - if (player->mo) - player->mo->skin = skin; + + player->camerascale = skin->camerascale; + player->shieldscale = skin->shieldscale; player->charability = (UINT8)skin->ability; player->charability2 = (UINT8)skin->ability2; @@ -2475,6 +2698,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) player->thokitem = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem; player->spinitem = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem; player->revitem = skin->revitem < 0 ? (mobjtype_t)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem; + player->followitem = skin->followitem; player->actionspd = skin->actionspd; player->mindash = skin->mindash; @@ -2488,26 +2712,49 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) player->jumpfactor = skin->jumpfactor; + player->height = skin->height; + player->spinheight = skin->spinheight; + if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback)) { if (playernum == consoleplayer) CV_StealthSetValue(&cv_playercolor, skin->prefcolor); else if (playernum == secondarydisplayplayer) CV_StealthSetValue(&cv_playercolor2, skin->prefcolor); - player->skincolor = skin->prefcolor; - if (player->mo) - player->mo->color = player->skincolor; + player->skincolor = newcolor = skin->prefcolor; + } + + if (player->followmobj) + { + P_RemoveMobj(player->followmobj); + P_SetTarget(&player->followmobj, NULL); } if (player->mo) + { + fixed_t radius = FixedMul(skin->radius, player->mo->scale); + if ((player->powers[pw_carry] == CR_NIGHTSMODE) && (skin->sprites[SPR2_NGT0].numframes == 0)) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin. + { + skin = &skins[DEFAULTNIGHTSSKIN]; + player->followitem = skin->followitem; + if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback)) + newcolor = skin->prefcolor; // will be updated in thinker to flashing + } + player->mo->skin = skin; + if (newcolor) + player->mo->color = newcolor; P_SetScale(player->mo, player->mo->scale); + player->mo->radius = radius; + + P_SetPlayerMobjState(player->mo, player->mo->state-states); // Prevent visual errors when switching between skins with differing number of frames + } return; } if (P_IsLocalPlayer(player)) - CONS_Alert(CONS_WARNING, M_GetText("Skin %d not found\n"), skinnum); + CONS_Alert(CONS_WARNING, M_GetText("Requested skin not found\n")); else if(server || IsPlayerAdmin(consoleplayer)) - CONS_Alert(CONS_WARNING, "Player %d (%s) skin %d not found\n", playernum, player_names[playernum], skinnum); + CONS_Alert(CONS_WARNING, "Player %d (%s) skin not found\n", playernum, player_names[playernum]); SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin } @@ -2536,6 +2783,192 @@ static UINT16 W_CheckForSkinMarkerInPwad(UINT16 wadid, UINT16 startlump) return INT16_MAX; // not found } +#define HUDNAMEWRITE(value) STRBUFCPY(skin->hudname, value) + +// turn _ into spaces and . into katana dot +#define SYMBOLCONVERT(name) for (value = name; *value; value++)\ + {\ + if (*value == '_') *value = ' ';\ + else if (*value == '.') *value = '\x1E';\ + } + +// +// Patch skins from a pwad, each skin preceded by 'P_SKIN' marker +// + +// Does the same is in w_wad, but check only for +// the first 6 characters (this is so we can have P_SKIN1, P_SKIN2.. +// for wad editors that don't like multiple resources of the same name) +// +static UINT16 W_CheckForPatchSkinMarkerInPwad(UINT16 wadid, UINT16 startlump) +{ + UINT16 i; + const char *P_SKIN = "P_SKIN"; + lumpinfo_t *lump_p; + + // scan forward, start at <startlump> + if (startlump < wadfiles[wadid]->numlumps) + { + lump_p = wadfiles[wadid]->lumpinfo + startlump; + for (i = startlump; i < wadfiles[wadid]->numlumps; i++, lump_p++) + if (memcmp(lump_p->name,P_SKIN,6)==0) + return i; + } + return INT16_MAX; // not found +} + +static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, skin_t *skin) +{ + UINT16 newlastlump; + UINT8 sprite2; + + *lump += 1; // start after S_SKIN + *lastlump = W_CheckNumForNamePwad("S_END",wadnum,*lump); // stop at S_END + + // old wadding practices die hard -- stop at S_SKIN (or P_SKIN) or S_START if they come before S_END. + newlastlump = W_CheckForSkinMarkerInPwad(wadnum,*lump); + if (newlastlump < *lastlump) *lastlump = newlastlump; + newlastlump = W_CheckForPatchSkinMarkerInPwad(wadnum,*lump); + if (newlastlump < *lastlump) *lastlump = newlastlump; + newlastlump = W_CheckNumForNamePwad("S_START",wadnum,*lump); + if (newlastlump < *lastlump) *lastlump = newlastlump; + + // ...and let's handle super, too + newlastlump = W_CheckNumForNamePwad("S_SUPER",wadnum,*lump); + if (newlastlump < *lastlump) + { + newlastlump++; + // load all sprite sets we are aware of... for super! + for (sprite2 = 0; sprite2 < free_spr2; sprite2++) + R_AddSingleSpriteDef((spritename = spr2names[sprite2]), &skin->sprites[FF_SPR2SUPER|sprite2], wadnum, newlastlump, *lastlump); + + newlastlump--; + *lastlump = newlastlump; // okay, make the normal sprite set loading end there + } + + // load all sprite sets we are aware of... for normal stuff. + for (sprite2 = 0; sprite2 < free_spr2; sprite2++) + R_AddSingleSpriteDef((spritename = spr2names[sprite2]), &skin->sprites[sprite2], wadnum, *lump, *lastlump); + +} + +// returns whether found appropriate property +static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) +{ + // custom translation table + if (!stricmp(stoken, "startcolor")) + skin->starttranscolor = atoi(value); + +#define FULLPROCESS(field) else if (!stricmp(stoken, #field)) skin->field = get_number(value); + // character type identification + FULLPROCESS(flags) + FULLPROCESS(ability) + FULLPROCESS(ability2) + + FULLPROCESS(thokitem) + FULLPROCESS(spinitem) + FULLPROCESS(revitem) + FULLPROCESS(followitem) +#undef FULLPROCESS + +#define GETFRACBITS(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value)<<FRACBITS; + GETFRACBITS(normalspeed) + GETFRACBITS(runspeed) + + GETFRACBITS(mindash) + GETFRACBITS(maxdash) + GETFRACBITS(actionspd) + + GETFRACBITS(radius) + GETFRACBITS(height) + GETFRACBITS(spinheight) +#undef GETFRACBITS + +#define GETINT(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value); + GETINT(thrustfactor) + GETINT(accelstart) + GETINT(acceleration) +#undef GETINT + +#define GETSKINCOLOR(field) else if (!stricmp(stoken, #field)) skin->field = R_GetColorByName(value); + GETSKINCOLOR(prefcolor) + GETSKINCOLOR(prefoppositecolor) +#undef GETSKINCOLOR + else if (!stricmp(stoken, "supercolor")) + skin->supercolor = R_GetSuperColorByName(value); + +#define GETFLOAT(field) else if (!stricmp(stoken, #field)) skin->field = FLOAT_TO_FIXED(atof(value)); + GETFLOAT(jumpfactor) + GETFLOAT(highresscale) + GETFLOAT(shieldscale) + GETFLOAT(camerascale) +#undef GETFLOAT + +#define GETFLAG(field) else if (!stricmp(stoken, #field)) { \ + strupr(value); \ + if (atoi(value) || value[0] == 'T' || value[0] == 'Y') \ + skin->flags |= (SF_##field); \ + else \ + skin->flags &= ~(SF_##field); \ +} + // parameters for individual character flags + // these are uppercase so they can be concatenated with SF_ + // 1, true, yes are all valid values + GETFLAG(SUPER) + GETFLAG(NOSUPERSPIN) + GETFLAG(NOSPINDASHDUST) + GETFLAG(HIRES) + GETFLAG(NOSKID) + GETFLAG(NOSPEEDADJUST) + GETFLAG(RUNONWATER) + GETFLAG(NOJUMPSPIN) + GETFLAG(NOJUMPDAMAGE) + GETFLAG(STOMPDAMAGE) + GETFLAG(MARIODAMAGE) + GETFLAG(MACHINE) + GETFLAG(DASHMODE) + GETFLAG(FASTEDGE) + GETFLAG(MULTIABILITY) +#undef GETFLAG + + else // let's check if it's a sound, otherwise error out + { + boolean found = false; + sfxenum_t i; + size_t stokenadjust; + + // Remove the prefix. (We need to affect an adjusting variable so that we can print error messages if it's not actually a sound.) + if ((stoken[0] == 'D' || stoken[0] == 'd') && (stoken[1] == 'S' || stoken[1] == 's')) // DS* + stokenadjust = 2; + else // sfx_* + stokenadjust = 4; + + // Remove the prefix. (We can affect this directly since we're not going to use it again.) + if ((value[0] == 'D' || value[0] == 'd') && (value[1] == 'S' || value[1] == 's')) // DS* + value += 2; + else // sfx_* + value += 4; + + // copy name of sounds that are remapped + // for this skin + for (i = 0; i < sfx_skinsoundslot0; i++) + { + if (!S_sfx[i].name) + continue; + if (S_sfx[i].skinsound != -1 + && !stricmp(S_sfx[i].name, + stoken + stokenadjust)) + { + skin->soundsid[S_sfx[i].skinsound] = + S_AddSoundFx(value, S_sfx[i].singularity, S_sfx[i].pitch, true); + found = true; + } + } + return found; + } + return true; +} + // // Find skin sprites, sounds & optional status bar face, & add them // @@ -2595,17 +3028,16 @@ void R_AddSkins(UINT16 wadnum) if (!value) I_Error("R_AddSkins: syntax error in S_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename); + // Some of these can't go in R_ProcessPatchableFields because they have side effects for future lines. + // Others can't go in there because we don't want them to be patchable. if (!stricmp(stoken, "name")) { - // the skin name must uniquely identify a single skin - // I'm lazy so if name is already used I leave the 'skin x' - // default skin name set in Sk_SetDefaultValue - if (R_SkinAvailable(value) == -1) - { + INT32 skinnum = R_SkinAvailable(value); + strlwr(value); + if (skinnum == -1) STRBUFCPY(skin->name, value); - strlwr(skin->name); - } - // I'm not lazy, so if the name is already used I make the name 'namex' + // the skin name must uniquely identify a single skin + // if the name is already used I make the name 'namex' // using the default skin name's number set above else { @@ -2616,11 +3048,9 @@ void R_AddSkins(UINT16 wadnum) "%s%d", value, numskins); value2[stringspace - 1] = '\0'; if (R_SkinAvailable(value2) == -1) - { - STRBUFCPY(skin->name, - value2); - strlwr(skin->name); - } + // I'm lazy so if NEW name is already used I leave the 'skin x' + // default skin name set in Sk_SetDefaultValue + STRBUFCPY(skin->name, value2); Z_Free(value2); } @@ -2629,40 +3059,34 @@ void R_AddSkins(UINT16 wadnum) { STRBUFCPY(skin->realname, skin->name); for (value = skin->realname; *value; value++) + { if (*value == '_') *value = ' '; // turn _ into spaces. + else if (*value == '.') *value = '\x1E'; // turn . into katana dot. + } } if (!hudname) { - STRBUFCPY(skin->hudname, skin->name); + HUDNAMEWRITE(skin->name); strupr(skin->hudname); - for (value = skin->hudname; *value; value++) - if (*value == '_') *value = ' '; // turn _ into spaces. + SYMBOLCONVERT(skin->hudname) } } else if (!stricmp(stoken, "realname")) { // Display name (eg. "Knuckles") realname = true; STRBUFCPY(skin->realname, value); - for (value = skin->realname; *value; value++) - if (*value == '_') *value = ' '; // turn _ into spaces. + SYMBOLCONVERT(skin->realname) if (!hudname) - STRBUFCPY(skin->hudname, skin->realname); + HUDNAMEWRITE(skin->realname); } else if (!stricmp(stoken, "hudname")) { // Life icon name (eg. "K.T.E") hudname = true; - STRBUFCPY(skin->hudname, value); - for (value = skin->hudname; *value; value++) - if (*value == '_') *value = ' '; // turn _ into spaces. + HUDNAMEWRITE(value); + SYMBOLCONVERT(skin->hudname) if (!realname) STRBUFCPY(skin->realname, skin->hudname); } - - else if (!stricmp(stoken, "sprite")) - { - strupr(value); - strncpy(skin->sprite, value, sizeof skin->sprite); - } else if (!stricmp(stoken, "charsel")) { strupr(value); @@ -2681,136 +3105,29 @@ void R_AddSkins(UINT16 wadnum) strupr(value); strncpy(skin->superface, value, sizeof skin->superface); } - -#define FULLPROCESS(field) else if (!stricmp(stoken, #field)) skin->field = get_number(value); - // character type identification - FULLPROCESS(flags) - FULLPROCESS(ability) - FULLPROCESS(ability2) - - FULLPROCESS(thokitem) - FULLPROCESS(spinitem) - FULLPROCESS(revitem) -#undef FULLPROCESS - -#define GETSPEED(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value)<<FRACBITS; - GETSPEED(normalspeed) - GETSPEED(runspeed) - GETSPEED(mindash) - GETSPEED(maxdash) - GETSPEED(actionspd) -#undef GETSPEED - -#define GETINT(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value); - GETINT(thrustfactor) - GETINT(accelstart) - GETINT(acceleration) -#undef GETINT - - // custom translation table - else if (!stricmp(stoken, "startcolor")) - skin->starttranscolor = atoi(value); - - else if (!stricmp(stoken, "prefcolor")) - skin->prefcolor = R_GetColorByName(value); - else if (!stricmp(stoken, "jumpfactor")) - skin->jumpfactor = FLOAT_TO_FIXED(atof(value)); - else if (!stricmp(stoken, "highresscale")) - skin->highresscale = FLOAT_TO_FIXED(atof(value)); - else + else if (!stricmp(stoken, "availability")) { - INT32 found = false; - sfxenum_t i; - // copy name of sounds that are remapped - // for this skin - for (i = 0; i < sfx_skinsoundslot0; i++) - { - if (!S_sfx[i].name) - continue; - if (S_sfx[i].skinsound != -1 - && !stricmp(S_sfx[i].name, - stoken + 2)) - { - skin->soundsid[S_sfx[i].skinsound] = - S_AddSoundFx(value+2, S_sfx[i].singularity, S_sfx[i].pitch, true); - found = true; - } - } - if (!found) - CONS_Debug(DBG_SETUP, "R_AddSkins: Unknown keyword '%s' in S_SKIN lump# %d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename); + skin->availability = atoi(value); + if (skin->availability >= MAXUNLOCKABLES) + skin->availability = 0; + if (skin->availability) + STRBUFCPY(unlockables[skin->availability - 1].name, skin->realname); } + else if (!R_ProcessPatchableFields(skin, stoken, value)) + CONS_Debug(DBG_SETUP, "R_AddSkins: Unknown keyword '%s' in S_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename); + next_token: stoken = strtok(NULL, "\r\n= "); } free(buf2); - lump++; // if no sprite defined use spirte just after this one - if (skin->sprite[0] == '\0') - { - const char *csprname = W_CheckNameForNumPwad(wadnum, lump); - - // skip to end of this skin's frames - lastlump = lump; - while (W_CheckNameForNumPwad(wadnum,lastlump) && memcmp(W_CheckNameForNumPwad(wadnum, lastlump),csprname,4)==0) - lastlump++; - // allocate (or replace) sprite frames, and set spritedef - R_AddSingleSpriteDef(csprname, &skin->spritedef, wadnum, lump, lastlump); - } - else - { - // search in the normal sprite tables - size_t name; - boolean found = false; - const char *sprname = skin->sprite; - for (name = 0;sprnames[name][0] != '\0';name++) - if (strncmp(sprnames[name], sprname, 4) == 0) - { - found = true; - skin->spritedef = sprites[name]; - } - - // not found so make a new one - // go through the entire current wad looking for our sprite - // don't just mass add anything beginning with our four letters. - // "HOODFACE" is not a sprite name. - if (!found) - { - UINT16 localllump = 0, lstart = UINT16_MAX, lend = UINT16_MAX; - const char *lname; - - while ((lname = W_CheckNameForNumPwad(wadnum,localllump))) - { - // If this is a valid sprite... - if (!memcmp(lname,sprname,4) && lname[4] && lname[5] && lname[5] >= '0' && lname[5] <= '8') - { - if (lstart == UINT16_MAX) - lstart = localllump; - // If already set do nothing - } - else - { - if (lstart != UINT16_MAX) - { - lend = localllump; - break; - } - // If not already set do nothing - } - ++localllump; - } - - R_AddSingleSpriteDef(sprname, &skin->spritedef, wadnum, lstart, lend); - } - - // I don't particularly care about skipping to the end of the used frames. - // We could be using frames from ANYWHERE in the current WAD file, including - // right before us, which is a terrible idea. - // So just let the function in the while loop take care of it for us. - } + // Add sprites + R_LoadSkinSprites(wadnum, &lump, &lastlump, skin); R_FlushTranslationColormapCache(); - CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name); + if (!skin->availability) // Safe to print... + CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name); #ifdef SKINVALUES skin_cons_t[numskins].value = numskins; skin_cons_t[numskins].strvalue = skin->name; @@ -2829,48 +3146,124 @@ next_token: return; } -#ifdef DELFILE -void R_DelSkins(UINT16 wadnum) +// +// Patch skin sprites +// +void R_PatchSkins(UINT16 wadnum) { UINT16 lump, lastlump = 0; - while ((lump = W_CheckForSkinMarkerInPwad(wadnum, lastlump)) != INT16_MAX) + char *buf; + char *buf2; + char *stoken; + char *value; + size_t size; + skin_t *skin; + boolean noskincomplain, realname, hudname; + + // + // search for all skin patch markers in pwad + // + + while ((lump = W_CheckForPatchSkinMarkerInPwad(wadnum, lastlump)) != INT16_MAX) { - if (skins[numskins].wadnum != wadnum) - break; - numskins--; - ST_UnLoadFaceGraphics(numskins); // only used by DELFILE - if (skins[numskins].sprite[0] != '\0') - { - const char *csprname = W_CheckNameForNumPwad(wadnum, lump); - - // skip to end of this skin's frames - lastlump = lump; - while (W_CheckNameForNumPwad(wadnum,lastlump) && memcmp(W_CheckNameForNumPwad(wadnum, lastlump),csprname,4)==0) - lastlump++; - // allocate (or replace) sprite frames, and set spritedef - R_DelSingleSpriteDef(csprname, &skins[numskins].spritedef, wadnum, lump, lastlump); - } - else + INT32 skinnum = 0; + + // advance by default + lastlump = lump + 1; + + buf = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE); + size = W_LumpLengthPwad(wadnum, lump); + + // for strtok + buf2 = malloc(size+1); + if (!buf2) + I_Error("R_PatchSkins: No more free memory\n"); + M_Memcpy(buf2,buf,size); + buf2[size] = '\0'; + + skin = NULL; + noskincomplain = realname = hudname = 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) + */ + + stoken = strtok(buf2, "\r\n= "); + while (stoken) { - // search in the normal sprite tables - size_t name; - boolean found = false; - const char *sprname = skins[numskins].sprite; - for (name = 0;sprnames[name][0] != '\0';name++) - if (strcmp(sprnames[name], sprname) == 0) + if ((stoken[0] == '/' && stoken[1] == '/') + || (stoken[0] == '#'))// skip comments + { + stoken = strtok(NULL, "\r\n"); // skip end of line + goto next_token; // find the real next token + } + + value = strtok(NULL, "\r\n= "); + + if (!value) + I_Error("R_PatchSkins: syntax error in P_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename); + + if (!skin) // Get the name! + { + if (!stricmp(stoken, "name")) { - found = true; - skins[numskins].spritedef = sprites[name]; + strlwr(value); + skinnum = R_SkinAvailable(value); + if (skinnum != -1) + skin = &skins[skinnum]; + else + { + CONS_Debug(DBG_SETUP, "R_PatchSkins: unknown skin name in P_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename); + noskincomplain = true; + } + } + } + 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")) + { // Display name (eg. "Knuckles") + realname = true; + STRBUFCPY(skin->realname, value); + SYMBOLCONVERT(skin->realname) + if (!hudname) + HUDNAMEWRITE(skin->realname); + } + else if (!stricmp(stoken, "hudname")) + { // Life icon name (eg. "K.T.E") + hudname = true; + HUDNAMEWRITE(value); + SYMBOLCONVERT(skin->hudname) + if (!realname) + STRBUFCPY(skin->realname, skin->hudname); } + else if (!R_ProcessPatchableFields(skin, stoken, value)) + CONS_Debug(DBG_SETUP, "R_PatchSkins: Unknown keyword '%s' in P_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename); + } + + if (!skin) + break; - // not found so make a new one - if (!found) - R_DelSingleSpriteDef(sprname, &skins[numskins].spritedef, wadnum, 0, INT16_MAX); +next_token: + stoken = strtok(NULL, "\r\n= "); + } + free(buf2); - while (W_CheckNameForNumPwad(wadnum,lastlump) && memcmp(W_CheckNameForNumPwad(wadnum, lastlump),sprname,4)==0) - lastlump++; + if (!skin) // Didn't include a name parameter? What a waste. + { + if (!noskincomplain) + CONS_Debug(DBG_SETUP, "R_PatchSkins: no skin name given in P_SKIN lump #%d (WAD %s)\n", lump, wadfiles[wadnum]->filename); + continue; } - CONS_Printf(M_GetText("Removed skin '%s'\n"), skins[numskins].name); + + // Patch sprites + R_LoadSkinSprites(wadnum, &lump, &lastlump, skin); + + if (!skin->availability) // Safe to print... + CONS_Printf(M_GetText("Patched skin '%s'\n"), skin->name); } + return; } -#endif + +#undef HUDNAMEWRITE +#undef SYMBOLCONVERT diff --git a/src/r_things.h b/src/r_things.h index 2823c3894e1b40b98b9c4310b8eb8a074e40036d..d287df8328293374265873a9d5e1602a3181f60f 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -16,6 +16,11 @@ #include "sounds.h" #include "r_plane.h" +#include "r_portal.h" + +// "Left" and "Right" character symbols for additional rotation functionality +#define ROT_L ('L' - '0') +#define ROT_R ('R' - '0') // number of sprite lumps for spritewidth,offset,topoffset lookup tables // Fab: this is a hack : should allocate the lookup tables per sprite @@ -40,22 +45,31 @@ extern fixed_t windowtop; extern fixed_t windowbottom; void R_DrawMaskedColumn(column_t *column); -void R_SortVisSprites(void); +void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight); //faB: find sprites in wadfile, replace existing, add new ones // (only sprites from namelist are added or replaced) void R_AddSpriteDefs(UINT16 wadnum); -#ifdef DELFILE -void R_DelSpriteDefs(UINT16 wadnum); -#endif - //SoM: 6/5/2000: Light sprites correctly! void R_AddSprites(sector_t *sec, INT32 lightlevel); void R_InitSprites(void); void R_ClearSprites(void); -void R_ClipSprites(void); -void R_DrawMasked(void); +void R_ClipSprites(drawseg_t* dsstart, portal_t* portal); + +/** Used to count the amount of masked elements + * per portal to later group them in separate + * drawnode lists. + */ +typedef struct +{ + size_t drawsegs[2]; + size_t vissprites[2]; + fixed_t viewx, viewy, viewz; /**< View z stored at the time of the BSP traversal for the view/portal. Masked sorting/drawing needs it. */ + sector_t* viewsector; +} maskcount_t; + +void R_DrawMasked(maskcount_t* masks, UINT8 nummasks); // ----------- // SKINS STUFF @@ -64,13 +78,12 @@ void R_DrawMasked(void); // should be all lowercase!! S_SKIN processing does a strlwr #define DEFAULTSKIN "sonic" #define DEFAULTSKIN2 "tails" // secondary player +#define DEFAULTNIGHTSSKIN 0 typedef struct { char name[SKINNAMESIZE+1]; // INT16 descriptive name of the skin - spritedef_t spritedef; UINT16 wadnum; - char sprite[4]; // Sprite name, if seperated from S_SKIN. skinflags_t flags; char realname[SKINNAMESIZE+1]; // Display name for level completion. @@ -82,6 +95,7 @@ typedef struct INT32 thokitem; INT32 spinitem; INT32 revitem; + INT32 followitem; fixed_t actionspd; fixed_t mindash; fixed_t maxdash; @@ -95,13 +109,27 @@ typedef struct fixed_t jumpfactor; // multiple of standard jump height + fixed_t radius; // Bounding box changes. + fixed_t height; + fixed_t spinheight; + + fixed_t shieldscale; // no change to bounding box, but helps set the shield's sprite size + fixed_t camerascale; + // Definable color translation table UINT8 starttranscolor; UINT8 prefcolor; + UINT8 supercolor; + UINT8 prefoppositecolor; // if 0 use tables instead + fixed_t highresscale; // scale of highres, default is 0.5 // specific sounds per skin sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table + + spritedef_t sprites[NUMPLAYERSPRITES*2]; // contains super versions too + + UINT8 availability; // lock? } skin_t; // ----------- @@ -109,9 +137,19 @@ typedef struct // ----------- typedef enum { + // actual cuts SC_NONE = 0, SC_TOP = 1, - SC_BOTTOM = 2 + SC_BOTTOM = 1<<1, + // other flags + SC_PRECIP = 1<<2, + SC_LINKDRAW = 1<<3, + SC_FULLBRIGHT = 1<<4, + SC_VFLIP = 1<<5, + SC_ISSCALED = 1>>6, + // masks + SC_CUTMASK = SC_TOP|SC_BOTTOM, + SC_FLAGMASK = ~SC_CUTMASK } spritecut_e; // A vissprite_t is a thing that will be drawn during a refresh, @@ -122,6 +160,9 @@ typedef struct vissprite_s struct vissprite_s *prev; struct vissprite_s *next; + // Bonus linkdraw pointer. + struct vissprite_s *linkdraw; + mobj_t *mobj; // for easy access INT32 x1, x2; @@ -131,7 +172,8 @@ typedef struct vissprite_s fixed_t pz, pzt; // physical bottom/top for sorting with 3D floors fixed_t startfrac; // horizontal position of x1 - fixed_t scale; + fixed_t scale, sortscale; // sortscale only differs from scale for paper sprites and MF2_LINKDRAW + fixed_t scalestep; // only for paper sprites, 0 otherwise fixed_t xiscale; // negative if flipped fixed_t texturemid; @@ -159,9 +201,6 @@ typedef struct vissprite_s INT16 clipbot[MAXVIDWIDTH], cliptop[MAXVIDWIDTH]; - boolean precip; - boolean vflip; // Flip vertically - boolean isScaled; INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing } vissprite_t; @@ -181,15 +220,17 @@ typedef struct drawnode_s extern INT32 numskins; extern skin_t skins[MAXSKINS]; +extern UINT32 visspritecount; void SetPlayerSkin(INT32 playernum,const char *skinname); void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002 +boolean R_SkinUsable(INT32 playernum, INT32 skinnum); +UINT32 R_GetSkinAvailabilities(void); INT32 R_SkinAvailable(const char *name); +void R_PatchSkins(UINT16 wadnum); void R_AddSkins(UINT16 wadnum); -#ifdef DELFILE -void R_DelSkins(UINT16 wadnum); -#endif +UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player); void R_InitDrawNodes(void); @@ -204,7 +245,7 @@ char *GetPlayerFacePic(INT32 skinnum); // Future: [[ ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!@ ]] FUNCMATH FUNCINLINE static ATTRINLINE char R_Frame2Char(UINT8 frame) { -#if 1 // 2.1 compat +#if 0 // 2.1 compat return 'A' + frame; #else if (frame < 26) return 'A' + frame; @@ -218,7 +259,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE char R_Frame2Char(UINT8 frame) FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn) { -#if 1 // 2.1 compat +#if 0 // 2.1 compat if (cn == '+') return '\\' - 'A'; // PK3 can't use backslash, so use + instead return cn - 'A'; #else @@ -231,4 +272,9 @@ FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn) #endif } +FUNCMATH FUNCINLINE static ATTRINLINE boolean R_ValidSpriteAngle(UINT8 rotation) +{ + return ((rotation <= 8) || (rotation == ROT_L) || (rotation == ROT_R)); +} + #endif //__R_THINGS__ diff --git a/src/s_sound.c b/src/s_sound.c index acb7dcbbe3e041abbf43f1187fe0bace07873032..2db8392d7484e3ef24838b0713bb81c1a63e5eef 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -36,6 +36,7 @@ extern INT32 msg_id; #include "d_main.h" #include "r_sky.h" // skyflatnum #include "p_local.h" // camera info +#include "fastcmp.h" #include "m_misc.h" // for tunes command #if defined(HAVE_BLUA) && defined(HAVE_LUA_MUSICPLUS) @@ -59,6 +60,8 @@ static void GameMIDIMusic_OnChange(void); static void GameSounds_OnChange(void); static void GameDigiMusic_OnChange(void); +static void ModFilter_OnChange(void); + // commands for music and sound servers #ifdef MUSSERV consvar_t musserver_cmd = {"musserver_cmd", "musserver", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -73,12 +76,8 @@ consvar_t sndserver_arg = {"sndserver_arg", "-quiet", CV_SAVE, NULL, 0, NULL, NU #define SURROUND #endif -#if defined (_WIN32_WCE) || defined (DC) || defined(GP2X) -consvar_t cv_samplerate = {"samplerate", "11025", 0, CV_Unsigned, NULL, 11025, NULL, NULL, 0, 0, NULL}; //Alam: For easy hacking? -#elif defined(_PSP) || defined(_WINDOWS) +#ifdef _WINDOWS consvar_t cv_samplerate = {"samplerate", "44100", 0, CV_Unsigned, NULL, 44100, NULL, NULL, 0, 0, NULL}; //Alam: For easy hacking? -#elif defined(_WII) -consvar_t cv_samplerate = {"samplerate", "32000", 0, CV_Unsigned, NULL, 32000, NULL, NULL, 0, 0, NULL}; //Alam: For easy hacking? #else consvar_t cv_samplerate = {"samplerate", "22050", 0, CV_Unsigned, NULL, 22050, NULL, NULL, 0, 0, NULL}; //Alam: For easy hacking? #endif @@ -93,12 +92,18 @@ static consvar_t precachesound = {"precachesound", "Off", CV_SAVE, CV_OnOff, NUL consvar_t cv_soundvolume = {"soundvolume", "18", CV_SAVE, soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_digmusicvolume = {"digmusicvolume", "18", CV_SAVE, soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_midimusicvolume = {"midimusicvolume", "18", CV_SAVE, soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + +static void Captioning_OnChange(void) +{ + S_ResetCaptions(); + if (cv_closedcaptioning.value) + S_StartSound(NULL, sfx_menu1); +} + +consvar_t cv_closedcaptioning = {"closedcaptioning", "Off", CV_SAVE|CV_CALL, CV_OnOff, Captioning_OnChange, 0, NULL, NULL, 0, 0, NULL}; + // number of channels available -#if defined (_WIN32_WCE) || defined (DC) || defined (PSP) || defined(GP2X) -consvar_t cv_numChannels = {"snd_channels", "8", CV_SAVE|CV_CALL, CV_Unsigned, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL}; -#else consvar_t cv_numChannels = {"snd_channels", "32", CV_SAVE|CV_CALL, CV_Unsigned, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL}; -#endif static consvar_t surround = {"surround", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -108,6 +113,11 @@ consvar_t cv_gamedigimusic = {"digimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_O consvar_t cv_gamemidimusic = {"midimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameMIDIMusic_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_gamesounds = {"sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameSounds_OnChange, 0, NULL, NULL, 0, 0, NULL}; +#ifdef HAVE_OPENMPT +static CV_PossibleValue_t interpolationfilter_cons_t[] = {{0, "Default"}, {1, "None"}, {2, "Linear"}, {4, "Cubic"}, {8, "Windowed sinc"}, {0, NULL}}; +consvar_t cv_modfilter = {"modfilter", "0", CV_SAVE|CV_CALL, interpolationfilter_cons_t, ModFilter_OnChange, 0, NULL, NULL, 0, 0, NULL}; +#endif + #define S_MAX_VOLUME 127 // when to clip out sounds @@ -142,23 +152,24 @@ consvar_t cv_gamesounds = {"sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, // percent attenuation from front to back #define S_IFRACVOL 30 -typedef struct -{ - // sound information (if null, channel avail.) - sfxinfo_t *sfxinfo; - - // origin of sound - const void *origin; - - // handle of the sound being played - INT32 handle; - -} channel_t; - // the set of channels available static channel_t *channels = NULL; static INT32 numofchannels = 0; +caption_t closedcaptions[NUMCAPTIONS]; + +void S_ResetCaptions(void) +{ + UINT8 i; + for (i = 0; i < NUMCAPTIONS; i++) + { + closedcaptions[i].c = NULL; + closedcaptions[i].s = NULL; + closedcaptions[i].t = 0; + closedcaptions[i].b = 0; + } +} + // // Internals. // @@ -265,11 +276,13 @@ void S_RegisterSoundStuff(void) CV_RegisterVar(&cv_gamesounds); CV_RegisterVar(&cv_gamedigimusic); CV_RegisterVar(&cv_gamemidimusic); +#ifdef HAVE_OPENMPT + CV_RegisterVar(&cv_modfilter); +#endif COM_AddCommand("tunes", Command_Tunes_f); COM_AddCommand("restartaudio", Command_RestartAudio_f); - #if defined (macintosh) && !defined (HAVE_SDL) // mp3 playlist stuff { INT32 i; @@ -323,6 +336,8 @@ static void SetChannelsNum(void) // Free all channels for use for (i = 0; i < numofchannels; i++) channels[i].sfxinfo = 0; + + S_ResetCaptions(); } @@ -365,6 +380,8 @@ void S_StopSounds(void) for (cnum = 0; cnum < numofchannels; cnum++) if (channels[cnum].sfxinfo) S_StopChannel(cnum); + + S_ResetCaptions(); } void S_StopSoundByID(void *origin, sfxenum_t sfx_id) @@ -413,6 +430,92 @@ void S_StopSoundByNum(sfxenum_t sfxnum) } } +void S_StartCaption(sfxenum_t sfx_id, INT32 cnum, UINT16 lifespan) +{ + UINT8 i, set, moveup, start; + boolean same = false; + sfxinfo_t *sfx; + + if (!cv_closedcaptioning.value) // no captions at all + return; + + // check for bogus sound # + // I_Assert(sfx_id >= 0); -- allowing sfx_None; this shouldn't be allowed directly if S_StartCaption is ever exposed to Lua by itself + I_Assert(sfx_id < NUMSFX); + + sfx = &S_sfx[sfx_id]; + + if (sfx->caption[0] == '/') // no caption for this one + return; + + start = ((closedcaptions[0].s && (closedcaptions[0].s-S_sfx == sfx_None)) ? 1 : 0); + + if (sfx_id) + { + for (i = start; i < (set = NUMCAPTIONS-1); i++) + { + same = ((sfx == closedcaptions[i].s) || (closedcaptions[i].s && fastcmp(sfx->caption, closedcaptions[i].s->caption))); + if (same) + { + set = i; + break; + } + } + } + else + { + set = 0; + same = (closedcaptions[0].s == sfx); + } + + moveup = 255; + + if (!same) + { + for (i = start; i < set; i++) + { + if (!(closedcaptions[i].c || closedcaptions[i].s) || (sfx->priority >= closedcaptions[i].s->priority)) + { + set = i; + if (closedcaptions[i].s && (sfx->priority >= closedcaptions[i].s->priority)) + moveup = i; + break; + } + } + for (i = NUMCAPTIONS-1; i > set; i--) + { + if (sfx == closedcaptions[i].s) + { + closedcaptions[i].c = NULL; + closedcaptions[i].s = NULL; + closedcaptions[i].t = 0; + closedcaptions[i].b = 0; + } + } + } + + if (moveup != 255) + { + for (i = moveup; i < NUMCAPTIONS-1; i++) + { + if (!(closedcaptions[i].c || closedcaptions[i].s)) + break; + } + for (; i > set; i--) + { + closedcaptions[i].c = closedcaptions[i-1].c; + closedcaptions[i].s = closedcaptions[i-1].s; + closedcaptions[i].t = closedcaptions[i-1].t; + closedcaptions[i].b = closedcaptions[i-1].b; + } + } + + closedcaptions[set].c = ((cnum == -1) ? NULL : &channels[cnum]); + closedcaptions[set].s = sfx; + closedcaptions[set].t = lifespan; + closedcaptions[set].b = 2; // bob +} + void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) { INT32 sep, pitch, priority, cnum; @@ -553,6 +656,9 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) sep = (~sep) & 255; #endif + // Handle closed caption input. + S_StartCaption(sfx_id, cnum, MAXCAPTIONTICS); + // Assigns the handle to one of the channels in the // mix/output buffer. channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum); @@ -603,6 +709,9 @@ dontplay: sep = (~sep) & 255; #endif + // Handle closed caption input. + S_StartCaption(sfx_id, cnum, MAXCAPTIONTICS); + // Assigns the handle to one of the channels in the // mix/output buffer. channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum); @@ -624,6 +733,7 @@ void S_StartSound(const void *origin, sfxenum_t sfx_id) // sfx_id = sfx_mario8; // break; case sfx_thok: + case sfx_wepfir: sfx_id = sfx_mario7; break; case sfx_pop: @@ -633,6 +743,14 @@ void S_StartSound(const void *origin, sfxenum_t sfx_id) sfx_id = sfx_mario6; break; case sfx_shield: + case sfx_wirlsg: + case sfx_forcsg: + case sfx_elemsg: + case sfx_armasg: + case sfx_attrsg: + case sfx_s3k3e: + case sfx_s3k3f: + case sfx_s3k41: sfx_id = sfx_mario3; break; case sfx_itemup: @@ -710,6 +828,7 @@ static INT32 actualmidimusicvolume; void S_UpdateSounds(void) { INT32 audible, cnum, volume, sep, pitch; + UINT8 i; channel_t *c; listener_t listener; @@ -737,9 +856,7 @@ void S_UpdateSounds(void) I_UpdateMumble(NULL, listener); #endif - // Stop cutting FMOD out. WE'RE sick of it. - I_UpdateSound(); - return; + goto notinlevel; } if (dedicated || sound_disabled) @@ -778,8 +895,7 @@ void S_UpdateSounds(void) if (hws_mode != HWS_DEFAULT_MODE) { HW3S_UpdateSources(); - I_UpdateSound(); - return; + goto notinlevel; } #endif @@ -867,7 +983,32 @@ void S_UpdateSounds(void) } } +notinlevel: I_UpdateSound(); + + { + boolean gamestopped = (paused || P_AutoPause()); + for (i = 0; i < NUMCAPTIONS; i++) // update captions + { + if (!closedcaptions[i].s) + continue; + + if (i == 0 && (closedcaptions[0].s-S_sfx == sfx_None) && gamestopped) + continue; + + if (!(--closedcaptions[i].t)) + { + closedcaptions[i].c = NULL; + closedcaptions[i].s = NULL; + } + else if (closedcaptions[i].c && !I_SoundIsPlaying(closedcaptions[i].c->handle)) + { + closedcaptions[i].c = NULL; + if (closedcaptions[i].t > CAPTIONFADETICS) + closedcaptions[i].t = CAPTIONFADETICS; + } + } + } } void S_SetSfxVolume(INT32 volume) @@ -1461,10 +1602,6 @@ void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32 { char newmusic[7]; -#if defined (DC) || defined (_WIN32_WCE) || defined (PSP) || defined(GP2X) - S_ClearSfx(); -#endif - if (S_MusicDisabled()) return; @@ -1541,6 +1678,12 @@ void S_StopMusic(void) S_SpeedMusic(1.0f); I_StopSong(); S_UnloadMusic(); // for now, stopping also means you unload the song + + if (cv_closedcaptioning.value) + { + if (closedcaptions[0].s-S_sfx == sfx_None) + closedcaptions[0].t = CAPTIONFADETICS; + } } // @@ -1777,7 +1920,7 @@ void GameDigiMusic_OnChange(void) if (Playing()) P_RestoreMusic(&players[consoleplayer]); else - S_ChangeMusicInternal("lclear", false); + S_ChangeMusicInternal("_clear", false); } else { @@ -1818,7 +1961,7 @@ void GameMIDIMusic_OnChange(void) if (Playing()) P_RestoreMusic(&players[consoleplayer]); else - S_ChangeMusicInternal("lclear", false); + S_ChangeMusicInternal("_clear", false); } else { @@ -1844,3 +1987,9 @@ void GameMIDIMusic_OnChange(void) } } } + +void ModFilter_OnChange(void) +{ + if (openmpt_mhandle) + openmpt_module_set_render_param(openmpt_mhandle, OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH, cv_modfilter.value); +} \ No newline at end of file diff --git a/src/s_sound.h b/src/s_sound.h index 157b8b1cc191e0c0a233729b87e8c2336e5eac8c..c17a4cf48d34c82f58ab0ae0a7aaeef8e8fb37a5 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -20,17 +20,26 @@ #include "command.h" #include "tables.h" // angle_t +#ifdef HAVE_OPENMPT +#include "libopenmpt/libopenmpt.h" +openmpt_module *openmpt_mhandle; +#endif + // mask used to indicate sound origin is player item pickup #define PICKUP_SOUND 0x8000 extern consvar_t stereoreverse; -extern consvar_t cv_soundvolume, cv_digmusicvolume, cv_midimusicvolume; +extern consvar_t cv_soundvolume, cv_closedcaptioning, cv_digmusicvolume, cv_midimusicvolume; extern consvar_t cv_numChannels; extern consvar_t cv_resetmusic; extern consvar_t cv_gamedigimusic; extern consvar_t cv_gamemidimusic; extern consvar_t cv_gamesounds; +#ifdef HAVE_OPENMPT +extern consvar_t cv_modfilter; +#endif + #ifdef SNDSERV extern consvar_t sndserver_cmd, sndserver_arg; #endif @@ -69,6 +78,34 @@ typedef struct { angle_t angle; } listener_t; +typedef struct +{ + // sound information (if null, channel avail.) + sfxinfo_t *sfxinfo; + + // origin of sound + const void *origin; + + // handle of the sound being played + INT32 handle; + +} channel_t; + +typedef struct { + channel_t *c; + sfxinfo_t *s; + UINT16 t; + UINT8 b; +} caption_t; + +#define NUMCAPTIONS 8 +#define MAXCAPTIONTICS (2*TICRATE) +#define CAPTIONFADETICS 20 + +extern caption_t closedcaptions[NUMCAPTIONS]; +void S_StartCaption(sfxenum_t sfx_id, INT32 cnum, UINT16 lifespan); +void S_ResetCaptions(void); + // register sound vars and commands at game startup void S_RegisterSoundStuff(void); diff --git a/src/screen.c b/src/screen.c index af6aed03c0c78abef969d2a87e3cd11a27c42609..ac7878c4a8f8d82061007ac754b51f88d06cb656 100644 --- a/src/screen.c +++ b/src/screen.c @@ -28,6 +28,10 @@ #include "d_main.h" #include "d_clisrv.h" #include "f_finale.h" +#include "i_sound.h" // closed captions +#include "s_sound.h" // ditto +#include "g_game.h" // ditto +#include "p_local.h" // P_AutoPause() #if defined (USEASM) && !defined (NORUSEASM)//&& (!defined (_MSC_VER) || (_MSC_VER <= 1200)) @@ -60,15 +64,9 @@ INT32 setmodeneeded; //video mode change needed if > 0 (the mode number to set + static CV_PossibleValue_t scr_depth_cons_t[] = {{8, "8 bits"}, {16, "16 bits"}, {24, "24 bits"}, {32, "32 bits"}, {0, NULL}}; //added : 03-02-98: default screen mode, as loaded/saved in config -#ifdef WII -consvar_t cv_scr_width = {"scr_width", "640", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_scr_height = {"scr_height", "480", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#else consvar_t cv_scr_width = {"scr_width", "1280", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_scr_height = {"scr_height", "800", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static void SCR_ChangeFullscreen (void); @@ -162,10 +160,13 @@ void SCR_SetMode(void) }*/ else I_Error("unknown bytes per pixel mode %d\n", vid.bpp); -/*#if !defined (DC) && !defined (WII) +/* if (SCR_IsAspectCorrect(vid.width, vid.height)) CONS_Alert(CONS_WARNING, M_GetText("Resolution is not aspect-correct!\nUse a multiple of %dx%d\n"), BASEVIDWIDTH, BASEVIDHEIGHT); -#endif*/ +*/ + + wallcolfunc = walldrawerfunc; + // set the apprpriate drawer for the sky (tall or INT16) setmodeneeded = 0; } @@ -404,6 +405,7 @@ void SCR_DisplayTicRate(void) tic_t ontic = I_GetTime(); tic_t totaltics = 0; INT32 ticcntcolor = 0; + const INT32 h = vid.height-(8*vid.dupy); for (i = lasttic + 1; i < TICRATE+lasttic && i < ontic; ++i) fpsgraph[i % TICRATE] = false; @@ -417,10 +419,65 @@ void SCR_DisplayTicRate(void) if (totaltics <= TICRATE/2) ticcntcolor = V_REDMAP; else if (totaltics == TICRATE) ticcntcolor = V_GREENMAP; - V_DrawString(vid.width-(24*vid.dupx), vid.height-(16*vid.dupy), - V_YELLOWMAP|V_NOSCALESTART, "FPS"); - V_DrawString(vid.width-(40*vid.dupx), vid.height-( 8*vid.dupy), + V_DrawString(vid.width-(72*vid.dupx), h, + V_YELLOWMAP|V_NOSCALESTART, "FPS:"); + V_DrawString(vid.width-(40*vid.dupx), h, ticcntcolor|V_NOSCALESTART, va("%02d/%02u", totaltics, TICRATE)); lasttic = ontic; } + +void SCR_ClosedCaptions(void) +{ + UINT8 i; + boolean gamestopped = (paused || P_AutoPause()); + INT32 basey = BASEVIDHEIGHT; + + if (gamestate != wipegamestate) + return; + + if (gamestate == GS_LEVEL) + { + if (splitscreen) + basey -= 8; + else if ((modeattacking == ATTACKING_NIGHTS) + || (!(maptol & TOL_NIGHTS) + && ((cv_powerupdisplay.value == 2) // "Always" + || (cv_powerupdisplay.value == 1 && !camera.chase)))) // "First-person only" + basey -= 16; + } + + for (i = 0; i < NUMCAPTIONS; i++) + { + INT32 flags, y; + char dot; + boolean music; + + if (!closedcaptions[i].s) + continue; + + music = (closedcaptions[i].s-S_sfx == sfx_None); + + if (music && !gamestopped && (closedcaptions[i].t < flashingtics) && (closedcaptions[i].t & 1)) + continue; + + flags = V_SNAPTORIGHT|V_SNAPTOBOTTOM|V_ALLOWLOWERCASE; + y = basey-((i + 2)*10); + + if (closedcaptions[i].b) + y -= (closedcaptions[i].b--)*vid.dupy; + + if (closedcaptions[i].t < CAPTIONFADETICS) + flags |= (((CAPTIONFADETICS-closedcaptions[i].t)/2)*V_10TRANS); + + if (music) + dot = '\x19'; + else if (closedcaptions[i].c && closedcaptions[i].c->origin) + dot = '\x1E'; + else + dot = ' '; + + V_DrawRightAlignedString(BASEVIDWIDTH - 20, y, flags, + va("%c [%s]", dot, (closedcaptions[i].s->caption[0] ? closedcaptions[i].s->caption : closedcaptions[i].s->name))); + } +} diff --git a/src/screen.h b/src/screen.h index 9ad254d3fcaca0b9dd3eded342ac4937db505e32..7aa6fdb638a1f68fa70373bb258777f71b701282 100644 --- a/src/screen.h +++ b/src/screen.h @@ -15,20 +15,16 @@ #include "command.h" -#if (defined (_WIN32) || defined (_WIN32_WCE)) && !defined (__CYGWIN__) && !defined (_XBOX) -#if defined (_WIN32_WCE) && defined (__GNUC__) -#include <sys/wcetypes.h> -#else +#if defined (_WIN32) && !defined (__CYGWIN__) #define RPC_NO_WINDOWS_H #include <windows.h> -#endif #define DNWH HWND #else #define DNWH void * // unused in DOS version #endif // quickhack for V_Init()... to be cleaned up -#if defined (DC) || defined (_WIN32_WCE) || defined (PSP) || defined (NOPOSTPROCESSING) +#ifdef NOPOSTPROCESSING #define NUMSCREENS 2 #else #define NUMSCREENS 5 @@ -43,15 +39,9 @@ // we try to re-allocate a minimum of buffers for stability of the memory, // so all the small-enough tables based on screen size, are allocated once // and for all at the maximum size. -#if defined (_WIN32_WCE) || defined (DC) || defined (_PSP) || defined (_NDS) +#if defined (_WIN32_WCE) #define MAXVIDWIDTH 320 #define MAXVIDHEIGHT 200 -#elif defined (GP2X) -#define MAXVIDWIDTH 320 //720 -#define MAXVIDHEIGHT 240 //576 -#elif defined (WII) // Wii, VGA/640x480 -#define MAXVIDWIDTH 640 -#define MAXVIDHEIGHT 480 #else #define MAXVIDWIDTH 1920 // don't set this too high because actually #define MAXVIDHEIGHT 1200 // lots of tables are allocated with the MAX size. @@ -110,7 +100,7 @@ typedef struct vmode_s INT32 windowed; // if true this is a windowed mode INT32 numpages; vesa_extra_t *pextradata; // vesa mode extra data -#if defined (_WIN32) && !defined (_XBOX) +#ifdef _WIN32 INT32 (WINAPI *setmode)(viddef_t *lvid, struct vmode_s *pcurrentmode); #else INT32 (*setmode)(viddef_t *lvid, struct vmode_s *pcurrentmode); @@ -180,5 +170,6 @@ FUNCMATH boolean SCR_IsAspectCorrect(INT32 width, INT32 height); // move out to main code for consistency void SCR_DisplayTicRate(void); +void SCR_ClosedCaptions(void); #undef DNWH #endif //__SCREEN_H__ diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt index de2157055839476d8599db462d22e2d7cdeb1b20..f1aa135b9eafd520e0700835b9c509898f22bef3 100644 --- a/src/sdl/CMakeLists.txt +++ b/src/sdl/CMakeLists.txt @@ -149,6 +149,7 @@ if(${SDL2_FOUND}) SDL2 SDL2_mixer ${GME_LIBRARIES} + ${OPENMPT_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${OPENGL_LIBRARIES} @@ -159,6 +160,7 @@ if(${SDL2_FOUND}) ${SDL2_LIBRARIES} ${SDL2_MIXER_LIBRARIES} ${GME_LIBRARIES} + ${OPENMPT_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${OPENGL_LIBRARIES} @@ -238,6 +240,7 @@ if(${SDL2_FOUND}) ${SDL2_INCLUDE_DIRS} ${SDL2_MIXER_INCLUDE_DIRS} ${GME_INCLUDE_DIRS} + ${OPENMPT_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIRS} @@ -284,12 +287,14 @@ if(${SDL2_FOUND}) HINTS ${CMAKE_SOURCE_DIR}/libs/dll-binaries/x86_64 HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2/x86_64-w64-mingw32/bin HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2_mixer/x86_64-w64-mingw32/bin + HINTS ${CMAKE_SOURCE_DIR}/libs/libopenmpt/bin/x86_64/mingw ) else() find_library(SRB2_SDL2_DLL_${dllname} "${defaultname}" HINTS ${CMAKE_SOURCE_DIR}/libs/dll-binaries/i686 HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2/i686-w64-mingw32/bin HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2_mixer/i686-w64-mingw32/bin + HINTS ${CMAKE_SOURCE_DIR}/libs/libopenmpt/bin/x86/mingw ) endif() else() @@ -298,12 +303,14 @@ if(${SDL2_FOUND}) HINTS ${CMAKE_SOURCE_DIR}/libs/dll-binaries/x86_64 HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2/lib/x64 HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2_mixer/lib/x64 + HINTS ${CMAKE_SOURCE_DIR}/libs/libopenmpt/bin/x86_64/mingw ) else() find_library(SRB2_SDL2_DLL_${dllname} "${defaultname}" HINTS ${CMAKE_SOURCE_DIR}/libs/dll-binaries/i686 HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2/lib/x86 HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2_mixer/lib/x86 + HINTS ${CMAKE_SOURCE_DIR}/libs/libopenmpt/bin/x86/mingw ) endif() endif() @@ -324,6 +331,9 @@ if(${SDL2_FOUND}) if(${SRB2_CONFIG_HAVE_GME}) getwinlib(libgme "libgme.dll") endif() + if(${SRB2_CONFIG_HAVE_OPENMPT}) + getwinlib(libopenmpt "libopenmpt.dll") + endif() install(PROGRAMS ${win_extra_dll_list} diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj index c25305ca619757b706c692201513e5f5f52e089f..8a205f53abf97f77b2443b61d5cf6312a1f81bea 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj +++ b/src/sdl/Srb2SDL-vc10.vcxproj @@ -94,6 +94,7 @@ <Import Project="..\..\libs\SDL2.props" /> <Import Project="..\..\libs\SDL_mixer.props" /> <Import Project="..\..\libs\libgme.props" /> + <Import Project="..\..\libs\libopenmpt.props" /> <Import Project="Srb2SDL.props" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters index bf8d5bf7678ffb0b5ca92310e4512945259b4c52..8ccd5deb5dea0d709c16daf4e136065c62152d6b 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj.filters +++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters @@ -462,6 +462,9 @@ <ClInclude Include="sdlmain.h"> <Filter>SDLApp</Filter> </ClInclude> + <ClInclude Include="..\hardware\hw_clip.h"> + <Filter>Hw_Hardware</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <CustomBuild Include="..\tmap.nas"> @@ -912,6 +915,9 @@ <ClCompile Include="SDL_main\SDL_windows_main.c"> <Filter>SDLApp</Filter> </ClCompile> + <ClCompile Include="..\hardware\hw_clip.c"> + <Filter>Hw_Hardware</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <Image Include="Srb2SDL.ico"> diff --git a/src/sdl/Srb2SDL.props b/src/sdl/Srb2SDL.props index 75839a5b2cb9c4efaf589ffa98845f1fd56aaf76..17b41bddc1ae2f4f3d12ec2d0ce0160ccf541e72 100644 --- a/src/sdl/Srb2SDL.props +++ b/src/sdl/Srb2SDL.props @@ -6,7 +6,7 @@ <ItemDefinitionGroup> <ClCompile> <!-- x86/x64 defines: has specific libraries that ARM does not --> - <PreprocessorDefinitions Condition="'$(Platform)' == 'Win32' OR '$(Platform)' == 'x64'">HAVE_ZLIB;HAVE_LIBGME;USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;SDLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Platform)' == 'Win32' OR '$(Platform)' == 'x64'">HAVE_ZLIB;HAVE_LIBGME;USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;HAVE_OPENMPT;SDLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions> <!-- ARM defines --> <PreprocessorDefinitions Condition="'$(Platform)' != 'Win32' AND '$(Platform)' != 'x64'">USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;SDLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 517c183ee144019fcb32384aef779c5f40cbf005..7a30d4c8524f45bc6c94119e223aced6db204832 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -131,7 +131,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #include <errno.h> #endif -// Locations for searching the srb2.srb +// Locations for searching the srb2.pk3 #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) #define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2" #define DEFAULTWADLOCATION2 "/usr/local/games/SRB2" @@ -149,8 +149,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); /** \brief WAD file to look for */ -#define WADKEYWORD1 "srb2.srb" -#define WADKEYWORD2 "srb2.wad" +#define WADKEYWORD1 "srb2.pk3" /** \brief holds wad path */ static char returnWadPath[256]; @@ -677,7 +676,7 @@ void I_StartupKeyboard (void) void I_OutputMsg(const char *fmt, ...) { size_t len; - XBOXSTATIC char txt[8192]; + char txt[8192]; va_list argptr; va_start(argptr,fmt); @@ -1035,7 +1034,7 @@ static int joy_open(const char *fname) { if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) { - CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError()); + CONS_Printf(M_GetText("Couldn't initialize gamepad: %s\n"), SDL_GetError()); return -1; } else @@ -1045,7 +1044,7 @@ static int joy_open(const char *fname) if (num_joy < joyindex) { - CONS_Printf(M_GetText("Cannot use joystick #%d/(%s), it doesn't exist\n"),joyindex,fname); + CONS_Printf("Cannot use gamepad #%d/(%s), it doesn't exist\n",joyindex,fname); for (i = 0; i < num_joy; i++) CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i)); I_ShutdownJoystick(); @@ -1321,7 +1320,7 @@ static int joy_open2(const char *fname) { if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) { - CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError()); + CONS_Printf(M_GetText("Couldn't initialize gamepad: %s\n"), SDL_GetError()); return -1; } else @@ -1329,7 +1328,7 @@ static int joy_open2(const char *fname) if (num_joy < joyindex) { - CONS_Printf(M_GetText("Cannot use joystick #%d/(%s), it doesn't exist\n"),joyindex,fname); + CONS_Printf("Cannot use gamepad #%d/(%s), it doesn't exist\n",joyindex,fname); for (i = 0; i < num_joy; i++) CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i)); I_ShutdownJoystick2(); @@ -2451,7 +2450,7 @@ char *I_GetUserName(void) INT32 I_mkdir(const char *dirname, INT32 unixright) { //[segabor] -#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) || defined (__CYGWIN__) || defined (__OS2__) +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) || defined (__CYGWIN__) return mkdir(dirname, unixright); #elif defined (_WIN32) UNREFERENCED_PARAMETER(unixright); /// \todo should implement ntright under nt... @@ -2545,14 +2544,6 @@ static boolean isWadPathOk(const char *path) return true; } - sprintf(wad3path, pandf, path, WADKEYWORD2); - - if (FIL_ReadFileOK(wad3path)) - { - free(wad3path); - return true; - } - free(wad3path); return false; } @@ -2570,7 +2561,7 @@ static void pathonly(char *s) } } -/** \brief search for srb2.srb in the given path +/** \brief search for srb2.pk3 in the given path \param searchDir starting path @@ -2591,19 +2582,12 @@ static const char *searchWad(const char *searchDir) return tempsw; } - strcpy(tempsw, WADKEYWORD2); - fstemp = filesearch(tempsw, searchDir, NULL, true, 20); - if (fstemp == FS_FOUND) - { - pathonly(tempsw); - return tempsw; - } return NULL; } -/** \brief go through all possible paths and look for srb2.srb +/** \brief go through all possible paths and look for srb2.pk3 - \return path to srb2.srb if any + \return path to srb2.pk3 if any */ static const char *locateWad(void) { @@ -2732,7 +2716,7 @@ const char *I_LocateWad(void) if (waddir) { - // change to the directory where we found srb2.srb + // change to the directory where we found srb2.pk3 #if defined (_WIN32) SetCurrentDirectoryA(waddir); #else @@ -2823,16 +2807,6 @@ UINT32 I_GetFreeMem(UINT32 *total) if (total) *total = (UINT32)info.dwTotalPhys; return (UINT32)info.dwAvailPhys; -#elif defined (__OS2__) - UINT32 pr_arena; - - if (total) - DosQuerySysInfo( QSV_TOTPHYSMEM, QSV_TOTPHYSMEM, - (PVOID) total, sizeof (UINT32)); - DosQuerySysInfo( QSV_MAXPRMEM, QSV_MAXPRMEM, - (PVOID) &pr_arena, sizeof (UINT32)); - - return pr_arena; #elif defined (__linux__) /* Linux */ char buf[1024]; diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index c9bccf2ac97c67ff7b5578aa8b473d1e18816a5d..98f5783c1c28ef672003a771448a07e288fcd0be 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1010,7 +1010,7 @@ static inline boolean I_SkipFrame(void) if (!paused) return false; /* FALLTHRU */ - case GS_TIMEATTACK: + //case GS_TIMEATTACK: -- sorry optimisation but now we have a cool level platter and that being laggardly looks terrible case GS_WAITINGPLAYERS: return skip; // Skip odd frames default: @@ -1031,6 +1031,10 @@ void I_FinishUpdate(void) if (I_SkipFrame()) return; + // draw captions if enabled + if (cv_closedcaptioning.value) + SCR_ClosedCaptions(); + if (cv_ticrate.value) SCR_DisplayTicRate(); diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 045e82b15cf4930f706be444fce10b805a14eae8..3932d23d3374b0c3e323e48ab623ac175bfc3c34 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -72,6 +72,17 @@ #endif // HAVE_ZLIB #endif // HAVE_LIBGME +static UINT16 BUFFERSIZE = 2048; +static UINT16 SAMPLERATE = 44100; + +#ifdef HAVE_OPENMPT +#include "libopenmpt/libopenmpt.h" +#endif + +/// ------------------------ +/// Audio Declarations +/// ------------------------ + UINT8 sound_started = false; static Mix_Music *music; @@ -93,13 +104,19 @@ static void (*fading_callback)(void); #ifdef HAVE_LIBGME static Music_Emu *gme; -static INT32 current_track; +static UINT16 current_track; +#endif + +#ifdef HAVE_OPENMPT +int mod_err = OPENMPT_ERROR_OK; +static const char *mod_err_str; +static UINT16 current_subsong; #endif static void var_cleanup(void) { - loop_point = song_length =\ - music_bytes = fading_source = fading_target =\ + loop_point = song_length = 0.0f; + music_bytes = fading_source = fading_target =\ fading_timer = fading_duration = 0; songpaused = is_looping =\ @@ -143,16 +160,21 @@ void I_StartupSound(void) music_volume = sfx_volume = 0; #if SDL_MIXER_VERSION_ATLEAST(1,2,11) - Mix_Init(MIX_INIT_FLAC|MIX_INIT_MOD|MIX_INIT_MP3|MIX_INIT_OGG); + Mix_Init(MIX_INIT_FLAC|MIX_INIT_MP3|MIX_INIT_OGG|MIX_INIT_MOD); #endif - if (Mix_OpenAudio(44100, AUDIO_S16SYS, 2, 2048) < 0) + if (Mix_OpenAudio(SAMPLERATE, AUDIO_S16SYS, 2, BUFFERSIZE) < 0) { CONS_Alert(CONS_ERROR, "Error starting SDL_Mixer: %s\n", Mix_GetError()); // call to start audio failed -- we do not have it return; } +#ifdef HAVE_OPENMPT + CONS_Printf("libopenmpt version: %s\n", openmpt_get_string("library_version")); + CONS_Printf("libopenmpt build date: %s\n", openmpt_get_string("build")); +#endif + sound_started = true; songpaused = false; Mix_AllocateChannels(256); @@ -175,6 +197,10 @@ void I_ShutdownSound(void) if (gme) gme_delete(gme); #endif +#ifdef HAVE_OPENMPT + if (openmpt_mhandle) + openmpt_module_destroy(openmpt_mhandle); +#endif } void I_UpdateSound(void) @@ -569,7 +595,7 @@ static void music_loop(void) { Mix_PlayMusic(music, 0); Mix_SetMusicPosition(loop_point); - music_bytes = loop_point*44100.0L*4; //assume 44.1khz, 4-byte length (see I_GetSongPosition) + music_bytes = (UINT32)(loop_point*44100.0L*4); //assume 44.1khz, 4-byte length (see I_GetSongPosition) } else I_StopSong(); @@ -625,12 +651,39 @@ static void mix_gme(void *udata, Uint8 *stream, int len) // play gme into stream gme_play(gme, len/2, (short *)stream); + // Limiter to prevent music from being disorted with some formats + if (music_volume >= 18) + music_volume = 18; + // apply volume to stream for (i = 0, p = (short *)stream; i < len/2; i++, p++) - *p = ((INT32)*p) * (music_volume*internal_volume/100)*2 / 42; + *p = ((INT32)*p) * (music_volume*internal_volume/100)*2 / 40; } #endif +#ifdef HAVE_OPENMPT +static void mix_openmpt(void *udata, Uint8 *stream, int len) +{ + int i; + short *p; + + (void)udata; + + if (!openmpt_mhandle || songpaused) + return; + + // Play module into stream + openmpt_module_read_interleaved_stereo(openmpt_mhandle, SAMPLERATE, BUFFERSIZE, (short *)stream); + + // Limiter to prevent music from being disorted with some formats + if (music_volume >= 18) + music_volume = 18; + + // apply volume to stream + for (i = 0, p = (short *)stream; i < len/2; i++, p++) + *p = ((INT32)*p) * (music_volume*internal_volume/100)*2 / 40; +} +#endif /// ------------------------ /// Music System @@ -655,6 +708,10 @@ musictype_t I_SongType(void) if (gme) return MU_GME; else +#endif +#ifdef HAVE_OPENMPT + if (openmpt_mhandle) + return MU_MOD_EX; #endif if (!music) return MU_NONE; @@ -673,6 +730,9 @@ boolean I_SongPlaying(void) return ( #ifdef HAVE_LIBGME (I_SongType() == MU_GME && gme) || +#endif +#ifdef HAVE_OPENMPT + (I_SongType() == MU_MOD_EX && openmpt_mhandle) || #endif music != NULL ); @@ -699,8 +759,19 @@ boolean I_SetSongSpeed(float speed) SDL_UnlockAudio(); return true; } + else +#endif +#ifdef HAVE_OPENMPT + if (openmpt_mhandle) + { + char modspd[16]; + sprintf(modspd, "%g", speed); + openmpt_module_ctl_set(openmpt_mhandle, "play.tempo_factor", modspd); + return true; + } #else (void)speed; + return false; #endif return false; } @@ -741,6 +812,11 @@ UINT32 I_GetSongLength(void) return max(length, 0); } else +#endif +#ifdef HAVE_OPENMPT + if (openmpt_mhandle) + return (UINT32)(openmpt_module_get_duration_seconds(openmpt_mhandle) * 1000.); + else #endif if (!music || I_SongType() == MU_MOD || I_SongType() == MU_MID) return 0; @@ -826,6 +902,16 @@ boolean I_SetSongPosition(UINT32 position) // return true; } else +#endif +#ifdef HAVE_OPENMPT + if (openmpt_mhandle) + { + // This isn't 100% correct because we don't account for loop points because we can't get them. + // But if you seek past end of song, OpenMPT seeks to 0. So adjust the position anyway. + openmpt_module_set_position_seconds(openmpt_mhandle, (double)(get_adjusted_position(position)/1000.0L)); // returns new position + return true; + } + else #endif if (!music || I_SongType() == MU_MID) return false; @@ -843,7 +929,7 @@ boolean I_SetSongPosition(UINT32 position) Mix_RewindMusic(); // needed for mp3 if(Mix_SetMusicPosition((float)(position/1000.0L)) == 0) - music_bytes = position/1000.0L*44100.0L*4; //assume 44.1khz, 4-byte length (see I_GetSongPosition) + music_bytes = (UINT32)(position/1000.0L*44100.0L*4); //assume 44.1khz, 4-byte length (see I_GetSongPosition) else // NOTE: This block fires on incorrect song format, // NOT if position input is greater than song length. @@ -883,11 +969,19 @@ UINT32 I_GetSongPosition(void) return max(position, 0); } else +#endif +#ifdef HAVE_OPENMPT + if (openmpt_mhandle) + // This will be incorrect if we adjust for length because we can't get loop points. + // So return unadjusted. See note in SetMusicPosition: we adjust for that. + return (UINT32)(openmpt_module_get_position_seconds(openmpt_mhandle)*1000.); + //return get_adjusted_position((UINT32)(openmpt_module_get_position_seconds(openmpt_mhandle)*1000.)); + else #endif if (!music || I_SongType() == MU_MID) return 0; else - return music_bytes/44100.0L*1000.0L/4; //assume 44.1khz + return (UINT32)(music_bytes/44100.0L*1000.0L/4); //assume 44.1khz // 4 = byte length for 16-bit samples (AUDIO_S16SYS), stereo (2-channel) // This is hardcoded in I_StartupSound. Other formats for factor: // 8M: 1 | 8S: 2 | 16M: 2 | 16S: 4 @@ -912,6 +1006,9 @@ boolean I_LoadSong(char *data, size_t len) if (music #ifdef HAVE_LIBGME || gme +#endif +#ifdef HAVE_OPENMPT + || openmpt_mhandle #endif ) I_UnloadSong(); @@ -1026,6 +1123,40 @@ boolean I_LoadSong(char *data, size_t len) return false; } +#ifdef HAVE_OPENMPT + switch(Mix_GetMusicType(music)) + { + case MUS_MODPLUG: + case MUS_MOD: + openmpt_mhandle = openmpt_module_create_from_memory2(data, len, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + if (!openmpt_mhandle) + { + mod_err = openmpt_module_error_get_last(openmpt_mhandle); + mod_err_str = openmpt_error_string(mod_err); + CONS_Alert(CONS_ERROR, "openmpt_module_create_from_memory2: %s\n", mod_err_str); + Mix_FreeMusic(music); + music = NULL; + return false; + } + else + { + Mix_FreeMusic(music); + music = NULL; + return true; + } + break; + case MUS_WAV: + case MUS_MID: + case MUS_OGG: + case MUS_MP3: + case MUS_FLAC: + Mix_HookMusic(NULL, NULL); + break; + default: + break; + } +#endif + // Find the OGG loop point. loop_point = 0.0f; song_length = 0.0f; @@ -1070,6 +1201,13 @@ void I_UnloadSong(void) gme_delete(gme); gme = NULL; } +#endif +#ifdef HAVE_OPENMPT + if (openmpt_mhandle) + { + openmpt_module_destroy(openmpt_mhandle); + openmpt_mhandle = NULL; + } #endif if (music) { @@ -1089,6 +1227,19 @@ boolean I_PlaySong(boolean looping) return true; } else +#endif +#ifdef HAVE_OPENMPT + if (openmpt_mhandle) + { + openmpt_module_select_subsong(openmpt_mhandle, 0); + openmpt_module_set_render_param(openmpt_mhandle, OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH, cv_modfilter.value); + if (looping) + openmpt_module_set_repeat_count(openmpt_mhandle, -1); // Always repeat + current_subsong = 0; + Mix_HookMusic(mix_openmpt, openmpt_mhandle); + return true; + } + else #endif if (!music) return false; @@ -1130,6 +1281,13 @@ void I_StopSong(void) Mix_HookMusic(NULL, NULL); current_track = -1; } +#endif +#ifdef HAVE_OPENMPT + if (openmpt_mhandle) + { + Mix_HookMusic(NULL, NULL); + current_subsong = -1; + } #endif if (music) { @@ -1191,15 +1349,13 @@ void I_SetMusicVolume(UINT8 volume) boolean I_SetSongTrack(int track) { #ifdef HAVE_LIBGME - if (current_track == track) - return false; - // If the specified track is within the number of tracks playing, then change it if (gme) { + if (current_track == track) + return false; SDL_LockAudio(); - if (track >= 0 - && track < gme_track_count(gme)) + if (track >= 0 && track < gme_track_count(gme)-1) { gme_err_t gme_e = gme_start_track(gme, track); if (gme_e != NULL) @@ -1216,8 +1372,24 @@ boolean I_SetSongTrack(int track) } else #endif - if (I_SongType() == MU_MOD) - return !Mix_SetMusicPosition(track); +#ifdef HAVE_OPENMPT + if (openmpt_mhandle) + { + if (current_subsong == track) + return false; + SDL_LockAudio(); + if (track >= 0 && track < openmpt_module_get_num_subsongs(openmpt_mhandle)) + { + openmpt_module_select_subsong(openmpt_mhandle, track); + current_subsong = track; + SDL_UnlockAudio(); + return true; + } + SDL_UnlockAudio(); + + return false; + } +#endif (void)track; return false; } diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index e32da0614364385dfc65f2f7a185e8eae9d39c43..d9967ae0375d9ab30a3772f9c934e5ee26c75663 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -1577,4 +1577,4 @@ static boolean I_StartGMESong(const char *musicname, boolean looping) } #endif -#endif //HAVE_SDL \ No newline at end of file +#endif //HAVE_SDL diff --git a/src/sdl12/IMG_xpm.c b/src/sdl12/IMG_xpm.c deleted file mode 100644 index e08736d66515b89367f29022afd4ed663e570497..0000000000000000000000000000000000000000 --- a/src/sdl12/IMG_xpm.c +++ /dev/null @@ -1,506 +0,0 @@ -/* - SDL_image: An example image loading library for use with SDL - Copyright (C) 1999-2004 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ - -/* $Id: IMG_xpm.c,v 1.10 2004/01/04 22:04:38 slouken Exp $ */ - -/* - * XPM (X PixMap) image loader: - * - * Supports the XPMv3 format, EXCEPT: - * - hotspot coordinates are ignored - * - only colour ('c') colour symbols are used - * - rgb.txt is not used (for portability), so only RGB colours - * are recognized (#rrggbb etc) - only a few basic colour names are - * handled - * - * The result is an 8bpp indexed surface if possible, otherwise 32bpp. - * The colourkey is correctly set if transparency is used. - * - * Besides the standard API, also provides - * - * SDL_Surface *IMG_ReadXPMFromArray(char **xpm) - * - * that reads the image data from an XPM file included in the C source. - * - * TODO: include rgb.txt here. The full table (from solaris 2.6) only - * requires about 13K in binary form. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <ctype.h> - -//#include "SDL_image.h" - - -#ifdef LOAD_XPM - -/* See if an image is contained in a data source */ -#if 0 -int IMG_isXPM(SDL_RWops *src) -{ - char magic[9]; - - return (SDL_RWread(src, magic, sizeof (magic), 1) - && memcmp(magic, "/* XPM */", 9) == 0); -} -#endif - -/* Hash table to look up colors from pixel strings */ -#define STARTING_HASH_SIZE 256 - -struct hash_entry { - char *key; - Uint32 color; - struct hash_entry *next; -}; - -struct color_hash { - struct hash_entry **table; - struct hash_entry *entries; /* array of all entries */ - struct hash_entry *next_free; - size_t size; - int maxnum; -}; - -static int hash_key(const char *key, int cpp, size_t size) -{ - int hash; - - hash = 0; - while ( cpp-- > 0 ) { - hash = hash * 33 + *key++; - } - return (int)(hash & (size - 1)); -} - -static struct color_hash *create_colorhash(int maxnum) -{ - size_t bytes; - int s; - struct color_hash *hash; - - /* we know how many entries we need, so we can allocate - everything here */ - hash = malloc(sizeof *hash); - if (!hash) - return NULL; - - /* use power-of-2 sized hash table for decoding speed */ - for (s = STARTING_HASH_SIZE; s < maxnum; s <<= 1) - ; - hash->size = s; - hash->maxnum = maxnum; - bytes = hash->size * sizeof (struct hash_entry **); - hash->entries = NULL; /* in case malloc fails */ - hash->table = malloc(bytes); - if (!hash->table) - return NULL; - memset(hash->table, 0, bytes); - hash->entries = malloc(maxnum * sizeof (struct hash_entry)); - if (!hash->entries) - { - free(hash->table); - return NULL; - } - hash->next_free = hash->entries; - return hash; -} - -static int add_colorhash(struct color_hash *hash, - char *key, int cpp, Uint32 color) -{ - const int indexkey = hash_key(key, cpp, hash->size); - struct hash_entry *e = hash->next_free++; - e->color = color; - e->key = key; - e->next = hash->table[indexkey]; - hash->table[indexkey] = e; - return 1; -} - -/* fast lookup that works if cpp == 1 */ -#define QUICK_COLORHASH(hash, key) ((hash)->table[*(const Uint8 *)(key)]->color) - -static Uint32 get_colorhash(struct color_hash *hash, const char *key, int cpp) -{ - struct hash_entry *entry = hash->table[hash_key(key, cpp, hash->size)]; - while (entry) { - if (memcmp(key, entry->key, cpp) == 0) - return entry->color; - entry = entry->next; - } - return 0; /* garbage in - garbage out */ -} - -static void free_colorhash(struct color_hash *hash) -{ - if (hash && hash->table) { - free(hash->table); - free(hash->entries); - free(hash); - } -} - -/* portable case-insensitive string comparison */ -static int string_equal(const char *a, const char *b, size_t n) -{ - while (*a && *b && n) { - if (toupper((unsigned char)*a) != toupper((unsigned char)*b)) - return 0; - a++; - b++; - n--; - } - return *a == *b; -} - -#undef ARRAYSIZE -#define ARRAYSIZE(a) (int)(sizeof (a) / sizeof ((a)[0])) - -/* - * convert colour spec to RGB (in 0xrrggbb format). - * return 1 if successful. - */ -static int color_to_rgb(const char *spec, size_t speclen, Uint32 *rgb) -{ - /* poor man's rgb.txt */ - static struct { const char *name; Uint32 rgb; } known[] = { - {"none", 0xffffffff}, - {"black", 0x00000000}, - {"white", 0x00ffffff}, - {"red", 0x00ff0000}, - {"green", 0x0000ff00}, - {"blue", 0x000000ff} - }; - - if (spec[0] == '#') { - char buf[7]; - switch (speclen) { - case 4: - buf[0] = buf[1] = spec[1]; - buf[2] = buf[3] = spec[2]; - buf[4] = buf[5] = spec[3]; - break; - case 7: - memcpy(buf, spec + 1, 6); - break; - case 13: - buf[0] = spec[1]; - buf[1] = spec[2]; - buf[2] = spec[5]; - buf[3] = spec[6]; - buf[4] = spec[9]; - buf[5] = spec[10]; - break; - } - buf[6] = '\0'; - *rgb = (Uint32)strtol(buf, NULL, 16); - return 1; - } else { - int i; - for (i = 0; i < ARRAYSIZE(known); i++) - if (string_equal(known[i].name, spec, speclen)) { - *rgb = known[i].rgb; - return 1; - } - return 0; - } -} - -#ifndef MAX -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#endif - -static char *linebuf; -static int buflen; -static const char *error; - -/* - * Read next line from the source. - * If len > 0, it's assumed to be at least len chars (for efficiency). - * Return NULL and set error upon EOF or parse error. - */ -static const char *get_next_line(const char ***lines, SDL_RWops *src, int len) -{ - char *linebufnew; - if (lines) { - return *(*lines)++; - } else { - char c; - int n; - do { - if (SDL_RWread(src, &c, 1, 1) <= 0) { - error = "Premature end of data"; - return NULL; - } - } while (c != '"'); - if (len) { - len += 4; /* "\",\n\0" */ - if (len > buflen){ - buflen = len; - linebufnew = realloc(linebuf, buflen); - if(!linebufnew) { - free(linebuf); - error = "Out of memory"; - return NULL; - } - linebuf = linebufnew; - } - if (SDL_RWread(src, linebuf, len - 1, 1) <= 0) { - error = "Premature end of data"; - return NULL; - } - n = len - 2; - } else { - n = 0; - do { - if (n >= buflen - 1) { - if (buflen == 0) - buflen = 16; - buflen *= 2; - linebufnew = realloc(linebuf, buflen); - if(!linebufnew) { - free(linebuf); - error = "Out of memory"; - return NULL; - } - linebuf = linebufnew; - } - if (SDL_RWread(src, linebuf + n, 1, 1) <= 0) { - error = "Premature end of data"; - return NULL; - } - } while (linebuf[n++] != '"'); - n--; - } - linebuf[n] = '\0'; - return linebuf; - } -} - -#define SKIPSPACE(p) \ -do { \ - while (isspace((unsigned char)*(p))) \ - ++(p); \ -} while (0) - -#define SKIPNONSPACE(p) \ -do { \ - while (!isspace((unsigned char)*(p)) && *p) \ - ++(p); \ -} while (0) - -/* read XPM from either array or RWops */ -static SDL_Surface *load_xpm(const char **xpm, SDL_RWops *src) -{ - SDL_Surface *image = NULL; - int indexc; - int x, y; - int w, h, ncolors, cpp; - int indexed; - Uint8 *dst; - struct color_hash *colors = NULL; - SDL_Color *im_colors = NULL; - char *keystrings = NULL, *nextkey; - const char *line; - const char ***xpmlines = NULL; - int pixels_len; - - error = NULL; - linebuf = NULL; - buflen = 0; - - if (xpm) - xpmlines = &xpm; - - line = get_next_line(xpmlines, src, 0); - if (!line) - goto done; - /* - * The header string of an XPMv3 image has the format - * - * <width> <height> <ncolors> <cpp> [ <hotspot_x> <hotspot_y> ] - * - * where the hotspot coords are intended for mouse cursors. - * Right now we don't use the hotspots but it should be handled - * one day. - */ - if (sscanf(line, "%d %d %d %d", &w, &h, &ncolors, &cpp) != 4 - || w <= 0 || h <= 0 || ncolors <= 0 || cpp <= 0) { - error = "Invalid format description"; - goto done; - } - - keystrings = malloc(ncolors * cpp); - if (!keystrings) { - error = "Out of memory"; - goto done; - } - nextkey = keystrings; - - /* Create the new surface */ - if (ncolors <= 256) { - indexed = 1; - image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8, - 0, 0, 0, 0); - im_colors = image->format->palette->colors; - image->format->palette->ncolors = ncolors; - } else { - indexed = 0; - image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, - 0xff0000, 0x00ff00, 0x0000ff, 0); - } - if (!image) { - /* Hmm, some SDL error (out of memory?) */ - goto done; - } - - /* Read the colors */ - colors = create_colorhash(ncolors); - if (!colors) { - error = "Out of memory"; - goto done; - } - for (indexc = 0; indexc < ncolors; ++indexc ) { - const char *p; - line = get_next_line(xpmlines, src, 0); - if (!line) - goto done; - - p = line + cpp + 1; - - /* parse a colour definition */ - for (;;) { - char nametype; - const char *colname; - Uint32 rgb, pixel; - - SKIPSPACE(p); - if (!*p) { - error = "colour parse error"; - goto done; - } - nametype = *p; - SKIPNONSPACE(p); - SKIPSPACE(p); - colname = p; - SKIPNONSPACE(p); - if (nametype == 's') - continue; /* skip symbolic colour names */ - - if (!color_to_rgb(colname, p - colname, &rgb)) - continue; - - memcpy(nextkey, line, cpp); - if (indexed) { - SDL_Color *c = im_colors + indexc; - c->r = (Uint8)(rgb >> 16); - c->g = (Uint8)(rgb >> 8); - c->b = (Uint8)(rgb); - pixel = indexc; - } else - pixel = rgb; - add_colorhash(colors, nextkey, cpp, pixel); - nextkey += cpp; - if (rgb == 0xffffffff) - SDL_SetColorKey(image, SDL_SRCCOLORKEY, pixel); - break; - } - } - - /* Read the pixels */ - pixels_len = w * cpp; - dst = image->pixels; - for (y = 0; y < h; y++) { - line = get_next_line(xpmlines, src, pixels_len); - if (indexed) { - /* optimization for some common cases */ - if (cpp == 1) - for (x = 0; x < w; x++) - dst[x] = (Uint8)QUICK_COLORHASH(colors, - line + x); - else - for (x = 0; x < w; x++) - dst[x] = (Uint8)get_colorhash(colors, - line + x * cpp, - cpp); - } else { - for (x = 0; x < w; x++) - ((Uint32*)dst)[x] = get_colorhash(colors, - line + x * cpp, - cpp); - } - dst += image->pitch; - } - -done: - if (error) { - SDL_FreeSurface(image); - image = NULL; - SDL_SetError(error); - } - free(keystrings); - free_colorhash(colors); - free(linebuf); - return(image); -} - -/* Load a XPM type image from an RWops datasource */ -#if 0 -SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src) -{ - if ( !src ) { - /* The error message has been set in SDL_RWFromFile */ - return NULL; - } - return load_xpm(NULL, src); -} -#endif - -static inline SDL_Surface *IMG_ReadXPMFromArray(const char **xpm) -{ - return load_xpm(xpm, NULL); -} - -#else /* not LOAD_XPM */ - -/* See if an image is contained in a data source */ -#if 0 -int IMG_isXPM(SDL_RWops *src) -{ - return(0); -} - -/* Load a XPM type image from an SDL datasource */ -SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src) -{ - return(NULL); -} -#endif - -static inline SDL_Surface *IMG_ReadXPMFromArray(const char **xpm) -{ - return NULL; -} -#endif /* not LOAD_XPM */ diff --git a/src/sdl12/MakeCYG.cfg b/src/sdl12/MakeCYG.cfg deleted file mode 100644 index b55d9dc50361c2a4742ce7ce237da3cdaddf84d4..0000000000000000000000000000000000000000 --- a/src/sdl12/MakeCYG.cfg +++ /dev/null @@ -1,17 +0,0 @@ -# -# sdl12/makeCYG.cfg for SRB2/Cygwin -# - -# -#Cygwin, for debugging - - NOHW=1 - NOHS=1 - NOASM=1 - - OPTS+=-DLINUX - - i_system_o+=$(OBJDIR)/SRB2.res - - # name of the exefile - EXENAME?=lsdlsrb2.exe diff --git a/src/sdl12/MakeNIX.cfg b/src/sdl12/MakeNIX.cfg deleted file mode 100644 index 1278aaf06ccb7b8307bb959ac705e4c54b381a8e..0000000000000000000000000000000000000000 --- a/src/sdl12/MakeNIX.cfg +++ /dev/null @@ -1,92 +0,0 @@ -# -# sdl12/makeNIX.cfg for SRB2/?nix -# - -#Valgrind support -ifdef VALGRIND -VALGRIND_PKGCONFIG?=valgrind -VALGRIND_CFLAGS?=$(shell $(PKG_CONFIG) $(VALGRIND_PKGCONFIG) --cflags) -VALGRIND_LDFLAGS?=$(shell $(PKG_CONFIG) $(VALGRIND_PKGCONFIG) --libs) -ZDEBUG=1 -LIBS+=$(VALGRIND_LDFLAGS) -ifdef GCC46 -WFLAGS+=-Wno-error=unused-but-set-variable -WFLAGS+=-Wno-unused-but-set-variable -endif -endif - -# -#here is GNU/Linux and other -# - - OPTS=-DUNIXCOMMON - - #LDFLAGS = -L/usr/local/lib - LIBS=-lm -ifdef LINUX - LIBS+=-lrt -ifdef NOTERMIOS - OPTS+=-DNOTERMIOS -endif -endif - -# -#here is Solaris -# -ifdef SOLARIS - NOIPX=1 - NOASM=1 - OPTS+=-DSOLARIS -DINADDR_NONE=INADDR_ANY -DBSD_COMP - OPTS+=-I/usr/local/include -I/opt/sfw/include - LDFLAGS+=-L/opt/sfw/lib - LIBS+=-lsocket -lnsl -endif - -# -#here is FreeBSD -# -ifdef FREEBSD - OPTS+=-DLINUX -DFREEBSD -I/usr/X11R6/include - SDL_CONFIG?=sdl11-config - LDFLAGS+=-L/usr/X11R6/lib - LIBS+=-lipx -lkvm -endif - -# -#here is GP2x (arm-gp2x-linux) -# -ifdef GP2X - PNG_CONFIG?=$(PREFIX)-libpng12-config -ifdef STATIC #need a better setting name - CFLAGS+=-I$(OPEN2X)/include -ifndef NOMIXER - LIBS+=-lvorbisidec -ifdef MIKMOD - LIBS+=-lmikmod -endif -ifdef SMPEGLIB - LIBS+=-lsmpeg - LD=$(CXX) -endif -endif - NONET=1 -endif -ifndef ARCHNAME -"error" -endif - NONX86=1 - NOHW=1 - NOHS=1 - NOMD5=1 - WFLAGS+=-O0 - OPTS+=-DGP2X -ffast-math -mcpu=arm920t - EXENAME?=SRB2GP2X.gpe -endif - -ifndef NOHW - OPTS+=-I/usr/X11R6/include - LDFLAGS+=-L/usr/X11R6/lib -endif - - # name of the exefile - EXENAME?=lsdlsrb2 diff --git a/src/sdl12/Makefile.cfg b/src/sdl12/Makefile.cfg deleted file mode 100644 index 8d9ebc35cdb50cdc53ffadc56356fdfe36ca3acb..0000000000000000000000000000000000000000 --- a/src/sdl12/Makefile.cfg +++ /dev/null @@ -1,163 +0,0 @@ -# -# sdl12/makefile.cfg for SRB2/SDL -# - -# -#SDL...., *looks at Alam*, THIS IS A MESS! -# - -ifdef UNIXCOMMON -include sdl12/MakeNIX.cfg -endif - -ifdef PANDORA -include sdl12/SRB2Pandora/Makefile.cfg -endif #ifdef PANDORA - -ifdef DC -include sdl12/SRB2DC/Makefile.cfg -endif #ifdef DC - -ifdef PS3N -include sdl12/SRB2PS3/Makefile.cfg -endif #ifdef PS3N - -ifdef PSP -include sdl12/SRB2PSP/Makefile.cfg -endif #ifdef PSP - -ifdef XBOX -include sdl12/SRB2XBOX/Makefile.cfg -endif #ifdef XBOX - -ifdef WINCE -include sdl12/SRB2CE/Makefile.cfg -endif #ifef WINCE - -ifdef CYGWIN32 -include sdl12/MakeCYG.cfg -endif #ifdef CYGWIN32 - -ifdef SDL_PKGCONFIG -SDL_CFLAGS?=$(shell $(PKG_CONFIG) $(SDL_PKGCONFIG) --cflags) -SDL_LDFLAGS?=$(shell $(PKG_CONFIG) $(SDL_PKGCONFIG) --libs) -else -ifdef PREFIX - SDL_CONFIG?=$(PREFIX)-sdl-config -else - SDL_CONFIG?=sdl-config -endif - -ifdef STATIC - SDL_CFLAGS?=$(shell $(SDL_CONFIG) --cflags) - SDL_LDFLAGS?=$(shell $(SDL_CONFIG) --static-libs) -else - SDL_CFLAGS?=$(shell $(SDL_CONFIG) --cflags) - SDL_LDFLAGS?=$(shell $(SDL_CONFIG) --libs) -endif -endif - - - #use the x86 asm code -ifndef CYGWIN32 -ifndef NOASM - USEASM=1 -endif -endif - - OBJS+=$(OBJDIR)/i_video.o $(OBJDIR)/dosstr.o $(OBJDIR)/endtxt.o $(OBJDIR)/hwsym_sdl.o - - OPTS+=-DDIRECTFULLSCREEN -DHAVE_SDL - -ifndef NOHW - OBJS+=$(OBJDIR)/r_opengl.o $(OBJDIR)/ogl_sdl.o -endif - -ifndef NOHS -ifdef OPENAL - OBJS+=$(OBJDIR)/s_openal.o - OPTS+=-DSTATIC3DS - STATICHS=1 -else -ifdef FMOD - OBJS+=$(OBJDIR)/s_fmod.o - OPTS+=-DSTATIC3DS - STATICHS=1 -else -ifdef MINGW -ifdef DS3D - OBJS+=$(OBJDIR)/s_ds3d.o - OPTS+=-DSTATIC3DS - STATICHS=1 -endif -endif -endif -endif -endif - -ifdef FILTERS - OBJS+=$(OBJDIR)/filters.o $(OBJDIR)/hq2x.o $(OBJDIR)/lq2x.o - OPTS+=-DHAVE_FILTER -endif - -ifdef NOMIXER - i_sound_o=$(OBJDIR)/sdl_sound.o -else - i_sound_o=$(OBJDIR)/mixer_sound.o - OPTS+=-DHAVE_MIXER - SDL_LDFLAGS+=-lSDL_mixer -endif - -ifdef SDL_TTF - OPTS+=-DHAVE_TTF - SDL_LDFLAGS+=-lSDL_ttf -lfreetype -lz - OBJS+=$(OBJDIR)/i_ttf.o -endif - -#ifdef SDL_IMAGE -# OPTS+=-DHAVE_IMAGE -# SDL_LDFLAGS+=-lSDL_image -#endif - -ifdef SDL_NET - OPTS+=-DHAVE_SDLNET - SDL_LDFLAGS+=-lSDL_net -endif - -ifdef SDLMAIN - OPTS+=-DSDLMAIN -else -ifdef MINGW - SDL_CFLAGS+=-Umain - SDL_LDFLAGS+=-mconsole -endif -endif - -ifndef NOHW -ifdef OPENAL -ifdef MINGW - LIBS:=-lopenal32 $(LIBS) -else - LIBS:=-lopenal $(LIBS) -endif -else -ifdef MINGW -ifdef DS3D - LIBS:=-ldsound -luuid $(LIBS) -endif -endif -endif -endif - -# FIXME: DevkitPPC and ready-compiled SDL Wii require these things to be in a silly order -ifdef WII -include sdl12/SRB2WII/Makefile.cfg -endif #ifdef WII - -CFLAGS+=$(SDL_CFLAGS) -LIBS:=$(SDL_LDFLAGS) $(LIBS) -ifndef WII -ifdef STATIC - LIBS+=$(shell $(SDL_CONFIG) --static-libs) -endif -endif diff --git a/src/sdl12/SDL_icon.xpm b/src/sdl12/SDL_icon.xpm deleted file mode 100644 index cf72960dfc9048d1ab23b3c59ed4d29d65f4c404..0000000000000000000000000000000000000000 --- a/src/sdl12/SDL_icon.xpm +++ /dev/null @@ -1,425 +0,0 @@ -/* XPM */ -static char * C:\Repo\srb2\src\sdl\SDL_icon_xpm[] = { -"32 32 390 2", -" c None", -". c #4F4F70", -"+ c #4D4D87", -"@ c #4D4D84", -"# c #4E4E6C", -"$ c #6C6C95", -"% c #5E5EB2", -"& c #6B6BE7", -"* c #7373F9", -"= c #7C7CFF", -"- c #6F70E7", -"; c #494BB2", -"> c #4F4FA3", -", c #6464D4", -"' c #7979F5", -") c #5F5FCA", -"! c #5D5D93", -"~ c #3A3A9F", -"{ c #6060AC", -"] c #777793", -"^ c #5C5CB3", -"/ c #7373EA", -"( c #7A7AFF", -"_ c #7575FF", -": c #7979FF", -"< c #6264DD", -"[ c #47478C", -"} c #564567", -"| c #4647D0", -"1 c #5C5CAE", -"2 c #5E5EFF", -"3 c #2929FF", -"4 c #1D1DFF", -"5 c #1919D1", -"6 c #4F4F90", -"7 c #1E1ECE", -"8 c #5858FF", -"9 c #6767A8", -"0 c #4949A0", -"a c #7070FB", -"b c #7D7DFF", -"c c #7777FF", -"d c #7373FF", -"e c #7272FF", -"f c #7878FF", -"g c #6465D8", -"h c #363886", -"i c #9F7655", -"j c #C89B5C", -"k c #1D1CB7", -"l c #3031B1", -"m c #1919F4", -"n c #1111FF", -"o c #1818FF", -"p c #1B1BFF", -"q c #1C1CFF", -"r c #2626B3", -"s c #1E1EC8", -"t c #1A1AE8", -"u c #24249F", -"v c #2F2FD2", -"w c #7676FF", -"x c #6869E2", -"y c #414290", -"z c #8C6751", -"A c #FCBA68", -"B c #E9BD7D", -"C c #201EB8", -"D c #090AB8", -"E c #1616EB", -"F c #1818FD", -"G c #1414EE", -"H c #1010E1", -"I c #0E0EE2", -"J c #0E0EF4", -"K c #0606B2", -"L c #7A7A89", -"M c #0C0C9A", -"N c #0A0AA7", -"O c #2424E4", -"P c #6669E6", -"Q c #4F4A8F", -"R c #BF853B", -"S c #FFD98D", -"T c #CDAB76", -"U c #1717C4", -"V c #0F10BA", -"W c #0909B6", -"X c #0505C3", -"Y c #0000B6", -"Z c #0000BE", -"` c #0000AD", -" . c #1D1D83", -".. c #63638E", -"+. c #090975", -"@. c #1414F3", -"#. c #5B5BFF", -"$. c #7B7BFF", -"%. c #7070FF", -"&. c #6E6EFF", -"*. c #7172F6", -"=. c #625DAF", -"-. c #BA9E6C", -";. c #887167", -">. c #090DF2", -",. c #1313BE", -"'. c #000085", -"). c #0000AC", -"!. c #0202AA", -"~. c #242488", -"{. c #1414C7", -"]. c #1717FF", -"^. c #5959FF", -"/. c #7F7FFF", -"(. c #7474FF", -"_. c #7171FF", -":. c #8686FF", -"<. c #7574FF", -"[. c #797CFF", -"}. c #5756B8", -"|. c #1C19A4", -"1. c #1617FF", -"2. c #1212BD", -"3. c #040485", -"4. c #0707A4", -"5. c #1B1B71", -"6. c #373797", -"7. c #1616FF", -"8. c #5050FF", -"9. c #8080FF", -"0. c #AAAAFF", -"a. c #AEAEF6", -"b. c #8A8AEF", -"c. c #6969FB", -"d. c #2728FF", -"e. c #1314FF", -"f. c #1919FF", -"g. c #1313E8", -"h. c #1F1FF4", -"i. c #5454FF", -"j. c #6D6DF0", -"k. c #6868B5", -"l. c #0B0BB8", -"m. c #1212C5", -"n. c #1616FC", -"o. c #1515FF", -"p. c #1212FF", -"q. c #2323FF", -"r. c #3636FF", -"s. c #4040FF", -"t. c #4343F9", -"u. c #5D5DB8", -"v. c #7F7F92", -"w. c #878793", -"x. c #4B4B94", -"y. c #0B0CE2", -"z. c #1313FF", -"A. c #4C4CFF", -"B. c #8282FF", -"C. c #7171ED", -"D. c #636394", -"E. c #575785", -"F. c #A9A99C", -"G. c #1414BC", -"H. c #1414FF", -"I. c #0707FD", -"J. c #2525AA", -"K. c #A8A8A4", -"L. c #EBEBE2", -"M. c #F9F9F2", -"N. c #E1E1CC", -"O. c #4D4D9F", -"P. c #0B0BF7", -"Q. c #2121FF", -"R. c #3232FF", -"S. c #5555FF", -"T. c #6161B4", -"U. c #B5B5B2", -"V. c #FFFFF8", -"W. c #4F4F9A", -"X. c #0B0BF5", -"Y. c #1616C5", -"Z. c #A8A8A1", -"`. c #FFFFFC", -" + c #FFFFFF", -".+ c #C0C0C4", -"++ c #1212D4", -"@+ c #4444FF", -"#+ c #6464FF", -"$+ c #8383FF", -"%+ c #6767C3", -"&+ c #E4E4E4", -"*+ c #9494AE", -"=+ c #0808DF", -"-+ c #0D0DF2", -";+ c #61619A", -">+ c #F1F1E0", -",+ c #E8E8DD", -"'+ c #2424BB", -")+ c #1010FF", -"!+ c #3434FF", -"~+ c #6161FF", -"{+ c #6969D2", -"]+ c #EFEFF0", -"^+ c #C2C2BA", -"/+ c #1010B6", -"(+ c #0909AC", -"_+ c #A4A49A", -":+ c #EAEADE", -"<+ c #2525B8", -"[+ c #2F2FFF", -"}+ c #3C3CB5", -"|+ c #EEEEEE", -"1+ c #BBBBAD", -"2+ c #0B0B56", -"3+ c #0B0BFC", -"4+ c #1212EF", -"5+ c #0C0C3E", -"6+ c #919187", -"7+ c #DEDED6", -"8+ c #1F1FC0", -"9+ c #1A1AFF", -"0+ c #1717FA", -"a+ c #1515F8", -"b+ c #1111FC", -"c+ c #494992", -"d+ c #999998", -"e+ c #3E3E3B", -"f+ c #3C3C99", -"g+ c #535397", -"h+ c #5A5A4D", -"i+ c #6F6F70", -"j+ c #BFBFC9", -"k+ c #1111D6", -"l+ c #1515F1", -"m+ c #0F0FE2", -"n+ c #0D0DD9", -"o+ c #0909CD", -"p+ c #0808C7", -"q+ c #0505C7", -"r+ c #0303CB", -"s+ c #0101C0", -"t+ c #0202AF", -"u+ c #0606AC", -"v+ c #121283", -"w+ c #BBBBBB", -"x+ c #BEBEBE", -"y+ c #2F2F2E", -"z+ c #C7C8BB", -"A+ c #D8DAD1", -"B+ c #272828", -"C+ c #929292", -"D+ c #8688C7", -"E+ c #0506F6", -"F+ c #1616F5", -"G+ c #0B0BD3", -"H+ c #0202B6", -"I+ c #0000AF", -"J+ c #0000B4", -"K+ c #0000BD", -"L+ c #0000BB", -"M+ c #00009E", -"N+ c #2C2C7E", -"O+ c #6A6A8B", -"P+ c #959595", -"Q+ c #F0F0F1", -"R+ c #E1E1E1", -"S+ c #8C8E90", -"T+ c #BEBEBF", -"U+ c #C9C7C5", -"V+ c #939699", -"W+ c #E7EAED", -"X+ c #CBCBC7", -"Y+ c #413B9B", -"Z+ c #0607DD", -"`+ c #0C0CE2", -" @ c #0303B9", -".@ c #0000A8", -"+@ c #181888", -"@@ c #6A6A6A", -"#@ c #626263", -"$@ c #4B4B4C", -"%@ c #3E3B36", -"&@ c #9B805C", -"*@ c #D9B07D", -"=@ c #C9AE89", -"-@ c #B9AF9E", -";@ c #C7C5C4", -">@ c #CBCCCF", -",@ c #C7C6C6", -"'@ c #AEA59A", -")@ c #B69974", -"!@ c #D8B87F", -"~@ c #9B8272", -"{@ c #0E0B9B", -"]@ c #0000B7", -"^@ c #0000B8", -"/@ c #000082", -"(@ c #00007A", -"_@ c #636379", -":@ c #62533E", -"<@ c #B59B6C", -"[@ c #DEB07B", -"}@ c #FECC90", -"|@ c #FFCE92", -"1@ c #FEC98C", -"2@ c #F1BD82", -"3@ c #D1A979", -"4@ c #BC9E73", -"5@ c #CCA777", -"6@ c #EAB980", -"7@ c #FFCD90", -"8@ c #FFD595", -"9@ c #FDD782", -"0@ c #413678", -"a@ c #0000AE", -"b@ c #000077", -"c@ c #010193", -"d@ c #0C0CE4", -"e@ c #38389E", -"f@ c #EEC585", -"g@ c #FFDA9D", -"h@ c #FFC992", -"i@ c #FFC88F", -"j@ c #FFC990", -"k@ c #FFCE93", -"l@ c #FFD094", -"m@ c #FFCC92", -"n@ c #C9A174", -"o@ c #EDBD88", -"p@ c #FAD287", -"q@ c #3A2F7F", -"r@ c #0000BA", -"s@ c #0000B0", -"t@ c #0101B2", -"u@ c #1111ED", -"v@ c #1919C1", -"w@ c #95887C", -"x@ c #DCAC6E", -"y@ c #FFD393", -"z@ c #FFCD94", -"A@ c #FFCA93", -"B@ c #FFC991", -"C@ c #FFC78E", -"D@ c #FFCB91", -"E@ c #E0B581", -"F@ c #BB9A6F", -"G@ c #FFDC97", -"H@ c #C1A173", -"I@ c #0E0B9A", -"J@ c #0000B5", -"K@ c #0101B6", -"L@ c #1010E0", -"M@ c #1616EC", -"N@ c #A68156", -"O@ c #E7AC6B", -"P@ c #FFC582", -"Q@ c #FFCF8F", -"R@ c #FFD195", -"S@ c #FFD296", -"T@ c #FFD396", -"U@ c #FFD193", -"V@ c #FFD28F", -"W@ c #D2A96B", -"X@ c #2F2482", -"Y@ c #0000C1", -"Z@ c #0000C0", -"`@ c #0000BF", -" # c #0101BF", -".# c #1212F0", -"+# c #767698", -"@# c #9C866E", -"## c #A9865D", -"$# c #C0915D", -"%# c #C89760", -"&# c #C29360", -"*# c #AD8A61", -"=# c #9D8971", -"-# c #7F7A7A", -";# c #70708F", -"># c #6F6F91", -",# c #575788", -"'# c #464687", -")# c #2F2F87", -"!# c #15158F", -"~# c #0101A8", -"{# c #1313FB", -"]# c #57579F", -"^# c #343487", -"/# c #434388", -" ", -" ", -" ", -" . + @ # ", -" $ % & * = - ; > , ' ) ! ", -" ~ { ] ^ / = ( _ : < [ } | 1 2 3 4 5 6 ", -" 7 8 9 0 a b c d e f g h i j k l m n o p q r ", -" s t u v _ f d d d w x y z A B C D E F G H I J K L ", -" M N O _ c e d d d _ P Q R S T U V W X Y Z ` ... ", -" +.@.#.$.d d d d %.&._ *.=.-.;.>.,.'.).!.~. ", -" {.].^./.(.d d _.$.:._ <.[.}.|.1.2.3.4.5. ", -" 6.7.7.4 8.e : w 9.0.a.b.c.2 d.e.f.g.h.i.j.k. ", -" l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.o o z.A.B./.b C.D. ", -" E.F.G.].o H.z.I.J.K.L.M.N.O.P.o o o Q.R.S._.b B.T. ", -" U.V.W.X.f.f.7.Y.Z.`. + + +.+++].o o o.n z.q.@+#+$+%+ ", -" &+ +*+=+].o -+;+>+ + + + +,+'+H.o o o o o H.)+o !+~+{+ ", -" ]+ +^+/+H.o.(+_+ + + + + +:+<+z.o o o o o o o 7.n H.[+}+ ", -" |+ +1+2+3+4+5+6+ + + + + +7+8+H.o o f.9+f.9+f.F 0+a+b+o.c+ ", -" &+ +d+e+f+g+h+i+ + + + + +j+k+].f.9+l+m+n+o+p+q+r+s+t+u+v+ ", -" w+ +x+y+z+A+B+C+ + + + + +D+E+9+F+G+H+I+J+K+L+M+N+O+ ", -" P+Q+R+S+T+U+V+W+ + + + +X+Y+Z+`+ @I+J+Z .@+@E. ", -" @@#@$@%@&@*@=@-@;@>@,@'@)@!@~@{@]@^@I+/@(@_@ ", -" :@<@[@}@|@1@2@3@4@5@6@7@8@9@0@L+a@b@c@d@e@ ", -" f@g@h@i@i@j@k@l@|@m@n@o@p@q@r@s@t@u@p v@ ", -" w@x@y@z@A@B@i@C@D@E@F@G@H@I@L+J@K@L@p M@ ", -" N@O@P@Q@R@S@T@U@V@W@X@Y@Z@Y@`@ #.#p +# ", -" @###$#%#&#*#=#-#;#>#,#'#)#!#~#{#]# ", -" ^#/# ", -" ", -" ", -" ", -" "}; diff --git a/src/sdl12/SDL_main/SDL_dummy_main.c b/src/sdl12/SDL_main/SDL_dummy_main.c deleted file mode 100644 index d8cfdd5bb2a87d2bb2a718aaee1e42cb38914404..0000000000000000000000000000000000000000 --- a/src/sdl12/SDL_main/SDL_dummy_main.c +++ /dev/null @@ -1,12 +0,0 @@ -/* Include the SDL main definition header */ -#include "SDL_main.h" - -#ifdef main -#undef main -int main(int argc, char *argv[]) -{ - return(SDL_main(argc, argv)); -} -#else -/* Nothing to do on this platform */; -#endif diff --git a/src/sdl12/SDL_main/SDL_macosx_main.h b/src/sdl12/SDL_main/SDL_macosx_main.h deleted file mode 100644 index 4683df57a5e61fc41b189e67245f4a0a32d7552d..0000000000000000000000000000000000000000 --- a/src/sdl12/SDL_main/SDL_macosx_main.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser <dwaliss1@purdue.edu> - Non-NIB-Code & other changes: Max Horn <max@quendi.de> - - Feel free to customize this file to suit your needs -*/ - -#import <Cocoa/Cocoa.h> - -@interface SDLMain : NSObject -@end diff --git a/src/sdl12/SDL_main/SDL_macosx_main.m b/src/sdl12/SDL_main/SDL_macosx_main.m deleted file mode 100644 index 226afe13d257f0b78a1bc99e93b9631ebe4fa547..0000000000000000000000000000000000000000 --- a/src/sdl12/SDL_main/SDL_macosx_main.m +++ /dev/null @@ -1,374 +0,0 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser <dwaliss1@purdue.edu> - Non-NIB-Code & other changes: Max Horn <max@quendi.de> - - Feel free to customize this file to suit your needs -*/ - -#import "SDL.h" -#import "SDL_macosx_main.h" -#import <sys/param.h> /* for MAXPATHLEN */ -#import <unistd.h> - -/* For some reaon, Apple removed setAppleMenu from the headers in 10.4, - but the method still is there and works. To avoid warnings, we declare - it ourselves here. */ -@interface NSApplication(SDL_Missing_Methods) -- (void)setAppleMenu:(NSMenu *)menu; -@end - -/* Use this flag to determine whether we use SDLMain.nib or not */ -#define SDL_USE_NIB_FILE 0 - -/* Use this flag to determine whether we use CPS (docking) or not */ -#define SDL_USE_CPS 1 -#if SDL_USE_CPS -/* Portions of CPS.h */ -typedef struct CPSProcessSerNum -{ - UInt32 lo; - UInt32 hi; -} CPSProcessSerNum; - -extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); -extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); -extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); - -#endif /* SDL_USE_CPS */ - -static int gArgc; -static char **gArgv; -static BOOL gFinderLaunch; - -static void addArgument(const char *value) -{ - if(!gArgc) - gArgv = (char **)malloc(sizeof(*gArgv)); - else - { - char **newgArgv = (char **)realloc(gArgv, sizeof(*gArgv) * (gArgc + 1)); - if (!newgArgv) - { - newgArgv = malloc(sizeof(*gArgv) * (gArgc + 1)); - memcpy(newgArgv, gArgv, sizeof(*gArgv) * gArgc); - free(gArgv); - } - gArgv = newgArgv; - } - gArgc++; - gArgv[gArgc - 1] = (char *)malloc(sizeof(char) * (strlen(value) + 1)); - strcpy(gArgv[gArgc - 1], value); -} - -static NSString *getApplicationName(void) -{ - NSDictionary *dict; - NSString *appName = NULL; - - /* Determine the application name */ - dict = ( NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); - if (dict) - appName = [dict objectForKey: @"CFBundleName"]; - - if (![appName length]) - appName = [[NSProcessInfo processInfo] processName]; - - return appName; -} - -#if SDL_USE_NIB_FILE -/* A helper category for NSString */ -@interface NSString (ReplaceSubString) -- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; -@end -#endif - -@interface SDLApplication : NSApplication -@end - -@implementation SDLApplication -/* Invoked from the Quit menu item */ -- (void)terminate:(id)sender -{ -#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) - (void)sender; -#endif - /* Post a SDL_QUIT event */ - SDL_Event event; - event.type = SDL_QUIT; - SDL_PushEvent(&event); -} -@end - -/* The main class of the application, the application's delegate */ -@implementation SDLMain - -/* Set the working directory to the .app's parent directory */ -- (void) setupWorkingDirectory:(BOOL)shouldChdir -{ - if (shouldChdir) - { - char parentdir[MAXPATHLEN]; - CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); - if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) - { - assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */ - } - CFRelease(url); - CFRelease(url2); - } - -} - -#if SDL_USE_NIB_FILE - -/* Fix menu to contain the real app name instead of "SDL App" */ -- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName -{ - NSRange aRange; - NSEnumerator *enumerator; - NSMenuItem *menuItem; - - aRange = [[aMenu title] rangeOfString:@"SDL App"]; - if (aRange.length != 0) - [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; - - enumerator = [[aMenu itemArray] objectEnumerator]; - while ((menuItem = [enumerator nextObject])) - { - aRange = [[menuItem title] rangeOfString:@"SDL App"]; - if (aRange.length != 0) - [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; - if ([menuItem hasSubmenu]) - [self fixMenu:[menuItem submenu] withAppName:appName]; - } - [ aMenu sizeToFit ]; -} - -#else - -static void setApplicationMenu(void) -{ - /* warning: this code is very odd */ - NSMenu *appleMenu; - NSMenuItem *menuItem; - NSString *title; - NSString *appName; - - appName = getApplicationName(); - appleMenu = [[NSMenu alloc] initWithTitle:@""]; - - /* Add menu items */ - title = [@"About " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Hide " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; - - menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; - [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; - - [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Quit " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; - - - /* Put menu into the menubar */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; - [menuItem setSubmenu:appleMenu]; - [[NSApp mainMenu] addItem:menuItem]; - - /* Tell the application object that this is now the application menu */ - [NSApp setAppleMenu:appleMenu]; - - /* Finally give up our references to the objects */ - [appleMenu release]; - [menuItem release]; -} - -/* Create a window menu */ -static void setupWindowMenu(void) -{ - NSMenu *windowMenu; - NSMenuItem *windowMenuItem; - NSMenuItem *menuItem; - - windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; - - /* "Minimize" item */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; - [windowMenu addItem:menuItem]; - [menuItem release]; - - /* Put menu into the menubar */ - windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; - [windowMenuItem setSubmenu:windowMenu]; - [[NSApp mainMenu] addItem:windowMenuItem]; - - /* Tell the application object that this is now the window menu */ - [NSApp setWindowsMenu:windowMenu]; - - /* Finally give up our references to the objects */ - [windowMenu release]; - [windowMenuItem release]; -} - -/* Replacement for NSApplicationMain */ -static void CustomApplicationMain (int argc, char **argv) -{ -#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) - (void)argc; - (void)argv; -#endif - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - SDLMain *sdlMain; - - /* Ensure the application object is initialised */ - [SDLApplication sharedApplication]; - -#if SDL_USE_CPS - { - CPSProcessSerNum PSN; - /* Tell the dock about us */ - if (!CPSGetCurrentProcess(&PSN)) - if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) - if (!CPSSetFrontProcess(&PSN)) - [SDLApplication sharedApplication]; - } -#endif /* SDL_USE_CPS */ - - /* Set up the menubar */ - [NSApp setMainMenu:[[NSMenu alloc] init]]; - setApplicationMenu(); - setupWindowMenu(); - - /* Create SDLMain and make it the app delegate */ - sdlMain = [[SDLMain alloc] init]; - [NSApp setDelegate:sdlMain]; - - /* Start the main event loop */ - [NSApp run]; - - [sdlMain release]; - [pool release]; -} - -#endif - -- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename -{ -#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) - (void)theApplication; -#endif - addArgument("-iwad"); - addArgument([filename UTF8String]); - return YES; -} - -/* Called when the internal event loop has just started running */ -- (void) applicationDidFinishLaunching: (NSNotification *) note -{ -#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) - (void)note; -#endif - int status; - - /* Set the working directory to the .app's parent directory */ - [self setupWorkingDirectory:gFinderLaunch]; - -#if SDL_USE_NIB_FILE - /* Set the main menu to contain the real app name instead of "SDL App" */ - [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()]; -#endif - - if (!getenv("SRB2WADDIR")) - setenv("SRB2WADDIR", [[[NSBundle mainBundle] resourcePath] UTF8String], 1); - - /* Hand off to main application code */ - status = SDL_main (gArgc, gArgv); - - /* We're done, thank you for playing */ - exit(status); -} -@end - - -@implementation NSString (ReplaceSubString) - -- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString -{ - size_t bufferSize; - size_t selfLen = [self length]; - size_t aStringLen = [aString length]; - unichar *buffer; - NSRange localRange; - NSString *result; - - bufferSize = selfLen + aStringLen - aRange.length; - buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar)); - - /* Get first part into buffer */ - localRange.location = 0; - localRange.length = aRange.location; - [self getCharacters:buffer range:localRange]; - - /* Get middle part into buffer */ - localRange.location = 0; - localRange.length = aStringLen; - [aString getCharacters:(buffer+aRange.location) range:localRange]; - - /* Get last part into buffer */ - localRange.location = aRange.location + aRange.length; - localRange.length = selfLen - localRange.location; - [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; - - /* Build output string */ - result = [NSString stringWithCharacters:buffer length:bufferSize]; - - NSDeallocateMemoryPages(buffer, bufferSize); - - return result; -} - -@end - - - -#ifdef main -# undef main -#endif - - -/* Main entry point to executable - should *not* be SDL_main! */ -int main (int argc, char **argv) -{ - - /* Copy the arguments into a global variable */ - - /* This is passed if we are launched by double-clicking */ - if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { - gArgc = 1; - gFinderLaunch = YES; - } else { - gArgc = argc; - gFinderLaunch = NO; - } - gArgv = argv; - - /* Some additional arguments we always want to run with. */ - //addArgument("-opengl"); - -#if SDL_USE_NIB_FILE - [SDLApplication poseAsClass:[NSApplication class]]; - NSApplicationMain (argc, argv); -#else - CustomApplicationMain (argc, argv); -#endif - return 0; -} diff --git a/src/sdl12/SDL_main/SDL_openxdk_main.c b/src/sdl12/SDL_main/SDL_openxdk_main.c deleted file mode 100644 index 63db8da2d8f64f241bc05bc17a6609c270a4b65b..0000000000000000000000000000000000000000 --- a/src/sdl12/SDL_main/SDL_openxdk_main.c +++ /dev/null @@ -1,7 +0,0 @@ -/* Include the SDL main definition header */ -#include "SDL_main.h" - -void XBoxStartup() -{ - SDL_main(0, NULL); /// \todo ? -} diff --git a/src/sdl12/SDL_main/SDL_win32_main.c b/src/sdl12/SDL_main/SDL_win32_main.c deleted file mode 100644 index 46b20d0bd83590b0f23cf092ef5df4b46bf4d017..0000000000000000000000000000000000000000 --- a/src/sdl12/SDL_main/SDL_win32_main.c +++ /dev/null @@ -1,406 +0,0 @@ -/* - SDL_main.c, placed in the public domain by Sam Lantinga 4/13/98 - - The WinMain function -- calls your program's main() function -*/ - -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include <stdlib.h> -#define RPC_NO_WINDOWS_H -#include <windows.h> -#include <malloc.h> /* For _alloca() */ - -#include <tchar.h> - -#ifdef _WIN32_WCE -# define DIR_SEPERATOR TEXT("\\") -# define _tgetcwd(str,len) wcscpy(str,TEXT("")) -# define setbuf(f,b) -# define setvbuf(w,x,y,z) -# define _tremove(x) DeleteFile(x) -#else -# define DIR_SEPERATOR TEXT("/") -# include <direct.h> -#endif - -/* Include the SDL main definition header */ -#ifdef _MSC_VER -#pragma warning(disable : 4214 4244) -#endif -#include "SDL.h" -#include "SDL_main.h" -#ifdef _MSC_VER -#pragma warning(default : 4214 4244) -#endif -#include "../../win32/win_dbg.h" -#define USE_MESSAGEBOX - -#ifdef main -# ifndef _WIN32_WCE_EMULATION -# undef main -# endif /* _WIN32_WCE_EMULATION */ -#endif /* main */ - -/* The standard output files */ -//#ifdef _WIN32_WCE -//#define STDOUT_FILE TEXT("/Storage Card/SRB2DEMO/stdout.txt") -//#define STDERR_FILE TEXT("/Storage Card/SRB2DEMO/stderr.txt") -//#else -#define STDOUT_FILE TEXT("stdout.txt") -#define STDERR_FILE TEXT("stderr.txt") -//#endif - -#ifndef NO_STDIO_REDIRECT - static TCHAR stdoutPath[MAX_PATH]; - static TCHAR stderrPath[MAX_PATH]; -#endif - -#if defined(_WIN32_WCE) && _WIN32_WCE < 300 -/* seems to be undefined in Win CE although in online help */ -#define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t')) - -/* seems to be undefined in Win CE although in online help */ -char *strrchr(char *str, int c) -{ - char *p; - - /* Skip to the end of the string */ - p=str; - while (*p) - p++; - - /* Look for the given character */ - while ( (p >= str) && (*p != (CHAR)c) ) - p--; - - /* Return NULL if character not found */ - if ( p < str ) { - p = NULL; - } - return p; -} -#endif /* _WIN32_WCE < 300 */ - -/* Parse a command line buffer into arguments */ -static int ParseCommandLine(char *cmdline, char **argv) -{ - char *bufp; - int argc; - - argc = 0; - for ( bufp = cmdline; *bufp; ) { - /* Skip leading whitespace */ - while ( isspace(*bufp) ) { - ++bufp; - } - /* Skip over argument */ - if ( *bufp == '"' ) { - ++bufp; - if ( *bufp ) { - if ( argv ) { - argv[argc] = bufp; - } - ++argc; - } - /* Skip over word */ - while ( *bufp && (*bufp != '"') ) { - ++bufp; - } - } else { - if ( *bufp ) { - if ( argv ) { - argv[argc] = bufp; - } - ++argc; - } - /* Skip over word */ - while ( *bufp && ! isspace(*bufp) ) { - ++bufp; - } - } - if ( *bufp ) { - if ( argv ) { - *bufp = '\0'; - } - ++bufp; - } - } - if ( argv ) { - argv[argc] = NULL; - } - return(argc); -} - -/* Show an error message */ -static void ShowError(const char *title, const char *message) -{ -/* If USE_MESSAGEBOX is defined, you need to link with user32.lib */ -#ifdef USE_MESSAGEBOX - MessageBoxA(NULL, - message, - title, - MB_ICONEXCLAMATION|MB_OK); -#else - fprintf(stderr, "%s: %s\n", title, message); -#endif -} - -/* Pop up an out of memory message, returns to Windows */ -static BOOL OutOfMemory(void) -{ - ShowError("Fatal Error", "Out of memory - aborting"); - return FALSE; -} - -/* Remove the output files if there was no output written */ -static void __cdecl cleanup_output(void) -{ -#ifndef NO_STDIO_REDIRECT - FILE *file; - int empty; -#endif - - /* Flush the output in case anything is queued */ - fclose(stdout); - fclose(stderr); - -#ifndef NO_STDIO_REDIRECT - /* See if the files have any output in them */ - if ( stdoutPath[0] ) { - file = _tfopen(stdoutPath, TEXT("rb")); - if ( file ) { - empty = (fgetc(file) == EOF) ? 1 : 0; - fclose(file); - if ( empty ) { - _tremove(stdoutPath); - } - } - } - if ( stderrPath[0] ) { - file = _tfopen(stderrPath, TEXT("rb")); - if ( file ) { - empty = (fgetc(file) == EOF) ? 1 : 0; - fclose(file); - if ( empty ) { - _tremove(stderrPath); - } - } - } -#endif -} - -#if defined(_MSC_VER) && !defined(_WIN32_WCE) -/* The VC++ compiler needs main defined */ -#define console_main main -#endif - -/* This is where execution begins [console apps] */ -int console_main(int argc, char *argv[]) -{ - size_t n; - int st; - char *bufp, *appname; - - /* Get the class name from argv[0] */ - appname = argv[0]; - if ( (bufp=strrchr(argv[0], '\\')) != NULL ) { - appname = bufp+1; - } else - if ( (bufp=strrchr(argv[0], '/')) != NULL ) { - appname = bufp+1; - } - - if ( (bufp=strrchr(appname, '.')) == NULL ) - n = strlen(appname); - else - n = (bufp-appname); - - bufp = (char *)alloca(n+1); - if ( bufp == NULL ) { - return OutOfMemory(); - } - strncpy(bufp, appname, n); - bufp[n] = '\0'; - appname = bufp; - - /* Load SDL dynamic link library */ - if ( SDL_Init(SDL_INIT_NOPARACHUTE) < 0 ) { - ShowError("WinMain() error", SDL_GetError()); - return(FALSE); - } - atexit(cleanup_output); - atexit(SDL_Quit); - -#ifndef DISABLE_VIDEO -#if 0 - /* Create and register our class * - DJM: If we do this here, the user nevers gets a chance to - putenv(SDL_WINDOWID). This is already called later by - the (DIB|DX5)_CreateWindow function, so it should be - safe to comment it out here. - if ( SDL_RegisterApp(appname, CS_BYTEALIGNCLIENT, - GetModuleHandle(NULL)) < 0 ) { - ShowError("WinMain() error", SDL_GetError()); - exit(1); - }*/ -#else - /* Sam: - We still need to pass in the application handle so that - DirectInput will initialize properly when SDL_RegisterApp() - is called later in the video initialization. - */ - SDL_SetModuleHandle(GetModuleHandle(NULL)); -#endif /* 0 */ -#endif /* !DISABLE_VIDEO */ - - /* Run the application main() code */ - st = SDL_main(argc, argv); - - /* Exit cleanly, calling atexit() functions */ - //exit(0); - cleanup_output(); - SDL_Quit(); - - /* Hush little compiler, don't you cry... */ - return st; -} - -/* This is where execution begins [windowed apps] */ -#ifdef _WIN32_WCE -int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPWSTR szCmdLine, int sw) -#else -int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) -#endif -{ - HINSTANCE handle; - int Result = -1; - char **argv; - int argc; - LPSTR cmdline; -#ifdef _WIN32_WCE - size_t nLen; - LPTSTR bufp; -#else - LPSTR bufp; -#endif -#ifndef NO_STDIO_REDIRECT - FILE *newfp; -#endif - - /* Start up DDHELP.EXE before opening any files, so DDHELP doesn't - keep them open. This is a hack.. hopefully it will be fixed - someday. DDHELP.EXE starts up the first time DDRAW.DLL is loaded. - */ - hPrev = hInst = NULL; - sw = 0; - handle = LoadLibrary(TEXT("DDRAW.DLL")); - if ( handle != NULL ) { - FreeLibrary(handle); - } - -#ifndef NO_STDIO_REDIRECT - _tgetcwd( stdoutPath, sizeof( stdoutPath ) ); - _tcscat( stdoutPath, DIR_SEPERATOR STDOUT_FILE ); - - /* Redirect standard input and standard output */ - newfp = _tfreopen(stdoutPath, TEXT("w"), stdout); - -#ifndef _WIN32_WCE - if ( newfp == NULL ) { /* This happens on NT */ -#if !defined(stdout) - stdout = _tfopen(stdoutPath, TEXT("w")); -#else - newfp = _tfopen(stdoutPath, TEXT("w")); - if ( newfp ) { - *stdout = *newfp; - } -#endif - } -#endif /* _WIN32_WCE */ - - _tgetcwd( stderrPath, sizeof( stderrPath ) ); - _tcscat( stderrPath, DIR_SEPERATOR STDERR_FILE ); - - newfp = _tfreopen(stderrPath, TEXT("w"), stderr); -#ifndef _WIN32_WCE - if ( newfp == NULL ) { /* This happens on NT */ -#if !defined(stderr) - stderr = _tfopen(stderrPath, TEXT("w")); -#else - newfp = _tfopen(stderrPath, TEXT("w")); - if ( newfp ) { - *stderr = *newfp; - } -#endif - } -#endif /* _WIN32_WCE */ - - setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* Line buffered */ - setbuf(stderr, NULL); /* No buffering */ -#endif /* !NO_STDIO_REDIRECT */ - -#ifdef _WIN32_WCE - nLen = wcslen(szCmdLine)+128+1; - bufp = (wchar_t *)alloca(nLen*2); - wcscpy (bufp, TEXT("\"")); - GetModuleFileName(NULL, bufp+1, 128-3); - wcscpy (bufp+wcslen(bufp), TEXT("\" ")); - wcsncpy(bufp+wcslen(bufp), szCmdLine,nLen-wcslen(bufp)); - nLen = wcslen(bufp)+1; - cmdline = (char *)alloca(nLen); - if ( cmdline == NULL ) { - return OutOfMemory(); - } - WideCharToMultiByte(CP_ACP, 0, bufp, -1, cmdline, nLen, NULL, NULL); -#else - szCmdLine = NULL; - /* Grab the command line (use alloca() on Windows) */ - bufp = GetCommandLineA(); - cmdline = (LPSTR)alloca(strlen(bufp)+1); - if ( cmdline == NULL ) { - return OutOfMemory(); - } - strcpy(cmdline, bufp); -#endif - - /* Parse it into argv and argc */ - argc = ParseCommandLine(cmdline, NULL); - argv = (char **)alloca((argc+1)*(sizeof *argv)); - if ( argv == NULL ) { - return OutOfMemory(); - } - ParseCommandLine(cmdline, argv); - -#ifdef BUGTRAP - /* Try BugTrap. */ - if(InitBugTrap()) - Result = console_main(argc, argv); - else - { -#endif - - /* Run the main program (after a little SDL initialization) */ -#ifndef _WIN32_WCE - __try -#endif - { - Result = console_main(argc, argv); - } -#ifndef _WIN32_WCE - __except ( RecordExceptionInfo(GetExceptionInformation())) - { - SetUnhandledExceptionFilter(EXCEPTION_CONTINUE_SEARCH); //Do nothing here. - } -#endif - -#ifdef BUGTRAP - } /* BT failure clause. */ - - /* This is safe even if BT didn't start. */ - ShutdownBugTrap(); -#endif - - return Result; -} diff --git a/src/sdl12/SRB2CE/Makefile.cfg b/src/sdl12/SRB2CE/Makefile.cfg deleted file mode 100644 index 8d4ae3e48829f9c63b22e75ba5e16c420ba32ad9..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2CE/Makefile.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile.cfg for WinCE with GCC -# - -OPTS+=-D_WIN32_WCE -D_UNICODE -SDL_CFLAGS?= -SDL_LDFLAGS?= -NOHS=1 -NOHW=1 -NONET=1 -NOMIXER=1 -NOPNG=1 diff --git a/src/sdl12/SRB2CE/SRB2CE.zip b/src/sdl12/SRB2CE/SRB2CE.zip deleted file mode 100644 index 3ac8530dcb124cbda512a7d469da933c3fc974bf..0000000000000000000000000000000000000000 Binary files a/src/sdl12/SRB2CE/SRB2CE.zip and /dev/null differ diff --git a/src/sdl12/SRB2CE/cehelp.c b/src/sdl12/SRB2CE/cehelp.c deleted file mode 100644 index 13505cff732c68c7168b6830680064498be39304..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2CE/cehelp.c +++ /dev/null @@ -1,446 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 2004-2018 by Sonic Team Jr. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// DESCRIPTION: -// stub and replacement "ANSI" C functions for use under Windows CE -// -//----------------------------------------------------------------------------- - -#include "../../doomdef.h" -#include "cehelp.h" - -#define _SEC_IN_MINUTE 60 -#define _SEC_IN_HOUR 3600 -#define _SEC_IN_DAY 86400 - -static const int DAYS_IN_MONTH[12] = -{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - -#define _DAYS_IN_MONTH(x) ((x == 1) ? days_in_feb : DAYS_IN_MONTH[x]) - -static const int _DAYS_BEFORE_MONTH[12] = -{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; - -#define _ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || (((y)+1900) % 400) == 0)) -#define _DAYS_IN_YEAR(year) (_ISLEAP(year) ? 366 : 365) - -char *strerror(int ecode) -{ - static char buff[1024 + 1]; - DWORD dwMsgLen = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, - ecode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &buff[0], 1024, NULL); - return buff; -} - -int unlink( const char *filename ) -{ - return remove(filename); -} - -int remove( const char *path ) -{ - return DeleteFileA(path)-1; -} - -int rename( const char *oldname, const char *newname ) -{ - return MoveFileA(oldname, newname)!=0; -} - -static inline void STToTM(const SYSTEMTIME *st, struct tm *tm) -{ - if (!st || !tm) return; - tm->tm_sec = st->wSecond; - tm->tm_min = st->wMinute; - tm->tm_hour = st->wHour; - tm->tm_mday = st->wDay; - tm->tm_mon = st->wMonth - 1; - tm->tm_year = st->wYear - 1900; - tm->tm_wday = st->wDayOfWeek; - tm->tm_yday = 0; - tm->tm_isdst = 0; -} - -time_t time(time_t *T) -{ - time_t returntime; - SYSTEMTIME st; - struct tm stft; - GetSystemTime(&st); - STToTM(&st,&stft); - returntime = mktime(&stft); - if (T) *T = returntime; - return returntime; -} - -static inline UINT64 TTtoFT(const time_t wt, FILETIME *ft) -{ - UINT64 temptime = wt; // FILETIME: 1/(10^7) secs since January 1, 1601 - temptime *= 10000000; // time_t : 1 secs since January 1, 1970 - // 369 years * 365 days * 24 hours * 60 mins * 60 secs * 10 - // 123 leaps days * 24 hours * 60 mins * 60 secs * 10 - temptime += 116444736000000000; - if (ft) CopyMemory(ft,&temptime,sizeof (ULARGE_INTEGER)); - return temptime; -} - -static struct tm cehelptm; - -struct tm * localtime(const time_t *CLOCK) -{ - SYSTEMTIME st; - FILETIME stft; - UINT64 ftli = 0; - if (CLOCK) ftli = TTtoFT(*CLOCK, &stft); - if (ftli) - FileTimeToSystemTime(&stft,&st); - else - GetSystemTime(&st); - STToTM(&st,&cehelptm); - if (st.wYear >= 1970) - return &cehelptm; - else - return NULL; -} - -static void validate_structure (struct tm *tim_p) // from newlib -{ - div_t res; - int days_in_feb = 28; - - /* calculate time & date to account for out of range values */ - if (tim_p->tm_sec < 0 || tim_p->tm_sec > 59) - { - res = div (tim_p->tm_sec, 60); - tim_p->tm_min += res.quot; - if ((tim_p->tm_sec = res.rem) < 0) - { - tim_p->tm_sec += 60; - --tim_p->tm_min; - } - } - - if (tim_p->tm_min < 0 || tim_p->tm_min > 59) - { - res = div (tim_p->tm_min, 60); - tim_p->tm_hour += res.quot; - if ((tim_p->tm_min = res.rem) < 0) - { - tim_p->tm_min += 60; - --tim_p->tm_hour; - } - } - - if (tim_p->tm_hour < 0 || tim_p->tm_hour > 23) - { - res = div (tim_p->tm_hour, 24); - tim_p->tm_mday += res.quot; - if ((tim_p->tm_hour = res.rem) < 0) - { - tim_p->tm_hour += 24; - --tim_p->tm_mday; - } - } - - if (tim_p->tm_mon > 11) - { - res = div (tim_p->tm_mon, 12); - tim_p->tm_year += res.quot; - if ((tim_p->tm_mon = res.rem) < 0) - { - tim_p->tm_mon += 12; - --tim_p->tm_year; - } - } - - if (_DAYS_IN_YEAR (tim_p->tm_year) == 366) - days_in_feb = 29; - - if (tim_p->tm_mday <= 0) - { - while (tim_p->tm_mday <= 0) - { - if (--tim_p->tm_mon == -1) - { - tim_p->tm_year--; - tim_p->tm_mon = 11; - days_in_feb = - ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ? - 29 : 28); - } - tim_p->tm_mday += _DAYS_IN_MONTH (tim_p->tm_mon); - } - } - else - { - while (tim_p->tm_mday > _DAYS_IN_MONTH (tim_p->tm_mon)) - { - tim_p->tm_mday -= _DAYS_IN_MONTH (tim_p->tm_mon); - if (++tim_p->tm_mon == 12) - { - tim_p->tm_year++; - tim_p->tm_mon = 0; - days_in_feb = - ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ? - 29 : 28); - } - } - } -} - -time_t mktime (struct tm *tim_p) // from newlib -{ - time_t tim = 0; - long days = 0; - int year; - - /* validate structure */ - validate_structure (tim_p); - - /* compute hours, minutes, seconds */ - tim += tim_p->tm_sec + (tim_p->tm_min * _SEC_IN_MINUTE) + - (tim_p->tm_hour * _SEC_IN_HOUR); - - /* compute days in year */ - days += tim_p->tm_mday - 1; - days += _DAYS_BEFORE_MONTH[tim_p->tm_mon]; - if (tim_p->tm_mon > 1 && _DAYS_IN_YEAR (tim_p->tm_year) == 366) - days++; - - /* compute day of the year */ - tim_p->tm_yday = days; - - if (tim_p->tm_year > 10000 - || tim_p->tm_year < -10000) - { - return (time_t) -1; - } - - /* compute days in other years */ - if (tim_p->tm_year > 70) - { - for (year = 70; year < tim_p->tm_year; year++) - days += _DAYS_IN_YEAR (year); - } - else if (tim_p->tm_year < 70) - { - for (year = 69; year > tim_p->tm_year; year--) - days -= _DAYS_IN_YEAR (year); - days -= _DAYS_IN_YEAR (year); - } - - /* compute day of the week */ - if ((tim_p->tm_wday = (days + 4) % 7) < 0) - tim_p->tm_wday += 7; - - /* compute total seconds */ - tim += (days * _SEC_IN_DAY); - - return tim; -} - -#undef WINAPI -#define WINAPI __stdcall //__delcspec(dllexport) - -#ifdef _MSC_VER -//#pragma warning(disable : 4273) -#endif - - -static __forceinline int STRtoWSTR(LPCSTR lpMultiByteStr, int cchMultiByte, - LPWSTR lpWideCharStr, int cchWideChar) -{ - return MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,lpMultiByteStr, - cchMultiByte,lpWideCharStr,cchWideChar); -} - -static __forceinline int WSTRtoSTR(LPCWSTR lpWideCharStr, int cchWideChar, - LPSTR lpMultiByteStr, int cbMultiByte) -{ - return WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK|WC_SEPCHARS, - lpWideCharStr,cchWideChar,lpMultiByteStr,cbMultiByte,NULL,NULL); -} - -DWORD WINAPI FormatMessageA( - DWORD dwFlags, - LPCVOID lpSource, - DWORD dwMessageId, - DWORD dwLanguageId, - LPSTR lpBuffer, - DWORD nSize, - va_list *Arguments) -{ - const int nSizeW = STRtoWSTR(lpBuffer,nSize,NULL,0); - int nSizeF = 0; - LPWSTR lpBufferW = alloca(sizeof (wchar_t)*nSizeW); - LPWSTR lpSourceW = NULL; - - if (!lpBufferW) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - ZeroMemory(lpBuffer,nSize); - return nSizeF; - } - - if (dwFlags & FORMAT_MESSAGE_FROM_STRING) - { - const int sLen = STRtoWSTR(lpSource, -1, NULL, 0); - lpSourceW = alloca(sizeof (wchar_t)*sLen); - - if (lpSourceW) - STRtoWSTR(lpSource, -1, lpSourceW, sLen); - else - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return nSizeF; - } - } - - if (lpSourceW) - nSizeF = FormatMessageW(dwFlags, lpSourceW, dwMessageId, dwLanguageId, - lpBufferW, nSizeW, Arguments); - else - nSizeF = FormatMessageW(dwFlags, lpSource, dwMessageId, dwLanguageId, - lpBufferW, nSizeW, Arguments); - - return WSTRtoSTR(lpBufferW, nSizeF, lpBuffer, nSize); -} - -BOOL WINAPI DeleteFileA( - LPCSTR lpFileName) -{ - const int sLen = STRtoWSTR(lpFileName, -1, NULL, 0); - LPWSTR lpFileNameW = alloca(sizeof (wchar_t)*sLen); - - if (lpFileNameW) - STRtoWSTR(lpFileName, -1, lpFileNameW, sLen); - else - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return 0; - } - - return DeleteFileW(lpFileNameW); -} - -BOOL WINAPI MoveFileA( - LPCSTR lpExistingFileName, - LPCSTR lpNewFileName -) -{ - const int sLen1 = STRtoWSTR(lpExistingFileName, -1, NULL, 0); - LPWSTR lpExistingFileNameW = alloca(sizeof (wchar_t)*sLen1); - - const int sLen2 = STRtoWSTR(lpNewFileName, -1, NULL, 0); - LPWSTR lpNewFileNameW = alloca(sizeof (wchar_t)*sLen2); - - - if (!lpExistingFileNameW || !lpNewFileNameW) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return 0; - } - - STRtoWSTR(lpExistingFileName, -1, lpExistingFileNameW, sLen1); - STRtoWSTR(lpNewFileName, -1, lpNewFileNameW, sLen2); - - return MoveFileW(lpExistingFileNameW, lpNewFileNameW); -} - - -HANDLE WINAPI CreateFileA( - LPCSTR lpFileName, - DWORD dwDesiredAccess, - DWORD dwShareMode, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, - DWORD dwCreationDisposition, - DWORD dwFlagsAndAttributes, - HANDLE hTemplateFile) -{ - const int sLen = STRtoWSTR(lpFileName, -1, NULL, 0); - LPWSTR lpFileNameW = alloca(sizeof (wchar_t)*sLen); - - if (lpFileNameW) - STRtoWSTR(lpFileName, -1, lpFileNameW, sLen); - else - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return INVALID_HANDLE_VALUE; - } - - return CreateFileW(lpFileNameW, dwDesiredAccess, dwShareMode, - lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, - hTemplateFile); -} - -BOOL WINAPI CreateDirectoryA( - LPCSTR lpPathName, - LPSECURITY_ATTRIBUTES lpSecurityAttributes) -{ - const int sLen = STRtoWSTR(lpPathName, -1, NULL, 0); - LPWSTR lpPathNameW = alloca(sizeof (wchar_t)*sLen); - - if (lpPathNameW) - STRtoWSTR(lpPathName, -1, lpPathNameW, sLen); - else - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return 0; - } - - return CreateDirectoryW(lpPathNameW, lpSecurityAttributes); -} - -int WINAPI MessageBoxA( - HWND hWnd , - LPCSTR lpText, - LPCSTR lpCaption, - UINT uType) -{ - const int sLen1 = STRtoWSTR(lpText, -1, NULL, 0); - LPWSTR lpTextW = alloca(sizeof (wchar_t)*sLen1); - - const int sLen2 = STRtoWSTR(lpCaption, -1, NULL, 0); - LPWSTR lpCaptionW = alloca(sizeof (wchar_t)*sLen2); - - - if (!lpTextW || !lpCaptionW) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return 0; - } - - STRtoWSTR(lpText, -1, lpTextW, sLen1); - STRtoWSTR(lpCaption, -1, lpCaptionW, sLen2); - - return MessageBoxW(hWnd, lpTextW, lpCaptionW, uType); -} - -VOID WINAPI OutputDebugStringA( - LPCSTR lpOutputString) -{ - const int sLen = STRtoWSTR(lpOutputString, -1, NULL, 0); - LPWSTR lpOutputStringW = alloca(sizeof (wchar_t)*sLen); - - if (lpOutputStringW) - STRtoWSTR(lpOutputString, -1, lpOutputStringW, sLen); - else - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return; - } - - OutputDebugStringW(lpOutputStringW); -} diff --git a/src/sdl12/SRB2CE/cehelp.h b/src/sdl12/SRB2CE/cehelp.h deleted file mode 100644 index 3ed0d9dd4bc55f94139b9f581e600e5438f68dc3..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2CE/cehelp.h +++ /dev/null @@ -1,63 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 2004-2018 by Sonic Team Jr. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// DESCRIPTION: -// stub and replacement "ANSI" C functions for use under Windows CE -// -//----------------------------------------------------------------------------- - -#ifndef __I_WINCE__ -#define __I_WINCE__ - -#ifdef USEASMCE -#define USEASM // Remline if NASM doesn't work on x86 targets -#endif - -char *strerror(int ecode); -int access(const char *path, int amode); -int unlink( const char *filename ); -int remove( const char *path ); -int rename( const char *oldname, const char *newname ); -//CreateDirectoryEx( const char *currectpath, const char *path,SECURITY_ATTRIBUTES) - -#ifndef _TIME_T_DEFINED -typedef long time_t; /* time value */ -#define _TIME_T_DEFINED /* avoid multiple def's of time_t */ -#endif - -time_t time(time_t *T); - -#ifndef __GNUC__ -#ifndef _TM_DEFINED -struct tm { - int tm_sec; /* seconds after the minute - [0,59] */ - int tm_min; /* minutes after the hour - [0,59] */ - int tm_hour; /* hours since midnight - [0,23] */ - int tm_mday; /* day of the month - [1,31] */ - int tm_mon; /* months since January - [0,11] */ - int tm_year; /* years since 1900 */ - int tm_wday; /* days since Sunday - [0,6] */ - int tm_yday; /* days since January 1 - [0,365] */ - int tm_isdst; /* daylight savings time flag */ - }; -#define _TM_DEFINED -#endif - -struct tm * localtime(const time_t *CLOCK); - -time_t mktime (struct tm *tim_p); -#endif - -#endif diff --git a/src/sdl12/SRB2DC/.gitignore b/src/sdl12/SRB2DC/.gitignore deleted file mode 100644 index a966585d4dc8067dc64060c2883af2c65e394039..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2DC/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/scramble diff --git a/src/sdl12/SRB2DC/IP.BIN b/src/sdl12/SRB2DC/IP.BIN deleted file mode 100644 index c3366213bde1c6b5dc03db4cfdab85c1c74ef5fc..0000000000000000000000000000000000000000 Binary files a/src/sdl12/SRB2DC/IP.BIN and /dev/null differ diff --git a/src/sdl12/SRB2DC/Makefile.cfg b/src/sdl12/SRB2DC/Makefile.cfg deleted file mode 100644 index 3edaf8a168d98e0b2e30f23483d8feabb0d100b6..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2DC/Makefile.cfg +++ /dev/null @@ -1,53 +0,0 @@ -# -# Makefile.cfg for SRB2/Dreamcast -# - -#include $(KOS_BASE)/Makefile.rules - -# -#hmmm, the Dreamcast -# - - HOSTCC:=$(CC) - CC=$(KOS_CC) - PREFIX=$(KOS_CC_BASE)/bin/$(KOS_CC_PREFIX) - OBJDUMP=$(PREFIX)-objdump - OBJCOPY=$(PREFIX)-objcopy - - #NOHW=1 #No working MiniGL right now - NOHS=1 #No HWSound right now -ifndef LWIP - NONET=1 #No LWIP -endif - #i_net_o=$(OBJDIR)/i_udp.o #use KOS's UDP - #NOMIXER=1 #Basic sound only - NOIPX=1 #No IPX network code - NOPNG=1 #No Screenshot - - OPTS=$(KOS_CFLAGS) -DUNIXCOMMON -DDC -ifndef NOHW - OPTS+=-DSTATIC_OPENGL -DMINI_GL_COMPATIBILITY -DKOS_GL_COMPATIBILITY -endif - SDL_CFLAGS?=-I$(KOS_BASE)/addons/include/SDL - SDL_LDFLAGS?=-lSDL - LDFLAGS=$(KOS_LDFLAGS) - LIBS:=$(KOS_LIBS) -lconio -lm -ifndef NOMIXER - LIBS:=-loggvorbisplay -lSDL $(LIBS) -endif - -ifdef LWIP - OPTS+=-I$(KOS_BASE)/../kos-ports/lwip/kos/include -I$(KOS_BASE)/../kos-ports/lwip/lwip/src/include/ipv4 -I$(KOS_BASE)/../kos-ports/lwip/lwip/src/include -DIPv4 - LIBS:=-llwip4 -lkosutils $(LIBS) - OPTS+=-DHAVE_LWIP -endif -ifndef NOHW - LIBS+=-lgl -endif - - i_system_o+=$(OBJDIR)/dchelp.o - i_main_o=$(KOS_START) $(OBJDIR)/i_main.o $(OBJEXTRA) - - # name of the exefile - EXENAME?=SRB2.elf - BINNAME?=SRB2.BIN diff --git a/src/sdl12/SRB2DC/SELFBOOT.BIN b/src/sdl12/SRB2DC/SELFBOOT.BIN deleted file mode 100644 index a87ee386927e4dd72d947aa08faecd1b94677c93..0000000000000000000000000000000000000000 Binary files a/src/sdl12/SRB2DC/SELFBOOT.BIN and /dev/null differ diff --git a/src/sdl12/SRB2DC/VMU.xbm b/src/sdl12/SRB2DC/VMU.xbm deleted file mode 100644 index 0d56985f350e9f1476b53169f551d945caa60fc2..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2DC/VMU.xbm +++ /dev/null @@ -1,19 +0,0 @@ -#define VMU_width 48 -#define VMU_height 32 -static unsigned char VMU_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x58, 0x75, 0x00, 0x00, 0x00, 0x00, 0xee, 0xaa, 0x00, 0x00, - 0x00, 0x86, 0x55, 0x55, 0x01, 0x00, 0x00, 0xda, 0xc8, 0xaf, 0x00, 0x00, - 0x00, 0x62, 0x55, 0x54, 0x00, 0x00, 0x00, 0x32, 0xa2, 0x6c, 0x00, 0x00, - 0x00, 0x5c, 0x55, 0xfd, 0x01, 0x00, 0x00, 0xac, 0x88, 0xaa, 0x02, 0x00, - 0x00, 0x54, 0x75, 0x55, 0x05, 0x00, 0x00, 0xac, 0xbf, 0xaa, 0x0a, 0x00, - 0x00, 0xd6, 0x61, 0x55, 0x15, 0x00, 0x00, 0xe9, 0xc0, 0xaa, 0x2a, 0x00, - 0x00, 0x39, 0x40, 0x55, 0x55, 0x00, 0x00, 0x6d, 0xc0, 0xaa, 0xbe, 0x00, - 0x00, 0x6d, 0x40, 0xd5, 0xc3, 0x00, 0x00, 0x6d, 0xc0, 0xea, 0x00, 0x00, - 0x00, 0x29, 0x60, 0xf5, 0x00, 0x00, 0x00, 0x26, 0xe0, 0xfa, 0x00, 0x00, - 0x00, 0x58, 0xb8, 0xbd, 0x00, 0x00, 0x00, 0x84, 0x07, 0xdf, 0x00, 0x00, - 0x00, 0x08, 0x20, 0xae, 0x00, 0x00, 0x00, 0x30, 0xc0, 0x5f, 0x01, 0x00, - 0x00, 0xc0, 0x3f, 0xb8, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; diff --git a/src/sdl12/SRB2DC/dchelp.c b/src/sdl12/SRB2DC/dchelp.c deleted file mode 100644 index 1468baa8b8bbc6da300828dd584a6d016f108494..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2DC/dchelp.c +++ /dev/null @@ -1,134 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 2006-2018 by Sonic Team Jr. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// DESCRIPTION: -// stub and replacement "ANSI" C functions for use on Dreamcast/KOS -// -//----------------------------------------------------------------------------- -#include <kos/fs.h> -#include <errno.h> -#ifndef HAVE_LWIP -#include <sys/socket.h> -#endif -#include "../../doomdef.h" -#include "dchelp.h" - -int access(const char *path, int amode) -{ - file_t handle = FILEHND_INVALID; - - if (amode == F_OK || amode == R_OK) - handle=fs_open(path,O_RDONLY); - else if (amode == (R_OK|W_OK)) - handle=fs_open(path,O_RDWR); - else if (amode == W_OK) - handle=fs_open(path,O_WRONLY); - - if (handle != FILEHND_INVALID) - { - fs_close(handle); - return 0; - } - - return -1; -} - -double hypot(double x, double y) -{ - double ax, yx, yx2, yx1; - if (abs(y) > abs(x)) // |y|>|x| - { - ax = abs(y); // |y| => ax - yx = (x/y); - } - else // |x|>|y| - { - ax = abs(x); // |x| => ax - yx = (x/y); - } - yx2 = yx*yx; // (x/y)^2 - yx1 = sqrt(1+yx2); // (1 + (x/y)^2)^1/2 - return ax*yx1; // |x|*((1 + (x/y)^2)^1/2) -} - -#if !(defined (NONET) || defined (NOMD5)) -#ifdef HAVE_LWIP - -#include <lwip/lwip.h> - -static uint8 ip[4]; -static char *h_addr_listtmp[2] = {ip, NULL}; -static struct hostent hostenttmp = {NULL, NULL, 0, 1, h_addr_listtmp}; - -struct hostent *gethostbyname(const char *name) -{ - struct sockaddr_in dnssrv; - dnssrv.sin_family = AF_INET; - dnssrv.sin_port = htons(53); - dnssrv.sin_addr.s_addr = htonl(0x0a030202); ///< what? - if (lwip_gethostbyname(&dnssrv, name, ip) < 0) - return NULL; - else - return &hostenttmp; -} -#else - -struct hostent *gethostbyname(const char *name) -{ - (void)name; - return NULL; -} - -int ioctl(int s, long cmd, void *argp) -{ - return fs_ioctl(s, argp, cmd); //FIONBIO? -} - -int select(int maxfdp1, void *readset, void *writeset, void *exceptset, - void *timeout) -{ - (void)maxfdp1; - (void)readset; - (void)writeset; - (void)exceptset; - (void)timeout; - errno = EAFNOSUPPORT; - return -1; -} - -int getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen) -{ - (void)s; - (void)level; //SOL_SOCKET - (void)optname; //SO_RCVBUF, SO_ERROR - (void)optval; - (void)optlen; - errno = EAFNOSUPPORT; - return -1; -} - -int setsockopt (int s, int level, int optname, void *optval, socklen_t optlen) -{ - (void)s; - (void)level; //SOL_SOCKET - (void)optname; //SO_REUSEADDR, SO_BROADCAST, SO_RCVBUF - (void)optval; - (void)optlen; - errno = EAFNOSUPPORT; - return -1; -} - -#endif -#endif diff --git a/src/sdl12/SRB2DC/dchelp.h b/src/sdl12/SRB2DC/dchelp.h deleted file mode 100644 index 3647f9c8952a3d3adf94cdf60729e586e55ee369..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2DC/dchelp.h +++ /dev/null @@ -1,51 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 2006-2018 by Sonic Team Jr. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// DESCRIPTION: -// stub and replacement "ANSI" C functions for use on Dreamcast/KOS -// -//----------------------------------------------------------------------------- - -#ifndef __I_DREAMCAST__ -#define __I_DREAMCAST__ - -struct hostent -{ - char *h_name; /* Official name of host. */ - char **h_aliases; /* Alias list. */ - int h_addrtype; /* Host address type. */ - int h_length; /* Length of address. */ - char **h_addr_list; /* List of addresses from name server. */ -#define h_addr h_addr_list[0] /* Address, for backward compatibility. */ -}; - -struct hostent *gethostbyname(const char *name); - -#ifndef HAVE_LWIP -#define INADDR_NONE ((uint32) 0xffffffff) -#define INADDR_LOOPBACK ((uint32) 0x7f000001) -#define SOCK_STREAM 1 -#define FIONBIO 0 -#define SOL_SOCKET 0 -#define SO_ERROR 0 -#define SO_REUSEADDR 0 -#define SO_BROADCAST 0 -#define SO_RCVBUF 0 -int ioctl(int s, long cmd, void *argp); -int select(int maxfdp1, void *readset, void *writeset, void *exceptset, void *timeout); -int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); -int setsockopt(int s, int level, int optname, void *optval, socklen_t optlen); -#endif -#endif diff --git a/src/sdl12/SRB2DC/i_udp.c b/src/sdl12/SRB2DC/i_udp.c deleted file mode 100644 index cf7654c103e2a23303df1b3a769974099d879f97..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2DC/i_udp.c +++ /dev/null @@ -1,455 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// Copyright (C) 1993-1996 by id Software, Inc. -// Portions Copyright (C) 2005-2018 by Sonic Team Jr. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief KOS UDP network interface - -#include "../../doomdef.h" - -#include "../../i_system.h" -#include "../../d_event.h" -#include "../../d_net.h" -#include "../../m_argv.h" - -#include "../../doomstat.h" - -#include "../../i_net.h" - -#include "../../z_zone.h" - -#include "../../i_tcp.h" - -#include <kos/net.h> -//#include <net/net_ipv4.h> -#define NET_NONE 0x00000000 -#define NET_LOCAL 0x0100007F -#define NET_ANY 0xFFFFFFFF - -#define MAXBANS 20 - -typedef struct -{ - uint32 host; - uint16 port; -} IPaddress; - -static IPaddress clientaddress[MAXNETNODES+1]; -static boolean nodeconnected[MAXNETNODES+1]; - -static int mysocket = 0; -static boolean init_KOSUDP_driver = false; - -static size_t numbans = 0; -static IPaddress banned[MAXBANS]; -static boolean KOSUDP_bannednode[MAXNETNODES+1]; /// \note do we really need the +1? - -static inline int net_udp_sendto(int sock, const uint8 *data, int size, uint16 rem_port, uint32 rem_addr) -{ - uint8 dst_ip[4] = {((uint8*)(&(rem_addr)))[0], - ((uint8*)(&(rem_addr)))[1], - ((uint8*)(&(rem_addr)))[2], - ((uint8*)(&(rem_addr)))[3]}; - return net_udp_send_raw(net_default_dev, clientaddress[0].port, rem_port, dst_ip, data, size); - (void)sock; -} - -static inline int net_udp_recvfrom(int sock, uint8 *buf, int size, uint16 *rem_port, uint32 *rem_addr) -{ - return net_udp_recv(sock, buf, size); - (void)rem_port; - (void)rem_addr; -} - -static const char *KOSUDP_AddrToStr(IPaddress* sk) -{ - static char s[22]; // 255.255.255.255:65535 - sprintf(s,"%d.%d.%d.%d:%d", - ((uint8*)(&(sk->host)))[3], - ((uint8*)(&(sk->host)))[2], - ((uint8*)(&(sk->host)))[1], - ((uint8*)(&(sk->host)))[0], - net_ntohs(sk->port)); - return s; -} - -static const char *KOSUDP_GetNodeAddress(int node) -{ - if (!nodeconnected[node]) - return NULL; - return KOSUDP_AddrToStr(&clientaddress[node]); -} - -static const char *KOSUDP_GetBanAddress(size_t ban) -{ - if (ban > numbans) - return NULL; - return KOSUDP_AddrToStr(&banned[ban]); -} - -static boolean KOSUDP_cmpaddr(IPaddress* a, IPaddress* b) -{ - return (a->host == b->host && (b->port == 0 || a->port == b->port)); -} - -static SINT8 getfreenode(void) -{ - SINT8 j; - - for (j = 0; j < MAXNETNODES; j++) - if (!nodeconnected[j]) - { - nodeconnected[j] = true; - return j; - } - return -1; -} - -static void KOSUDP_Get(void) -{ - int size; - size_t i; - SINT8 j; - IPaddress temp = {clientaddress[BROADCASTADDR].host,clientaddress[BROADCASTADDR].port}; - - size = net_udp_recvfrom(mysocket,(char *)&doomcom->data, MAXPACKETLENGTH, &temp.port, &temp.host); - if (size == 0) - { - doomcom->remotenode = -1; // no packet - return; - } - - // find remote node number - for (i = 0; i < MAXNETNODES; i++) - if (KOSUDP_cmpaddr(&temp, &(clientaddress[i]))) - { - doomcom->remotenode = (INT16)i; // good packet from a game player - doomcom->datalength = (INT16)size; - return; - } - - // not found - - // find a free slot - j = getfreenode(); - if (j > 0) - { - M_Memcpy(&clientaddress[j], &temp, sizeof (temp)); - DEBFILE(va("New node detected: node:%d address:%s\n", j, - KOSUDP_GetNodeAddress(j))); - doomcom->remotenode = (INT16)j; // good packet from a game player - doomcom->datalength = (INT16)size; - // check if it's a banned dude so we can send a refusal later - for (i = 0; i < numbans; i++) - if (KOSUDP_cmpaddr(&temp, &banned[i])) - { - KOSUDP_bannednode[j] = true; - DEBFILE("This dude has been banned\n"); - break; - } - if (i == numbans) - KOSUDP_bannednode[j] = false; - return; - } - - DEBFILE("New node detected: No more free slots\n"); - doomcom->remotenode = -1; // no packet -} - -#if 0 -static boolean KOSUDP_CanSend(void) -{ - return true; -} -#endif - -static void KOSUDP_Send(void) -{ - const IPaddress *nodeinfo; - - if (!doomcom->remotenode || !nodeconnected[doomcom->remotenode]) - return; - - nodeinfo = clientaddress + doomcom->remotenode; - - if (net_udp_sendto(mysocket, (char *)&doomcom->data, doomcom->datalength, nodeinfo->port, nodeinfo->host) == -1) - { - CONS_Printf("KOSUDP: error sending data\n"); - } -} - -static void KOSUDP_FreeNodenum(int numnode) -{ - // can't disconnect from self :) - if (!numnode) - return; - - DEBFILE(va("Free node %d (%s)\n", numnode, KOSUDP_GetNodeAddress(numnode))); - - nodeconnected[numnode] = false; - - memset(&clientaddress[numnode], 0, sizeof (IPaddress)); -} - -static int KOSUDP_Socket(void) -{ - int temp = 0; - uint16 portnum = 0; - const uint32 hostip = net_default_dev?net_ntohl(net_ipv4_address(net_default_dev->ip_addr)):NET_LOCAL; - //Hurdler: I'd like to put a server and a client on the same computer - //Logan: Me too - //BP: in fact for client we can use any free port we want i have read - // in some doc that connect in udp can do it for us... - //Alam: where? - if (M_CheckParm("-clientport")) - { - if (!M_IsNextParm()) - I_Error("syntax: -clientport <portnum>"); - portnum = net_ntohs(atoi(M_GetNextParm())); - } - else - portnum = net_ntohs(sock_port); - - temp = net_udp_sock_open(portnum, hostip, portnum, NET_NONE); - if (temp) - { - int btemp = net_udp_sock_open(portnum, hostip, portnum, NET_ANY); - clientaddress[0].port = portnum; - clientaddress[0].host = NET_NONE; - if (btemp) - { - clientaddress[BROADCASTADDR].port = net_ntohs(sock_port); - clientaddress[BROADCASTADDR].host = NET_ANY; - } - else - { - CONS_Printf("KOSUDP: can't setup broadcast sock\n"); - net_udp_sock_close(temp); - return 0; - } - } - else - { - CONS_Printf("KOSUDP: can't setup main sock\n"); - return 0; - } - - doomcom->extratics = 1; // internet is very high ping - - return temp; -} - -static void I_ShutdownKOSUDPDriver(void) -{ - //net_shutdown(); - init_KOSUDP_driver = false; -} - -static void I_InitKOSUDPDriver(void) -{ - if (init_KOSUDP_driver) - I_ShutdownKOSUDPDriver(); - else - net_init(); - D_SetDoomcom(); - memset(&clientaddress,0,sizeof (clientaddress)); - init_KOSUDP_driver = true; -} - -static void KOSUDP_CloseSocket(void) -{ - if (mysocket) - net_udp_sock_close(mysocket); - mysocket = 0; -} - -static SINT8 KOSUDP_NetMakeNodewPort(const char *hostname, const char* port) -{ - SINT8 newnode; - uint16 portnum = net_ntohs(sock_port); - - if (port && !port[0]) - portnum = net_ntohs((UINT16)atoi(port)); - - newnode = getfreenode(); - if (newnode == -1) - return -1; - // find ip of the server - clientaddress[newnode].port = portnum; - clientaddress[newnode].host = inet_addr(hostname); - - if (clientaddress[newnode].host == NET_NONE) - { - free(hostname); - return -1; - } - return newnode; -} - -static boolean KOSUDP_OpenSocket(void) -{ - size_t i; - - memset(clientaddress, 0, sizeof (clientaddress)); - - for (i = 0; i < MAXNETNODES; i++) - nodeconnected[i] = false; - - //CONS_Printf("KOSUDP Code starting up\n"); - - nodeconnected[0] = true; // always connected to self - nodeconnected[BROADCASTADDR] = true; - I_NetSend = KOSUDP_Send; - I_NetGet = KOSUDP_Get; - I_NetCloseSocket = KOSUDP_CloseSocket; - I_NetFreeNodenum = KOSUDP_FreeNodenum; - I_NetMakeNodewPort = KOSUDP_NetMakeNodewPort; - - //I_NetCanSend = KOSUDP_CanSend; - - // build the socket but close it first - KOSUDP_CloseSocket(); - mysocket = KOSUDP_Socket(); - - if (mysocket) - { -#if 0 - // for select - myset = SDLNet_AllocSocketSet(1); - if (!myset) - { - CONS_Printf("SDL_Net: %s",SDLNet_GetError()); - return false; - } - if (SDLNet_UDP_AddSocket(myset,mysocket) == -1) - { - CONS_Printf("SDL_Net: %s",SDLNet_GetError()); - return false; - } -#endif - return true; - } - return false; -} - -static boolean KOSUDP_Ban(int node) -{ - if (numbans == MAXBANS) - return false; - - M_Memcpy(&banned[numbans], &clientaddress[node], sizeof (IPaddress)); - banned[numbans].port = 0' - numbans++; - return true; -} - -static void KOSUDP_ClearBans(void) -{ - numbans = 0; -} - -// -// I_InitNetwork -// Only required for DOS, so this is more a dummy -// -boolean I_InitNetwork(void) -{ - char serverhostname[255]; - boolean ret = false; - //if (!M_CheckParm ("-kosnet")) - // return false; - // initilize the driver - I_InitKOSUDPDriver(); - I_AddExitFunc(I_ShutdownKOSUDPDriver); - if (!init_KOSUDP_driver) - return false; - - if (M_CheckParm("-udpport")) - { - if (M_IsNextParm()) - sock_port = (UINT16)atoi(M_GetNextParm()); - else - sock_port = 0; - } - - // parse network game options, - if (M_CheckParm("-server") || dedicated) - { - server = true; - - // If a number of clients (i.e. nodes) is specified, the server will wait for the clients - // to connect before starting. - // If no number is specified here, the server starts with 1 client, and others can join - // in-game. - // Since Boris has implemented join in-game, there is no actual need for specifying a - // particular number here. - // FIXME: for dedicated server, numnodes needs to be set to 0 upon start -/* if (M_IsNextParm()) - doomcom->numnodes = (INT16)atoi(M_GetNextParm()); - else */if (dedicated) - doomcom->numnodes = 0; - else - doomcom->numnodes = 1; - - if (doomcom->numnodes < 0) - doomcom->numnodes = 0; - if (doomcom->numnodes > MAXNETNODES) - doomcom->numnodes = MAXNETNODES; - - // server - servernode = 0; - // FIXME: - // ??? and now ? - // server on a big modem ??? 4*isdn - net_bandwidth = 16000; - hardware_MAXPACKETLENGTH = INETPACKETLENGTH; - - ret = true; - } - else if (M_CheckParm("-connect")) - { - if (M_IsNextParm()) - strcpy(serverhostname, M_GetNextParm()); - else - serverhostname[0] = 0; // assuming server in the LAN, use broadcast to detect it - - // server address only in ip - if (serverhostname[0]) - { - COM_BufAddText("connect \""); - COM_BufAddText(serverhostname); - COM_BufAddText("\"\n"); - - // probably modem - hardware_MAXPACKETLENGTH = INETPACKETLENGTH; - } - else - { - // so we're on a LAN - COM_BufAddText("connect any\n"); - - net_bandwidth = 800000; - hardware_MAXPACKETLENGTH = MAXPACKETLENGTH; - } - } - - I_NetOpenSocket = KOSUDP_OpenSocket; - I_Ban = KOSUDP_Ban; - I_ClearBans = KOSUDP_ClearBans; - I_GetNodeAddress = KOSUDP_GetNodeAddress; - I_GetBanAddress = KOSUDP_GetBanAddress; - bannednode = KOSUDP_bannednode; - - return ret; -} diff --git a/src/sdl12/SRB2DC/scramble.c b/src/sdl12/SRB2DC/scramble.c deleted file mode 100644 index a3483b00dcd3a3ac8579b3a557ca9717dc4395cb..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2DC/scramble.c +++ /dev/null @@ -1,259 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> - -#define MAXCHUNK (2048*1024) - -static unsigned int seed; - -void my_srand(unsigned int n) -{ - seed = n & 0xffff; -} - -unsigned int my_rand() -{ - seed = (seed * 2109 + 9273) & 0x7fff; - return (seed + 0xc000) & 0xffff; -} - -void load(FILE *fh, unsigned char *ptr, unsigned long sz) -{ - if (fread(ptr, 1, sz, fh) != sz) - { - fprintf(stderr, "Read error!\n"); - exit(1); - } -} - -void load_chunk(FILE *fh, unsigned char *ptr, unsigned long sz) -{ - static int idx[MAXCHUNK/32]; - int i; - - /* Convert chunk size to number of slices */ - sz /= 32; - - /* Initialize index table with unity, - so that each slice gets loaded exactly once */ - for (i = 0; i < sz; i++) - idx[i] = i; - - for (i = sz-1; i >= 0; --i) - { - /* Select a replacement index */ - int x = (my_rand() * i) >> 16; - - /* Swap */ - int tmp = idx[i]; - idx[i] = idx[x]; - idx[x] = tmp; - - /* Load resulting slice */ - load(fh, ptr+32*idx[i], 32); - } -} - -void load_file(FILE *fh, unsigned char *ptr, unsigned long filesz) -{ - unsigned long chunksz; - - my_srand(filesz); - - /* Descramble 2 meg blocks for as long as possible, then - gradually reduce the window down to 32 bytes (1 slice) */ - for (chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1) - while (filesz >= chunksz) - { - load_chunk(fh, ptr, chunksz); - filesz -= chunksz; - ptr += chunksz; - } - - /* Load final incomplete slice */ - if (filesz) - load(fh, ptr, filesz); -} - -void read_file(char *filename, unsigned char **ptr, unsigned long *sz) -{ - FILE *fh = fopen(filename, "rb"); - if (fh == NULL) - { - fprintf(stderr, "Can't open \"%s\".\n", filename); - exit(1); - } - if (fseek(fh, 0, SEEK_END)<0) - { - fprintf(stderr, "Seek error.\n"); - exit(1); - } - *sz = ftell(fh); - *ptr = malloc(*sz); - if ( *ptr == NULL ) - { - fprintf(stderr, "Out of memory.\n"); - exit(1); - } - if (fseek(fh, 0, SEEK_SET)<0) - { - fprintf(stderr, "Seek error.\n"); - exit(1); - } - load_file(fh, *ptr, *sz); - fclose(fh); -} - -void save(FILE *fh, unsigned char *ptr, unsigned long sz) -{ - if (fwrite(ptr, 1, sz, fh) != sz) - { - fprintf(stderr, "Write error!\n"); - exit(1); - } -} - -void save_chunk(FILE *fh, unsigned char *ptr, unsigned long sz) -{ - static int idx[MAXCHUNK/32]; - int i; - - /* Convert chunk size to number of slices */ - sz /= 32; - - /* Initialize index table with unity, - so that each slice gets saved exactly once */ - for (i = 0; i < sz; i++) - idx[i] = i; - - for (i = sz-1; i >= 0; --i) - { - /* Select a replacement index */ - int x = (my_rand() * i) >> 16; - - /* Swap */ - int tmp = idx[i]; - idx[i] = idx[x]; - idx[x] = tmp; - - /* Save resulting slice */ - save(fh, ptr+32*idx[i], 32); - } -} - -void save_file(FILE *fh, unsigned char *ptr, unsigned long filesz) -{ - unsigned long chunksz; - - my_srand(filesz); - - /* Descramble 2 meg blocks for as long as possible, then - gradually reduce the window down to 32 bytes (1 slice) */ - for (chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1) - while (filesz >= chunksz) - { - save_chunk(fh, ptr, chunksz); - filesz -= chunksz; - ptr += chunksz; - } - - /* Save final incomplete slice */ - if (filesz) - save(fh, ptr, filesz); -} - -void write_file(char *filename, unsigned char *ptr, unsigned long sz) -{ - FILE *fh = fopen(filename, "wb"); - if (fh == NULL) - { - fprintf(stderr, "Can't open \"%s\".\n", filename); - exit(1); - } - save_file(fh, ptr, sz); - fclose(fh); -} - -void descramble(char *src, char *dst) -{ - unsigned char *ptr = NULL; - unsigned long sz = 0; - FILE *fh; - - read_file(src, &ptr, &sz); - - fh = fopen(dst, "wb"); - if (fh == NULL) - { - fprintf(stderr, "Can't open \"%s\".\n", dst); - exit(1); - } - if ( fwrite(ptr, 1, sz, fh) != sz ) - { - fprintf(stderr, "Write error.\n"); - exit(1); - } - fclose(fh); - free(ptr); -} - -void scramble(char *src, char *dst) -{ - unsigned char *ptr = NULL; - unsigned long sz = 0; - FILE *fh; - - fh = fopen(src, "rb"); - if (fh == NULL) - { - fprintf(stderr, "Can't open \"%s\".\n", src); - exit(1); - } - if (fseek(fh, 0, SEEK_END)<0) - { - fprintf(stderr, "Seek error.\n"); - exit(1); - } - sz = ftell(fh); - ptr = malloc(sz); - if ( ptr == NULL ) - { - fprintf(stderr, "Out of memory.\n"); - exit(1); - } - if (fseek(fh, 0, SEEK_SET)<0) - { - fprintf(stderr, "Seek error.\n"); - exit(1); - } - if ( fread(ptr, 1, sz, fh) != sz ) - { - fprintf(stderr, "Read error.\n"); - exit(1); - } - fclose(fh); - - write_file(dst, ptr, sz); - - free(ptr); -} - -int main(int argc, char *argv[]) -{ - int opt = 0; - - if (argc > 1 && !strcmp(argv[1], "-d")) - opt ++; - - if (argc != 3+opt) - { - fprintf(stderr, "Usage: %s [-d] from to\n", argv[0]); - exit(1); - } - - if (opt) - descramble(argv[2], argv[3]); - else - scramble(argv[1], argv[2]); - - return 0; -} diff --git a/src/sdl12/SRB2PS3/ICON0.png b/src/sdl12/SRB2PS3/ICON0.png deleted file mode 100644 index 140230c1e17bcf341498374ede7feea16ac5b54c..0000000000000000000000000000000000000000 Binary files a/src/sdl12/SRB2PS3/ICON0.png and /dev/null differ diff --git a/src/sdl12/SRB2PS3/Makefile.cfg b/src/sdl12/SRB2PS3/Makefile.cfg deleted file mode 100644 index 80f8db7bc046350650b1e87a63179f96c0677598..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2PS3/Makefile.cfg +++ /dev/null @@ -1,139 +0,0 @@ -# -# Makefile.cfg for SRB2 for the PlayStation 3 using PSL1GHT -# - -# Check if PS3DEV and PSL1GHT is set in the environment. If so, continue with compilation. -.SUFFIXES: - -ifeq ($(strip $(PS3DEV)),) -$(error "Please set PS3DEV in your environment. export PS3DEV=<path to>ps3dev-toolchain") -endif - -ifeq ($(strip $(PSL1GHT)),) -$(error "Please set PSL1GHT in your environment. export PSL1GHT=<path to>PSL1GHT") -endif - -# Set compiler flags - -# Disable same warning flags -WFLAGS+=-Wno-shadow -Wno-char-subscripts -Wno-format - -ifdef JAILBREAK -EXENAME?=SRB2PS3-jb.elf -PKGNAME?=SRB2PS3-jb.pkg -else -EXENAME?=SRB2PS3.elf -PKGNAME?=SRB2PS3.pkg -endif -DGBNAME?=$(EXENAME).debug - -SRB2PS3DIR=sdl12/SRB2PS3 -ICON0?=$(SRB2PS3DIR)/ICON0.png -SFOXML?=sfo.xml -SRB2TTF?=sdl12/srb2.ttf - -TITLE=Sonic Robo Blast 2 v2.0.6 -APPID=SRB2-PS3 -CONTENTID=UP0001-$(APPID)_00-0000000000000000 - -FSELF=$(PS3DEV)/bin/fself.py -MAKE_SELF_NPDRM=$(PS3DEV)/ps3publictools/make_self_npdrm -FINALIZE=$(PS3DEV)/ps3publictools/package_finalize -SFO=$(PS3DEV)/bin/sfo.py -PKG=$(PS3DEV)/bin/pkg.py -PS3LOADEXE=$(PS3DEV)/ps3tools/ps3load -SED=sed -MV=mv -XARGS=xargs -FOR=for -SHXARGS:=$(XARGS) -SHSED:=$(SED) -SPRXLINKER=$(PS3DEV)/bin/sprxlinker - -ifdef JAILBREAK -PKGDIR=$(BIN)/pkg-jb -else -PKGDIR=$(BIN)/pkg -endif -USRDIR=$(PKGDIR)/USRDIR -ETCDIR=$(USRDIR)/etc -WGET=wget -P $(ETCDIR) -c -nc - -ifndef ECHO - FSELF:=@$(FSELF) - MAKE_SELF_NPDRM:=@$(MAKE_SELF_NPDRM) - FINALIZE:=@$(FINALIZE) - SFO:=@$(SFO) - PKG:=@$(PKG) - PS3LOADEXE:=@$(PS3LOADEXE) - SED:=@$(SED) - MV:=@$(MV) - SPRXLINKER:=@$(SPRXLINKER) - XARGS:=@$(XARGS) - FOR:=@(FOR) -endif - -# SRB2PS3 needs SDL_ttf to display any console text -SDL_TTF=1 - -# newlib has no support for networking -#NONET=1 - -# use absolute paths because changing PATH variable breaks distcc -PREFIX := $(PS3DEV)/ppu/bin/$(PREFIX) - -# PS3DEV toolchain libdir and includedir -PS3DEV_INC := $(PS3DEV)/ppu/include -PS3DEV_LIB := $(PS3DEV)/ppu/lib - -# PSL1GHT libdir and includedir -PSL1GHT_INC := $(PSL1GHT)/ppu/include -PSL1GHT_LIB := $(PSL1GHT)/ppu/lib - -PS3PORTS := $(PS3DEV)/portlibs -PS3PORTS_BIN := $(PS3PORTS)/ppu/bin -PS3PORTS_INC := $(PS3PORTS)/ppu/include - -PNG_CONFIG := $(PS3PORTS_BIN)/libpng-config -# static compilation -PNG_STATIC=1 - -SDL_CONFIG := $(PS3PORTS_BIN)/sdl-config - -INCLUDE := -I$(PSL1GHT_INC) -I$(PS3DEV_INC) -I$(PS3PORTS_INC) - -OPTS+=-D_PS3 -DUNIXCOMMON -CFLAGS+= -g $(INCLUDE) -L$(PSL1GHT_LIB) -L$(PS3DEV_LIB) -L$(PS3DEV)/lib -CXXFLAGS+=$(CFLAGS) -LDFLAGS+= -B$(PSL1GHT_LIB) -B$(PS3DEV_LIB) -B$(PS3DEV)/lib -LIBS+=-lrsx -ifndef NONET -LIBS+=-lnet -lsysmodule -endif - -$(BIN)/$(PKGNAME): $(OBJS) $(BIN)/$(EXENAME) - @echo Linking $(PKGNAME)... - -$(MKDIR) $(ETCDIR) - $(CP) $(ICON0) $(PKGDIR) - $(CP) $(SRB2TTF) $(ETCDIR) -ifdef WITHDATA - $(FOR) datafile in $(shell echo $(D_FILES) | $(SHSED) 's/\.srb/\.wad/' | $(SHXARGS) -n 1 basename); do \ - $(WGET) http://alam.srb2.org/SRB2/2.0.6-Final/Resources/$$datafile; \ - done -endif - $(SPRXLINKER) $(BIN)/$(EXENAME) -ifdef JAILBREAK - $(SED) 's/@@PS3_SYSTEM_VER@@/3.41/' $(SRB2PS3DIR)/$(SFOXML) > $(BIN)/$(SFOXML) - $(FSELF) -n $(BIN)/$(EXENAME) $(USRDIR)/EBOOT.BIN -else - $(SED) 's/@@PS3_SYSTEM_VER@@/3.55/' $(SRB2PS3DIR)/$(SFOXML) > $(BIN)/$(SFOXML) - $(MAKE_SELF_NPDRM) $(BIN)/$(EXENAME) $(USRDIR)/EBOOT.BIN $(CONTENTID) -endif - $(SFO) --title "$(TITLE)" --appid "$(APPID)" -f $(BIN)/$(SFOXML) $(PKGDIR)/PARAM.SFO - $(PKG) --contentid $(CONTENTID) $(PKGDIR)/ $(BIN)/$(PKGNAME) -ifndef JAILBREAK - $(FINALIZE) $(BIN)/$(PKGNAME) -endif - -run: $(BIN)/$(EXENAME) - $(PS3LOADEXE) $(USRDIR)/EBOOT.BIN diff --git a/src/sdl12/SRB2PS3/sfo.xml b/src/sdl12/SRB2PS3/sfo.xml deleted file mode 100644 index d7719b5401f2aa88cfa513ca10ce31e926b27947..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2PS3/sfo.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" ?> -<sfo> - <value name="APP_VER" type="string"> - 02.06 - </value> - <value name="ATTRIBUTE" type="integer"> - 0 - </value> - <value name="BOOTABLE" type="integer"> - 1 - </value> - <value name="CATEGORY" type="string"> - HG - </value> - <value name="LICENSE" type="string"> - This application was created with the official non-official SDK called PSL1GHT, for more information visit http://www.psl1ght.com/ . This is in no way associated with Sony Computer Entertainment Inc., please do not contact them for help, they will not be able to provide it. - </value> - <value name="PARENTAL_LEVEL" type="integer"> - 0 - </value> - <value name="PS3_SYSTEM_VER" type="string"> - 0@@PS3_SYSTEM_VER@@00 - </value> - <value name="RESOLUTION" type="integer"> - 63 - </value> - <value name="SOUND_FORMAT" type="integer"> - 279 - </value> - <value name="TITLE" type="string"> - Sonic Robo Blast 2 - </value> - <value name="TITLE_ID" type="string"> - SRB200000 - </value> - <value name="VERSION" type="string"> - 02.06 - </value> -</sfo> diff --git a/src/sdl12/SRB2PSP/ICON0.png b/src/sdl12/SRB2PSP/ICON0.png deleted file mode 100644 index 140230c1e17bcf341498374ede7feea16ac5b54c..0000000000000000000000000000000000000000 Binary files a/src/sdl12/SRB2PSP/ICON0.png and /dev/null differ diff --git a/src/sdl12/SRB2PSP/Makefile.cfg b/src/sdl12/SRB2PSP/Makefile.cfg deleted file mode 100644 index 5e4c0ba2ff7d202033afc3bd256e762e12d9af46..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2PSP/Makefile.cfg +++ /dev/null @@ -1,126 +0,0 @@ -# -# Makefile.cfg for SRB2/PSP -# - -# -#hmmm, the PSP -# - - PSPSDK=$(shell psp-config -p) - PSPDEV=$(shell psp-config -d) - PSPPREFIX=$(shell psp-config -P) - STRIP=psp-strip - MKSFO?=mksfoex -d MEMSIZE=1 - #MKSFO=mksfo - PACK_PBP=pack-pbp - FIXUP=psp-fixup-imports - HOSTCC:=$(CC) - CC=$(PSPDEV)/bin/psp-gcc - OBJCOPY=psp-objcopy - OBJDUMP=psp-objdump -ifdef FIXEDPRX - PRXGEN=psp-prxgen -else - PRXGEN=$(OBJCOPY) -endif -ifndef PRXSIGN - SIGNER:=$(PSPDEV)/bin/$(OBJCOPY) -endif - -ifndef ECHO - MKSFO:=@$(MKSFO) - PACK_PBP:=@$(PACK_PBP) - FIXUP:=@$(FIXUP) - PRXGEN:=@$(PRXGEN) -endif - - PSP_EBOOT_TITLE=SRB2-PSP vME - PSP_EBOOT_SFO=$(BIN)/PARAM.SFO - PSP_EBOOT_ICON=sdl12/SRB2PSP/ICON0.png - PSP_EBOOT_ICON1=NULL - PSP_EBOOT_UNKPNG=NULL - PSP_EBOOT_PIC1=sdl12/SRB2PSP/PIC1.png - PSP_EBOOT_SND0=NULL - PSP_EBOOT_PSAR=NULL - - SIGNER?=sdl12/SRB2PSP/psp-prxsign/psp-prxsign - - SDL=1 - PREFIX=psp - NONX86=1 - #NOHW=1 - NOHS=1 - NOMD5=1 - NONET=1 #No TCPIP code - NOPNG=1 #No Screenshot - - OPTS=-I$(PSPPREFIX)/include -I$(PSPSDK)/include - OPTS+=-DUNIXCOMMON -DFORCESDLMAIN -G0 - WFLAGS+=-Wno-undef - WFLAGS+=-O1 - LIBS=-lm - SDL_CONFIG?=$(PSPPREFIX)/bin/sdl-config - #SDL_CFLAGS?=-I$(PSPDEV)/psp/include/SDL - #SDL_LDFLAGS?=-lSDLmain -lSDL -lglut -lGLU -lGL -lpspgu -lpspaudiolib -lpspaudio -lpsphprm -lpspvfpu -lpsprtc -ifndef NOMIXER - LIBS:=-liberty -lvorbisfile -lvorbis -logg -lSDL $(LIBS) -endif -ifndef NOHW - OPTS+=-DSTATIC_OPENGL -DMINI_GL_COMPATIBILITY - LIBS+=-lGLU -lGL -lm -endif - #PSPSDK_LIBS=-L$(PSPSDK)/lib -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk - #LIBS+=$(PSPSDK_LIBS) -lc -lpspnet -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility -lpspuser -lpspkernel -ifdef FIXEDPRX - LDFLAGS := -specs=$(PSPSDK)/lib/prxspecs -Wl,-q,-T$(PSPSDK)/lib/linkfile.prx $(LDFLAGS) - LIBS+=$(PSPSDK)/lib/prxexports.o -endif - -ifeq ($(PSP_FW_VERSION),) -PSP_FW_VERSION=150 -endif - - CPPFLAGS:=-D_PSP_FW_VERSION=$(PSP_FW_VERSION) $(CPPFLAGS) - - - # name of the exefile - EXENAME?=SRB2PSP.elf - PRXNAME?=SRB2PSP.prx - DBGNAME?=SRB2PSP.debug - -post-build: $(BIN)/EBOOT.PBP - -kxploit: $(BIN)/$(EXENAME) $(PSP_EBOOT_SFO) - -$(MKDIR) "$(BIN)/kxploit/srb2" - @echo emitting kxploit/srb2/ - $(STRIP) $(BIN)/$(EXENAME) -o $(BIN)/kxploit/srb2/EBOOT.PBP - @echo emitting kxploit/srb2% - -$(MKDIR) "$(BIN)/kxploit/srb2%/" - $(PACK_PBP) "$(BIN)/kxploit/srb2%/EBOOT.PBP" $(PSP_EBOOT_SFO) $(PSP_EBOOT_ICON) \ - $(PSP_EBOOT_ICON1) $(PSP_EBOOT_UNKPNG) $(PSP_EBOOT_PIC1) \ - $(PSP_EBOOT_SND0) NULL $(PSP_EBOOT_PSAR) - -sdl12/SRB2PSP/psp-prxsign/psp-prxsign: - -$(MAKE) -C sdl12/SRB2PSP/psp-prxsign CFLAGS=-pipe CC="$(HOSTCC)" - -fix-up: $(BIN)/$(EXENAME) - @echo Running psp-fixup-imports on $(EXENAME) - $(FIXUP) $(BIN)/$(EXENAME) - -$(BIN)/$(PRXNAME): $(BIN)/$(EXENAME) fix-up - @echo Building $(PRXNAME) out of $(EXENAME) - $(PRXGEN) $(BIN)/$(EXENAME) $@ - -$(BIN)/EBOOT.PBP: $(BIN)/$(PRXNAME) $(SIGNER) $(PSP_EBOOT_SFO) - @echo Signing and running pack-pbp to make PBP - $(SIGNER) $(BIN)/$(PRXNAME) $(BIN)/$(PRXNAME).sign - $(PACK_PBP) $@ $(PSP_EBOOT_SFO) $(PSP_EBOOT_ICON) \ - $(PSP_EBOOT_ICON1) $(PSP_EBOOT_UNKPNG) $(PSP_EBOOT_PIC1) \ - $(PSP_EBOOT_SND0) $(BIN)/$(PRXNAME).sign $(PSP_EBOOT_PSAR) - $(REMOVE) $(BIN)/$(PRXNAME).sign - -$(PSP_EBOOT_SFO): - -$(MKDIR) $(BIN) - $(MKSFO) '$(PSP_EBOOT_TITLE)' $@ - -#include $(PSPSDK)/lib/build.mak diff --git a/src/sdl12/SRB2PSP/PIC1.png b/src/sdl12/SRB2PSP/PIC1.png deleted file mode 100644 index 0722a96bc78ce4c82edaed348bc6f86826e5690a..0000000000000000000000000000000000000000 Binary files a/src/sdl12/SRB2PSP/PIC1.png and /dev/null differ diff --git a/src/sdl12/SRB2PSP/psp-prxsign/.gitignore b/src/sdl12/SRB2PSP/psp-prxsign/.gitignore deleted file mode 100644 index 6a07f1a5a2baa158afc10a9ea7dd98ac57c83d2e..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2PSP/psp-prxsign/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/psp-prxsign -/psp-prxsign.exe diff --git a/src/sdl12/SRB2PSP/psp-prxsign/Makefile b/src/sdl12/SRB2PSP/psp-prxsign/Makefile deleted file mode 100644 index 4a9b7da0f29b4cad9972d099ea87490113bc91e4..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2PSP/psp-prxsign/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -EXE=psp-prxsign -SRC=main.c cmac.c -OBJ=$(SRC:.c=.o)# replaces the .c from SRC with .o - -OPENSSL_PKGCONFIG?=openssl -OPENSSL_CFLAGS?=$(shell pkg-config $(OPENSSL_PKGCONFIG) --cflags) -OPENSSL_LDFLAGS?=$(shell pkg-config $(OPENSSL_PKGCONFIG) --libs) - -CFLAGS+=$(OPENSSL_CFLAGS) -LDFLAGS+=$(OPENSSL_LDFLAGS) - -.PHONY : all # .PHONY ignores files named all - -all: $(EXE) # all is dependent on $(BIN) to be complete - - -$(EXE): $(OBJ) # $(EXE) is dependent on all of the files in $(OBJ) to exist - $(CC) $^ $(LDFLAGS) -o $@ - -.PHONY : clean # .PHONY ignores files named clean -clean: - -$(RM) $(OBJ) $(EXE) diff --git a/src/sdl12/SRB2PSP/psp-prxsign/cmac.c b/src/sdl12/SRB2PSP/psp-prxsign/cmac.c deleted file mode 100644 index f527f7a71a322d49ba850250587eed1e77568abf..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2PSP/psp-prxsign/cmac.c +++ /dev/null @@ -1,130 +0,0 @@ -#include "cmac.h" - -#define AES_128 0 -unsigned char const_Rb[16] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 -}; -unsigned char const_Zero[16] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -void xor_128(unsigned char *a, unsigned char *b, unsigned char *out) -{ - int i; - for (i=0;i<16; i++) - { - out[i] = a[i] ^ b[i]; - } -} - -/* AES-CMAC Generation Function */ - -static inline void leftshift_onebit(unsigned char *input,unsigned char *output) -{ - int i; - unsigned char overflow = 0; - - for ( i=15; i>=0; i-- ) - { - output[i] = input[i] << 1; - output[i] |= overflow; - overflow = (input[i] & 0x80)?1:0; - } -} - -void generate_subkey(unsigned char *key, unsigned char *K1, unsigned char *K2) -{ - unsigned char L[16]; - unsigned char Z[16]; - unsigned char tmp[16]; - int i; - - for ( i=0; i<16; i++ ) Z[i] = 0; - - AES_KEY aes; - AES_set_encrypt_key(key, 128, &aes); - - AES_encrypt(Z, L, &aes); - - if ( (L[0] & 0x80) == 0 ) /* If MSB(L) = 0, then K1 = L << 1 */ - { - leftshift_onebit(L,K1); - } else { /* Else K1 = ( L << 1 ) (+) Rb */ - leftshift_onebit(L,tmp); - xor_128(tmp,const_Rb,K1); - } - - if ( (K1[0] & 0x80) == 0 ) - { - leftshift_onebit(K1,K2); - } else { - leftshift_onebit(K1,tmp); - xor_128(tmp,const_Rb,K2); - } -} - -static inline void padding ( unsigned char *lastb, unsigned char *pad, int length ) -{ - int j; - - /* original last block */ - for ( j=0; j<16; j++ ) - { - if ( j < length ) - { - pad[j] = lastb[j]; - } else if ( j == length ) { - pad[j] = 0x80; - } else { - pad[j] = 0x00; - } - } -} - -void AES_CMAC ( unsigned char *key, unsigned char *input, int length, unsigned char *mac ) -{ - unsigned char X[16],Y[16], M_last[16], padded[16]; - unsigned char K1[16], K2[16]; - int n, i, flag; - generate_subkey(key,K1,K2); - - n = (length+15) / 16; /* n is number of rounds */ - - if ( n == 0 ) - { - n = 1; - flag = 0; - } else { - if ( (length%16) == 0 ) { /* last block is a complete block */ - flag = 1; - } else { /* last block is not complete block */ - flag = 0; - } - - } - - if ( flag ) { /* last block is complete block */ - xor_128(&input[16*(n-1)],K1,M_last); - } else { - padding(&input[16*(n-1)],padded,length%16); - xor_128(padded,K2,M_last); - } - AES_KEY aes; - AES_set_encrypt_key(key, 128, &aes); - - for ( i=0; i<16; i++ ) X[i] = 0; - for ( i=0; i<n-1; i++ ) - { - xor_128(X,&input[16*i],Y); /* Y := Mi (+) X */ - AES_encrypt(Y, X, &aes); /* X := AES-128(KEY, Y); */ - } - - xor_128(X,M_last,Y); - AES_encrypt(Y, X, &aes); - - for ( i=0; i<16; i++ ) { - mac[i] = X[i]; - } -} diff --git a/src/sdl12/SRB2PSP/psp-prxsign/cmac.h b/src/sdl12/SRB2PSP/psp-prxsign/cmac.h deleted file mode 100644 index 563045841770a6c236e41d897199bce757ba2894..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2PSP/psp-prxsign/cmac.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - --------------------------------------------------------------------------- - Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. - - LICENSE TERMS - - The redistribution and use of this software (with or without changes) - is allowed without the payment of fees or royalties provided that: - - 1. source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - 2. binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation; - - 3. the name of the copyright holder is not used to endorse products - built using this software without specific written permission. - - DISCLAIMER - - This software is provided 'as is' with no explicit or implied warranties - in respect of its properties, including, but not limited to, correctness - and/or fitness for purpose. - --------------------------------------------------------------------------- - Issue Date: 6/10/2008 -*/ - -#ifndef CMAC_AES_H -#define CMAC_AES_H - -#include <string.h> -#include <openssl/aes.h> - -void xor_128(unsigned char *a, unsigned char *b, unsigned char *out); -void generate_subkey(unsigned char *key, unsigned char *K1, unsigned char *K2); -void AES_CMAC(unsigned char *key, unsigned char *input, int length, unsigned char *mac); - -#endif diff --git a/src/sdl12/SRB2PSP/psp-prxsign/kirk_header.h b/src/sdl12/SRB2PSP/psp-prxsign/kirk_header.h deleted file mode 100644 index 76c921ef06ceb3f51a347750e85992cfd037bc40..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2PSP/psp-prxsign/kirk_header.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __kirk_header__ -#define __kirk_header__ - -static unsigned int size_kirk_header = 272; -static unsigned char kirk_header[] __attribute__((aligned(16))) = { - 0x2a, 0x4f, 0x3c, 0x49, 0x8a, 0x73, 0x4e, 0xd1, 0xf4, 0x55, 0x93, 0x0b, 0x9b, 0x69, 0xdc, 0x65, - 0x73, 0x22, 0x69, 0xd3, 0x73, 0x96, 0x7a, 0x60, 0x66, 0x8c, 0x88, 0xcf, 0x2f, 0x83, 0x58, 0xbc, - 0xb2, 0x00, 0x0a, 0x11, 0x72, 0x43, 0xc5, 0xde, 0xef, 0xbb, 0x2c, 0xbf, 0x97, 0x79, 0x6b, 0x9c, - 0x10, 0x1e, 0x7c, 0x57, 0x0e, 0xdb, 0x1d, 0x61, 0x6e, 0xb5, 0xf9, 0x3d, 0x35, 0xe9, 0x5c, 0xd8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x33, 0x55, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7e, 0x50, 0x53, 0x50, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x22, 0x74, 0x69, 0x66, 0x70, 0x73, - 0x70, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x33, 0x55, 0x00, 0x50, 0x34, 0x55, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x40, 0x67, 0x3d, 0x00, 0x50, 0x55, 0x0a, 0x01, 0x10, 0x00, 0x40, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x6b, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x4c, 0x6b, 0x3d, 0x00, 0xcc, 0xbb, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, -}; - -#endif diff --git a/src/sdl12/SRB2PSP/psp-prxsign/main.c b/src/sdl12/SRB2PSP/psp-prxsign/main.c deleted file mode 100644 index a970ae6c1f7d50a12572c16ebe13b1e3f2da9b38..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2PSP/psp-prxsign/main.c +++ /dev/null @@ -1,190 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <openssl/aes.h> -#include <openssl/sha.h> -#include <elf.h> -#include "cmac.h" -#include "kirk_header.h" -#include "psp_header.h" - -typedef unsigned char byte; - -typedef struct { - byte key[16]; - byte ckey[16]; - byte head_hash[16]; - byte data_hash[16]; - byte unused[32]; - int unk1; // 1 - int unk2; // 0 - int unk3[2]; - int datasize; - int dataoffset; - int unk4[6]; -} kirk1head_t; - -// secret kirk command 1 key -byte kirk_key[] = { - 0x98, 0xc9, 0x40, 0x97, 0x5c, 0x1d, 0x10, 0xe8, 0x7f, 0xe6, 0x0e, 0xa3, 0xfd, 0x03, 0xa8, 0xba -}; - -int main(int argc, char **argv) -{ - int i, relrem, size, fullsize, blocks, datasize; - size_t j; - kirk1head_t kirk; - byte iv[16]; - byte cmac[32]; - byte subk[32]; - byte psph[0x150]; - byte *datablob; - byte *filebuff; - FILE *f; - AES_KEY aesKey; - Elf32_Ehdr *ehdr; - Elf32_Shdr *shdr; - Elf32_Rel *relo; - - if(argc < 3) { - printf("Usage: %s unsigned.prx signed.prx\n", argv[0]); - return 1; - } - - // clean kirk header, use modified PRXdecrypter to get it - /*f = fopen(argv[1], "rb"); - if(!f) { - printf("failed to open %s\n", argv[1]); - return 1; - } - fread(&kirk, 1, sizeof(kirk1head_t), f); - fclose(f);*/ - //memcpy(&kirk, kirk_header, size_kirk_header); - memcpy(&kirk, kirk_header, sizeof(kirk1head_t)); - - datasize = kirk.datasize; - if(datasize % 16) datasize += 16 - (datasize % 16); - - // original ~PSP header - /*f = fopen(argv[2], "rb"); - if(!f) { - free(datablob); - printf("failed to open %s\n", argv[2]); - return 1; - } - fread(psph, 1, 0x150, f); - fclose(f);*/ - memcpy(&psph, psp_header, size_psp_header); - - // file to encrypt - f = fopen(argv[1], "rb"); - if(!f) { - printf("psp-prxsign: Unable to open PRX\n"); - return 1; - } - fseek(f, 0, SEEK_END); - size = ftell(f); - if(size > datasize - 16) { - fclose(f); - printf("psp-prxsign: PRX is too large\n"); - return 1; - } - printf("%s : %i\n", argv[1], size); - fseek(f, 0, SEEK_SET); - - fullsize = datasize + 0x30 + kirk.dataoffset; - - // datablob holds everything needed to calculate data HASH - datablob = malloc(fullsize); - if(!datablob) { - fclose(f); - printf("psp-prxsign: Failed to allocate memory for blob\n"); - return 1; - } - memset(datablob, 0, fullsize); - memcpy(datablob, &kirk.unk1, 0x30); - memcpy(datablob + 0x30, psph, kirk.dataoffset); - filebuff = datablob + 0x30 + kirk.dataoffset; - - int whocares = fread(filebuff, 1, size, f); - (void)whocares; - fclose(f); - - // remove relocations type 7 - relrem = 0; - ehdr = (void *)filebuff; - if(!memcmp(ehdr->e_ident, ELFMAG, 4) && ehdr->e_shnum) { - shdr = (void *)(filebuff + ehdr->e_shoff); - for(i = 0; i < ehdr->e_shnum; i++) { - if(shdr[i].sh_type == 0x700000A0) { - relo = (void *)(filebuff + shdr[i].sh_offset); - for(j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++) { - if((relo[j].r_info & 0xFF) == 7) { - relo[j].r_info = 0; - relrem++; - } - } - } - } - } - //printf("%i relocations type 7 removed\ncalculating ...\n", relrem); - - // get AES/CMAC key - AES_set_decrypt_key(kirk_key, 128, &aesKey); - memset(iv, 0, 16); - AES_cbc_encrypt(kirk.key, kirk.key, 32, &aesKey, iv, AES_DECRYPT); - - // check header hash, optional - // if you take correct kirk header, hash is always correct -/* AES_CMAC(kirk.ckey, datablob, 0x30, cmac); - if(memcmp(cmac, kirk.head_hash, 16)) { - free(datablob); - printf("header hash invalid\n"); - return 1; - } -*/ - - // encrypt input file - AES_set_encrypt_key(kirk.key, 128, &aesKey); - memset(iv, 0, 16); - AES_cbc_encrypt(filebuff, filebuff, datasize, &aesKey, iv, AES_ENCRYPT); - - // make CMAC correct - generate_subkey(kirk.ckey, subk, subk + 16); - AES_set_encrypt_key(kirk.ckey, 128, &aesKey); - blocks = fullsize / 16; - memset(cmac, 0, 16); - for(i = 0; i < blocks - 1; i++) { - xor_128(cmac, &datablob[16 * i], cmac + 16); - AES_encrypt(cmac + 16, cmac, &aesKey); - } - - AES_set_decrypt_key(kirk.ckey, 128, &aesKey); - AES_decrypt(kirk.data_hash, iv, &aesKey); - xor_128(cmac, iv, iv); - xor_128(iv, subk, &datablob[16 * (blocks-1)]); - // check it, optional - // it works, this is only if you want to change something -/* AES_CMAC(kirk.ckey, datablob, fullsize, cmac); - if(memcmp(cmac, kirk.data_hash, 16)) { - fclose(f); - free(datablob); - printf("data hash calculation error\n"); - return 1; - } -*/ - f = fopen(argv[2], "wb"); - if(!f) { - free(datablob); - printf("psp-prxsign: Failed to write signed PRX\n"); - return 1; - } - //printf("saving ...\n"); - // save ~PSP header - fwrite(psph, 1, 0x150, f); - // save encrypted file - fwrite(filebuff, 1, fullsize - 0x30 - kirk.dataoffset, f); - fclose(f); - free(datablob); - //printf("everything done\n"); - return 0; -} diff --git a/src/sdl12/SRB2PSP/psp-prxsign/psp_header.h b/src/sdl12/SRB2PSP/psp-prxsign/psp_header.h deleted file mode 100644 index 7faef832c9ed78732cdae4ffeff35d972622ec05..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2PSP/psp-prxsign/psp_header.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __psp_header__ -#define __psp_header__ - -static unsigned int size_psp_header = 336; -static unsigned char psp_header[] __attribute__((aligned(16))) = { - 0x7e, 0x50, 0x53, 0x50, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x22, 0x74, 0x69, 0x66, 0x70, 0x73, - 0x70, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x33, 0x55, 0x00, 0x50, 0x34, 0x55, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x40, 0x67, 0x3d, 0x00, 0x50, 0x55, 0x0a, 0x01, 0x10, 0x00, 0x40, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x6b, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x4c, 0x6b, 0x3d, 0x00, 0xcc, 0xbb, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, - 0x90, 0x82, 0x4c, 0x48, 0xa3, 0x53, 0xb2, 0x1b, 0x13, 0x95, 0x2f, 0xf1, 0x0b, 0x90, 0x9c, 0x11, - 0x61, 0x40, 0x20, 0x67, 0xf8, 0xdb, 0xfc, 0x95, 0x5c, 0xbe, 0x8c, 0x80, 0xf3, 0x92, 0x03, 0x01, - 0xb0, 0xbe, 0xf5, 0xf8, 0xa1, 0xaf, 0xaf, 0xa8, 0x38, 0x26, 0x63, 0x09, 0x26, 0x0e, 0xb7, 0xd5, - 0x00, 0x33, 0x55, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5c, 0x3e, 0x03, 0x22, 0xe5, 0x7d, 0xb9, 0xd1, 0x13, 0x67, 0x97, 0xa3, 0x5b, 0xd8, 0x77, 0x1f, - 0xf0, 0x05, 0xf3, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x4a, 0xd7, 0x37, - 0xc2, 0x8f, 0x15, 0x43, 0x33, 0x93, 0x4d, 0x5b, 0xc0, 0x6e, 0xe4, 0x00, 0xc6, 0x0a, 0x71, 0x11, - 0x98, 0xb6, 0xc3, 0xb7, 0x59, 0x66, 0x21, 0xa8, 0x65, 0xf6, 0x53, 0xa9, 0x7a, 0x48, 0x17, 0xb6, -}; - -#endif diff --git a/src/sdl12/SRB2Pandora/Makefile.cfg b/src/sdl12/SRB2Pandora/Makefile.cfg deleted file mode 100644 index 1f057a21215f28a3bdd65f604e482f30281b91f1..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2Pandora/Makefile.cfg +++ /dev/null @@ -1,39 +0,0 @@ -# Quick Pandora target to make a compliant SRB2 PND file. - -PNDNAME=SRB2.pnd -PNDDIR=$(BIN)/pnd -ICON=sdl12/SRB2Pandora/icon.png -PXML=sdl12/SRB2Pandora/PXML.xml - -SED=sed -CAT=cat -CP=cp -XARGS=xargs -FOR=for -WGET=wget -P $(PNDDIR) -c -nc - -SHXARGS:=$(XARGS) -SHSED:=$(SED) - -ifndef ECHO - CP:=@$(CP) - CAT:=@$(CAT) - SED:=@$(SED) - XARGS:=@$(XARGS) - FOR:=@(FOR) -endif - -$(BIN)/$(PNDNAME): $(BIN)/$(EXENAME) - @echo Linking $(PNDNAME)... - $(MKDIR) $(PNDDIR) - $(CP) $(BIN)/$(EXENAME) $(PNDDIR) - $(CP) $(ICON) $(PNDDIR) - $(CP) $(PXML) $(PNDDIR) -ifdef WITHDATA - $(FOR) datafile in $(shell echo $(D_FILES) | $(SHSED) 's/\.srb/\.wad/' | $(SHXARGS) -n 1 basename); do \ - $(WGET) http://alam.srb2.org/SRB2/2.0.6-Final/Resources/$$datafile; \ - done -endif - $(MKISOFS) -l -r -o $@ $(PNDDIR) - $(CAT) $(PXML) >> $@ - $(REMOVE) -r $(PNDDIR) diff --git a/src/sdl12/SRB2Pandora/PXML.xml b/src/sdl12/SRB2Pandora/PXML.xml deleted file mode 100644 index 33a9587dbd7081cece3ad7804ab1db3d728685d4..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2Pandora/PXML.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<PXML xmlns="http://openpandora.org/namespaces/PXML"> - <application id="srb2.pandora.v20" appdata="srb2"> - <title lang="en_US">Sonic Robo Blast 2</title> - <title lang="ja_JA">ソニック・ロボ・ブラスト・2</title> - <description lang="en_US">A 3D Sonic fangame with a huge fanbase developing custom content, including characters, levels, and even large-scale modifications</description> - <version major="2" minor="0" release="6" build="1" /> - <exec command="lsdlsrb2" background="true" standalone="true" x11="ignore"/> - <author name="Sonic Team Junior" website="http://www.srb2.org/" email="stjr@srb2.org"/> - <icon src="icon.png"/> - <categories> - <category name="Game"> - <subcategory name="ActionGame" /> - </category> - </categories> - </application> -</PXML> diff --git a/src/sdl12/SRB2Pandora/icon.png b/src/sdl12/SRB2Pandora/icon.png deleted file mode 100644 index 63af73ac3a4e3046783312465aec2d985172f726..0000000000000000000000000000000000000000 Binary files a/src/sdl12/SRB2Pandora/icon.png and /dev/null differ diff --git a/src/sdl12/SRB2WII/Makefile.cfg b/src/sdl12/SRB2WII/Makefile.cfg deleted file mode 100644 index 778d2c3d6c40214376f2f8e81e29269610021e63..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2WII/Makefile.cfg +++ /dev/null @@ -1,124 +0,0 @@ -# -# Makefile.cfg for SRB2Wii native using libogc -# - -# Check if DEVKITPPC is set in the environment. If so, continue with compilation. -.SUFFIXES: - -ifeq ($(strip $(DEVKITPPC)),) -$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC") -endif - -# Set compiler flags - -SRB2NAME?=srb2wii -EXENAME?=$(SRB2NAME).elf -DBGNAME?=$(SRB2NAME).elf.debug -DOLNAME?=$(SRB2NAME).dol - -ICONPNG?=sdl12/SRB2WII/icon.png -METAXML?=sdl12/SRB2WII/meta.xml - -APPDIR=apps/$(SRB2NAME) -ZIPNAME=$(SRB2NAME).zip - -ELF2DOL=$(DEVKITPPC)/bin/elf2dol -WIILOADEXE=$(DEVKITPPC)/bin/wiiload -ZIP=zip -r -9 -WGET=wget -P srb2wii -c -nc -SED=sed -XARGS=xargs -SHXARGS:=$(XARGS) -SHSED:=$(SED) -FOR=for - -ifndef ECHO - ELF2DOL:=@$(ELF2DOL) - WIILOADEXE:=@$(WIILOADEXE) - ZIP:=@$(ZIP) - SED:=@$(SED) - XARGS:=@$(XARGS) - FOR:=@$(FOR) -endif - -# Disable same warning flags -WFLAGS+=-Wno-shadow -Wno-char-subscripts -Wno-old-style-definition -Wno-unsuffixed-float-constants - -# newlib has no support for networking -NONET=1 - -# use pkgconfig for PKG -PNG_PKGCONFIG=libpng - -# use absolute paths because changing PATH variable breaks distcc -PREFIX := $(DEVKITPPC)/bin/$(PREFIX) - -# FIXME: DevkitPPC and ready-compiled SDL Wii require these things to be in a silly order -# libogc/DevkitPro required stuff -LIBOGC := $(DEVKITPRO)/libogc -LIBOGC_INC := $(LIBOGC)/include -LIBOGC_LIB := $(LIBOGC)/lib - -PORTLIBS := $(DEVKITPRO)/portlibs/ppc -PORTLIBS_INC := $(PORTLIBS)/include -PORTLIBS_LIB := $(PORTLIBS)/lib - -SDL_CPPFLAGS := -I$(LIBOGC_INC)/SDL -SDL_LIB := $(DEVKITPRO)/libogc/lib/wii -INCLUDE := -I$(LIBOGC_INC) $(SDL_CPPFLAGS) -I$(PORTLIBS_INC) - -PKG_CONFIG_PATH := $(PORTLIBS)/lib/pkgconfig -PKG_BROKEN_SWTICH := --static --define-variable=DEVKITPRO=$(DEVKITPRO) -PNG_PKGCONFIG := $(PKG_CONFIG_PATH)/libpng.pc $(PKG_BROKEN_SWTICH) -ZLIB_PKGCONFIG := $(PKG_CONFIG_PATH)/zlib.pc $(PKG_BROKEN_SWTICH) - -ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags) -ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs) - -ifdef RDB - LIBS+=-ldb - OPTS+=-DREMOTE_DEBUGGING=$(RDB) -endif - -LIBS+= -L$(SDL_LIB) -ifndef NOMIXER - LD=$(CXX) - LIBS+=-lSDL_mixer -lvorbisidec -lsmpeg -endif -LIBS+=-lSDL - -LIBS+=$(ZLIB_LDFLAGS) -lfat -lwiiuse -lbte -logc -lm -lwiikeyboard -L$(LIBOGC_LIB) - -MACHDEP = -DGEKKO -mrvl -mcpu=750 -meabi -mhard-float -OPTS+=-DWII -D_WII -DUNIXCOMMON -CFLAGS+=-D__BIG_ENDIAN__ -g -O3 -fsigned-char $(MACHDEP) $(INCLUDE) -CXXFLAGS+=$(CFLAGS) -LDFLAGS+=-g $(MACHDEP) -Wl,-Map,$(notdir $@).map - -SDL_CONFIG=/bin/true -SDL_CFLAGS= -SDL_LDFLAGS= - -$(BIN)/$(DOLNAME): $(BIN)/$(EXENAME) - @echo Linking $(DOLNAME)... - $(ELF2DOL) $(BIN)/$(EXENAME) $(BIN)/$(DOLNAME) - @echo Creating /apps/$(SRB2NAME)... - $(MKDIR) $(APPDIR) - $(CP) $(BIN)/$(DOLNAME) $(APPDIR)/boot.dol - $(CP) $(ICONPNG) $(APPDIR) - $(CP) $(METAXML) $(APPDIR) -ifdef WITHDATA - $(MKDIR) srb2wii - $(FOR) datafile in $(shell echo $(D_FILES) | $(SHSED) -e 's/\.srb/\.wad/' -e 's/music.dta//' | $(SHXARGS) -n 1 basename); do \ - $(WGET) http://alam.srb2.org/SRB2/2.0.6-Final/Resources/$$datafile; \ - done - # downsampled music.dta specially for SRB2Wii - $(WGET) http://repos.srb2.org/srb2ports/music.dta - $(ZIP) $(BIN)/$(ZIPNAME) $(APPDIR) srb2wii -else - $(ZIP) $(BIN)/$(ZIPNAME) $(APPDIR) -endif - $(REMOVE) -r $(APPDIR) - -run: $(BIN)/$(EXENAME) - $(WIILOADEXE) $(BIN)/$(DBGNAME) diff --git a/src/sdl12/SRB2WII/icon.png b/src/sdl12/SRB2WII/icon.png deleted file mode 100644 index d22324bc6a9e51dac5c2e82cb2d78ca73d277c23..0000000000000000000000000000000000000000 Binary files a/src/sdl12/SRB2WII/icon.png and /dev/null differ diff --git a/src/sdl12/SRB2WII/meta.xml b/src/sdl12/SRB2WII/meta.xml deleted file mode 100644 index 843176d3af290f931139e3695b015533357642a4..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2WII/meta.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<app version="1"> - <name>SRB2Wii</name> - <coder>Callum</coder> - <version>2.0.6</version> - <release_date>20101207</release_date> - <short_description>A 3D Sonic fangame</short_description> - <long_description>Sonic Robo Blast 2 is a 3D fangame by a small group called -Sonic Team Junior, using the Doom engine as a base. -The game has been worked on for almost 11 years so far, and -it is still being very much developed today, with a huge -fanbase developing custom content, including characters, -levels, and even large-scale modifications that play out -a brand new adventure. -Based on the Doom II engine, SRB2's system requirements -are very low, even the oldest computers can play it at a -decent speed.</long_description> -</app> diff --git a/src/sdl12/SRB2XBOX/Makefile.cfg b/src/sdl12/SRB2XBOX/Makefile.cfg deleted file mode 100644 index 56966d438c0b5b54f59d2498aaec57c2c038d53f..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2XBOX/Makefile.cfg +++ /dev/null @@ -1,44 +0,0 @@ -# -# Makefile.cfg for SRB2/XBOX -# - -# -#hmmm, the XBOX -# - - NOHW=1 #No working OpenGL right now - NOHS=1 #No HWSound right now - NOASM=1 #No Fast code - NONET=1 #No network code - NOMD5=1 #No Slow MD5 - NOPNG=1 #No Screenshot - #SDLMAIN=1 #SDLMain! - -ifndef OPENXDK - OPENXDK=/usr/local/openxdk -endif - - CXBE=$(OPENXDK)/bin/cxbe - -ifdef ECHO - CXBE:=@$(CXBE) -endif - -ifndef NOHW - OPTS+=-DMINI_GL_COMPATIBILITY -endif - - BUILTLM=-fno-builtin - CFLAGS+=-D_XBOX -std=gnu99 -ffreestanding $(BUILTLM) -fno-exceptions - CFLAGS+=-I$(OPENXDK)/i386-pc-xbox/include -I$(OPENXDK)/include - OPTS+=-nostdlib -mno-cygwin -march=i386 - LDFLAGS+=-nostdlib -Wl,--file-alignment,0x20 -Wl,--section-alignment,0x20 -shared -Wl,--entry,_WinMainCRTStartup -Wl,--strip-all -L$(OPENXDK)/i386-pc-xbox/lib -L$(OPENXDK)/lib - LIBS=-lg -lc -lm - SDL_CFLAGS?=-I$(OPENXDK)/include/SDL - SDL_LDFLAGS?=-lSDL -lopenxdk -lhal -lc -lhal -lusb -lhal -lc -lxboxkrnl - - i_system_o+=$(OBJDIR)/xboxhelp.o - - # name of the exefile - EXENAME?=SRB2XBOX.EXE - BINNAME?=default.xbe diff --git a/src/sdl12/SRB2XBOX/xboxhelp.c b/src/sdl12/SRB2XBOX/xboxhelp.c deleted file mode 100644 index 05b6c5e68fd76adceb002fa7e63a01e4e3b2d8c6..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2XBOX/xboxhelp.c +++ /dev/null @@ -1,91 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 2004-2018 by Sonic Team Jr. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// DESCRIPTION: -// stub and replacement "ANSI" C functions for use under OpenXDK -// -//----------------------------------------------------------------------------- - -#include "../../doomdef.h" -#include "xboxhelp.h" -#ifdef __GNUC__ -#include <unistd.h> -#else -#include <stdlib.h> -#endif - -char *getcwd(char *_buf, size_t _size ) -{ - (void)_buf; - (void)_size; - return _buf; -} - -#ifdef _MSC_VER -int mkdir(const char *path) -{ - (void)path; - return 0; -} -#elif 0 //__GNUC__? -int mkdir(const char *path, mode_t _mode) -{ - (void)path; - (void)_mode; - return 0; -} -#endif - -int chdir (const char *__path ) -{ - (void)__path; - return 0; -} - -time_t time(time_t *T) -{ - long returntime = 0; - (void)T; -/* - SYSTEMTIME st; - FILETIME stft; - INT64 ftli; - if (!T) return returntime; - GetSystemTime(&st); - SystemTimeToFileTime(&st,&stft); - CopyMemory(&ftli,&stft,sizeof (LARGE_INTEGER)); - returntime = (long)ftli; - *T = returntime; -*/ - return returntime; -} - -#ifdef _MSC_VER -#include <RtcApi.h> -void __cdecl _RTC_Initialize(void) -{ -} -char *getenv(const char *__env) -{ - __env = NULL; - return NULL; -} - -int putenv(const char *__env) -{ - __env = NULL; - return 0; -} -#endif diff --git a/src/sdl12/SRB2XBOX/xboxhelp.h b/src/sdl12/SRB2XBOX/xboxhelp.h deleted file mode 100644 index 97ef0a3be16b53162f4c45d9a2e3e941fcefaee3..0000000000000000000000000000000000000000 --- a/src/sdl12/SRB2XBOX/xboxhelp.h +++ /dev/null @@ -1,6 +0,0 @@ -#if defined (_MSC_VER) -int access(const char *path, int amode); -char *getcwd(char *_buf, size_t _size ); -int mkdir(const char *path); -int chdir (const char *__path ); -#endif diff --git a/src/sdl12/Srb2SDL-vc10.vcxproj b/src/sdl12/Srb2SDL-vc10.vcxproj deleted file mode 100644 index 0ac7e9e555348f77cb0c2901214daa3edd0828f6..0000000000000000000000000000000000000000 --- a/src/sdl12/Srb2SDL-vc10.vcxproj +++ /dev/null @@ -1,1519 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectName>Srb2SDL</ProjectName> - <ProjectGuid>{61BA7D3C-F77D-4D31-B718-1177FE482CF2}</ProjectGuid> - <RootNamespace>Srb2SDL</RootNamespace> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\..\..\bin\VC10\$(Platform)\$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\..\..\objs\VC10\$(Platform)\$(Configuration)\SDL\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\..\..\bin\VC10\$(Platform)\$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\..\..\objs\VC10\$(Platform)\$(Configuration)\SDL\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\..\..\bin\VC10\$(Platform)\$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\..\..\objs\VC10\$(Platform)\$(Configuration)\SDL\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\..\..\bin\VC10\$(Platform)\$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\..\..\objs\VC10\$(Platform)\$(Configuration)\SDL\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental> - <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SDL12_PREFIX)\include;$(SDL12_MIXER_PREFIX)\include;$(FMOD3_PREFIX)api\inc;$(IncludePath)</IncludePath> - <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SDL12_PREFIX)\include;$(SDL12_MIXER_PREFIX)\include;$(FMOD3_PREFIX)api\inc;$(IncludePath)</IncludePath> - <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SDL12_PREFIX)\include;$(SDL12_MIXER_PREFIX)\include;$(FMOD3_PREFIX)api\inc;$(IncludePath)</IncludePath> - <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SDL12_PREFIX)\include;$(SDL12_MIXER_PREFIX)\include;$(FMOD3_PREFIX)api\inc;$(IncludePath)</IncludePath> - <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SDL12_PREFIX)\lib;$(SDL12_MIXER_PREFIX)\lib;$(LibraryPath)</LibraryPath> - <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SDL12_PREFIX)\lib;$(SDL12_MIXER_PREFIX)\lib;$(LibraryPath)</LibraryPath> - <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SDL12_PREFIX)\lib\x64;$(SDL12_MIXER_PREFIX)\lib\x64;$(LibraryPath)</LibraryPath> - <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SDL12_PREFIX)\lib\x64;$(SDL12_MIXER_PREFIX)\lib\x64;$(LibraryPath)</LibraryPath> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <PreBuildEvent> - <Message>Getting revision number from the SCM system</Message> - <Command>"$(ProjectDir)..\..\comptime.bat" "$(ProjectDir).."</Command> - </PreBuildEvent> - <Midl> - <TypeLibraryName>.\..\..\bin\VC10\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.tlb</TypeLibraryName> - <HeaderFileName> - </HeaderFileName> - </Midl> - <ClCompile> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>$(ProjectDir)..\..\libs\libpng-src;$(ProjectDir)..\..\libs\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_DEBUG;USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;USEASM;HAVE_PNG;COMPVERSION;HAVE_BLUA;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> - <ProgramDataBaseFileName>$(IntDir)Srb2SDL.pdb</ProgramDataBaseFileName> - <BrowseInformation>true</BrowseInformation> - <WarningLevel>Level4</WarningLevel> - <TreatWarningAsError>true</TreatWarningAsError> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>EditAndContinue</DebugInformationFormat> - <CompileAs>CompileAsC</CompileAs> - <DisableSpecificWarnings>4121;%(DisableSpecificWarnings)</DisableSpecificWarnings> - </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Culture>0x0409</Culture> - </ResourceCompile> - <Link> - <AdditionalDependencies>SDL.lib;SDL_mixer.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> - <OutputFile>$(OutDir)srb2sdl.exe</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(OutDir)srb2sdl.pdb</ProgramDatabaseFile> - <SubSystem>Console</SubSystem> - <RandomizedBaseAddress>false</RandomizedBaseAddress> - <DataExecutionPrevention> - </DataExecutionPrevention> - <TargetMachine>MachineX86</TargetMachine> - </Link> - <Bscmake> - <SuppressStartupBanner>true</SuppressStartupBanner> - <OutputFile>$(OutDir)Srb2sdl.bsc</OutputFile> - </Bscmake> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <PreBuildEvent> - <Message>Getting revision number from the SCM system</Message> - <Command>"$(ProjectDir)..\..\comptime.bat" "$(ProjectDir).."</Command> - </PreBuildEvent> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - <TypeLibraryName>.\..\..\bin\VC10\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.tlb</TypeLibraryName> - <HeaderFileName> - </HeaderFileName> - </Midl> - <ClCompile> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>$(ProjectDir)..\..\libs\libpng-src;$(ProjectDir)..\..\libs\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_DEBUG;USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;HAVE_PNG;COMPVERSION;HAVE_BLUA;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> - <ProgramDataBaseFileName>$(IntDir)Srb2SDL.pdb</ProgramDataBaseFileName> - <BrowseInformation>true</BrowseInformation> - <WarningLevel>Level4</WarningLevel> - <TreatWarningAsError>true</TreatWarningAsError> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <CompileAs>CompileAsC</CompileAs> - <DisableSpecificWarnings>4121;%(DisableSpecificWarnings)</DisableSpecificWarnings> - </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Culture>0x0409</Culture> - </ResourceCompile> - <Link> - <AdditionalDependencies>SDL.lib;SDL_mixer.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> - <OutputFile>$(OutDir)srb2sdl.exe</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(OutDir)srb2sdl.pdb</ProgramDatabaseFile> - <SubSystem>Console</SubSystem> - <RandomizedBaseAddress>false</RandomizedBaseAddress> - <DataExecutionPrevention> - </DataExecutionPrevention> - <TargetMachine>MachineX64</TargetMachine> - </Link> - <Bscmake> - <SuppressStartupBanner>true</SuppressStartupBanner> - <OutputFile>$(OutDir)Srb2sdl.bsc</OutputFile> - </Bscmake> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <PreBuildEvent> - <Message>Getting revision number from the SCM system</Message> - <Command>"$(ProjectDir)..\..\comptime.bat" "$(ProjectDir).."</Command> - </PreBuildEvent> - <Midl> - <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MkTypLibCompatible>true</MkTypLibCompatible> - <SuppressStartupBanner>true</SuppressStartupBanner> - <TargetEnvironment>Win32</TargetEnvironment> - <TypeLibraryName>.\..\..\bin\VC10\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.tlb</TypeLibraryName> - <HeaderFileName> - </HeaderFileName> - </Midl> - <ClCompile> - <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions> - <Optimization>Disabled</Optimization> - <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> - <IntrinsicFunctions>true</IntrinsicFunctions> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <OmitFramePointers>true</OmitFramePointers> - <AdditionalIncludeDirectories>$(ProjectDir)..\..\libs\libpng-src;$(ProjectDir)..\..\libs\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>NDEBUG;SDLMAIN;NO_STDIO_REDIRECT;USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;USEASM;HAVE_PNG;COMPVERSION;HAVE_BLUA;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <StringPooling>true</StringPooling> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <PrecompiledHeaderOutputFile>.\..\..\objs\VC10\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.pch</PrecompiledHeaderOutputFile> - <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> - <ProgramDataBaseFileName>$(IntDir)Srb2SDL.pdb</ProgramDataBaseFileName> - <BrowseInformation>true</BrowseInformation> - <WarningLevel>Level3</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <CompileAs>CompileAsC</CompileAs> - <DisableSpecificWarnings>4121;%(DisableSpecificWarnings)</DisableSpecificWarnings> - </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Culture>0x0409</Culture> - </ResourceCompile> - <Link> - <AdditionalDependencies>SDL.lib;SDL_mixer.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> - <OutputFile>$(OutDir)srb2sdl.exe</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(OutDir)srb2sdl.pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <RandomizedBaseAddress>false</RandomizedBaseAddress> - <DataExecutionPrevention> - </DataExecutionPrevention> - <TargetMachine>MachineX86</TargetMachine> - </Link> - <Bscmake> - <SuppressStartupBanner>true</SuppressStartupBanner> - <OutputFile>$(OutDir)Srb2sdl.bsc</OutputFile> - </Bscmake> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <PreBuildEvent> - <Message>Getting revision number from the SCM system</Message> - <Command>"$(ProjectDir)..\..\comptime.bat" "$(ProjectDir).."</Command> - </PreBuildEvent> - <Midl> - <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MkTypLibCompatible>true</MkTypLibCompatible> - <SuppressStartupBanner>true</SuppressStartupBanner> - <TargetEnvironment>X64</TargetEnvironment> - <TypeLibraryName>.\..\..\bin\VC10\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.tlb</TypeLibraryName> - <HeaderFileName> - </HeaderFileName> - </Midl> - <ClCompile> - <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions> - <Optimization>Disabled</Optimization> - <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> - <IntrinsicFunctions>true</IntrinsicFunctions> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <OmitFramePointers>true</OmitFramePointers> - <AdditionalIncludeDirectories>$(ProjectDir)..\..\libs\libpng-src;$(ProjectDir)..\..\libs\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>NDEBUG;SDLMAIN;NO_STDIO_REDIRECT;USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;HAVE_PNG;COMPVERSION;HAVE_BLUA;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <StringPooling>true</StringPooling> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <PrecompiledHeaderOutputFile>.\..\..\objs\VC10\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.pch</PrecompiledHeaderOutputFile> - <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> - <ProgramDataBaseFileName>$(IntDir)Srb2SDL.pdb</ProgramDataBaseFileName> - <BrowseInformation>true</BrowseInformation> - <WarningLevel>Level3</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <CompileAs>CompileAsC</CompileAs> - <DisableSpecificWarnings>4121;%(DisableSpecificWarnings)</DisableSpecificWarnings> - </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Culture>0x0409</Culture> - </ResourceCompile> - <Link> - <AdditionalDependencies>SDL.lib;SDL_mixer.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> - <OutputFile>$(OutDir)srb2sdl.exe</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(OutDir)srb2sdl.pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <RandomizedBaseAddress>false</RandomizedBaseAddress> - <DataExecutionPrevention> - </DataExecutionPrevention> - <TargetMachine>MachineX64</TargetMachine> - </Link> - <Bscmake> - <SuppressStartupBanner>true</SuppressStartupBanner> - <OutputFile>$(OutDir)Srb2sdl.bsc</OutputFile> - </Bscmake> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\blua\lapi.c" /> - <ClCompile Include="..\blua\lauxlib.c" /> - <ClCompile Include="..\blua\lbaselib.c" /> - <ClCompile Include="..\blua\lcode.c" /> - <ClCompile Include="..\blua\ldebug.c" /> - <ClCompile Include="..\blua\ldo.c" /> - <ClCompile Include="..\blua\ldump.c" /> - <ClCompile Include="..\blua\lfunc.c" /> - <ClCompile Include="..\blua\lgc.c" /> - <ClCompile Include="..\blua\linit.c" /> - <ClCompile Include="..\blua\llex.c" /> - <ClCompile Include="..\blua\lmem.c" /> - <ClCompile Include="..\blua\lobject.c" /> - <ClCompile Include="..\blua\lopcodes.c" /> - <ClCompile Include="..\blua\lparser.c" /> - <ClCompile Include="..\blua\lstate.c" /> - <ClCompile Include="..\blua\lstring.c" /> - <ClCompile Include="..\blua\lstrlib.c" /> - <ClCompile Include="..\blua\ltable.c" /> - <ClCompile Include="..\blua\ltablib.c" /> - <ClCompile Include="..\blua\ltm.c" /> - <ClCompile Include="..\blua\lundump.c" /> - <ClCompile Include="..\blua\lvm.c" /> - <ClCompile Include="..\blua\lzio.c" /> - <ClCompile Include="..\b_bot.c" /> - <ClCompile Include="..\m_cond.c" /> - <ClCompile Include="dosstr.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="endtxt.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\filesrch.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="hwsym_sdl.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="i_cdmus.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="i_main.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="i_net.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="i_sound.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="i_system.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="i_video.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="IMG_xpm.c"> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="ogl_sdl.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\hardware\r_opengl\r_opengl.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="SDL_main\SDL_win32_main.c"> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\win32\win_dbg.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="filter\filters.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="filter\hq2x.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="filter\lq2x.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\comptime.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\d_clisrv.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\d_main.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\d_net.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\d_netcmd.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\d_netfil.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\dehacked.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\z_zone.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\f_finale.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\f_wipe.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\g_game.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\g_input.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\am_map.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\command.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\console.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\hu_stuff.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\st_stuff.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\y_inter.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\hardware\hw3sound.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\hardware\hw_bsp.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\hardware\hw_cache.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\hardware\hw_draw.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\hardware\hw_light.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\hardware\hw_main.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\hardware\hw_md2.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\hardware\hw_md2load.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\hardware\hw_md3load.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\hardware\hw_model.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\hardware\hw_trick.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\hardware\u_list.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\i_tcp.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\mserv.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\m_argv.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\m_bbox.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\m_cheat.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\m_fixed.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\m_menu.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\apng.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\m_misc.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\m_queue.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\m_random.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\string.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\info.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\p_ceilng.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\p_enemy.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\p_fab.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\p_floor.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\p_inter.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\p_lights.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\p_map.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\p_maputl.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\p_mobj.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\p_polyobj.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\p_saveg.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\p_setup.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\p_sight.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\p_spec.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\p_telept.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\p_tick.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\p_user.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\tables.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\r_bsp.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\r_data.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\r_draw.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\r_draw16.c"> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\r_draw8.c"> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\r_main.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\r_plane.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\r_segs.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\r_sky.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\r_splats.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\r_things.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\screen.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\v_video.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\s_sound.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\sounds.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\lzf.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\md5.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\w_wad.c"> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\blua\lapi.h" /> - <ClInclude Include="..\blua\lauxlib.h" /> - <ClInclude Include="..\blua\lcode.h" /> - <ClInclude Include="..\blua\ldebug.h" /> - <ClInclude Include="..\blua\ldo.h" /> - <ClInclude Include="..\blua\lfunc.h" /> - <ClInclude Include="..\blua\lgc.h" /> - <ClInclude Include="..\blua\llex.h" /> - <ClInclude Include="..\blua\llimits.h" /> - <ClInclude Include="..\blua\lmem.h" /> - <ClInclude Include="..\blua\lobject.h" /> - <ClInclude Include="..\blua\lopcodes.h" /> - <ClInclude Include="..\blua\lparser.h" /> - <ClInclude Include="..\blua\lstate.h" /> - <ClInclude Include="..\blua\lstring.h" /> - <ClInclude Include="..\blua\ltable.h" /> - <ClInclude Include="..\blua\ltm.h" /> - <ClInclude Include="..\blua\lua.h" /> - <ClInclude Include="..\blua\luaconf.h" /> - <ClInclude Include="..\blua\lualib.h" /> - <ClInclude Include="..\blua\lundump.h" /> - <ClInclude Include="..\blua\lvm.h" /> - <ClInclude Include="..\blua\lzio.h" /> - <ClInclude Include="..\b_bot.h" /> - <ClInclude Include="..\m_cond.h" /> - <ClInclude Include="endtxt.h" /> - <ClInclude Include="..\filesrch.h" /> - <ClInclude Include="hwsym_sdl.h" /> - <ClInclude Include="ogl_sdl.h" /> - <ClInclude Include="..\hardware\r_opengl\r_opengl.h" /> - <ClInclude Include="sdlmain.h" /> - <ClInclude Include="..\win32\win_dbg.h" /> - <ClInclude Include="..\win32\win_main.h" /> - <ClInclude Include="filter\filters.h" /> - <ClInclude Include="filter\hq2x.h" /> - <ClInclude Include="filter\interp.h" /> - <ClInclude Include="filter\lq2x.h" /> - <ClInclude Include="..\p5prof.h" /> - <ClInclude Include="..\apng.h" /> - <ClInclude Include="..\d_clisrv.h" /> - <ClInclude Include="..\d_event.h" /> - <ClInclude Include="..\d_main.h" /> - <ClInclude Include="..\d_net.h" /> - <ClInclude Include="..\d_netcmd.h" /> - <ClInclude Include="..\d_netfil.h" /> - <ClInclude Include="..\d_player.h" /> - <ClInclude Include="..\d_think.h" /> - <ClInclude Include="..\d_ticcmd.h" /> - <ClInclude Include="..\dehacked.h" /> - <ClInclude Include="..\doomdata.h" /> - <ClInclude Include="..\doomdef.h" /> - <ClInclude Include="..\doomstat.h" /> - <ClInclude Include="..\doomtype.h" /> - <ClInclude Include="..\z_zone.h" /> - <ClInclude Include="..\f_finale.h" /> - <ClInclude Include="..\g_game.h" /> - <ClInclude Include="..\g_input.h" /> - <ClInclude Include="..\g_state.h" /> - <ClInclude Include="..\am_map.h" /> - <ClInclude Include="..\command.h" /> - <ClInclude Include="..\console.h" /> - <ClInclude Include="..\hu_stuff.h" /> - <ClInclude Include="..\st_stuff.h" /> - <ClInclude Include="..\y_inter.h" /> - <ClInclude Include="..\hardware\hw3dsdrv.h" /> - <ClInclude Include="..\hardware\hw3sound.h" /> - <ClInclude Include="..\hardware\hw_data.h" /> - <ClInclude Include="..\hardware\hw_defs.h" /> - <ClInclude Include="..\hardware\hw_dll.h" /> - <ClInclude Include="..\hardware\hw_drv.h" /> - <ClInclude Include="..\hardware\hw_glide.h" /> - <ClInclude Include="..\hardware\hw_glob.h" /> - <ClInclude Include="..\hardware\hw_light.h" /> - <ClInclude Include="..\hardware\hw_main.h" /> - <ClInclude Include="..\hardware\hw_md2.h" /> - <ClInclude Include="..\hardware\hw_md2load.h" /> - <ClInclude Include="..\hardware\hw_md3load.h" /> - <ClInclude Include="..\hardware\hw_model.h" /> - <ClInclude Include="..\hardware\hws_data.h" /> - <ClInclude Include="..\hardware\u_list.h" /> - <ClInclude Include="..\byteptr.h" /> - <ClInclude Include="..\i_joy.h" /> - <ClInclude Include="..\i_net.h" /> - <ClInclude Include="..\i_sound.h" /> - <ClInclude Include="..\i_system.h" /> - <ClInclude Include="..\i_tcp.h" /> - <ClInclude Include="..\i_video.h" /> - <ClInclude Include="..\keys.h" /> - <ClInclude Include="..\mserv.h" /> - <ClInclude Include="..\m_argv.h" /> - <ClInclude Include="..\m_bbox.h" /> - <ClInclude Include="..\m_cheat.h" /> - <ClInclude Include="..\m_dllist.h" /> - <ClInclude Include="..\m_fixed.h" /> - <ClInclude Include="..\m_menu.h" /> - <ClInclude Include="..\m_misc.h" /> - <ClInclude Include="..\m_queue.h" /> - <ClInclude Include="..\m_random.h" /> - <ClInclude Include="..\m_swap.h" /> - <ClInclude Include="..\info.h" /> - <ClInclude Include="..\p_local.h" /> - <ClInclude Include="..\p_maputl.h" /> - <ClInclude Include="..\p_mobj.h" /> - <ClInclude Include="..\p_polyobj.h" /> - <ClInclude Include="..\p_pspr.h" /> - <ClInclude Include="..\p_saveg.h" /> - <ClInclude Include="..\p_setup.h" /> - <ClInclude Include="..\p_spec.h" /> - <ClInclude Include="..\p_tick.h" /> - <ClInclude Include="..\tables.h" /> - <ClInclude Include="..\r_bsp.h" /> - <ClInclude Include="..\r_data.h" /> - <ClInclude Include="..\r_defs.h" /> - <ClInclude Include="..\r_draw.h" /> - <ClInclude Include="..\r_local.h" /> - <ClInclude Include="..\r_main.h" /> - <ClInclude Include="..\r_plane.h" /> - <ClInclude Include="..\r_segs.h" /> - <ClInclude Include="..\r_sky.h" /> - <ClInclude Include="..\r_splats.h" /> - <ClInclude Include="..\r_state.h" /> - <ClInclude Include="..\r_things.h" /> - <ClInclude Include="..\screen.h" /> - <ClInclude Include="..\v_video.h" /> - <ClInclude Include="..\s_sound.h" /> - <ClInclude Include="..\sounds.h" /> - <ClInclude Include="..\lzf.h" /> - <ClInclude Include="..\md5.h" /> - <ClInclude Include="..\w_wad.h" /> - </ItemGroup> - <ItemGroup> - <None Include="SDL_icon.xpm" /> - <CustomBuild Include="..\tmap.nas"> - <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compiling %(Filename).nas with NASM...</Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)"</Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> - <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Compiling %(Filename).nas with NASM...</Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)"</Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs> - <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compiling %(Filename).nas with NASM...</Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)"</Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> - <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Compiling %(Filename).nas with NASM...</Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)"</Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs> - </CustomBuild> - <CustomBuild Include="..\tmap_mmx.nas"> - <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compiling %(Filename).nas with NASM...</Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)"</Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> - <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Compiling %(Filename).nas with NASM...</Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)"</Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs> - <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compiling %(Filename).nas with NASM...</Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)"</Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> - <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Compiling %(Filename).nas with NASM...</Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)"</Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs> - </CustomBuild> - <CustomBuild Include="..\tmap_vc.nas"> - <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compiling %(Filename).nas with NASM...</Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)"</Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> - <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Compiling %(Filename).nas with NASM...</Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)"</Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs> - <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compiling %(Filename).nas with NASM...</Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)"</Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> - <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Compiling %(Filename).nas with NASM...</Message> - <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)"</Command> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs> - </CustomBuild> - <None Include="..\..\doc\copying" /> - <None Include="..\..\doc\faq.txt" /> - <None Include="..\..\readme.txt" /> - <None Include="..\..\doc\source.txt" /> - <None Include="..\win32\Srb2win.ico" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\win32\Srb2win.rc"> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\Users\alam\svn\srb2mods\SRB2\branches\ALAM\src\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\Users\alam\svn\srb2mods\SRB2\branches\ALAM\src\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\Users\alam\svn\srb2mods\SRB2\branches\ALAM\src\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\Users\alam\svn\srb2mods\SRB2\branches\ALAM\src\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ResourceCompile> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="..\..\libs\libpng-src\projects\visualc10\libpng.vcxproj"> - <Project>{72b01aca-7a1a-4f7b-acef-2607299cf052}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - <ProjectReference Include="..\..\libs\zlib\projects\visualc10\zlib.vcxproj"> - <Project>{73a5729c-7323-41d4-ab48-8a03c9f81603}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> diff --git a/src/sdl12/Srb2SDL-vc9.vcproj b/src/sdl12/Srb2SDL-vc9.vcproj deleted file mode 100644 index fa386e381b11ab04d98cfd05e7e747ac34767bc2..0000000000000000000000000000000000000000 --- a/src/sdl12/Srb2SDL-vc9.vcproj +++ /dev/null @@ -1,5889 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="9.00" - Name="Srb2SDL" - ProjectGUID="{61BA7D3C-F77D-4D31-B718-1177FE482CF2}" - RootNamespace="Srb2SDL" - TargetFrameworkVersion="0" - > - <Platforms> - <Platform - Name="Win32" - /> - <Platform - Name="x64" - /> - </Platforms> - <ToolFiles> - </ToolFiles> - <Configurations> - <Configuration - Name="Debug|Win32" - OutputDirectory=".\..\..\bin\VC9\$(PlatformName)\$(ConfigurationName)" - IntermediateDirectory=".\..\..\objs\VC9\$(PlatformName)\$(ConfigurationName)\SDL" - ConfigurationType="1" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops" - UseOfMFC="0" - ATLMinimizesCRunTimeLibraryUsage="false" - > - <Tool - Name="VCPreBuildEventTool" - Description="Getting revision number from the SCM system" - CommandLine=""$(ProjectDir)..\..\comptime.bat" "$(ProjectDir).."" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - TypeLibraryName=".\..\..\bin\VC9\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.tlb" - HeaderFileName="" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="0" - AdditionalIncludeDirectories=""$(ProjectDir)..\..\libs\libpng-src";"$(ProjectDir)..\..\libs\zlib"" - PreprocessorDefinitions="_DEBUG;USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;USEASM;HAVE_PNG;HAVE_BLUA;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE" - MinimalRebuild="true" - BasicRuntimeChecks="3" - RuntimeLibrary="1" - AssemblerListingLocation="$(IntDir)\" - ProgramDataBaseFileName="$(IntDir)\Srb2SDL.pdb" - BrowseInformation="1" - WarningLevel="4" - WarnAsError="true" - SuppressStartupBanner="true" - DebugInformationFormat="4" - CompileAs="1" - DisableSpecificWarnings="4121" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - PreprocessorDefinitions="_DEBUG" - Culture="1033" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="SDL.lib SDL_mixer.lib ws2_32.lib" - OutputFile="$(OutDir)\srb2sdl.exe" - LinkIncremental="2" - SuppressStartupBanner="true" - GenerateDebugInformation="true" - ProgramDatabaseFile="$(OutDir)\srb2sdl.pdb" - SubSystem="1" - RandomizedBaseAddress="1" - DataExecutionPrevention="0" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - SuppressStartupBanner="true" - OutputFile="$(OutDir)\Srb2sdl.bsc" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - <Configuration - Name="Debug|x64" - OutputDirectory=".\..\..\bin\VC9\$(PlatformName)\$(ConfigurationName)" - IntermediateDirectory=".\..\..\objs\VC9\$(PlatformName)\$(ConfigurationName)\SDL" - ConfigurationType="1" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops" - UseOfMFC="0" - ATLMinimizesCRunTimeLibraryUsage="false" - > - <Tool - Name="VCPreBuildEventTool" - Description="Getting revision number from the SCM system" - CommandLine=""$(ProjectDir)..\..\comptime.bat" "$(ProjectDir).."" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - TargetEnvironment="3" - TypeLibraryName=".\..\..\bin\VC9\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.tlb" - HeaderFileName="" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="0" - AdditionalIncludeDirectories=""$(ProjectDir)..\..\libs\libpng-src";"$(ProjectDir)..\..\libs\zlib"" - PreprocessorDefinitions="_DEBUG;USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;HAVE_PNG;HAVE_BLUA;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE" - MinimalRebuild="true" - BasicRuntimeChecks="3" - RuntimeLibrary="1" - AssemblerListingLocation="$(IntDir)\" - ProgramDataBaseFileName="$(IntDir)\Srb2SDL.pdb" - BrowseInformation="1" - WarningLevel="4" - WarnAsError="true" - SuppressStartupBanner="true" - DebugInformationFormat="3" - CompileAs="1" - DisableSpecificWarnings="4121" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - PreprocessorDefinitions="_DEBUG" - Culture="1033" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="SDL.lib SDL_mixer.lib ws2_32.lib" - OutputFile="$(OutDir)\srb2sdl.exe" - LinkIncremental="2" - SuppressStartupBanner="true" - GenerateDebugInformation="true" - ProgramDatabaseFile="$(OutDir)\srb2sdl.pdb" - SubSystem="1" - RandomizedBaseAddress="1" - DataExecutionPrevention="0" - TargetMachine="17" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - SuppressStartupBanner="true" - OutputFile="$(OutDir)\Srb2sdl.bsc" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - <Configuration - Name="Release|Win32" - OutputDirectory=".\..\..\bin\VC9\$(PlatformName)\$(ConfigurationName)" - IntermediateDirectory=".\..\..\objs\VC9\$(PlatformName)\$(ConfigurationName)\SDL" - ConfigurationType="1" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops" - UseOfMFC="0" - ATLMinimizesCRunTimeLibraryUsage="false" - > - <Tool - Name="VCPreBuildEventTool" - Description="Getting revision number from the SCM system" - CommandLine=""$(ProjectDir)..\..\comptime.bat" "$(ProjectDir).."" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - PreprocessorDefinitions="NDEBUG" - MkTypLibCompatible="true" - SuppressStartupBanner="true" - TargetEnvironment="1" - TypeLibraryName=".\..\..\bin\VC9\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.tlb" - HeaderFileName="" - /> - <Tool - Name="VCCLCompilerTool" - AdditionalOptions="/MP" - Optimization="4" - InlineFunctionExpansion="1" - EnableIntrinsicFunctions="true" - FavorSizeOrSpeed="1" - OmitFramePointers="true" - AdditionalIncludeDirectories=""$(ProjectDir)..\..\libs\libpng-src";"$(ProjectDir)..\..\libs\zlib"" - PreprocessorDefinitions="NDEBUG;SDLMAIN;NO_STDIO_REDIRECT;USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;USEASM;HAVE_PNG;HAVE_BLUA;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE" - StringPooling="true" - RuntimeLibrary="0" - PrecompiledHeaderFile=".\..\..\objs\VC9\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.pch" - AssemblerListingLocation="$(IntDir)\" - ProgramDataBaseFileName="$(IntDir)\Srb2SDL.pdb" - BrowseInformation="1" - WarningLevel="3" - SuppressStartupBanner="true" - DebugInformationFormat="3" - CompileAs="1" - DisableSpecificWarnings="4121" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - PreprocessorDefinitions="NDEBUG" - Culture="1033" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="SDL.lib SDL_mixer.lib ws2_32.lib" - OutputFile="$(OutDir)\srb2sdl.exe" - LinkIncremental="1" - SuppressStartupBanner="true" - GenerateDebugInformation="true" - ProgramDatabaseFile="$(OutDir)\srb2sdl.pdb" - SubSystem="2" - RandomizedBaseAddress="1" - DataExecutionPrevention="0" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - SuppressStartupBanner="true" - OutputFile="$(OutDir)\Srb2sdl.bsc" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - <Configuration - Name="Release|x64" - OutputDirectory=".\..\..\bin\VC9\$(PlatformName)\$(ConfigurationName)" - IntermediateDirectory=".\..\..\objs\VC9\$(PlatformName)\$(ConfigurationName)\SDL" - ConfigurationType="1" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops" - UseOfMFC="0" - ATLMinimizesCRunTimeLibraryUsage="false" - > - <Tool - Name="VCPreBuildEventTool" - Description="Getting revision number from the SCM system" - CommandLine=""$(ProjectDir)..\..\comptime.bat" "$(ProjectDir).."" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - PreprocessorDefinitions="NDEBUG" - MkTypLibCompatible="true" - SuppressStartupBanner="true" - TargetEnvironment="3" - TypeLibraryName=".\..\..\bin\VC9\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.tlb" - HeaderFileName="" - /> - <Tool - Name="VCCLCompilerTool" - AdditionalOptions="/MP" - Optimization="4" - InlineFunctionExpansion="1" - EnableIntrinsicFunctions="true" - FavorSizeOrSpeed="1" - OmitFramePointers="true" - AdditionalIncludeDirectories=""$(ProjectDir)..\..\libs\libpng-src";"$(ProjectDir)..\..\libs\zlib"" - PreprocessorDefinitions="NDEBUG;SDLMAIN;NO_STDIO_REDIRECT;USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;HAVE_PNG;HAVE_BLUA;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE" - StringPooling="true" - RuntimeLibrary="0" - PrecompiledHeaderFile=".\..\..\objs\VC9\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.pch" - AssemblerListingLocation="$(IntDir)\" - ProgramDataBaseFileName="$(IntDir)\Srb2SDL.pdb" - BrowseInformation="1" - WarningLevel="3" - SuppressStartupBanner="true" - DebugInformationFormat="3" - CompileAs="1" - DisableSpecificWarnings="4121" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - PreprocessorDefinitions="NDEBUG" - Culture="1033" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="SDL.lib SDL_mixer.lib ws2_32.lib" - OutputFile="$(OutDir)\srb2sdl.exe" - LinkIncremental="1" - SuppressStartupBanner="true" - GenerateDebugInformation="true" - ProgramDatabaseFile="$(OutDir)\srb2sdl.pdb" - SubSystem="2" - RandomizedBaseAddress="1" - DataExecutionPrevention="0" - TargetMachine="17" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - SuppressStartupBanner="true" - OutputFile="$(OutDir)\Srb2sdl.bsc" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - </Configurations> - <References> - </References> - <Files> - <Filter - Name="SDLapp" - > - <File - RelativePath="dosstr.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="endtxt.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="endtxt.h" - > - </File> - <File - RelativePath="..\filesrch.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\filesrch.h" - > - </File> - <File - RelativePath="hwsym_sdl.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="hwsym_sdl.h" - > - </File> - <File - RelativePath="i_cdmus.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="i_main.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="i_net.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="i_sound.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="i_system.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="i_video.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="IMG_xpm.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="ogl_sdl.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="ogl_sdl.h" - > - </File> - <File - RelativePath="..\hardware\r_opengl\r_opengl.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\hardware\r_opengl\r_opengl.h" - > - </File> - <File - RelativePath="SDL_icon.xpm" - > - </File> - <File - RelativePath="SDL_main\SDL_win32_main.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="sdlmain.h" - > - </File> - <File - RelativePath="..\win32\Srb2win.rc" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCResourceCompilerTool" - PreprocessorDefinitions="" - AdditionalIncludeDirectories="\Users\alam\svn\srb2mods\SRB2\branches\ALAM\src\win32" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCResourceCompilerTool" - PreprocessorDefinitions="" - AdditionalIncludeDirectories="\Users\alam\svn\srb2mods\SRB2\branches\ALAM\src\win32" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCResourceCompilerTool" - PreprocessorDefinitions="" - AdditionalIncludeDirectories="\Users\alam\svn\srb2mods\SRB2\branches\ALAM\src\win32" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCResourceCompilerTool" - PreprocessorDefinitions="" - AdditionalIncludeDirectories="\Users\alam\svn\srb2mods\SRB2\branches\ALAM\src\win32" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\win32\win_dbg.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\win32\win_dbg.h" - > - </File> - <File - RelativePath="..\win32\win_main.h" - > - </File> - <Filter - Name="filter" - > - <File - RelativePath="filter\filters.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="filter\filters.h" - > - </File> - <File - RelativePath="filter\hq2x.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="filter\hq2x.h" - > - </File> - <File - RelativePath="filter\interp.h" - > - </File> - <File - RelativePath="filter\lq2x.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="filter\lq2x.h" - > - </File> - </Filter> - </Filter> - <Filter - Name="A_Asm" - > - <File - RelativePath="..\p5prof.h" - > - </File> - <File - RelativePath="..\tmap.nas" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - Description="Compiling $(InputName).nas with NASM..." - CommandLine="nasm -g -o $(IntDir)/$(InputName).obj -f win32 "$(InputPath)"
" - Outputs="$(IntDir)/$(InputName).obj" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - ExcludedFromBuild="true" - > - <Tool - Name="VCCustomBuildTool" - Description="Compiling $(InputName).nas with NASM..." - CommandLine="nasm -g -o $(IntDir)/$(InputName).obj -f win32 "$(InputPath)"
" - Outputs="$(IntDir)/$(InputName).obj" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - Description="Compiling $(InputName).nas with NASM..." - CommandLine="nasm -g -o $(IntDir)/$(InputName).obj -f win32 "$(InputPath)"
" - Outputs="$(IntDir)/$(InputName).obj" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - ExcludedFromBuild="true" - > - <Tool - Name="VCCustomBuildTool" - Description="Compiling $(InputName).nas with NASM..." - CommandLine="nasm -g -o $(IntDir)/$(InputName).obj -f win32 "$(InputPath)"
" - Outputs="$(IntDir)/$(InputName).obj" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\tmap_mmx.nas" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - Description="Compiling $(InputName).nas with NASM..." - CommandLine="nasm -g -o $(IntDir)/$(InputName).obj -f win32 "$(InputPath)"
" - Outputs="$(IntDir)/$(InputName).obj" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - ExcludedFromBuild="true" - > - <Tool - Name="VCCustomBuildTool" - Description="Compiling $(InputName).nas with NASM..." - CommandLine="nasm -g -o $(IntDir)/$(InputName).obj -f win32 "$(InputPath)"
" - Outputs="$(IntDir)/$(InputName).obj" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - Description="Compiling $(InputName).nas with NASM..." - CommandLine="nasm -g -o $(IntDir)/$(InputName).obj -f win32 "$(InputPath)"
" - Outputs="$(IntDir)/$(InputName).obj" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - ExcludedFromBuild="true" - > - <Tool - Name="VCCustomBuildTool" - Description="Compiling $(InputName).nas with NASM..." - CommandLine="nasm -g -o $(IntDir)/$(InputName).obj -f win32 "$(InputPath)"
" - Outputs="$(IntDir)/$(InputName).obj" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\tmap_vc.nas" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - Description="Compiling $(InputName).nas with NASM..." - CommandLine="nasm -g -o $(IntDir)/$(InputName).obj -f win32 "$(InputPath)"
" - Outputs="$(IntDir)/$(InputName).obj" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - ExcludedFromBuild="true" - > - <Tool - Name="VCCustomBuildTool" - Description="Compiling $(InputName).nas with NASM..." - CommandLine="nasm -g -o $(IntDir)/$(InputName).obj -f win32 "$(InputPath)"
" - Outputs="$(IntDir)/$(InputName).obj" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - Description="Compiling $(InputName).nas with NASM..." - CommandLine="nasm -g -o $(IntDir)/$(InputName).obj -f win32 "$(InputPath)"
" - Outputs="$(IntDir)/$(InputName).obj" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - ExcludedFromBuild="true" - > - <Tool - Name="VCCustomBuildTool" - Description="Compiling $(InputName).nas with NASM..." - CommandLine="nasm -g -o $(IntDir)/$(InputName).obj -f win32 "$(InputPath)"
" - Outputs="$(IntDir)/$(InputName).obj" - /> - </FileConfiguration> - </File> - </Filter> - <Filter - Name="D_Doom" - > - <File - RelativePath="..\comptime.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\d_clisrv.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\d_clisrv.h" - > - </File> - <File - RelativePath="..\d_event.h" - > - </File> - <File - RelativePath="..\d_main.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\d_main.h" - > - </File> - <File - RelativePath="..\d_net.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\d_net.h" - > - </File> - <File - RelativePath="..\d_netcmd.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\d_netcmd.h" - > - </File> - <File - RelativePath="..\d_netfil.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\d_netfil.h" - > - </File> - <File - RelativePath="..\d_player.h" - > - </File> - <File - RelativePath="..\d_think.h" - > - </File> - <File - RelativePath="..\d_ticcmd.h" - > - </File> - <File - RelativePath="..\dehacked.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\dehacked.h" - > - </File> - <File - RelativePath="..\doomdata.h" - > - </File> - <File - RelativePath="..\doomdef.h" - > - </File> - <File - RelativePath="..\doomstat.h" - > - </File> - <File - RelativePath="..\doomtype.h" - > - </File> - <File - RelativePath="..\z_zone.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\z_zone.h" - > - </File> - </Filter> - <Filter - Name="F_Frame" - > - <File - RelativePath="..\f_finale.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\f_finale.h" - > - </File> - <File - RelativePath="..\f_wipe.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - </Filter> - <Filter - Name="G_Game" - > - <File - RelativePath="..\g_game.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\g_game.h" - > - </File> - <File - RelativePath="..\g_input.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\g_input.h" - > - </File> - <File - RelativePath="..\g_state.h" - > - </File> - </Filter> - <Filter - Name="H_Hud" - > - <File - RelativePath="..\am_map.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\am_map.h" - > - </File> - <File - RelativePath="..\command.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\command.h" - > - </File> - <File - RelativePath="..\console.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\console.h" - > - </File> - <File - RelativePath="..\hu_stuff.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\hu_stuff.h" - > - </File> - <File - RelativePath="..\st_stuff.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\st_stuff.h" - > - </File> - <File - RelativePath="..\y_inter.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\y_inter.h" - > - </File> - </Filter> - <Filter - Name="Hw_Hardware" - > - <File - RelativePath="..\hardware\hw3dsdrv.h" - > - </File> - <File - RelativePath="..\hardware\hw3sound.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\hardware\hw3sound.h" - > - </File> - <File - RelativePath="..\hardware\hw_bsp.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\hardware\hw_cache.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\hardware\hw_data.h" - > - </File> - <File - RelativePath="..\hardware\hw_defs.h" - > - </File> - <File - RelativePath="..\hardware\hw_dll.h" - > - </File> - <File - RelativePath="..\hardware\hw_draw.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\hardware\hw_drv.h" - > - </File> - <File - RelativePath="..\hardware\hw_glide.h" - > - </File> - <File - RelativePath="..\hardware\hw_glob.h" - > - </File> - <File - RelativePath="..\hardware\hw_light.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\hardware\hw_light.h" - > - </File> - <File - RelativePath="..\hardware\hw_main.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\hardware\hw_main.h" - > - </File> - <File - RelativePath="..\hardware\hw_md2.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\hardware\hw_md2.h" - > - </File> - <File - RelativePath="..\hardware\hw_trick.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\hardware\hws_data.h" - > - </File> - </Filter> - <Filter - Name="I_Interface" - > - <File - RelativePath="..\byteptr.h" - > - </File> - <File - RelativePath="..\i_addrinfo.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\i_addrinfo.h" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - ExcludedFromBuild="true" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - ExcludedFromBuild="true" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\i_joy.h" - > - </File> - <File - RelativePath="..\i_net.h" - > - </File> - <File - RelativePath="..\i_sound.h" - > - </File> - <File - RelativePath="..\i_system.h" - > - </File> - <File - RelativePath="..\i_tcp.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\i_tcp.h" - > - </File> - <File - RelativePath="..\i_video.h" - > - </File> - <File - RelativePath="..\keys.h" - > - </File> - <File - RelativePath="..\mserv.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\mserv.h" - > - </File> - </Filter> - <Filter - Name="M_Misc" - > - <File - RelativePath="..\apng.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\apng.h" - > - </File> - <File - RelativePath="..\m_argv.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\m_argv.h" - > - </File> - <File - RelativePath="..\m_bbox.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\m_bbox.h" - > - </File> - <File - RelativePath="..\m_cheat.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\m_cheat.h" - > - </File> - <File - RelativePath="..\m_cond.c" - > - </File> - <File - RelativePath="..\m_cond.h" - > - </File> - <File - RelativePath="..\m_dllist.h" - > - </File> - <File - RelativePath="..\m_fixed.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\m_fixed.h" - > - </File> - <File - RelativePath="..\m_menu.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\m_menu.h" - > - </File> - <File - RelativePath="..\m_misc.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\m_misc.h" - > - </File> - <File - RelativePath="..\m_queue.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\m_queue.h" - > - </File> - <File - RelativePath="..\m_random.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\m_random.h" - > - </File> - <File - RelativePath="..\m_swap.h" - > - </File> - <File - RelativePath="..\string.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - </Filter> - <Filter - Name="P_Play" - > - <File - RelativePath="..\info.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\info.h" - > - </File> - <File - RelativePath="..\p_ceilng.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\p_enemy.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\p_fab.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\p_floor.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\p_inter.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\p_lights.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\p_local.h" - > - </File> - <File - RelativePath="..\p_map.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\p_maputl.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\p_maputl.h" - > - </File> - <File - RelativePath="..\p_mobj.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\p_mobj.h" - > - </File> - <File - RelativePath="..\p_polyobj.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\p_polyobj.h" - > - </File> - <File - RelativePath="..\p_pspr.h" - > - </File> - <File - RelativePath="..\p_saveg.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\p_saveg.h" - > - </File> - <File - RelativePath="..\p_setup.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\p_setup.h" - > - </File> - <File - RelativePath="..\p_sight.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\p_spec.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\p_spec.h" - > - </File> - <File - RelativePath="..\p_telept.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\p_tick.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\p_tick.h" - > - </File> - <File - RelativePath="..\p_user.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\tables.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\tables.h" - > - </File> - </Filter> - <Filter - Name="R_Rend" - > - <File - RelativePath="..\r_bsp.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\r_bsp.h" - > - </File> - <File - RelativePath="..\r_data.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\r_data.h" - > - </File> - <File - RelativePath="..\r_defs.h" - > - </File> - <File - RelativePath="..\r_draw.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\r_draw.h" - > - </File> - <File - RelativePath="..\r_draw16.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\r_draw8.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\r_local.h" - > - </File> - <File - RelativePath="..\r_main.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\r_main.h" - > - </File> - <File - RelativePath="..\r_plane.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\r_plane.h" - > - </File> - <File - RelativePath="..\r_segs.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\r_segs.h" - > - </File> - <File - RelativePath="..\r_sky.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\r_sky.h" - > - </File> - <File - RelativePath="..\r_splats.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\r_splats.h" - > - </File> - <File - RelativePath="..\r_state.h" - > - </File> - <File - RelativePath="..\r_things.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\r_things.h" - > - </File> - <File - RelativePath="..\screen.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\screen.h" - > - </File> - <File - RelativePath="..\v_video.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\v_video.h" - > - </File> - </Filter> - <Filter - Name="S_Sounds" - > - <File - RelativePath="..\s_sound.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\s_sound.h" - > - </File> - <File - RelativePath="..\sounds.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\sounds.h" - > - </File> - </Filter> - <Filter - Name="W_Wad" - > - <File - RelativePath="..\lzf.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\lzf.h" - > - </File> - <File - RelativePath="..\md5.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\md5.h" - > - </File> - <File - RelativePath="..\w_wad.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\w_wad.h" - > - </File> - </Filter> - <Filter - Name="Docs" - > - <File - RelativePath="..\..\doc\copying" - > - </File> - <File - RelativePath="..\..\doc\faq.txt" - > - </File> - <File - RelativePath="..\..\readme.txt" - > - </File> - <File - RelativePath="..\..\doc\source.txt" - > - </File> - </Filter> - <Filter - Name="B_Bot" - > - <File - RelativePath="..\b_bot.c" - > - </File> - <File - RelativePath="..\b_bot.h" - > - </File> - </Filter> - <Filter - Name="LUA" - > - <File - RelativePath="..\fastcmp.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\lua_baselib.c" - > - </File> - <File - RelativePath="..\lua_consolelib.c" - > - </File> - <File - RelativePath="..\lua_hook.h" - > - </File> - <File - RelativePath="..\lua_hooklib.c" - > - </File> - <File - RelativePath="..\lua_infolib.c" - > - </File> - <File - RelativePath="..\lua_libs.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\lua_maplib.c" - > - </File> - <File - RelativePath="..\lua_mathlib.c" - > - </File> - <File - RelativePath="..\lua_mobjlib.c" - > - </File> - <File - RelativePath="..\lua_playerlib.c" - > - </File> - <File - RelativePath="..\lua_script.c" - > - </File> - <File - RelativePath="..\lua_script.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\lua_thinkerlib.c" - > - </File> - </Filter> - <Filter - Name="BLUA" - > - <File - RelativePath="..\blua\lapi.c" - > - </File> - <File - RelativePath="..\blua\lapi.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\lauxlib.c" - > - </File> - <File - RelativePath="..\blua\lauxlib.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\lbaselib.c" - > - </File> - <File - RelativePath="..\blua\lcode.c" - > - </File> - <File - RelativePath="..\blua\lcode.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\ldebug.c" - > - </File> - <File - RelativePath="..\blua\ldebug.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\ldo.c" - > - </File> - <File - RelativePath="..\blua\ldo.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\ldump.c" - > - </File> - <File - RelativePath="..\blua\lfunc.c" - > - </File> - <File - RelativePath="..\blua\lfunc.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\lgc.c" - > - </File> - <File - RelativePath="..\blua\lgc.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\linit.c" - > - </File> - <File - RelativePath="..\blua\llex.c" - > - </File> - <File - RelativePath="..\blua\llex.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\llimits.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\lmem.c" - > - </File> - <File - RelativePath="..\blua\lmem.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\lobject.c" - > - </File> - <File - RelativePath="..\blua\lobject.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\lopcodes.c" - > - </File> - <File - RelativePath="..\blua\lopcodes.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\lparser.c" - > - </File> - <File - RelativePath="..\blua\lparser.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\lstate.c" - > - </File> - <File - RelativePath="..\blua\lstate.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\lstring.c" - > - </File> - <File - RelativePath="..\blua\lstring.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\lstrlib.c" - > - </File> - <File - RelativePath="..\blua\ltable.c" - > - </File> - <File - RelativePath="..\blua\ltable.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\ltablib.c" - > - </File> - <File - RelativePath="..\blua\ltm.c" - > - </File> - <File - RelativePath="..\blua\ltm.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\lua.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\luaconf.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\lualib.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\lundump.c" - > - </File> - <File - RelativePath="..\blua\lundump.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\lvm.c" - > - </File> - <File - RelativePath="..\blua\lvm.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\blua\lzio.c" - > - </File> - <File - RelativePath="..\blua\lzio.h" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Debug|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|x64" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - </Filter> - <File - RelativePath="..\win32\Srb2win.ico" - > - </File> - </Files> - <Globals> - </Globals> -</VisualStudioProject> diff --git a/src/sdl12/Srb2SDL.dsp b/src/sdl12/Srb2SDL.dsp deleted file mode 100644 index 879113ca2f0d7c6f8a71e7e709303224046cb91f..0000000000000000000000000000000000000000 --- a/src/sdl12/Srb2SDL.dsp +++ /dev/null @@ -1,1057 +0,0 @@ -# Microsoft Developer Studio Project File - Name="Srb2SDL" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=Srb2SDL - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "Srb2SDL.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Srb2SDL.mak" CFG="Srb2SDL - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Srb2SDL - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "Srb2SDL - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "Srb2SDL - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "..\..\bin\VC\Release\SDL" -# PROP Intermediate_Dir "..\..\objs\VC\Release\SDL" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -MTL=midl.exe -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /G5 /W3 /GX /Zi /Ot /Og /Oi /Op /Oy /Ob1 /I "..\..\libs\libpng-src" /I "..\..\libs\zlib" /D "NDEBUG" /D "SDLMAIN" /D "NO_STDIO_REDIRECT" /D "USE_WGL_SWAP" /D "DIRECTFULLSCREEN" /D "HAVE_SDL" /D "HWRENDER" /D "HW3SOUND" /D "HAVE_FILTER" /D "HAVE_MIXER" /D "USEASM" /D "HAVE_PNG" /FR /FD /GF /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -# SUBTRACT RSC /x -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo /o"..\..\objs\SDL\Release\SRB2.bsc" -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 SDL.lib SDL_mixer.lib user32.lib advapi32.lib ws2_32.lib /nologo /subsystem:windows /pdb:"C:\srb2demo2\srb2sdl.pdb" /debug /machine:I386 /out:"C:\srb2demo2\srb2sdl.exe" -# SUBTRACT LINK32 /profile /pdb:none /incremental:yes - -!ELSEIF "$(CFG)" == "Srb2SDL - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "..\..\bin\VC\Debug\SDL" -# PROP Intermediate_Dir "..\..\objs\VC\Debug\SDL" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -MTL=midl.exe -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /G6 /W4 /WX /Gm /GX /ZI /Od /Op /I "..\..\libs\libpng-src" /I "..\..\libs\zlib" /D "_DEBUG" /D "USE_WGL_SWAP" /D "DIRECTFULLSCREEN" /D "HAVE_SDL" /D "HWRENDER" /D "HW3SOUND" /D "HAVE_FILTER" /D "HAVE_MIXER" /D "USEASM" /D "HAVE_PNG" /FR /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -# SUBTRACT RSC /x -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo /o"..\..\objs\SDL\Debug\SRB2.bsc" -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 SDL.lib SDL_mixer.lib user32.lib advapi32.lib ws2_32.lib /nologo /subsystem:console /pdb:"C:\srb2demo2\srb2sdldebug.pdb" /debug /machine:I386 /out:"C:\srb2demo2\srb2sdldebug.exe" /pdbtype:sept -# SUBTRACT LINK32 /pdb:none - -!ENDIF - -# Begin Target - -# Name "Srb2SDL - Win32 Release" -# Name "Srb2SDL - Win32 Debug" -# Begin Group "SDLapp" - -# PROP Default_Filter "" -# Begin Group "filter" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=.\filter\filters.c -# End Source File -# Begin Source File - -SOURCE=.\filter\filters.h -# End Source File -# Begin Source File - -SOURCE=.\filter\hq2x.c -# End Source File -# Begin Source File - -SOURCE=.\filter\hq2x.h -# End Source File -# Begin Source File - -SOURCE=.\filter\interp.h -# End Source File -# Begin Source File - -SOURCE=.\filter\lq2x.c -# End Source File -# Begin Source File - -SOURCE=.\filter\lq2x.h -# End Source File -# End Group -# Begin Source File - -SOURCE=.\dosstr.c -# End Source File -# Begin Source File - -SOURCE=.\endtxt.c -# End Source File -# Begin Source File - -SOURCE=.\endtxt.h -# End Source File -# Begin Source File - -SOURCE=..\filesrch.c -# End Source File -# Begin Source File - -SOURCE=..\filesrch.h -# End Source File -# Begin Source File - -SOURCE=.\hwsym_sdl.c -# End Source File -# Begin Source File - -SOURCE=.\hwsym_sdl.h -# End Source File -# Begin Source File - -SOURCE=.\i_cdmus.c -# End Source File -# Begin Source File - -SOURCE=.\i_main.c -# End Source File -# Begin Source File - -SOURCE=.\i_net.c -# End Source File -# Begin Source File - -SOURCE=.\i_sound.c -# End Source File -# Begin Source File - -SOURCE=.\i_system.c -# End Source File -# Begin Source File - -SOURCE=.\i_video.c -# End Source File -# Begin Source File - -SOURCE=.\IMG_xpm.c -# PROP Exclude_From_Build 1 -# End Source File -# Begin Source File - -SOURCE=.\ogl_sdl.c -# End Source File -# Begin Source File - -SOURCE=.\ogl_sdl.h -# End Source File -# Begin Source File - -SOURCE=..\hardware\r_opengl\r_opengl.c -# End Source File -# Begin Source File - -SOURCE=..\hardware\r_opengl\r_opengl.h -# End Source File -# Begin Source File - -SOURCE=.\SDL_icon.xpm -# End Source File -# Begin Source File - -SOURCE=.\SDL_main\SDL_win32_main.c - -!IF "$(CFG)" == "Srb2SDL - Win32 Release" - -!ELSEIF "$(CFG)" == "Srb2SDL - Win32 Debug" - -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\sdlmain.h -# End Source File -# Begin Source File - -SOURCE=..\win32\Srb2win.rc -# End Source File -# Begin Source File - -SOURCE=..\win32\win_dbg.c -# End Source File -# Begin Source File - -SOURCE=..\win32\win_dbg.h -# End Source File -# Begin Source File - -SOURCE=..\win32\win_main.h -# End Source File -# End Group -# Begin Group "A_Asm" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\p5prof.h -# End Source File -# Begin Source File - -SOURCE=..\tmap.nas - -!IF "$(CFG)" == "Srb2SDL - Win32 Release" - -# PROP Ignore_Default_Tool 1 -# Begin Custom Build - Compiling $(InputName).nas with NASM... -IntDir=.\..\..\objs\VC\Release\SDL -InputPath=..\tmap.nas -InputName=tmap - -"$(IntDir)/$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - nasm -g -o $(IntDir)/$(InputName).obj -f win32 $(InputPath) - -# End Custom Build - -!ELSEIF "$(CFG)" == "Srb2SDL - Win32 Debug" - -# PROP Ignore_Default_Tool 1 -# Begin Custom Build - Compiling $(InputName).nas with NASM... -IntDir=.\..\..\objs\VC\Debug\SDL -InputPath=..\tmap.nas -InputName=tmap - -"$(IntDir)/$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - nasm -g -o $(IntDir)/$(InputName).obj -f win32 $(InputPath) - -# End Custom Build - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\tmap_mmx.nas - -!IF "$(CFG)" == "Srb2SDL - Win32 Release" - -# PROP Ignore_Default_Tool 1 -# Begin Custom Build - Compiling $(InputName).nas with NASM... -IntDir=.\..\..\objs\VC\Release\SDL -InputPath=..\tmap_mmx.nas -InputName=tmap_mmx - -"$(IntDir)/$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - nasm -g -o $(IntDir)/$(InputName).obj -f win32 $(InputPath) - -# End Custom Build - -!ELSEIF "$(CFG)" == "Srb2SDL - Win32 Debug" - -# PROP Ignore_Default_Tool 1 -# Begin Custom Build - Compiling $(InputName).nas with NASM... - -IntDir=.\..\..\objs\VC\Debug\SDL -InputPath=..\tmap_mmx.nas -InputName=tmap_mmx - -"$(IntDir)/$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - nasm -g -o $(IntDir)/$(InputName).obj -f win32 $(InputPath) - -# End Custom Build - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\tmap_vc.nas - -!IF "$(CFG)" == "Srb2SDL - Win32 Release" - -# Begin Custom Build - Compiling $(InputName).nas with NASM... -IntDir=.\..\..\objs\VC\Release\SDL -InputPath=..\tmap_vc.nas -InputName=tmap_vc - -"$(IntDir)/$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - nasm -g -o $(IntDir)/$(InputName).obj -f win32 $(InputPath) - -# End Custom Build - -!ELSEIF "$(CFG)" == "Srb2SDL - Win32 Debug" - -# Begin Custom Build - Compiling $(InputName).nas with NASM... -IntDir=.\..\..\objs\VC\Debug\SDL -InputPath=..\tmap_vc.nas -InputName=tmap_vc - -"$(IntDir)/$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - nasm -g -o $(IntDir)/$(InputName).obj -f win32 $(InputPath) - -# End Custom Build - -!ENDIF - -# End Source File -# End Group -# Begin Group "D_Doom" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\comptime.c -# End Source File -# Begin Source File - -SOURCE=..\d_clisrv.c -# End Source File -# Begin Source File - -SOURCE=..\d_clisrv.h -# End Source File -# Begin Source File - -SOURCE=..\d_event.h -# End Source File -# Begin Source File - -SOURCE=..\d_main.c -# End Source File -# Begin Source File - -SOURCE=..\d_main.h -# End Source File -# Begin Source File - -SOURCE=..\d_net.c -# End Source File -# Begin Source File - -SOURCE=..\d_net.h -# End Source File -# Begin Source File - -SOURCE=..\d_netcmd.c -# End Source File -# Begin Source File - -SOURCE=..\d_netcmd.h -# End Source File -# Begin Source File - -SOURCE=..\d_netfil.c -# End Source File -# Begin Source File - -SOURCE=..\d_netfil.h -# End Source File -# Begin Source File - -SOURCE=..\d_player.h -# End Source File -# Begin Source File - -SOURCE=..\d_think.h -# End Source File -# Begin Source File - -SOURCE=..\d_ticcmd.h -# End Source File -# Begin Source File - -SOURCE=..\dehacked.c -# End Source File -# Begin Source File - -SOURCE=..\dehacked.h -# End Source File -# Begin Source File - -SOURCE=..\doomdata.h -# End Source File -# Begin Source File - -SOURCE=..\doomdef.h -# End Source File -# Begin Source File - -SOURCE=..\doomstat.h -# End Source File -# Begin Source File - -SOURCE=..\doomtype.h -# End Source File -# Begin Source File - -SOURCE=..\z_zone.c -# End Source File -# Begin Source File - -SOURCE=..\z_zone.h -# End Source File -# End Group -# Begin Group "F_Frame" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\f_finale.c -# End Source File -# Begin Source File - -SOURCE=..\f_finale.h -# End Source File -# Begin Source File - -SOURCE=..\f_wipe.c -# End Source File -# End Group -# Begin Group "G_Game" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\g_game.c -# End Source File -# Begin Source File - -SOURCE=..\g_game.h -# End Source File -# Begin Source File - -SOURCE=..\g_input.c -# End Source File -# Begin Source File - -SOURCE=..\g_input.h -# End Source File -# Begin Source File - -SOURCE=..\g_state.h -# End Source File -# End Group -# Begin Group "H_Hud" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\am_map.c -# End Source File -# Begin Source File - -SOURCE=..\am_map.h -# End Source File -# Begin Source File - -SOURCE=..\command.c -# End Source File -# Begin Source File - -SOURCE=..\command.h -# End Source File -# Begin Source File - -SOURCE=..\console.c -# End Source File -# Begin Source File - -SOURCE=..\console.h -# End Source File -# Begin Source File - -SOURCE=..\hu_stuff.c -# End Source File -# Begin Source File - -SOURCE=..\hu_stuff.h -# End Source File -# Begin Source File - -SOURCE=..\st_stuff.c -# End Source File -# Begin Source File - -SOURCE=..\st_stuff.h -# End Source File -# Begin Source File - -SOURCE=..\y_inter.c -# End Source File -# Begin Source File - -SOURCE=..\y_inter.h -# End Source File -# End Group -# Begin Group "Hw_Hardware" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\hardware\hw3dsdrv.h -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw3sound.c -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw3sound.h -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw_bsp.c -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw_cache.c -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw_data.h -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw_defs.h -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw_dll.h -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw_draw.c -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw_drv.h -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw_glide.h -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw_glob.h -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw_light.c -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw_light.h -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw_main.c -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw_main.h -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw_md2.c -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw_md2.h -# End Source File -# Begin Source File - -SOURCE=..\hardware\hw_trick.c -# End Source File -# Begin Source File - -SOURCE=..\hardware\hws_data.h -# End Source File -# End Group -# Begin Group "I_Interface" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\byteptr.h -# End Source File -# Begin Source File - -SOURCE=..\i_joy.h -# End Source File -# Begin Source File - -SOURCE=..\i_net.h -# End Source File -# Begin Source File - -SOURCE=..\i_sound.h -# End Source File -# Begin Source File - -SOURCE=..\i_system.h -# End Source File -# Begin Source File - -SOURCE=..\i_tcp.c -# End Source File -# Begin Source File - -SOURCE=..\i_tcp.h -# End Source File -# Begin Source File - -SOURCE=..\i_video.h -# End Source File -# Begin Source File - -SOURCE=..\keys.h -# End Source File -# Begin Source File - -SOURCE=..\mserv.c -# End Source File -# Begin Source File - -SOURCE=..\mserv.h -# End Source File -# End Group -# Begin Group "M_Misc" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\m_argv.c -# End Source File -# Begin Source File - -SOURCE=..\m_argv.h -# End Source File -# Begin Source File - -SOURCE=..\m_bbox.c -# End Source File -# Begin Source File - -SOURCE=..\m_bbox.h -# End Source File -# Begin Source File - -SOURCE=..\m_cheat.c -# End Source File -# Begin Source File - -SOURCE=..\m_cheat.h -# End Source File -# Begin Source File - -SOURCE=..\m_dllist.h -# End Source File -# Begin Source File - -SOURCE=..\m_fixed.c -# End Source File -# Begin Source File - -SOURCE=..\m_fixed.h -# End Source File -# Begin Source File - -SOURCE=..\m_menu.c -# End Source File -# Begin Source File - -SOURCE=..\m_menu.h -# End Source File -# Begin Source File - -SOURCE=..\m_misc.c -# End Source File -# Begin Source File - -SOURCE=..\m_misc.h -# End Source File -# Begin Source File - -SOURCE=..\m_queue.c -# End Source File -# Begin Source File - -SOURCE=..\m_queue.h -# End Source File -# Begin Source File - -SOURCE=..\m_random.c -# End Source File -# Begin Source File - -SOURCE=..\m_random.h -# End Source File -# Begin Source File - -SOURCE=..\m_swap.h -# End Source File -# Begin Source File - -SOURCE=..\string.c -# End Source File -# End Group -# Begin Group "P_Play" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\info.c -# End Source File -# Begin Source File - -SOURCE=..\info.h -# End Source File -# Begin Source File - -SOURCE=..\p_ceilng.c -# End Source File -# Begin Source File - -SOURCE=..\p_enemy.c -# End Source File -# Begin Source File - -SOURCE=..\p_fab.c -# End Source File -# Begin Source File - -SOURCE=..\p_floor.c -# End Source File -# Begin Source File - -SOURCE=..\p_inter.c -# End Source File -# Begin Source File - -SOURCE=..\p_lights.c -# End Source File -# Begin Source File - -SOURCE=..\p_local.h -# End Source File -# Begin Source File - -SOURCE=..\p_map.c -# End Source File -# Begin Source File - -SOURCE=..\p_maputl.c -# End Source File -# Begin Source File - -SOURCE=..\p_maputl.h -# End Source File -# Begin Source File - -SOURCE=..\p_mobj.c -# End Source File -# Begin Source File - -SOURCE=..\p_mobj.h -# End Source File -# Begin Source File - -SOURCE=..\p_polyobj.c -# End Source File -# Begin Source File - -SOURCE=..\p_polyobj.h -# End Source File -# Begin Source File - -SOURCE=..\p_pspr.h -# End Source File -# Begin Source File - -SOURCE=..\p_saveg.c -# End Source File -# Begin Source File - -SOURCE=..\p_saveg.h -# End Source File -# Begin Source File - -SOURCE=..\p_setup.c -# End Source File -# Begin Source File - -SOURCE=..\p_setup.h -# End Source File -# Begin Source File - -SOURCE=..\p_sight.c -# End Source File -# Begin Source File - -SOURCE=..\p_spec.c -# End Source File -# Begin Source File - -SOURCE=..\p_spec.h -# End Source File -# Begin Source File - -SOURCE=..\p_telept.c -# End Source File -# Begin Source File - -SOURCE=..\p_tick.c -# End Source File -# Begin Source File - -SOURCE=..\p_tick.h -# End Source File -# Begin Source File - -SOURCE=..\p_user.c -# End Source File -# Begin Source File - -SOURCE=..\tables.c -# End Source File -# Begin Source File - -SOURCE=..\tables.h -# End Source File -# End Group -# Begin Group "R_Rend" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\r_bsp.c -# End Source File -# Begin Source File - -SOURCE=..\r_bsp.h -# End Source File -# Begin Source File - -SOURCE=..\r_data.c -# End Source File -# Begin Source File - -SOURCE=..\r_data.h -# End Source File -# Begin Source File - -SOURCE=..\r_defs.h -# End Source File -# Begin Source File - -SOURCE=..\r_draw.c -# End Source File -# Begin Source File - -SOURCE=..\r_draw.h -# End Source File -# Begin Source File - -SOURCE=..\r_draw16.c -# PROP Exclude_From_Build 1 -# End Source File -# Begin Source File - -SOURCE=..\r_draw8.c -# PROP Exclude_From_Build 1 -# End Source File -# Begin Source File - -SOURCE=..\r_local.h -# End Source File -# Begin Source File - -SOURCE=..\r_main.c -# End Source File -# Begin Source File - -SOURCE=..\r_main.h -# End Source File -# Begin Source File - -SOURCE=..\r_plane.c -# End Source File -# Begin Source File - -SOURCE=..\r_plane.h -# End Source File -# Begin Source File - -SOURCE=..\r_segs.c -# End Source File -# Begin Source File - -SOURCE=..\r_segs.h -# End Source File -# Begin Source File - -SOURCE=..\r_sky.c -# End Source File -# Begin Source File - -SOURCE=..\r_sky.h -# End Source File -# Begin Source File - -SOURCE=..\r_splats.c -# End Source File -# Begin Source File - -SOURCE=..\r_splats.h -# End Source File -# Begin Source File - -SOURCE=..\r_state.h -# End Source File -# Begin Source File - -SOURCE=..\r_things.c -# End Source File -# Begin Source File - -SOURCE=..\r_things.h -# End Source File -# Begin Source File - -SOURCE=..\screen.c -# End Source File -# Begin Source File - -SOURCE=..\screen.h -# End Source File -# Begin Source File - -SOURCE=..\v_video.c -# End Source File -# Begin Source File - -SOURCE=..\v_video.h -# End Source File -# End Group -# Begin Group "S_Sounds" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\s_sound.c -# End Source File -# Begin Source File - -SOURCE=..\s_sound.h -# End Source File -# Begin Source File - -SOURCE=..\sounds.c -# End Source File -# Begin Source File - -SOURCE=..\sounds.h -# End Source File -# End Group -# Begin Group "W_Wad" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\lzf.c -# End Source File -# Begin Source File - -SOURCE=..\lzf.h -# End Source File -# Begin Source File - -SOURCE=..\md5.c -# End Source File -# Begin Source File - -SOURCE=..\md5.h -# End Source File -# Begin Source File - -SOURCE=..\w_wad.c -# End Source File -# Begin Source File - -SOURCE=..\w_wad.h -# End Source File -# End Group -# Begin Group "Docs" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\doc\copying -# End Source File -# Begin Source File - -SOURCE=..\..\doc\faq.txt -# End Source File -# Begin Source File - -SOURCE=..\..\readme.txt -# End Source File -# Begin Source File - -SOURCE=..\..\doc\source.txt -# End Source File -# End Group -# Begin Source File - -SOURCE=..\win32\Srb2win.ico -# End Source File -# End Target -# End Project diff --git a/src/sdl12/Srb2SDL.dsw b/src/sdl12/Srb2SDL.dsw deleted file mode 100644 index 4f8f7bdce3b9de5b568c5371e4dd07d0d71f7131..0000000000000000000000000000000000000000 --- a/src/sdl12/Srb2SDL.dsw +++ /dev/null @@ -1,74 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "Srb2SDL"=.\Srb2SDL.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libpng - End Project Dependency - Begin Project Dependency - Project_Dep_Name zlib - End Project Dependency -}}} - -############################################################################### - -Project: "libpng"="..\..\libs\libpng-src\projects\visualc6\libpng.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name zlib - End Project Dependency -}}} - -############################################################################### - -Project: "s_openal"=..\hardware\s_openal\s_openal.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "zlib"=..\..\libs\zlib\projects\visualc6\zlib.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/src/sdl12/Srb2SDL.ico b/src/sdl12/Srb2SDL.ico deleted file mode 100644 index 700276fd4b9ac2810a6981eb054921f3708c702b..0000000000000000000000000000000000000000 Binary files a/src/sdl12/Srb2SDL.ico and /dev/null differ diff --git a/src/sdl12/dosstr.c b/src/sdl12/dosstr.c deleted file mode 100644 index f9bbee9b4cf39e9ba7392e0a63e37c027d6d6f5e..0000000000000000000000000000000000000000 --- a/src/sdl12/dosstr.c +++ /dev/null @@ -1,38 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// This file is in the public domain. -// (Re)written by Graue in 2006. -// -//----------------------------------------------------------------------------- -/// \file -/// \brief String uppercasing/lowercasing functions for non-DOS non-Win32 -/// systems - -#include "../doomtype.h" - -#ifndef HAVE_DOSSTR_FUNCS - -#include <ctype.h> - -int strupr(char *n) -{ - while (*n != '\0') - { - *n = toupper(*n); - n++; - } - return 1; -} - -int strlwr(char *n) -{ - while (*n != '\0') - { - *n = tolower(*n); - n++; - } - return 1; -} - -#endif diff --git a/src/sdl12/endtxt.c b/src/sdl12/endtxt.c deleted file mode 100644 index 1d7756b4de067a25e044adf1a47e3c8955510212..0000000000000000000000000000000000000000 --- a/src/sdl12/endtxt.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Function to write the SRB2 end message text - * - * Copyright (C) 1998 by Udo Munk <udo@umserver.umnet.de> - * - * This code is provided AS IS and there are no guarantees, none. - * Feel free to share and modify. - */ -//----------------------------------------------------------------------------- -/// \file -/// \brief Support to show ENDOOM text -/// -/// Loads the lump ENDOOM, set up the console to print -/// out the colors and text - -#include <stdio.h> -#include <stdlib.h> - -// need this 19990118 by Kin -#include "../doomdef.h" -#include "../w_wad.h" -#include "../z_zone.h" -#include "endtxt.h" -/** \brief The ShowEndTxt function - - - Prints out the ENDOOM the way DOOM.EXE/DOOM2.EXE did for Win32 or Linux/GNU - - \return void - - -*/ - -void ShowEndTxt(void) -{ -#if !(defined (_WIN32_WCE) || defined (_XBOX) || defined (_arch_dreamcast)) - INT32 i; - UINT16 j, att = 0; - INT32 nlflag = 1; -#ifdef _WIN32 - HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD mode, bytesWritten; - CONSOLE_SCREEN_BUFFER_INFO backupcon; - COORD resizewin = {80,-1}; - CHAR let = 0; -#endif - UINT16 *ptext; - void *data; - lumpnum_t endoomnum = W_GetNumForName("ENDOOM"); - //char *col; - - /* if the xterm has more then 80 columns we need to add nl's */ - /* doesn't work, COLUMNS is not in the environment at this time ??? - col = I_getenv("COLUMNS"); - if (col) { - if (atoi(col) > 80) - nlflag++; - } - */ - - /* get the lump with the text */ - data = ptext = W_CacheLumpNum(endoomnum, PU_CACHE); - -#ifdef _WIN32 - if (co == INVALID_HANDLE_VALUE || GetFileType(co) != FILE_TYPE_CHAR || !GetConsoleMode(co, &mode)) // test if it a good handle - { - Z_Free(data); - return; - } - - backupcon.wAttributes = FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE; // Just in case - GetConsoleScreenBufferInfo(co, &backupcon); //Store old state - resizewin.Y = backupcon.dwSize.Y; - if (backupcon.dwSize.X < resizewin.X) - SetConsoleScreenBufferSize(co, resizewin); - - for (i=1; i<=80*25; i++) // print 80x25 text and deal with the attributes too - { - j = (UINT16)(*ptext >> 8); // attribute first - let = (char)(*ptext & 0xff); // text second - if (j != att) // attribute changed? - { - att = j; // save current attribute - SetConsoleTextAttribute(co, j); //set fg and bg color for buffer - } - - WriteConsoleA(co, &let, 1, &bytesWritten, NULL); // now the text - - if (nlflag && !(i % 80) && backupcon.dwSize.X > resizewin.X) // do we need a nl? - { - att = backupcon.wAttributes; - SetConsoleTextAttribute(co, att); // all attributes off - WriteConsoleA(co, "\n", 1, &bytesWritten, NULL); // newline to console - } - ptext++; - } - SetConsoleTextAttribute(co, backupcon.wAttributes); // all attributes off -#else - /* print 80x25 text and deal with the attributes too */ - for (i=1; i<=80*25; i++) { - /* attribute first */ - /* attribute changed? */ - if ((j = *ptext >> 8) != att) { - /* save current attribute */ - att = j; - /* set new attribute, forground color first */ - printf("\033["); - switch (j & 0x0f) { - case 0: /* black */ - printf("30"); - break; - case 1: /* blue */ - printf("34"); - break; - case 2: /* green */ - printf("32"); - break; - case 3: /* cyan */ - printf("36"); - break; - case 4: /* red */ - printf("31"); - break; - case 5: /* magenta */ - printf("35"); - break; - case 6: /* brown */ - printf("33"); - break; - case 7: /* bright grey */ - printf("37"); - break; - case 8: /* dark grey */ - printf("1;30"); - break; - case 9: /* bright blue */ - printf("1;34"); - break; - case 10: /* bright green */ - printf("1;32"); - break; - case 11: /* bright cyan */ - printf("1;36"); - break; - case 12: /* bright red */ - printf("1;31"); - break; - case 13: /* bright magenta */ - printf("1;35"); - break; - case 14: /* yellow */ - printf("1;33"); - break; - case 15: /* white */ - printf("1;37"); - break; - } - printf("m"); - /* now background color */ - printf("\033["); - switch ((j >> 4) & 0x0f) { - case 0: /* black */ - printf("40"); - break; - case 1: /* blue */ - printf("44"); - break; - case 2: /* green */ - printf("42"); - break; - case 3: /* cyan */ - printf("46"); - break; - case 4: /* red */ - printf("41"); - break; - case 5: /* magenta */ - printf("45"); - break; - case 6: /* brown */ - printf("43"); - break; - case 7: /* bright grey */ - printf("47"); - break; - case 8: /* dark grey */ - printf("1;40"); - break; - case 9: /* bright blue */ - printf("1;44"); - break; - case 10: /* bright green */ - printf("1;42"); - break; - case 11: /* bright cyan */ - printf("1;46"); - break; - case 12: /* bright red */ - printf("1;41"); - break; - case 13: /* bright magenta */ - printf("1;45"); - break; - case 14: /* yellow */ - printf("1;43"); - break; - case 15: /* white */ - printf("1;47"); - break; - } - printf("m"); - } - - /* now the text */ - printf("%c",*ptext++ & 0xff); - - /* do we need a nl? */ - if (nlflag) - { - if (!(i % 80)) - { - printf("\033[0m"); - att = 0; - printf("\n"); - } - } - } - /* all attributes off */ - printf("\033[0m"); -#endif - if (nlflag) - printf("\n"); - - Z_Free(data); -#endif -} diff --git a/src/sdl12/endtxt.h b/src/sdl12/endtxt.h deleted file mode 100644 index 41f8e51adc2c1f12af6df13ba7f949176d63e4c0..0000000000000000000000000000000000000000 --- a/src/sdl12/endtxt.h +++ /dev/null @@ -1,24 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief Support to show ENDOOM text - -#ifndef __ENDTXT__ -#define __ENDTXT__ - -void ShowEndTxt (void); - -#endif diff --git a/src/sdl12/filter/filters.c b/src/sdl12/filter/filters.c deleted file mode 100644 index 1b2346e8e8554a9c7b094caf6531b3e3f950a12b..0000000000000000000000000000000000000000 --- a/src/sdl12/filter/filters.c +++ /dev/null @@ -1,1000 +0,0 @@ -#include <math.h> -#include "filters.h" - -//Alam_GBC: C file based on sms_sdl's filter.c - -/* 2X SAI Filter */ -static Uint32 colorMask = 0xF7DEF7DE; -static Uint32 lowPixelMask = 0x08210821; -static Uint32 qcolorMask = 0xE79CE79C; -static Uint32 qlowpixelMask = 0x18631863; -static Uint32 redblueMask = 0xF81F; -static Uint32 greenMask = 0x7E0; - -SDL_Surface *filter_2x(SDL_Surface *src, SDL_Rect *srcclp, filter_2 filter) -{ - return filter_2xe(src,srcclp,filter,0,0,0); -} - -SDL_Surface *filter_2xe(SDL_Surface *src, SDL_Rect *srcclp, filter_2 filter,Uint8 R, Uint8 G, Uint8 B) -{ - SDL_Surface *srcfilter = NULL; - SDL_Rect dstclp = {0,3,0,0}; - SDL_Surface *dstfilter = NULL; - Uint32 Fillcolor = 0; - if(!src || !filter) return NULL; // Need src and filter - if(srcclp) // size by clp - { - dstclp.w = srcclp->w; //clp's width - dstclp.h = srcclp->h; //clp's height - } - else // size by src - { - dstclp.w = (Uint16)src->w; //src's width - dstclp.h = (Uint16)src->h; //src's height - } - if(filter == hq2x32 || filter == lq2x32) // src 0888 surface - srcfilter = SDL_CreateRGBSurface(SDL_SWSURFACE,dstclp.w,dstclp.h+6,32,0x00FF0000,0x0000FF00,0x000000FF,0x00); - else // src 565 surface - srcfilter = SDL_CreateRGBSurface(SDL_SWSURFACE,dstclp.w,dstclp.h+6,16,0x0000F800,0x000007E0,0x0000001F,0x00); - if(!srcfilter) return NULL; //No Memory? - Fillcolor = SDL_MapRGB(srcfilter->format,R,G,B); //Choose color - SDL_FillRect(srcfilter,NULL,Fillcolor); //fill it - if(filter == filter_hq2x || filter == hq2x32 || filter == lq2x32) // dst 0888 surface - dstfilter = SDL_CreateRGBSurface(SDL_SWSURFACE,dstclp.w*2,dstclp.h*2,32,0x00FF0000,0x0000FF00,0x000000FF,0x00); - else // dst 565 surface - dstfilter = SDL_CreateRGBSurface(SDL_SWSURFACE,dstclp.w*2,dstclp.h*2,16,0x0000F800,0x000007E0,0x0000001F,0x00); - if(!dstfilter || SDL_BlitSurface(src,srcclp,srcfilter,&dstclp) == -1) // No dstfilter or Blit failed - { - SDL_FreeSurface(srcfilter); // Free memory - return NULL; //No Memory? - } - else // have dstfilter ready and srcfilter done - { - SDL_FillRect(dstfilter,NULL,Fillcolor); //fill it too - filter(FILTER(srcfilter,dstfilter)); //filtering - SDL_FreeSurface(srcfilter); //almost - } - return dstfilter; //done -} - - -int filter_init_2xsai(SDL_PixelFormat *BitFormat) -{ - if (!BitFormat || BitFormat->BytesPerPixel != 2 ||BitFormat->Amask != 0x0) - { - return 0; - } - else if (BitFormat->Rmask == 0xF800 && BitFormat->Gmask == 0x7E0 - && BitFormat->Bmask == 0x1F && BitFormat->BitsPerPixel == 16) //565 - { - colorMask = 0xF7DEF7DE; - lowPixelMask = 0x08210821; - qcolorMask = 0xE79CE79C; - qlowpixelMask = 0x18631863; - redblueMask = 0xF81F; - greenMask = 0x7E0; - } - else if (BitFormat->Rmask == 0x7C00 && BitFormat->Gmask == 0x3E0 - && BitFormat->Bmask == 0x1F && BitFormat->BitsPerPixel == 15) //555 - { - colorMask = 0x7BDE7BDE; - lowPixelMask = 0x04210421; - qcolorMask = 0x739C739C; - qlowpixelMask = 0x0C630C63; - redblueMask = 0x7C1F; - greenMask = 0x3E0; - } - else - { - return 0; - } -#ifdef MMX - if(BitFormat->Gmask == 0x7E0) Init_2xSaIMMX(565); - else Init_2xSaIMMX(555); -#endif - return 1; -} - - -FUNCINLINE static ATTRINLINE int GetResult1 (Uint32 A, Uint32 B, Uint32 C, Uint32 D, Uint32 E) -{ - int x = 0; - int y = 0; - int r = 0; - (void)E; - - if (A == C) - x += 1; - else if (B == C) - y += 1; - if (A == D) - x += 1; - else if (B == D) - y += 1; - if (x <= 1) - r += 1; - if (y <= 1) - r -= 1; - return r; -} - -FUNCINLINE static ATTRINLINE int GetResult2 (Uint32 A, Uint32 B, Uint32 C, Uint32 D, Uint32 E) -{ - int x = 0; - int y = 0; - int r = 0; - (void)E; - - if (A == C) - x += 1; - else if (B == C) - y += 1; - if (A == D) - x += 1; - else if (B == D) - y += 1; - if (x <= 1) - r -= 1; - if (y <= 1) - r += 1; - return r; -} - -FUNCINLINE static ATTRINLINE int GetResult (Uint32 A, Uint32 B, Uint32 C, Uint32 D) -{ - int x = 0; - int y = 0; - int r = 0; - - if (A == C) - x += 1; - else if (B == C) - y += 1; - if (A == D) - x += 1; - else if (B == D) - y += 1; - if (x <= 1) - r += 1; - if (y <= 1) - r -= 1; - return r; -} - -FUNCINLINE static ATTRINLINE Uint32 INTERPOLATE (Uint32 A, Uint32 B) -{ - if (A != B) - { - return (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + - (A & B & lowPixelMask)); - } - else - return A; -} - -FUNCINLINE static ATTRINLINE Uint32 Q_INTERPOLATE (Uint32 A, Uint32 B, Uint32 C, Uint32 D) -{ - register Uint32 x = ((A & qcolorMask) >> 2) + - ((B & qcolorMask) >> 2) + - ((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2); - register Uint32 y = (A & qlowpixelMask) + - (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask); - y = (y >> 2) & qlowpixelMask; - return x + y; -} - -#define BLUE_MASK565 0x001F001F -#define RED_MASK565 0xF800F800 -#define GREEN_MASK565 0x07E007E0 - -#define BLUE_MASK555 0x001F001F -#define RED_MASK555 0x7C007C00 -#define GREEN_MASK555 0x03E003E0 - -void filter_super2xsai(Uint8 *srcPtr, Uint32 srcPitch, - Uint8 *dstPtr, Uint32 dstPitch, - int width, int height) -{ - Uint16 *bP; - Uint8 *dP; - Uint32 inc_bP; - Uint32 Nextline = srcPitch >> 1; - - Uint32 finish; - inc_bP = 1; - - for (; height; height--) - { - bP = (Uint16 *) srcPtr; - dP = (Uint8 *) dstPtr; - - for (finish = width; finish; finish -= inc_bP) - { - Uint32 color4, color5, color6; - Uint32 color1, color2, color3; - Uint32 colorA0, colorA1, colorA2, colorA3, - colorB0, colorB1, colorB2, colorB3, colorS1, colorS2; - Uint32 product1a, product1b, product2a, product2b; - -//--------------------------------------- B1 B2 -// 4 5 6 S2 -// 1 2 3 S1 -// A1 A2 - - colorB0 = *(bP - Nextline - 1); - colorB1 = *(bP - Nextline); - colorB2 = *(bP - Nextline + 1); - colorB3 = *(bP - Nextline + 2); - - color4 = *(bP - 1); - color5 = *(bP); - color6 = *(bP + 1); - colorS2 = *(bP + 2); - - color1 = *(bP + Nextline - 1); - color2 = *(bP + Nextline); - color3 = *(bP + Nextline + 1); - colorS1 = *(bP + Nextline + 2); - - colorA0 = *(bP + Nextline + Nextline - 1); - colorA1 = *(bP + Nextline + Nextline); - colorA2 = *(bP + Nextline + Nextline + 1); - colorA3 = *(bP + Nextline + Nextline + 2); - -//-------------------------------------- - if (color2 == color6 && color5 != color3) - { - product2b = product1b = color2; - } - else if (color5 == color3 && color2 != color6) - { - product2b = product1b = color5; - } - else if (color5 == color3 && color2 == color6) - { - register int r = 0; - - r += GetResult (color6, color5, color1, colorA1); - r += GetResult (color6, color5, color4, colorB1); - r += GetResult (color6, color5, colorA2, colorS1); - r += GetResult (color6, color5, colorB2, colorS2); - - if (r > 0) - product2b = product1b = color6; - else if (r < 0) - product2b = product1b = color5; - else - { - product2b = product1b = INTERPOLATE (color5, color6); - } - } - else - { - if (color6 == color3 && color3 == colorA1 - && color2 != colorA2 && color3 != colorA0) - product2b = - Q_INTERPOLATE (color3, color3, color3, color2); - else if (color5 == color2 && color2 == colorA2 - && colorA1 != color3 && color2 != colorA3) - product2b = - Q_INTERPOLATE (color2, color2, color2, color3); - else - product2b = INTERPOLATE (color2, color3); - - if (color6 == color3 && color6 == colorB1 - && color5 != colorB2 && color6 != colorB0) - product1b = - Q_INTERPOLATE (color6, color6, color6, color5); - else if (color5 == color2 && color5 == colorB2 - && colorB1 != color6 && color5 != colorB3) - product1b = - Q_INTERPOLATE (color6, color5, color5, color5); - else - product1b = INTERPOLATE (color5, color6); - } - - if (color5 == color3 && color2 != color6 && color4 == color5 - && color5 != colorA2) - product2a = INTERPOLATE (color2, color5); - else - if (color5 == color1 && color6 == color5 - && color4 != color2 && color5 != colorA0) - product2a = INTERPOLATE (color2, color5); - else - product2a = color2; - - if (color2 == color6 && color5 != color3 && color1 == color2 - && color2 != colorB2) - product1a = INTERPOLATE (color2, color5); - else - if (color4 == color2 && color3 == color2 - && color1 != color5 && color2 != colorB0) - product1a = INTERPOLATE (color2, color5); - else - product1a = color5; - -#ifdef LSB_FIRST - product1a = product1a | (product1b << 16); - product2a = product2a | (product2b << 16); -#else - product1a = (product1a << 16) | product1b; - product2a = (product2a << 16) | product2b; -#endif - *((Uint32 *) dP) = product1a; - *((Uint32 *) (dP + dstPitch)) = product2a; - - bP += inc_bP; - dP += sizeof (Uint32); - } // end of for ( finish= width etc..) - - srcPtr += srcPitch; - dstPtr += dstPitch * 2; - } // endof: for (; height; height--) -} - -void filter_supereagle(Uint8 *srcPtr, Uint32 srcPitch, /* Uint8 *deltaPtr, */ - Uint8 *dstPtr, Uint32 dstPitch, int width, int height) -{ - Uint8 *dP; - Uint16 *bP; - Uint32 inc_bP; - - - - Uint32 finish; - Uint32 Nextline = srcPitch >> 1; - - inc_bP = 1; - - for (; height ; height--) - { - bP = (Uint16 *) srcPtr; - dP = dstPtr; - for (finish = width; finish; finish -= inc_bP) - { - Uint32 color4, color5, color6; - Uint32 color1, color2, color3; - Uint32 colorA1, colorA2, colorB1, colorB2, colorS1, colorS2; - Uint32 product1a, product1b, product2a, product2b; - colorB1 = *(bP - Nextline); - colorB2 = *(bP - Nextline + 1); - - color4 = *(bP - 1); - color5 = *(bP); - color6 = *(bP + 1); - colorS2 = *(bP + 2); - - color1 = *(bP + Nextline - 1); - color2 = *(bP + Nextline); - color3 = *(bP + Nextline + 1); - colorS1 = *(bP + Nextline + 2); - - colorA1 = *(bP + Nextline + Nextline); - colorA2 = *(bP + Nextline + Nextline + 1); - // -------------------------------------- - if (color2 == color6 && color5 != color3) - { - product1b = product2a = color2; - if ((color1 == color2) || (color6 == colorB2)) - { - product1a = INTERPOLATE (color2, color5); - product1a = INTERPOLATE (color2, product1a); -// product1a = color2; - } - else - { - product1a = INTERPOLATE (color5, color6); - } - - if ((color6 == colorS2) || (color2 == colorA1)) - { - product2b = INTERPOLATE (color2, color3); - product2b = INTERPOLATE (color2, product2b); -// product2b = color2; - } - else - { - product2b = INTERPOLATE (color2, color3); - } - } - else if (color5 == color3 && color2 != color6) - { - product2b = product1a = color5; - - if ((colorB1 == color5) || (color3 == colorS1)) - { - product1b = INTERPOLATE (color5, color6); - product1b = INTERPOLATE (color5, product1b); -// product1b = color5; - } - else - { - product1b = INTERPOLATE (color5, color6); - } - - if ((color3 == colorA2) || (color4 == color5)) - { - product2a = INTERPOLATE (color5, color2); - product2a = INTERPOLATE (color5, product2a); -// product2a = color5; - } - else - { - product2a = INTERPOLATE (color2, color3); - } - - } - else if (color5 == color3 && color2 == color6) - { - register int r = 0; - - r += GetResult (color6, color5, color1, colorA1); - r += GetResult (color6, color5, color4, colorB1); - r += GetResult (color6, color5, colorA2, colorS1); - r += GetResult (color6, color5, colorB2, colorS2); - - if (r > 0) - { - product1b = product2a = color2; - product1a = product2b = INTERPOLATE (color5, color6); - } - else if (r < 0) - { - product2b = product1a = color5; - product1b = product2a = INTERPOLATE (color5, color6); - } - else - { - product2b = product1a = color5; - product1b = product2a = color2; - } - } - else - { - product2b = product1a = INTERPOLATE (color2, color6); - product2b = - Q_INTERPOLATE (color3, color3, color3, product2b); - product1a = - Q_INTERPOLATE (color5, color5, color5, product1a); - - product2a = product1b = INTERPOLATE (color5, color3); - product2a = - Q_INTERPOLATE (color2, color2, color2, product2a); - product1b = - Q_INTERPOLATE (color6, color6, color6, product1b); - -// product1a = color5; -// product1b = color6; -// product2a = color2; -// product2b = color3; - } -#ifdef LSB_FIRST - product1a = product1a | (product1b << 16); - product2a = product2a | (product2b << 16); -#else - product1a = (product1a << 16) | product1b; - product2a = (product2a << 16) | product2b; -#endif - - *((Uint32 *) dP) = product1a; - *((Uint32 *) (dP + dstPitch)) = product2a; - - bP += inc_bP; - dP += sizeof (Uint32); - } // end of for ( finish= width etc..) - srcPtr += srcPitch; - dstPtr += dstPitch * 2; - } // endof: for (height; height; height--) -} - -void filter_2xsai (Uint8 *srcPtr, Uint32 srcPitch, - Uint8 *dstPtr, Uint32 dstPitch, int width, int height) -{ - Uint8 *dP; - Uint16 *bP; - Uint32 inc_bP; - - - Uint32 finish; - Uint32 Nextline = srcPitch >> 1; - inc_bP = 1; - - - for (; height; height--) - { - bP = (Uint16 *) srcPtr; - dP = dstPtr; - - for (finish = width; finish; finish -= inc_bP) - { - - register Uint32 colorA, colorB; - Uint32 colorC, colorD, - colorE, colorF, colorG, colorH, - colorI, colorJ, colorK, colorL, - - colorM, colorN, colorO, colorP; - Uint32 product, product1, product2; - -//--------------------------------------- -// Map of the pixels: I|E F|J -// G|A B|K -// H|C D|L -// M|N O|P - colorI = *(bP - Nextline - 1); - colorE = *(bP - Nextline); - colorF = *(bP - Nextline + 1); - colorJ = *(bP - Nextline + 2); - - colorG = *(bP - 1); - colorA = *(bP); - colorB = *(bP + 1); - colorK = *(bP + 2); - - colorH = *(bP + Nextline - 1); - colorC = *(bP + Nextline); - colorD = *(bP + Nextline + 1); - colorL = *(bP + Nextline + 2); - - colorM = *(bP + Nextline + Nextline - 1); - colorN = *(bP + Nextline + Nextline); - colorO = *(bP + Nextline + Nextline + 1); - colorP = *(bP + Nextline + Nextline + 2); - - if ((colorA == colorD) && (colorB != colorC)) - { - if (((colorA == colorE) && (colorB == colorL)) || - ((colorA == colorC) && (colorA == colorF) - && (colorB != colorE) && (colorB == colorJ))) - { - product = colorA; - } - else - { - product = INTERPOLATE (colorA, colorB); - } - - if (((colorA == colorG) && (colorC == colorO)) || - ((colorA == colorB) && (colorA == colorH) - && (colorG != colorC) && (colorC == colorM))) - { - product1 = colorA; - } - else - { - product1 = INTERPOLATE (colorA, colorC); - } - product2 = colorA; - } - else if ((colorB == colorC) && (colorA != colorD)) - { - if (((colorB == colorF) && (colorA == colorH)) || - ((colorB == colorE) && (colorB == colorD) - && (colorA != colorF) && (colorA == colorI))) - { - product = colorB; - } - else - { - product = INTERPOLATE (colorA, colorB); - } - - if (((colorC == colorH) && (colorA == colorF)) || - ((colorC == colorG) && (colorC == colorD) - && (colorA != colorH) && (colorA == colorI))) - { - product1 = colorC; - } - else - { - product1 = INTERPOLATE (colorA, colorC); - } - product2 = colorB; - } - else if ((colorA == colorD) && (colorB == colorC)) - { - if (colorA == colorB) - { - product = colorA; - product1 = colorA; - product2 = colorA; - } - else - { - register int r = 0; - - product1 = INTERPOLATE (colorA, colorC); - product = INTERPOLATE (colorA, colorB); - - r += - GetResult1 (colorA, colorB, colorG, colorE, - colorI); - r += - GetResult2 (colorB, colorA, colorK, colorF, - colorJ); - r += - GetResult2 (colorB, colorA, colorH, colorN, - colorM); - r += - GetResult1 (colorA, colorB, colorL, colorO, - colorP); - - if (r > 0) - product2 = colorA; - else if (r < 0) - product2 = colorB; - else - { - product2 = - Q_INTERPOLATE (colorA, colorB, colorC, - colorD); - } - } - } - else - { - product2 = Q_INTERPOLATE (colorA, colorB, colorC, colorD); - - if ((colorA == colorC) && (colorA == colorF) - && (colorB != colorE) && (colorB == colorJ)) - { - product = colorA; - } - else - if ((colorB == colorE) && (colorB == colorD) - && (colorA != colorF) && (colorA == colorI)) - { - product = colorB; - } - else - { - product = INTERPOLATE (colorA, colorB); - } - - if ((colorA == colorB) && (colorA == colorH) - && (colorG != colorC) && (colorC == colorM)) - { - product1 = colorA; - } - else - if ((colorC == colorG) && (colorC == colorD) - && (colorA != colorH) && (colorA == colorI)) - { - product1 = colorC; - } - else - { - product1 = INTERPOLATE (colorA, colorC); - } - } -#ifdef LSB_FIRST - product = colorA | (product << 16); - product1 = product1 | (product2 << 16); -#else - product = (colorA << 16) | product; - product1 = (product1 << 16) | product2; -#endif - *((Uint32 *) dP) = product; - *((Uint32 *) (dP + dstPitch)) = product1; - - bP += inc_bP; - dP += sizeof (Uint32); - } // end of for ( finish= width etc..) - - srcPtr += srcPitch; - dstPtr += dstPitch * 2; - } // endof: for (height; height; height--) -} - -#if 0 -static inline Uint32 Bilinear(Uint32 A, Uint32 B, Uint32 x) -{ - unsigned long areaA, areaB; - unsigned long result; - - if (A == B) - return A; - - areaB = (x >> 11) & 0x1f; // reduce 16 bit fraction to 5 bits - areaA = 0x20 - areaB; - - A = (A & redblueMask) | ((A & greenMask) << 16); - B = (B & redblueMask) | ((B & greenMask) << 16); - - result = ((areaA * A) + (areaB * B)) >> 5; - - return (result & redblueMask) | ((result >> 16) & greenMask); - -} - -static inline Uint32 Bilinear4 (Uint32 A, Uint32 B, Uint32 C, Uint32 D, Uint32 x, - Uint32 y) -{ - unsigned long areaA, areaB, areaC, areaD; - unsigned long result, xy; - - x = (x >> 11) & 0x1f; - y = (y >> 11) & 0x1f; - xy = (x * y) >> 5; - - A = (A & redblueMask) | ((A & greenMask) << 16); - B = (B & redblueMask) | ((B & greenMask) << 16); - C = (C & redblueMask) | ((C & greenMask) << 16); - D = (D & redblueMask) | ((D & greenMask) << 16); - - areaA = 0x20 + xy - x - y; - areaB = x - xy; - areaC = y - xy; - areaD = xy; - - result = ((areaA * A) + (areaB * B) + (areaC * C) + (areaD * D)) >> 5; - - return (result & redblueMask) | ((result >> 16) & greenMask); -} -#endif - - -void filter_advmame2x(Uint8 *srcPtr, Uint32 srcPitch, - Uint8 *dstPtr, Uint32 dstPitch, - int width, int height) -{ - unsigned int nextlineSrc = srcPitch / sizeof(short); - short *p = (short *)srcPtr; - - unsigned int nextlineDst = dstPitch / sizeof(short); - short *q = (short *)dstPtr; - - while(height--) { - int i = 0, j = 0; - for(i = 0; i < width; ++i, j += 2) { - short B = *(p + i - nextlineSrc); - short D = *(p + i - 1); - short E = *(p + i); - short F = *(p + i + 1); - short H = *(p + i + nextlineSrc); - - *(q + j) = (short)(D == B && B != F && D != H ? D : E); - *(q + j + 1) = (short)(B == F && B != D && F != H ? F : E); - *(q + j + nextlineDst) = (short)(D == H && D != B && H != F ? D : E); - *(q + j + nextlineDst + 1) = (short)(H == F && D != H && B != F ? F : E); - } - p += nextlineSrc; - q += nextlineDst << 1; - } -} - - -void filter_tv2x(Uint8 *srcPtr, Uint32 srcPitch, - Uint8 *dstPtr, Uint32 dstPitch, - int width, int height) -{ - unsigned int nextlineSrc = srcPitch / sizeof(Uint16); - Uint16 *p = (Uint16 *)srcPtr; - - unsigned int nextlineDst = dstPitch / sizeof(Uint16); - Uint16 *q = (Uint16 *)dstPtr; - - while(height--) { - int i = 0, j = 0; - for(; i < width; ++i, j += 2) { - Uint16 p1 = *(p + i); - Uint32 pi; - - pi = (((p1 & redblueMask) * 7) >> 3) & redblueMask; - pi |= (((p1 & greenMask) * 7) >> 3) & greenMask; - - *(q + j) = (Uint16)p1; - *(q + j + 1) = (Uint16)p1; - *(q + j + nextlineDst) = (Uint16)pi; - *(q + j + nextlineDst + 1) = (Uint16)pi; - } - p += nextlineSrc; - q += nextlineDst << 1; - } -} - -void filter_normal2x(Uint8 *srcPtr, Uint32 srcPitch, - Uint8 *dstPtr, Uint32 dstPitch, - int width, int height) -{ - unsigned int nextlineSrc = srcPitch / sizeof(Uint16); - Uint16 *p = (Uint16 *)srcPtr; - - unsigned int nextlineDst = dstPitch / sizeof(Uint16); - Uint16 *q = (Uint16 *)dstPtr; - - while(height--) { - int i = 0, j = 0; - for(; i < width; ++i, j += 2) { - Uint16 color = *(p + i); - - *(q + j) = color; - *(q + j + 1) = color; - *(q + j + nextlineDst) = color; - *(q + j + nextlineDst + 1) = color; - } - p += nextlineSrc; - q += nextlineDst << 1; - } -} - -void filter_scan50(Uint8 *srcPtr, Uint32 srcPitch, - Uint8 *dstPtr, Uint32 dstPitch, - int width, int height) -{ - - unsigned int nextlineSrc = srcPitch / sizeof(Uint16); - Uint16 *p = (Uint16 *)srcPtr; - - unsigned int nextlineDst = dstPitch / sizeof(Uint16); - Uint16 *q = (Uint16 *)dstPtr; - - while(height--) { - int i = 0, j = 0; - for(; i < width; ++i, j += 2) { - Uint16 p1 = *(p + i); - Uint16 p2 = *(p + i + nextlineSrc); - // 0111 1011 1110 1111 == 0x7BEF - Uint16 pm = (Uint16)(((p1 + p2) >> 2) & 0x7BEF); - - *(q + j) = p1; - *(q + j + 1) = p1; - *(q + j + nextlineDst) = pm; - *(q + j + nextlineDst + 1) = pm; - - } - p += nextlineSrc; - q += nextlineDst << 1; - } -} - - -void filter_scan100(Uint8 *srcPtr, Uint32 srcPitch, - Uint8 *dstPtr, Uint32 dstPitch, - int width, int height) -{ - unsigned int nextlineSrc = srcPitch / sizeof(Uint16); - Uint16 *p = (Uint16 *)srcPtr; - - unsigned int nextlineDst = dstPitch / sizeof(Uint16); - Uint16 *q = (Uint16 *)dstPtr; - - while(height--) { - int i = 0, j = 0; - for(; i < width; ++i, j += 2) { - *(q + j) = *(q + j + 1) = *(p + i); - } - p += nextlineSrc; - q += nextlineDst << 1; - } -} - - -FUNCINLINE static ATTRINLINE Uint16 DOT_16(Uint16 c, int j, int i) { - static const Uint16 dotmatrix[16] = { - 0x01E0, 0x0007, 0x3800, 0x0000, - 0x39E7, 0x0000, 0x39E7, 0x0000, - 0x3800, 0x0000, 0x01E0, 0x0007, - 0x39E7, 0x0000, 0x39E7, 0x0000 - }; - return (Uint16)(c - ((c >> 2) & *(dotmatrix + ((j & 3) << 2) + (i & 3)))); -} - -void filter_dotmatrix(Uint8 *srcPtr, Uint32 srcPitch, - Uint8 *dstPtr, Uint32 dstPitch, - int width, int height) -{ - unsigned int nextlineSrc = srcPitch / sizeof(Uint16); - Uint16 *p = (Uint16 *)srcPtr; - - unsigned int nextlineDst = dstPitch / sizeof(Uint16); - Uint16 *q = (Uint16 *)dstPtr; - - int i, ii, j, jj; - for(j = 0, jj = 0; j < height; ++j, jj += 2) { - for(i = 0, ii = 0; i < width; ++i, ii += 2) { - Uint16 c = *(p + i); - *(q + ii) = DOT_16(c, jj, ii); - *(q + ii + 1) = DOT_16(c, jj, ii + 1); - *(q + ii + nextlineDst) = DOT_16(c, jj + 1, ii); - *(q + ii + nextlineDst + 1) = DOT_16(c, jj + 1, ii + 1); - } - p += nextlineSrc; - q += nextlineDst << 1; - } -} - - -void filter_bilinear(Uint8 *srcPtr, Uint32 srcPitch, - Uint8 *dstPtr, Uint32 dstPitch, - int width, int height) -{ - unsigned int nextlineSrc = srcPitch / sizeof(Uint16); - Uint16 *p = (Uint16 *)srcPtr; - unsigned int nextlineDst = dstPitch / sizeof(Uint16); - Uint16 *q = (Uint16 *)dstPtr; - - while(height--) { - int i, ii; - for(i = 0, ii = 0; i < width; ++i, ii += 2) { - Uint16 A = *(p + i); - Uint16 B = *(p + i + 1); - Uint16 C = *(p + i + nextlineSrc); - Uint16 D = *(p + i + nextlineSrc + 1); - *(q + ii) = A; - *(q + ii + 1) = (Uint16)INTERPOLATE(A, B); - *(q + ii + nextlineDst) = (Uint16)INTERPOLATE(A, C); - *(q + ii + nextlineDst + 1) = (Uint16)Q_INTERPOLATE(A, B, C, D); - } - p += nextlineSrc; - q += nextlineDst << 1; - } -} - - -// NEED_OPTIMIZE -static void MULT(Uint16 c, float* r, float* g, float* b, float alpha) { - *r += alpha * ((c & RED_MASK565 ) >> 11); - *g += alpha * ((c & GREEN_MASK565) >> 5); - *b += alpha * ((c & BLUE_MASK565 ) >> 0); -} - -static Uint16 MAKE_RGB565(float r, float g, float b) { - return (Uint16) - (((((Uint8)r) << 11) & RED_MASK565 ) | - ((((Uint8)g) << 5) & GREEN_MASK565) | - ((((Uint8)b) << 0) & BLUE_MASK565 )); -} - -FUNCINLINE static ATTRINLINE float CUBIC_WEIGHT(float x) { - // P(x) = { x, x>0 | 0, x<=0 } - // P(x + 2) ^ 3 - 4 * P(x + 1) ^ 3 + 6 * P(x) ^ 3 - 4 * P(x - 1) ^ 3 - double r = 0.; - if(x + 2 > 0) r += pow(x + 2, 3); - if(x + 1 > 0) r += -4 * pow(x + 1, 3); - if(x > 0) r += 6 * pow(x , 3); - if(x - 1 > 0) r += -4 * pow(x - 1, 3); - return (float)r / 6; -} - -void filter_bicubic(Uint8 *srcPtr, Uint32 srcPitch, - Uint8 *dstPtr, Uint32 dstPitch, - int width, int height) -{ - unsigned int nextlineSrc = srcPitch / sizeof(Uint16); - Uint16 *p = (Uint16 *)srcPtr; - unsigned int nextlineDst = dstPitch / sizeof(Uint16); - Uint16 *q = (Uint16 *)dstPtr; - int dx = width << 1, dy = height << 1; - float fsx = (float)width / dx; - float fsy = (float)height / dy; - float v = 0.0f; - int j = 0; - for(; j < dy; ++j) { - float u = 0.0f; - int iv = (int)v; - float decy = v - iv; - int i = 0; - for(; i < dx; ++i) { - int iu = (int)u; - float decx = u - iu; - float r, g, b; - int m; - r = g = b = 0.; - for(m = -1; m <= 2; ++m) { - float r1 = CUBIC_WEIGHT(decy - m); - int n; - for(n = -1; n <= 2; ++n) { - float r2 = CUBIC_WEIGHT(n - decx); - Uint16* pIn = p + (iu + n) + (iv + m) * nextlineSrc; - MULT(*pIn, &r, &g, &b, r1 * r2); - } - } - *(q + i) = MAKE_RGB565(r, g, b); - u += fsx; - } - q += nextlineDst; - v += fsy; - } -} diff --git a/src/sdl12/filter/filters.h b/src/sdl12/filter/filters.h deleted file mode 100644 index c4a84b4c9a0f38aab30b686f8d16d87fc1b22add..0000000000000000000000000000000000000000 --- a/src/sdl12/filter/filters.h +++ /dev/null @@ -1,212 +0,0 @@ -#ifndef __FILTERS_H__ -#define __FILTERS_H__ - -#ifdef _MSC_VER -#pragma warning(disable : 4514 4214 4244) -#endif - -#include "SDL.h" - -#ifdef _MSC_VER -#pragma warning(default : 4214 4244) -#endif - -typedef enum { - FILTER_2XSAI = 0, - FILTER_SUPER2XSAI, - FILTER_SUPEREAGLE, - FILTER_ADVMAME2X , - FILTER_TV2X , - FILTER_NORMAL2X , - FILTER_BILINEAR , - FILTER_DOTMATRIX , - FILTER_NUM , -} t_filter; - -typedef void (*filter_2)(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); -SDL_Surface *filter_2x(SDL_Surface *src, SDL_Rect *srcclp, filter_2 filter); -SDL_Surface *filter_2xe(SDL_Surface *src, SDL_Rect *srcclp, filter_2 filter,Uint8 R, Uint8 G, Uint8 B); -//Alam_GBC: Header file based on sms_sdl's filter.h -//Note: need 3 lines at the bottom and top? - -//int filter_init_2xsai(SDL_PixelFormat *BitFormat); -#define FILTER(src,dst) (Uint8 *)(src->pixels)+src->pitch*3, (Uint32)src->pitch, (Uint8 *)dst->pixels, (Uint32)dst->pitch, src->w, src->h-6 -#define SDLFILTER(src,dst) (Uint8 *)src->pixels, (Uint32)src->pitch, (Uint8 *)dst->pixels, (Uint32)dst->pitch, src->w, src->h -int filter_init_2xsai(SDL_PixelFormat *BitFormat); //unless? -void filter_scan50(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); -void filter_scan100(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); - -void filter_2xsai(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); -void filter_super2xsai(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); -void filter_supereagle(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); -void filter_advmame2x(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); -void filter_tv2x(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); -void filter_normal2x(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); -void filter_bilinear(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); -void filter_dotmatrix(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); -void filter_bicubic(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); -void lq2x16(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); -void hq2x16(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); - -void filter_hq2x(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); -void lq2x32(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); -void hq2x32(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); - -#ifdef FILTERS -typedef struct filter_s { filter_2 filter; int bpp; } filter_t; -#define NUMFILTERS 13 -static filter_t filtermode[NUMFILTERS+1] = { - {NULL , 0}, //None - {filter_normal2x , 16}, //2xNormal - {filter_advmame2x , 16}, //AdvMAME2x - {filter_tv2x , 16}, //TV2x - {filter_bilinear , 16}, //Bilinear - {filter_dotmatrix , 16}, //DotMatrix - {lq2x16 , 16}, //16LQ2x - {hq2x16 , 16}, //16HQ2x - {lq2x32 , 32}, //32LQ2x - {hq2x32 , 32}, //32HQ2x -// {filter_bicubic , 16}, //Slow Bicubic - // BAD - {filter_2xsai , 16}, //2xSAI - {filter_super2xsai, 16}, //Super2xSAI - {filter_supereagle, 16}, //SuperEagle -}; -CV_PossibleValue_t CV_Filters[] = {{ 0, "None"}, { 1, "2xNormal"}, - { 2, "AdvMAME2x"}, { 3, "TV2x"}, { 4, "Bilinear"} , { 5, "DotMatrix"}, - { 6, "16LQ2x"}, { 7, "16HQ2x"}, { 8, "32LQ2x"} , { 9, "32HQ2x"}, - {10, "2xSAI"}, {11, "Super2xSAI"}, {12, "SuperEagle"}, {0, NULL},}; -static void Filterchange(void); -consvar_t cv_filter = {"filter", "None", CV_CALL|CV_NOINIT, CV_Filters,Filterchange,0,NULL,NULL,0,0,NULL}; -static filter_2 blitfilter = NULL; -static SDL_Surface *preSurface = NULL; -static SDL_Surface *f2xSurface = NULL; - -static void Filterchange(void) -{ - if(blitfilter) // only filtering? - { - int i=0; - for(;i < NUMFILTERS; i++)//find old filter - { - if(filtermode[i].filter == blitfilter) //Found it - break; //Stop - } - if(i < NUMFILTERS && filtermode[i].bpp == filtermode[cv_filter.value].bpp) //Easy to swap? - blitfilter = filtermode[cv_filter.value].filter; // Swap with new filter - } -} - -FUNCINLINE static ATTRINLINE void FilterBlit(SDL_Surface *froSurface) -{ - if(froSurface && blitfilter && preSurface && f2xSurface) - { - SDL_Rect dstclp = {0,3,0,0}; - int lockedpre = 0, lockedf2x = 0, blitpre = 0; - blitpre = SDL_BlitSurface(froSurface,NULL,preSurface,&dstclp); - if(SDL_MUSTLOCK(preSurface)) lockedpre = SDL_LockSurface(preSurface); - if(SDL_MUSTLOCK(f2xSurface)) lockedf2x = SDL_LockSurface(f2xSurface); - if(lockedpre == 0 && preSurface->pixels && lockedf2x == 0 && f2xSurface->pixels && blitpre == 0) - { - blitfilter(FILTER(preSurface,f2xSurface)); - if(SDL_MUSTLOCK(preSurface)) SDL_UnlockSurface(preSurface); - if(SDL_MUSTLOCK(f2xSurface)) SDL_UnlockSurface(f2xSurface); - } - } - else - { - blitfilter = NULL; - if(preSurface) SDL_FreeSurface(preSurface); - preSurface = NULL; - if(f2xSurface) SDL_FreeSurface(f2xSurface); - f2xSurface = NULL; - } -} - -FUNCINLINE static ATTRINLINE int Setupf2x(int width, int height, int bpp) -{ - blitfilter = NULL; - if(preSurface) SDL_FreeSurface(preSurface); - preSurface = NULL; - if(f2xSurface) SDL_FreeSurface(f2xSurface); - f2xSurface = NULL; - if( !(width%2) && !(height%2) && width >= BASEVIDWIDTH*2 && height >= BASEVIDHEIGHT*2 && cv_filter.value - && cv_filter.value <= NUMFILTERS && filtermode[cv_filter.value].filter && filtermode[cv_filter.value].bpp) - { - int hwidth = width/2 + 6; - int heighth = height/2 + 6; - int hbpp = filtermode[cv_filter.value].bpp; - switch(hbpp) - { - case 8: - preSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,hwidth,heighth, 8,0x00000000,0x00000000,0x00000000,0x00); - f2xSurface = SDL_CreateRGBSurface(SDL_HWSURFACE, width,height , 8,0x00000000,0x00000000,0x00000000,0x00); - case 15: - preSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,hwidth,heighth,15,0x00007C00,0x000003E0,0x0000001F,0x00); - f2xSurface = SDL_CreateRGBSurface(SDL_HWSURFACE, width,height ,15,0x00007C00,0x000003E0,0x0000001F,0x00); - break; - case 16: - preSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,hwidth,heighth,16,0x0000F800,0x000007E0,0x0000001F,0x00); - f2xSurface = SDL_CreateRGBSurface(SDL_HWSURFACE, width,height ,16,0x0000F800,0x000007E0,0x0000001F,0x00); - break; - case 24: - preSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,hwidth,heighth,24,0x00FF0000,0x0000FF00,0x000000FF,0x00); - f2xSurface = SDL_CreateRGBSurface(SDL_HWSURFACE, width,height ,24,0x00FF0000,0x0000FF00,0x000000FF,0x00); - break; - case 32: - preSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,hwidth,heighth,32,0x00FF0000,0x0000FF00,0x000000FF,0x00); - f2xSurface = SDL_CreateRGBSurface(SDL_HWSURFACE, width,height ,32,0x00FF0000,0x0000FF00,0x000000FF,0x00); - break; - default: - //I_Error("Filter help"); - break; - } - if(preSurface && f2xSurface) - { - blitfilter = filtermode[cv_filter.value].filter; - if(bpp < hbpp) bpp = hbpp; - } - else - { - if(preSurface) SDL_FreeSurface(preSurface); - preSurface = NULL; - if(f2xSurface) SDL_FreeSurface(f2xSurface); - f2xSurface = NULL; - } - } - return bpp; -} -#else - -#ifdef __GNUC__ // __attribute__ ((X)) -#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) -#define FUNCINLINE __attribute__((always_inline)) -#endif -#define FUNCNOINLINE __attribute__((noinline)) -#elif defined(_MSC_VER) -#define inline __inline -#define ATTRNORETURN __declspec(noreturn) -#define ATTRINLINE __forceinline -#if _MSC_VER > 1200 -#define ATTRNOINLINE __declspec(noinline) -#endif -#endif - - - -#ifndef FUNCINLINE -#define FUNCINLINE -#endif -#ifndef FUNCNOINLINE -#define FUNCNOINLINE -#endif -#ifndef ATTRINLINE -#define ATTRINLINE inline -#endif -#ifndef ATTRNOINLINE -#define ATTRNOINLINE -#endif - -#endif - -#endif diff --git a/src/sdl12/filter/hq2x.c b/src/sdl12/filter/hq2x.c deleted file mode 100644 index acdbcb168b1f2600f00a9ef4f7eb737faf861317..0000000000000000000000000000000000000000 --- a/src/sdl12/filter/hq2x.c +++ /dev/null @@ -1,3125 +0,0 @@ -//hq2x filter demo program -//---------------------------------------------------------- -//Copyright (C) 2003 MaxSt ( maxst@hiend3d.com ) - -//This program is free software; you can redistribute it and/or -//modify it under the terms of the GNU Lesser General Public -//License as published by the Free Software Foundation; either -//version 2.1 of the License, or (at your option) any later version. -// -//This program is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -//Lesser General Public License for more details. -// -//You should have received a copy of the GNU Lesser General Public -//License along with this program; if not, write to the Free Software -//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -#include "filters.h" -#include <math.h> -#ifdef __GNUC__ -#include <stdlib.h> -#endif - - -#if (defined(__GNUC__) && defined(__i386__)) || (defined(_MSC_VER) && defined(_X86_)) -#define HQ2XASM -#endif - -#ifdef _MSC_VER -//#define HQ2XMMXASM -#endif - -static int LUT16to32[65536]; -static int RGBtoYUV[65536]; -#ifdef HQ2XMMXASM -#include "SDL_cpuinfo.h" -static SDL_bool hasMMX = 0; -const Sint64 reg_blank = 0; -const Sint64 const3 = 0x0000000300030003; -const Sint64 const5 = 0x0000000500050005; -const Sint64 const6 = 0x0000000600060006; -const Sint64 const14 = 0x0000000E000E000E; -const Sint64 tr3eshold = 0x0000000000300706; -#endif -static int YUV1, YUV2; -const int Ymask = 0x00FF0000; -const int Umask = 0x0000FF00; -const int Vmask = 0x000000FF; -const int trY = 0x00300000; -const int trU = 0x00000700; -const int trV = 0x00000006; - -FUNCINLINE static ATTRINLINE void Interp1(Uint8 * pc, int c1, int c2) -{ -#ifdef HQ2XASM - //*((int*)pc) = (c1*3+c2)/4; -#ifdef __GNUC__ - int c3 = c1; - __asm__("shl $2, %1; add %2, %1; sub %3, %1; shr $2, %1":"=d"(*((int*)pc)):"d"(c1),"r"(c2),"r"(c3):"memory"); -#else - __asm - { - mov eax, pc - mov edx, c1 - shl edx, 2 - add edx, c2 - sub edx, c1 - shr edx, 2 - mov [eax], edx - } -#endif -#else - *((int*)pc) = (c1*3+c2) >> 2; -#endif -} - -FUNCINLINE static ATTRINLINE void Interp2(Uint8 * pc, int c1, int c2, int c3) -{ -#ifdef HQ2XASM -// *((int*)pc) = (c1*2+c2+c3) >> 2; -#ifdef __GNUC__ - __asm__("shl $1, %1; add %2, %1; add %3, %1; shr $2, %1":"=d"(*((int*)pc)):"d"(c1),"r"(c2),"r"(c3):"memory"); -#else - __asm - { - mov eax, pc - mov edx, c1 - shl edx, 1 - add edx, c2 - add edx, c3 - shr edx, 2 - mov [eax], edx - } -#endif -#else - *((int*)pc) = (c1*2+c2+c3) >> 2; -#endif -} - -#if 0 -static inline void Interp5(Uint8 * pc, int c1, int c2) -{ -#ifdef HQ2XASM - //*((int*)pc) = (c1+c2)/2; -#ifdef __GNUC__ - __asm__("add %2, %1; shr $1, %1":"=d"(*((int*)pc)):"d"(c1),"r"(c2):"memory"); -#else - __asm - { - mov eax, pc - mov edx, c1 - add edx, c2 - shr edx, 1 - mov [eax], edx - } -#endif -#else - *((int*)pc) = (c1+c2) >> 1; -#endif -} -#endif - -FUNCINLINE static ATTRINLINE void Interp6(Uint8 * pc, int c1, int c2, int c3) -{ -#ifdef HQ2XMMXASM - //*((int*)pc) = (c1*5+c2*2+c3)/8; - if(hasMMX) -#ifdef __GNUC__ - __asm__("movd %1, %%mm1; movd %2, %%mm2, movd %3, %%mm3; punpcklbw $_reg_blank, %%mm1; punpcklbw $_reg_blank, %%mm2; punpcklbw $_reg_blank, %%mm3; pmullw $_const5, %%mm1; psllw $1, %%mm2; paddw %%mm3, %%mm1; paddw %%mm2, %%mm1; psrlw $3, %%mm1; packuswb $_reg_blank, %%mm1; movd %%mm1, %0" : "=r"(*((int*)pc)) : "r" (c1),"r" (c2),"r" (c3) : "memory"); -#else - __asm - { - mov eax, pc - movd mm1, c1 - movd mm2, c2 - movd mm3, c3 - punpcklbw mm1, reg_blank - punpcklbw mm2, reg_blank - punpcklbw mm3, reg_blank - pmullw mm1, const5 - psllw mm2, 1 - paddw mm1, mm3 - paddw mm1, mm2 - psrlw mm1, 3 - packuswb mm1, reg_blank - movd [eax], mm1 - } -#endif - else -#endif - *((int*)pc) = ((((c1 & 0x00FF00)*5 + (c2 & 0x00FF00)*2 + (c3 & 0x00FF00) ) & 0x0007F800) + - (((c1 & 0xFF00FF)*5 + (c2 & 0xFF00FF)*2 + (c3 & 0xFF00FF) ) & 0x07F807F8)) >> 3; -} - -FUNCINLINE static ATTRINLINE void Interp7(Uint8 * pc, int c1, int c2, int c3) -{ -#ifdef HQ2XMMXASM - //*((int*)pc) = (c1*6+c2+c3)/8; - if(hasMMX) -#ifdef __GNUC__ - __asm__("movd %1, %%mm1; movd %2, %%mm2, movd %3, %%mm3; punpcklbw $_reg_blank, %%mm1; punpcklbw $_reg_blank, %%mm2; punpcklbw $_reg_blank, %%mm3; pmull2 $_const6, %%mm1; padw %%mm3, %%mm2; paddw %%mm2, %%mm1; psrlw $3, %%mm1; packuswb $_reg_blank, %%mm1; movd %%mm1, %0 " : "=r" (*((int*)pc)): "r"(c1), "r"(c2), "r"(c3) : "memory"); -#else - __asm - { - mov eax, pc - movd mm1, c1 - movd mm2, c2 - movd mm3, c3 - punpcklbw mm1, reg_blank - punpcklbw mm2, reg_blank - punpcklbw mm3, reg_blank - pmullw mm1, const6 - paddw mm2, mm3 - paddw mm1, mm2 - psrlw mm1, 3 - packuswb mm1, reg_blank - movd [eax], mm1 - } -#endif - else -#endif - *((int*)pc) = ((((c1 & 0x00FF00)*6 + (c2 & 0x00FF00) + (c3 & 0x00FF00) ) & 0x0007F800) + - (((c1 & 0xFF00FF)*6 + (c2 & 0xFF00FF) + (c3 & 0xFF00FF) ) & 0x07F807F8)) >> 3; -} - -FUNCINLINE static ATTRINLINE void Interp9(Uint8 * pc, int c1, int c2, int c3) -{ -#ifdef HQ2XMMXASM - //*((int*)pc) = (c1*2+(c2+c3)*3)/8; - if(hasMMX) -#ifdef __GNUC__ - __asm__("movd %1, %%mm1; movd %2, %%mm2, movd %3, %%mm3; punpcklbw $_reg_blank, %%mm1; punpcklbw $_reg_blank, %%mm2; punpcklbw $_reg_blank, %%mm3; psllw $1, %%mm1; paddw %%mm3, %%mm2; pmullw $_const3, %%mm2; padw %%mm2, %%mm1; psrlw $3, %%mm1; packuswb $_reg_blank, %%mm1; movd %%mm1, %0;" : "=r"(*((int*)pc)) : "r" (c1),"r" (c2),"r" (c3) : "memory"); -#else - __asm - { - mov eax, pc - movd mm1, c1 - movd mm2, c2 - movd mm3, c3 - punpcklbw mm1, reg_blank - punpcklbw mm2, reg_blank - punpcklbw mm3, reg_blank - psllw mm1, 1 - paddw mm2, mm3 - pmullw mm2, const3 - paddw mm1, mm2 - psrlw mm1, 3 - packuswb mm1, reg_blank - movd [eax], mm1 - } -#endif - else -#endif - *((int*)pc) = ((((c1 & 0x00FF00)*2 + ((c2 & 0x00FF00) + (c3 & 0x00FF00))*3 ) & 0x0007F800) + - (((c1 & 0xFF00FF)*2 + ((c2 & 0xFF00FF) + (c3 & 0xFF00FF))*3 ) & 0x07F807F8)) >> 3; -} - -FUNCINLINE static ATTRINLINE void Interp10(Uint8 * pc, int c1, int c2, int c3) -{ -#ifdef HQ2XMMXASM - //*((int*)pc) = (c1*14+c2+c3)/16; - if(hasMMX) -#ifdef __GNUC__ - __asm__("movd %1, %%mm1; movd %2, %%mm2, movd %3, %%mm3; punpcklbw $_reg_blank, %%mm1; punpcklbw $_reg_blank, %%mm2; punpcklbw $_reg_blank, %%mm3; pmullw $_const14, %%mm1; paddw %%mm3, %%mm2; paddw %%mm2, %%mm1; psrlw $4, %%mm1; packuswb $_req_blank, %%mm1; movd %%mm1, %0;" : "=r"(*((int*)pc)) : "r" (c1),"r" (c2),"r" (c3) : "memory"); -#else - __asm - { - mov eax, pc - movd mm1, c1 - movd mm2, c2 - movd mm3, c3 - punpcklbw mm1, reg_blank - punpcklbw mm2, reg_blank - punpcklbw mm3, reg_blank - pmullw mm1, const14 - paddw mm2, mm3 - paddw mm1, mm2 - psrlw mm1, 4 - packuswb mm1, reg_blank - movd [eax], mm1 - } -#endif - else -#endif - *((int*)pc) = ((((c1 & 0x00FF00)*14 + (c2 & 0x00FF00) + (c3 & 0x00FF00) ) & 0x000FF000) + - (((c1 & 0xFF00FF)*14 + (c2 & 0xFF00FF) + (c3 & 0xFF00FF) ) & 0x0FF00FF0)) >> 4; -} -#define PIXEL00_0 *((int*)(pOut)) = c[5]; -#define PIXEL00_10 Interp1(pOut, c[5], c[1]); -#define PIXEL00_11 Interp1(pOut, c[5], c[4]); -#define PIXEL00_12 Interp1(pOut, c[5], c[2]); -#define PIXEL00_20 Interp2(pOut, c[5], c[4], c[2]); -#define PIXEL00_21 Interp2(pOut, c[5], c[1], c[2]); -#define PIXEL00_22 Interp2(pOut, c[5], c[1], c[4]); -#define PIXEL00_60 Interp6(pOut, c[5], c[2], c[4]); -#define PIXEL00_61 Interp6(pOut, c[5], c[4], c[2]); -#define PIXEL00_70 Interp7(pOut, c[5], c[4], c[2]); -#define PIXEL00_90 Interp9(pOut, c[5], c[4], c[2]); -#define PIXEL00_100 Interp10(pOut, c[5], c[4], c[2]); -#define PIXEL01_0 *((int*)(pOut+4)) = c[5]; -#define PIXEL01_10 Interp1(pOut+4, c[5], c[3]); -#define PIXEL01_11 Interp1(pOut+4, c[5], c[2]); -#define PIXEL01_12 Interp1(pOut+4, c[5], c[6]); -#define PIXEL01_20 Interp2(pOut+4, c[5], c[2], c[6]); -#define PIXEL01_21 Interp2(pOut+4, c[5], c[3], c[6]); -#define PIXEL01_22 Interp2(pOut+4, c[5], c[3], c[2]); -#define PIXEL01_60 Interp6(pOut+4, c[5], c[6], c[2]); -#define PIXEL01_61 Interp6(pOut+4, c[5], c[2], c[6]); -#define PIXEL01_70 Interp7(pOut+4, c[5], c[2], c[6]); -#define PIXEL01_90 Interp9(pOut+4, c[5], c[2], c[6]); -#define PIXEL01_100 Interp10(pOut+4, c[5], c[2], c[6]); -#define PIXEL10_0 *((int*)(pOut+BpL)) = c[5]; -#define PIXEL10_10 Interp1(pOut+BpL, c[5], c[7]); -#define PIXEL10_11 Interp1(pOut+BpL, c[5], c[8]); -#define PIXEL10_12 Interp1(pOut+BpL, c[5], c[4]); -#define PIXEL10_20 Interp2(pOut+BpL, c[5], c[8], c[4]); -#define PIXEL10_21 Interp2(pOut+BpL, c[5], c[7], c[4]); -#define PIXEL10_22 Interp2(pOut+BpL, c[5], c[7], c[8]); -#define PIXEL10_60 Interp6(pOut+BpL, c[5], c[4], c[8]); -#define PIXEL10_61 Interp6(pOut+BpL, c[5], c[8], c[4]); -#define PIXEL10_70 Interp7(pOut+BpL, c[5], c[8], c[4]); -#define PIXEL10_90 Interp9(pOut+BpL, c[5], c[8], c[4]); -#define PIXEL10_100 Interp10(pOut+BpL, c[5], c[8], c[4]); -#define PIXEL11_0 *((int*)(pOut+BpL+4)) = c[5]; -#define PIXEL11_10 Interp1(pOut+BpL+4, c[5], c[9]); -#define PIXEL11_11 Interp1(pOut+BpL+4, c[5], c[6]); -#define PIXEL11_12 Interp1(pOut+BpL+4, c[5], c[8]); -#define PIXEL11_20 Interp2(pOut+BpL+4, c[5], c[6], c[8]); -#define PIXEL11_21 Interp2(pOut+BpL+4, c[5], c[9], c[8]); -#define PIXEL11_22 Interp2(pOut+BpL+4, c[5], c[9], c[6]); -#define PIXEL11_60 Interp6(pOut+BpL+4, c[5], c[8], c[6]); -#define PIXEL11_61 Interp6(pOut+BpL+4, c[5], c[6], c[8]); -#define PIXEL11_70 Interp7(pOut+BpL+4, c[5], c[6], c[8]); -#define PIXEL11_90 Interp9(pOut+BpL+4, c[5], c[6], c[8]); -#define PIXEL11_100 Interp10(pOut+BpL+4, c[5], c[6], c[8]); - -#ifdef _MSC_VER -#pragma warning(disable: 4035) -#endif - -FUNCINLINE static ATTRINLINE int Diff(Uint32 w1, Uint32 w2) -{ -#ifdef HQ2XMMXASM - if(hasMMX) - { -#ifdef __GNUC__ - int diffresult = 0; - if(w1 != w2) - __asm__("movd %3+%1*4, %%mm1; movq %%mm1, %%mm5; movd %3+%2*4, %%mm2; psubusb %%mm2, %%mm1; psubusb %%mm5, %%mm2; por %%mm2, %%mm1; psubusb $_treshold, %%mm1; movd %%mm1, %0" : "=c" (diffresult):"d" (w1),"q" (w2),"c" (RGBtoYUV) : "memory"); - return diffresult; -#else - __asm - { - xor eax,eax - mov ebx,w1 - mov edx,w2 - cmp ebx,edx - je FIN - mov ecx,offset RGBtoYUV - movd mm1,[ecx + ebx*4] - movq mm5,mm1 - movd mm2,[ecx + edx*4] - psubusb mm1,mm2 - psubusb mm2,mm5 - por mm1,mm2 - psubusb mm1,treshold - movd eax,mm1 -FIN: - }// returns result in eax register -#endif - } - else -#endif - { - YUV1 = RGBtoYUV[w1]; - YUV2 = RGBtoYUV[w2]; - return ( ( abs((YUV1 & Ymask) - (YUV2 & Ymask)) > trY ) || - ( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) || - ( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) ); - } -} - - -#ifdef _MSC_VER -#pragma warning(default: 4035) -#endif - - -static void hq2x_32( Uint8 * pIn, Uint8 * pOut, int Xres, int Yres, int BpL ) -{ - int i, j, k; - int prevline, nextline; - int w[10]; - int c[10]; - - // +----+----+----+ - // | | | | - // | w1 | w2 | w3 | - // +----+----+----+ - // | | | | - // | w4 | w5 | w6 | - // +----+----+----+ - // | | | | - // | w7 | w8 | w9 | - // +----+----+----+ - - for (j=0; j<Yres; j++) - { - if (j>0) prevline = -Xres*2; else prevline = 0; - if (j<Yres-1) nextline = Xres*2; else nextline = 0; - - for (i=0; i<Xres; i++) - { - int pattern = 0; - int flag = 1; - - w[2] = *((Uint16*)(pIn + prevline)); - w[5] = *((Uint16*)pIn); - w[8] = *((Uint16*)(pIn + nextline)); - - if (i>0) - { - w[1] = *((Uint16*)(pIn + prevline - 2)); - w[4] = *((Uint16*)(pIn - 2)); - w[7] = *((Uint16*)(pIn + nextline - 2)); - } - else - { - w[1] = w[2]; - w[4] = w[5]; - w[7] = w[8]; - } - - if (i<Xres-1) - { - w[3] = *((Uint16*)(pIn + prevline + 2)); - w[6] = *((Uint16*)(pIn + 2)); - w[9] = *((Uint16*)(pIn + nextline + 2)); - } - else - { - w[3] = w[2]; - w[6] = w[5]; - w[9] = w[8]; - } - -#ifdef HQ2XMMXASM - if(hasMMX) - { - if ( Diff(w[5],w[1]) ) pattern |= 0x0001; - if ( Diff(w[5],w[2]) ) pattern |= 0x0002; - if ( Diff(w[5],w[3]) ) pattern |= 0x0004; - if ( Diff(w[5],w[4]) ) pattern |= 0x0008; - if ( Diff(w[5],w[6]) ) pattern |= 0x0010; - if ( Diff(w[5],w[7]) ) pattern |= 0x0020; - if ( Diff(w[5],w[8]) ) pattern |= 0x0040; - if ( Diff(w[5],w[9]) ) pattern |= 0x0080; - } - else -#endif - { - YUV1 = RGBtoYUV[w[5]]; - - for (k=1; k<=9; k++) - { - if (k==5) continue; - - if ( w[k] != w[5] ) - { - YUV2 = RGBtoYUV[w[k]]; - if ( ( abs((YUV1 & Ymask) - (YUV2 & Ymask)) > trY ) || - ( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) || - ( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) ) - pattern |= flag; - } - flag <<= 1; - } - } - - for (k=1; k<=9; k++) - c[k] = LUT16to32[w[k]]; - - switch (pattern) - { - case 0: - case 1: - case 4: - case 32: - case 128: - case 5: - case 132: - case 160: - case 33: - case 129: - case 36: - case 133: - case 164: - case 161: - case 37: - case 165: - { - PIXEL00_20 - PIXEL01_20 - PIXEL10_20 - PIXEL11_20 - break; - } - case 2: - case 34: - case 130: - case 162: - { - PIXEL00_22 - PIXEL01_21 - PIXEL10_20 - PIXEL11_20 - break; - } - case 16: - case 17: - case 48: - case 49: - { - PIXEL00_20 - PIXEL01_22 - PIXEL10_20 - PIXEL11_21 - break; - } - case 64: - case 65: - case 68: - case 69: - { - PIXEL00_20 - PIXEL01_20 - PIXEL10_21 - PIXEL11_22 - break; - } - case 8: - case 12: - case 136: - case 140: - { - PIXEL00_21 - PIXEL01_20 - PIXEL10_22 - PIXEL11_20 - break; - } - case 3: - case 35: - case 131: - case 163: - { - PIXEL00_11 - PIXEL01_21 - PIXEL10_20 - PIXEL11_20 - break; - } - case 6: - case 38: - case 134: - case 166: - { - PIXEL00_22 - PIXEL01_12 - PIXEL10_20 - PIXEL11_20 - break; - } - case 20: - case 21: - case 52: - case 53: - { - PIXEL00_20 - PIXEL01_11 - PIXEL10_20 - PIXEL11_21 - break; - } - case 144: - case 145: - case 176: - case 177: - { - PIXEL00_20 - PIXEL01_22 - PIXEL10_20 - PIXEL11_12 - break; - } - case 192: - case 193: - case 196: - case 197: - { - PIXEL00_20 - PIXEL01_20 - PIXEL10_21 - PIXEL11_11 - break; - } - case 96: - case 97: - case 100: - case 101: - { - PIXEL00_20 - PIXEL01_20 - PIXEL10_12 - PIXEL11_22 - break; - } - case 40: - case 44: - case 168: - case 172: - { - PIXEL00_21 - PIXEL01_20 - PIXEL10_11 - PIXEL11_20 - break; - } - case 9: - case 13: - case 137: - case 141: - { - PIXEL00_12 - PIXEL01_20 - PIXEL10_22 - PIXEL11_20 - break; - } - case 18: - case 50: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_20 - } - PIXEL10_20 - PIXEL11_21 - break; - } - case 80: - case 81: - { - PIXEL00_20 - PIXEL01_22 - PIXEL10_21 - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_20 - } - break; - } - case 72: - case 76: - { - PIXEL00_21 - PIXEL01_20 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_20 - } - PIXEL11_22 - break; - } - case 10: - case 138: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_20 - } - PIXEL01_21 - PIXEL10_22 - PIXEL11_20 - break; - } - case 66: - { - PIXEL00_22 - PIXEL01_21 - PIXEL10_21 - PIXEL11_22 - break; - } - case 24: - { - PIXEL00_21 - PIXEL01_22 - PIXEL10_22 - PIXEL11_21 - break; - } - case 7: - case 39: - case 135: - { - PIXEL00_11 - PIXEL01_12 - PIXEL10_20 - PIXEL11_20 - break; - } - case 148: - case 149: - case 180: - { - PIXEL00_20 - PIXEL01_11 - PIXEL10_20 - PIXEL11_12 - break; - } - case 224: - case 228: - case 225: - { - PIXEL00_20 - PIXEL01_20 - PIXEL10_12 - PIXEL11_11 - break; - } - case 41: - case 169: - case 45: - { - PIXEL00_12 - PIXEL01_20 - PIXEL10_11 - PIXEL11_20 - break; - } - case 22: - case 54: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_20 - PIXEL11_21 - break; - } - case 208: - case 209: - { - PIXEL00_20 - PIXEL01_22 - PIXEL10_21 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 104: - case 108: - { - PIXEL00_21 - PIXEL01_20 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_22 - break; - } - case 11: - case 139: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_21 - PIXEL10_22 - PIXEL11_20 - break; - } - case 19: - case 51: - { - if (Diff(w[2], w[6])) - { - PIXEL00_11 - PIXEL01_10 - } - else - { - PIXEL00_60 - PIXEL01_90 - } - PIXEL10_20 - PIXEL11_21 - break; - } - case 146: - case 178: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_10 - PIXEL11_12 - } - else - { - PIXEL01_90 - PIXEL11_61 - } - PIXEL10_20 - break; - } - case 84: - case 85: - { - PIXEL00_20 - if (Diff(w[6], w[8])) - { - PIXEL01_11 - PIXEL11_10 - } - else - { - PIXEL01_60 - PIXEL11_90 - } - PIXEL10_21 - break; - } - case 112: - case 113: - { - PIXEL00_20 - PIXEL01_22 - if (Diff(w[6], w[8])) - { - PIXEL10_12 - PIXEL11_10 - } - else - { - PIXEL10_61 - PIXEL11_90 - } - break; - } - case 200: - case 204: - { - PIXEL00_21 - PIXEL01_20 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - PIXEL11_11 - } - else - { - PIXEL10_90 - PIXEL11_60 - } - break; - } - case 73: - case 77: - { - if (Diff(w[8], w[4])) - { - PIXEL00_12 - PIXEL10_10 - } - else - { - PIXEL00_61 - PIXEL10_90 - } - PIXEL01_20 - PIXEL11_22 - break; - } - case 42: - case 170: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - PIXEL10_11 - } - else - { - PIXEL00_90 - PIXEL10_60 - } - PIXEL01_21 - PIXEL11_20 - break; - } - case 14: - case 142: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - PIXEL01_12 - } - else - { - PIXEL00_90 - PIXEL01_61 - } - PIXEL10_22 - PIXEL11_20 - break; - } - case 67: - { - PIXEL00_11 - PIXEL01_21 - PIXEL10_21 - PIXEL11_22 - break; - } - case 70: - { - PIXEL00_22 - PIXEL01_12 - PIXEL10_21 - PIXEL11_22 - break; - } - case 28: - { - PIXEL00_21 - PIXEL01_11 - PIXEL10_22 - PIXEL11_21 - break; - } - case 152: - { - PIXEL00_21 - PIXEL01_22 - PIXEL10_22 - PIXEL11_12 - break; - } - case 194: - { - PIXEL00_22 - PIXEL01_21 - PIXEL10_21 - PIXEL11_11 - break; - } - case 98: - { - PIXEL00_22 - PIXEL01_21 - PIXEL10_12 - PIXEL11_22 - break; - } - case 56: - { - PIXEL00_21 - PIXEL01_22 - PIXEL10_11 - PIXEL11_21 - break; - } - case 25: - { - PIXEL00_12 - PIXEL01_22 - PIXEL10_22 - PIXEL11_21 - break; - } - case 26: - case 31: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_22 - PIXEL11_21 - break; - } - case 82: - case 214: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_21 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 88: - case 248: - { - PIXEL00_21 - PIXEL01_22 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 74: - case 107: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_21 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_22 - break; - } - case 27: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_10 - PIXEL10_22 - PIXEL11_21 - break; - } - case 86: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_21 - PIXEL11_10 - break; - } - case 216: - { - PIXEL00_21 - PIXEL01_22 - PIXEL10_10 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 106: - { - PIXEL00_10 - PIXEL01_21 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_22 - break; - } - case 30: - { - PIXEL00_10 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_22 - PIXEL11_21 - break; - } - case 210: - { - PIXEL00_22 - PIXEL01_10 - PIXEL10_21 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 120: - { - PIXEL00_21 - PIXEL01_22 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_10 - break; - } - case 75: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_21 - PIXEL10_10 - PIXEL11_22 - break; - } - case 29: - { - PIXEL00_12 - PIXEL01_11 - PIXEL10_22 - PIXEL11_21 - break; - } - case 198: - { - PIXEL00_22 - PIXEL01_12 - PIXEL10_21 - PIXEL11_11 - break; - } - case 184: - { - PIXEL00_21 - PIXEL01_22 - PIXEL10_11 - PIXEL11_12 - break; - } - case 99: - { - PIXEL00_11 - PIXEL01_21 - PIXEL10_12 - PIXEL11_22 - break; - } - case 57: - { - PIXEL00_12 - PIXEL01_22 - PIXEL10_11 - PIXEL11_21 - break; - } - case 71: - { - PIXEL00_11 - PIXEL01_12 - PIXEL10_21 - PIXEL11_22 - break; - } - case 156: - { - PIXEL00_21 - PIXEL01_11 - PIXEL10_22 - PIXEL11_12 - break; - } - case 226: - { - PIXEL00_22 - PIXEL01_21 - PIXEL10_12 - PIXEL11_11 - break; - } - case 60: - { - PIXEL00_21 - PIXEL01_11 - PIXEL10_11 - PIXEL11_21 - break; - } - case 195: - { - PIXEL00_11 - PIXEL01_21 - PIXEL10_21 - PIXEL11_11 - break; - } - case 102: - { - PIXEL00_22 - PIXEL01_12 - PIXEL10_12 - PIXEL11_22 - break; - } - case 153: - { - PIXEL00_12 - PIXEL01_22 - PIXEL10_22 - PIXEL11_12 - break; - } - case 58: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_11 - PIXEL11_21 - break; - } - case 83: - { - PIXEL00_11 - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_21 - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 92: - { - PIXEL00_21 - PIXEL01_11 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 202: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - PIXEL01_21 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - PIXEL11_11 - break; - } - case 78: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - PIXEL01_12 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - PIXEL11_22 - break; - } - case 154: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_22 - PIXEL11_12 - break; - } - case 114: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_12 - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 89: - { - PIXEL00_12 - PIXEL01_22 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 90: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 55: - case 23: - { - if (Diff(w[2], w[6])) - { - PIXEL00_11 - PIXEL01_0 - } - else - { - PIXEL00_60 - PIXEL01_90 - } - PIXEL10_20 - PIXEL11_21 - break; - } - case 182: - case 150: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - PIXEL11_12 - } - else - { - PIXEL01_90 - PIXEL11_61 - } - PIXEL10_20 - break; - } - case 213: - case 212: - { - PIXEL00_20 - if (Diff(w[6], w[8])) - { - PIXEL01_11 - PIXEL11_0 - } - else - { - PIXEL01_60 - PIXEL11_90 - } - PIXEL10_21 - break; - } - case 241: - case 240: - { - PIXEL00_20 - PIXEL01_22 - if (Diff(w[6], w[8])) - { - PIXEL10_12 - PIXEL11_0 - } - else - { - PIXEL10_61 - PIXEL11_90 - } - break; - } - case 236: - case 232: - { - PIXEL00_21 - PIXEL01_20 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - PIXEL11_11 - } - else - { - PIXEL10_90 - PIXEL11_60 - } - break; - } - case 109: - case 105: - { - if (Diff(w[8], w[4])) - { - PIXEL00_12 - PIXEL10_0 - } - else - { - PIXEL00_61 - PIXEL10_90 - } - PIXEL01_20 - PIXEL11_22 - break; - } - case 171: - case 43: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - PIXEL10_11 - } - else - { - PIXEL00_90 - PIXEL10_60 - } - PIXEL01_21 - PIXEL11_20 - break; - } - case 143: - case 15: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - PIXEL01_12 - } - else - { - PIXEL00_90 - PIXEL01_61 - } - PIXEL10_22 - PIXEL11_20 - break; - } - case 124: - { - PIXEL00_21 - PIXEL01_11 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_10 - break; - } - case 203: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_21 - PIXEL10_10 - PIXEL11_11 - break; - } - case 62: - { - PIXEL00_10 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_11 - PIXEL11_21 - break; - } - case 211: - { - PIXEL00_11 - PIXEL01_10 - PIXEL10_21 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 118: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_12 - PIXEL11_10 - break; - } - case 217: - { - PIXEL00_12 - PIXEL01_22 - PIXEL10_10 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 110: - { - PIXEL00_10 - PIXEL01_12 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_22 - break; - } - case 155: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_10 - PIXEL10_22 - PIXEL11_12 - break; - } - case 188: - { - PIXEL00_21 - PIXEL01_11 - PIXEL10_11 - PIXEL11_12 - break; - } - case 185: - { - PIXEL00_12 - PIXEL01_22 - PIXEL10_11 - PIXEL11_12 - break; - } - case 61: - { - PIXEL00_12 - PIXEL01_11 - PIXEL10_11 - PIXEL11_21 - break; - } - case 157: - { - PIXEL00_12 - PIXEL01_11 - PIXEL10_22 - PIXEL11_12 - break; - } - case 103: - { - PIXEL00_11 - PIXEL01_12 - PIXEL10_12 - PIXEL11_22 - break; - } - case 227: - { - PIXEL00_11 - PIXEL01_21 - PIXEL10_12 - PIXEL11_11 - break; - } - case 230: - { - PIXEL00_22 - PIXEL01_12 - PIXEL10_12 - PIXEL11_11 - break; - } - case 199: - { - PIXEL00_11 - PIXEL01_12 - PIXEL10_21 - PIXEL11_11 - break; - } - case 220: - { - PIXEL00_21 - PIXEL01_11 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 158: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_22 - PIXEL11_12 - break; - } - case 234: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - PIXEL01_21 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_11 - break; - } - case 242: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_12 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 59: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_11 - PIXEL11_21 - break; - } - case 121: - { - PIXEL00_12 - PIXEL01_22 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 87: - { - PIXEL00_11 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_21 - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 79: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_12 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - PIXEL11_22 - break; - } - case 122: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 94: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 218: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 91: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 229: - { - PIXEL00_20 - PIXEL01_20 - PIXEL10_12 - PIXEL11_11 - break; - } - case 167: - { - PIXEL00_11 - PIXEL01_12 - PIXEL10_20 - PIXEL11_20 - break; - } - case 173: - { - PIXEL00_12 - PIXEL01_20 - PIXEL10_11 - PIXEL11_20 - break; - } - case 181: - { - PIXEL00_20 - PIXEL01_11 - PIXEL10_20 - PIXEL11_12 - break; - } - case 186: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_11 - PIXEL11_12 - break; - } - case 115: - { - PIXEL00_11 - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_12 - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 93: - { - PIXEL00_12 - PIXEL01_11 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 206: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - PIXEL01_12 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - PIXEL11_11 - break; - } - case 205: - case 201: - { - PIXEL00_12 - PIXEL01_20 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - PIXEL11_11 - break; - } - case 174: - case 46: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - PIXEL01_12 - PIXEL10_11 - PIXEL11_20 - break; - } - case 179: - case 147: - { - PIXEL00_11 - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_20 - PIXEL11_12 - break; - } - case 117: - case 116: - { - PIXEL00_20 - PIXEL01_11 - PIXEL10_12 - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 189: - { - PIXEL00_12 - PIXEL01_11 - PIXEL10_11 - PIXEL11_12 - break; - } - case 231: - { - PIXEL00_11 - PIXEL01_12 - PIXEL10_12 - PIXEL11_11 - break; - } - case 126: - { - PIXEL00_10 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_10 - break; - } - case 219: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_10 - PIXEL10_10 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 125: - { - if (Diff(w[8], w[4])) - { - PIXEL00_12 - PIXEL10_0 - } - else - { - PIXEL00_61 - PIXEL10_90 - } - PIXEL01_11 - PIXEL11_10 - break; - } - case 221: - { - PIXEL00_12 - if (Diff(w[6], w[8])) - { - PIXEL01_11 - PIXEL11_0 - } - else - { - PIXEL01_60 - PIXEL11_90 - } - PIXEL10_10 - break; - } - case 207: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - PIXEL01_12 - } - else - { - PIXEL00_90 - PIXEL01_61 - } - PIXEL10_10 - PIXEL11_11 - break; - } - case 238: - { - PIXEL00_10 - PIXEL01_12 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - PIXEL11_11 - } - else - { - PIXEL10_90 - PIXEL11_60 - } - break; - } - case 190: - { - PIXEL00_10 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - PIXEL11_12 - } - else - { - PIXEL01_90 - PIXEL11_61 - } - PIXEL10_11 - break; - } - case 187: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - PIXEL10_11 - } - else - { - PIXEL00_90 - PIXEL10_60 - } - PIXEL01_10 - PIXEL11_12 - break; - } - case 243: - { - PIXEL00_11 - PIXEL01_10 - if (Diff(w[6], w[8])) - { - PIXEL10_12 - PIXEL11_0 - } - else - { - PIXEL10_61 - PIXEL11_90 - } - break; - } - case 119: - { - if (Diff(w[2], w[6])) - { - PIXEL00_11 - PIXEL01_0 - } - else - { - PIXEL00_60 - PIXEL01_90 - } - PIXEL10_12 - PIXEL11_10 - break; - } - case 237: - case 233: - { - PIXEL00_12 - PIXEL01_20 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_100 - } - PIXEL11_11 - break; - } - case 175: - case 47: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_100 - } - PIXEL01_12 - PIXEL10_11 - PIXEL11_20 - break; - } - case 183: - case 151: - { - PIXEL00_11 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_100 - } - PIXEL10_20 - PIXEL11_12 - break; - } - case 245: - case 244: - { - PIXEL00_20 - PIXEL01_11 - PIXEL10_12 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_100 - } - break; - } - case 250: - { - PIXEL00_10 - PIXEL01_10 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 123: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_10 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_10 - break; - } - case 95: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_10 - PIXEL11_10 - break; - } - case 222: - { - PIXEL00_10 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_10 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 252: - { - PIXEL00_21 - PIXEL01_11 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_100 - } - break; - } - case 249: - { - PIXEL00_12 - PIXEL01_22 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_100 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 235: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_21 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_100 - } - PIXEL11_11 - break; - } - case 111: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_100 - } - PIXEL01_12 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_22 - break; - } - case 63: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_100 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_11 - PIXEL11_21 - break; - } - case 159: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_100 - } - PIXEL10_22 - PIXEL11_12 - break; - } - case 215: - { - PIXEL00_11 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_100 - } - PIXEL10_21 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 246: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_12 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_100 - } - break; - } - case 254: - { - PIXEL00_10 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_100 - } - break; - } - case 253: - { - PIXEL00_12 - PIXEL01_11 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_100 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_100 - } - break; - } - case 251: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_10 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_100 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 239: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_100 - } - PIXEL01_12 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_100 - } - PIXEL11_11 - break; - } - case 127: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_100 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_10 - break; - } - case 191: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_100 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_100 - } - PIXEL10_11 - PIXEL11_12 - break; - } - case 223: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_100 - } - PIXEL10_10 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 247: - { - PIXEL00_11 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_100 - } - PIXEL10_12 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_100 - } - break; - } - case 255: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_100 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_100 - } - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_100 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_100 - } - break; - } - } - pIn+=2; - pOut+=8; - } - pOut+=BpL; - } -} - -FUNCINLINE static ATTRINLINE void InitLUTs(void) -{ - int i, j, k, r, g, b, Y, u, v; - -#ifdef HQ2XMMXASM - hasMMX = SDL_HasMMX(); -#endif - - for (i=0; i<65536; i++) - LUT16to32[i] = ((i & 0xF800) << 8) + ((i & 0x07E0) << 5) + ((i & 0x001F) << 3); - - for (i=0; i<32; i++) - for (j=0; j<64; j++) - for (k=0; k<32; k++) - { - r = i << 3; - g = j << 2; - b = k << 3; - Y = (r + g + b) >> 2; - u = 128 + ((r - b) >> 2); - v = 128 + ((-r + 2*g -b)>>3); - RGBtoYUV[ (i << 11) + (j << 5) + k ] = (Y<<16) + (u<<8) + v; - } -} - -void filter_hq2x(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height) -{ - static Uint8 doneLUT = 1; - (void)srcPitch; - if(doneLUT) InitLUTs(); - else doneLUT = 0; - hq2x_32( srcPtr, dstPtr, width, height, dstPitch ); -} diff --git a/src/sdl12/filter/hq2x.h b/src/sdl12/filter/hq2x.h deleted file mode 100644 index 49c0b268700655bcbaa69c968ff3d044779793a5..0000000000000000000000000000000000000000 --- a/src/sdl12/filter/hq2x.h +++ /dev/null @@ -1,1824 +0,0 @@ -case 0 : -case 1 : -case 4 : -case 5 : -case 32 : -case 33 : -case 36 : -case 37 : -case 128 : -case 129 : -case 132 : -case 133 : -case 160 : -case 161 : -case 164 : -case 165 : -{ - P0 = I211(4, 1, 3); - P1 = I211(4, 1, 5); - P2 = I211(4, 3, 7); - P3 = I211(4, 5, 7); -} break; -case 2 : -case 34 : -case 130 : -case 162 : -{ - P0 = I31(4, 0); - P1 = I31(4, 2); - P2 = I211(4, 3, 7); - P3 = I211(4, 5, 7); -} break; -case 3 : -case 35 : -case 131 : -case 163 : -{ - P0 = I31(4, 3); - P1 = I31(4, 2); - P2 = I211(4, 3, 7); - P3 = I211(4, 5, 7); -} break; -case 6 : -case 38 : -case 134 : -case 166 : -{ - P0 = I31(4, 0); - P1 = I31(4, 5); - P2 = I211(4, 3, 7); - P3 = I211(4, 5, 7); -} break; -case 7 : -case 39 : -case 135 : -case 167 : -{ - P0 = I31(4, 3); - P1 = I31(4, 5); - P2 = I211(4, 3, 7); - P3 = I211(4, 5, 7); -} break; -case 8 : -case 12 : -case 136 : -case 140 : -{ - P0 = I31(4, 0); - P1 = I211(4, 1, 5); - P2 = I31(4, 6); - P3 = I211(4, 5, 7); -} break; -case 9 : -case 13 : -case 137 : -case 141 : -{ - P0 = I31(4, 1); - P1 = I211(4, 1, 5); - P2 = I31(4, 6); - P3 = I211(4, 5, 7); -} break; -case 10 : -case 138 : -{ - P1 = I31(4, 2); - P2 = I31(4, 6); - P3 = I211(4, 5, 7); - if (MUL) { - P0 = I31(4, 0); - } else { - P0 = I211(4, 1, 3); - } -} break; -case 11 : -case 139 : -{ - P1 = I31(4, 2); - P2 = I31(4, 6); - P3 = I211(4, 5, 7); - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } -} break; -case 14 : -case 142 : -{ - P2 = I31(4, 6); - P3 = I211(4, 5, 7); - if (MUL) { - P0 = I31(4, 0); - P1 = I31(4, 5); - } else { - P0 = I332(1, 3, 4); - P1 = I521(4, 1, 5); - } -} break; -case 15 : -case 143 : -{ - P2 = I31(4, 6); - P3 = I211(4, 5, 7); - if (MUL) { - P0 = IC(4); - P1 = I31(4, 5); - } else { - P0 = I332(1, 3, 4); - P1 = I521(4, 1, 5); - } -} break; -case 16 : -case 17 : -case 48 : -case 49 : -{ - P0 = I211(4, 1, 3); - P1 = I31(4, 2); - P2 = I211(4, 3, 7); - P3 = I31(4, 8); -} break; -case 18 : -case 50 : -{ - P0 = I31(4, 0); - P2 = I211(4, 3, 7); - P3 = I31(4, 8); - if (MUR) { - P1 = I31(4, 2); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 19 : -case 51 : -{ - P2 = I211(4, 3, 7); - P3 = I31(4, 8); - if (MUR) { - P0 = I31(4, 3); - P1 = I31(4, 2); - } else { - P0 = I521(4, 1, 3); - P1 = I332(1, 5, 4); - } -} break; -case 20 : -case 21 : -case 52 : -case 53 : -{ - P0 = I211(4, 1, 3); - P1 = I31(4, 1); - P2 = I211(4, 3, 7); - P3 = I31(4, 8); -} break; -case 22 : -case 54 : -{ - P0 = I31(4, 0); - P2 = I211(4, 3, 7); - P3 = I31(4, 8); - if (MUR) { - P1 = IC(4); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 23 : -case 55 : -{ - P2 = I211(4, 3, 7); - P3 = I31(4, 8); - if (MUR) { - P0 = I31(4, 3); - P1 = IC(4); - } else { - P0 = I521(4, 1, 3); - P1 = I332(1, 5, 4); - } -} break; -case 24 : -case 66 : -{ - P0 = I31(4, 0); - P1 = I31(4, 2); - P2 = I31(4, 6); - P3 = I31(4, 8); -} break; -case 25 : -{ - P0 = I31(4, 1); - P1 = I31(4, 2); - P2 = I31(4, 6); - P3 = I31(4, 8); -} break; -case 26 : -case 31 : -case 95 : -{ - P2 = I31(4, 6); - P3 = I31(4, 8); - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 27 : -case 75 : -{ - P1 = I31(4, 2); - P2 = I31(4, 6); - P3 = I31(4, 8); - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } -} break; -case 28 : -{ - P0 = I31(4, 0); - P1 = I31(4, 1); - P2 = I31(4, 6); - P3 = I31(4, 8); -} break; -case 29 : -{ - P0 = I31(4, 1); - P1 = I31(4, 1); - P2 = I31(4, 6); - P3 = I31(4, 8); -} break; -case 30 : -case 86 : -{ - P0 = I31(4, 0); - P2 = I31(4, 6); - P3 = I31(4, 8); - if (MUR) { - P1 = IC(4); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 40 : -case 44 : -case 168 : -case 172 : -{ - P0 = I31(4, 0); - P1 = I211(4, 1, 5); - P2 = I31(4, 7); - P3 = I211(4, 5, 7); -} break; -case 41 : -case 45 : -case 169 : -case 173 : -{ - P0 = I31(4, 1); - P1 = I211(4, 1, 5); - P2 = I31(4, 7); - P3 = I211(4, 5, 7); -} break; -case 42 : -case 170 : -{ - P1 = I31(4, 2); - P3 = I211(4, 5, 7); - if (MUL) { - P0 = I31(4, 0); - P2 = I31(4, 7); - } else { - P0 = I332(1, 3, 4); - P2 = I521(4, 3, 7); - } -} break; -case 43 : -case 171 : -{ - P1 = I31(4, 2); - P3 = I211(4, 5, 7); - if (MUL) { - P0 = IC(4); - P2 = I31(4, 7); - } else { - P0 = I332(1, 3, 4); - P2 = I521(4, 3, 7); - } -} break; -case 46 : -case 174 : -{ - P1 = I31(4, 5); - P2 = I31(4, 7); - P3 = I211(4, 5, 7); - if (MUL) { - P0 = I31(4, 0); - } else { - P0 = I611(4, 1, 3); - } -} break; -case 47 : -case 175 : -{ - P1 = I31(4, 5); - P2 = I31(4, 7); - P3 = I211(4, 5, 7); - if (MUL) { - P0 = IC(4); - } else { - P0 = I1411(4, 1, 3); - } -} break; -case 56 : -{ - P0 = I31(4, 0); - P1 = I31(4, 2); - P2 = I31(4, 7); - P3 = I31(4, 8); -} break; -case 57 : -{ - P0 = I31(4, 1); - P1 = I31(4, 2); - P2 = I31(4, 7); - P3 = I31(4, 8); -} break; -case 58 : -{ - P2 = I31(4, 7); - P3 = I31(4, 8); - if (MUL) { - P0 = I31(4, 0); - } else { - P0 = I611(4, 1, 3); - } - if (MUR) { - P1 = I31(4, 2); - } else { - P1 = I611(4, 1, 5); - } -} break; -case 59 : -{ - P2 = I31(4, 7); - P3 = I31(4, 8); - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } - if (MUR) { - P1 = I31(4, 2); - } else { - P1 = I611(4, 1, 5); - } -} break; -case 60 : -{ - P0 = I31(4, 0); - P1 = I31(4, 1); - P2 = I31(4, 7); - P3 = I31(4, 8); -} break; -case 61 : -{ - P0 = I31(4, 1); - P1 = I31(4, 1); - P2 = I31(4, 7); - P3 = I31(4, 8); -} break; -case 62 : -{ - P0 = I31(4, 0); - P2 = I31(4, 7); - P3 = I31(4, 8); - if (MUR) { - P1 = IC(4); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 63 : -{ - P2 = I31(4, 7); - P3 = I31(4, 8); - if (MUL) { - P0 = IC(4); - } else { - P0 = I1411(4, 1, 3); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 64 : -case 65 : -case 68 : -case 69 : -{ - P0 = I211(4, 1, 3); - P1 = I211(4, 1, 5); - P2 = I31(4, 6); - P3 = I31(4, 8); -} break; -case 67 : -{ - P0 = I31(4, 3); - P1 = I31(4, 2); - P2 = I31(4, 6); - P3 = I31(4, 8); -} break; -case 70 : -{ - P0 = I31(4, 0); - P1 = I31(4, 5); - P2 = I31(4, 6); - P3 = I31(4, 8); -} break; -case 71 : -{ - P0 = I31(4, 3); - P1 = I31(4, 5); - P2 = I31(4, 6); - P3 = I31(4, 8); -} break; -case 72 : -case 76 : -{ - P0 = I31(4, 0); - P1 = I211(4, 1, 5); - P3 = I31(4, 8); - if (MDL) { - P2 = I31(4, 6); - } else { - P2 = I211(4, 3, 7); - } -} break; -case 73 : -case 77 : -{ - P1 = I211(4, 1, 5); - P3 = I31(4, 8); - if (MDL) { - P0 = I31(4, 1); - P2 = I31(4, 6); - } else { - P0 = I521(4, 3, 1); - P2 = I332(3, 7, 4); - } -} break; -case 74 : -case 107 : -case 123 : -{ - P1 = I31(4, 2); - P3 = I31(4, 8); - if (MDL) { - P2 = IC(4); - } else { - P2 = I211(4, 3, 7); - } - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } -} break; -case 78 : -{ - P1 = I31(4, 5); - P3 = I31(4, 8); - if (MDL) { - P2 = I31(4, 6); - } else { - P2 = I611(4, 3, 7); - } - if (MUL) { - P0 = I31(4, 0); - } else { - P0 = I611(4, 1, 3); - } -} break; -case 79 : -{ - P1 = I31(4, 5); - P3 = I31(4, 8); - if (MDL) { - P2 = I31(4, 6); - } else { - P2 = I611(4, 3, 7); - } - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } -} break; -case 80 : -case 81 : -{ - P0 = I211(4, 1, 3); - P1 = I31(4, 2); - P2 = I31(4, 6); - if (MDR) { - P3 = I31(4, 8); - } else { - P3 = I211(4, 5, 7); - } -} break; -case 82 : -case 214 : -case 222 : -{ - P0 = I31(4, 0); - P2 = I31(4, 6); - if (MDR) { - P3 = IC(4); - } else { - P3 = I211(4, 5, 7); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 83 : -{ - P0 = I31(4, 3); - P2 = I31(4, 6); - if (MDR) { - P3 = I31(4, 8); - } else { - P3 = I611(4, 5, 7); - } - if (MUR) { - P1 = I31(4, 2); - } else { - P1 = I611(4, 1, 5); - } -} break; -case 84 : -case 85 : -{ - P0 = I211(4, 1, 3); - P2 = I31(4, 6); - if (MDR) { - P1 = I31(4, 1); - P3 = I31(4, 8); - } else { - P1 = I521(4, 5, 1); - P3 = I332(5, 7, 4); - } -} break; -case 87 : -{ - P0 = I31(4, 3); - P2 = I31(4, 6); - if (MDR) { - P3 = I31(4, 8); - } else { - P3 = I611(4, 5, 7); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 88 : -case 248 : -case 250 : -{ - P0 = I31(4, 0); - P1 = I31(4, 2); - if (MDL) { - P2 = IC(4); - } else { - P2 = I211(4, 3, 7); - } - if (MDR) { - P3 = IC(4); - } else { - P3 = I211(4, 5, 7); - } -} break; -case 89 : -{ - P0 = I31(4, 1); - P1 = I31(4, 2); - if (MDL) { - P2 = I31(4, 6); - } else { - P2 = I611(4, 3, 7); - } - if (MDR) { - P3 = I31(4, 8); - } else { - P3 = I611(4, 5, 7); - } -} break; -case 90 : -{ - if (MDL) { - P2 = I31(4, 6); - } else { - P2 = I611(4, 3, 7); - } - if (MDR) { - P3 = I31(4, 8); - } else { - P3 = I611(4, 5, 7); - } - if (MUL) { - P0 = I31(4, 0); - } else { - P0 = I611(4, 1, 3); - } - if (MUR) { - P1 = I31(4, 2); - } else { - P1 = I611(4, 1, 5); - } -} break; -case 91 : -{ - if (MDL) { - P2 = I31(4, 6); - } else { - P2 = I611(4, 3, 7); - } - if (MDR) { - P3 = I31(4, 8); - } else { - P3 = I611(4, 5, 7); - } - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } - if (MUR) { - P1 = I31(4, 2); - } else { - P1 = I611(4, 1, 5); - } -} break; -case 92 : -{ - P0 = I31(4, 0); - P1 = I31(4, 1); - if (MDL) { - P2 = I31(4, 6); - } else { - P2 = I611(4, 3, 7); - } - if (MDR) { - P3 = I31(4, 8); - } else { - P3 = I611(4, 5, 7); - } -} break; -case 93 : -{ - P0 = I31(4, 1); - P1 = I31(4, 1); - if (MDL) { - P2 = I31(4, 6); - } else { - P2 = I611(4, 3, 7); - } - if (MDR) { - P3 = I31(4, 8); - } else { - P3 = I611(4, 5, 7); - } -} break; -case 94 : -{ - if (MDL) { - P2 = I31(4, 6); - } else { - P2 = I611(4, 3, 7); - } - if (MDR) { - P3 = I31(4, 8); - } else { - P3 = I611(4, 5, 7); - } - if (MUL) { - P0 = I31(4, 0); - } else { - P0 = I611(4, 1, 3); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 96 : -case 97 : -case 100 : -case 101 : -{ - P0 = I211(4, 1, 3); - P1 = I211(4, 1, 5); - P2 = I31(4, 3); - P3 = I31(4, 8); -} break; -case 98 : -{ - P0 = I31(4, 0); - P1 = I31(4, 2); - P2 = I31(4, 3); - P3 = I31(4, 8); -} break; -case 99 : -{ - P0 = I31(4, 3); - P1 = I31(4, 2); - P2 = I31(4, 3); - P3 = I31(4, 8); -} break; -case 102 : -{ - P0 = I31(4, 0); - P1 = I31(4, 5); - P2 = I31(4, 3); - P3 = I31(4, 8); -} break; -case 103 : -{ - P0 = I31(4, 3); - P1 = I31(4, 5); - P2 = I31(4, 3); - P3 = I31(4, 8); -} break; -case 104 : -case 108 : -{ - P0 = I31(4, 0); - P1 = I211(4, 1, 5); - P3 = I31(4, 8); - if (MDL) { - P2 = IC(4); - } else { - P2 = I211(4, 3, 7); - } -} break; -case 105 : -case 109 : -{ - P1 = I211(4, 1, 5); - P3 = I31(4, 8); - if (MDL) { - P0 = I31(4, 1); - P2 = IC(4); - } else { - P0 = I521(4, 3, 1); - P2 = I332(3, 7, 4); - } -} break; -case 106 : -case 120 : -{ - P0 = I31(4, 0); - P1 = I31(4, 2); - P3 = I31(4, 8); - if (MDL) { - P2 = IC(4); - } else { - P2 = I211(4, 3, 7); - } -} break; -case 110 : -{ - P0 = I31(4, 0); - P1 = I31(4, 5); - P3 = I31(4, 8); - if (MDL) { - P2 = IC(4); - } else { - P2 = I211(4, 3, 7); - } -} break; -case 111 : -{ - P1 = I31(4, 5); - P3 = I31(4, 8); - if (MDL) { - P2 = IC(4); - } else { - P2 = I211(4, 3, 7); - } - if (MUL) { - P0 = IC(4); - } else { - P0 = I1411(4, 1, 3); - } -} break; -case 112 : -case 113 : -{ - P0 = I211(4, 1, 3); - P1 = I31(4, 2); - if (MDR) { - P2 = I31(4, 3); - P3 = I31(4, 8); - } else { - P2 = I521(4, 7, 3); - P3 = I332(5, 7, 4); - } -} break; -case 114 : -{ - P0 = I31(4, 0); - P2 = I31(4, 3); - if (MDR) { - P3 = I31(4, 8); - } else { - P3 = I611(4, 5, 7); - } - if (MUR) { - P1 = I31(4, 2); - } else { - P1 = I611(4, 1, 5); - } -} break; -case 115 : -{ - P0 = I31(4, 3); - P2 = I31(4, 3); - if (MDR) { - P3 = I31(4, 8); - } else { - P3 = I611(4, 5, 7); - } - if (MUR) { - P1 = I31(4, 2); - } else { - P1 = I611(4, 1, 5); - } -} break; -case 116 : -case 117 : -{ - P0 = I211(4, 1, 3); - P1 = I31(4, 1); - P2 = I31(4, 3); - if (MDR) { - P3 = I31(4, 8); - } else { - P3 = I611(4, 5, 7); - } -} break; -case 118 : -{ - P0 = I31(4, 0); - P2 = I31(4, 3); - P3 = I31(4, 8); - if (MUR) { - P1 = IC(4); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 119 : -{ - P2 = I31(4, 3); - P3 = I31(4, 8); - if (MUR) { - P0 = I31(4, 3); - P1 = IC(4); - } else { - P0 = I521(4, 1, 3); - P1 = I332(1, 5, 4); - } -} break; -case 121 : -{ - P0 = I31(4, 1); - P1 = I31(4, 2); - if (MDL) { - P2 = IC(4); - } else { - P2 = I211(4, 3, 7); - } - if (MDR) { - P3 = I31(4, 8); - } else { - P3 = I611(4, 5, 7); - } -} break; -case 122 : -{ - if (MDL) { - P2 = IC(4); - } else { - P2 = I211(4, 3, 7); - } - if (MDR) { - P3 = I31(4, 8); - } else { - P3 = I611(4, 5, 7); - } - if (MUL) { - P0 = I31(4, 0); - } else { - P0 = I611(4, 1, 3); - } - if (MUR) { - P1 = I31(4, 2); - } else { - P1 = I611(4, 1, 5); - } -} break; -case 124 : -{ - P0 = I31(4, 0); - P1 = I31(4, 1); - P3 = I31(4, 8); - if (MDL) { - P2 = IC(4); - } else { - P2 = I211(4, 3, 7); - } -} break; -case 125 : -{ - P1 = I31(4, 1); - P3 = I31(4, 8); - if (MDL) { - P0 = I31(4, 1); - P2 = IC(4); - } else { - P0 = I521(4, 3, 1); - P2 = I332(3, 7, 4); - } -} break; -case 126 : -{ - P0 = I31(4, 0); - P3 = I31(4, 8); - if (MDL) { - P2 = IC(4); - } else { - P2 = I211(4, 3, 7); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 127 : -{ - P3 = I31(4, 8); - if (MDL) { - P2 = IC(4); - } else { - P2 = I211(4, 3, 7); - } - if (MUL) { - P0 = IC(4); - } else { - P0 = I1411(4, 1, 3); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 144 : -case 145 : -case 176 : -case 177 : -{ - P0 = I211(4, 1, 3); - P1 = I31(4, 2); - P2 = I211(4, 3, 7); - P3 = I31(4, 7); -} break; -case 146 : -case 178 : -{ - P0 = I31(4, 0); - P2 = I211(4, 3, 7); - if (MUR) { - P1 = I31(4, 2); - P3 = I31(4, 7); - } else { - P1 = I332(1, 5, 4); - P3 = I521(4, 5, 7); - } -} break; -case 147 : -case 179 : -{ - P0 = I31(4, 3); - P2 = I211(4, 3, 7); - P3 = I31(4, 7); - if (MUR) { - P1 = I31(4, 2); - } else { - P1 = I611(4, 1, 5); - } -} break; -case 148 : -case 149 : -case 180 : -case 181 : -{ - P0 = I211(4, 1, 3); - P1 = I31(4, 1); - P2 = I211(4, 3, 7); - P3 = I31(4, 7); -} break; -case 150 : -case 182 : -{ - P0 = I31(4, 0); - P2 = I211(4, 3, 7); - if (MUR) { - P1 = IC(4); - P3 = I31(4, 7); - } else { - P1 = I332(1, 5, 4); - P3 = I521(4, 5, 7); - } -} break; -case 151 : -case 183 : -{ - P0 = I31(4, 3); - P2 = I211(4, 3, 7); - P3 = I31(4, 7); - if (MUR) { - P1 = IC(4); - } else { - P1 = I1411(4, 1, 5); - } -} break; -case 152 : -{ - P0 = I31(4, 0); - P1 = I31(4, 2); - P2 = I31(4, 6); - P3 = I31(4, 7); -} break; -case 153 : -{ - P0 = I31(4, 1); - P1 = I31(4, 2); - P2 = I31(4, 6); - P3 = I31(4, 7); -} break; -case 154 : -{ - P2 = I31(4, 6); - P3 = I31(4, 7); - if (MUL) { - P0 = I31(4, 0); - } else { - P0 = I611(4, 1, 3); - } - if (MUR) { - P1 = I31(4, 2); - } else { - P1 = I611(4, 1, 5); - } -} break; -case 155 : -{ - P1 = I31(4, 2); - P2 = I31(4, 6); - P3 = I31(4, 7); - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } -} break; -case 156 : -{ - P0 = I31(4, 0); - P1 = I31(4, 1); - P2 = I31(4, 6); - P3 = I31(4, 7); -} break; -case 157 : -{ - P0 = I31(4, 1); - P1 = I31(4, 1); - P2 = I31(4, 6); - P3 = I31(4, 7); -} break; -case 158 : -{ - P2 = I31(4, 6); - P3 = I31(4, 7); - if (MUL) { - P0 = I31(4, 0); - } else { - P0 = I611(4, 1, 3); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 159 : -{ - P2 = I31(4, 6); - P3 = I31(4, 7); - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I1411(4, 1, 5); - } -} break; -case 184 : -{ - P0 = I31(4, 0); - P1 = I31(4, 2); - P2 = I31(4, 7); - P3 = I31(4, 7); -} break; -case 185 : -{ - P0 = I31(4, 1); - P1 = I31(4, 2); - P2 = I31(4, 7); - P3 = I31(4, 7); -} break; -case 186 : -{ - P2 = I31(4, 7); - P3 = I31(4, 7); - if (MUL) { - P0 = I31(4, 0); - } else { - P0 = I611(4, 1, 3); - } - if (MUR) { - P1 = I31(4, 2); - } else { - P1 = I611(4, 1, 5); - } -} break; -case 187 : -{ - P1 = I31(4, 2); - P3 = I31(4, 7); - if (MUL) { - P0 = IC(4); - P2 = I31(4, 7); - } else { - P0 = I332(1, 3, 4); - P2 = I521(4, 3, 7); - } -} break; -case 188 : -{ - P0 = I31(4, 0); - P1 = I31(4, 1); - P2 = I31(4, 7); - P3 = I31(4, 7); -} break; -case 189 : -{ - P0 = I31(4, 1); - P1 = I31(4, 1); - P2 = I31(4, 7); - P3 = I31(4, 7); -} break; -case 190 : -{ - P0 = I31(4, 0); - P2 = I31(4, 7); - if (MUR) { - P1 = IC(4); - P3 = I31(4, 7); - } else { - P1 = I332(1, 5, 4); - P3 = I521(4, 5, 7); - } -} break; -case 191 : -{ - P2 = I31(4, 7); - P3 = I31(4, 7); - if (MUL) { - P0 = IC(4); - } else { - P0 = I1411(4, 1, 3); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I1411(4, 1, 5); - } -} break; -case 192 : -case 193 : -case 196 : -case 197 : -{ - P0 = I211(4, 1, 3); - P1 = I211(4, 1, 5); - P2 = I31(4, 6); - P3 = I31(4, 5); -} break; -case 194 : -{ - P0 = I31(4, 0); - P1 = I31(4, 2); - P2 = I31(4, 6); - P3 = I31(4, 5); -} break; -case 195 : -{ - P0 = I31(4, 3); - P1 = I31(4, 2); - P2 = I31(4, 6); - P3 = I31(4, 5); -} break; -case 198 : -{ - P0 = I31(4, 0); - P1 = I31(4, 5); - P2 = I31(4, 6); - P3 = I31(4, 5); -} break; -case 199 : -{ - P0 = I31(4, 3); - P1 = I31(4, 5); - P2 = I31(4, 6); - P3 = I31(4, 5); -} break; -case 200 : -case 204 : -{ - P0 = I31(4, 0); - P1 = I211(4, 1, 5); - if (MDL) { - P2 = I31(4, 6); - P3 = I31(4, 5); - } else { - P2 = I332(3, 7, 4); - P3 = I521(4, 7, 5); - } -} break; -case 201 : -case 205 : -{ - P0 = I31(4, 1); - P1 = I211(4, 1, 5); - P3 = I31(4, 5); - if (MDL) { - P2 = I31(4, 6); - } else { - P2 = I611(4, 3, 7); - } -} break; -case 202 : -{ - P1 = I31(4, 2); - P3 = I31(4, 5); - if (MDL) { - P2 = I31(4, 6); - } else { - P2 = I611(4, 3, 7); - } - if (MUL) { - P0 = I31(4, 0); - } else { - P0 = I611(4, 1, 3); - } -} break; -case 203 : -{ - P1 = I31(4, 2); - P2 = I31(4, 6); - P3 = I31(4, 5); - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } -} break; -case 206 : -{ - P1 = I31(4, 5); - P3 = I31(4, 5); - if (MDL) { - P2 = I31(4, 6); - } else { - P2 = I611(4, 3, 7); - } - if (MUL) { - P0 = I31(4, 0); - } else { - P0 = I611(4, 1, 3); - } -} break; -case 207 : -{ - P2 = I31(4, 6); - P3 = I31(4, 5); - if (MUL) { - P0 = IC(4); - P1 = I31(4, 5); - } else { - P0 = I332(1, 3, 4); - P1 = I521(4, 1, 5); - } -} break; -case 208 : -case 209 : -{ - P0 = I211(4, 1, 3); - P1 = I31(4, 2); - P2 = I31(4, 6); - if (MDR) { - P3 = IC(4); - } else { - P3 = I211(4, 5, 7); - } -} break; -case 210 : -case 216 : -{ - P0 = I31(4, 0); - P1 = I31(4, 2); - P2 = I31(4, 6); - if (MDR) { - P3 = IC(4); - } else { - P3 = I211(4, 5, 7); - } -} break; -case 211 : -{ - P0 = I31(4, 3); - P1 = I31(4, 2); - P2 = I31(4, 6); - if (MDR) { - P3 = IC(4); - } else { - P3 = I211(4, 5, 7); - } -} break; -case 212 : -case 213 : -{ - P0 = I211(4, 1, 3); - P2 = I31(4, 6); - if (MDR) { - P1 = I31(4, 1); - P3 = IC(4); - } else { - P1 = I521(4, 5, 1); - P3 = I332(5, 7, 4); - } -} break; -case 215 : -{ - P0 = I31(4, 3); - P2 = I31(4, 6); - if (MDR) { - P3 = IC(4); - } else { - P3 = I211(4, 5, 7); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I1411(4, 1, 5); - } -} break; -case 217 : -{ - P0 = I31(4, 1); - P1 = I31(4, 2); - P2 = I31(4, 6); - if (MDR) { - P3 = IC(4); - } else { - P3 = I211(4, 5, 7); - } -} break; -case 218 : -{ - if (MDL) { - P2 = I31(4, 6); - } else { - P2 = I611(4, 3, 7); - } - if (MDR) { - P3 = IC(4); - } else { - P3 = I211(4, 5, 7); - } - if (MUL) { - P0 = I31(4, 0); - } else { - P0 = I611(4, 1, 3); - } - if (MUR) { - P1 = I31(4, 2); - } else { - P1 = I611(4, 1, 5); - } -} break; -case 219 : -{ - P1 = I31(4, 2); - P2 = I31(4, 6); - if (MDR) { - P3 = IC(4); - } else { - P3 = I211(4, 5, 7); - } - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } -} break; -case 220 : -{ - P0 = I31(4, 0); - P1 = I31(4, 1); - if (MDL) { - P2 = I31(4, 6); - } else { - P2 = I611(4, 3, 7); - } - if (MDR) { - P3 = IC(4); - } else { - P3 = I211(4, 5, 7); - } -} break; -case 221 : -{ - P0 = I31(4, 1); - P2 = I31(4, 6); - if (MDR) { - P1 = I31(4, 1); - P3 = IC(4); - } else { - P1 = I521(4, 5, 1); - P3 = I332(5, 7, 4); - } -} break; -case 223 : -{ - P2 = I31(4, 6); - if (MDR) { - P3 = IC(4); - } else { - P3 = I211(4, 5, 7); - } - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I1411(4, 1, 5); - } -} break; -case 224 : -case 225 : -case 228 : -case 229 : -{ - P0 = I211(4, 1, 3); - P1 = I211(4, 1, 5); - P2 = I31(4, 3); - P3 = I31(4, 5); -} break; -case 226 : -{ - P0 = I31(4, 0); - P1 = I31(4, 2); - P2 = I31(4, 3); - P3 = I31(4, 5); -} break; -case 227 : -{ - P0 = I31(4, 3); - P1 = I31(4, 2); - P2 = I31(4, 3); - P3 = I31(4, 5); -} break; -case 230 : -{ - P0 = I31(4, 0); - P1 = I31(4, 5); - P2 = I31(4, 3); - P3 = I31(4, 5); -} break; -case 231 : -{ - P0 = I31(4, 3); - P1 = I31(4, 5); - P2 = I31(4, 3); - P3 = I31(4, 5); -} break; -case 232 : -case 236 : -{ - P0 = I31(4, 0); - P1 = I211(4, 1, 5); - if (MDL) { - P2 = IC(4); - P3 = I31(4, 5); - } else { - P2 = I332(3, 7, 4); - P3 = I521(4, 7, 5); - } -} break; -case 233 : -case 237 : -{ - P0 = I31(4, 1); - P1 = I211(4, 1, 5); - P3 = I31(4, 5); - if (MDL) { - P2 = IC(4); - } else { - P2 = I1411(4, 3, 7); - } -} break; -case 234 : -{ - P1 = I31(4, 2); - P3 = I31(4, 5); - if (MDL) { - P2 = IC(4); - } else { - P2 = I211(4, 3, 7); - } - if (MUL) { - P0 = I31(4, 0); - } else { - P0 = I611(4, 1, 3); - } -} break; -case 235 : -{ - P1 = I31(4, 2); - P3 = I31(4, 5); - if (MDL) { - P2 = IC(4); - } else { - P2 = I1411(4, 3, 7); - } - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } -} break; -case 238 : -{ - P0 = I31(4, 0); - P1 = I31(4, 5); - if (MDL) { - P2 = IC(4); - P3 = I31(4, 5); - } else { - P2 = I332(3, 7, 4); - P3 = I521(4, 7, 5); - } -} break; -case 239 : -{ - P1 = I31(4, 5); - P3 = I31(4, 5); - if (MDL) { - P2 = IC(4); - } else { - P2 = I1411(4, 3, 7); - } - if (MUL) { - P0 = IC(4); - } else { - P0 = I1411(4, 1, 3); - } -} break; -case 240 : -case 241 : -{ - P0 = I211(4, 1, 3); - P1 = I31(4, 2); - if (MDR) { - P2 = I31(4, 3); - P3 = IC(4); - } else { - P2 = I521(4, 7, 3); - P3 = I332(5, 7, 4); - } -} break; -case 242 : -{ - P0 = I31(4, 0); - P2 = I31(4, 3); - if (MDR) { - P3 = IC(4); - } else { - P3 = I211(4, 5, 7); - } - if (MUR) { - P1 = I31(4, 2); - } else { - P1 = I611(4, 1, 5); - } -} break; -case 243 : -{ - P0 = I31(4, 3); - P1 = I31(4, 2); - if (MDR) { - P2 = I31(4, 3); - P3 = IC(4); - } else { - P2 = I521(4, 7, 3); - P3 = I332(5, 7, 4); - } -} break; -case 244 : -case 245 : -{ - P0 = I211(4, 1, 3); - P1 = I31(4, 1); - P2 = I31(4, 3); - if (MDR) { - P3 = IC(4); - } else { - P3 = I1411(4, 5, 7); - } -} break; -case 246 : -{ - P0 = I31(4, 0); - P2 = I31(4, 3); - if (MDR) { - P3 = IC(4); - } else { - P3 = I1411(4, 5, 7); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 247 : -{ - P0 = I31(4, 3); - P2 = I31(4, 3); - if (MDR) { - P3 = IC(4); - } else { - P3 = I1411(4, 5, 7); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I1411(4, 1, 5); - } -} break; -case 249 : -{ - P0 = I31(4, 1); - P1 = I31(4, 2); - if (MDL) { - P2 = IC(4); - } else { - P2 = I1411(4, 3, 7); - } - if (MDR) { - P3 = IC(4); - } else { - P3 = I211(4, 5, 7); - } -} break; -case 251 : -{ - P1 = I31(4, 2); - if (MDL) { - P2 = IC(4); - } else { - P2 = I1411(4, 3, 7); - } - if (MDR) { - P3 = IC(4); - } else { - P3 = I211(4, 5, 7); - } - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } -} break; -case 252 : -{ - P0 = I31(4, 0); - P1 = I31(4, 1); - if (MDL) { - P2 = IC(4); - } else { - P2 = I211(4, 3, 7); - } - if (MDR) { - P3 = IC(4); - } else { - P3 = I1411(4, 5, 7); - } -} break; -case 253 : -{ - P0 = I31(4, 1); - P1 = I31(4, 1); - if (MDL) { - P2 = IC(4); - } else { - P2 = I1411(4, 3, 7); - } - if (MDR) { - P3 = IC(4); - } else { - P3 = I1411(4, 5, 7); - } -} break; -case 254 : -{ - P0 = I31(4, 0); - if (MDL) { - P2 = IC(4); - } else { - P2 = I211(4, 3, 7); - } - if (MDR) { - P3 = IC(4); - } else { - P3 = I1411(4, 5, 7); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 255 : -{ - if (MDL) { - P2 = IC(4); - } else { - P2 = I1411(4, 3, 7); - } - if (MDR) { - P3 = IC(4); - } else { - P3 = I1411(4, 5, 7); - } - if (MUL) { - P0 = IC(4); - } else { - P0 = I1411(4, 1, 3); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I1411(4, 1, 5); - } -} break; diff --git a/src/sdl12/filter/interp.h b/src/sdl12/filter/interp.h deleted file mode 100644 index e994387fb8d402e5a7b92bbd6bd77e5bdecfca78..0000000000000000000000000000000000000000 --- a/src/sdl12/filter/interp.h +++ /dev/null @@ -1,306 +0,0 @@ -/* - * This file is part of the Advance project. - * - * Copyright (C) 2003 Andrea Mazzoleni - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * In addition, as a special exception, Andrea Mazzoleni - * gives permission to link the code of this program with - * the MAME library (or with modified versions of MAME that use the - * same license as MAME), and distribute linked combinations including - * the two. You must obey the GNU General Public License in all - * respects for all of the code used other than MAME. If you modify - * this file, you may extend this exception to your version of the - * file, but you are not obligated to do so. If you do not wish to - * do so, delete this exception statement from your version. - */ - -#ifndef __INTERP_H -#define __INTERP_H - -/***************************************************************************/ -/* Basic types */ - -/***************************************************************************/ -/* interpolation */ - -static Uint32 interp_mask[2] = {0xF81F,0x07E0}; -static Uint32 interp_bits_per_pixel = 16; - -#define INTERP_16_MASK_1(v) (v & interp_mask[0]) -#define INTERP_16_MASK_2(v) (v & interp_mask[1]) - -FUNCINLINE static ATTRINLINE Uint16 interp_16_521(Uint16 p1, Uint16 p2, Uint16 p3) -{ - return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*5 + INTERP_16_MASK_1(p2)*2 + INTERP_16_MASK_1(p3)*1) / 8) - | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*5 + INTERP_16_MASK_2(p2)*2 + INTERP_16_MASK_2(p3)*1) / 8)); -} - -FUNCINLINE static ATTRINLINE Uint16 interp_16_332(Uint16 p1, Uint16 p2, Uint16 p3) -{ - return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*3 + INTERP_16_MASK_1(p2)*3 + INTERP_16_MASK_1(p3)*2) / 8) - | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*3 + INTERP_16_MASK_2(p2)*3 + INTERP_16_MASK_2(p3)*2) / 8)); -} - -FUNCINLINE static ATTRINLINE Uint16 interp_16_611(Uint16 p1, Uint16 p2, Uint16 p3) -{ - return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*6 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 8) - | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*6 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 8)); -} - -/* -FUNCINLINE static ATTRINLINE Uint16 interp_16_71(Uint16 p1, Uint16 p2) -{ - return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*7 + INTERP_16_MASK_1(p2)) / 8) - | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*7 + INTERP_16_MASK_2(p2)) / 8)); -} -*/ - -FUNCINLINE static ATTRINLINE Uint16 interp_16_211(Uint16 p1, Uint16 p2, Uint16 p3) -{ - return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*2 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 4) - | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*2 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 4)); -} - -/* -FUNCINLINE static ATTRINLINE Uint16 interp_16_772(Uint16 p1, Uint16 p2, Uint16 p3) -{ - return (Uint16)(INTERP_16_MASK_1(((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2))*7 + INTERP_16_MASK_1(p3)*2) / 16) - | INTERP_16_MASK_2(((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2))*7 + INTERP_16_MASK_2(p3)*2) / 16)); -} - -FUNCINLINE static ATTRINLINE Uint16 interp_16_11(Uint16 p1, Uint16 p2) -{ - return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2)) / 2) - | INTERP_16_MASK_2((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2)) / 2)); -} -*/ - -FUNCINLINE static ATTRINLINE Uint16 interp_16_31(Uint16 p1, Uint16 p2) -{ - return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*3 + INTERP_16_MASK_1(p2)) / 4) - | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*3 + INTERP_16_MASK_2(p2)) / 4)); -} - -FUNCINLINE static ATTRINLINE Uint16 interp_16_1411(Uint16 p1, Uint16 p2, Uint16 p3) -{ - return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*14 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 16) - | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*14 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 16)); -} - -/* -FUNCINLINE static ATTRINLINE Uint16 interp_16_431(Uint16 p1, Uint16 p2, Uint16 p3) -{ - return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*4 + INTERP_16_MASK_1(p2)*3 + INTERP_16_MASK_1(p3)) / 8) - | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*4 + INTERP_16_MASK_2(p2)*3 + INTERP_16_MASK_2(p3)) / 8)); -} - -FUNCINLINE static ATTRINLINE Uint16 interp_16_53(Uint16 p1, Uint16 p2) -{ - return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*5 + INTERP_16_MASK_1(p2)*3) / 8) - | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*5 + INTERP_16_MASK_2(p2)*3) / 8)); -} - -FUNCINLINE static ATTRINLINE Uint16 interp_16_151(Uint16 p1, Uint16 p2) -{ - return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*15 + INTERP_16_MASK_1(p2)) / 16) - | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*15 + INTERP_16_MASK_2(p2)) / 16)); -} - -FUNCINLINE static ATTRINLINE Uint16 interp_16_97(Uint16 p1, Uint16 p2) -{ - return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*9 + INTERP_16_MASK_1(p2)*7) / 16) - | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*9 + INTERP_16_MASK_2(p2)*7) / 16)); -} -*/ - -#define INTERP_32_MASK_1(v) (v & 0xFF00FF) -#define INTERP_32_MASK_2(v) (v & 0x00FF00) - -FUNCINLINE static ATTRINLINE Uint32 interp_32_521(Uint32 p1, Uint32 p2, Uint32 p3) -{ - return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*5 + INTERP_32_MASK_1(p2)*2 + INTERP_32_MASK_1(p3)*1) / 8) - | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*5 + INTERP_32_MASK_2(p2)*2 + INTERP_32_MASK_2(p3)*1) / 8); -} - -FUNCINLINE static ATTRINLINE Uint32 interp_32_332(Uint32 p1, Uint32 p2, Uint32 p3) -{ - return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*3 + INTERP_32_MASK_1(p2)*3 + INTERP_32_MASK_1(p3)*2) / 8) - | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*3 + INTERP_32_MASK_2(p2)*3 + INTERP_32_MASK_2(p3)*2) / 8); -} - -FUNCINLINE static ATTRINLINE Uint32 interp_32_211(Uint32 p1, Uint32 p2, Uint32 p3) -{ - return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*2 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 4) - | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*2 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 4); -} - -FUNCINLINE static ATTRINLINE Uint32 interp_32_611(Uint32 p1, Uint32 p2, Uint32 p3) -{ - return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*6 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 8) - | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*6 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 8); -} - -/* -FUNCINLINE static ATTRINLINE Uint32 interp_32_71(Uint32 p1, Uint32 p2) -{ - return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*7 + INTERP_32_MASK_1(p2)) / 8) - | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*7 + INTERP_32_MASK_2(p2)) / 8); -} - -FUNCINLINE static ATTRINLINE Uint32 interp_32_772(Uint32 p1, Uint32 p2, Uint32 p3) -{ - return INTERP_32_MASK_1(((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2))*7 + INTERP_32_MASK_1(p3)*2) / 16) - | INTERP_32_MASK_2(((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2))*7 + INTERP_32_MASK_2(p3)*2) / 16); -} - -FUNCINLINE static ATTRINLINE Uint32 interp_32_11(Uint32 p1, Uint32 p2) -{ - return INTERP_32_MASK_1((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2)) / 2) - | INTERP_32_MASK_2((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2)) / 2); -} -*/ - -FUNCINLINE static ATTRINLINE Uint32 interp_32_31(Uint32 p1, Uint32 p2) -{ - return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*3 + INTERP_32_MASK_1(p2)) / 4) - | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*3 + INTERP_32_MASK_2(p2)) / 4); -} - -FUNCINLINE static ATTRINLINE Uint32 interp_32_1411(Uint32 p1, Uint32 p2, Uint32 p3) -{ - return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*14 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 16) - | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*14 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 16); -} - -/* -FUNCINLINE static ATTRINLINE Uint32 interp_32_431(Uint32 p1, Uint32 p2, Uint32 p3) -{ - return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*4 + INTERP_32_MASK_1(p2)*3 + INTERP_32_MASK_1(p3)) / 8) - | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*4 + INTERP_32_MASK_2(p2)*3 + INTERP_32_MASK_2(p3)) / 8); -} - -FUNCINLINE static ATTRINLINE Uint32 interp_32_53(Uint32 p1, Uint32 p2) -{ - return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*5 + INTERP_32_MASK_1(p2)*3) / 8) - | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*5 + INTERP_32_MASK_2(p2)*3) / 8); -} - -FUNCINLINE static ATTRINLINE Uint32 interp_32_151(Uint32 p1, Uint32 p2) -{ - return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*15 + INTERP_32_MASK_1(p2)) / 16) - | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*15 + INTERP_32_MASK_2(p2)) / 16); -} - -FUNCINLINE static ATTRINLINE Uint32 interp_32_97(Uint32 p1, Uint32 p2) -{ - return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*9 + INTERP_32_MASK_1(p2)*7) / 16) - | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*9 + INTERP_32_MASK_2(p2)*7) / 16); -} -*/ - -/***************************************************************************/ -/* diff */ - -#define INTERP_Y_LIMIT (0x30*4) -#define INTERP_U_LIMIT (0x07*4) -#define INTERP_V_LIMIT (0x06*8) - -static int interp_16_diff(Uint16 p1, Uint16 p2) -{ - int r, g, b; - int y, u, v; - - if (p1 == p2) - return 0; - - if (interp_bits_per_pixel == 16) { - b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3; - g = (int)((p1 & 0x7E0) - (p2 & 0x7E0)) >> 3; - r = (int)((p1 & 0xF800) - (p2 & 0xF800)) >> 8; - } else { - b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3; - g = (int)((p1 & 0x3E0) - (p2 & 0x3E0)) >> 2; - r = (int)((p1 & 0x7C00) - (p2 & 0x7C00)) >> 7; - } - - y = r + g + b; - u = r - b; - v = -r + 2*g - b; - - if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT) - return 1; - - if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT) - return 1; - - if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT) - return 1; - - return 0; -} - -static int interp_32_diff(Uint32 p1, Uint32 p2) -{ - int r, g, b; - int y, u, v; - - if ((p1 & 0xF8F8F8) == (p2 & 0xF8F8F8)) - return 0; - - b = (int)((p1 & 0xFF) - (p2 & 0xFF)); - g = (int)((p1 & 0xFF00) - (p2 & 0xFF00)) >> 8; - r = (int)((p1 & 0xFF0000) - (p2 & 0xFF0000)) >> 16; - - y = r + g + b; - u = r - b; - v = -r + 2*g - b; - - if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT) - return 1; - - if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT) - return 1; - - if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT) - return 1; - - return 0; -} - -/* -static void interp_set(Uint32 bits_per_pixel) -{ - interp_bits_per_pixel = bits_per_pixel; - - switch (bits_per_pixel) { - case 15 : - interp_mask[0] = 0x7C1F; - interp_mask[1] = 0x03E0; - break; - case 16 : - interp_mask[0] = 0xF81F; - interp_mask[1] = 0x07E0; - break; - case 32 : - interp_mask[0] = 0xFF00FF; - interp_mask[1] = 0x00FF00; - break; - } -} -*/ - -#endif diff --git a/src/sdl12/filter/lq2x.c b/src/sdl12/filter/lq2x.c deleted file mode 100644 index 8d06fa8ccae45a19922bd1768f084d40087d4aac..0000000000000000000000000000000000000000 --- a/src/sdl12/filter/lq2x.c +++ /dev/null @@ -1,564 +0,0 @@ -#include "filters.h" -#include "interp.h" - -static void hq2x_16_def(Uint16* dst0, Uint16* dst1, const Uint16* src0, const Uint16* src1, const Uint16* src2, Uint32 count) -{ - Uint32 i; - - for(i=0;i<count;++i) { - Uint8 mask; - - Uint16 c[9]; - - c[1] = src0[0]; - c[4] = src1[0]; - c[7] = src2[0]; - - if (i>0) { - c[0] = src0[-1]; - c[3] = src1[-1]; - c[6] = src2[-1]; - } else { - c[0] = c[1]; - c[3] = c[4]; - c[6] = c[7]; - } - - if (i<count-1) { - c[2] = src0[1]; - c[5] = src1[1]; - c[8] = src2[1]; - } else { - c[2] = c[1]; - c[5] = c[4]; - c[8] = c[7]; - } - - mask = 0; - - if (interp_16_diff(c[0], c[4])) - mask |= 1 << 0; - if (interp_16_diff(c[1], c[4])) - mask |= 1 << 1; - if (interp_16_diff(c[2], c[4])) - mask |= 1 << 2; - if (interp_16_diff(c[3], c[4])) - mask |= 1 << 3; - if (interp_16_diff(c[5], c[4])) - mask |= 1 << 4; - if (interp_16_diff(c[6], c[4])) - mask |= 1 << 5; - if (interp_16_diff(c[7], c[4])) - mask |= 1 << 6; - if (interp_16_diff(c[8], c[4])) - mask |= 1 << 7; - -#define P0 dst0[0] -#define P1 dst0[1] -#define P2 dst1[0] -#define P3 dst1[1] -#define MUR interp_16_diff(c[1], c[5]) -#define MDR interp_16_diff(c[5], c[7]) -#define MDL interp_16_diff(c[7], c[3]) -#define MUL interp_16_diff(c[3], c[1]) -#define IC(p0) c[p0] -#define I11(p0,p1) interp_16_11(c[p0], c[p1]) -#define I211(p0,p1,p2) interp_16_211(c[p0], c[p1], c[p2]) -#define I31(p0,p1) interp_16_31(c[p0], c[p1]) -#define I332(p0,p1,p2) interp_16_332(c[p0], c[p1], c[p2]) -#define I431(p0,p1,p2) interp_16_431(c[p0], c[p1], c[p2]) -#define I521(p0,p1,p2) interp_16_521(c[p0], c[p1], c[p2]) -#define I53(p0,p1) interp_16_53(c[p0], c[p1]) -#define I611(p0,p1,p2) interp_16_611(c[p0], c[p1], c[p2]) -#define I71(p0,p1) interp_16_71(c[p0], c[p1]) -#define I772(p0,p1,p2) interp_16_772(c[p0], c[p1], c[p2]) -#define I97(p0,p1) interp_16_97(c[p0], c[p1]) -#define I1411(p0,p1,p2) interp_16_1411(c[p0], c[p1], c[p2]) -#define I151(p0,p1) interp_16_151(c[p0], c[p1]) - - switch (mask) { -#include "hq2x.h" - } - -#undef P0 -#undef P1 -#undef P2 -#undef P3 -#undef MUR -#undef MDR -#undef MDL -#undef MUL -#undef IC -#undef I11 -#undef I211 -#undef I31 -#undef I332 -#undef I431 -#undef I521 -#undef I53 -#undef I611 -#undef I71 -#undef I772 -#undef I97 -#undef I1411 -#undef I151 - - src0 += 1; - src1 += 1; - src2 += 1; - dst0 += 2; - dst1 += 2; - } -} - -static void hq2x_32_def(Uint32* dst0, Uint32* dst1, const Uint32* src0, const Uint32* src1, const Uint32* src2, Uint32 count) -{ - Uint32 i; - - for(i=0;i<count;++i) { - Uint8 mask; - - Uint32 c[9]; - - c[1] = src0[0]; - c[4] = src1[0]; - c[7] = src2[0]; - - if (i>0) { - c[0] = src0[-1]; - c[3] = src1[-1]; - c[6] = src2[-1]; - } else { - c[0] = c[1]; - c[3] = c[4]; - c[6] = c[7]; - } - - if (i<count-1) { - c[2] = src0[1]; - c[5] = src1[1]; - c[8] = src2[1]; - } else { - c[2] = c[1]; - c[5] = c[4]; - c[8] = c[7]; - } - - mask = 0; - - if (interp_32_diff(c[0], c[4])) - mask |= 1 << 0; - if (interp_32_diff(c[1], c[4])) - mask |= 1 << 1; - if (interp_32_diff(c[2], c[4])) - mask |= 1 << 2; - if (interp_32_diff(c[3], c[4])) - mask |= 1 << 3; - if (interp_32_diff(c[5], c[4])) - mask |= 1 << 4; - if (interp_32_diff(c[6], c[4])) - mask |= 1 << 5; - if (interp_32_diff(c[7], c[4])) - mask |= 1 << 6; - if (interp_32_diff(c[8], c[4])) - mask |= 1 << 7; - -#define P0 dst0[0] -#define P1 dst0[1] -#define P2 dst1[0] -#define P3 dst1[1] -#define MUR interp_32_diff(c[1], c[5]) -#define MDR interp_32_diff(c[5], c[7]) -#define MDL interp_32_diff(c[7], c[3]) -#define MUL interp_32_diff(c[3], c[1]) -#define IC(p0) c[p0] -#define I11(p0,p1) interp_32_11(c[p0], c[p1]) -#define I211(p0,p1,p2) interp_32_211(c[p0], c[p1], c[p2]) -#define I31(p0,p1) interp_32_31(c[p0], c[p1]) -#define I332(p0,p1,p2) interp_32_332(c[p0], c[p1], c[p2]) -#define I431(p0,p1,p2) interp_32_431(c[p0], c[p1], c[p2]) -#define I521(p0,p1,p2) interp_32_521(c[p0], c[p1], c[p2]) -#define I53(p0,p1) interp_32_53(c[p0], c[p1]) -#define I611(p0,p1,p2) interp_32_611(c[p0], c[p1], c[p2]) -#define I71(p0,p1) interp_32_71(c[p0], c[p1]) -#define I772(p0,p1,p2) interp_32_772(c[p0], c[p1], c[p2]) -#define I97(p0,p1) interp_32_97(c[p0], c[p1]) -#define I1411(p0,p1,p2) interp_32_1411(c[p0], c[p1], c[p2]) -#define I151(p0,p1) interp_32_151(c[p0], c[p1]) - - switch (mask) { -#include "hq2x.h" - } - -#undef P0 -#undef P1 -#undef P2 -#undef P3 -#undef MUR -#undef MDR -#undef MDL -#undef MUL -#undef IC -#undef I11 -#undef I211 -#undef I31 -#undef I332 -#undef I431 -#undef I521 -#undef I53 -#undef I611 -#undef I71 -#undef I772 -#undef I97 -#undef I1411 -#undef I151 - - src0 += 1; - src1 += 1; - src2 += 1; - dst0 += 2; - dst1 += 2; - } -} - -/***************************************************************************/ -/* LQ2x C implementation */ - -/* - * This effect is derived from the hq2x effect made by Maxim Stepin - */ - -static void lq2x_16_def(Uint16* dst0, Uint16* dst1, const Uint16* src0, const Uint16* src1, const Uint16* src2, Uint32 count) -{ - Uint32 i; - - for(i=0;i<count;++i) { - Uint8 mask; - - Uint16 c[9]; - - c[1] = src0[0]; - c[4] = src1[0]; - c[7] = src2[0]; - - if (i>0) { - c[0] = src0[-1]; - c[3] = src1[-1]; - c[6] = src2[-1]; - } else { - c[0] = c[1]; - c[3] = c[4]; - c[6] = c[7]; - } - - if (i<count-1) { - c[2] = src0[1]; - c[5] = src1[1]; - c[8] = src2[1]; - } else { - c[2] = c[1]; - c[5] = c[4]; - c[8] = c[7]; - } - - mask = 0; - - if (c[0] != c[4]) - mask |= 1 << 0; - if (c[1] != c[4]) - mask |= 1 << 1; - if (c[2] != c[4]) - mask |= 1 << 2; - if (c[3] != c[4]) - mask |= 1 << 3; - if (c[5] != c[4]) - mask |= 1 << 4; - if (c[6] != c[4]) - mask |= 1 << 5; - if (c[7] != c[4]) - mask |= 1 << 6; - if (c[8] != c[4]) - mask |= 1 << 7; - -#define P0 dst0[0] -#define P1 dst0[1] -#define P2 dst1[0] -#define P3 dst1[1] -#define MUR (c[1] != c[5]) -#define MDR (c[5] != c[7]) -#define MDL (c[7] != c[3]) -#define MUL (c[3] != c[1]) -#define IC(p0) c[p0] -#define I11(p0,p1) interp_16_11(c[p0], c[p1]) -#define I211(p0,p1,p2) interp_16_211(c[p0], c[p1], c[p2]) -#define I31(p0,p1) interp_16_31(c[p0], c[p1]) -#define I332(p0,p1,p2) interp_16_332(c[p0], c[p1], c[p2]) -#define I431(p0,p1,p2) interp_16_431(c[p0], c[p1], c[p2]) -#define I521(p0,p1,p2) interp_16_521(c[p0], c[p1], c[p2]) -#define I53(p0,p1) interp_16_53(c[p0], c[p1]) -#define I611(p0,p1,p2) interp_16_611(c[p0], c[p1], c[p2]) -#define I71(p0,p1) interp_16_71(c[p0], c[p1]) -#define I772(p0,p1,p2) interp_16_772(c[p0], c[p1], c[p2]) -#define I97(p0,p1) interp_16_97(c[p0], c[p1]) -#define I1411(p0,p1,p2) interp_16_1411(c[p0], c[p1], c[p2]) -#define I151(p0,p1) interp_16_151(c[p0], c[p1]) - - switch (mask) { -#include "lq2x.h" - } - -#undef P0 -#undef P1 -#undef P2 -#undef P3 -#undef MUR -#undef MDR -#undef MDL -#undef MUL -#undef IC -#undef I11 -#undef I211 -#undef I31 -#undef I332 -#undef I431 -#undef I521 -#undef I53 -#undef I611 -#undef I71 -#undef I772 -#undef I97 -#undef I1411 -#undef I151 - - src0 += 1; - src1 += 1; - src2 += 1; - dst0 += 2; - dst1 += 2; - } -} - -static void lq2x_32_def(Uint32* dst0, Uint32* dst1, const Uint32* src0, const Uint32* src1, const Uint32* src2, Uint32 count) -{ - Uint32 i; - - for(i=0;i<count;++i) { - Uint8 mask; - - Uint32 c[9]; - - c[1] = src0[0]; - c[4] = src1[0]; - c[7] = src2[0]; - - if (i>0) { - c[0] = src0[-1]; - c[3] = src1[-1]; - c[6] = src2[-1]; - } else { - c[0] = c[1]; - c[3] = c[4]; - c[6] = c[7]; - } - - if (i<count-1) { - c[2] = src0[1]; - c[5] = src1[1]; - c[8] = src2[1]; - } else { - c[2] = c[1]; - c[5] = c[4]; - c[8] = c[7]; - } - - mask = 0; - - if (c[0] != c[4]) - mask |= 1 << 0; - if (c[1] != c[4]) - mask |= 1 << 1; - if (c[2] != c[4]) - mask |= 1 << 2; - if (c[3] != c[4]) - mask |= 1 << 3; - if (c[5] != c[4]) - mask |= 1 << 4; - if (c[6] != c[4]) - mask |= 1 << 5; - if (c[7] != c[4]) - mask |= 1 << 6; - if (c[8] != c[4]) - mask |= 1 << 7; - -#define P0 dst0[0] -#define P1 dst0[1] -#define P2 dst1[0] -#define P3 dst1[1] -#define MUR (c[1] != c[5]) -#define MDR (c[5] != c[7]) -#define MDL (c[7] != c[3]) -#define MUL (c[3] != c[1]) -#define IC(p0) c[p0] -#define I11(p0,p1) interp_32_11(c[p0], c[p1]) -#define I211(p0,p1,p2) interp_32_211(c[p0], c[p1], c[p2]) -#define I31(p0,p1) interp_32_31(c[p0], c[p1]) -#define I332(p0,p1,p2) interp_32_332(c[p0], c[p1], c[p2]) -#define I431(p0,p1,p2) interp_32_431(c[p0], c[p1], c[p2]) -#define I521(p0,p1,p2) interp_32_521(c[p0], c[p1], c[p2]) -#define I53(p0,p1) interp_32_53(c[p0], c[p1]) -#define I611(p0,p1,p2) interp_32_611(c[p0], c[p1], c[p2]) -#define I71(p0,p1) interp_32_71(c[p0], c[p1]) -#define I772(p0,p1,p2) interp_32_772(c[p0], c[p1], c[p2]) -#define I97(p0,p1) interp_32_97(c[p0], c[p1]) -#define I1411(p0,p1,p2) interp_32_1411(c[p0], c[p1], c[p2]) -#define I151(p0,p1) interp_32_151(c[p0], c[p1]) - - switch (mask) { -#include "lq2x.h" - } - -#undef P0 -#undef P1 -#undef P2 -#undef P3 -#undef MUR -#undef MDR -#undef MDL -#undef MUL -#undef IC -#undef I11 -#undef I211 -#undef I31 -#undef I332 -#undef I431 -#undef I521 -#undef I53 -#undef I611 -#undef I71 -#undef I772 -#undef I97 -#undef I1411 -#undef I151 - - src0 += 1; - src1 += 1; - src2 += 1; - dst0 += 2; - dst1 += 2; - } -} - -void hq2x16(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, - Uint32 dstPitch, int width, int height) -{ - Uint16 *dst0 = (Uint16 *)dstPtr; - Uint16 *dst1 = dst0 + (dstPitch >> 1); - - Uint16 *src0 = (Uint16 *)srcPtr; - Uint16 *src1 = src0 + (srcPitch >> 1); - Uint16 *src2 = src1 + (srcPitch >> 1); - int count = height-2; - - hq2x_16_def(dst0, dst1, src0, src0, src1, width); - - while(count) { - dst0 += dstPitch; - dst1 += dstPitch; - hq2x_16_def(dst0, dst1, src0, src1, src2, width); - src0 = src1; - src1 = src2; - src2 += srcPitch >> 1; - --count; - } - dst0 += dstPitch; - dst1 += dstPitch; - hq2x_16_def(dst0, dst1, src0, src1, src1, width); -} - -void hq2x32(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, - Uint32 dstPitch, int width, int height) -{ - Uint32 *dst0 = (Uint32 *)dstPtr; - Uint32 *dst1 = dst0 + (dstPitch >> 2); - - Uint32 *src0 = (Uint32 *)srcPtr; - Uint32 *src1 = src0 + (srcPitch >> 2); - Uint32 *src2 = src1 + (srcPitch >> 2); - int count = height-2; - - hq2x_32_def(dst0, dst1, src0, src0, src1, width); - - while(count) { - dst0 += dstPitch >> 1; - dst1 += dstPitch >> 1; - hq2x_32_def(dst0, dst1, src0, src1, src2, width); - src0 = src1; - src1 = src2; - src2 += srcPitch >> 2; - --count; - } - dst0 += dstPitch >> 1; - dst1 += dstPitch >> 1; - hq2x_32_def(dst0, dst1, src0, src1, src1, width); -} - -void lq2x16(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, - Uint32 dstPitch, int width, int height) -{ - Uint16 *dst0 = (Uint16 *)dstPtr; - Uint16 *dst1 = dst0 + (dstPitch >> 1); - - Uint16 *src0 = (Uint16 *)srcPtr; - Uint16 *src1 = src0 + (srcPitch >> 1); - Uint16 *src2 = src1 + (srcPitch >> 1); - int count = height-2; - - lq2x_16_def(dst0, dst1, src0, src0, src1, width); - - while(count) { - dst0 += dstPitch; - dst1 += dstPitch; - lq2x_16_def(dst0, dst1, src0, src1, src2, width); - src0 = src1; - src1 = src2; - src2 += srcPitch >> 1; - --count; - } - dst0 += dstPitch; - dst1 += dstPitch; - lq2x_16_def(dst0, dst1, src0, src1, src1, width); -} - -void lq2x32(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, - Uint32 dstPitch, int width, int height) -{ - Uint32 *dst0 = (Uint32 *)dstPtr; - Uint32 *dst1 = dst0 + (dstPitch >> 2); - - Uint32 *src0 = (Uint32 *)srcPtr; - Uint32 *src1 = src0 + (srcPitch >> 2); - Uint32 *src2 = src1 + (srcPitch >> 2); - int count = height-2; - - lq2x_32_def(dst0, dst1, src0, src0, src1, width); - - while(count) { - dst0 += dstPitch >> 1; - dst1 += dstPitch >> 1; - lq2x_32_def(dst0, dst1, src0, src1, src2, width); - src0 = src1; - src1 = src2; - src2 += srcPitch >> 2; - --count; - } - dst0 += dstPitch >> 1; - dst1 += dstPitch >> 1; - lq2x_32_def(dst0, dst1, src0, src1, src1, width); -} - -/* -static inline void hq2x_init(Uint32 bits_per_pixel) -{ - interp_set(bits_per_pixel); -} -*/ diff --git a/src/sdl12/filter/lq2x.h b/src/sdl12/filter/lq2x.h deleted file mode 100644 index 094c2b5aeef069bca6afb9efcb8ce270ea2b887a..0000000000000000000000000000000000000000 --- a/src/sdl12/filter/lq2x.h +++ /dev/null @@ -1,1284 +0,0 @@ -case 0 : -case 2 : -case 4 : -case 6 : -case 8 : -case 12 : -case 16 : -case 20 : -case 24 : -case 28 : -case 32 : -case 34 : -case 36 : -case 38 : -case 40 : -case 44 : -case 48 : -case 52 : -case 56 : -case 60 : -case 64 : -case 66 : -case 68 : -case 70 : -case 96 : -case 98 : -case 100 : -case 102 : -case 128 : -case 130 : -case 132 : -case 134 : -case 136 : -case 140 : -case 144 : -case 148 : -case 152 : -case 156 : -case 160 : -case 162 : -case 164 : -case 166 : -case 168 : -case 172 : -case 176 : -case 180 : -case 184 : -case 188 : -case 192 : -case 194 : -case 196 : -case 198 : -case 224 : -case 226 : -case 228 : -case 230 : -{ - P0 = IC(0); - P1 = IC(0); - P2 = IC(0); - P3 = IC(0); -} break; -case 1 : -case 5 : -case 9 : -case 13 : -case 17 : -case 21 : -case 25 : -case 29 : -case 33 : -case 37 : -case 41 : -case 45 : -case 49 : -case 53 : -case 57 : -case 61 : -case 65 : -case 69 : -case 97 : -case 101 : -case 129 : -case 133 : -case 137 : -case 141 : -case 145 : -case 149 : -case 153 : -case 157 : -case 161 : -case 165 : -case 169 : -case 173 : -case 177 : -case 181 : -case 185 : -case 189 : -case 193 : -case 197 : -case 225 : -case 229 : -{ - P0 = IC(1); - P1 = IC(1); - P2 = IC(1); - P3 = IC(1); -} break; -case 3 : -case 35 : -case 67 : -case 99 : -case 131 : -case 163 : -case 195 : -case 227 : -{ - P0 = IC(2); - P1 = IC(2); - P2 = IC(2); - P3 = IC(2); -} break; -case 7 : -case 39 : -case 71 : -case 103 : -case 135 : -case 167 : -case 199 : -case 231 : -{ - P0 = IC(3); - P1 = IC(3); - P2 = IC(3); - P3 = IC(3); -} break; -case 10 : -case 138 : -{ - P1 = IC(0); - P2 = IC(0); - P3 = IC(0); - if (MUL) { - P0 = IC(0); - } else { - P0 = I211(0, 1, 3); - } -} break; -case 11 : -case 27 : -case 75 : -case 139 : -case 155 : -case 203 : -{ - P1 = IC(2); - P2 = IC(2); - P3 = IC(2); - if (MUL) { - P0 = IC(2); - } else { - P0 = I211(2, 1, 3); - } -} break; -case 14 : -case 142 : -{ - P2 = IC(0); - P3 = IC(0); - if (MUL) { - P0 = IC(0); - P1 = IC(0); - } else { - P0 = I332(1, 3, 0); - P1 = I31(0, 1); - } -} break; -case 15 : -case 143 : -case 207 : -{ - P2 = IC(4); - P3 = IC(4); - if (MUL) { - P0 = IC(4); - P1 = IC(4); - } else { - P0 = I332(1, 3, 4); - P1 = I31(4, 1); - } -} break; -case 18 : -case 22 : -case 30 : -case 50 : -case 54 : -case 62 : -case 86 : -case 118 : -{ - P0 = IC(0); - P2 = IC(0); - P3 = IC(0); - if (MUR) { - P1 = IC(0); - } else { - P1 = I211(0, 1, 5); - } -} break; -case 19 : -case 51 : -{ - P2 = IC(2); - P3 = IC(2); - if (MUR) { - P0 = IC(2); - P1 = IC(2); - } else { - P0 = I31(2, 1); - P1 = I332(1, 5, 2); - } -} break; -case 23 : -case 55 : -case 119 : -{ - P2 = IC(3); - P3 = IC(3); - if (MUR) { - P0 = IC(3); - P1 = IC(3); - } else { - P0 = I31(3, 1); - P1 = I332(1, 5, 3); - } -} break; -case 26 : -{ - P2 = IC(0); - P3 = IC(0); - if (MUL) { - P0 = IC(0); - } else { - P0 = I211(0, 1, 3); - } - if (MUR) { - P1 = IC(0); - } else { - P1 = I211(0, 1, 5); - } -} break; -case 31 : -case 95 : -{ - P2 = IC(4); - P3 = IC(4); - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 42 : -case 170 : -{ - P1 = IC(0); - P3 = IC(0); - if (MUL) { - P0 = IC(0); - P2 = IC(0); - } else { - P0 = I332(1, 3, 0); - P2 = I31(0, 3); - } -} break; -case 43 : -case 171 : -case 187 : -{ - P1 = IC(2); - P3 = IC(2); - if (MUL) { - P0 = IC(2); - P2 = IC(2); - } else { - P0 = I332(1, 3, 2); - P2 = I31(2, 3); - } -} break; -case 46 : -case 174 : -{ - P1 = IC(0); - P2 = IC(0); - P3 = IC(0); - if (MUL) { - P0 = IC(0); - } else { - P0 = I611(0, 1, 3); - } -} break; -case 47 : -case 175 : -{ - P1 = IC(4); - P2 = IC(4); - P3 = IC(4); - if (MUL) { - P0 = IC(4); - } else { - P0 = I1411(4, 1, 3); - } -} break; -case 58 : -case 154 : -case 186 : -{ - P2 = IC(0); - P3 = IC(0); - if (MUL) { - P0 = IC(0); - } else { - P0 = I611(0, 1, 3); - } - if (MUR) { - P1 = IC(0); - } else { - P1 = I611(0, 1, 5); - } -} break; -case 59 : -{ - P2 = IC(2); - P3 = IC(2); - if (MUL) { - P0 = IC(2); - } else { - P0 = I211(2, 1, 3); - } - if (MUR) { - P1 = IC(2); - } else { - P1 = I611(2, 1, 5); - } -} break; -case 63 : -{ - P2 = IC(4); - P3 = IC(4); - if (MUL) { - P0 = IC(4); - } else { - P0 = I1411(4, 1, 3); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 72 : -case 76 : -case 104 : -case 106 : -case 108 : -case 110 : -case 120 : -case 124 : -{ - P0 = IC(0); - P1 = IC(0); - P3 = IC(0); - if (MDL) { - P2 = IC(0); - } else { - P2 = I211(0, 3, 7); - } -} break; -case 73 : -case 77 : -case 105 : -case 109 : -case 125 : -{ - P1 = IC(1); - P3 = IC(1); - if (MDL) { - P0 = IC(1); - P2 = IC(1); - } else { - P0 = I31(1, 3); - P2 = I332(3, 7, 1); - } -} break; -case 74 : -{ - P1 = IC(0); - P3 = IC(0); - if (MDL) { - P2 = IC(0); - } else { - P2 = I211(0, 3, 7); - } - if (MUL) { - P0 = IC(0); - } else { - P0 = I211(0, 1, 3); - } -} break; -case 78 : -case 202 : -case 206 : -{ - P1 = IC(0); - P3 = IC(0); - if (MDL) { - P2 = IC(0); - } else { - P2 = I611(0, 3, 7); - } - if (MUL) { - P0 = IC(0); - } else { - P0 = I611(0, 1, 3); - } -} break; -case 79 : -{ - P1 = IC(4); - P3 = IC(4); - if (MDL) { - P2 = IC(4); - } else { - P2 = I611(4, 3, 7); - } - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } -} break; -case 80 : -case 208 : -case 210 : -case 216 : -{ - P0 = IC(0); - P1 = IC(0); - P2 = IC(0); - if (MDR) { - P3 = IC(0); - } else { - P3 = I211(0, 5, 7); - } -} break; -case 81 : -case 209 : -case 217 : -{ - P0 = IC(1); - P1 = IC(1); - P2 = IC(1); - if (MDR) { - P3 = IC(1); - } else { - P3 = I211(1, 5, 7); - } -} break; -case 82 : -case 214 : -case 222 : -{ - P0 = IC(0); - P2 = IC(0); - if (MDR) { - P3 = IC(0); - } else { - P3 = I211(0, 5, 7); - } - if (MUR) { - P1 = IC(0); - } else { - P1 = I211(0, 1, 5); - } -} break; -case 83 : -case 115 : -{ - P0 = IC(2); - P2 = IC(2); - if (MDR) { - P3 = IC(2); - } else { - P3 = I611(2, 5, 7); - } - if (MUR) { - P1 = IC(2); - } else { - P1 = I611(2, 1, 5); - } -} break; -case 84 : -case 212 : -{ - P0 = IC(0); - P2 = IC(0); - if (MDR) { - P1 = IC(0); - P3 = IC(0); - } else { - P1 = I31(0, 5); - P3 = I332(5, 7, 0); - } -} break; -case 85 : -case 213 : -case 221 : -{ - P0 = IC(1); - P2 = IC(1); - if (MDR) { - P1 = IC(1); - P3 = IC(1); - } else { - P1 = I31(1, 5); - P3 = I332(5, 7, 1); - } -} break; -case 87 : -{ - P0 = IC(3); - P2 = IC(3); - if (MDR) { - P3 = IC(3); - } else { - P3 = I611(3, 5, 7); - } - if (MUR) { - P1 = IC(3); - } else { - P1 = I211(3, 1, 5); - } -} break; -case 88 : -case 248 : -case 250 : -{ - P0 = IC(0); - P1 = IC(0); - if (MDL) { - P2 = IC(0); - } else { - P2 = I211(0, 3, 7); - } - if (MDR) { - P3 = IC(0); - } else { - P3 = I211(0, 5, 7); - } -} break; -case 89 : -case 93 : -{ - P0 = IC(1); - P1 = IC(1); - if (MDL) { - P2 = IC(1); - } else { - P2 = I611(1, 3, 7); - } - if (MDR) { - P3 = IC(1); - } else { - P3 = I611(1, 5, 7); - } -} break; -case 90 : -{ - if (MDL) { - P2 = IC(0); - } else { - P2 = I611(0, 3, 7); - } - if (MDR) { - P3 = IC(0); - } else { - P3 = I611(0, 5, 7); - } - if (MUL) { - P0 = IC(0); - } else { - P0 = I611(0, 1, 3); - } - if (MUR) { - P1 = IC(0); - } else { - P1 = I611(0, 1, 5); - } -} break; -case 91 : -{ - if (MDL) { - P2 = IC(2); - } else { - P2 = I611(2, 3, 7); - } - if (MDR) { - P3 = IC(2); - } else { - P3 = I611(2, 5, 7); - } - if (MUL) { - P0 = IC(2); - } else { - P0 = I211(2, 1, 3); - } - if (MUR) { - P1 = IC(2); - } else { - P1 = I611(2, 1, 5); - } -} break; -case 92 : -{ - P0 = IC(0); - P1 = IC(0); - if (MDL) { - P2 = IC(0); - } else { - P2 = I611(0, 3, 7); - } - if (MDR) { - P3 = IC(0); - } else { - P3 = I611(0, 5, 7); - } -} break; -case 94 : -{ - if (MDL) { - P2 = IC(0); - } else { - P2 = I611(0, 3, 7); - } - if (MDR) { - P3 = IC(0); - } else { - P3 = I611(0, 5, 7); - } - if (MUL) { - P0 = IC(0); - } else { - P0 = I611(0, 1, 3); - } - if (MUR) { - P1 = IC(0); - } else { - P1 = I211(0, 1, 5); - } -} break; -case 107 : -case 123 : -{ - P1 = IC(2); - P3 = IC(2); - if (MDL) { - P2 = IC(2); - } else { - P2 = I211(2, 3, 7); - } - if (MUL) { - P0 = IC(2); - } else { - P0 = I211(2, 1, 3); - } -} break; -case 111 : -{ - P1 = IC(4); - P3 = IC(4); - if (MDL) { - P2 = IC(4); - } else { - P2 = I211(4, 3, 7); - } - if (MUL) { - P0 = IC(4); - } else { - P0 = I1411(4, 1, 3); - } -} break; -case 112 : -case 240 : -{ - P0 = IC(0); - P1 = IC(0); - if (MDR) { - P2 = IC(0); - P3 = IC(0); - } else { - P2 = I31(0, 7); - P3 = I332(5, 7, 0); - } -} break; -case 113 : -case 241 : -{ - P0 = IC(1); - P1 = IC(1); - if (MDR) { - P2 = IC(1); - P3 = IC(1); - } else { - P2 = I31(1, 7); - P3 = I332(5, 7, 1); - } -} break; -case 114 : -{ - P0 = IC(0); - P2 = IC(0); - if (MDR) { - P3 = IC(0); - } else { - P3 = I611(0, 5, 7); - } - if (MUR) { - P1 = IC(0); - } else { - P1 = I611(0, 1, 5); - } -} break; -case 116 : -{ - P0 = IC(0); - P1 = IC(0); - P2 = IC(0); - if (MDR) { - P3 = IC(0); - } else { - P3 = I611(0, 5, 7); - } -} break; -case 117 : -{ - P0 = IC(1); - P1 = IC(1); - P2 = IC(1); - if (MDR) { - P3 = IC(1); - } else { - P3 = I611(1, 5, 7); - } -} break; -case 121 : -{ - P0 = IC(1); - P1 = IC(1); - if (MDL) { - P2 = IC(1); - } else { - P2 = I211(1, 3, 7); - } - if (MDR) { - P3 = IC(1); - } else { - P3 = I611(1, 5, 7); - } -} break; -case 122 : -{ - if (MDL) { - P2 = IC(0); - } else { - P2 = I211(0, 3, 7); - } - if (MDR) { - P3 = IC(0); - } else { - P3 = I611(0, 5, 7); - } - if (MUL) { - P0 = IC(0); - } else { - P0 = I611(0, 1, 3); - } - if (MUR) { - P1 = IC(0); - } else { - P1 = I611(0, 1, 5); - } -} break; -case 126 : -{ - P0 = IC(0); - P3 = IC(0); - if (MDL) { - P2 = IC(0); - } else { - P2 = I211(0, 3, 7); - } - if (MUR) { - P1 = IC(0); - } else { - P1 = I211(0, 1, 5); - } -} break; -case 127 : -{ - P3 = IC(4); - if (MDL) { - P2 = IC(4); - } else { - P2 = I211(4, 3, 7); - } - if (MUL) { - P0 = IC(4); - } else { - P0 = I1411(4, 1, 3); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I211(4, 1, 5); - } -} break; -case 146 : -case 150 : -case 178 : -case 182 : -case 190 : -{ - P0 = IC(0); - P2 = IC(0); - if (MUR) { - P1 = IC(0); - P3 = IC(0); - } else { - P1 = I332(1, 5, 0); - P3 = I31(0, 5); - } -} break; -case 147 : -case 179 : -{ - P0 = IC(2); - P2 = IC(2); - P3 = IC(2); - if (MUR) { - P1 = IC(2); - } else { - P1 = I611(2, 1, 5); - } -} break; -case 151 : -case 183 : -{ - P0 = IC(3); - P2 = IC(3); - P3 = IC(3); - if (MUR) { - P1 = IC(3); - } else { - P1 = I1411(3, 1, 5); - } -} break; -case 158 : -{ - P2 = IC(0); - P3 = IC(0); - if (MUL) { - P0 = IC(0); - } else { - P0 = I611(0, 1, 3); - } - if (MUR) { - P1 = IC(0); - } else { - P1 = I211(0, 1, 5); - } -} break; -case 159 : -{ - P2 = IC(4); - P3 = IC(4); - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I1411(4, 1, 5); - } -} break; -case 191 : -{ - P2 = IC(4); - P3 = IC(4); - if (MUL) { - P0 = IC(4); - } else { - P0 = I1411(4, 1, 3); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I1411(4, 1, 5); - } -} break; -case 200 : -case 204 : -case 232 : -case 236 : -case 238 : -{ - P0 = IC(0); - P1 = IC(0); - if (MDL) { - P2 = IC(0); - P3 = IC(0); - } else { - P2 = I332(3, 7, 0); - P3 = I31(0, 7); - } -} break; -case 201 : -case 205 : -{ - P0 = IC(1); - P1 = IC(1); - P3 = IC(1); - if (MDL) { - P2 = IC(1); - } else { - P2 = I611(1, 3, 7); - } -} break; -case 211 : -{ - P0 = IC(2); - P1 = IC(2); - P2 = IC(2); - if (MDR) { - P3 = IC(2); - } else { - P3 = I211(2, 5, 7); - } -} break; -case 215 : -{ - P0 = IC(3); - P2 = IC(3); - if (MDR) { - P3 = IC(3); - } else { - P3 = I211(3, 5, 7); - } - if (MUR) { - P1 = IC(3); - } else { - P1 = I1411(3, 1, 5); - } -} break; -case 218 : -{ - if (MDL) { - P2 = IC(0); - } else { - P2 = I611(0, 3, 7); - } - if (MDR) { - P3 = IC(0); - } else { - P3 = I211(0, 5, 7); - } - if (MUL) { - P0 = IC(0); - } else { - P0 = I611(0, 1, 3); - } - if (MUR) { - P1 = IC(0); - } else { - P1 = I611(0, 1, 5); - } -} break; -case 219 : -{ - P1 = IC(2); - P2 = IC(2); - if (MDR) { - P3 = IC(2); - } else { - P3 = I211(2, 5, 7); - } - if (MUL) { - P0 = IC(2); - } else { - P0 = I211(2, 1, 3); - } -} break; -case 220 : -{ - P0 = IC(0); - P1 = IC(0); - if (MDL) { - P2 = IC(0); - } else { - P2 = I611(0, 3, 7); - } - if (MDR) { - P3 = IC(0); - } else { - P3 = I211(0, 5, 7); - } -} break; -case 223 : -{ - P2 = IC(4); - if (MDR) { - P3 = IC(4); - } else { - P3 = I211(4, 5, 7); - } - if (MUL) { - P0 = IC(4); - } else { - P0 = I211(4, 1, 3); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I1411(4, 1, 5); - } -} break; -case 233 : -case 237 : -{ - P0 = IC(1); - P1 = IC(1); - P3 = IC(1); - if (MDL) { - P2 = IC(1); - } else { - P2 = I1411(1, 3, 7); - } -} break; -case 234 : -{ - P1 = IC(0); - P3 = IC(0); - if (MDL) { - P2 = IC(0); - } else { - P2 = I211(0, 3, 7); - } - if (MUL) { - P0 = IC(0); - } else { - P0 = I611(0, 1, 3); - } -} break; -case 235 : -{ - P1 = IC(2); - P3 = IC(2); - if (MDL) { - P2 = IC(2); - } else { - P2 = I1411(2, 3, 7); - } - if (MUL) { - P0 = IC(2); - } else { - P0 = I211(2, 1, 3); - } -} break; -case 239 : -{ - P1 = IC(4); - P3 = IC(4); - if (MDL) { - P2 = IC(4); - } else { - P2 = I1411(4, 3, 7); - } - if (MUL) { - P0 = IC(4); - } else { - P0 = I1411(4, 1, 3); - } -} break; -case 242 : -{ - P0 = IC(0); - P2 = IC(0); - if (MDR) { - P3 = IC(0); - } else { - P3 = I211(0, 5, 7); - } - if (MUR) { - P1 = IC(0); - } else { - P1 = I611(0, 1, 5); - } -} break; -case 243 : -{ - P0 = IC(2); - P1 = IC(2); - if (MDR) { - P2 = IC(2); - P3 = IC(2); - } else { - P2 = I31(2, 7); - P3 = I332(5, 7, 2); - } -} break; -case 244 : -{ - P0 = IC(0); - P1 = IC(0); - P2 = IC(0); - if (MDR) { - P3 = IC(0); - } else { - P3 = I1411(0, 5, 7); - } -} break; -case 245 : -{ - P0 = IC(1); - P1 = IC(1); - P2 = IC(1); - if (MDR) { - P3 = IC(1); - } else { - P3 = I1411(1, 5, 7); - } -} break; -case 246 : -{ - P0 = IC(0); - P2 = IC(0); - if (MDR) { - P3 = IC(0); - } else { - P3 = I1411(0, 5, 7); - } - if (MUR) { - P1 = IC(0); - } else { - P1 = I211(0, 1, 5); - } -} break; -case 247 : -{ - P0 = IC(3); - P2 = IC(3); - if (MDR) { - P3 = IC(3); - } else { - P3 = I1411(3, 5, 7); - } - if (MUR) { - P1 = IC(3); - } else { - P1 = I1411(3, 1, 5); - } -} break; -case 249 : -{ - P0 = IC(1); - P1 = IC(1); - if (MDL) { - P2 = IC(1); - } else { - P2 = I1411(1, 3, 7); - } - if (MDR) { - P3 = IC(1); - } else { - P3 = I211(1, 5, 7); - } -} break; -case 251 : -{ - P1 = IC(2); - if (MDL) { - P2 = IC(2); - } else { - P2 = I1411(2, 3, 7); - } - if (MDR) { - P3 = IC(2); - } else { - P3 = I211(2, 5, 7); - } - if (MUL) { - P0 = IC(2); - } else { - P0 = I211(2, 1, 3); - } -} break; -case 252 : -{ - P0 = IC(0); - P1 = IC(0); - if (MDL) { - P2 = IC(0); - } else { - P2 = I211(0, 3, 7); - } - if (MDR) { - P3 = IC(0); - } else { - P3 = I1411(0, 5, 7); - } -} break; -case 253 : -{ - P0 = IC(1); - P1 = IC(1); - if (MDL) { - P2 = IC(1); - } else { - P2 = I1411(1, 3, 7); - } - if (MDR) { - P3 = IC(1); - } else { - P3 = I1411(1, 5, 7); - } -} break; -case 254 : -{ - P0 = IC(0); - if (MDL) { - P2 = IC(0); - } else { - P2 = I211(0, 3, 7); - } - if (MDR) { - P3 = IC(0); - } else { - P3 = I1411(0, 5, 7); - } - if (MUR) { - P1 = IC(0); - } else { - P1 = I211(0, 1, 5); - } -} break; -case 255 : -{ - if (MDL) { - P2 = IC(4); - } else { - P2 = I1411(4, 3, 7); - } - if (MDR) { - P3 = IC(4); - } else { - P3 = I1411(4, 5, 7); - } - if (MUL) { - P0 = IC(4); - } else { - P0 = I1411(4, 1, 3); - } - if (MUR) { - P1 = IC(4); - } else { - P1 = I1411(4, 1, 5); - } -} break; diff --git a/src/sdl12/filter/main.c b/src/sdl12/filter/main.c deleted file mode 100644 index 98ab1541c9539eeb3473ea38d6c1df595e007da3..0000000000000000000000000000000000000000 --- a/src/sdl12/filter/main.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "filters.h" - -int main(int argc, char *argv[]) -{ - SDL_Surface *src = NULL; - SDL_Surface *dst = NULL; - src = SDL_LoadBMP("src.bmp"); //load - if(!src) return -1; //check - dst = filter_2x(src, NULL, hq2x32); //prcoess - SDL_FreeSurface(src); //free - if(!dst) return 0; //error - SDL_SaveBMP(dst, "dst.bmp"); //save - SDL_FreeSurface(dst); //free - return 1; //good -} diff --git a/src/sdl12/hwsym_sdl.c b/src/sdl12/hwsym_sdl.c deleted file mode 100644 index 49340138f46bc5a98223f8895fd175b18ccad18d..0000000000000000000000000000000000000000 --- a/src/sdl12/hwsym_sdl.c +++ /dev/null @@ -1,186 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -/// \file -/// \brief Tool for dynamic referencing of hardware rendering functions -/// -/// Declaration and definition of the HW rendering -/// functions do have the same name. Originally, the -/// implementation was stored in a separate library. -/// For SDL, we need some function to return the addresses, -/// otherwise we have a conflict with the compiler. - -#include "hwsym_sdl.h" -#include "../doomdef.h" - -#ifdef _MSC_VER -#pragma warning(disable : 4214 4244) -#endif - -#ifdef HAVE_SDL - -#include "SDL.h" - -#ifdef _MSC_VER -#pragma warning(default : 4214 4244) -#endif - -#if defined (_XBOX) || defined (_arch_dreamcast) || defined(GP2X) -#define NOLOADSO -#endif - -#if SDL_VERSION_ATLEAST(1,2,6) && !defined (NOLOADSO) -#include "SDL_loadso.h" // 1.2.6+ -#elif !defined (NOLOADSO) -#define NOLOADSO -#endif - -#define _CREATE_DLL_ // necessary for Unix AND Windows - -#ifdef HWRENDER -#include "../hardware/hw_drv.h" -#include "ogl_sdl.h" -#ifdef STATIC_OPENGL -#include "../hardware/r_opengl/r_opengl.h" -#endif -#endif - -#ifdef HW3SOUND -#include "../hardware/hw3dsdrv.h" -#endif - -#define GETFUNC(func) \ - else if (0 == strcmp(#func, funcName)) \ - funcPointer = &func \ -// -// -/** \brief The *hwSym function - - Stupid function to return function addresses - - \param funcName the name of the function - \param handle an object to look in(NULL for self) - - \return void -*/ -// -void *hwSym(const char *funcName,void *handle) -{ - void *funcPointer = NULL; -#ifdef HWRENDER - if (0 == strcmp("SetPalette", funcName)) - funcPointer = &OglSdlSetPalette; - GETFUNC(Init); - GETFUNC(Draw2DLine); - GETFUNC(DrawPolygon); - GETFUNC(SetBlend); - GETFUNC(ClearBuffer); - GETFUNC(SetTexture); - GETFUNC(ReadRect); - GETFUNC(GClipRect); - GETFUNC(ClearMipMapCache); - GETFUNC(SetSpecialState); - GETFUNC(GetTextureUsed); - GETFUNC(DrawMD2); - GETFUNC(DrawMD2i); - GETFUNC(SetTransform); - GETFUNC(GetRenderVersion); -#ifdef SHUFFLE - GETFUNC(PostImgRedraw); -#endif //SHUFFLE - GETFUNC(FlushScreenTextures); - GETFUNC(StartScreenWipe); - GETFUNC(EndScreenWipe); - GETFUNC(DoScreenWipe); - GETFUNC(DrawIntermissionBG); - GETFUNC(MakeScreenTexture); - GETFUNC(MakeScreenFinalTexture); - GETFUNC(DrawScreenFinalTexture); -#else //HWRENDER - if (0 == strcmp("FinishUpdate", funcName)) - return funcPointer; //&FinishUpdate; -#endif //!HWRENDER -#ifdef STATIC3DS - GETFUNC(Startup); - GETFUNC(AddSfx); - GETFUNC(AddSource); - GETFUNC(StartSource); - GETFUNC(StopSource); - GETFUNC(GetHW3DSVersion); - GETFUNC(BeginFrameUpdate); - GETFUNC(EndFrameUpdate); - GETFUNC(IsPlaying); - GETFUNC(UpdateListener); - GETFUNC(UpdateSourceParms); - GETFUNC(SetGlobalSfxVolume); - GETFUNC(SetCone); - GETFUNC(Update3DSource); - GETFUNC(ReloadSource); - GETFUNC(KillSource); - GETFUNC(Shutdown); - GETFUNC(GetHW3DSTitle); -#endif -#ifdef NOLOADSO - else - funcPointer = handle; -#else - else if (handle) - funcPointer = SDL_LoadFunction(handle,funcName); -#endif - if (!funcPointer) - I_OutputMsg("hwSym for %s: %s\n", funcName, SDL_GetError()); - return funcPointer; -} - -/** \brief The *hwOpen function - - \param hwfile Open a handle to the SO - - \return Handle to SO - - -*/ - -void *hwOpen(const char *hwfile) -{ -#ifdef NOLOADSO - (void)hwfile; - return NULL; -#else - void *tempso = NULL; - tempso = SDL_LoadObject(hwfile); - if (!tempso) I_OutputMsg("hwOpen of %s: %s\n", hwfile, SDL_GetError()); - return tempso; -#endif -} - -/** \brief The hwClose function - - \param handle Close the handle of the SO - - \return void - - -*/ - -void hwClose(void *handle) -{ -#ifdef NOLOADSO - (void)handle; -#else - SDL_UnloadObject(handle); -#endif -} -#endif diff --git a/src/sdl12/hwsym_sdl.h b/src/sdl12/hwsym_sdl.h deleted file mode 100644 index 7297587bf3bcb42f5e3f10e52b43cc232e022b5b..0000000000000000000000000000000000000000 --- a/src/sdl12/hwsym_sdl.h +++ /dev/null @@ -1,23 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief Tool for dynamic referencing of hardware rendering/3D sound functions - -void *hwSym(const char *funcName,void *handle); - -void *hwOpen(const char *hwfile); - -void hwClose(void *handle); diff --git a/src/sdl12/i_cdmus.c b/src/sdl12/i_cdmus.c deleted file mode 100644 index b3490592eebcc9208ad788a0d7b7aa5a65558135..0000000000000000000000000000000000000000 --- a/src/sdl12/i_cdmus.c +++ /dev/null @@ -1,588 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief cd music interface -/// - -#ifdef HAVE_SDL - -#if defined (DC) || defined (_WIN32_WCE) || defined(GP2X) || defined(_PS3) -#define NOSDLCD -#endif - -#include <stdlib.h> -#ifndef NOSDLCD - -#ifdef _MSC_VER -#pragma warning(disable : 4214 4244) -#endif - -#include "SDL.h" - -#ifdef _MSC_VER -#pragma warning(default : 4214 4244) -#endif - -#endif - -#include "../doomtype.h" -#include "../i_sound.h" -#include "../command.h" -#include "../m_argv.h" -#include "../s_sound.h" - -#define MAX_CD_TRACKS 256 - -#ifdef _XBOX -INT32 SDL_SYS_CDInit(void) -{ - return(0); -} - -void SDL_SYS_CDQuit(void) -{ - return; -} -#endif - -UINT8 cdaudio_started = 0; // for system startup/shutdown - -consvar_t cd_volume = {"cd_volume","18",CV_SAVE,soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cdUpdate = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; - -#ifndef NOSDLCD -static SDL_bool cdValid = SDL_FALSE; -static SDL_bool cdPlaying = SDL_FALSE; -static SDL_bool wasPlaying = SDL_FALSE; -static SDL_bool cdEnabled = SDL_FALSE; -static SDL_bool playLooping = SDL_FALSE; -static Uint8 playTrack = 0; -static Uint8 maxTrack = MAX_CD_TRACKS-1; -static Uint8 cdRemap[MAX_CD_TRACKS]; -static INT32 cdvolume = -1; -static SDL_CD *cdrom = NULL; -static CDstatus cdStatus = CD_ERROR; - -/************************************************************************** - * - * function: CDAudio_GetAudioDiskInfo - * - * description: - * set number of tracks if CD is available - * - **************************************************************************/ -static INT32 CDAudio_GetAudioDiskInfo(void) -{ - cdValid = SDL_FALSE; - maxTrack = 0; - - if (!cdrom) - return 0;//Alam: Lies! - - cdStatus = SDL_CDStatus(cdrom); - - if (!CD_INDRIVE(cdStatus)) - { - CONS_Printf("%s", M_GetText("No CD in drive\n")); - return -1; - } - - if (cdStatus == CD_ERROR) - { - CONS_Printf(M_GetText("CD Error: %s\n"), SDL_GetError()); - return -1; - } - - cdValid = SDL_TRUE; - maxTrack = (Uint8)cdrom->numtracks; - - return 0; -} - - -/************************************************************************** - * - * function: I_EjectCD - * - * description: - * - * - **************************************************************************/ -static void I_EjectCD(void) -{ - if (!cdrom || !cdEnabled) - return; // no cd init'd - - I_StopCD(); - - if (SDL_CDEject(cdrom)) - CONS_Printf("%s", M_GetText("CD eject failed\n")); -} - -/************************************************************************** - * - * function: Command_Cd_f - * - * description: - * handles all CD commands from the console - * - **************************************************************************/ -static void Command_Cd_f (void) -{ - const char *command; - size_t ret, n; - - if (!cdaudio_started) - return; - - if (COM_Argc() < 2) - { - CONS_Printf ("%s", M_GetText("cd [on] [off] [remap] [reset] [select]\n" - " [open] [info] [play <track>] [resume]\n" - " [stop] [pause] [loop <track>]\n")); - return; - } - - command = COM_Argv (1); - - if (!strncmp(command, "on", 2)) - { - cdEnabled = SDL_TRUE; - return; - } - - if (!strncmp(command, "off", 3)) - { - I_StopCD(); - cdEnabled = SDL_FALSE; - return; - } - - if (!strncmp(command, "select", 6)) - { - INT32 newcddrive; - newcddrive = atoi(COM_Argv(2)); - command = SDL_CDName(newcddrive); - I_StopCD(); - cdEnabled = SDL_FALSE; - SDL_CDClose(cdrom); - cdrom = SDL_CDOpen(newcddrive); - if (cdrom) - { - cdEnabled = SDL_TRUE; - CONS_Printf(M_GetText("Opened CD-ROM drive %s\n"), command ? command : COM_Argv(2)); - } - else CONS_Printf(M_GetText("Couldn't open CD-ROM drive %s: %s\n"), command ? command : COM_Argv(2), SDL_GetError()); - return; - } - - if (!strncmp(command, "remap", 5)) - { - ret = COM_Argc() - 2; - if (ret <= 0) - { - for (n = 1; n < MAX_CD_TRACKS; n++) - { - if (cdRemap[n] != n) - CONS_Printf(" %s -> %u\n", sizeu1(n), cdRemap[n]); - } - return; - } - for (n = 1; n <= ret; n++) - cdRemap[n] = (Uint8)atoi(COM_Argv (n+1)); - return; - } - - if (!strncmp(command, "reset", 5)) - { - if (!cdrom) return; - cdEnabled = SDL_TRUE; - I_StopCD(); - for (n = 0; n < MAX_CD_TRACKS; n++) - cdRemap[n] = (Uint8)n; - CDAudio_GetAudioDiskInfo(); - return; - } - - if (!cdValid) - { - if (CDAudio_GetAudioDiskInfo()==-1 && !cdValid) - { - CONS_Printf("%s", M_GetText("No CD in drive\n")); - return; - } - } - - if (!strncmp(command, "open", 4)) - { - I_EjectCD(); - cdValid = SDL_FALSE; - return; - } - - if (!strncmp(command, "info", 4)) - { - CONS_Printf(M_GetText("%u tracks\n"), maxTrack); - if (cdPlaying) - CONS_Printf(M_GetText("Currently %s track %u\n"), playLooping ? M_GetText("looping") : M_GetText("playing"), playTrack); - else if (wasPlaying) - CONS_Printf(M_GetText("Paused %s track %u\n"), playLooping ? M_GetText("looping") : M_GetText("playing"), playTrack); - CONS_Printf(M_GetText("Volume is %d\n"), cdvolume); - return; - } - - if (!strncmp(command, "play", 4)) - { - I_PlayCD((UINT8)atoi(COM_Argv (2)), SDL_FALSE); - return; - } - - if (!strncmp(command, "loop", 4)) - { - I_PlayCD((UINT8)atoi(COM_Argv (2)), true); - return; - } - - if (!strncmp(command, "stop", 4)) - { - I_StopCD(); - return; - } - if (!strncmp(command, "pause", 5)) - { - I_PauseCD(); - return; - } - - if (!strncmp(command, "resume", 6)) - { - I_ResumeCD(); - return; - } - - CONS_Printf(M_GetText("Invalid CD command \"CD %s\"\n"), COM_Argv(1)); -} -#endif - -/************************************************************************** - * - * function: StopCD - * - * description: - * - * - **************************************************************************/ -void I_StopCD(void) -{ -#ifndef NOSDLCD - if (!cdrom || !cdEnabled) - return; - - if (!(cdPlaying || wasPlaying)) - return; - - if (SDL_CDStop(cdrom)) - I_OutputMsg("cdromstop failed\n"); - - wasPlaying = SDL_FALSE; - cdPlaying = SDL_FALSE; -#endif -} - -/************************************************************************** - * - * function: PauseCD - * - * description: - * - * - **************************************************************************/ -void I_PauseCD (void) -{ -#ifndef NOSDLCD - if (!cdrom || !cdEnabled) - return; - - if (!cdPlaying) - return; - - if (SDL_CDPause(cdrom)) - I_OutputMsg("cdrompause failed\n"); - - wasPlaying = cdPlaying; - cdPlaying = SDL_FALSE; -#endif -} - -/************************************************************************** - * - * function: ResumeCD - * - * description: - * - * - **************************************************************************/ -// continue after a pause -void I_ResumeCD (void) -{ -#ifndef NOSDLCD - if (!cdrom || !cdEnabled) - return; - - if (!cdValid) - return; - - if (!wasPlaying) - return; - - if (cd_volume.value == 0) - return; - - if (SDL_CDResume(cdrom)) - I_OutputMsg("cdromresume failed\n"); - - cdPlaying = SDL_TRUE; - wasPlaying = SDL_FALSE; -#endif -} - - -/************************************************************************** - * - * function: ShutdownCD - * - * description: - * - * - **************************************************************************/ -void I_ShutdownCD (void) -{ -#ifndef NOSDLCD - if (!cdaudio_started) - return; - - I_StopCD(); - - CONS_Printf("I_ShutdownCD: "); - SDL_CDClose(cdrom); - cdrom = NULL; - cdaudio_started = false; - CONS_Printf("%s", M_GetText("shut down\n")); - SDL_QuitSubSystem(SDL_INIT_CDROM); - cdEnabled = SDL_FALSE; -#endif -} - -/************************************************************************** - * - * function: InitCD - * - * description: - * Initialize the first CD drive SDL detects and add console command 'cd' - * - **************************************************************************/ -void I_InitCD (void) -{ -#ifndef NOSDLCD - INT32 i; - - // Has been checked in d_main.c, but doesn't hurt here - if (M_CheckParm ("-nocd")) - return; - - CONS_Printf("%s", M_GetText("I_InitCD: Init CD audio\n")); - - // Initialize SDL first - if (SDL_InitSubSystem(SDL_INIT_CDROM) < 0) - { - CONS_Printf(M_GetText("Couldn't initialize SDL CDROM: %s\n"), SDL_GetError()); - return; - } - - // Open drive - cdrom = SDL_CDOpen(0); - - if (!cdrom) - { - const char *cdName = SDL_CDName(0); - if (!cdName) - CONS_Printf(M_GetText("Couldn't open CD-ROM drive %s: %s\n"), "\b", SDL_GetError()); - else - CONS_Printf(M_GetText("Couldn't open CD-ROM drive %s: %s\n"), cdName, SDL_GetError()); - //return; - } - - for (i = 0; i < MAX_CD_TRACKS; i++) - cdRemap[i] = (Uint8)i; - - cdaudio_started = true; - if (cdrom) cdEnabled = SDL_TRUE; - - if (CDAudio_GetAudioDiskInfo()==-1) - { - CONS_Printf("%s", M_GetText("No CD in drive\n")); - cdValid = SDL_FALSE; - } - - COM_AddCommand ("cd", Command_Cd_f); - - CONS_Printf("%s", M_GetText("CD audio Initialized\n")); -#endif -} - - - -// -/************************************************************************** - * - * function: UpdateCD - * - * description: - * sets CD volume (may have changed) and initiates play evey 2 seconds - * in case the song has elapsed - * - **************************************************************************/ -void I_UpdateCD (void) -{ -#ifndef NOSDLCD - static Uint32 lastchk = 0; - - if (!cdEnabled || !cdrom) - return; - - I_SetVolumeCD(cd_volume.value); - - if (cdPlaying && lastchk < SDL_GetTicks()) - { - lastchk = SDL_GetTicks() + 2000; //two seconds between chks - - if (CDAudio_GetAudioDiskInfo()==-1) - { - cdPlaying = SDL_FALSE; - return; - } - - if (cdStatus != CD_PLAYING && cdStatus != CD_PAUSED) - { - cdPlaying = SDL_FALSE; - if (playLooping) - I_PlayCD(playTrack, true); - } - } -#endif -} - - - -/************************************************************************** - * - * function: PlayCD - * - * description: - * play the requested track and set the looping flag - * pauses the CD if volume is 0 - * - **************************************************************************/ - -void I_PlayCD (UINT8 track, UINT8 looping) -{ -#ifdef NOSDLCD - (void)track; - (void)looping; -#else - if (!cdrom || !cdEnabled) - return; - - if (!cdValid) - { - CDAudio_GetAudioDiskInfo(); - if (!cdValid) - return; - } - - track = cdRemap[track]; - - if (track < 1 || track > maxTrack) - { - CONS_Printf(M_GetText("Bad track number %u.\n"), track); - return; - } - - // don't try to play a non-audio track - if (cdrom->track[track].type == SDL_DATA_TRACK) - { - CONS_Printf(M_GetText("Track %u is not audio\n"), track); - return; - } - - if (cdPlaying) - { - if (playTrack == track) - return; - I_StopCD(); - } - - if (SDL_CDPlayTracks(cdrom, track, 0, 1, 0)) - { - CONS_Printf(M_GetText("Error playing track %d: %s\n"), track, SDL_GetError()); - return; - } - - playLooping = looping; - playTrack = (Uint8)track; - cdPlaying = SDL_TRUE; - - if (cd_volume.value == 0) - I_PauseCD(); -#endif -} - - -/************************************************************************** - * - * function: SetVolumeCD - * - * description: - * SDL does not support setting the CD volume - * use pause instead and toggle between full and no music - * - **************************************************************************/ - -boolean I_SetVolumeCD (INT32 volume) -{ -#ifdef NOSDLCD - (void)volume; -#else - if (volume != cdvolume) - { - if (volume > 0 && volume < 16) - { - CV_SetValue(&cd_volume, 31); - cdvolume = 31; - I_ResumeCD(); - } - else if (volume > 15 && volume < 31) - { - CV_SetValue(&cd_volume, 0); - cdvolume = 0; - I_PauseCD(); - } - } -#endif - return false; -} - -#endif diff --git a/src/sdl12/i_main.c b/src/sdl12/i_main.c deleted file mode 100644 index 1c438e0834f97aed1c15d962c9e982c246892921..0000000000000000000000000000000000000000 --- a/src/sdl12/i_main.c +++ /dev/null @@ -1,247 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1993-1996 by id Software, Inc. -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief Main program, simply calls D_SRB2Main and D_SRB2Loop, the high level loop. - -#include "../doomdef.h" -#include "../m_argv.h" -#include "../d_main.h" -#include "../i_system.h" - -#ifdef __GNUC__ -#include <unistd.h> -#endif - -#ifdef _WII -#include <limits.h> -#include <network.h> -#include <fat.h> -#ifdef REMOTE_DEBUGGING -#include <debug.h> -#endif -static char wiicwd[PATH_MAX] = "sd:/"; -static char localip[16] = {0}; -static char gateway[16] = {0}; -static char netmask[16] = {0}; -#endif - -#ifdef _PSP -#include <pspmoduleinfo.h> -#include <pspthreadman.h> -PSP_HEAP_SIZE_KB(24*1024); -PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER | PSP_THREAD_ATTR_VFPU); -PSP_MAIN_THREAD_NAME("SRB2"); -PSP_MAIN_THREAD_STACK_SIZE_KB(256); -#endif - -#ifdef HAVE_SDL - -#ifdef HAVE_TTF -#include "SDL.h" -#include "i_ttf.h" -#endif - -#ifdef SDLMAIN -#include "SDL_main.h" -#elif defined(FORCESDLMAIN) -extern int SDL_main(int argc, char *argv[]); -#endif - -#ifdef LOGMESSAGES -FILE *logstream = NULL; -#endif - -#ifndef DOXYGEN -#ifndef O_TEXT -#define O_TEXT 0 -#endif - -#ifndef O_SEQUENTIAL -#define O_SEQUENTIAL 0 -#endif -#endif - -#if defined (_WIN32) && !defined (_XBOX) -#include "../win32/win_dbg.h" -typedef BOOL (WINAPI *p_IsDebuggerPresent)(VOID); -#endif - -#ifdef _arch_dreamcast -#include <arch/arch.h> -KOS_INIT_FLAGS(INIT_DEFAULT -//| INIT_NET -//| INIT_MALLOCSTATS -//| INIT_QUIET -//| INIT_OCRAM -//| INIT_NO_DCLOAD -); -#endif - -#if defined (_WIN32) && !defined (_XBOX) && !defined (_WIN32_WCE) -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 - - -/** \brief The main function - - \param argc number of arg - \param *argv string table - - \return int -*/ -FUNCNORETURN -#if defined (_XBOX) && defined (__GNUC__) -void XBoxStartup() -{ - const char *logdir = NULL; - myargc = -1; - myargv = NULL; -#else -#ifdef FORCESDLMAIN -int SDL_main(int argc, char **argv) -#else -int main(int argc, char **argv) -#endif -{ - const char *logdir = NULL; - myargc = argc; - myargv = argv; /// \todo pull out path to exe from this string -#endif - -#ifdef HAVE_TTF -#ifdef _PS3 - // apparently there is a bug in SDL_PSL1GHT which needs this to be set to work around - SDL_setenv("SDL_VIDEODRIVER", "psl1ght", 1); - I_StartupTTF(FONTPOINTSIZE, SDL_INIT_VIDEO, SDL_SWSURFACE|SDL_DOUBLEBUF); -#elif defined(_WIN32) - I_StartupTTF(FONTPOINTSIZE, SDL_INIT_VIDEO|SDL_INIT_AUDIO, SDL_SWSURFACE); -#else - I_StartupTTF(FONTPOINTSIZE, SDL_INIT_VIDEO, SDL_SWSURFACE); -#endif -#endif - -#ifdef _PS3 - // initialise controllers. - //ioPadInit(7); -#endif - -// init Wii-specific stuff -#ifdef _WII - // Start network - if_config(localip, netmask, gateway, TRUE); - -#ifdef REMOTE_DEBUGGING -#if REMOTE_DEBUGGING == 0 - DEBUG_Init(GDBSTUB_DEVICE_TCP, GDBSTUB_DEF_TCPPORT); // Port 2828 -#elif REMOTE_DEBUGGING > 2 - DEBUG_Init(GDBSTUB_DEVICE_TCP, REMOTE_DEBUGGING); // Custom Port -#elif REMOTE_DEBUGGING < 0 - DEBUG_Init(GDBSTUB_DEVICE_USB, GDBSTUB_DEF_CHANNEL); // Slot 1 -#else - DEBUG_Init(GDBSTUB_DEVICE_USB, REMOTE_DEBUGGING-1); // Custom Slot -#endif -#endif - // Start FAT filesystem - fatInitDefault(); - - if (getcwd(wiicwd, PATH_MAX)) - I_PutEnv(va("HOME=%ssrb2wii", wiicwd)); -#endif - - logdir = D_Home(); - -#ifdef LOGMESSAGES -#if defined(_WIN32_WCE) || defined(GP2X) - logstream = fopen(va("%s.log",argv[0]), "a"); -#elif defined (_WII) - logstream = fopen(va("%s/srb2log.txt",logdir), "a"); -#elif defined (DEFAULTDIR) - if (logdir) - logstream = fopen(va("%s/"DEFAULTDIR"/srb2log.txt",logdir), "a"); - else -#endif - logstream = fopen("./srb2log.txt", "a"); -#endif - - //I_OutputMsg("I_StartupSystem() ...\n"); - I_StartupSystem(); -#if defined (_WIN32) && !defined (_XBOX) -#ifndef _WIN32_WCE - { - p_IsDebuggerPresent pfnIsDebuggerPresent = (p_IsDebuggerPresent)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsDebuggerPresent"); - if ((!pfnIsDebuggerPresent || !pfnIsDebuggerPresent()) -#ifdef BUGTRAP - && !InitBugTrap() -#endif - ) - { - LoadLibraryA("exchndl.dll"); - } - } -#endif - prevExceptionFilter = SetUnhandledExceptionFilter(RecordExceptionInfo); -#ifndef _WIN32_WCE - MakeCodeWritable(); -#endif -#endif - // startup SRB2 - CONS_Printf("%s", M_GetText("Setting up SRB2...\n")); - D_SRB2Main(); - CONS_Printf("%s", M_GetText("Entering main game loop...\n")); - // never return - D_SRB2Loop(); - -#ifdef BUGTRAP - // This is safe even if BT didn't start. - ShutdownBugTrap(); -#endif - - // return to OS -#ifndef __GNUC__ - return 0; -#endif -} -#endif diff --git a/src/sdl12/i_net.c b/src/sdl12/i_net.c deleted file mode 100644 index ee4a34c13dd8d4d10950d53d972d0cf873068943..0000000000000000000000000000000000000000 --- a/src/sdl12/i_net.c +++ /dev/null @@ -1,442 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1993-1996 by id Software, Inc. -// Portions Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief SDL network interface - -#include "../doomdef.h" - -#include "../i_system.h" -#include "../d_event.h" -#include "../d_net.h" -#include "../m_argv.h" - -#include "../doomstat.h" - -#include "../i_net.h" - -#include "../z_zone.h" - -#include "../i_tcp.h" - -#ifdef HAVE_SDL - -#ifdef HAVE_SDLNET - -#include "SDL_net.h" - -#define MAXBANS 20 - -static IPaddress clientaddress[MAXNETNODES+1]; -static IPaddress banned[MAXBANS]; - -static UDPpacket mypacket; -static UDPsocket mysocket = NULL; -static SDLNet_SocketSet myset = NULL; - -static size_t numbans = 0; -static boolean NET_bannednode[MAXNETNODES+1]; /// \note do we really need the +1? -static boolean init_SDLNet_driver = false; - -static const char *NET_AddrToStr(IPaddress* sk) -{ - static char s[22]; // 255.255.255.255:65535 - strcpy(s, SDLNet_ResolveIP(sk)); - if (sk->port != 0) strcat(s, va(":%d", sk->port)); - return s; -} - -static const char *NET_GetNodeAddress(INT32 node) -{ - if (!nodeconnected[node]) - return NULL; - return NET_AddrToStr(&clientaddress[node]); -} - -static const char *NET_GetBanAddress(size_t ban) -{ - if (ban > numbans) - return NULL; - return NET_AddrToStr(&banned[ban]); -} - -static boolean NET_cmpaddr(IPaddress* a, IPaddress* b) -{ - return (a->host == b->host && (b->port == 0 || a->port == b->port)); -} - -static boolean NET_CanGet(void) -{ - return myset?(SDLNet_CheckSockets(myset,0) == 1):false; -} - -static void NET_Get(void) -{ - INT32 mystatus; - INT32 newnode; - mypacket.len = MAXPACKETLENGTH; - if (!NET_CanGet()) - { - doomcom->remotenode = -1; // no packet - return; - } - mystatus = SDLNet_UDP_Recv(mysocket,&mypacket); - if (mystatus != -1) - { - if (mypacket.channel != -1) - { - doomcom->remotenode = mypacket.channel+1; // good packet from a game player - doomcom->datalength = mypacket.len; - return; - } - newnode = SDLNet_UDP_Bind(mysocket,-1,&mypacket.address); - if (newnode != -1) - { - size_t i; - newnode++; - M_Memcpy(&clientaddress[newnode], &mypacket.address, sizeof (IPaddress)); - DEBFILE(va("New node detected: node:%d address:%s\n", newnode, - NET_GetNodeAddress(newnode))); - doomcom->remotenode = newnode; // good packet from a game player - doomcom->datalength = mypacket.len; - for (i = 0; i < numbans; i++) - { - if (NET_cmpaddr(&mypacket.address, &banned[i])) - { - DEBFILE("This dude has been banned\n"); - NET_bannednode[newnode] = true; - break; - } - } - if (i == numbans) - NET_bannednode[newnode] = false; - return; - } - else - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - } - else if (mystatus == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - } - - DEBFILE("New node detected: No more free slots\n"); - doomcom->remotenode = -1; // no packet -} - -#if 0 -static boolean NET_CanSend(void) -{ - return true; -} -#endif - -static void NET_Send(void) -{ - if (!doomcom->remotenode) - return; - mypacket.len = doomcom->datalength; - if (SDLNet_UDP_Send(mysocket,doomcom->remotenode-1,&mypacket) == 0) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - } -} - -static void NET_FreeNodenum(INT32 numnode) -{ - // can't disconnect from self :) - if (!numnode) - return; - - DEBFILE(va("Free node %d (%s)\n", numnode, NET_GetNodeAddress(numnode))); - - SDLNet_UDP_Unbind(mysocket,numnode-1); - - memset(&clientaddress[numnode], 0, sizeof (IPaddress)); -} - -static UDPsocket NET_Socket(void) -{ - UDPsocket temp = NULL; - Uint16 portnum = 0; - IPaddress tempip = {INADDR_BROADCAST,0}; - //Hurdler: I'd like to put a server and a client on the same computer - //Logan: Me too - //BP: in fact for client we can use any free port we want i have read - // in some doc that connect in udp can do it for us... - //Alam: where? - if (M_CheckParm("-clientport")) - { - if (!M_IsNextParm()) - I_Error("syntax: -clientport <portnum>"); - portnum = atoi(M_GetNextParm()); - } - else - portnum = sock_port; - temp = SDLNet_UDP_Open(portnum); - if (!temp) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return NULL; - } - if (SDLNet_UDP_Bind(temp,BROADCASTADDR-1,&tempip) == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - SDLNet_UDP_Close(temp); - return NULL; - } - clientaddress[BROADCASTADDR].port = sock_port; - clientaddress[BROADCASTADDR].host = INADDR_BROADCAST; - - doomcom->extratics = 1; // internet is very high ping - - return temp; -} - -static void I_ShutdownSDLNetDriver(void) -{ - if (myset) SDLNet_FreeSocketSet(myset); - myset = NULL; - SDLNet_Quit(); - init_SDLNet_driver = false; -} - -static void I_InitSDLNetDriver(void) -{ - if (init_SDLNet_driver) - I_ShutdownSDLNetDriver(); - if (SDLNet_Init() == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return; // No good! - } - D_SetDoomcom(); - mypacket.data = doomcom->data; - init_SDLNet_driver = true; -} - -static void NET_CloseSocket(void) -{ - if (mysocket) - SDLNet_UDP_Close(mysocket); - mysocket = NULL; -} - -static SINT8 NET_NetMakeNodewPort(const char *hostname, const char *port) -{ - INT32 newnode; - UINT16 portnum = sock_port; - IPaddress hostnameIP; - - // retrieve portnum from address! - if (port && !port[0]) - portnum = atoi(port); - - if (SDLNet_ResolveHost(&hostnameIP,hostname,portnum) == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return -1; - } - newnode = SDLNet_UDP_Bind(mysocket,-1,&hostnameIP); - if (newnode == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return newnode; - } - newnode++; - M_Memcpy(&clientaddress[newnode],&hostnameIP,sizeof (IPaddress)); - return (SINT8)newnode; -} - - -static boolean NET_OpenSocket(void) -{ - memset(clientaddress, 0, sizeof (clientaddress)); - - //I_OutputMsg("SDL_Net Code starting up\n"); - - I_NetSend = NET_Send; - I_NetGet = NET_Get; - I_NetCloseSocket = NET_CloseSocket; - I_NetFreeNodenum = NET_FreeNodenum; - I_NetMakeNodewPort = NET_NetMakeNodewPort; - - //I_NetCanSend = NET_CanSend; - - // build the socket but close it first - NET_CloseSocket(); - mysocket = NET_Socket(); - - if (!mysocket) - return false; - - // for select - myset = SDLNet_AllocSocketSet(1); - if (!myset) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return false; - } - if (SDLNet_UDP_AddSocket(myset,mysocket) == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return false; - } - return true; -} - -static boolean NET_Ban(INT32 node) -{ - if (numbans == MAXBANS) - return false; - - M_Memcpy(&banned[numbans], &clientaddress[node], sizeof (IPaddress)); - banned[numbans].port = 0; - numbans++; - return true; -} - -static boolean NET_SetBanAddress(const char *address, const char *mask) -{ - (void)mask; - if (bans == MAXBANS) - return false; - - if (SDLNet_ResolveHost(&banned[numbans], address, 0) == -1) - return false; - numbans++; - return true; -} - -static void NET_ClearBans(void) -{ - numbans = 0; -} -#endif - -// -// I_InitNetwork -// Only required for DOS, so this is more a dummy -// -boolean I_InitNetwork(void) -{ -#ifdef HAVE_SDLNET - char serverhostname[255]; - boolean ret = false; - SDL_version SDLcompiled; - const SDL_version *SDLlinked = SDLNet_Linked_Version(); - SDL_NET_VERSION(&SDLcompiled) - I_OutputMsg("Compiled for SDL_Net version: %d.%d.%d\n", - SDLcompiled.major, SDLcompiled.minor, SDLcompiled.patch); - I_OutputMsg("Linked with SDL_Net version: %d.%d.%d\n", - SDLlinked->major, SDLlinked->minor, SDLlinked->patch); - //if (!M_CheckParm ("-sdlnet")) - // return false; - // initilize the driver - I_InitSDLNetDriver(); - I_AddExitFunc(I_ShutdownSDLNetDriver); - if (!init_SDLNet_driver) - return false; - - if (M_CheckParm("-udpport")) - { - if (M_IsNextParm()) - sock_port = (UINT16)atoi(M_GetNextParm()); - else - sock_port = 0; - } - - // parse network game options, - if (M_CheckParm("-server") || dedicated) - { - server = true; - - // If a number of clients (i.e. nodes) is specified, the server will wait for the clients - // to connect before starting. - // If no number is specified here, the server starts with 1 client, and others can join - // in-game. - // Since Boris has implemented join in-game, there is no actual need for specifying a - // particular number here. - // FIXME: for dedicated server, numnodes needs to be set to 0 upon start -/* if (M_IsNextParm()) - doomcom->numnodes = (INT16)atoi(M_GetNextParm()); - else */if (dedicated) - doomcom->numnodes = 0; - else - doomcom->numnodes = 1; - - if (doomcom->numnodes < 0) - doomcom->numnodes = 0; - if (doomcom->numnodes > MAXNETNODES) - doomcom->numnodes = MAXNETNODES; - - // server - servernode = 0; - // FIXME: - // ??? and now ? - // server on a big modem ??? 4*isdn - net_bandwidth = 16000; - hardware_MAXPACKETLENGTH = INETPACKETLENGTH; - - ret = true; - } - else if (M_CheckParm("-connect")) - { - if (M_IsNextParm()) - strcpy(serverhostname, M_GetNextParm()); - else - serverhostname[0] = 0; // assuming server in the LAN, use broadcast to detect it - - // server address only in ip - if (serverhostname[0]) - { - COM_BufAddText("connect \""); - COM_BufAddText(serverhostname); - COM_BufAddText("\"\n"); - - // probably modem - hardware_MAXPACKETLENGTH = INETPACKETLENGTH; - } - else - { - // so we're on a LAN - COM_BufAddText("connect any\n"); - - net_bandwidth = 800000; - hardware_MAXPACKETLENGTH = MAXPACKETLENGTH; - } - } - - mypacket.maxlen = hardware_MAXPACKETLENGTH; - I_NetOpenSocket = NET_OpenSocket; - I_Ban = NET_Ban; - I_ClearBans = NET_ClearBans; - I_GetNodeAddress = NET_GetNodeAddress; - I_GetBenAddress = NET_GetBenAddress; - I_SetBanAddress = NET_SetBanAddress; - bannednode = NET_bannednode; - - return ret; -#else - if ( M_CheckParm ("-net") ) - { - I_Error("-net not supported, use -server and -connect\n" - "see docs for more\n"); - } - return false; -#endif -} -#endif diff --git a/src/sdl12/i_system.c b/src/sdl12/i_system.c deleted file mode 100644 index 10fbc50eed0892fa9301560477b0f8c84d1d7530..0000000000000000000000000000000000000000 --- a/src/sdl12/i_system.c +++ /dev/null @@ -1,3139 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1993-1996 by id Software, Inc. -// Portions Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// Changes by Graue <graue@oceanbase.org> are in the public domain. -// -//----------------------------------------------------------------------------- -/// \file -/// \brief SRB2 system stuff for SDL - -#ifndef _WIN32_WCE -#include <signal.h> -#endif - -#ifdef _XBOX -#include "SRB2XBOX/xboxhelp.h" -#endif - -#if defined (_WIN32) && !defined (_XBOX) -#define RPC_NO_WINDOWS_H -#include <windows.h> -#include "../doomtype.h" -#ifndef _WIN32_WCE -typedef BOOL (WINAPI *p_GetDiskFreeSpaceExA)(LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER); -typedef BOOL (WINAPI *p_IsProcessorFeaturePresent) (DWORD); -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); -typedef HANDLE (WINAPI *p_GetCurrentProcess) (VOID); -typedef BOOL (WINAPI *p_GetProcessAffinityMask) (HANDLE, PDWORD_PTR, PDWORD_PTR); -typedef BOOL (WINAPI *p_SetProcessAffinityMask) (HANDLE, DWORD_PTR); -#endif -#endif -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#ifdef __GNUC__ -#include <unistd.h> -#elif defined (_MSC_VER) -#include <direct.h> -#endif -#if defined (__unix__) || defined (UNIXCOMMON) -#include <fcntl.h> -#endif - -#ifdef _arch_dreamcast -#include <arch/gdb.h> -#include <arch/timer.h> -#include <conio/conio.h> -#include <dc/pvr.h> -void __set_fpscr(long); // in libgcc / kernel's startup.s? -#else -#include <stdio.h> -#if defined (_WIN32) && !defined (_WIN32_WCE) && !defined (_XBOX) -#include <conio.h> -#endif -#endif - -#ifdef _MSC_VER -#pragma warning(disable : 4214 4244) -#endif - -#ifdef HAVE_SDL - -#include "SDL.h" - -#ifdef HAVE_TTF -#include "i_ttf.h" -#endif - -#ifdef _MSC_VER -#pragma warning(default : 4214 4244) -#endif - -#if SDL_VERSION_ATLEAST(1,2,7) && !defined (DC) -#include "SDL_cpuinfo.h" // 1.2.7 or greater -#define HAVE_SDLCPUINFO -#endif - -#ifdef _PSP -//#include <pspiofilemgr.h> -#elif !defined(_PS3) -#if defined (__unix__) || defined(__APPLE__) || (defined (UNIXCOMMON) && !defined (_arch_dreamcast) && !defined (__HAIKU__) && !defined (_WII)) -#if defined (__linux__) -#include <sys/vfs.h> -#else -#include <sys/param.h> -#include <sys/mount.h> -/*For meminfo*/ -#include <sys/types.h> -#ifdef FREEBSD -#include <kvm.h> -#endif -#include <nlist.h> -#include <sys/vmmeter.h> -#endif -#endif -#endif - -#ifndef _PS3 -#if defined (__linux__) || (defined (UNIXCOMMON) && !defined (_arch_dreamcast) && !defined (_PSP) && !defined (__HAIKU__) && !defined (_WII)) -#ifndef NOTERMIOS -#include <termios.h> -#include <sys/ioctl.h> // ioctl -#define HAVE_TERMIOS -#endif -#endif -#endif - -#ifndef NOMUMBLE -#if defined (__linux__) && !defined(_PS3) // need -lrt -#include <sys/mman.h> -#ifdef MAP_FAILED -#define HAVE_SHM -#endif -#include <wchar.h> -#endif - -#if defined (_WIN32) && !defined (_WIN32_WCE) && !defined (_XBOX) -#define HAVE_MUMBLE -#define WINMUMBLE -#elif defined (HAVE_SHM) -#define HAVE_MUMBLE -#endif -#endif // NOMUMBLE - -#ifdef _WIN32_WCE -#include "SRB2CE/cehelp.h" -#endif - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -// Locations for searching the srb2.srb -#ifdef _arch_dreamcast -#define DEFAULTWADLOCATION1 "/cd" -#define DEFAULTWADLOCATION2 "/pc" -#define DEFAULTWADLOCATION3 "/pc/home/alam/srb2code/data" -#define DEFAULTSEARCHPATH1 "/cd" -#define DEFAULTSEARCHPATH2 "/pc" -//#define DEFAULTSEARCHPATH3 "/pc/home/alam/srb2code/data" -#elif defined (GP2X) -#define DEFAULTWADLOCATION1 "/mnt/sd" -#define DEFAULTWADLOCATION2 "/mnt/sd/SRB2" -#define DEFAULTWADLOCATION3 "/tmp/mnt/sd" -#define DEFAULTWADLOCATION4 "/tmp/mnt/sd/SRB2" -#define DEFAULTSEARCHPATH1 "/mnt/sd" -#define DEFAULTSEARCHPATH2 "/tmp/mnt/sd" -#elif defined (_WII) -#define NOCWD -#define NOHOME -#define NEED_SDL_GETENV -#define DEFAULTWADLOCATION1 "sd:/srb2wii" -#define DEFAULTWADLOCATION2 "usb:/srb2wii" -#define DEFAULTSEARCHPATH1 "sd:/srb2wii" -#define DEFAULTSEARCHPATH2 "usb:/srb2wii" -// PS3: TODO: this will need modification most likely -#elif defined (_PS3) -#define NOCWD -#define NOHOME -#define DEFAULTWADLOCATION1 "/dev_hdd0/game/SRB2-PS3_/USRDIR/etc" -#define DEFAULTWADLOCATION2 "/dev_usb/SRB2PS3" -#define DEFAULTSEARCHPATH1 "/dev_hdd0/game/SRB2-PS3_/USRDIR/etc" -#define DEFAULTSEARCHPATH2 "/dev_usb/SRB2PS3" -#elif defined (_PSP) -#define NOCWD -#define NOHOME -#define DEFAULTWADLOCATION1 "host0:/bin/Resources" -#define DEFAULTWADLOCATION2 "ms0:/PSP/GAME/SRB2PSP" -#define DEFAULTSEARCHPATH1 "host0:/" -#define DEFAULTSEARCHPATH2 "ms0:/PSP/GAME/SRB2PSP" -#elif defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) -#define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2" -#define DEFAULTWADLOCATION2 "/usr/local/games/SRB2" -#define DEFAULTWADLOCATION3 "/usr/share/games/SRB2" -#define DEFAULTWADLOCATION4 "/usr/games/SRB2" -#define DEFAULTSEARCHPATH1 "/usr/local/games" -#define DEFAULTSEARCHPATH2 "/usr/games" -#define DEFAULTSEARCHPATH3 "/usr/local" -#elif defined (_XBOX) -#define NOCWD -#ifdef __GNUC__ -#include <openxdk/debug.h> -#endif -#define DEFAULTWADLOCATION1 "c:\\srb2" -#define DEFAULTWADLOCATION2 "d:\\srb2" -#define DEFAULTWADLOCATION3 "e:\\srb2" -#define DEFAULTWADLOCATION4 "f:\\srb2" -#define DEFAULTWADLOCATION5 "g:\\srb2" -#define DEFAULTWADLOCATION6 "h:\\srb2" -#define DEFAULTWADLOCATION7 "i:\\srb2" -#elif defined (_WIN32_WCE) -#define NOCWD -#define NOHOME -#define DEFAULTWADLOCATION1 "\\Storage Card\\SRB2DEMO" -#define DEFAULTSEARCHPATH1 "\\Storage Card" -#elif defined (_WIN32) -#define DEFAULTWADLOCATION1 "c:\\games\\srb2" -#define DEFAULTWADLOCATION2 "\\games\\srb2" -#define DEFAULTSEARCHPATH1 "c:\\games" -#define DEFAULTSEARCHPATH2 "\\games" -#endif - -/** \brief WAD file to look for -*/ -#define WADKEYWORD1 "srb2.srb" -#define WADKEYWORD2 "srb2.wad" -/** \brief holds wad path -*/ -static char returnWadPath[256]; - -//Alam_GBC: SDL - -#include "../doomdef.h" -#include "../m_misc.h" -#include "../i_video.h" -#include "../i_sound.h" -#include "../i_system.h" -#include "../screen.h" //vid.WndParent -#include "../d_net.h" -#include "../g_game.h" -#include "../filesrch.h" -#include "endtxt.h" -#include "sdlmain.h" - -#include "../i_joy.h" - -#include "../m_argv.h" - -#ifdef MAC_ALERT -#include "macosx/mac_alert.h" -#endif - -#include "../d_main.h" - -#if !defined(NOMUMBLE) && defined(HAVE_MUMBLE) -// Mumble context string -#include "../d_clisrv.h" -#include "../byteptr.h" -#endif - -/** \brief The JoyReset function - - \param JoySet Joystick info to reset - - \return void -*/ -static void JoyReset(SDLJoyInfo_t *JoySet) -{ - if (JoySet->dev) - { -#ifdef GP2X //GP2X's SDL does an illegal free on the 1st joystick... - if (SDL_JoystickIndex(JoySet->dev) != 0) -#endif - SDL_JoystickClose(JoySet->dev); - } - JoySet->dev = NULL; - JoySet->oldjoy = -1; - JoySet->axises = JoySet->buttons = JoySet->hats = JoySet->balls = 0; - //JoySet->scale -} - -/** \brief First joystick up and running -*/ -static INT32 joystick_started = 0; - -/** \brief SDL info about joystick 1 -*/ -SDLJoyInfo_t JoyInfo; - - -/** \brief Second joystick up and running -*/ -static INT32 joystick2_started = 0; - -/** \brief SDL inof about joystick 2 -*/ -SDLJoyInfo_t JoyInfo2; - -#ifdef HAVE_TERMIOS -static INT32 fdmouse2 = -1; -static INT32 mouse2_started = 0; -#endif - -SDL_bool consolevent = SDL_FALSE; -SDL_bool framebuffer = SDL_FALSE; - -UINT8 keyboard_started = false; - -#if 0 -static void signal_handler(INT32 num) -{ - //static char msg[] = "oh no! back to reality!\r\n"; - char * sigmsg; - char sigdef[32]; - - switch (num) - { - case SIGINT: - sigmsg = "interrupt"; - break; - case SIGILL: - sigmsg = "illegal instruction - invalid function image"; - break; - case SIGFPE: - sigmsg = "floating point exception"; - break; - case SIGSEGV: - sigmsg = "segment violation"; - break; - case SIGTERM: - sigmsg = "Software termination signal from kill"; - break; -#if !(defined (__unix_) || defined (UNIXCOMMON)) - case SIGBREAK: - sigmsg = "Ctrl-Break sequence"; - break; -#endif - case SIGABRT: - sigmsg = "abnormal termination triggered by abort call"; - break; - default: - sprintf(sigdef,"signal number %d", num); - sigmsg = sigdef; - } - - I_OutputMsg("signal_handler() error: %s\n", sigmsg); - signal(num, SIG_DFL); //default signal action - raise(num); - I_Quit(); -} -#endif - -#if defined (NDEBUG) && !defined (DC) && !defined (_WIN32_WCE) -FUNCNORETURN static ATTRNORETURN void quit_handler(int num) -{ - signal(num, SIG_DFL); //default signal action - raise(num); - I_Quit(); -} -#endif - -#ifdef HAVE_TERMIOS -// TERMIOS console code from Quake3: thank you! -SDL_bool stdin_active = SDL_TRUE; - -typedef struct -{ - size_t cursor; - char buffer[256]; -} feild_t; - -feild_t tty_con; - -// when printing general stuff to stdout stderr (Sys_Printf) -// we need to disable the tty console stuff -// this increments so we can recursively disable -static INT32 ttycon_hide = 0; -// some key codes that the terminal may be using -// TTimo NOTE: I'm not sure how relevant this is -static INT32 tty_erase; -static INT32 tty_eof; - -static struct termios tty_tc; - -// ============================================================= -// tty console routines -// NOTE: if the user is editing a line when something gets printed to the early console then it won't look good -// so we provide tty_Clear and tty_Show to be called before and after a stdout or stderr output -// ============================================================= - -// flush stdin, I suspect some terminals are sending a LOT of garbage -// FIXME TTimo relevant? -#if 0 -static inline void tty_FlushIn(void) -{ - char key; - while (read(STDIN_FILENO, &key, 1)!=-1); -} -#endif - -// do a backspace -// TTimo NOTE: it seems on some terminals just sending '\b' is not enough -// so for now, in any case we send "\b \b" .. yeah well .. -// (there may be a way to find out if '\b' alone would work though) -static void tty_Back(void) -{ - char key; - ssize_t d; - key = '\b'; - d = write(STDOUT_FILENO, &key, 1); - key = ' '; - d = write(STDOUT_FILENO, &key, 1); - key = '\b'; - d = write(STDOUT_FILENO, &key, 1); - (void)d; -} - -static void tty_Clear(void) -{ - size_t i; - if (tty_con.cursor>0) - { - for (i=0; i<tty_con.cursor; i++) - { - tty_Back(); - } - } - -} - -// clear the display of the line currently edited -// bring cursor back to beginning of line -static inline void tty_Hide(void) -{ - //I_Assert(consolevent); - if (ttycon_hide) - { - ttycon_hide++; - return; - } - tty_Clear(); - ttycon_hide++; -} - -// show the current line -// FIXME TTimo need to position the cursor if needed?? -static inline void tty_Show(void) -{ - size_t i; - ssize_t d; - //I_Assert(consolevent); - I_Assert(ttycon_hide>0); - ttycon_hide--; - if (ttycon_hide == 0 && tty_con.cursor) - { - for (i=0; i<tty_con.cursor; i++) - { - d = write(STDOUT_FILENO, tty_con.buffer+i, 1); - } - } - (void)d; -} - -// never exit without calling this, or your terminal will be left in a pretty bad state -static void I_ShutdownConsole(void) -{ - if (consolevent) - { - I_OutputMsg("Shutdown tty console\n"); - consolevent = SDL_FALSE; - tcsetattr (STDIN_FILENO, TCSADRAIN, &tty_tc); - } -} - -static void I_StartupConsole(void) -{ - struct termios tc; - - // TTimo - // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=390 (404) - // then SIGTTIN or SIGTOU is emitted, if not catched, turns into a SIGSTP - signal(SIGTTIN, SIG_IGN); - signal(SIGTTOU, SIG_IGN); - -#if !defined(GP2X) //read is bad on GP2X - consolevent = !M_CheckParm("-noconsole"); -#endif - framebuffer = M_CheckParm("-framebuffer"); - - if (framebuffer) - consolevent = SDL_FALSE; - - if (!consolevent) return; - - if (isatty(STDIN_FILENO)!=1) - { - I_OutputMsg("stdin is not a tty, tty console mode failed\n"); - consolevent = SDL_FALSE; - return; - } - memset(&tty_con, 0x00, sizeof(tty_con)); - tcgetattr (0, &tty_tc); - tty_erase = tty_tc.c_cc[VERASE]; - tty_eof = tty_tc.c_cc[VEOF]; - tc = tty_tc; - /* - ECHO: don't echo input characters - ICANON: enable canonical mode. This enables the special - characters EOF, EOL, EOL2, ERASE, KILL, REPRINT, - STATUS, and WERASE, and buffers by lines. - ISIG: when any of the characters INTR, QUIT, SUSP, or - DSUSP are received, generate the corresponding signal - */ - tc.c_lflag &= ~(ECHO | ICANON); - /* - ISTRIP strip off bit 8 - INPCK enable input parity checking - */ - tc.c_iflag &= ~(ISTRIP | INPCK); - tc.c_cc[VMIN] = 0; //1? - tc.c_cc[VTIME] = 0; - tcsetattr (0, TCSADRAIN, &tc); -} - -void I_GetConsoleEvents(void) -{ - // we use this when sending back commands - event_t ev = {0,0,0,0}; - char key = 0; - ssize_t d; - - if (!consolevent) - return; - - ev.type = ev_console; - if (read(STDIN_FILENO, &key, 1) == -1 || !key) - return; - - // we have something - // backspace? - // NOTE TTimo testing a lot of values .. seems it's the only way to get it to work everywhere - if ((key == tty_erase) || (key == 127) || (key == 8)) - { - if (tty_con.cursor > 0) - { - tty_con.cursor--; - tty_con.buffer[tty_con.cursor] = '\0'; - tty_Back(); - } - ev.data1 = KEY_BACKSPACE; - } - else if (key < ' ') // check if this is a control char - { - if (key == '\n') - { - tty_Clear(); - tty_con.cursor = 0; - ev.data1 = KEY_ENTER; - } - else return; - } - else - { - // push regular character - ev.data1 = tty_con.buffer[tty_con.cursor] = key; - tty_con.cursor++; - // print the current line (this is differential) - d = write(STDOUT_FILENO, &key, 1); - } - if (ev.data1) D_PostEvent(&ev); - //tty_FlushIn(); - (void)d; -} - -#elif defined (_WIN32) && !(defined (_XBOX) || defined (_WIN32_WCE)) -static BOOL I_ReadyConsole(HANDLE ci) -{ - DWORD gotinput; - if (ci == INVALID_HANDLE_VALUE) return FALSE; - if (WaitForSingleObject(ci,0) != WAIT_OBJECT_0) return FALSE; - if (GetFileType(ci) != FILE_TYPE_CHAR) return FALSE; - if (!GetConsoleMode(ci, &gotinput)) return FALSE; - return (GetNumberOfConsoleInputEvents(ci, &gotinput) && gotinput); -} - -static boolean entering_con_command = false; - -void I_GetConsoleEvents(void) -{ - event_t ev = {0,0,0,0}; - HANDLE ci = GetStdHandle(STD_INPUT_HANDLE); - HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO CSBI; - INPUT_RECORD input; - DWORD t; - - while (I_ReadyConsole(ci) && ReadConsoleInput(ci, &input, 1, &t) && t) - { - memset(&ev,0x00,sizeof (ev)); - switch (input.EventType) - { - case KEY_EVENT: - if (input.Event.KeyEvent.bKeyDown) - { - ev.type = ev_console; - entering_con_command = true; - switch (input.Event.KeyEvent.wVirtualKeyCode) - { - case VK_ESCAPE: - case VK_TAB: - ev.data1 = KEY_NULL; - break; - case VK_SHIFT: - ev.data1 = KEY_LSHIFT; - break; - case VK_RETURN: - entering_con_command = false; - // Fall through. - default: - ev.data1 = MapVirtualKey(input.Event.KeyEvent.wVirtualKeyCode,2); // convert in to char - } - if (co != INVALID_HANDLE_VALUE && GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &t)) - { - if (ev.data1 && ev.data1 != KEY_LSHIFT && ev.data1 != KEY_RSHIFT) - { -#ifdef _UNICODE - WriteConsole(co, &input.Event.KeyEvent.uChar.UnicodeChar, 1, &t, NULL); -#else - WriteConsole(co, &input.Event.KeyEvent.uChar.AsciiChar, 1 , &t, NULL); -#endif - } - if (input.Event.KeyEvent.wVirtualKeyCode == VK_BACK - && GetConsoleScreenBufferInfo(co,&CSBI)) - { - WriteConsoleOutputCharacterA(co, " ",1, CSBI.dwCursorPosition, &t); - } - } - } - else - { - ev.type = ev_keyup; - switch (input.Event.KeyEvent.wVirtualKeyCode) - { - case VK_SHIFT: - ev.data1 = KEY_LSHIFT; - break; - default: - break; - } - } - if (ev.data1) D_PostEvent(&ev); - break; - case MOUSE_EVENT: - case WINDOW_BUFFER_SIZE_EVENT: - case MENU_EVENT: - case FOCUS_EVENT: - break; - } - } -} - -static void I_StartupConsole(void) -{ - HANDLE ci, co; - const INT32 ded = M_CheckParm("-dedicated"); -#ifdef SDLMAIN - BOOL gotConsole = FALSE; - if (M_CheckParm("-console") || ded) - gotConsole = AllocConsole(); -#else - BOOL gotConsole = TRUE; - if (M_CheckParm("-detachconsole")) - { - FreeConsole(); - gotConsole = AllocConsole(); - } -#ifdef _DEBUG - else if (M_CheckParm("-noconsole") && !ded) -#else - else if (!M_CheckParm("-console") && !ded) -#endif - { - FreeConsole(); - gotConsole = FALSE; - } -#endif - - if (gotConsole) - { - SetConsoleTitleA("SRB2 Console"); - consolevent = SDL_TRUE; - } - - //Let get the real console HANDLE, because Mingw's Bash is bad! - ci = CreateFile(TEXT("CONIN$") , GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - co = CreateFile(TEXT("CONOUT$"), GENERIC_WRITE|GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (ci != INVALID_HANDLE_VALUE) - { - const DWORD CM = ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT; - SetStdHandle(STD_INPUT_HANDLE, ci); - if (GetFileType(ci) == FILE_TYPE_CHAR) - SetConsoleMode(ci, CM); //default mode but no ENABLE_MOUSE_INPUT - } - if (co != INVALID_HANDLE_VALUE) - { - SetStdHandle(STD_OUTPUT_HANDLE, co); - SetStdHandle(STD_ERROR_HANDLE, co); - } -} -static inline void I_ShutdownConsole(void){} -#else -void I_GetConsoleEvents(void){} -static inline void I_StartupConsole(void) -{ -#ifdef _arch_dreamcast - char title[] = "SRB2 for Dreamcast!\n"; - __set_fpscr(0x00040000); /* ignore FPU underflow */ - //printf("\nHello world!\n\n"); - pvr_init_defaults(); - conio_init(CONIO_TTY_PVR, CONIO_INPUT_LINE); - conio_set_theme(CONIO_THEME_MATRIX); - conio_clear(); - conio_putstr(title); - //printf("\nHello world!\n\n"); -#endif -#ifdef _DEBUG - consolevent = !M_CheckParm("-noconsole"); -#else - consolevent = M_CheckParm("-console"); -#endif - - framebuffer = M_CheckParm("-framebuffer"); - - if (framebuffer) - consolevent = SDL_FALSE; -} -static inline void I_ShutdownConsole(void){} -#endif - -// -// StartupKeyboard -// -void I_StartupKeyboard (void) -{ -#if defined (NDEBUG) && !defined (DC) -#ifdef SIGILL -// signal(SIGILL , signal_handler); -#endif -#ifdef SIGINT - signal(SIGINT , quit_handler); -#endif -#ifdef SIGSEGV -// signal(SIGSEGV , signal_handler); -#endif -#ifdef SIGBREAK - signal(SIGBREAK , quit_handler); -#endif -#ifdef SIGABRT -// signal(SIGABRT , signal_handler); -#endif -#ifdef SIGTERM - signal(SIGTERM , quit_handler); -#endif -#endif -} - -// -//I_OutputMsg -// -void I_OutputMsg(const char *fmt, ...) -{ - size_t len; - XBOXSTATIC char txt[8192]; - va_list argptr; - -#ifdef _arch_dreamcast - if (!keyboard_started) conio_printf(fmt); -#endif - - va_start(argptr,fmt); - vsprintf(txt, fmt, argptr); - va_end(argptr); - -#ifdef HAVE_TTF - if (TTF_WasInit()) I_TTFDrawText(currentfont, solid, DEFAULTFONTFGR, DEFAULTFONTFGG, DEFAULTFONTFGB, DEFAULTFONTFGA, - DEFAULTFONTBGR, DEFAULTFONTBGG, DEFAULTFONTBGB, DEFAULTFONTBGA, txt); -#endif - -#if defined (_WIN32) && !defined (_XBOX) && defined (_MSC_VER) - OutputDebugStringA(txt); -#endif - - len = strlen(txt); - -#ifdef LOGMESSAGES - if (logstream) - { - size_t d = fwrite(txt, len, 1, logstream); - fflush(logstream); - (void)d; - } -#endif - -#if defined (_WIN32) && !defined (_XBOX) && !defined(_WIN32_WCE) -#ifdef DEBUGFILE - if (debugfile != stderr) -#endif - { - HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD bytesWritten; - - if (co == INVALID_HANDLE_VALUE) - return; - - if (GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &bytesWritten)) - { - static COORD coordNextWrite = {0,0}; - LPVOID oldLines = NULL; - INT oldLength; - CONSOLE_SCREEN_BUFFER_INFO csbi; - - // Save the lines that we're going to obliterate. - GetConsoleScreenBufferInfo(co, &csbi); - oldLength = csbi.dwSize.X * (csbi.dwCursorPosition.Y - coordNextWrite.Y) + csbi.dwCursorPosition.X - coordNextWrite.X; - - if (oldLength > 0) - { - LPVOID blank = malloc(oldLength); - if (!blank) return; - memset(blank, ' ', oldLength); // Blank out. - oldLines = malloc(oldLength*sizeof(TCHAR)); - if (!oldLines) - { - free(blank); - return; - } - - ReadConsoleOutputCharacter(co, oldLines, oldLength, coordNextWrite, &bytesWritten); - - // Move to where we what to print - which is where we would've been, - // had console input not been in the way, - SetConsoleCursorPosition(co, coordNextWrite); - - WriteConsoleA(co, blank, oldLength, &bytesWritten, NULL); - free(blank); - - // And back to where we want to print again. - SetConsoleCursorPosition(co, coordNextWrite); - } - - // Actually write the string now! - WriteConsoleA(co, txt, (DWORD)len, &bytesWritten, NULL); - - // Next time, output where we left off. - GetConsoleScreenBufferInfo(co, &csbi); - coordNextWrite = csbi.dwCursorPosition; - - // Restore what was overwritten. - if (oldLines && entering_con_command) - WriteConsole(co, oldLines, oldLength, &bytesWritten, NULL); - if (oldLines) free(oldLines); - } - else // Redirected to a file. - WriteFile(co, txt, (DWORD)len, &bytesWritten, NULL); - } -#else -#ifdef HAVE_TERMIOS - if (consolevent) - { - tty_Hide(); - } -#endif - - if (!framebuffer) - fprintf(stderr, "%s", txt); -#ifdef HAVE_TERMIOS - if (consolevent) - { - tty_Show(); - } -#endif - - // 2004-03-03 AJR Since not all messages end in newline, some were getting displayed late. - if (!framebuffer) - fflush(stderr); - -#endif -} - -// -// I_GetKey -// -INT32 I_GetKey (void) -{ - // Warning: I_GetKey empties the event queue till next keypress - event_t *ev; - INT32 rc = 0; - - // return the first keypress from the event queue - for (; eventtail != eventhead; eventtail = (eventtail+1)&(MAXEVENTS-1)) - { - ev = &events[eventtail]; - if (ev->type == ev_keydown || ev->type == ev_console) - { - rc = ev->data1; - continue; - } - } - - return rc; -} - -// -// I_JoyScale -// -void I_JoyScale(void) -{ -#ifdef GP2X - if (JoyInfo.dev && SDL_JoystickIndex(JoyInfo.dev) == 0) - Joystick.bGamepadStyle = true; - else -#endif - Joystick.bGamepadStyle = cv_joyscale.value==0; - JoyInfo.scale = Joystick.bGamepadStyle?1:cv_joyscale.value; -} - -void I_JoyScale2(void) -{ -#ifdef GP2X - if (JoyInfo2.dev && SDL_JoystickIndex(JoyInfo2.dev) == 0) - Joystick.bGamepadStyle = true; - else -#endif - Joystick2.bGamepadStyle = cv_joyscale2.value==0; - JoyInfo2.scale = Joystick2.bGamepadStyle?1:cv_joyscale2.value; -} - -/** \brief Joystick 1 buttons states -*/ -static UINT64 lastjoybuttons = 0; - -/** \brief Joystick 1 hats state -*/ -static UINT64 lastjoyhats = 0; - -/** \brief Shuts down joystick 1 - - - \return void - - -*/ -static void I_ShutdownJoystick(void) -{ - INT32 i; - event_t event; - event.type=ev_keyup; - event.data2 = 0; - event.data3 = 0; - - lastjoybuttons = lastjoyhats = 0; - - // emulate the up of all joystick buttons - for (i=0;i<JOYBUTTONS;i++) - { - event.data1=KEY_JOY1+i; - D_PostEvent(&event); - } - - // emulate the up of all joystick hats - for (i=0;i<JOYHATS*4;i++) - { - event.data1=KEY_HAT1+i; - D_PostEvent(&event); - } - - // reset joystick position - event.type = ev_joystick; - for (i=0;i<JOYAXISSET; i++) - { - event.data1 = i; - D_PostEvent(&event); - } - - joystick_started = 0; - JoyReset(&JoyInfo); - if (!joystick_started && !joystick2_started && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) - { - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); - if (cv_usejoystick.value == 0) - { - I_OutputMsg("I_Joystick: SDL's Joystick system has been shutdown\n"); - } - } -} - -void I_GetJoystickEvents(void) -{ - static event_t event = {0,0,0,0}; - INT32 i = 0; - UINT64 joyhats = 0; -#if 0 - UINT64 joybuttons = 0; - Sint16 axisx, axisy; -#endif - - if (!joystick_started) return; - - if (!JoyInfo.dev) //I_ShutdownJoystick(); - return; - -#if 0 - //faB: look for as much buttons as g_input code supports, - // we don't use the others - for (i = JoyInfo.buttons - 1; i >= 0; i--) - { - joybuttons <<= 1; - if (SDL_JoystickGetButton(JoyInfo.dev,i)) - joybuttons |= 1; - } - - if (joybuttons != lastjoybuttons) - { - INT64 j = 1; // keep only bits that changed since last time - INT64 newbuttons = joybuttons ^ lastjoybuttons; - lastjoybuttons = joybuttons; - - for (i = 0; i < JOYBUTTONS; i++, j <<= 1) - { - if (newbuttons & j) // button changed state? - { - if (joybuttons & j) - event.type = ev_keydown; - else - event.type = ev_keyup; -#ifdef _PSP - if (i == 12) - event.data1 = KEY_ESCAPE; - else -#endif - event.data1 = KEY_JOY1 + i; - D_PostEvent(&event); - } - } - } -#endif - - for (i = JoyInfo.hats - 1; i >= 0; i--) - { - Uint8 hat = SDL_JoystickGetHat(JoyInfo.dev, i); - - if (hat & SDL_HAT_UP ) joyhats|=(UINT64)0x1<<(0 + 4*i); - if (hat & SDL_HAT_DOWN ) joyhats|=(UINT64)0x1<<(1 + 4*i); - if (hat & SDL_HAT_LEFT ) joyhats|=(UINT64)0x1<<(2 + 4*i); - if (hat & SDL_HAT_RIGHT) joyhats|=(UINT64)0x1<<(3 + 4*i); - } - - if (joyhats != lastjoyhats) - { - INT64 j = 1; // keep only bits that changed since last time - INT64 newhats = joyhats ^ lastjoyhats; - lastjoyhats = joyhats; - - for (i = 0; i < JOYHATS*4; i++, j <<= 1) - { - if (newhats & j) // hat changed state? - { - if (joyhats & j) - event.type = ev_keydown; - else - event.type = ev_keyup; - event.data1 = KEY_HAT1 + i; - D_PostEvent(&event); - } - } - } - -#if 0 - // send joystick axis positions - event.type = ev_joystick; - - for (i = JOYAXISSET - 1; i >= 0; i--) - { - event.data1 = i; - if (i*2 + 1 <= JoyInfo.axises) - axisx = SDL_JoystickGetAxis(JoyInfo.dev, i*2 + 0); - else axisx = 0; - if (i*2 + 2 <= JoyInfo.axises) - axisy = SDL_JoystickGetAxis(JoyInfo.dev, i*2 + 1); - else axisy = 0; - -#ifdef _arch_dreamcast // -128 to 127 - axisx = axisx*8; - axisy = axisy*8; -#else // -32768 to 32767 - axisx = axisx/32; - axisy = axisy/32; -#endif - - if (Joystick.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (axisx < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (axisx > (JOYAXISRANGE/2)) - event.data2 = 1; - else event.data2 = 0; - if (axisy < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (axisy > (JOYAXISRANGE/2)) - event.data3 = 1; - else event.data3 = 0; - } - else - { - - axisx = JoyInfo.scale?((axisx/JoyInfo.scale)*JoyInfo.scale):axisx; - axisy = JoyInfo.scale?((axisy/JoyInfo.scale)*JoyInfo.scale):axisy; - -#ifdef SDL_JDEADZONE - if (-SDL_JDEADZONE <= axisx && axisx <= SDL_JDEADZONE) axisx = 0; - if (-SDL_JDEADZONE <= axisy && axisy <= SDL_JDEADZONE) axisy = 0; -#endif - - // analog control style , just send the raw data - event.data2 = axisx; // x axis - event.data3 = axisy; // y axis - } - D_PostEvent(&event); - } -#endif -} - -/** \brief Open joystick handle - - \param fname name of joystick - - \return axises - - -*/ -static int joy_open(const char *fname) -{ - int joyindex = atoi(fname); - int num_joy = 0; - int i; - - if (joystick_started == 0 && joystick2_started == 0) - { - if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) - { - CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError()); - return -1; - } - else - { - num_joy = SDL_NumJoysticks(); - } - - if (num_joy < joyindex) - { - CONS_Printf(M_GetText("Cannot use joystick #%d/(%s), it doesn't exist\n"),joyindex,fname); - for (i = 0; i < num_joy; i++) - CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickName(i)); - I_ShutdownJoystick(); - return -1; - } - } - else - { - JoyReset(&JoyInfo); - //I_ShutdownJoystick(); - //joy_open(fname); - } - - num_joy = SDL_NumJoysticks(); - - if (joyindex <= 0 || num_joy == 0 || JoyInfo.oldjoy == joyindex) - { -// I_OutputMsg("Unable to use that joystick #(%s), non-number\n",fname); - if (num_joy != 0) - { - CONS_Printf(M_GetText("Found %d joysticks on this system\n"), num_joy); - for (i = 0; i < num_joy; i++) - CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickName(i)); - } - else - CONS_Printf("%s", M_GetText("Found no joysticks on this system\n")); - if (joyindex <= 0 || num_joy == 0) return 0; - } - - JoyInfo.dev = SDL_JoystickOpen(joyindex-1); - CONS_Printf(M_GetText("Joystick: %s\n"), SDL_JoystickName(joyindex-1)); - - if (JoyInfo.dev == NULL) - { - CONS_Printf(M_GetText("Couldn't open joystick: %s\n"), SDL_GetError()); - I_ShutdownJoystick(); - return -1; - } - else - { - JoyInfo.axises = SDL_JoystickNumAxes(JoyInfo.dev); - if (JoyInfo.axises > JOYAXISSET*2) - JoyInfo.axises = JOYAXISSET*2; -/* if (joyaxes<2) - { - I_OutputMsg("Not enought axes?\n"); - I_ShutdownJoystick(); - return 0; - }*/ - - JoyInfo.buttons = SDL_JoystickNumButtons(JoyInfo.dev); - if (JoyInfo.buttons > JOYBUTTONS) - JoyInfo.buttons = JOYBUTTONS; - -#ifdef DC - JoyInfo.hats = 0; -#else - JoyInfo.hats = SDL_JoystickNumHats(JoyInfo.dev); - if (JoyInfo.hats > JOYHATS) - JoyInfo.hats = JOYHATS; - - JoyInfo.balls = SDL_JoystickNumBalls(JoyInfo.dev); -#endif - - //Joystick.bGamepadStyle = !stricmp(SDL_JoystickName(SDL_JoystickIndex(JoyInfo.dev)), "pad"); - - return JoyInfo.axises; - } -} - -//Joystick2 - -/** \brief Joystick 2 buttons states -*/ -static UINT64 lastjoy2buttons = 0; - -/** \brief Joystick 2 hats state -*/ -static UINT64 lastjoy2hats = 0; - -/** \brief Shuts down joystick 2 - - - \return void -*/ -static void I_ShutdownJoystick2(void) -{ - INT32 i; - event_t event; - event.type = ev_keyup; - event.data2 = 0; - event.data3 = 0; - - lastjoy2buttons = lastjoy2hats = 0; - - // emulate the up of all joystick buttons - for (i = 0; i < JOYBUTTONS; i++) - { - event.data1 = KEY_2JOY1 + i; - D_PostEvent(&event); - } - - // emulate the up of all joystick hats - for (i = 0; i < JOYHATS*4; i++) - { - event.data1 = KEY_2HAT1 + i; - D_PostEvent(&event); - } - - // reset joystick position - event.type = ev_joystick2; - for (i = 0; i < JOYAXISSET; i++) - { - event.data1 = i; - D_PostEvent(&event); - } - - JoyReset(&JoyInfo2); - if (!joystick_started && !joystick2_started && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) - { - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); - if (cv_usejoystick2.value == 0) - { - DEBFILE("I_Joystick2: SDL's Joystick system has been shutdown\n"); - } - } -} - -void I_GetJoystick2Events(void) -{ - static event_t event = {0,0,0,0}; - INT32 i = 0; - UINT64 joyhats = 0; -#if 0 - INT64 joybuttons = 0; - INT32 axisx, axisy; -#endif - - if (!joystick2_started) - return; - - if (!JoyInfo2.dev) //I_ShutdownJoystick2(); - return; - - -#if 0 - //faB: look for as much buttons as g_input code supports, - // we don't use the others - for (i = JoyInfo2.buttons - 1; i >= 0; i--) - { - joybuttons <<= 1; - if (SDL_JoystickGetButton(JoyInfo2.dev,i)) - joybuttons |= 1; - } - - if (joybuttons != lastjoy2buttons) - { - INT64 j = 1; // keep only bits that changed since last time - INT64 newbuttons = joybuttons ^ lastjoy2buttons; - lastjoy2buttons = joybuttons; - - for (i = 0; i < JOYBUTTONS; i++, j <<= 1) - { - if (newbuttons & j) // button changed state? - { - if (joybuttons & j) - event.type = ev_keydown; - else - event.type = ev_keyup; - event.data1 = KEY_2JOY1 + i; - D_PostEvent(&event); - } - } - } -#endif - - for (i = JoyInfo2.hats - 1; i >= 0; i--) - { - Uint8 hat = SDL_JoystickGetHat(JoyInfo2.dev, i); - - if (hat & SDL_HAT_UP ) joyhats|=(UINT64)0x1<<(0 + 4*i); - if (hat & SDL_HAT_DOWN ) joyhats|=(UINT64)0x1<<(1 + 4*i); - if (hat & SDL_HAT_LEFT ) joyhats|=(UINT64)0x1<<(2 + 4*i); - if (hat & SDL_HAT_RIGHT) joyhats|=(UINT64)0x1<<(3 + 4*i); - } - - if (joyhats != lastjoy2hats) - { - INT64 j = 1; // keep only bits that changed since last time - INT64 newhats = joyhats ^ lastjoy2hats; - lastjoy2hats = joyhats; - - for (i = 0; i < JOYHATS*4; i++, j <<= 1) - { - if (newhats & j) // hat changed state? - { - if (joyhats & j) - event.type = ev_keydown; - else - event.type = ev_keyup; - event.data1 = KEY_2HAT1 + i; - D_PostEvent(&event); - } - } - } - -#if 0 - // send joystick axis positions - event.type = ev_joystick2; - - for (i = JOYAXISSET - 1; i >= 0; i--) - { - event.data1 = i; - if (i*2 + 1 <= JoyInfo2.axises) - axisx = SDL_JoystickGetAxis(JoyInfo2.dev, i*2 + 0); - else axisx = 0; - if (i*2 + 2 <= JoyInfo2.axises) - axisy = SDL_JoystickGetAxis(JoyInfo2.dev, i*2 + 1); - else axisy = 0; - -#ifdef _arch_dreamcast // -128 to 127 - axisx = axisx*8; - axisy = axisy*8; -#else // -32768 to 32767 - axisx = axisx/32; - axisy = axisy/32; -#endif - - if (Joystick2.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (axisx < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (axisx > (JOYAXISRANGE/2)) - event.data2 = 1; - else - event.data2 = 0; - if (axisy < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (axisy > (JOYAXISRANGE/2)) - event.data3 = 1; - else - event.data3 = 0; - } - else - { - - axisx = JoyInfo2.scale?((axisx/JoyInfo2.scale)*JoyInfo2.scale):axisx; - axisy = JoyInfo2.scale?((axisy/JoyInfo2.scale)*JoyInfo2.scale):axisy; - -#ifdef SDL_JDEADZONE - if (-SDL_JDEADZONE <= axisx && axisx <= SDL_JDEADZONE) axisx = 0; - if (-SDL_JDEADZONE <= axisy && axisy <= SDL_JDEADZONE) axisy = 0; -#endif - - // analog control style , just send the raw data - event.data2 = axisx; // x axis - event.data3 = axisy; // y axis - } - D_PostEvent(&event); - } -#endif - -} - -/** \brief Open joystick handle - - \param fname name of joystick - - \return axises - - -*/ -static int joy_open2(const char *fname) -{ - int joyindex = atoi(fname); - int num_joy = 0; - int i; - - if (joystick_started == 0 && joystick2_started == 0) - { - if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) - { - CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError()); - return -1; - } - else - num_joy = SDL_NumJoysticks(); - - if (num_joy < joyindex) - { - CONS_Printf(M_GetText("Cannot use joystick #%d/(%s), it doesn't exist\n"),joyindex,fname); - for (i = 0; i < num_joy; i++) - CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickName(i)); - I_ShutdownJoystick2(); - return -1; - } - } - else - { - JoyReset(&JoyInfo2); - //I_ShutdownJoystick(); - //joy_open(fname); - } - - num_joy = SDL_NumJoysticks(); - - if (joyindex <= 0 || num_joy == 0 || JoyInfo2.oldjoy == joyindex) - { -// I_OutputMsg("Unable to use that joystick #(%s), non-number\n",fname); - if (num_joy != 0) - { - CONS_Printf(M_GetText("Found %d joysticks on this system\n"), num_joy); - for (i = 0; i < num_joy; i++) - CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickName(i)); - } - else - CONS_Printf("%s", M_GetText("Found no joysticks on this system\n")); - if (joyindex <= 0 || num_joy == 0) return 0; - } - - JoyInfo2.dev = SDL_JoystickOpen(joyindex-1); - CONS_Printf(M_GetText("Joystick2: %s\n"), SDL_JoystickName(joyindex-1)); - - if (!JoyInfo2.dev) - { - CONS_Printf(M_GetText("Couldn't open joystick2: %s\n"), SDL_GetError()); - I_ShutdownJoystick2(); - return -1; - } - else - { - JoyInfo2.axises = SDL_JoystickNumAxes(JoyInfo2.dev); - if (JoyInfo2.axises > JOYAXISSET*2) - JoyInfo2.axises = JOYAXISSET*2; -/* if (joyaxes < 2) - { - I_OutputMsg("Not enought axes?\n"); - I_ShutdownJoystick2(); - return 0; - }*/ - - JoyInfo2.buttons = SDL_JoystickNumButtons(JoyInfo2.dev); - if (JoyInfo2.buttons > JOYBUTTONS) - JoyInfo2.buttons = JOYBUTTONS; - -#ifdef DC - JoyInfo2.hats = 0; -#else - JoyInfo2.hats = SDL_JoystickNumHats(JoyInfo2.dev); - if (JoyInfo2.hats > JOYHATS) - JoyInfo2.hats = JOYHATS; - - JoyInfo2.balls = SDL_JoystickNumBalls(JoyInfo2.dev); -#endif - - //Joystick.bGamepadStyle = !stricmp(SDL_JoystickName(SDL_JoystickIndex(JoyInfo2.dev)), "pad"); - - return JoyInfo2.axises; - } -} - -// -// I_InitJoystick -// -void I_InitJoystick(void) -{ - I_ShutdownJoystick(); - if (!strcmp(cv_usejoystick.string, "0") || M_CheckParm("-nojoy")) - return; - if (joy_open(cv_usejoystick.string) != -1) - JoyInfo.oldjoy = atoi(cv_usejoystick.string); - else - { - cv_usejoystick.value = 0; - return; - } - joystick_started = 1; -} - -void I_InitJoystick2(void) -{ - I_ShutdownJoystick2(); - if (!strcmp(cv_usejoystick2.string, "0") || M_CheckParm("-nojoy")) - return; - if (joy_open2(cv_usejoystick2.string) != -1) - JoyInfo2.oldjoy = atoi(cv_usejoystick2.string); - else - { - cv_usejoystick2.value = 0; - return; - } - joystick2_started = 1; -} - -static void I_ShutdownInput(void) -{ - if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) - { - JoyReset(&JoyInfo); - JoyReset(&JoyInfo2); - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); - } - -} - -INT32 I_NumJoys(void) -{ - INT32 numjoy = 0; - if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) - { - if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != -1) - numjoy = SDL_NumJoysticks(); - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); - } - else - numjoy = SDL_NumJoysticks(); - return numjoy; -} - -static char joyname[255]; // MAX_PATH; joystick name is straight from the driver - -const char *I_GetJoyName(INT32 joyindex) -{ - const char *tempname = NULL; - joyindex--; //SDL's Joystick System starts at 0, not 1 - if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) - { - if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != -1) - { - tempname = SDL_JoystickNameForIndex(joyindex); - if (tempname) - strncpy(joyname, tempname, 255); - } - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); - } - else - { - tempname = SDL_JoystickNameForIndex(joyindex); - if (tempname) - strncpy(joyname, tempname, 255); - } - return joyname; -} - -#ifndef NOMUMBLE -#ifdef HAVE_MUMBLE -// Best Mumble positional audio settings: -// Minimum distance 3.0 m -// Bloom 175% -// Maximum distance 80.0 m -// Minimum volume 50% -#define DEG2RAD (0.017453292519943295769236907684883l) // TAU/360 or PI/180 -#define MUMBLEUNIT (64.0f) // FRACUNITS in a Meter - -static struct { -#ifdef WINMUMBLE - UINT32 uiVersion; - DWORD uiTick; -#else - Uint32 uiVersion; - Uint32 uiTick; -#endif - float fAvatarPosition[3]; - float fAvatarFront[3]; - float fAvatarTop[3]; // defaults to Y-is-up (only used for leaning) - wchar_t name[256]; // game name - float fCameraPosition[3]; - float fCameraFront[3]; - float fCameraTop[3]; // defaults to Y-is-up (only used for leaning) - wchar_t identity[256]; // player id -#ifdef WINMUMBLE - UINT32 context_len; -#else - Uint32 context_len; -#endif - unsigned char context[256]; // server/team - wchar_t description[2048]; // game description -} *mumble = NULL; -#endif // HAVE_MUMBLE - -static void I_SetupMumble(void) -{ -#ifdef WINMUMBLE - HANDLE hMap = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, L"MumbleLink"); - if (!hMap) - return; - - mumble = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(*mumble)); - if (!mumble) - CloseHandle(hMap); -#elif defined (HAVE_SHM) - int shmfd; - char memname[256]; - - snprintf(memname, 256, "/MumbleLink.%d", getuid()); - shmfd = shm_open(memname, O_RDWR, S_IRUSR | S_IWUSR); - - if(shmfd < 0) - return; - - mumble = mmap(NULL, sizeof(*mumble), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0); - if (mumble == MAP_FAILED) - mumble = NULL; -#endif -} - -void I_UpdateMumble(const mobj_t *mobj, const listener_t listener) -{ -#ifdef HAVE_MUMBLE - double angle; - fixed_t anglef; - - if (!mumble) - return; - - if(mumble->uiVersion != 2) { - wcsncpy(mumble->name, L"SRB2 "VERSIONSTRING, 256); - wcsncpy(mumble->description, L"Sonic Robo Blast 2 with integrated Mumble Link support.", 2048); - mumble->uiVersion = 2; - } - mumble->uiTick++; - - if (!netgame || gamestate != GS_LEVEL) { // Zero out, but never delink. - mumble->fAvatarPosition[0] = mumble->fAvatarPosition[1] = mumble->fAvatarPosition[2] = 0.0f; - mumble->fAvatarFront[0] = 1.0f; - mumble->fAvatarFront[1] = mumble->fAvatarFront[2] = 0.0f; - mumble->fCameraPosition[0] = mumble->fCameraPosition[1] = mumble->fCameraPosition[2] = 0.0f; - mumble->fCameraFront[0] = 1.0f; - mumble->fCameraFront[1] = mumble->fCameraFront[2] = 0.0f; - return; - } - - { - UINT8 *p = mumble->context; - WRITEMEM(p, server_context, 8); - WRITEINT16(p, gamemap); - mumble->context_len = p - mumble->context; - } - - if (mobj) { - mumble->fAvatarPosition[0] = FIXED_TO_FLOAT(mobj->x) / MUMBLEUNIT; - mumble->fAvatarPosition[1] = FIXED_TO_FLOAT(mobj->z) / MUMBLEUNIT; - mumble->fAvatarPosition[2] = FIXED_TO_FLOAT(mobj->y) / MUMBLEUNIT; - - anglef = AngleFixed(mobj->angle); - angle = FIXED_TO_FLOAT(anglef)*DEG2RAD; - mumble->fAvatarFront[0] = (float)cos(angle); - mumble->fAvatarFront[1] = 0.0f; - mumble->fAvatarFront[2] = (float)sin(angle); - } else { - mumble->fAvatarPosition[0] = mumble->fAvatarPosition[1] = mumble->fAvatarPosition[2] = 0.0f; - mumble->fAvatarFront[0] = 1.0f; - mumble->fAvatarFront[1] = mumble->fAvatarFront[2] = 0.0f; - } - - mumble->fCameraPosition[0] = FIXED_TO_FLOAT(listener.x) / MUMBLEUNIT; - mumble->fCameraPosition[1] = FIXED_TO_FLOAT(listener.z) / MUMBLEUNIT; - mumble->fCameraPosition[2] = FIXED_TO_FLOAT(listener.y) / MUMBLEUNIT; - - anglef = AngleFixed(listener.angle); - angle = FIXED_TO_FLOAT(anglef)*DEG2RAD; - mumble->fCameraFront[0] = (float)cos(angle); - mumble->fCameraFront[1] = 0.0f; - mumble->fCameraFront[2] = (float)sin(angle); -#else - (void)mobj; - (void)listener; -#endif // HAVE_MUMBLE -} -#undef WINMUMBLE -#endif // NOMUMBLE - -#ifdef HAVE_TERMIOS - -void I_GetMouseEvents(void) -{ - static UINT8 mdata[5]; - static INT32 i = 0,om2b = 0; - INT32 di, j, mlp, button; - event_t event; - const INT32 mswap[8] = {0, 4, 1, 5, 2, 6, 3, 7}; - - if (!mouse2_started) return; - for (mlp = 0; mlp < 20; mlp++) - { - for (; i < 5; i++) - { - di = read(fdmouse2, mdata+i, 1); - if (di == -1) return; - } - if ((mdata[0] & 0xf8) != 0x80) - { - for (j = 1; j < 5; j++) - if ((mdata[j] & 0xf8) == 0x80) - for (i = 0; i < 5-j; i++) // shift - mdata[i] = mdata[i+j]; - if (i < 5) continue; - } - else - { - button = mswap[~mdata[0] & 0x07]; - for (j = 0; j < MOUSEBUTTONS; j++) - { - if (om2b & (1<<j)) - { - if (!(button & (1<<j))) //keyup - { - event.type = ev_keyup; - event.data1 = KEY_2MOUSE1+j; - D_PostEvent(&event); - om2b ^= 1 << j; - } - } - else - { - if (button & (1<<j)) - { - event.type = ev_keydown; - event.data1 = KEY_2MOUSE1+j; - D_PostEvent(&event); - om2b ^= 1 << j; - } - } - } - event.data2 = ((SINT8)mdata[1])+((SINT8)mdata[3]); - event.data3 = ((SINT8)mdata[2])+((SINT8)mdata[4]); - if (event.data2 && event.data3) - { - event.type = ev_mouse2; - event.data1 = 0; - D_PostEvent(&event); - } - } - i = 0; - } -} - -// -// I_ShutdownMouse2 -// -static void I_ShutdownMouse2(void) -{ - if (fdmouse2 != -1) close(fdmouse2); - mouse2_started = 0; -} -#elif defined (_WIN32) && !defined (_XBOX) - -static HANDLE mouse2filehandle = INVALID_HANDLE_VALUE; - -static void I_ShutdownMouse2(void) -{ - event_t event; - INT32 i; - - if (mouse2filehandle == INVALID_HANDLE_VALUE) - return; - - SetCommMask(mouse2filehandle, 0); - - EscapeCommFunction(mouse2filehandle, CLRDTR); - EscapeCommFunction(mouse2filehandle, CLRRTS); - - PurgeComm(mouse2filehandle, PURGE_TXABORT | PURGE_RXABORT | - PURGE_TXCLEAR | PURGE_RXCLEAR); - - CloseHandle(mouse2filehandle); - - // emulate the up of all mouse buttons - for (i = 0; i < MOUSEBUTTONS; i++) - { - event.type = ev_keyup; - event.data1 = KEY_2MOUSE1+i; - D_PostEvent(&event); - } - - mouse2filehandle = INVALID_HANDLE_VALUE; -} - -#define MOUSECOMBUFFERSIZE 256 -static INT32 handlermouse2x,handlermouse2y,handlermouse2buttons; - -static void I_PoolMouse2(void) -{ - UINT8 buffer[MOUSECOMBUFFERSIZE]; - COMSTAT ComStat; - DWORD dwErrorFlags; - DWORD dwLength; - char dx,dy; - - static INT32 bytenum; - static UINT8 combytes[4]; - DWORD i; - - ClearCommError(mouse2filehandle, &dwErrorFlags, &ComStat); - dwLength = min(MOUSECOMBUFFERSIZE, ComStat.cbInQue); - - if (dwLength <= 0) - return; - - if (!ReadFile(mouse2filehandle, buffer, dwLength, &dwLength, NULL)) - { - CONS_Alert(CONS_WARNING, "%s", M_GetText("Read Error on secondary mouse port\n")); - return; - } - - // parse the mouse packets - for (i = 0; i < dwLength; i++) - { - if ((buffer[i] & 64)== 64) - bytenum = 0; - - if (bytenum < 4) - combytes[bytenum] = buffer[i]; - bytenum++; - - if (bytenum == 1) - { - handlermouse2buttons &= ~3; - handlermouse2buttons |= ((combytes[0] & (32+16)) >> 4); - } - else if (bytenum == 3) - { - dx = (char)((combytes[0] & 3) << 6); - dy = (char)((combytes[0] & 12) << 4); - dx = (char)(dx + combytes[1]); - dy = (char)(dy + combytes[2]); - handlermouse2x+= dx; - handlermouse2y+= dy; - } - else if (bytenum == 4) // fourth UINT8 (logitech mouses) - { - if (buffer[i] & 32) - handlermouse2buttons |= 4; - else - handlermouse2buttons &= ~4; - } - } -} - -void I_GetMouseEvents(void) -{ - static UINT8 lastbuttons2 = 0; //mouse movement - event_t event; - - if (mouse2filehandle == INVALID_HANDLE_VALUE) - return; - - I_PoolMouse2(); - // post key event for buttons - if (handlermouse2buttons != lastbuttons2) - { - INT32 i, j = 1, k; - k = (handlermouse2buttons ^ lastbuttons2); // only changed bit to 1 - lastbuttons2 = (UINT8)handlermouse2buttons; - - for (i = 0; i < MOUSEBUTTONS; i++, j <<= 1) - if (k & j) - { - if (handlermouse2buttons & j) - event.type = ev_keydown; - else - event.type = ev_keyup; - event.data1 = KEY_2MOUSE1+i; - D_PostEvent(&event); - } - } - - if (handlermouse2x != 0 || handlermouse2y != 0) - { - event.type = ev_mouse2; - event.data1 = 0; -// event.data1 = buttons; // not needed - event.data2 = handlermouse2x << 1; - event.data3 = -handlermouse2y << 1; - handlermouse2x = 0; - handlermouse2y = 0; - - D_PostEvent(&event); - } -} -#else -void I_GetMouseEvents(void){}; -#endif - -// -// I_StartupMouse2 -// -void I_StartupMouse2(void) -{ -#ifdef HAVE_TERMIOS - struct termios m2tio; - size_t i; - INT32 dtr = -1, rts = -1;; - I_ShutdownMouse2(); - if (cv_usemouse2.value == 0) return; - if ((fdmouse2 = open(cv_mouse2port.string, O_RDONLY|O_NONBLOCK|O_NOCTTY)) == -1) - { - CONS_Printf(M_GetText("Error opening %s!\n"), cv_mouse2port.string); - return; - } - tcflush(fdmouse2, TCIOFLUSH); - m2tio.c_iflag = IGNBRK; - m2tio.c_oflag = 0; - m2tio.c_cflag = CREAD|CLOCAL|HUPCL|CS8|CSTOPB|B1200; - m2tio.c_lflag = 0; - m2tio.c_cc[VTIME] = 0; - m2tio.c_cc[VMIN] = 1; - tcsetattr(fdmouse2, TCSANOW, &m2tio); - for (i = 0; i < strlen(cv_mouse2opt.string); i++) - { - if (toupper(cv_mouse2opt.string[i]) == 'D') - { - if (cv_mouse2opt.string[i+1] == '-') - dtr = 0; - else - dtr = 1; - } - if (toupper(cv_mouse2opt.string[i]) == 'R') - { - if (cv_mouse2opt.string[i+1] == '-') - rts = 0; - else - rts = 1; - } - if (dtr != -1 || rts != -1) - { - INT32 c; - if (!ioctl(fdmouse2, TIOCMGET, &c)) - { - if (!dtr) - c &= ~TIOCM_DTR; - else if (dtr > 0) - c |= TIOCM_DTR; - } - if (!rts) - c &= ~TIOCM_RTS; - else if (rts > 0) - c |= TIOCM_RTS; - ioctl(fdmouse2, TIOCMSET, &c); - } - } - mouse2_started = 1; - I_AddExitFunc(I_ShutdownMouse2); -#elif defined (_WIN32) && !defined (_XBOX) - DCB dcb; - - if (mouse2filehandle != INVALID_HANDLE_VALUE) - I_ShutdownMouse2(); - - if (cv_usemouse2.value == 0) - return; - - if (mouse2filehandle == INVALID_HANDLE_VALUE) - { - // COM file handle - mouse2filehandle = CreateFileA(cv_mouse2port.string, GENERIC_READ | GENERIC_WRITE, - 0, // exclusive access - NULL, // no security attrs - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (mouse2filehandle == INVALID_HANDLE_VALUE) - { - INT32 e = GetLastError(); - if (e == 5) - CONS_Alert(CONS_ERROR, M_GetText("Can't open %s: Access denied\n"), cv_mouse2port.string); - else - CONS_Alert(CONS_ERROR, M_GetText("Can't open %s: error %d\n"), cv_mouse2port.string, e); - return; - } - } - - // getevent when somthing happens - //SetCommMask(mouse2filehandle, EV_RXCHAR); - - // buffers - SetupComm(mouse2filehandle, MOUSECOMBUFFERSIZE, MOUSECOMBUFFERSIZE); - - // purge buffers - PurgeComm(mouse2filehandle, PURGE_TXABORT | PURGE_RXABORT - | PURGE_TXCLEAR | PURGE_RXCLEAR); - - // setup port to 1200 7N1 - dcb.DCBlength = sizeof (DCB); - - GetCommState(mouse2filehandle, &dcb); - - dcb.BaudRate = CBR_1200; - dcb.ByteSize = 7; - dcb.Parity = NOPARITY; - dcb.StopBits = ONESTOPBIT; - - dcb.fDtrControl = DTR_CONTROL_ENABLE; - dcb.fRtsControl = RTS_CONTROL_ENABLE; - - dcb.fBinary = TRUE; - dcb.fParity = TRUE; - - SetCommState(mouse2filehandle, &dcb); - I_AddExitFunc(I_ShutdownMouse2); -#endif -} - -// -// I_Tactile -// -void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect) -{ - // UNUSED. - (void)pFFType; - (void)FFEffect; -} - -void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect) -{ - // UNUSED. - (void)pFFType; - (void)FFEffect; -} - -/** \brief empty ticcmd for player 1 -*/ -static ticcmd_t emptycmd; - -ticcmd_t *I_BaseTiccmd(void) -{ - return &emptycmd; -} - -/** \brief empty ticcmd for player 2 -*/ -static ticcmd_t emptycmd2; - -ticcmd_t *I_BaseTiccmd2(void) -{ - return &emptycmd2; -} - -#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) -static HMODULE winmm = NULL; -static DWORD starttickcount = 0; // hack for win2k time bug -static p_timeGetTime pfntimeGetTime = NULL; - -// --------- -// I_GetTime -// Use the High Resolution Timer if available, -// else use the multimedia timer which has 1 millisecond precision on Windowz 95, -// but lower precision on Windows NT -// --------- - -tic_t I_GetTime(void) -{ - tic_t newtics = 0; - - if (!starttickcount) // high precision timer - { - LARGE_INTEGER currtime; // use only LowPart if high resolution counter is not available - static LARGE_INTEGER basetime = {{0, 0}}; - - // use this if High Resolution timer is found - static LARGE_INTEGER frequency; - - if (!basetime.LowPart) - { - if (!QueryPerformanceFrequency(&frequency)) - frequency.QuadPart = 0; - else - QueryPerformanceCounter(&basetime); - } - - if (frequency.LowPart && QueryPerformanceCounter(&currtime)) - { - newtics = (INT32)((currtime.QuadPart - basetime.QuadPart) * NEWTICRATE - / frequency.QuadPart); - } - else if (pfntimeGetTime) - { - currtime.LowPart = pfntimeGetTime(); - if (!basetime.LowPart) - basetime.LowPart = currtime.LowPart; - newtics = ((currtime.LowPart - basetime.LowPart)/(1000/NEWTICRATE)); - } - } - else - newtics = (GetTickCount() - starttickcount)/(1000/NEWTICRATE); - - return newtics; -} - -static void I_ShutdownTimer(void) -{ - pfntimeGetTime = NULL; - if (winmm) - { - p_timeEndPeriod pfntimeEndPeriod = (p_timeEndPeriod)GetProcAddress(winmm, "timeEndPeriod"); - if (pfntimeEndPeriod) - pfntimeEndPeriod(1); - FreeLibrary(winmm); - winmm = NULL; - } -} -#else -// -// I_GetTime -// returns time in 1/TICRATE second tics -// -tic_t I_GetTime (void) -{ -#ifdef _arch_dreamcast - static Uint64 basetime = 0; - Uint64 ticks = timer_ms_gettime64(); //using timer_ms_gettime64 instand of SDL_GetTicks for the Dreamcast -#else - static Uint32 basetime = 0; - Uint32 ticks = SDL_GetTicks(); -#endif - - if (!basetime) - basetime = ticks; - - ticks -= basetime; - - ticks = (ticks*TICRATE); - -#if 0 //#ifdef _WIN32_WCE - ticks = (ticks/10); -#else - ticks = (ticks/1000); -#endif - - return (tic_t)ticks; -} -#endif - -// -//I_StartupTimer -// -void I_StartupTimer(void) -{ -#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) - // for win2k time bug - if (M_CheckParm("-gettickcount")) - { - starttickcount = GetTickCount(); - CONS_Printf("%s", M_GetText("Using GetTickCount()\n")); - } - winmm = LoadLibraryA("winmm.dll"); - if (winmm) - { - p_timeEndPeriod pfntimeBeginPeriod = (p_timeEndPeriod)GetProcAddress(winmm, "timeBeginPeriod"); - if (pfntimeBeginPeriod) - pfntimeBeginPeriod(1); - pfntimeGetTime = (p_timeGetTime)GetProcAddress(winmm, "timeGetTime"); - } - I_AddExitFunc(I_ShutdownTimer); -#elif 0 //#elif !defined (_arch_dreamcast) && !defined(GP2X) // the DC have it own timer and GP2X have broken pthreads? - if (SDL_InitSubSystem(SDL_INIT_TIMER) < 0) - I_Error("SRB2: Needs SDL_Timer, Error: %s", SDL_GetError()); -#endif -} - - - -void I_Sleep(void) -{ -#if !(defined (_arch_dreamcast) || defined (_XBOX)) - if (cv_sleep.value != -1) - SDL_Delay(cv_sleep.value); -#endif -} - -INT32 I_StartupSystem(void) -{ - SDL_version SDLcompiled; - const SDL_version *SDLlinked; -#ifdef _XBOX -#ifdef __GNUC__ - char DP[] =" Sonic Robo Blast 2!\n"; - debugPrint(DP); -#endif - unlink("e:/Games/SRB2/stdout.txt"); - freopen("e:/Games/SRB2/stdout.txt", "w+", stdout); - unlink("e:/Games/SRB2/stderr.txt"); - freopen("e:/Games/SRB2/stderr.txt", "w+", stderr); -#endif -#ifdef _arch_dreamcast -#ifdef _DEBUG - //gdb_init(); -#endif - printf(__FILE__":%i\n",__LINE__); -#ifdef _DEBUG - //gdb_breakpoint(); -#endif -#endif - SDL_VERSION(&SDLcompiled) - SDLlinked = SDL_Linked_Version(); - I_StartupConsole(); - I_OutputMsg("Compiled for SDL version: %d.%d.%d\n", - SDLcompiled.major, SDLcompiled.minor, SDLcompiled.patch); - I_OutputMsg("Linked with SDL version: %d.%d.%d\n", - SDLlinked->major, SDLlinked->minor, SDLlinked->patch); -#if 0 //#ifdef GP2X //start up everything - if (SDL_Init(SDL_INIT_NOPARACHUTE|SDL_INIT_EVERYTHING) < 0) -#else - if (SDL_Init(SDL_INIT_NOPARACHUTE) < 0) -#endif - I_Error("SRB2: SDL System Error: %s", SDL_GetError()); //Alam: Oh no.... -#ifndef NOMUMBLE - I_SetupMumble(); -#endif - return 0; -} - - -// -// I_Quit -// -void I_Quit(void) -{ - static SDL_bool quiting = SDL_FALSE; - - /* prevent recursive I_Quit() */ - if (quiting) goto death; - SDLforceUngrabMouse(); - quiting = SDL_FALSE; - I_ShutdownConsole(); - M_SaveConfig(NULL); //save game config, cvars.. -#ifndef NONET - D_SaveBan(); // save the ban list -#endif - G_SaveGameData(); // Tails 12-08-2002 - //added:16-02-98: when recording a demo, should exit using 'q' key, - // but sometimes we forget and use 'F10'.. so save here too. - - if (demorecording) - G_CheckDemoStatus(); - if (metalrecording) - G_StopMetalRecording(); - - D_QuitNetGame(); - I_ShutdownMusic(); - I_ShutdownSound(); - I_ShutdownCD(); - // use this for 1.28 19990220 by Kin - I_ShutdownGraphics(); - I_ShutdownInput(); - I_ShutdownSystem(); -#ifndef _arch_dreamcast - SDL_Quit(); -#endif - /* if option -noendtxt is set, don't print the text */ - if (!M_CheckParm("-noendtxt") && W_CheckNumForName("ENDOOM") != LUMPERROR) - { - printf("\r"); - ShowEndTxt(); - } - if (myargmalloc) - free(myargv); // Deallocate allocated memory -death: - W_Shutdown(); -#ifdef GP2X - chdir("/usr/gp2x"); - execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL); -#endif - exit(0); -} - -void I_WaitVBL(INT32 count) -{ - count = 1; - SDL_Delay(count); -} - -void I_BeginRead(void) -{ -} - -void I_EndRead(void) -{ -} - -// -// I_Error -// -/** \brief phuck recursive errors -*/ -static INT32 errorcount = 0; - -/** \brief recursive error detecting -*/ -static boolean shutdowning = false; - -void I_Error(const char *error, ...) -{ - va_list argptr; -#if (defined (MAC_ALERT) || defined (_WIN32) || (defined (_WIN32_WCE) && !defined (__GNUC__))) && !defined (_XBOX) - char buffer[8192]; -#endif - - // recursive error detecting - if (shutdowning) - { - errorcount++; - if (errorcount == 1) - SDLforceUngrabMouse(); - // try to shutdown each subsystem separately - if (errorcount == 2) - I_ShutdownMusic(); - if (errorcount == 3) - I_ShutdownSound(); - if (errorcount == 4) - I_ShutdownCD(); - if (errorcount == 5) - I_ShutdownGraphics(); - if (errorcount == 6) - I_ShutdownInput(); - if (errorcount == 7) - I_ShutdownSystem(); -#ifndef _arch_dreamcast - if (errorcount == 8) - SDL_Quit(); -#endif - if (errorcount == 9) - { - M_SaveConfig(NULL); - G_SaveGameData(); - } - if (errorcount > 20) - { -#ifdef MAC_ALERT - va_start(argptr, error); - vsprintf(buffer, error, argptr); - va_end(argptr); - // 2004-03-03 AJR Since the Mac user is most likely double clicking to run the game, give them a panel. - MacShowAlert("Recursive Error", buffer, "Quit", NULL, NULL); -#elif (defined (_WIN32) || (defined (_WIN32_WCE)) && !defined (__GNUC__)) && !defined (_XBOX) - va_start(argptr,error); - vsprintf(buffer, error, argptr); - va_end(argptr); -#ifndef _WIN32_WCE - { - HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD bytesWritten; - if (co != INVALID_HANDLE_VALUE) - { - if (GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &bytesWritten)) - WriteConsoleA(co, buffer, (DWORD)strlen(buffer), NULL, NULL); - else - WriteFile(co, buffer, (DWORD)strlen(buffer), &bytesWritten, NULL); - } - } -#endif - OutputDebugStringA(buffer); - MessageBoxA(vid.WndParent, buffer, "SRB2 Recursive Error", MB_OK|MB_ICONERROR); -#else - // Don't print garbage - va_start(argptr, error); - if (!framebuffer) - vfprintf (stderr, error, argptr); - va_end(argptr); -#endif - W_Shutdown(); -#ifdef GP2X - chdir("/usr/gp2x"); - execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL); -#endif - exit(-1); // recursive errors detected - } - } - shutdowning = true; - I_ShutdownConsole(); -#ifndef MAC_ALERT - // Message first. - va_start(argptr,error); - if (!framebuffer) - { - fprintf(stderr, "Error: "); - vfprintf(stderr,error,argptr); - fprintf(stderr, "\n"); - } - va_end(argptr); - - if (!framebuffer) - fflush(stderr); -#endif - M_SaveConfig(NULL); // save game config, cvars.. -#ifndef NONET - D_SaveBan(); // save the ban list -#endif - G_SaveGameData(); // Tails 12-08-2002 - - // Shutdown. Here might be other errors. - if (demorecording) - G_CheckDemoStatus(); - if (metalrecording) - G_StopMetalRecording(); - - D_QuitNetGame(); - I_ShutdownMusic(); - I_ShutdownSound(); - I_ShutdownCD(); - // use this for 1.28 19990220 by Kin - I_ShutdownGraphics(); - I_ShutdownInput(); - I_ShutdownSystem(); -#ifndef _arch_dreamcast - SDL_Quit(); -#endif -#ifdef MAC_ALERT - va_start(argptr, error); - vsprintf(buffer, error, argptr); - va_end(argptr); - // 2004-03-03 AJR Since the Mac user is most likely double clicking to run the game, give them a panel. - MacShowAlert("Critical Error", buffer, "Quit", NULL, NULL); -#endif - W_Shutdown(); -#if defined (PARANOIA) && defined (__CYGWIN__) - *(INT32 *)2 = 4; //Alam: Debug! -#endif -#ifdef GP2X - chdir("/usr/gp2x"); - execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL); -#endif - exit(-1); -} - -/** \brief quit function table -*/ -static quitfuncptr quit_funcs[MAX_QUIT_FUNCS]; /* initialized to all bits 0 */ - -// -// Adds a function to the list that need to be called by I_SystemShutdown(). -// -void I_AddExitFunc(void (*func)()) -{ - INT32 c; - - for (c = 0; c < MAX_QUIT_FUNCS; c++) - { - if (!quit_funcs[c]) - { - quit_funcs[c] = func; - break; - } - } -} - - -// -// Removes a function from the list that need to be called by -// I_SystemShutdown(). -// -void I_RemoveExitFunc(void (*func)()) -{ - INT32 c; - - for (c = 0; c < MAX_QUIT_FUNCS; c++) - { - if (quit_funcs[c] == func) - { - while (c < MAX_QUIT_FUNCS-1) - { - quit_funcs[c] = quit_funcs[c+1]; - c++; - } - quit_funcs[MAX_QUIT_FUNCS-1] = NULL; - break; - } - } -} - -// -// Closes down everything. This includes restoring the initial -// palette and video mode, and removing whatever mouse, keyboard, and -// timer routines have been installed. -// -// NOTE: Shutdown user funcs are effectively called in reverse order. -// -void I_ShutdownSystem(void) -{ - INT32 c; - - for (c = MAX_QUIT_FUNCS-1; c >= 0; c--) - if (quit_funcs[c]) - (*quit_funcs[c])(); -#ifdef LOGMESSAGES - if (logstream) - { - fclose(logstream); - logstream = NULL; - } -#endif - -} - -void I_GetDiskFreeSpace(INT64 *freespace) -{ -#if defined (_arch_dreamcast) || defined (_PSP) - *freespace = 0; -#elif defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) -#if defined (SOLARIS) || defined (__HAIKU__) || defined (_WII) || defined (_PS3) - *freespace = INT32_MAX; - return; -#else // Both Linux and BSD have this, apparently. - struct statfs stfs; - if (statfs(".", &stfs) == -1) - { - *freespace = INT32_MAX; - return; - } - *freespace = stfs.f_bavail * stfs.f_bsize; -#endif -#elif (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) - static p_GetDiskFreeSpaceExA pfnGetDiskFreeSpaceEx = NULL; - static boolean testwin95 = false; - ULARGE_INTEGER usedbytes, lfreespace; - - if (!testwin95) - { - pfnGetDiskFreeSpaceEx = (p_GetDiskFreeSpaceExA)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetDiskFreeSpaceExA"); - testwin95 = true; - } - if (pfnGetDiskFreeSpaceEx) - { - if (pfnGetDiskFreeSpaceEx(NULL, &lfreespace, &usedbytes, NULL)) - *freespace = lfreespace.QuadPart; - else - *freespace = INT32_MAX; - } - else - { - DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters; - GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector, - &NumberOfFreeClusters, &TotalNumberOfClusters); - *freespace = BytesPerSector*SectorsPerCluster*NumberOfFreeClusters; - } -#else // Dummy for platform independent; 1GB should be enough - *freespace = 1024*1024*1024; -#endif -} - -char *I_GetUserName(void) -{ -#ifdef GP2X - static char username[MAXPLAYERNAME] = "GP2XUSER"; - return username; -#elif defined (PSP) - static char username[MAXPLAYERNAME] = "PSPUSER"; - return username; -#elif !(defined (_WIN32_WCE) || defined (_XBOX)) - static char username[MAXPLAYERNAME]; - char *p; -#ifdef _WIN32 - DWORD i = MAXPLAYERNAME; - - if (!GetUserNameA(username, &i)) -#endif - { - p = I_GetEnv("USER"); - if (!p) - { - p = I_GetEnv("user"); - if (!p) - { - p = I_GetEnv("USERNAME"); - if (!p) - { - p = I_GetEnv("username"); - if (!p) - { - return NULL; - } - } - } - } - strncpy(username, p, MAXPLAYERNAME); - } - - - if (strcmp(username, "") != 0) - return username; -#endif - return NULL; // dummy for platform independent version -} - -INT32 I_mkdir(const char *dirname, INT32 unixright) -{ -//[segabor] -#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) || defined (__CYGWIN__) || defined (__OS2__) - return mkdir(dirname, unixright); -#elif (defined (_WIN32) || (defined (_WIN32_WCE) && !defined (__GNUC__))) && !defined (_XBOX) - UNREFERENCED_PARAMETER(unixright); /// \todo should implement ntright under nt... - return CreateDirectoryA(dirname, NULL); -#else - (void)dirname; - (void)unixright; - return false; -#endif -} - -char *I_GetEnv(const char *name) -{ -#ifdef NEED_SDL_GETENV - return SDL_getenv(name); -#elif defined(_WIN32_WCE) - (void)name; - return NULL; -#else - return getenv(name); -#endif -} - -INT32 I_PutEnv(char *variable) -{ -#ifdef NEED_SDL_GETENV - return SDL_putenv(variable); -#elif defined(_WIN32_WCE) - return ((variable)?-1:0); -#else - return putenv(variable); -#endif -} - -INT32 I_ClipboardCopy(const char *data, size_t size) -{ - (void)data; - (void)size; - return -1; -} - -char *I_ClipboardPaste(void) -{ - return NULL; -} - -/** \brief The isWadPathOk function - - \param path string path to check - - \return if true, wad file found - - -*/ -static boolean isWadPathOk(const char *path) -{ - char *wad3path = malloc(256); - - if (!wad3path) - return false; - - sprintf(wad3path, pandf, path, WADKEYWORD1); - - if (FIL_ReadFileOK(wad3path)) - { - free(wad3path); - return true; - } - - sprintf(wad3path, pandf, path, WADKEYWORD2); - - if (FIL_ReadFileOK(wad3path)) - { - free(wad3path); - return true; - } - - free(wad3path); - return false; -} - -static void pathonly(char *s) -{ - size_t j; - - for (j = strlen(s); j != (size_t)-1; j--) - if ((s[j] == '\\') || (s[j] == ':') || (s[j] == '/')) - { - if (s[j] == ':') s[j+1] = 0; - else s[j] = 0; - return; - } -} - -/** \brief search for srb2.srb in the given path - - \param searchDir starting path - - \return WAD path if not NULL - - -*/ -static const char *searchWad(const char *searchDir) -{ - static char tempsw[256] = ""; - filestatus_t fstemp; - - strcpy(tempsw, WADKEYWORD1); - fstemp = filesearch(tempsw,searchDir,NULL,true,20); - if (fstemp == FS_FOUND) - { - pathonly(tempsw); - return tempsw; - } - - strcpy(tempsw, WADKEYWORD2); - fstemp = filesearch(tempsw, searchDir, NULL, true, 20); - if (fstemp == FS_FOUND) - { - pathonly(tempsw); - return tempsw; - } - return NULL; -} - -/** \brief go through all possible paths and look for srb2.srb - - \return path to srb2.srb if any -*/ -static const char *locateWad(void) -{ - const char *envstr; - const char *WadPath; - - I_OutputMsg("SRB2WADDIR"); - // does SRB2WADDIR exist? - if (((envstr = I_GetEnv("SRB2WADDIR")) != NULL) && isWadPathOk(envstr)) - return envstr; - -#if defined(_WIN32_WCE) || defined(_PS3) || defined(_PSP) - // examine argv[0] - strcpy(returnWadPath, myargv[0]); - pathonly(returnWadPath); - I_PutEnv(va("HOME=%s",returnWadPath)); - if (isWadPathOk(returnWadPath)) - return returnWadPath; -#endif - -#ifndef NOCWD - I_OutputMsg(",."); - // examine current dir - strcpy(returnWadPath, "."); - if (isWadPathOk(returnWadPath)) - return NULL; -#endif - - // examine default dirs -#ifdef DEFAULTWADLOCATION1 - I_OutputMsg(","DEFAULTWADLOCATION1); - strcpy(returnWadPath, DEFAULTWADLOCATION1); - if (isWadPathOk(returnWadPath)) - return returnWadPath; -#endif -#ifdef DEFAULTWADLOCATION2 - I_OutputMsg(","DEFAULTWADLOCATION2); - strcpy(returnWadPath, DEFAULTWADLOCATION2); - if (isWadPathOk(returnWadPath)) - return returnWadPath; -#endif -#ifdef DEFAULTWADLOCATION3 - I_OutputMsg(","DEFAULTWADLOCATION3); - strcpy(returnWadPath, DEFAULTWADLOCATION3); - if (isWadPathOk(returnWadPath)) - return returnWadPath; -#endif -#ifdef DEFAULTWADLOCATION4 - I_OutputMsg(","DEFAULTWADLOCATION4); - strcpy(returnWadPath, DEFAULTWADLOCATION4); - if (isWadPathOk(returnWadPath)) - return returnWadPath; -#endif -#ifdef DEFAULTWADLOCATION5 - I_OutputMsg(","DEFAULTWADLOCATION5); - strcpy(returnWadPath, DEFAULTWADLOCATION5); - if (isWadPathOk(returnWadPath)) - return returnWadPath; -#endif -#ifdef DEFAULTWADLOCATION6 - I_OutputMsg(","DEFAULTWADLOCATION6); - strcpy(returnWadPath, DEFAULTWADLOCATION6); - if (isWadPathOk(returnWadPath)) - return returnWadPath; -#endif -#ifdef DEFAULTWADLOCATION7 - I_OutputMsg(","DEFAULTWADLOCATION7); - strcpy(returnWadPath, DEFAULTWADLOCATION7); - if (isWadPathOk(returnWadPath)) - return returnWadPath; -#endif -#ifndef NOHOME - // find in $HOME - I_OutputMsg(",HOME"); - if ((envstr = I_GetEnv("HOME")) != NULL) - { - WadPath = searchWad(envstr); - if (WadPath) - return WadPath; - } -#endif -#ifdef DEFAULTSEARCHPATH1 - // find in /usr/local - I_OutputMsg(", in:"DEFAULTSEARCHPATH1); - WadPath = searchWad(DEFAULTSEARCHPATH1); - if (WadPath) - return WadPath; -#endif -#ifdef DEFAULTSEARCHPATH2 - // find in /usr/games - I_OutputMsg(", in:"DEFAULTSEARCHPATH2); - WadPath = searchWad(DEFAULTSEARCHPATH2); - if (WadPath) - return WadPath; -#endif -#ifdef DEFAULTSEARCHPATH3 - // find in ??? - I_OutputMsg(", in:"DEFAULTSEARCHPATH3); - WadPath = searchWad(DEFAULTSEARCHPATH3); - if (WadPath) - return WadPath; -#endif - // if nothing was found - return NULL; -} - -const char *I_LocateWad(void) -{ - const char *waddir; - - I_OutputMsg("Looking for WADs in: "); - waddir = locateWad(); - I_OutputMsg("\n"); - - if (waddir) - { - // change to the directory where we found srb2.srb -#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) - SetCurrentDirectoryA(waddir); -#elif !defined (_WIN32_WCE) && !defined (_PS3) - if (chdir(waddir) == -1) - I_OutputMsg("Couldn't change working directory\n"); -#endif - } - return waddir; -} - -#ifdef LINUX -#define MEMINFO_FILE "/proc/meminfo" -#define MEMTOTAL "MemTotal:" -#define MEMFREE "MemFree:" -#endif - -// quick fix for compil -UINT32 I_GetFreeMem(UINT32 *total) -{ -#if defined (_arch_dreamcast) - //Dreamcast! - if (total) - *total = 16<<20; - return 8<<20; -#elif defined (_PSP) - // PSP - if (total) - *total = 32<<20; - return 16<<20; -#elif defined (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) - { - *total = 0L; - return 0; - } - if (kvm_nlist(kd, namelist) != 0) - { - kvm_close (kd); - *total = 0L; - return 0; - } - if (kvm_read(kd, namelist[X_SUM].n_value, &sum, - sizeof (sum)) != sizeof (sum)) - { - kvm_close(kd); - *total = 0L; - return 0; - } - kvm_close(kd); - - if (total) - *total = sum.v_page_count * sum.v_page_size; - return sum.v_free_count * sum.v_page_size; -#elif defined (SOLARIS) - /* Just guess */ - if (total) - *total = 32 << 20; - return 32 << 20; -#elif defined (LINUX) - /* Linux */ - char buf[1024]; - char *memTag; - UINT32 freeKBytes; - UINT32 totalKBytes; - INT32 n; - INT32 meminfo_fd = -1; - - meminfo_fd = open(MEMINFO_FILE, O_RDONLY); - n = read(meminfo_fd, buf, 1023); - close(meminfo_fd); - - if (n < 0) - { - // Error - *total = 0L; - return 0; - } - - buf[n] = '\0'; - if (NULL == (memTag = strstr(buf, MEMTOTAL))) - { - // Error - *total = 0L; - return 0; - } - - memTag += sizeof (MEMTOTAL); - totalKBytes = atoi(memTag); - - if (NULL == (memTag = strstr(buf, MEMFREE))) - { - // Error - *total = 0L; - return 0; - } - - memTag += sizeof (MEMFREE); - freeKBytes = atoi(memTag); - - if (total) - *total = totalKBytes << 10; - return freeKBytes << 10; -#elif (defined (_WIN32) || (defined (_WIN32_WCE) && !defined (__GNUC__))) && !defined (_XBOX) - MEMORYSTATUS info; - - info.dwLength = sizeof (MEMORYSTATUS); - GlobalMemoryStatus( &info ); - if (total) - *total = (UINT32)info.dwTotalPhys; - return (UINT32)info.dwAvailPhys; -#elif defined (__OS2__) - UINT32 pr_arena; - - if (total) - DosQuerySysInfo( QSV_TOTPHYSMEM, QSV_TOTPHYSMEM, - (PVOID) total, sizeof (UINT32)); - DosQuerySysInfo( QSV_MAXPRMEM, QSV_MAXPRMEM, - (PVOID) &pr_arena, sizeof (UINT32)); - - return pr_arena; -#else - // Guess 48 MB. - if (total) - *total = 48<<20; - return 48<<20; -#endif /* LINUX */ -} - -const CPUInfoFlags *I_CPUInfo(void) -{ -#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) - static CPUInfoFlags WIN_CPUInfo; - SYSTEM_INFO SI; - p_IsProcessorFeaturePresent pfnCPUID = (p_IsProcessorFeaturePresent)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsProcessorFeaturePresent"); - - ZeroMemory(&WIN_CPUInfo,sizeof (WIN_CPUInfo)); - if (pfnCPUID) - { - WIN_CPUInfo.FPPE = pfnCPUID( 0); //PF_FLOATING_POINT_PRECISION_ERRATA - WIN_CPUInfo.FPE = pfnCPUID( 1); //PF_FLOATING_POINT_EMULATED - WIN_CPUInfo.cmpxchg = pfnCPUID( 2); //PF_COMPARE_EXCHANGE_DOUBLE - WIN_CPUInfo.MMX = pfnCPUID( 3); //PF_MMX_INSTRUCTIONS_AVAILABLE - WIN_CPUInfo.PPCMM64 = pfnCPUID( 4); //PF_PPC_MOVEMEM_64BIT_OK - WIN_CPUInfo.ALPHAbyte = pfnCPUID( 5); //PF_ALPHA_BYTE_INSTRUCTIONS - WIN_CPUInfo.SSE = pfnCPUID( 6); //PF_XMMI_INSTRUCTIONS_AVAILABLE - WIN_CPUInfo.AMD3DNow = pfnCPUID( 7); //PF_3DNOW_INSTRUCTIONS_AVAILABLE - WIN_CPUInfo.RDTSC = pfnCPUID( 8); //PF_RDTSC_INSTRUCTION_AVAILABLE - WIN_CPUInfo.PAE = pfnCPUID( 9); //PF_PAE_ENABLED - WIN_CPUInfo.SSE2 = pfnCPUID(10); //PF_XMMI64_INSTRUCTIONS_AVAILABLE - //WIN_CPUInfo.blank = pfnCPUID(11); //PF_SSE_DAZ_MODE_AVAILABLE - WIN_CPUInfo.DEP = pfnCPUID(12); //PF_NX_ENABLED - WIN_CPUInfo.SSE3 = pfnCPUID(13); //PF_SSE3_INSTRUCTIONS_AVAILABLE - WIN_CPUInfo.cmpxchg16b = pfnCPUID(14); //PF_COMPARE_EXCHANGE128 - WIN_CPUInfo.cmp8xchg16 = pfnCPUID(15); //PF_COMPARE64_EXCHANGE128 - WIN_CPUInfo.PFC = pfnCPUID(16); //PF_CHANNELS_ENABLED - } -#ifdef HAVE_SDLCPUINFO - else - { - WIN_CPUInfo.RDTSC = SDL_HasRDTSC(); - WIN_CPUInfo.MMX = SDL_HasMMX(); - WIN_CPUInfo.AMD3DNow = SDL_Has3DNow(); - WIN_CPUInfo.SSE = SDL_HasSSE(); - WIN_CPUInfo.SSE2 = SDL_HasSSE2(); - WIN_CPUInfo.AltiVec = SDL_HasAltiVec(); - } - WIN_CPUInfo.MMXExt = SDL_HasMMXExt(); - WIN_CPUInfo.AMD3DNowExt = SDL_Has3DNowExt(); -#endif - GetSystemInfo(&SI); - WIN_CPUInfo.CPUs = SI.dwNumberOfProcessors; - WIN_CPUInfo.IA64 = (SI.dwProcessorType == 2200); // PROCESSOR_INTEL_IA64 - WIN_CPUInfo.AMD64 = (SI.dwProcessorType == 8664); // PROCESSOR_AMD_X8664 - return &WIN_CPUInfo; -#elif defined (HAVE_SDLCPUINFO) - static CPUInfoFlags SDL_CPUInfo; - memset(&SDL_CPUInfo,0,sizeof (CPUInfoFlags)); - SDL_CPUInfo.RDTSC = SDL_HasRDTSC(); - SDL_CPUInfo.MMX = SDL_HasMMX(); - SDL_CPUInfo.MMXExt = SDL_HasMMXExt(); - SDL_CPUInfo.AMD3DNow = SDL_Has3DNow(); - SDL_CPUInfo.AMD3DNowExt = SDL_Has3DNowExt(); - SDL_CPUInfo.SSE = SDL_HasSSE(); - SDL_CPUInfo.SSE2 = SDL_HasSSE2(); - SDL_CPUInfo.AltiVec = SDL_HasAltiVec(); - return &SDL_CPUInfo; -#else - return NULL; /// \todo CPUID asm -#endif -} - -#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) -static void CPUAffinity_OnChange(void); -static consvar_t cv_cpuaffinity = {"cpuaffinity", "-1", CV_SAVE | CV_CALL, NULL, CPUAffinity_OnChange, 0, NULL, NULL, 0, 0, NULL}; - -static p_GetCurrentProcess pfnGetCurrentProcess = NULL; -static p_GetProcessAffinityMask pfnGetProcessAffinityMask = NULL; -static p_SetProcessAffinityMask pfnSetProcessAffinityMask = NULL; - -static inline VOID GetAffinityFuncs(VOID) -{ - HMODULE h = GetModuleHandleA("kernel32.dll"); - pfnGetCurrentProcess = (p_GetCurrentProcess)GetProcAddress(h, "GetCurrentProcess"); - pfnGetProcessAffinityMask = (p_GetProcessAffinityMask)GetProcAddress(h, "GetProcessAffinityMask"); - pfnSetProcessAffinityMask = (p_SetProcessAffinityMask)GetProcAddress(h, "SetProcessAffinityMask"); -} - -static void CPUAffinity_OnChange(void) -{ - DWORD_PTR dwProcMask, dwSysMask; - HANDLE selfpid; - - if (!pfnGetCurrentProcess || !pfnGetProcessAffinityMask || !pfnSetProcessAffinityMask) - return; - else - selfpid = pfnGetCurrentProcess(); - - pfnGetProcessAffinityMask(selfpid, &dwProcMask, &dwSysMask); - - /* If resulting mask is zero, don't change anything and fall back to - * actual mask. - */ - if(dwSysMask & cv_cpuaffinity.value) - { - pfnSetProcessAffinityMask(selfpid, dwSysMask & cv_cpuaffinity.value); - CV_StealthSetValue(&cv_cpuaffinity, (INT32)(dwSysMask & cv_cpuaffinity.value)); - } - else - CV_StealthSetValue(&cv_cpuaffinity, (INT32)dwProcMask); -} -#endif - -void I_RegisterSysCommands(void) -{ -#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) - GetAffinityFuncs(); - CV_RegisterVar(&cv_cpuaffinity); -#endif -} -#endif diff --git a/src/sdl12/i_ttf.c b/src/sdl12/i_ttf.c deleted file mode 100644 index 770a81d98596d463248e5b7e032e1bbb835df699..0000000000000000000000000000000000000000 --- a/src/sdl12/i_ttf.c +++ /dev/null @@ -1,340 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 2011 by Callum Dickinson. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief SDL_ttf interface code. Necessary for platforms with no framebuffer console systems. - -#if defined(SDL) && defined(HAVE_TTF) -#include "SDL.h" -#include "SDL_ttf.h" -#include "../doomdef.h" -#include "../doomstat.h" -#include "../d_netfil.h" -#include "../filesrch.h" -#include "i_ttf.h" - -// Search directories to find aforementioned TTF file. -#ifdef _PS3 -#include <sysutil/video.h> -#define FONTSEARCHPATH1 "/dev_hdd0/game/SRB2-PS3_/USRDIR/etc" -#elif defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) -#define FONTSEARCHPATH1 "/usr/share/fonts" -#define FONTSEARCHPATH2 "/usr/local/share/fonts" -#define FONTSEARCHPATH3 "/usr/games/SRB2" -#define FONTSEARCHPATH4 "/usr/local/games/SRB2" -#define FONTSEARCHPATH5 "/usr/local/share/games/SRB2" -#else -#define FONTSEARCHPATH1 "." -#endif - -#define FONTHANDLE -1 - -// Renduring surfaces. -SDL_Surface *TTFSurface = NULL; -SDL_Surface *TTFRendSurface = NULL; -// Text box. -SDL_Rect TTFRect; -// Temporary storage for the new TTFRect, used to check for -// line wrapping. -SDL_Rect TTFRectCheck; -// Text rendering resolution. -videoResolution res; -// Text storage buffer, the contents get printed to the SDL surface. -char textbuffer[8192]; - -// look for default ttf file in given directory -static char *searchFont(const char *fontsearchDir) -{ - static char tempsw[256] = ""; - filestatus_t fstemp; - - strcpy(tempsw, FONTFILE); - fstemp = filesearch(tempsw, fontsearchDir, NULL, true, 20); - if (fstemp == FS_FOUND) - { - return tempsw; - } - return NULL; -} - -// Load TTF font from file. -INT32 I_TTFLoadFont(const char *file, UINT32 ptsize) -{ - TTF_Font *tmpfont = NULL; - float fontsize; - - // If a font is currently loaded, unload it. - if (currentfont) - { - TTF_CloseFont(currentfont); - } - - // Scale the specified font point size for the current resolution. - fontsize = (ptsize * 0.005f) * (res.width - res.height); - - tmpfont = TTF_OpenFont(file, fontsize); - - if (!tmpfont) - return FONTHANDLE; - - // set pointer for current font - currentfont = tmpfont; - - // set current font point size - currentfontpoint = ptsize; - - // get font properties, and set them - currentfontstyle = TTF_GetFontStyle(currentfont); - TTF_SetFontStyle(currentfont, currentfontstyle); - - // these functions only exist in SDL_ttf 2.0.10 onwards -#if SDL_TTF_VERSION_ATLEAST(2,0,10) - currentfontkerning = TTF_GetFontKerning(currentfont); - TTF_SetFontKerning(currentfont, currentfontkerning); - - currentfonthinting = TTF_GetFontHinting(currentfont); - TTF_SetFontHinting(currentfont, currentfonthinting); - - currentfontoutline = TTF_GetFontOutline(currentfont); - TTF_SetFontOutline(currentfont, currentfontoutline); -#endif - - return 0; -} - -static void I_TTFRendSurface(const char *textmsg, TTF_Font *font, TextQuality quality, SDL_Color fontfgcolor, SDL_Color fontbgcolor) -{ - // Print text in the buffer. - // SDL_ttf has three modes to draw text. - // Solid rendering is quick, but dirty. Use it if you need speed more than quality. - switch (quality) - { - case solid: - TTFRendSurface = TTF_RenderText_Solid(font, textmsg, fontfgcolor); - break; - // Shaded rendering adds a background to the rendered text. Because of this, I_TTFDrawText - // takes an extra color more than the other styles to be a background color. - // Shaded is supposedly as fast as solid rendering and about as good quality as blended. - case shaded: - TTFRendSurface = TTF_RenderText_Shaded(font, textmsg, fontfgcolor, fontbgcolor); - break; - // Blended rendering is the opposite of solid. Good quality, but slow. - case blended: - TTFRendSurface = TTF_RenderText_Blended(font, textmsg, fontfgcolor); - break; - } - - // Get SDL to update the main surface. - SDL_BlitSurface(TTFRendSurface, NULL, TTFSurface, &TTFRect); - SDL_Flip(TTFSurface); -} - -// Draw text to screen. It will accept four colour vales (red, green, blue and alpha) -// with foreground for draw modes Solid and Blended, and an extra four values for background -// colour with draw type Shaded. -void I_TTFDrawText(TTF_Font *font, TextQuality quality, INT32 fgR, INT32 fgG, INT32 fgB, INT32 fgA, INT32 bgR, INT32 bgG, INT32 bgB, INT32 bgA, const char *textmsg) -{ - // Temporary small buffer to store character to process. - // NULL pointer to prevc to kill warning - char c, prevc = 0x0; - // hack to allow TTF_SizeText to work properly. - char linebuffer[2]; - // Don't need h, but TTF_SizeText needs a height parameter - INT32 w, h; - - // Globally declare foreground and background text colours, - // text drawing mode and the font to draw. - SDL_Color fontfgcolor = {fgR, fgG, fgB, fgA}; - SDL_Color fontbgcolor = {bgR, bgG, bgB, bgA}; - - // Keep on processing until the null terminator in the text buffer is reached. - while (*textmsg != '\0') - { - // Copy pointer for current character into the temporary buffer. - c = *textmsg; - // If c is a newline, move to the next available line. - if (c == '\n') - { - TTFRectCheck.x = 0; - TTFRectCheck.y += (currentfontpoint + 1); - } - // Otherwise... - else - { - // If the previous character was a newline, actually move to the next line. - if (prevc == '\n') - { - if (textbuffer != NULL) - { - // Render cached text to the SDL surface. - I_TTFRendSurface(textbuffer, font, quality, fontfgcolor, fontbgcolor); - // Empty text buffer. - memset(textbuffer, '\0', 1); - } - TTFRect.x = TTFRectCheck.x; - TTFRect.y = TTFRectCheck.y; - } - // Copy the character to the text buffer. - sprintf(textbuffer, "%s%c", textbuffer, c); - // Hack to allow TTF_SizeText to work properly. - sprintf(linebuffer, "%c", c); - // If we have reached the end of the screen, move to the next available line. - TTF_SizeText(currentfont, linebuffer, &w, &h); - TTFRectCheck.x += w; - if (TTFRectCheck.x >= res.width) - { - // Render cached text to the SDL surface. - I_TTFRendSurface(textbuffer, font, quality, fontfgcolor, fontbgcolor); - // Empty text buffer. - memset(textbuffer, '\0', 1); - // Move to the next line. - TTFRectCheck.x = 0; - TTFRectCheck.y += (currentfontpoint + 1); - // Set stored co-ordinates for next line. - TTFRect.x = TTFRectCheck.x; - TTFRect.y = TTFRectCheck.y; - } - } - // Add 1 to the pointer reference for the character to process. - textmsg++; - // Copy contents of the now-old buffer to somewhere else, so it can be referenced in next loop. - prevc = c; - } - - // If the buffer was previously emptied by a line wrapping operation and - // no text came after that, don't print anything. Otherwise, print everything - // still in the buffer. - if (textbuffer != NULL) - { - // Render cached text to the SDL surface. - I_TTFRendSurface(textbuffer, font, quality, fontfgcolor, fontbgcolor); - // Empty text buffer. - memset(textbuffer, '\0', 1); - // Set stored co-ordinates for next line. - TTFRect.x = TTFRectCheck.x; - TTFRect.y = TTFRectCheck.y; - } -} - -// Initialise SDL_ttf. -void I_StartupTTF(UINT32 fontpointsize, Uint32 initflags, Uint32 vidmodeflags) -{ - char *fontpath = NULL; - INT32 fontstatus = -1; -#ifdef _PS3 - videoState state; - videoGetState(0, 0, &state); - videoGetResolution(state.displayMode.resolution, &res); - bitsperpixel = 24; -#else - res.width = 320; - res.height = 200; - bitsperpixel = 8; -#endif - - // what's the point of trying to display an error? - // SDL_ttf is not started, can't display anything to screen (presumably)... - if (SDL_InitSubSystem(initflags) < 0) - I_Error("Couldn't initialize SDL: %s\n", SDL_GetError()); - - TTFSurface = SDL_SetVideoMode(res.width, res.height, bitsperpixel, vidmodeflags); - if (!TTFSurface) - I_Error("Couldn't set SDL Video resolution: %s\n", SDL_GetError()); - - if (TTF_Init() < 0) - I_Error("Couldn't start SDL_ttf: %s\n", TTF_GetError()); - - // look for default font in many directories -#ifdef FONTSEARCHPATH1 - fontpath = searchFont(FONTSEARCHPATH1); - if (fontpath) fontstatus = I_TTFLoadFont(fontpath, fontpointsize); -#endif -#ifdef FONTSEARCHPATH2 - if (fontstatus < 0) - { - fontpath = searchFont(FONTSEARCHPATH2); - if (fontpath) fontstatus = I_TTFLoadFont(fontpath, fontpointsize); - } -#endif -#ifdef FONTSEARCHPATH3 - if (fontstatus < 0) - { - fontpath = searchFont(FONTSEARCHPATH3); - if (fontpath) fontstatus = I_TTFLoadFont(fontpath, fontpointsize); - } -#endif -#ifdef FONTSEARCHPATH4 - if (fontstatus < 0) - { - fontpath = searchFont(FONTSEARCHPATH4); - if (fontpath) fontstatus = I_TTFLoadFont(fontpath, fontpointsize); - } -#endif -#ifdef FONTSEARCHPATH5 - if (fontstatus < 0) - { - fontpath = searchFont(FONTSEARCHPATH5); - if (fontpath) fontstatus = I_TTFLoadFont(fontpath, fontpointsize); - } -#endif -#ifdef FONTSEARCHPATH6 - if (fontstatus < 0) - { - fontpath = searchFont(FONTSEARCHPATH6); - if (fontpath) fontstatus = I_TTFLoadFont(fontpath, fontpointsize); - } -#endif -#ifdef FONTSEARCHPATH7 - if (fontstatus < 0) - { - fontpath = searchFont(FONTSEARCHPATH7); - if (fontpath) fontstatus = I_TTFLoadFont(fontpath, fontpointsize); - } -#endif - // argh! no font file found! disable SDL_ttf code - if (fontstatus < 0) - { - I_ShutdownTTF(); - CONS_Printf("Unable to find default font files! Not loading SDL_ttf\n"); - } - else - { - // Get SDL_ttf compiled and linked version - SDL_version TTFcompiled; - const SDL_version *TTFlinked; - - SDL_TTF_VERSION(&TTFcompiled); - TTFlinked = TTF_Linked_Version(); - - // Display it on screen - CONS_Printf("Compiled for SDL_ttf version: %d.%d.%d\n", - TTFcompiled.major, TTFcompiled.minor, TTFcompiled.patch); - CONS_Printf("Linked with SDL_ttf version: %d.%d.%d\n", - TTFlinked->major, TTFlinked->minor, TTFlinked->patch); - } -} - -void I_ShutdownTTF(void) -{ - // close current font - TTF_CloseFont(currentfont); - // shutdown SDL_ttf - TTF_Quit(); - - // Free TTF rendering surfaces. - SDL_FreeSurface(TTFSurface); - SDL_FreeSurface(TTFRendSurface); -} -#endif diff --git a/src/sdl12/i_ttf.h b/src/sdl12/i_ttf.h deleted file mode 100644 index 929c8021ccfae374c30415afca9a09e68ccc1c50..0000000000000000000000000000000000000000 --- a/src/sdl12/i_ttf.h +++ /dev/null @@ -1,88 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 2011 by Callum Dickinson. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief SDL_ttf interface code. Necessary for platforms with SDL inits that need to run immediately. - -#ifndef __I_TTF__ -#define __I_TTF__ - -#include "../doomdef.h" -#include "SDL_ttf.h" - -// Default name for standard TTF file. -#define FONTFILE "srb2.ttf" -#define FONTPOINTSIZE 12 - -// Default font foreground colours -#define DEFAULTFONTFGR 255 -#define DEFAULTFONTFGG 255 -#define DEFAULTFONTFGB 255 -#define DEFAULTFONTFGA 255 - -// Default font background colours -#define DEFAULTFONTBGR 0 -#define DEFAULTFONTBGG 0 -#define DEFAULTFONTBGB 0 -#define DEFAULTFONTBGA 255 - -#ifndef SDL_TTF_COMPILEDVERSION -#define SDL_TTF_COMPILEDVERSION \ - SDL_VERSIONNUM(TTF_MAJOR_VERSION, TTF_MINOR_VERSION, TTF_PATCHLEVEL) -#endif - -#ifndef SDL_TTF_VERSION_ATLEAST -#define SDL_TTF_VERSION_ATLEAST(X, Y, Z) \ - (SDL_TTF_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) -#endif - -TTF_Font* currentfont; -int currentfontpoint; -int currentfontstyle; -#if SDL_TTF_VERSION_ATLEAST(2,0,10) -int currentfontkerning; -int currentfonthinting; -int currentfontoutline; -#endif - -#ifndef _PS3 -typedef struct -{ - UINT16 width; - UINT16 height; -} VideoResolution; -#endif -UINT8 bitsperpixel; - -typedef enum -{ - solid, - shaded, - blended -} TextQuality; - -// Load TTF font from file. -INT32 I_TTFLoadFont(const char *file, UINT32 ptsize); - -// Draw TTF text to screen. It will accept four colour vales (red, green, blue and alpha) -// with foreground for draw modes Solid and Blended, and an extra four values for background -// colour with draw type Shaded. -void I_TTFDrawText(TTF_Font *font, TextQuality quality, INT32 fgR, INT32 fgG, INT32 fgB, INT32 fgA, INT32 bgR, INT32 bgG, INT32 bgB, INT32 bgA, const char *textmsg); - -// Initialise SDL_ttf. -void I_StartupTTF(UINT32 fontpointsize, Uint32 initflags, Uint32 vidmodeflags); - -void I_ShutdownTTF(void); -#endif diff --git a/src/sdl12/i_video.c b/src/sdl12/i_video.c deleted file mode 100644 index 349e06cbab345d3ca064bf1e6ce169b669706a77..0000000000000000000000000000000000000000 --- a/src/sdl12/i_video.c +++ /dev/null @@ -1,2101 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1993-1996 by id Software, Inc. -// Portions Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief SRB2 graphics stuff for SDL - -#include <stdlib.h> - -#ifndef _WIN32_WCE -#include <signal.h> -#endif - -#ifdef _MSC_VER -#pragma warning(disable : 4214 4244) -#endif - -#ifdef HAVE_SDL - -#include "SDL.h" - -#ifdef _MSC_VER -#pragma warning(default : 4214 4244) -#endif - -#if SDL_VERSION_ATLEAST(1,2,9) && defined (_arch_dreamcast) -#define HAVE_DCSDL -#include "SDL_dreamcast.h" -#endif - -#if SDL_VERSION_ATLEAST(1,2,9) && defined (GP2X) -#define HAVE_GP2XSDL -#include "SDL_gp2x.h" -#endif - -#if SDL_VERSION_ATLEAST(1,3,0) -#define SDLK_EQUALS SDLK_KP_EQUALSAS400 -#define SDLK_LMETA SDLK_LGUI -#define SDLK_RMETA SDLK_RGUI -#else -#define HAVE_SDLMETAKEYS -#endif - -#ifdef HAVE_TTF -#include "i_ttf.h" -#endif - -#ifdef HAVE_IMAGE -#include "SDL_image.h" -#elseif !(defined (DC) || defined (_WIN32_WCE) || defined (PSP) || defined(GP2X)) -#define LOAD_XPM //I want XPM! -#include "IMG_xpm.c" //Alam: I don't want to add SDL_Image.dll/so -#define HAVE_IMAGE //I have SDL_Image, sortof -#endif - -#ifdef HAVE_IMAGE -#include "SDL_icon.xpm" -#endif - -#include "../doomdef.h" - -#if defined (_WIN32) && !defined (_XBOX) -#include "SDL_syswm.h" -#endif - -#ifdef _arch_dreamcast -#include <conio/conio.h> -#include <dc/maple.h> -#include <dc/maple/vmu.h> -//#include "SRB2DC/VMU.xbm" -//#include <dc/pvr.h> -//#define malloc pvr_mem_malloc -//#define free pvr_mem_free -#endif - -#if defined (_XBOX) && defined (__GNUC__) -#include <openxdk/debug.h> -#endif - -#include "../doomstat.h" -#include "../i_system.h" -#include "../v_video.h" -#include "../m_argv.h" -#include "../m_menu.h" -#include "../d_main.h" -#include "../s_sound.h" -#include "../i_sound.h" // midi pause/unpause -#include "../i_joy.h" -#include "../st_stuff.h" -#include "../g_game.h" -#include "../i_video.h" -#include "../console.h" -#include "../command.h" -#include "sdlmain.h" -#ifdef HWRENDER -#include "../hardware/hw_main.h" -#include "../hardware/hw_drv.h" -// For dynamic referencing of HW rendering functions -#include "hwsym_sdl.h" -#include "ogl_sdl.h" -#endif - -#ifdef REMOTE_DEBUGGING -#ifdef _WII -#include <debug.h> -#endif -#endif - -#ifdef HAVE_FILTER -#define FILTERS -#include "filter/filters.h" -#endif - -// maximum number of windowed modes (see windowedModes[][]) -#if defined (_WIN32_WCE) || defined (DC) || defined (PSP) || defined(GP2X) -#define MAXWINMODES (1) -#elif defined (WII) -#define MAXWINMODES (8) -#elif defined (_PS3) -#define MAXWINMODES (26) -#else -#define MAXWINMODES (27) -#endif - -/** \brief -*/ -static INT32 numVidModes = -1; - -/** \brief -*/ -static char vidModeName[33][32]; // allow 33 different modes - -rendermode_t rendermode=render_soft; - -boolean highcolor = false; - -// synchronize page flipping with screen refresh -#if defined(DC) || (defined(GP2X) && !defined(HAVE_GP2XSDL)) -consvar_t cv_vidwait = {"vid_wait", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -#else -consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif -static consvar_t cv_stretch = {"stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - -UINT8 graphics_started = 0; // Is used in console.c and screen.c - -// To disable fullscreen at startup; is set in VID_PrepareModeList -boolean allow_fullscreen = false; -static SDL_bool disable_fullscreen = SDL_FALSE; -#define USE_FULLSCREEN (disable_fullscreen||!allow_fullscreen)?0:cv_fullscreen.value -static SDL_bool disable_mouse = SDL_FALSE; -#define USE_MOUSEINPUT (!disable_mouse && cv_usemouse.value && SDL_GetAppState() & SDL_APPACTIVE) -#define MOUSE_MENU false //(!disable_mouse && cv_usemouse.value && menuactive && !USE_FULLSCREEN) -#define MOUSEBUTTONS_MAX MOUSEBUTTONS - -// first entry in the modelist which is not bigger than MAXVIDWIDTHxMAXVIDHEIGHT -static INT32 firstEntry = 0; - -// SDL vars -#ifndef HWRENDER //[segabor] !!! I had problem compiling this source with gcc 3.3 -static SDL_Surface *vidSurface = NULL; -#endif -static SDL_Surface *bufSurface = NULL; -static SDL_Surface *icoSurface = NULL; -static SDL_Color localPalette[256]; -static SDL_Rect **modeList = NULL; -#ifdef DC -static Uint8 BitsPerPixel = 15; -#else -static Uint8 BitsPerPixel = 16; -#endif -static Uint16 realwidth = BASEVIDWIDTH; -static Uint16 realheight = BASEVIDHEIGHT; -#ifdef _WIN32_WCE -static const Uint32 surfaceFlagsW = SDL_HWPALETTE; //Can't handle WinCE changing sides -#else -static const Uint32 surfaceFlagsW = SDL_HWPALETTE/*|SDL_RESIZABLE*/; -#endif -#ifdef _PSP -static const Uint32 surfaceFlagsF = SDL_HWSURFACE|SDL_FULLSCREEN; -#else -static const Uint32 surfaceFlagsF = SDL_HWPALETTE|SDL_FULLSCREEN; -#endif -static SDL_bool mousegrabok = SDL_TRUE; -#define HalfWarpMouse(x,y) SDL_WarpMouse((Uint16)(x/2),(Uint16)(y/2)) -#if defined (_WIN32_WCE) || defined (DC) || defined (PSP) || defined(GP2X) -static SDL_bool videoblitok = SDL_TRUE; -#else -static SDL_bool videoblitok = SDL_FALSE; -#endif -static SDL_bool exposevideo = SDL_FALSE; - -// windowed video modes from which to choose from. -static INT32 windowedModes[MAXWINMODES][2] = -{ -#if !(defined (_WIN32_WCE) || defined (DC) || defined (PSP) || defined (GP2X)) -#ifndef WII -#ifndef _PS3 - {1920,1200}, // 1.60,6.00 -#endif - {1680,1050}, // 1.60,5.25 - {1600,1200}, // 1.33,5.00 - {1600,1000}, // 1.60,5.00 - {1536,1152}, // 1.33,4.80 - {1536, 960}, // 1.60,4.80 - {1440, 900}, // 1.60,4.50 - {1400,1050}, // 1.33,4.375 - {1400, 875}, // 1.60,4.375 - {1360, 850}, // 1.60,4.25 - {1280, 960}, // 1.33,4.00 - {1280, 800}, // 1.60,4.00 - {1152, 864}, // 1.33,3.60 - {1120, 700}, // 1.60,3.50 - {1024, 768}, // 1.33,3.20 - { 960, 720}, // 1.33,3.00 - { 960, 600}, // 1.60,3.00 - { 800, 600}, // 1.33,2.50 - { 800, 500}, // 1.60,2.50 -#endif - { 640, 480}, // 1.33,2.00 - { 640, 400}, // 1.60,2.00 - { 576, 432}, // 1.33,1.80 - { 512, 384}, // 1.33,1.60 - { 416, 312}, // 1.33,1.30 - { 400, 300}, // 1.33,1.25 - { 320, 240}, // 1.33,1.00 -#endif - { 320, 200}, // 1.60,1.00 -}; - -static void SDLSetMode(INT32 width, INT32 height, INT32 bpp, Uint32 flags) -{ - const char *SDLVD = I_GetEnv("SDL_VIDEODRIVER"); -#ifdef _WIN32_WCE - if (bpp < 16) - bpp = 16; // 256 mode poo -#endif -#ifdef _WII - bpp = 16; // 8-bit mode poo -#endif -#ifdef DC - if (bpp < 15) - bpp = 15; - height = 240; -#endif -#ifdef PSP - bpp = 16; -#endif -#ifdef GP2X - bpp = 16; -#ifdef HAVE_GP2XSDL - height = 240; -#endif -#endif -#ifdef FILTERS - bpp = Setupf2x(width, height, bpp); -#endif - if (SDLVD && strncasecmp(SDLVD,"glSDL",6) == 0) //for glSDL videodriver - vidSurface = SDL_SetVideoMode(width, height,0,SDL_DOUBLEBUF); -#ifdef _WII // don't want it to use HWSURFACE, so make it first here - else if (SDL_VideoModeOK(width, height, bpp, flags|SDL_SWSURFACE|SDL_DOUBLEBUF) >= bpp) // SDL Wii uses double buffering - vidSurface = SDL_SetVideoMode(width, height, bpp, flags|SDL_SWSURFACE|SDL_DOUBLEBUF); -#endif - else if (cv_vidwait.value && videoblitok && SDL_VideoModeOK(width, height, bpp, flags|SDL_HWSURFACE|SDL_DOUBLEBUF) >= bpp) - vidSurface = SDL_SetVideoMode(width, height, bpp, flags|SDL_HWSURFACE|SDL_DOUBLEBUF); - else if (videoblitok && SDL_VideoModeOK(width, height, bpp, flags|SDL_HWSURFACE) >= bpp) - vidSurface = SDL_SetVideoMode(width, height, bpp, flags|SDL_HWSURFACE); - else if (SDL_VideoModeOK(width, height, bpp, flags|SDL_SWSURFACE) >= bpp) - vidSurface = SDL_SetVideoMode(width, height, bpp, flags|SDL_SWSURFACE); - else return; - realwidth = (Uint16)width; - realheight = (Uint16)height; -#ifdef HAVE_DCSDL - //SDL_DC_SetWindow(320,200); - SDL_DC_EmulateMouse(SDL_FALSE); - SDL_DC_EmulateKeyboard(SDL_TRUE); -#endif -#ifdef HAVE_GP2XSDL - SDL_ShowCursor(SDL_DISABLE); //For GP2X Open2x -#endif -#ifdef FILTERS - if (vidSurface && preSurface && f2xSurface) - { - vid.width = width/2; - vid.height = height/2; - } -#endif -} - -// -// Translates the SDL key into SRB2 key -// - -static INT32 SDLatekey(SDLKey sym) -{ - INT32 rc = sym + 0x80; - -#ifdef _WIN32_WCE - if (sym == SDLK_KP8) - sym = SDLK_UP; - else if (sym == SDLK_KP4) - sym = SDLK_LEFT; - else if (sym == SDLK_KP6) - sym = SDLK_RIGHT; - else if (sym == SDLK_KP2) - sym = SDLK_DOWN; -#endif - - switch (sym) - { - case SDLK_LEFT: - rc = KEY_LEFTARROW; - break; - case SDLK_RIGHT: - rc = KEY_RIGHTARROW; - break; - case SDLK_DOWN: - rc = KEY_DOWNARROW; - break; - case SDLK_UP: - rc = KEY_UPARROW; - break; - - case SDLK_ESCAPE: - rc = KEY_ESCAPE; - break; - case SDLK_SPACE: - rc = KEY_SPACE; - break; - case SDLK_RETURN: - case SDLK_KP_ENTER: - rc = KEY_ENTER; - break; - case SDLK_TAB: - rc = KEY_TAB; - break; - case SDLK_F1: - rc = KEY_F1; - break; - case SDLK_F2: - rc = KEY_F2; - break; - case SDLK_F3: - rc = KEY_F3; - break; - case SDLK_F4: - rc = KEY_F4; - break; - case SDLK_F5: - rc = KEY_F5; - break; - case SDLK_F6: - rc = KEY_F6; - break; - case SDLK_F7: - rc = KEY_F7; - break; - case SDLK_F8: - rc = KEY_F8; - break; - case SDLK_F9: - rc = KEY_F9; - break; - case SDLK_F10: - rc = KEY_F10; - break; - case SDLK_F11: - rc = KEY_F11; - break; - case SDLK_F12: - rc = KEY_F12; - break; - - case SDLK_BACKSPACE: - rc = KEY_BACKSPACE; - break; - case SDLK_DELETE: - rc = KEY_DEL; - break; - - case SDLK_KP_EQUALS: //Alam & Logan: WTF? Mac KB haves one! XD - case SDLK_PAUSE: - rc = KEY_PAUSE; - break; - - case SDLK_EQUALS: - case SDLK_PLUS: - rc = KEY_EQUALS; - break; - - case SDLK_MINUS: - rc = KEY_MINUS; - break; - - case SDLK_LSHIFT: - rc = KEY_LSHIFT; - break; - - case SDLK_RSHIFT: - rc = KEY_RSHIFT; - break; - - case SDLK_CAPSLOCK: - rc = KEY_CAPSLOCK; - break; - - case SDLK_LCTRL: - rc = KEY_LCTRL; - break; - case SDLK_RCTRL: - rc = KEY_RCTRL; - break; - - case SDLK_LALT: - rc = KEY_LALT; - break; - case SDLK_RALT: - rc = KEY_RALT; - break; - - case SDLK_NUMLOCK: - rc = KEY_NUMLOCK; - break; - case SDLK_SCROLLOCK: - rc = KEY_SCROLLLOCK; - break; - - case SDLK_PAGEUP: - rc = KEY_PGUP; - break; - case SDLK_PAGEDOWN: - rc = KEY_PGDN; - break; - case SDLK_END: - rc = KEY_END; - break; - case SDLK_HOME: - rc = KEY_HOME; - break; - case SDLK_INSERT: - rc = KEY_INS; - break; - - case SDLK_KP0: - rc = KEY_KEYPAD0; - break; - case SDLK_KP1: - rc = KEY_KEYPAD1; - break; - case SDLK_KP2: - rc = KEY_KEYPAD2; - break; - case SDLK_KP3: - rc = KEY_KEYPAD3; - break; - case SDLK_KP4: - rc = KEY_KEYPAD4; - break; - case SDLK_KP5: - rc = KEY_KEYPAD5; - break; - case SDLK_KP6: - rc = KEY_KEYPAD6; - break; - case SDLK_KP7: - rc = KEY_KEYPAD7; - break; - case SDLK_KP8: - rc = KEY_KEYPAD8; - break; - case SDLK_KP9: - rc = KEY_KEYPAD9; - break; - - case SDLK_KP_PERIOD: - rc = KEY_KPADDEL; - break; - case SDLK_KP_DIVIDE: - rc = KEY_KPADSLASH; - break; - case SDLK_KP_MULTIPLY: - rc = '*'; - break; - case SDLK_KP_MINUS: - rc = KEY_MINUSPAD; - break; - case SDLK_KP_PLUS: - rc = KEY_PLUSPAD; - break; - -#ifndef _arch_dreamcast - case SDLK_LSUPER: -#ifdef HAVE_SDLMETAKEYS - case SDLK_LMETA: -#endif - rc = KEY_LEFTWIN; - break; - case SDLK_RSUPER: -#ifdef HAVE_SDLMETAKEYS - case SDLK_RMETA: -#endif - rc = KEY_RIGHTWIN; - break; - - case SDLK_MENU: - rc = KEY_MENU; - break; -#endif - - default: - if (sym >= SDLK_SPACE && sym <= SDLK_DELETE) - rc = sym - SDLK_SPACE + ' '; - else if (sym >= 'A' && sym <= 'Z') - rc = sym - 'A' + 'a'; - else if (sym) - { - I_OutputMsg("Unknown Keycode %i, Name: %s\n",sym, SDL_GetKeyName( sym )); - } - else if (!sym) rc = 0; - break; - } - - return rc; -} - -static void SDLdoUngrabMouse(void) -{ - if (SDL_GRAB_ON == SDL_WM_GrabInput(SDL_GRAB_QUERY)) - { - SDL_WM_GrabInput(SDL_GRAB_OFF); - } -} - -void SDLforceUngrabMouse(void) -{ - if (SDL_WasInit(SDL_INIT_VIDEO)==SDL_INIT_VIDEO) - SDL_WM_GrabInput(SDL_GRAB_OFF); -} - -static void VID_Command_NumModes_f (void) -{ - CONS_Printf(M_GetText("%d video mode(s) available(s)\n"), VID_NumModes()); -} - -static void SurfaceInfo(const SDL_Surface *infoSurface, const char *SurfaceText) -{ - INT32 vfBPP; - const SDL_Surface *VidSur = SDL_GetVideoSurface(); - - if (!infoSurface) - return; - - if (!SurfaceText) - SurfaceText = M_GetText("Unknown Surface"); - - vfBPP = infoSurface->format?infoSurface->format->BitsPerPixel:0; - - CONS_Printf("\x82" "%s\n", SurfaceText); - CONS_Printf(M_GetText(" %ix%i at %i bit color\n"), infoSurface->w, infoSurface->h, vfBPP); - - if (infoSurface->flags&SDL_HWSURFACE) - CONS_Printf("%s", M_GetText(" Stored in video memory\n")); - else if (infoSurface->flags&SDL_OPENGL) - CONS_Printf("%s", M_GetText(" Stored in an OpenGL context\n")); - else if (infoSurface->flags&SDL_PREALLOC) - CONS_Printf("%s", M_GetText(" Uses preallocated memory\n")); - else - CONS_Printf("%s", M_GetText(" Stored in system memory\n")); - - if (infoSurface->flags&SDL_ASYNCBLIT) - CONS_Printf("%s", M_GetText(" Uses asynchronous blits if possible\n")); - else - CONS_Printf("%s", M_GetText(" Uses synchronous blits if possible\n")); - - if (infoSurface->flags&SDL_ANYFORMAT) - CONS_Printf("%s", M_GetText(" Allows any pixel-format\n")); - - if (infoSurface->flags&SDL_HWPALETTE) - CONS_Printf("%s", M_GetText(" Has exclusive palette access\n")); - else if (VidSur == infoSurface) - CONS_Printf("%s", M_GetText(" Has nonexclusive palette access\n")); - - if (infoSurface->flags&SDL_DOUBLEBUF) - CONS_Printf("%s", M_GetText(" Double buffered\n")); - else if (VidSur == infoSurface) - CONS_Printf("%s", M_GetText(" No hardware flipping\n")); - - if (infoSurface->flags&SDL_FULLSCREEN) - CONS_Printf("%s", M_GetText(" Full screen\n")); - else if (infoSurface->flags&SDL_RESIZABLE) - CONS_Printf("%s", M_GetText(" Resizable window\n")); - else if (VidSur == infoSurface) - CONS_Printf("%s", M_GetText(" Nonresizable window\n")); - - if (infoSurface->flags&SDL_HWACCEL) - CONS_Printf("%s", M_GetText(" Uses hardware acceleration blit\n")); - if (infoSurface->flags&SDL_SRCCOLORKEY) - CONS_Printf("%s", M_GetText(" Use colorkey blitting\n")); - if (infoSurface->flags&SDL_RLEACCEL) - CONS_Printf("%s", M_GetText(" Colorkey RLE acceleration blit\n")); - if (infoSurface->flags&SDL_SRCALPHA) - CONS_Printf("%s", M_GetText(" Use alpha blending acceleration blit\n")); - -} - -static void VID_Command_Info_f (void) -{ - const SDL_VideoInfo *videoInfo; - videoInfo = SDL_GetVideoInfo(); //Alam: Double-Check - if (videoInfo) - { - CONS_Printf("%s", M_GetText("Video Interface Capabilities:\n")); - if (videoInfo->hw_available) - CONS_Printf("%s", M_GetText(" Hardware surfaces\n")); - if (videoInfo->wm_available) - CONS_Printf("%s", M_GetText(" Window manager\n")); - //UnusedBits1 :6 - //UnusedBits2 :1 - if (videoInfo->blit_hw) - CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW\n")); - if (videoInfo->blit_hw_CC) - CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW with Colorkey\n")); - if (videoInfo->wm_available) - CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW with Alpha\n")); - if (videoInfo->blit_sw) - { - CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW\n")); - if (!M_CheckParm("-noblit")) videoblitok = SDL_TRUE; - } - if (videoInfo->blit_sw_CC) - CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW with Colorkey\n")); - if (videoInfo->blit_sw_A) - CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW with Alpha\n")); - if (videoInfo->blit_fill) - CONS_Printf("%s", M_GetText(" Accelerated Color filling\n")); - //UnusedBits3 :16 - if (videoInfo->video_mem) - CONS_Printf(M_GetText(" There is %i KB of video memory\n"), videoInfo->video_mem); - else - CONS_Printf("%s", M_GetText(" There no video memory for SDL\n")); - //*vfmt - } - SurfaceInfo(bufSurface, M_GetText("Current Engine Mode")); -#ifdef FILTERS - SurfaceInfo(preSurface, M_GetText("Prebuffer Mode")); - SurfaceInfo(f2xSurface, M_GetText("Postbuffer Mode")); -#endif - SurfaceInfo(vidSurface, M_GetText("Current Video Mode")); -} - -static void VID_Command_ModeList_f(void) -{ -#if !defined (DC) && !defined (_WIN32_WCE) && !defined (_PSP) && !defined(GP2X) - INT32 i; -#ifdef HWRENDER - if (rendermode == render_opengl) - modeList = SDL_ListModes(NULL, SDL_OPENGL|SDL_FULLSCREEN); - else -#endif - modeList = SDL_ListModes(NULL, surfaceFlagsF|SDL_HWSURFACE); //Alam: At least hardware surface - - if (modeList == (SDL_Rect **)0 && cv_fullscreen.value) - { - CONS_Printf("%s", M_GetText("No video modes present\n")); - cv_fullscreen.value = 0; - } - else if (modeList != (SDL_Rect **)0) - { - numVidModes = 0; - if (modeList == (SDL_Rect **)-1) - numVidModes = -1; // should not happen with fullscreen modes - else while (modeList[numVidModes]) - numVidModes++; - } - CONS_Printf(M_GetText("Found %d FullScreen Video Modes:\n"), numVidModes); - for (i=0 ; i<numVidModes; i++) - { // fullscreen modes - INT32 modeNum = firstEntry + i; - if (modeNum >= numVidModes) - break; - - CONS_Printf(M_GetText("%dx%d and "), - modeList[modeNum]->w, - modeList[modeNum]->h); - } - CONS_Printf("%s", M_GetText("None\n")); -#endif -} - -static void VID_Command_Mode_f (void) -{ - INT32 modenum; - - if (COM_Argc()!= 2) - { - CONS_Printf(M_GetText("vid_mode <modenum> : set video mode, current video mode %i\n"), vid.modenum); - return; - } - - modenum = atoi(COM_Argv(1)); - - if (modenum >= VID_NumModes()) - CONS_Printf(M_GetText("Video mode not present\n")); - else - setmodeneeded = modenum+1; // request vid mode change -} - -#if defined(RPC_NO_WINDOWS_H) && !defined(_WIN32_WCE) -static VOID MainWndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - UNREFERENCED_PARAMETER(hWnd); - UNREFERENCED_PARAMETER(message); - UNREFERENCED_PARAMETER(wParam); - switch (message) - { - case WM_SETTEXT: - COM_BufAddText((LPCSTR)lParam); - break; - } -} -#endif - -#if 0 //#ifdef _WIN32 - // Disable Composition in Vista DWM (Desktop Window Manager) ---------------- -static HMODULE DMdll = NULL; -typedef HRESULT (CALLBACK *P_DwmIsCompositionEnabled) (BOOL *pfEnabled); -static P_DwmIsCompositionEnabled pfnDwmIsCompositionEnabled = NULL; -typedef HRESULT (CALLBACK *P_DwmEnableComposition) (BOOL fEnable); -static P_DwmEnableComposition pfnDwmEnableComposition = NULL; -static BOOL AeroWasEnabled = FALSE; - -static inline VOID UnloadDM(VOID) -{ - pfnDwmEnableComposition = NULL; - pfnDwmIsCompositionEnabled = NULL; - if (DMdll) FreeLibrary(DMdll); - DMdll = NULL; -} - -static inline BOOL LoadDM(VOID) -{ - if (DMdll) - return TRUE; - - DMdll = LoadLibraryA("dwmapi.dll"); - if (DMdll) - I_OutputMsg("dmwapi.dll loaded, Vista's Desktop Window Manager API\n"); - else - return FALSE; - - pfnDwmIsCompositionEnabled = (P_DwmIsCompositionEnabled)GetProcAddress(DMdll, "DwmIsCompositionEnabled"); - if (pfnDwmIsCompositionEnabled) - I_OutputMsg("Composition Aero API found, DwmIsCompositionEnabled\n"); - - pfnDwmEnableComposition = (P_DwmEnableComposition)GetProcAddress(DMdll, "DwmEnableComposition"); - if (pfnDwmEnableComposition) - I_OutputMsg("Composition Aero API found, DwmEnableComposition\n"); - - return TRUE; -} - -static inline VOID DisableAero(VOID) -{ - BOOL pfnDwmEnableCompositiond = FALSE; - AeroWasEnabled = FALSE; - - if (!LoadDM()) - return; - - if (pfnDwmIsCompositionEnabled && SUCCEEDED(pfnDwmIsCompositionEnabled(&pfnDwmEnableCompositiond))) - I_OutputMsg("Got the result of DwmIsCompositionEnabled, %i\n", pfnDwmEnableCompositiond); - else - return; - - if ((AeroWasEnabled = pfnDwmEnableCompositiond)) - I_OutputMsg("Disable the Aero rendering\n"); - else - return; - - if (pfnDwmEnableComposition && SUCCEEDED(pfnDwmEnableComposition(FALSE))) - I_OutputMsg("Aero rendering disabled\n"); - else - I_OutputMsg("We failed to disable the Aero rendering\n"); -} - -static inline VOID ResetAero(VOID) -{ - if (pfnDwmEnableComposition && AeroWasEnabled) - { - if (SUCCEEDED(pfnDwmEnableComposition(AeroWasEnabled))) - I_OutputMsg("Aero rendering setting restored\n"); - else - I_OutputMsg("We failed to restore Aero rendering\n"); - } - UnloadDM(); -} -#endif - -static inline void SDLJoyRemap(event_t *event) -{ -#if defined(GP2X) -#define GP2X_BUTTON_UP (0) -#define GP2X_BUTTON_DOWN (4) -#define GP2X_BUTTON_LEFT (2) -#define GP2X_BUTTON_RIGHT (6) -#define GP2X_BUTTON_UPLEFT (1) -#define GP2X_BUTTON_UPRIGHT (7) -#define GP2X_BUTTON_DOWNLEFT (3) -#define GP2X_BUTTON_DOWNRIGHT (5) -#define GP2X_BUTTON_CLICK (18) -#define GP2X_BUTTON_A (12) -#define GP2X_BUTTON_B (13) -#define GP2X_BUTTON_X (14) -#define GP2X_BUTTON_Y (15) -#define GP2X_BUTTON_L (10) -#define GP2X_BUTTON_R (11) -#define GP2X_BUTTON_START (8) -#define GP2X_BUTTON_SELECT (9) -#define GP2X_BUTTON_VOLUP (16) -#define GP2X_BUTTON_VOLDOWN (17) - if ((event->type == ev_keydown || event->type == ev_keyup) && (KEY_JOY1 <= event->data1 && event->data1 <= KEY_JOY1+JOYBUTTONS)) - { - INT32 button = event->data1-KEY_JOY1; - if (button <= 7) - { - static UINT8 DPAD = 0; - if (event->type == ev_keyup) - { - event->type = ev_console; - DPAD &= ~(1<<button); - } - else - { - event->type = ev_joystick; - DPAD |= 1<<button; - } - event->data2 = event->data3 = INT32_MAX; - if ((DPAD & (1<<GP2X_BUTTON_UP)) && ((DPAD & (1<<GP2X_BUTTON_UPLEFT)) || (DPAD & (1<<GP2X_BUTTON_UPRIGHT)))) - button = GP2X_BUTTON_UP; - if ((DPAD & (1<<GP2X_BUTTON_LEFT)) && ((DPAD & (1<<GP2X_BUTTON_UPLEFT)) || (DPAD & (1<<GP2X_BUTTON_DOWNLEFT)))) - button = GP2X_BUTTON_LEFT; - if ((DPAD & (1<<GP2X_BUTTON_DOWN)) && ((DPAD & (1<<GP2X_BUTTON_DOWNLEFT)) || (DPAD & (1<<GP2X_BUTTON_DOWNRIGHT)))) - button = GP2X_BUTTON_DOWN; - if ((DPAD & (1<<GP2X_BUTTON_RIGHT)) && ((DPAD & (1<<GP2X_BUTTON_UPRIGHT)) || (DPAD & (1<<GP2X_BUTTON_DOWNRIGHT)))) - button = GP2X_BUTTON_RIGHT; - if (DPAD == 0) - { - event->type = ev_joystick; - event->data2 = event->data3 = 0; - } - else switch (button) - { - case GP2X_BUTTON_UP: - event->data3 = -1; - break; - case GP2X_BUTTON_DOWN: - event->data3 = 1; - break; - case GP2X_BUTTON_LEFT: - event->data2 = -1; - break; - case GP2X_BUTTON_RIGHT: - event->data2 = 1; - break; - case GP2X_BUTTON_UPLEFT: - event->data2 = -1; - event->data3 = -1; - break; - case GP2X_BUTTON_UPRIGHT: - event->data2 = 1; - event->data3 = -1; - break; - case GP2X_BUTTON_DOWNLEFT: - event->data2 = -1; - event->data3 = 1; - break; - case GP2X_BUTTON_DOWNRIGHT: - event->data2 = 1; - event->data3 = 1; - default: - break; - } - event->data1 = 0; - return; - } - else switch (button) - { - case GP2X_BUTTON_CLICK: - event->data1 = KEY_ENTER; - break; - case GP2X_BUTTON_A: - event->data1 = KEY_JOY1+0; - break; - case GP2X_BUTTON_B: - event->data1 = KEY_JOY1+2; - break; - case GP2X_BUTTON_X: - event->data1 = KEY_JOY1+3; - break; - case GP2X_BUTTON_Y: - event->data1 = KEY_JOY1+1; - break; - case GP2X_BUTTON_L: - event->data1 = KEY_JOY1+4; - break; - case GP2X_BUTTON_R: - event->data1 = KEY_JOY1+5; - break; - case GP2X_BUTTON_START: - event->data1 = KEY_ESCAPE; - break; - case GP2X_BUTTON_SELECT: - event->data1 = KEY_JOY1+8; - break; - case GP2X_BUTTON_VOLUP: - event->data1 = KEY_JOY1+6; - break; - case GP2X_BUTTON_VOLDOWN: - event->data1 = KEY_JOY1+7; - break; - default: - break; - } - //I_OutputMsg("Button %i: event key %i and type: %i\n", button, event->data1, event->type); - } -#elif defined(_PSP) - if (event->data1 > KEY_JOY1 + 9 + 2) // All button after D-Pad and Select/Start - event->data1 -= 4; // remap D-pad to Hats, offset of -4 - else if (event->data1 == KEY_JOY1 + 6) // Down - event->data1 = KEY_HAT1+1; - else if (event->data1 == KEY_JOY1 + 7) // Left - event->data1 = KEY_HAT1+2; - else if (event->data1 == KEY_JOY1 + 8) // Up - event->data1 = KEY_HAT1+0; - else if (event->data1 == KEY_JOY1 + 9) // Right - event->data1 = KEY_HAT1+3; - else if (event->data1 == KEY_JOY1 + 10) // Select - event->data1 = KEY_TAB; - else if (event->data1 == KEY_JOY1 + 11) // Start - event->data1 = KEY_ESCAPE; -#else - (void)event; -#endif -} - -static INT32 SDLJoyAxis(const Sint16 axis, evtype_t which) -{ -#ifdef _arch_dreamcast // -128 to 127 SDL for DC have give us a smaller range - INT32 raxis = axis*8; -#else // -32768 to 32767 - INT32 raxis = axis/32; -#endif - if (which == ev_joystick) - { - if (Joystick.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (raxis < -(JOYAXISRANGE/2)) - raxis = -1; - else if (raxis > (JOYAXISRANGE/2)) - raxis = 1; - else - raxis = 0; - } - else - { - raxis = JoyInfo.scale!=1?((raxis/JoyInfo.scale)*JoyInfo.scale):raxis; - -#ifdef SDL_JDEADZONE - if (-SDL_JDEADZONE <= raxis && raxis <= SDL_JDEADZONE) - raxis = 0; -#endif - } - } - else if (which == ev_joystick2) - { - if (Joystick2.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (raxis < -(JOYAXISRANGE/2)) - raxis = -1; - else if (raxis > (JOYAXISRANGE/2)) - raxis = 1; - else raxis = 0; - } - else - { - raxis = JoyInfo2.scale!=1?((raxis/JoyInfo2.scale)*JoyInfo2.scale):raxis; - -#ifdef SDL_JDEADZONE - if (-SDL_JDEADZONE <= raxis && raxis <= SDL_JDEADZONE) - raxis = 0; -#endif - } - } - return raxis; -} - -void I_GetEvent(void) -{ - SDL_Event inputEvent; - static SDL_bool sdlquit = SDL_FALSE; //Alam: once, just once - event_t event; - - if (!graphics_started) - return; - - memset(&inputEvent, 0x00, sizeof(inputEvent)); - while (SDL_PollEvent(&inputEvent)) - { - memset(&event,0x00,sizeof (event_t)); - switch (inputEvent.type) - { - case SDL_ACTIVEEVENT: - if (inputEvent.active.state & (SDL_APPACTIVE|SDL_APPINPUTFOCUS)) - { - // pause music when alt-tab - if (inputEvent.active.gain /*&& !paused */) - { - static SDL_bool firsttimeonmouse = SDL_TRUE; - if (!firsttimeonmouse) - { - if (cv_usemouse.value) I_StartupMouse(); - } - else firsttimeonmouse = SDL_FALSE; - //if (!netgame && !con_destlines) paused = false; - if (gamestate == GS_LEVEL) - if (!paused) I_ResumeSong(0); //resume it - } - else /*if (!paused)*/ - { - if (!disable_mouse) - SDLforceUngrabMouse(); - if (!netgame && gamestate == GS_LEVEL) paused = true; - memset(gamekeydown, 0, NUMKEYS); - //S_PauseSound(); - if (gamestate == GS_LEVEL) - I_PauseSong(0); //pause it - } - } - if (MOUSE_MENU) - { - SDLdoUngrabMouse(); - break; - } - if ((SDL_APPMOUSEFOCUS&inputEvent.active.state) && USE_MOUSEINPUT && inputEvent.active.gain) - HalfWarpMouse(realwidth, realheight); - break; - case SDL_KEYDOWN: - case SDL_KEYUP: - /// \todo inputEvent.key.which? - if (inputEvent.type == SDL_KEYUP) - event.type = ev_keyup; - else if (inputEvent.type == SDL_KEYDOWN) - event.type = ev_keydown; - else break; - event.data1 = SDLatekey(inputEvent.key.keysym.sym); - if (event.data1) D_PostEvent(&event); - break; - case SDL_MOUSEMOTION: - /// \todo inputEvent.motion.which - if (MOUSE_MENU) - { - SDLdoUngrabMouse(); - break; - } - if (USE_MOUSEINPUT) - { - // If the event is from warping the pointer back to middle - // of the screen then ignore it. - if ((inputEvent.motion.x == realwidth/2) && - (inputEvent.motion.y == realheight/2)) - { - break; - } - else - { - event.data2 = +inputEvent.motion.xrel; - event.data3 = -inputEvent.motion.yrel; - } - event.type = ev_mouse; - D_PostEvent(&event); - // Warp the pointer back to the middle of the window - // or we cannot move any further if it's at a border. - if ((inputEvent.motion.x < (realwidth/2 )-(realwidth/4 )) || - (inputEvent.motion.y < (realheight/2)-(realheight/4)) || - (inputEvent.motion.x > (realwidth/2 )+(realwidth/4 )) || - (inputEvent.motion.y > (realheight/2)+(realheight/4) ) ) - { - //if (SDL_GRAB_ON == SDL_WM_GrabInput(SDL_GRAB_QUERY) || !mousegrabok) - HalfWarpMouse(realwidth, realheight); - } - } - break; - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - /// \todo inputEvent.button.which - if (USE_MOUSEINPUT) - { - if (inputEvent.type == SDL_MOUSEBUTTONUP) - event.type = ev_keyup; - else if (inputEvent.type == SDL_MOUSEBUTTONDOWN) - event.type = ev_keydown; - else break; - if (inputEvent.button.button==SDL_BUTTON_WHEELUP || inputEvent.button.button==SDL_BUTTON_WHEELDOWN) - { - if (inputEvent.type == SDL_MOUSEBUTTONUP) - event.data1 = 0; //Alam: dumb! this could be a real button with some mice - else - event.data1 = KEY_MOUSEWHEELUP + inputEvent.button.button - SDL_BUTTON_WHEELUP; - } - else if (inputEvent.button.button == SDL_BUTTON_MIDDLE) - event.data1 = KEY_MOUSE1+2; - else if (inputEvent.button.button == SDL_BUTTON_RIGHT) - event.data1 = KEY_MOUSE1+1; - else if (inputEvent.button.button <= MOUSEBUTTONS) - event.data1 = KEY_MOUSE1 + inputEvent.button.button - SDL_BUTTON_LEFT; - if (event.data1) D_PostEvent(&event); - } - break; - case SDL_JOYAXISMOTION: - inputEvent.jaxis.which++; - inputEvent.jaxis.axis++; - event.data1 = event.data2 = event.data3 = INT32_MAX; - if (cv_usejoystick.value == inputEvent.jaxis.which) - { - event.type = ev_joystick; - } - else if (cv_usejoystick.value == inputEvent.jaxis.which) - { - event.type = ev_joystick2; - } - else break; - //axis - if (inputEvent.jaxis.axis > JOYAXISSET*2) - break; - //vaule - if (inputEvent.jaxis.axis%2) - { - event.data1 = inputEvent.jaxis.axis / 2; - event.data2 = SDLJoyAxis(inputEvent.jaxis.value, event.type); - } - else - { - inputEvent.jaxis.axis--; - event.data1 = inputEvent.jaxis.axis / 2; - event.data3 = SDLJoyAxis(inputEvent.jaxis.value, event.type); - } - D_PostEvent(&event); - break; - case SDL_JOYBALLMOTION: - case SDL_JOYHATMOTION: - break; //NONE - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - inputEvent.jbutton.which++; - if (cv_usejoystick.value == inputEvent.jbutton.which) - event.data1 = KEY_JOY1; - else if (cv_usejoystick.value == inputEvent.jbutton.which) - event.data1 = KEY_2JOY1; - else break; - if (inputEvent.type == SDL_JOYBUTTONUP) - event.type = ev_keyup; - else if (inputEvent.type == SDL_JOYBUTTONDOWN) - event.type = ev_keydown; - else break; - if (inputEvent.jbutton.button < JOYBUTTONS) - event.data1 += inputEvent.jbutton.button; - else - break; - SDLJoyRemap(&event); - if (event.type != ev_console) D_PostEvent(&event); - break; -#ifndef _WIN32_WCE - case SDL_QUIT: - if (!sdlquit) - { - sdlquit = SDL_TRUE; - M_QuitResponse('y'); - } - break; -#endif -#if defined(RPC_NO_WINDOWS_H) && !defined(_WIN32_WCE) - case SDL_SYSWMEVENT: - MainWndproc(inputEvent.syswm.msg->hwnd, - inputEvent.syswm.msg->msg, - inputEvent.syswm.msg->wParam, - inputEvent.syswm.msg->lParam); - break; -#endif - case SDL_VIDEORESIZE: - if (gamestate == GS_LEVEL || gamestate == GS_TITLESCREEN || gamestate == GS_EVALUATION) - setmodeneeded = VID_GetModeForSize(inputEvent.resize.w,inputEvent.resize.h)+1; - if (render_soft == rendermode) - { -#ifdef FILTERS - INT32 filtervalue = cv_filter.value; - if (blitfilter) CV_SetValue(&cv_filter,1); -#endif - SDLSetMode(realwidth, realheight, vid.bpp*8, surfaceFlagsW); - if (vidSurface) SDL_SetColors(vidSurface, localPalette, 0, 256); -#ifdef FILTERS - CV_SetValue(&cv_filter,filtervalue); -#endif - } - else - SDLSetMode(realwidth, realheight, vid.bpp*8, surfaceFlagsW); - if (!vidSurface) - I_Error("Could not reset vidmode: %s\n",SDL_GetError()); - break; - case SDL_VIDEOEXPOSE: - exposevideo = SDL_TRUE; - break; - default: - break; - } - } - //reset wheel like in win32, I don't understand it but works - gamekeydown[KEY_MOUSEWHEELDOWN] = gamekeydown[KEY_MOUSEWHEELUP] = 0; -} - -void I_StartupMouse(void) -{ - static SDL_bool firsttimeonmouse = SDL_TRUE; - - if (disable_mouse) - return; - - if (!firsttimeonmouse) - HalfWarpMouse(realwidth, realheight); // warp to center - else - firsttimeonmouse = SDL_FALSE; - if (cv_usemouse.value) - return; - else - SDLdoUngrabMouse(); -} - -// -// I_OsPolling -// -void I_OsPolling(void) -{ - if (consolevent) - I_GetConsoleEvents(); - if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) - { - SDL_JoystickUpdate(); - I_GetJoystickEvents(); - I_GetJoystick2Events(); - } -#ifdef _arch_dreamcast - //vmu_set_icon(VMU_bits); -#endif - - I_GetMouseEvents(); - - I_GetEvent(); -} - -// -// I_UpdateNoBlit -// -void I_UpdateNoBlit(void) -{ - if (!vidSurface) - return; -#ifdef HWRENDER - if (rendermode != render_soft) - OglSdlFinishUpdate(cv_vidwait.value); - else -#endif - if (vidSurface->flags&SDL_DOUBLEBUF) - SDL_Flip(vidSurface); - else if (exposevideo) - SDL_UpdateRect(vidSurface, 0, 0, 0, 0); - exposevideo = SDL_FALSE; -} - -// I_SkipFrame -// -// Returns true if it thinks we can afford to skip this frame -// from PrBoom's src/SDL/i_video.c -static inline boolean I_SkipFrame(void) -{ - static boolean skip = false; - - if (render_soft != rendermode) - return false; - - skip = !skip; - -#if 0 //(defined (GP2X) || defined (PSP) || defined (_arch_dreamcast)) - return skip; -#endif - - switch (gamestate) - { - case GS_LEVEL: - if (!paused) - return false; - case GS_TIMEATTACK: - case GS_WAITINGPLAYERS: - return skip; // Skip odd frames - default: - return false; - } -} - -static inline SDL_bool SDLmatchVideoformat(void) -{ - const SDL_PixelFormat *vidformat = vidSurface->format; - const INT32 vfBPP = vidformat?vidformat->BitsPerPixel:0; - return (((vfBPP == 8 && vid.bpp == 1 && - !vidformat->Rmask && !vidformat->Gmask && !vidformat->Bmask) || - (vfBPP == 15 && vid.bpp == 2 && vidformat->Rmask == 0x7C00 && - vidformat->Gmask == 0x03E0 && vidformat->Bmask == 0x001F )) && - !vidformat->Amask && (vidSurface->flags & SDL_RLEACCEL) == 0); -} - -// -// I_FinishUpdate -// -void I_FinishUpdate(void) -{ - if (!vidSurface) - return; //Alam: No software or OpenGl surface - - if (I_SkipFrame()) - return; - - if (cv_ticrate.value) - SCR_DisplayTicRate(); - - if (render_soft == rendermode && screens[0]) - { - SDL_Rect *dstrect = NULL; - SDL_Rect rect = {0, 0, 0, 0}; - SDL_PixelFormat *vidformat = vidSurface->format; - int lockedsf = 0, blited = 0; - - rect.w = (Sint16)vid.width; - rect.h = (Sint16)vid.height; - - if (vidSurface->h > vid.height) - rect.y = (Sint16)((vidSurface->h-vid.height)/2); - - dstrect = ▭ - - - if (!bufSurface && !vid.direct) //Double-Check - { - if (vid.bpp == 1) bufSurface = SDL_CreateRGBSurfaceFrom(screens[0],vid.width,vid.height,8, - (int)vid.rowbytes,0x00000000,0x00000000,0x00000000,0x00000000); // 256 mode - else if (vid.bpp == 2) bufSurface = SDL_CreateRGBSurfaceFrom(screens[0],vid.width,vid.height,15, - (int)vid.rowbytes,0x00007C00,0x000003E0,0x0000001F,0x00000000); // 555 mode - if (bufSurface) SDL_SetColors(bufSurface, localPalette, 0, 256); - else I_OutputMsg("No system memory for SDL buffer surface\n"); - } - -#ifdef FILTERS - FilterBlit(bufSurface); - if (f2xSurface) //Alam: filter! - { - //I_OutputMsg("2x Filter Code\n"); - blited = SDL_BlitSurface(f2xSurface,NULL,vidSurface,NULL); - } - else -#endif -#if 0 - if (SDLmatchVideoformat() && !vid.direct)//Alam: DOS Way - { - if (SDL_MUSTLOCK(vidSurface)) lockedsf = SDL_LockSurface(vidSurface); - if (lockedsf == 0) - { - if (vidSurface->pixels > vid.height) - { - UINT8 *ptr = vidSurface->pixels; - size_t half_excess = vidSurface->pitch*(vidSurface->height-vid.height)/2; - memset(ptr, 0x1F, half_excess); - ptr += half_excess; - VID_BlitLinearScreen(screens[0], ptr, vid.width*vid.bpp, vid.height, - vid.rowbytes, vidSurface->pitch); - ptr += vid.height*vidSurface->pitch; - memset(ptr, 0x1F, half_excess); - } - else - VID_BlitLinearScreen(screens[0], vidSurface->pixels, vid.width*vid.bpp, - vid.height, vid.rowbytes, vidSurface->pitch ); - if (SDL_MUSTLOCK(vidSurface)) SDL_UnlockSurface(vidSurface); - } - } - else -#endif - if (bufSurface) //Alam: New Way to send video data - { - blited = SDL_BlitSurface(bufSurface,NULL,vidSurface,dstrect); - } - else if (vid.bpp == 1 && !vid.direct) - { - Uint8 *bP,*vP; //Src, Dst - Uint16 bW, vW; // Pitch Remainder - Sint32 pH, pW; //Height, Width - bP = (Uint8 *)screens[0]; - bW = (Uint16)(vid.rowbytes - vid.width); - //I_OutputMsg("Old Copy Code\n"); - if (SDL_MUSTLOCK(vidSurface)) lockedsf = SDL_LockSurface(vidSurface); - vP = (Uint8 *)vidSurface->pixels; - vW = (Uint16)(vidSurface->pitch - vidSurface->w*vidformat->BytesPerPixel); - if (vidSurface->h > vid.height) - vP += vidSurface->pitch*(vidSurface->h-vid.height)/2; - if (lockedsf == 0 && vidSurface->pixels) - { - if (vidformat->BytesPerPixel == 2) - { - for (pH=0;pH < vidSurface->h;pH++) - { - for (pW=0;pW < vidSurface->w;pW++) - { - *((Uint16 *)(void *)vP) = (Uint16)SDL_MapRGB(vidformat, - localPalette[*bP].r,localPalette[*bP].g,localPalette[*bP].b); - bP++; - vP += 2; - } - bP += bW; - vP += vW; - } - } - else if (vidformat->BytesPerPixel == 3) - { - for (pH=0;pH < vidSurface->h;pH++) - { - for (pW=0;pW < vidSurface->w;pW++) - { - *((Uint32 *)(void *)vP) = SDL_MapRGB(vidformat, - localPalette[*bP].r,localPalette[*bP].g,localPalette[*bP].b); - bP++; - vP += 3; - } - bP += bW; - vP += vW; - } - } - else if (vidformat->BytesPerPixel == 4) - { - for (pH=0;pH < vidSurface->h;pH++) - { - for (pW=0;pW < vidSurface->w;pW++) - { - *((Uint32 *)(void *)vP) = SDL_MapRGB(vidformat, - localPalette[*bP].r,localPalette[*bP].g,localPalette[*bP].b); - bP++; - vP += 4; - } - bP += bW; - vP += vW; - } - } - else - { - ;//NOP - } - } - if (SDL_MUSTLOCK(vidSurface)) SDL_UnlockSurface(vidSurface); - } - else /// \todo 15t15,15tN, others? - { - ;//NOP - } - -#ifdef HAVE_GP2XSDL - //if (blited == 0) - SDL_GP2X_WaitForBlitter(); -#endif - - if (lockedsf == 0 && blited == 0 && vidSurface->flags&SDL_DOUBLEBUF) - SDL_Flip(vidSurface); - else if (blited != -2 && lockedsf == 0) //Alam: -2 for Win32 Direct, yea, i know - SDL_UpdateRect(vidSurface, rect.x, rect.y, 0, 0); //Alam: almost always - else - I_OutputMsg("%s\n",SDL_GetError()); - } -#ifdef HWRENDER - else - { - OglSdlFinishUpdate(cv_vidwait.value); - } -#endif - exposevideo = SDL_FALSE; -} - -// -// I_UpdateNoVsync -// -void I_UpdateNoVsync(void) -{ - INT32 real_vidwait = cv_vidwait.value; - cv_vidwait.value = 0; - I_FinishUpdate(); - cv_vidwait.value = real_vidwait; -} - -// -// I_ReadScreen -// -void I_ReadScreen(UINT8 *scr) -{ - if (rendermode != render_soft) - I_Error ("I_ReadScreen: called while in non-software mode"); - else - VID_BlitLinearScreen(screens[0], scr, - vid.width*vid.bpp, vid.height, - vid.rowbytes, vid.rowbytes); -} - -// -// I_SetPalette -// -void I_SetPalette(RGBA_t *palette) -{ - size_t i; - for (i=0; i<256; i++) - { - localPalette[i].r = palette[i].s.red; - localPalette[i].g = palette[i].s.green; - localPalette[i].b = palette[i].s.blue; - } - if (vidSurface) SDL_SetColors(vidSurface, localPalette, 0, 256); - if (bufSurface) SDL_SetColors(bufSurface, localPalette, 0, 256); -} - -// return number of fullscreen + X11 modes -INT32 VID_NumModes(void) -{ - if (USE_FULLSCREEN && numVidModes != -1) - return numVidModes - firstEntry; - else - return MAXWINMODES; -} - -const char *VID_GetModeName(INT32 modeNum) -{ - if (USE_FULLSCREEN && numVidModes != -1) // fullscreen modes - { - modeNum += firstEntry; - if (modeNum >= numVidModes) - return NULL; - - sprintf(&vidModeName[modeNum][0], "%dx%d", - modeList[modeNum]->w, - modeList[modeNum]->h); - } - else // windowed modes - { - if (modeNum > MAXWINMODES) - return NULL; - - sprintf(&vidModeName[modeNum][0], "%dx%d", - windowedModes[modeNum][0], - windowedModes[modeNum][1]); - } - return &vidModeName[modeNum][0]; -} - -INT32 VID_GetModeForSize(INT32 w, INT32 h) -{ - INT32 matchMode = -1, i; - VID_PrepareModeList(); - if (USE_FULLSCREEN && numVidModes != -1) - { - for (i=firstEntry; i<numVidModes; i++) - { - if (modeList[i]->w == w && - modeList[i]->h == h) - { - matchMode = i; - break; - } - } - if (-1 == matchMode) // use smaller mode - { - w -= w%BASEVIDWIDTH; - h -= h%BASEVIDHEIGHT; - for (i=firstEntry; i<numVidModes; i++) - { - if (modeList[i]->w == w && - modeList[i]->h == h) - { - matchMode = i; - break; - } - } - if (-1 == matchMode) // use smallest mode - matchMode = numVidModes-1; - } - matchMode -= firstEntry; - } - else - { - for (i=0; i<MAXWINMODES; i++) - { - if (windowedModes[i][0] == w && - windowedModes[i][1] == h) - { - matchMode = i; - break; - } - } - if (-1 == matchMode) // use smaller mode - { - w -= w%BASEVIDWIDTH; - h -= h%BASEVIDHEIGHT; - for (i=0; i<MAXWINMODES; i++) - { - if (windowedModes[i][0] == w && - windowedModes[i][1] == h) - { - matchMode = i; - break; - } - } - if (-1 == matchMode) // use smallest mode - matchMode = MAXWINMODES-1; - } - } - return matchMode; -} - -void VID_PrepareModeList(void) -{ - INT32 i; - - firstEntry = 0; - -#ifdef HWRENDER - if (rendermode == render_opengl) - modeList = SDL_ListModes(NULL, SDL_OPENGL|SDL_FULLSCREEN); - else -#endif - modeList = SDL_ListModes(NULL, surfaceFlagsF|SDL_HWSURFACE); //Alam: At least hardware surface - - if (disable_fullscreen?0:cv_fullscreen.value) // only fullscreen needs preparation - { - if (-1 != numVidModes) - { - for (i=0; i<numVidModes; i++) - { - if (modeList[i]->w <= MAXVIDWIDTH && - modeList[i]->h <= MAXVIDHEIGHT) - { - firstEntry = i; - break; - } - } - } - } - allow_fullscreen = true; -} - -static inline void SDLESSet(void) -{ -#ifdef HAVE_DCSDL - INT32 j; - SDL_DC_SetVideoDriver(SDL_DC_DIRECT_VIDEO); //SDL_DC_DMA_VIDEO - for (j=0;j<4;j++) - { - SDL_DC_MapKey(j,SDL_DC_START,SDLK_ESCAPE); - SDL_DC_MapKey(j,SDL_DC_A,SDLK_UNKNOWN); - SDL_DC_MapKey(j,SDL_DC_B,SDLK_UNKNOWN); - SDL_DC_MapKey(j,SDL_DC_X,SDLK_UNKNOWN); - SDL_DC_MapKey(j,SDL_DC_Y,SDLK_UNKNOWN); - SDL_DC_MapKey(j,SDL_DC_L,SDLK_UNKNOWN); - SDL_DC_MapKey(j,SDL_DC_R,SDLK_UNKNOWN); - //SDL_DC_MapKey(j,SDL_DC_LEFT,SDLK_UNKNOWN); - //SDL_DC_MapKey(j,SDL_DC_RIGHT,SDLK_UNKNOWN); - //SDL_DC_MapKey(j,SDL_DC_UP,SDLK_UNKNOWN); - //SDL_DC_MapKey(j,SDL_DC_DOWN,SDLK_UNKNOWN); - } - //SDL_DC_MapKey(0,SDL_DC_L,SDLK_LEFTBRACKET); - //SDL_DC_MapKey(0,SDL_DC_R,SDLK_RIGHTBRACKET); - //SDL_DC_MapKey(0,SDL_DC_START,SDLK_UNKNOWN); - //SDL_DC_MapKey(1,SDL_DC_L,SDLK_z); - //SDL_DC_MapKey(1,SDL_DC_R,SDLK_x); -#endif -#ifdef HAVE_GP2XSDL - SDL_GP2X_MiniDisplay(0,0); - //SDL_GP2X_DenyGfxMemory(NULL, 0); - SDL_GP2X_AllowGfxMemory(NULL, 0); -#endif -} - -static void SDLWMSet(void) -{ -#ifdef RPC_NO_WINDOWS_H - SDL_SysWMinfo SDLWM; - memset(&SDLWM,0,sizeof (SDL_SysWMinfo)); - SDL_VERSION(&SDLWM.version) - if (SDL_GetWMInfo(&SDLWM)) - vid.WndParent = SDLWM.window; - else - vid.WndParent = INVALID_HANDLE_VALUE; - if (vid.WndParent != INVALID_HANDLE_VALUE) - { - SetFocus(vid.WndParent); - ShowWindow(vid.WndParent, SW_SHOW); - } -#ifndef _WIN32_WCE - SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); -#endif -#endif - SDL_EventState(SDL_VIDEORESIZE, SDL_IGNORE); -} - -static void* SDLGetDirect(void) -{ -#if 0 //#ifndef __MACH__ // Do not directly access the MacOSX's OpenGL memory - if (!SDL_MUSTLOCK(vidSurface) && SDLmatchVideoformat()) - { - vid.rowbytes = vidSurface->pitch; - return vidSurface->pixels; - } -#endif // you can not use the video memory in pixels member in fullscreen mode - return NULL; -} - -INT32 VID_SetMode(INT32 modeNum) -{ -#ifdef _WIN32_WCE - (void)modeNum; -#else - SDLdoUngrabMouse(); - vid.recalc = true; - BitsPerPixel = (Uint8)cv_scr_depth.value; - //vid.bpp = BitsPerPixel==8?1:2; - // Window title - SDL_WM_SetCaption("SRB2 "VERSIONSTRING, "SRB2"); - - if (render_soft == rendermode) - { - //Alam: SDL_Video system free vidSurface for me - if (vid.buffer) free(vid.buffer); - vid.buffer = NULL; - if (bufSurface) SDL_FreeSurface(bufSurface); - bufSurface = NULL; - } - - if (USE_FULLSCREEN) - { - if (numVidModes != -1) - { - modeNum += firstEntry; - vid.width = modeList[modeNum]->w; - vid.height = modeList[modeNum]->h; - } - else - { - vid.width = windowedModes[modeNum][0]; - vid.height = windowedModes[modeNum][1]; - } - if (render_soft == rendermode) - { - SDLSetMode(vid.width, vid.height, BitsPerPixel, surfaceFlagsF); - - if (!vidSurface) - { - cv_fullscreen.value = 0; - modeNum = VID_GetModeForSize(vid.width,vid.height); - vid.width = windowedModes[modeNum][0]; - vid.height = windowedModes[modeNum][1]; - SDLSetMode(vid.width, vid.height, BitsPerPixel, surfaceFlagsW); - if (!vidSurface) - I_Error("Could not set vidmode: %s\n",SDL_GetError()); - } - } -#ifdef HWRENDER - else // (render_soft != rendermode) - { - if (!OglSdlSurface(vid.width, vid.height, true)) - { - cv_fullscreen.value = 0; - modeNum = VID_GetModeForSize(vid.width,vid.height); - vid.width = windowedModes[modeNum][0]; - vid.height = windowedModes[modeNum][1]; - if (!OglSdlSurface(vid.width, vid.height,false)) - I_Error("Could not set vidmode: %s\n",SDL_GetError()); - } - - realwidth = (Uint16)vid.width; - realheight = (Uint16)vid.height; - } -#endif - } - else //(cv_fullscreen.value) - { - vid.width = windowedModes[modeNum][0]; - vid.height = windowedModes[modeNum][1]; - - if (render_soft == rendermode) - { - SDLSetMode(vid.width, vid.height, BitsPerPixel, surfaceFlagsW); - if (!vidSurface) - I_Error("Could not set vidmode: %s\n",SDL_GetError()); - } -#ifdef HWRENDER - else //(render_soft != rendermode) - { - if (!OglSdlSurface(vid.width, vid.height, false)) - I_Error("Could not set vidmode: %s\n",SDL_GetError()); - realwidth = (Uint16)vid.width; - realheight = (Uint16)vid.height; - } -#endif - } - - vid.modenum = VID_GetModeForSize(vidSurface->w,vidSurface->h); - - if (render_soft == rendermode) - { - vid.rowbytes = vid.width*vid.bpp; - vid.direct = SDLGetDirect(); - vid.buffer = malloc(vid.rowbytes*vid.height*NUMSCREENS); - if (vid.buffer) memset(vid.buffer,0x00,vid.rowbytes*vid.height*NUMSCREENS); - else I_Error ("Not enough memory for video buffer\n"); - } - -#if 0 // broken - if (!cv_stretch.value && (float)vid.width/vid.height != ((float)BASEVIDWIDTH/BASEVIDHEIGHT)) - vid.height = (INT32)(vid.width * ((float)BASEVIDHEIGHT/BASEVIDWIDTH));// Adjust the height to match -#endif -#endif - I_StartupMouse(); - - SDLWMSet(); - - return true; -} - -void I_StartupGraphics(void) -{ - static char SDLNOMOUSE[] = "SDL_NOMOUSE=1"; - static char SDLVIDEOMID[] = "SDL_VIDEO_CENTERED=center"; - - if (dedicated) - { - rendermode = render_none; - return; - } - if (graphics_started) - return; - - COM_AddCommand ("vid_nummodes", VID_Command_NumModes_f); - COM_AddCommand ("vid_info", VID_Command_Info_f); - COM_AddCommand ("vid_modelist", VID_Command_ModeList_f); - COM_AddCommand ("vid_mode", VID_Command_Mode_f); - CV_RegisterVar (&cv_vidwait); - CV_RegisterVar (&cv_stretch); -#ifdef FILTERS - CV_RegisterVar (&cv_filter); -#endif -#ifdef _PSP // pitch is 0, mod of 0 crash - disable_mouse = true; -#else - disable_mouse = M_CheckParm("-nomouse"); -#endif - if (disable_mouse) - I_PutEnv(SDLNOMOUSE); - if (!I_GetEnv("SDL_VIDEO_CENTERED")) - I_PutEnv(SDLVIDEOMID); - disable_fullscreen = M_CheckParm("-win"); - - keyboard_started = true; -#ifdef _arch_dreamcast - conio_shutdown(); -#endif - -#if !defined(HAVE_TTF) -#ifdef _WIN32 // Initialize Audio as well, otherwise Win32's DirectX can not use audio - if (SDL_InitSubSystem(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0) -#else //SDL_OpenAudio will do SDL_InitSubSystem(SDL_INIT_AUDIO) - if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) -#endif - { -#ifdef _WIN32 - if (SDL_WasInit(SDL_INIT_AUDIO)==0) - CONS_Printf(M_GetText("Couldn't initialize SDL's Audio System with Video System: %s\n"), SDL_GetError()); - if (SDL_WasInit(SDL_INIT_VIDEO)==0) -#endif - { - CONS_Printf(M_GetText("Couldn't initialize SDL's Video System: %s\n"), SDL_GetError()); - return; - } - } -#ifdef REMOTE_DEBUGGING -#ifdef _WII - _break(); // break for debugger -#endif -#endif -#endif - { - char vd[100]; //stack space for video name - CONS_Printf(M_GetText("Starting up with video driver : %s\n"), SDL_VideoDriverName(vd,100)); - if (strncasecmp(vd, "gcvideo", 8) == 0 || strncasecmp(vd, "fbcon", 6) == 0 || strncasecmp(vd, "wii", 4) == 0 || strncasecmp(vd, "psl1ght", 8) == 0) - framebuffer = SDL_TRUE; - } - if (M_CheckParm("-software")) - rendermode = render_soft; - SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); - SDLESSet(); - VID_Command_ModeList_f(); - vid.buffer = NULL; // For software mode - vid.width = BASEVIDWIDTH; // Default size for startup - vid.height = BASEVIDHEIGHT; // BitsPerPixel is the SDL interface's - vid.recalc = true; // Set up the console stufff - vid.direct = NULL; // Maybe direct access? - vid.bpp = 1; // This is the game engine's Bpp - vid.WndParent = NULL; //For the window? - -#ifdef HAVE_TTF - I_ShutdownTTF(); -#endif - - // Window title -#ifdef _WIN32_WCE - SDL_WM_SetCaption("SRB2 "VERSIONSTRING, "SRB2"); -#else - SDL_WM_SetCaption("SRB2: Starting up", "SRB2"); -#endif - - // Window icon -#ifdef HAVE_IMAGE - icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm); -#endif - SDL_WM_SetIcon(icoSurface, NULL); - -#ifdef _WIN32 - //DisableAero(); //also disable Aero on Vista -#endif - -#ifdef HWRENDER - if (M_CheckParm("-opengl") || rendermode == render_opengl) - { - rendermode = render_opengl; - HWD.pfnInit = hwSym("Init",NULL); - HWD.pfnFinishUpdate = NULL; - HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); - HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); - HWD.pfnSetBlend = hwSym("SetBlend",NULL); - HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); - HWD.pfnSetTexture = hwSym("SetTexture",NULL); - HWD.pfnReadRect = hwSym("ReadRect",NULL); - HWD.pfnGClipRect = hwSym("GClipRect",NULL); - HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); - HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); - HWD.pfnSetPalette = hwSym("SetPalette",NULL); - HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); - HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); - HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); - HWD.pfnSetTransform = hwSym("SetTransform",NULL); - HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); -#ifdef SHUFFLE - HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); -#endif - HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); - HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); - HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); - HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); - HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); - HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); - // check gl renderer lib - if (HWD.pfnGetRenderVersion() != VERSION) - I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); -#if 1 //#ifdef _WIN32_WCE - vid.width = BASEVIDWIDTH; - vid.height = BASEVIDHEIGHT; -#else - vid.width = 640; // hack to make voodoo cards work in 640x480 - vid.height = 480; -#endif - if (HWD.pfnInit(I_Error)) // let load the OpenGL library - { - /* - * We want at least 1 bit R, G, and B, - * and at least 16 bpp. Why 1 bit? May be more? - */ - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 1); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 1); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 1); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - if (!OglSdlSurface(vid.width, vid.height, (USE_FULLSCREEN))) - if (!OglSdlSurface(vid.width, vid.height, !(USE_FULLSCREEN))) - rendermode = render_soft; - } - else - rendermode = render_soft; - } -#else - rendermode = render_soft; //force software mode when there no HWRENDER code -#endif - if (render_soft == rendermode) - { -#if defined(_WII) - vid.width = 640; - vid.height = 480; -#elif defined(_PS3) - vid.width = 720; - vid.height = 480; -#else - vid.width = BASEVIDWIDTH; - vid.height = BASEVIDHEIGHT; -#endif - SDLSetMode(vid.width, vid.height, BitsPerPixel, surfaceFlagsW); - if (!vidSurface) - { - CONS_Printf(M_GetText("Could not set vidmode: %s\n") ,SDL_GetError()); - vid.rowbytes = 0; - graphics_started = true; - return; - } - vid.rowbytes = vid.width * vid.bpp; - vid.direct = SDLGetDirect(); - vid.buffer = malloc(vid.rowbytes*vid.height*NUMSCREENS); - if (vid.buffer) memset(vid.buffer,0x00,vid.rowbytes*vid.height*NUMSCREENS); - else CONS_Printf("%s", M_GetText("Not enough memory for video buffer\n")); - } - if (M_CheckParm("-nomousegrab")) - mousegrabok = SDL_FALSE; -#ifdef _DEBUG - else - { - char videodriver[4] = {'S','D','L',0}; - if (!M_CheckParm("-mousegrab") && - SDL_VideoDriverName(videodriver,4) && - strncasecmp("X11",videodriver,4) == 0) - mousegrabok = SDL_FALSE; //X11's XGrabPointer not good - } -#endif - realwidth = (Uint16)vid.width; - realheight = (Uint16)vid.height; - - VID_Command_Info_f(); - if (!disable_mouse) SDL_ShowCursor(SDL_DISABLE); - SDLdoUngrabMouse(); - - SDLWMSet(); - - graphics_started = true; -} - -void I_ShutdownGraphics(void) -{ - const rendermode_t oldrendermode = rendermode; - - rendermode = render_none; - if (icoSurface) SDL_FreeSurface(icoSurface); - icoSurface = NULL; - if (render_soft == oldrendermode) - { - vidSurface = NULL; //Alam: SDL_Video system free vidSurface for me - if (vid.buffer) free(vid.buffer); - vid.buffer = NULL; - if (bufSurface) SDL_FreeSurface(bufSurface); - bufSurface = NULL; -#ifdef FILTERS - if (preSurface) SDL_FreeSurface(preSurface); - preSurface = NULL; - if (f2xSurface) SDL_FreeSurface(f2xSurface); - f2xSurface = NULL; -#endif - } - - // was graphics initialized anyway? - if (!graphics_started) - return; - CONS_Printf("I_ShutdownGraphics: "); -#ifdef _WIN32 - //ResetAero(); -#endif - graphics_started = false; - CONS_Printf("%s", M_GetText("shut down\n")); -#ifdef HWRENDER - if (GLUhandle) - hwClose(GLUhandle); -#endif -#ifndef _arch_dreamcast - SDL_QuitSubSystem(SDL_INIT_VIDEO); -#endif - framebuffer = SDL_FALSE; -} -#endif diff --git a/src/sdl12/macosx/English.lproj/InfoPlist.strings b/src/sdl12/macosx/English.lproj/InfoPlist.strings deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/sdl12/macosx/Info.plist b/src/sdl12/macosx/Info.plist deleted file mode 100644 index ae0ce24de8e9ca4e07340ceb7851c1b13ec474bd..0000000000000000000000000000000000000000 --- a/src/sdl12/macosx/Info.plist +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>English</string> - <key>CFBundleExecutable</key> - <string>${EXECUTABLE_NAME}</string> - <key>CFBundleIconFile</key> - <string>Srb2mac.icns</string> - <key>CFBundleIdentifier</key> - <string>com.yourcompany.Srb2mac</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>${PRODUCT_NAME}</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1.0</string> - <key>NSMainNibFile</key> - <string>SDLMain</string> - <key>NSPrincipalClass</key> - <string>NSApplication</string> -</dict> -</plist> diff --git a/src/sdl12/macosx/Srb2mac.icns b/src/sdl12/macosx/Srb2mac.icns deleted file mode 100644 index 96cb8a36d991818eb03b7d80343518ab168bda7d..0000000000000000000000000000000000000000 Binary files a/src/sdl12/macosx/Srb2mac.icns and /dev/null differ diff --git a/src/sdl12/macosx/Srb2mac.pbproj/project.pbxproj b/src/sdl12/macosx/Srb2mac.pbproj/project.pbxproj deleted file mode 100644 index 1f8e3276a01c5666c76da3a3f8b4a824b4476d60..0000000000000000000000000000000000000000 --- a/src/sdl12/macosx/Srb2mac.pbproj/project.pbxproj +++ /dev/null @@ -1,3560 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 38; - objects = { - 6726EB5E10190F860074DCBA = { - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 7; - files = ( - 6755C8D0101802C300A80195, - 6755C8D1101802C300A80195, - 6755C8D2101802C300A80195, - 6755C8D3101802C300A80195, - 6755C8D4101802C300A80195, - 6755C8D5101802C300A80195, - 6755C8D6101802C300A80195, - 6755C8D7101802C300A80195, - 6755C8D8101802C300A80195, - ); - isa = PBXCopyFilesBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 6726EB5F10190FFC0074DCBA = { - buildActionMask = 2147483647; - files = ( - ); - generatedFileNames = ( - ); - isa = PBXShellScriptBuildPhase; - neededFileNames = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "touch -c $SRCROOT/../../comptime.c"; - }; - 6755C7A91017FE2500A80195 = { - fileEncoding = 30; - isa = PBXFileReference; - name = lzf.c; - path = ../../lzf.c; - refType = 2; - }; - 6755C7AA1017FE2500A80195 = { - fileEncoding = 30; - isa = PBXFileReference; - name = lzf.h; - path = ../../lzf.h; - refType = 2; - }; - 6755C7AB1017FE2500A80195 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_dllist.h; - path = ../../m_dllist.h; - refType = 2; - }; - 6755C7AC1017FE2500A80195 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_queue.c; - path = ../../m_queue.c; - refType = 2; - }; - 6755C7AD1017FE2500A80195 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_queue.h; - path = ../../m_queue.h; - refType = 2; - }; - 6755C7AE1017FE2500A80195 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_polyobj.c; - path = ../../p_polyobj.c; - refType = 2; - }; - 6755C7AF1017FE2500A80195 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_polyobj.h; - path = ../../p_polyobj.h; - refType = 2; - }; - 6755C7B11017FE2500A80195 = { - fileEncoding = 30; - isa = PBXFileReference; - name = string.c; - path = ../../string.c; - refType = 2; - }; - 6755C7B21017FE2500A80195 = { - fileRef = 6755C7A91017FE2500A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C7B31017FE2500A80195 = { - fileRef = 6755C7AA1017FE2500A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C7B51017FE2500A80195 = { - fileRef = 6755C7AC1017FE2500A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C7B71017FE2500A80195 = { - fileRef = 6755C7AE1017FE2500A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C7B81017FE2500A80195 = { - fileRef = 6755C7AF1017FE2500A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C7BB1017FE2500A80195 = { - fileRef = 6755C7A91017FE2500A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C7BC1017FE2500A80195 = { - fileRef = 6755C7AA1017FE2500A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C7BD1017FE2500A80195 = { - fileRef = 6755C7AB1017FE2500A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C7BE1017FE2500A80195 = { - fileRef = 6755C7AC1017FE2500A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C7BF1017FE2500A80195 = { - fileRef = 6755C7AD1017FE2500A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C7C01017FE2500A80195 = { - fileRef = 6755C7AE1017FE2500A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C7C11017FE2500A80195 = { - fileRef = 6755C7AF1017FE2500A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C7C41017FE4400A80195 = { - children = ( - 6755C7FA1017FE4500A80195, - 6755C7FB1017FE4500A80195, - ); - isa = PBXGroup; - name = macosx; - path = ""; - refType = 2; - }; - 6755C7FA1017FE4500A80195 = { - fileEncoding = 30; - isa = PBXFileReference; - path = mac_alert.c; - refType = 2; - }; - 6755C7FB1017FE4500A80195 = { - fileEncoding = 30; - isa = PBXFileReference; - path = mac_alert.h; - refType = 2; - }; - 6755C82A1017FE4500A80195 = { - fileEncoding = 30; - isa = PBXFileReference; - name = sdlmain.h; - path = ../sdlmain.h; - refType = 2; - }; - 6755C84B1017FE4500A80195 = { - fileRef = 6755C7FA1017FE4500A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8651017FE4500A80195 = { - fileRef = 6755C82A1017FE4500A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8861017FE4500A80195 = { - fileRef = 6755C7FA1017FE4500A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8871017FE4500A80195 = { - fileRef = 6755C7FB1017FE4500A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8A01017FE4500A80195 = { - fileRef = 6755C82A1017FE4500A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8A41017FE8000A80195 = { - children = ( - 84177748085A1097000C01D8, - 84177749085A1097000C01D8, - 8417774A085A1097000C01D8, - 8417774B085A1097000C01D8, - 8417774C085A1097000C01D8, - 8417774D085A1097000C01D8, - 8417774E085A1097000C01D8, - 8417774F085A1097000C01D8, - 84177750085A1097000C01D8, - 84177751085A1097000C01D8, - 84177752085A1097000C01D8, - 84177753085A1097000C01D8, - 84177754085A1097000C01D8, - 84177755085A10AA000C01D8, - 84177756085A10AA000C01D8, - 6755C82A1017FE4500A80195, - 84177757085A10AA000C01D8, - 6755C7C41017FE4400A80195, - ); - isa = PBXGroup; - name = SDL; - path = ""; - refType = 2; - }; - 6755C8BE101802C300A80195 = { - isa = PBXFileReference; - name = drill.dta; - path = ../../../bin/Resources/drill.dta; - refType = 2; - }; - 6755C8BF101802C300A80195 = { - isa = PBXFileReference; - name = fmod.dll; - path = ../../../bin/Resources/fmod.dll; - refType = 2; - }; - 6755C8C0101802C300A80195 = { - isa = PBXFileReference; - name = knux.plr; - path = ../../../bin/Resources/knux.plr; - refType = 2; - }; - 6755C8C1101802C300A80195 = { - isa = PBXFileReference; - name = music.dta; - path = ../../../bin/Resources/music.dta; - refType = 2; - }; - 6755C8C2101802C300A80195 = { - isa = PBXFileReference; - name = rings.wpn; - path = ../../../bin/Resources/rings.wpn; - refType = 2; - }; - 6755C8C3101802C300A80195 = { - isa = PBXFileReference; - name = soar.dta; - path = ../../../bin/Resources/soar.dta; - refType = 2; - }; - 6755C8C4101802C300A80195 = { - isa = PBXFileReference; - name = sonic.plr; - path = ../../../bin/Resources/sonic.plr; - refType = 2; - }; - 6755C8C5101802C300A80195 = { - isa = PBXFileReference; - name = srb2.wad; - path = ../../../bin/Resources/srb2.wad; - refType = 2; - }; - 6755C8C6101802C300A80195 = { - isa = PBXFileReference; - name = tails.plr; - path = ../../../bin/Resources/tails.plr; - refType = 2; - }; - 6755C8C7101802C300A80195 = { - fileRef = 6755C8BE101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8C8101802C300A80195 = { - fileRef = 6755C8BF101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8C9101802C300A80195 = { - fileRef = 6755C8C0101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8CA101802C300A80195 = { - fileRef = 6755C8C1101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8CB101802C300A80195 = { - fileRef = 6755C8C2101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8CC101802C300A80195 = { - fileRef = 6755C8C3101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8CD101802C300A80195 = { - fileRef = 6755C8C4101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8CE101802C300A80195 = { - fileRef = 6755C8C5101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8CF101802C300A80195 = { - fileRef = 6755C8C6101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8D0101802C300A80195 = { - fileRef = 6755C8BE101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8D1101802C300A80195 = { - fileRef = 6755C8BF101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8D2101802C300A80195 = { - fileRef = 6755C8C0101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8D3101802C300A80195 = { - fileRef = 6755C8C1101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8D4101802C300A80195 = { - fileRef = 6755C8C2101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8D5101802C300A80195 = { - fileRef = 6755C8C3101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8D6101802C300A80195 = { - fileRef = 6755C8C4101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8D7101802C300A80195 = { - fileRef = 6755C8C5101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 6755C8D8101802C300A80195 = { - fileRef = 6755C8C6101802C300A80195; - isa = PBXBuildFile; - settings = { - }; - }; - 677B5EC810180D4E00A80195 = { - fileRef = 84177758085A10D2000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 677B5EC910180D6600A80195 = { - children = ( - 84177758085A10D2000C01D8, - ); - isa = PBXGroup; - name = r_opengl; - refType = 4; - }; - 677B5ECA10180D7100A80195 = { - children = ( - 84F202CA08A92AA0000C01D8, - ); - isa = PBXGroup; - name = s_openal; - refType = 4; - }; - 67B2D0C91018779900A80195 = { - fileRef = 84177748085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 67B2D0CA1018779D00A80195 = { - fileRef = 84177748085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; -//670 -//671 -//672 -//673 -//674 -//840 -//841 -//842 -//843 -//844 - 840CE6B009198AA7000C01D8 = { - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 840CE6B309198ABB000C01D8, - 840CE6B409198ABB000C01D8, - 849BD32D0A7E471D000C01D8, - ); - isa = PBXCopyFilesBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 840CE6B309198ABB000C01D8 = { - fileRef = 84C4E04B08620A46000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 840CE6B409198ABB000C01D8 = { - fileRef = 84C4E04C08620A46000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 841776FE085A0C64000C01D8 = { - children = ( - 84C4E00D0862063C000C01D8, - 84177705085A0CDB000C01D8, - 84177706085A0D9D000C01D8, - 84177708085A0DB5000C01D8, - 84177709085A0DD1000C01D8, - 84177712085A0EB5000C01D8, - 8417770B085A0E17000C01D8, - 8417770C085A0E40000C01D8, - 8417770D085A0E4E000C01D8, - 8417770E085A0E5B000C01D8, - 8417770F085A0E66000C01D8, - 84177710085A0E71000C01D8, - 84177711085A0E77000C01D8, - 841779E2085A138F000C01D8, - 84F202C708A92A5D000C01D8, - 84C4E03F0862096F000C01D8, - 84C4E0420862098A000C01D8, - 84C4E045086209D3000C01D8, - 84C4E048086209FF000C01D8, - 84C4E04C08620A46000C01D8, - 84C4E04B08620A46000C01D8, - 849BD31C0A7E45B3000C01D8, - ); - isa = PBXGroup; - refType = 4; - }; - 84177700085A0C64000C01D8 = { - buildRules = ( - ); - buildSettings = { - COPY_PHASE_STRIP = NO; - }; - isa = PBXBuildStyle; - name = Development; - }; - 84177701085A0C64000C01D8 = { - buildRules = ( - ); - buildSettings = { - COPY_PHASE_STRIP = YES; - }; - isa = PBXBuildStyle; - name = Deployment; - }; - 84177702085A0C64000C01D8 = { - buildStyles = ( - 84177700085A0C64000C01D8, - 84177701085A0C64000C01D8, - ); - hasScannedForEncodings = 1; - isa = PBXProject; - mainGroup = 841776FE085A0C64000C01D8; - productRefGroup = 841779E2085A138F000C01D8; - projectDirPath = ""; - targets = ( - 841779E0085A138F000C01D8, - 841779E9085A13B1000C01D8, - ); - }; - 84177705085A0CDB000C01D8 = { - children = ( - 849603A80A791C11000C01D8, - 84177713085A0FCE000C01D8, - 84177714085A0FCE000C01D8, - 84177716085A0FCE000C01D8, - 84177717085A0FCE000C01D8, - 84177718085A0FCE000C01D8, - 84177719085A0FCE000C01D8, - 8417771A085A0FCE000C01D8, - 8417771B085A0FCE000C01D8, - 8417771C085A0FCE000C01D8, - 8417771D085A0FCE000C01D8, - 8417771E085A0FCE000C01D8, - 8417771F085A0FCE000C01D8, - 84177720085A0FCE000C01D8, - 84177721085A0FCE000C01D8, - 84177722085A0FCE000C01D8, - 84177723085A0FCE000C01D8, - 84177724085A0FF2000C01D8, - 84177725085A0FF2000C01D8, - 84177726085A0FF2000C01D8, - 84177727085A0FF2000C01D8, - 6755C7B11017FE2500A80195, - ); - isa = PBXGroup; - name = D_SRB2; - path = ""; - refType = 2; - }; - 84177706085A0D9D000C01D8 = { - children = ( - 8417772A085A100E000C01D8, - 8417772B085A100E000C01D8, - 8417772C085A100E000C01D8, - ); - isa = PBXGroup; - name = F_Frame; - path = ""; - refType = 2; - }; - 84177708085A0DB5000C01D8 = { - children = ( - 841779DA085A1347000C01D8, - 841778C6085A1295000C01D8, - 841778C4085A1295000C01D8, - 841778C5085A1295000C01D8, - 8417772D085A1029000C01D8, - 8417772E085A1029000C01D8, - 8417772F085A1029000C01D8, - 84177730085A1029000C01D8, - 84177731085A1029000C01D8, - 841779D4085A1296000C01D8, - 841779D5085A1296000C01D8, - ); - isa = PBXGroup; - name = G_Game; - path = ""; - refType = 2; - }; - 84177709085A0DD1000C01D8 = { - children = ( - 841778BE085A1295000C01D8, - 841778BF085A1295000C01D8, - 841778C2085A1295000C01D8, - 841778C3085A1295000C01D8, - 841778C0085A1295000C01D8, - 841778C1085A1295000C01D8, - 84177732085A1040000C01D8, - 84177733085A1040000C01D8, - 841779D2085A1296000C01D8, - 841779D3085A1296000C01D8, - 841779D8085A1296000C01D8, - 8490D433085DF537000C01D8, - ); - isa = PBXGroup; - name = H_Hud; - path = ""; - refType = 2; - }; - 8417770B085A0E17000C01D8 = { - children = ( - 6755C8A41017FE8000A80195, - 84177759085A10D2000C01D8, - 841777A4085A1200000C01D8, - 841777A5085A1200000C01D8, - 841777A6085A1200000C01D8, - 841777A8085A1200000C01D8, - 841777A9085A1200000C01D8, - 841777AA085A1200000C01D8, - 841777AB085A1200000C01D8, - 841777AC085A1200000C01D8, - 841777AD085A1200000C01D8, - 841777AE085A1200000C01D8, - ); - isa = PBXGroup; - name = I_Interface; - path = ""; - refType = 2; - }; - 8417770C085A0E40000C01D8 = { - children = ( - 8417775A085A10EB000C01D8, - 8417775B085A10EB000C01D8, - 8417775C085A10EB000C01D8, - 8417775D085A10EB000C01D8, - 8417775E085A10EB000C01D8, - 8417775F085A10EB000C01D8, - 6755C7AB1017FE2500A80195, - 84177760085A10EB000C01D8, - 84177761085A10EB000C01D8, - 84177762085A10EB000C01D8, - 84177763085A10EB000C01D8, - 84177764085A10EB000C01D8, - 84177765085A10EB000C01D8, - 6755C7AC1017FE2500A80195, - 6755C7AD1017FE2500A80195, - 84177766085A10EB000C01D8, - 84177767085A10EB000C01D8, - 84177768085A10EB000C01D8, - ); - isa = PBXGroup; - name = M_Misc; - path = ""; - refType = 2; - }; - 8417770D085A0E4E000C01D8 = { - children = ( - 84177769085A1104000C01D8, - 8417776A085A1104000C01D8, - 8417776B085A1104000C01D8, - 8417776C085A1104000C01D8, - 8417776D085A1104000C01D8, - 8417776E085A1104000C01D8, - 8417776F085A1104000C01D8, - 84177770085A1104000C01D8, - 84177771085A1104000C01D8, - 84177772085A1104000C01D8, - 84177773085A1104000C01D8, - 84177774085A1104000C01D8, - 6755C7AE1017FE2500A80195, - 6755C7AF1017FE2500A80195, - 84177775085A1104000C01D8, - 84177776085A1104000C01D8, - 84177777085A1104000C01D8, - 84177778085A1104000C01D8, - 84177779085A1104000C01D8, - 8417777A085A1104000C01D8, - 8417777B085A1104000C01D8, - 8417777C085A1104000C01D8, - 8417777D085A1104000C01D8, - 8417777E085A1104000C01D8, - 8417777F085A1104000C01D8, - 84177780085A1104000C01D8, - ); - isa = PBXGroup; - name = P_Play; - path = ""; - refType = 2; - }; - 8417770E085A0E5B000C01D8 = { - children = ( - 84177781085A111B000C01D8, - 84177782085A111B000C01D8, - 84177783085A111B000C01D8, - 84177784085A111B000C01D8, - 84177785085A111B000C01D8, - 84177786085A111B000C01D8, - 84177787085A111B000C01D8, - 84177788085A111B000C01D8, - 84177789085A111B000C01D8, - 8417778A085A111B000C01D8, - 8417778B085A111B000C01D8, - 8417778C085A111B000C01D8, - 8417778D085A111B000C01D8, - 8417778E085A111B000C01D8, - 8417778F085A111B000C01D8, - 84177790085A111B000C01D8, - 84177791085A111B000C01D8, - 84177792085A111B000C01D8, - 84177793085A111B000C01D8, - 84177794085A111B000C01D8, - 84177795085A111B000C01D8, - 84177796085A111B000C01D8, - 84177797085A111B000C01D8, - 841777A2085A1197000C01D8, - 841777A3085A1197000C01D8, - 8490D436085DF57B000C01D8, - 841779D7085A1296000C01D8, - ); - isa = PBXGroup; - name = R_Rend; - path = ""; - refType = 2; - }; - 8417770F085A0E66000C01D8 = { - children = ( - 84177798085A1138000C01D8, - 84177799085A1138000C01D8, - 8417779A085A1138000C01D8, - 8417779B085A1138000C01D8, - ); - isa = PBXGroup; - name = S_Sounds; - path = ""; - refType = 2; - }; - 84177710085A0E71000C01D8 = { - children = ( - 8417779C085A114C000C01D8, - 8417779D085A114C000C01D8, - 8417779E085A116B000C01D8, - 8417779F085A116B000C01D8, - ); - isa = PBXGroup; - name = SDL_main; - path = ""; - refType = 2; - }; - 84177711085A0E77000C01D8 = { - children = ( - 6755C7A91017FE2500A80195, - 6755C7AA1017FE2500A80195, - 841777AF085A1228000C01D8, - 841777B0085A1228000C01D8, - 841777A0085A117F000C01D8, - 841777A1085A117F000C01D8, - 841778BC085A122A000C01D8, - 841778BD085A122A000C01D8, - ); - isa = PBXGroup; - name = W_Wad; - path = ""; - refType = 2; - }; - 84177712085A0EB5000C01D8 = { - children = ( - 677B5EC910180D6600A80195, - 677B5ECA10180D7100A80195, - 84177734085A106C000C01D8, - 84177735085A106C000C01D8, - 84177736085A106C000C01D8, - 84177737085A106C000C01D8, - 84177738085A106C000C01D8, - 84177739085A106C000C01D8, - 8417773A085A106C000C01D8, - 8417773B085A106C000C01D8, - 8417773C085A106C000C01D8, - 8417773D085A106C000C01D8, - 8417773E085A106C000C01D8, - 8417773F085A106C000C01D8, - 84177740085A106C000C01D8, - 84177741085A106C000C01D8, - 84177742085A106C000C01D8, - 84177743085A106C000C01D8, - 84177744085A106C000C01D8, - 84177745085A106C000C01D8, - 84177746085A106C000C01D8, - 84177747085A106C000C01D8, - ); - isa = PBXGroup; - name = Hw_Hardware; - path = ""; - refType = 2; - }; - 84177713085A0FCE000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = d_clisrv.c; - path = ../../d_clisrv.c; - refType = 2; - }; - 84177714085A0FCE000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = d_clisrv.h; - path = ../../d_clisrv.h; - refType = 2; - }; - 84177716085A0FCE000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = d_event.h; - path = ../../d_event.h; - refType = 2; - }; - 84177717085A0FCE000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = d_main.c; - path = ../../d_main.c; - refType = 2; - }; - 84177718085A0FCE000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = d_main.h; - path = ../../d_main.h; - refType = 2; - }; - 84177719085A0FCE000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = d_net.c; - path = ../../d_net.c; - refType = 2; - }; - 8417771A085A0FCE000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = d_net.h; - path = ../../d_net.h; - refType = 2; - }; - 8417771B085A0FCE000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = d_netcmd.c; - path = ../../d_netcmd.c; - refType = 2; - }; - 8417771C085A0FCE000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = d_netcmd.h; - path = ../../d_netcmd.h; - refType = 2; - }; - 8417771D085A0FCE000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = d_netfil.c; - path = ../../d_netfil.c; - refType = 2; - }; - 8417771E085A0FCE000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = d_netfil.h; - path = ../../d_netfil.h; - refType = 2; - }; - 8417771F085A0FCE000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = d_player.h; - path = ../../d_player.h; - refType = 2; - }; - 84177720085A0FCE000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = d_think.h; - path = ../../d_think.h; - refType = 2; - }; - 84177721085A0FCE000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = d_ticcmd.h; - path = ../../d_ticcmd.h; - refType = 2; - }; - 84177722085A0FCE000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = dehacked.c; - path = ../../dehacked.c; - refType = 2; - }; - 84177723085A0FCE000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = dehacked.h; - path = ../../dehacked.h; - refType = 2; - }; - 84177724085A0FF2000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = doomdata.h; - path = ../../doomdata.h; - refType = 2; - }; - 84177725085A0FF2000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = doomdef.h; - path = ../../doomdef.h; - refType = 2; - }; - 84177726085A0FF2000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = doomstat.h; - path = ../../doomstat.h; - refType = 2; - }; - 84177727085A0FF2000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = doomtype.h; - path = ../../doomtype.h; - refType = 2; - }; - 8417772A085A100E000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = f_finale.c; - path = ../../f_finale.c; - refType = 2; - }; - 8417772B085A100E000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = f_finale.h; - path = ../../f_finale.h; - refType = 2; - }; - 8417772C085A100E000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = f_wipe.c; - path = ../../f_wipe.c; - refType = 2; - }; - 8417772D085A1029000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = g_game.c; - path = ../../g_game.c; - refType = 2; - }; - 8417772E085A1029000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = g_game.h; - path = ../../g_game.h; - refType = 2; - }; - 8417772F085A1029000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = g_input.c; - path = ../../g_input.c; - refType = 2; - }; - 84177730085A1029000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = g_input.h; - path = ../../g_input.h; - refType = 2; - }; - 84177731085A1029000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = g_state.h; - path = ../../g_state.h; - refType = 2; - }; - 84177732085A1040000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hu_stuff.c; - path = ../../hu_stuff.c; - refType = 2; - }; - 84177733085A1040000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hu_stuff.h; - path = ../../hu_stuff.h; - refType = 2; - }; - 84177734085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_bsp.c; - path = ../../hardware/hw_bsp.c; - refType = 2; - }; - 84177735085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_cache.c; - path = ../../hardware/hw_cache.c; - refType = 2; - }; - 84177736085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_data.h; - path = ../../hardware/hw_data.h; - refType = 2; - }; - 84177737085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_defs.h; - path = ../../hardware/hw_defs.h; - refType = 2; - }; - 84177738085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_dll.h; - path = ../../hardware/hw_dll.h; - refType = 2; - }; - 84177739085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_draw.c; - path = ../../hardware/hw_draw.c; - refType = 2; - }; - 8417773A085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_drv.h; - path = ../../hardware/hw_drv.h; - refType = 2; - }; - 8417773B085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_glide.h; - path = ../../hardware/hw_glide.h; - refType = 2; - }; - 8417773C085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_glob.h; - path = ../../hardware/hw_glob.h; - refType = 2; - }; - 8417773D085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_light.c; - path = ../../hardware/hw_light.c; - refType = 2; - }; - 8417773E085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_light.h; - path = ../../hardware/hw_light.h; - refType = 2; - }; - 8417773F085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_main.c; - path = ../../hardware/hw_main.c; - refType = 2; - }; - 84177740085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_main.h; - path = ../../hardware/hw_main.h; - refType = 2; - }; - 84177741085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_md2.c; - path = ../../hardware/hw_md2.c; - refType = 2; - }; - 84177742085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_md2.h; - path = ../../hardware/hw_md2.h; - refType = 2; - }; - 84177743085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_trick.c; - path = ../../hardware/hw_trick.c; - refType = 2; - }; - 84177744085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw3dsdrv.h; - path = ../../hardware/hw3dsdrv.h; - refType = 2; - }; - 84177745085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw3sound.c; - path = ../../hardware/hw3sound.c; - refType = 2; - }; - 84177746085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw3sound.h; - path = ../../hardware/hw3sound.h; - refType = 2; - }; - 84177747085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hws_data.h; - path = ../../hardware/hws_data.h; - refType = 2; - }; - 84177748085A1097000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = dosstr.c; - path = ../dosstr.c; - refType = 2; - }; - 84177749085A1097000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = endtxt.c; - path = ../endtxt.c; - refType = 2; - }; - 8417774A085A1097000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = endtxt.h; - path = ../endtxt.h; - refType = 2; - }; - 8417774B085A1097000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = filesrch.c; - path = ../../filesrch.c; - refType = 2; - }; - 8417774C085A1097000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hwsym_sdl.c; - path = ../hwsym_sdl.c; - refType = 2; - }; - 8417774D085A1097000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hwsym_sdl.h; - path = ../hwsym_sdl.h; - refType = 2; - }; - 8417774E085A1097000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = i_cdmus.c; - path = ../i_cdmus.c; - refType = 2; - }; - 8417774F085A1097000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = i_main.c; - path = ../i_main.c; - refType = 2; - }; - 84177750085A1097000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = i_net.c; - path = ../i_net.c; - refType = 2; - }; - 84177751085A1097000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = i_sound.c; - path = ../i_sound.c; - refType = 2; - }; - 84177752085A1097000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = i_system.c; - path = ../i_system.c; - refType = 2; - }; - 84177753085A1097000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = i_video.c; - path = ../i_video.c; - refType = 2; - }; - 84177754085A1097000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = IMG_xpm.c; - path = ../IMG_xpm.c; - refType = 2; - }; - 84177755085A10AA000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = ogl_sdl.c; - path = ../ogl_sdl.c; - refType = 2; - }; - 84177756085A10AA000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = ogl_sdl.h; - path = ../ogl_sdl.h; - refType = 2; - }; - 84177757085A10AA000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = SDL_icon.xpm; - path = ../SDL_icon.xpm; - refType = 2; - }; - 84177758085A10D2000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_opengl.c; - path = ../../hardware/r_opengl/r_opengl.c; - refType = 2; - }; - 84177759085A10D2000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_opengl.h; - path = ../../hardware/r_opengl/r_opengl.h; - refType = 2; - }; - 8417775A085A10EB000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_argv.c; - path = ../../m_argv.c; - refType = 2; - }; - 8417775B085A10EB000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_argv.h; - path = ../../m_argv.h; - refType = 2; - }; - 8417775C085A10EB000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_bbox.c; - path = ../../m_bbox.c; - refType = 2; - }; - 8417775D085A10EB000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_bbox.h; - path = ../../m_bbox.h; - refType = 2; - }; - 8417775E085A10EB000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_cheat.c; - path = ../../m_cheat.c; - refType = 2; - }; - 8417775F085A10EB000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_cheat.h; - path = ../../m_cheat.h; - refType = 2; - }; - 84177760085A10EB000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_fixed.c; - path = ../../m_fixed.c; - refType = 2; - }; - 84177761085A10EB000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_fixed.h; - path = ../../m_fixed.h; - refType = 2; - }; - 84177762085A10EB000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_menu.c; - path = ../../m_menu.c; - refType = 2; - }; - 84177763085A10EB000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_menu.h; - path = ../../m_menu.h; - refType = 2; - }; - 84177764085A10EB000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_misc.c; - path = ../../m_misc.c; - refType = 2; - }; - 84177765085A10EB000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_misc.h; - path = ../../m_misc.h; - refType = 2; - }; - 84177764085A10EB000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = apng.c; - path = ../../apng.c; - refType = 2; - }; - 84177765085A10EB000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_misc.h; - path = ../../apng.h; - refType = 2; - }; - 84177766085A10EB000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_random.c; - path = ../../m_random.c; - refType = 2; - }; - 84177767085A10EB000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_random.h; - path = ../../m_random.h; - refType = 2; - }; - 84177768085A10EB000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = m_swap.h; - path = ../../m_swap.h; - refType = 2; - }; - 84177769085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_ceilng.c; - path = ../../p_ceilng.c; - refType = 2; - }; - 8417776A085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_enemy.c; - path = ../../p_enemy.c; - refType = 2; - }; - 8417776B085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_fab.c; - path = ../../p_fab.c; - refType = 2; - }; - 8417776C085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_floor.c; - path = ../../p_floor.c; - refType = 2; - }; - 8417776D085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_inter.c; - path = ../../p_inter.c; - refType = 2; - }; - 8417776E085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_lights.c; - path = ../../p_lights.c; - refType = 2; - }; - 8417776F085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_local.h; - path = ../../p_local.h; - refType = 2; - }; - 84177770085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_map.c; - path = ../../p_map.c; - refType = 2; - }; - 84177771085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_maputl.c; - path = ../../p_maputl.c; - refType = 2; - }; - 84177772085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_maputl.h; - path = ../../p_maputl.h; - refType = 2; - }; - 84177773085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_mobj.c; - path = ../../p_mobj.c; - refType = 2; - }; - 84177774085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_mobj.h; - path = ../../p_mobj.h; - refType = 2; - }; - 84177775085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_pspr.h; - path = ../../p_pspr.h; - refType = 2; - }; - 84177776085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_saveg.c; - path = ../../p_saveg.c; - refType = 2; - }; - 84177777085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_saveg.h; - path = ../../p_saveg.h; - refType = 2; - }; - 84177778085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_setup.c; - path = ../../p_setup.c; - refType = 2; - }; - 84177779085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_setup.h; - path = ../../p_setup.h; - refType = 2; - }; - 8417777A085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_sight.c; - path = ../../p_sight.c; - refType = 2; - }; - 8417777B085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_spec.c; - path = ../../p_spec.c; - refType = 2; - }; - 8417777C085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_spec.h; - path = ../../p_spec.h; - refType = 2; - }; - 8417777D085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_telept.c; - path = ../../p_telept.c; - refType = 2; - }; - 8417777E085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_tick.c; - path = ../../p_tick.c; - refType = 2; - }; - 8417777F085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_tick.h; - path = ../../p_tick.h; - refType = 2; - }; - 84177780085A1104000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = p_user.c; - path = ../../p_user.c; - refType = 2; - }; - 84177781085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_bsp.c; - path = ../../r_bsp.c; - refType = 2; - }; - 84177782085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_bsp.h; - path = ../../r_bsp.h; - refType = 2; - }; - 84177783085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_data.c; - path = ../../r_data.c; - refType = 2; - }; - 84177784085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_data.h; - path = ../../r_data.h; - refType = 2; - }; - 84177785085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_defs.h; - path = ../../r_defs.h; - refType = 2; - }; - 84177786085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_draw.c; - path = ../../r_draw.c; - refType = 2; - }; - 84177787085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_draw.h; - path = ../../r_draw.h; - refType = 2; - }; - 84177788085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_draw8.c; - path = ../../r_draw8.c; - refType = 2; - }; - 84177789085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_draw16.c; - path = ../../r_draw16.c; - refType = 2; - }; - 8417778A085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_local.h; - path = ../../r_local.h; - refType = 2; - }; - 8417778B085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_main.c; - path = ../../r_main.c; - refType = 2; - }; - 8417778C085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_main.h; - path = ../../r_main.h; - refType = 2; - }; - 8417778D085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_plane.c; - path = ../../r_plane.c; - refType = 2; - }; - 8417778E085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_plane.h; - path = ../../r_plane.h; - refType = 2; - }; - 8417778F085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_segs.c; - path = ../../r_segs.c; - refType = 2; - }; - 84177790085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_segs.h; - path = ../../r_segs.h; - refType = 2; - }; - 84177791085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_sky.c; - path = ../../r_sky.c; - refType = 2; - }; - 84177792085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_sky.h; - path = ../../r_sky.h; - refType = 2; - }; - 84177793085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_splats.c; - path = ../../r_splats.c; - refType = 2; - }; - 84177794085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_splats.h; - path = ../../r_splats.h; - refType = 2; - }; - 84177795085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_state.h; - path = ../../r_state.h; - refType = 2; - }; - 84177796085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_things.c; - path = ../../r_things.c; - refType = 2; - }; - 84177797085A111B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = r_things.h; - path = ../../r_things.h; - refType = 2; - }; - 84177798085A1138000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = s_sound.c; - path = ../../s_sound.c; - refType = 2; - }; - 84177799085A1138000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = s_sound.h; - path = ../../s_sound.h; - refType = 2; - }; - 8417779A085A1138000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = sounds.c; - path = ../../sounds.c; - refType = 2; - }; - 8417779B085A1138000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = sounds.h; - path = ../../sounds.h; - refType = 2; - }; - 8417779C085A114C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - path = mac_alert.c; - refType = 2; - }; - 8417779D085A114C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - path = mac_alert.h; - refType = 2; - }; - 8417779E085A116B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = SDL_macosx_main.h; - path = ../SDL_main/SDL_macosx_main.h; - refType = 2; - }; - 8417779F085A116B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = SDL_macosx_main.m; - path = ../SDL_main/SDL_macosx_main.m; - refType = 2; - }; - 841777A0085A117F000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = w_wad.c; - path = ../../w_wad.c; - refType = 2; - }; - 841777A1085A117F000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = w_wad.h; - path = ../../w_wad.h; - refType = 2; - }; - 841777A2085A1197000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = screen.c; - path = ../../screen.c; - refType = 2; - }; - 841777A3085A1197000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = screen.h; - path = ../../screen.h; - refType = 2; - }; - 841777A4085A1200000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = filesrch.h; - path = ../../filesrch.h; - refType = 2; - }; - 841777A5085A1200000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = i_joy.h; - path = ../../i_joy.h; - refType = 2; - }; - 841777A6085A1200000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = i_net.h; - path = ../../i_net.h; - refType = 2; - }; - 841777A8085A1200000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = i_sound.h; - path = ../../i_sound.h; - refType = 2; - }; - 841777A9085A1200000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = i_system.h; - path = ../../i_system.h; - refType = 2; - }; - 841777AA085A1200000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = i_tcp.c; - path = ../../i_tcp.c; - refType = 2; - }; - 841777AB085A1200000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = i_tcp.h; - path = ../../i_tcp.h; - refType = 2; - }; - 841777AC085A1200000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = i_video.h; - path = ../../i_video.h; - refType = 2; - }; - 841777AD085A1200000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = mserv.c; - path = ../../mserv.c; - refType = 2; - }; - 841777AE085A1200000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = mserv.h; - path = ../../mserv.h; - refType = 2; - }; - 841777AF085A1228000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = md5.c; - path = ../../md5.c; - refType = 2; - }; - 841777B0085A1228000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = md5.h; - path = ../../md5.h; - refType = 2; - }; - 841778BC085A122A000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = z_zone.c; - path = ../../z_zone.c; - refType = 2; - }; - 841778BD085A122A000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = z_zone.h; - path = ../../z_zone.h; - refType = 2; - }; - 841778BE085A1295000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = am_map.c; - path = ../../am_map.c; - refType = 2; - }; - 841778BF085A1295000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = am_map.h; - path = ../../am_map.h; - refType = 2; - }; - 841778C0085A1295000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = command.c; - path = ../../command.c; - refType = 2; - }; - 841778C1085A1295000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = command.h; - path = ../../command.h; - refType = 2; - }; - 841778C2085A1295000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = console.c; - path = ../../console.c; - refType = 2; - }; - 841778C3085A1295000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = console.h; - path = ../../console.h; - refType = 2; - }; - 841778C4085A1295000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = info.c; - path = ../../info.c; - refType = 2; - }; - 841778C5085A1295000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = info.h; - path = ../../info.h; - refType = 2; - }; - 841778C6085A1295000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = keys.h; - path = ../../keys.h; - refType = 2; - }; - 841779D2085A1296000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = st_stuff.c; - path = ../../st_stuff.c; - refType = 2; - }; - 841779D3085A1296000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = st_stuff.h; - path = ../../st_stuff.h; - refType = 2; - }; - 841779D4085A1296000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = tables.c; - path = ../../tables.c; - refType = 2; - }; - 841779D5085A1296000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = tables.h; - path = ../../tables.h; - refType = 2; - }; - 841779D7085A1296000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = v_video.h; - path = ../../v_video.h; - refType = 2; - }; - 841779D8085A1296000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = y_inter.c; - path = ../../y_inter.c; - refType = 2; - }; - 841779DA085A1347000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = byteptr.h; - path = ../../byteptr.h; - refType = 2; - }; - 841779DC085A138F000C01D8 = { - buildActionMask = 2147483647; - files = ( - 6755C8C7101802C300A80195, - 6755C8C8101802C300A80195, - 6755C8C9101802C300A80195, - 6755C8CA101802C300A80195, - 6755C8CB101802C300A80195, - 6755C8CC101802C300A80195, - 6755C8CD101802C300A80195, - 6755C8CE101802C300A80195, - 6755C8CF101802C300A80195, - ); - isa = PBXResourcesBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 841779DD085A138F000C01D8 = { - buildActionMask = 2147483647; - files = ( - 84177A2A085A18A8000C01D8, - 84177A2E085A18D2000C01D8, - 84177A30085A18D3000C01D8, - 84177A32085A18D4000C01D8, - 84177A34085A18D5000C01D8, - 84177A39085A18D8000C01D8, - 84177A3F085A18DC000C01D8, - 84177A41085A18E0000C01D8, - 84177A43085A18E1000C01D8, - 84177A46085A18E8000C01D8, - 84177A4A085A18EA000C01D8, - 84177A4E085A18EC000C01D8, - 84177A50085A18F2000C01D8, - 84177A52085A193F000C01D8, - 84177A53085A1940000C01D8, - 84177A54085A1942000C01D8, - 84177A55085A1943000C01D8, - 84177A56085A195A000C01D8, - 84177A57085A195B000C01D8, - 84177A58085A1968000C01D8, - 84177A59085A1969000C01D8, - 84177A5A085A196B000C01D8, - 84177A5B085A197A000C01D8, - 84177A5C085A197C000C01D8, - 84177A5D085A197D000C01D8, - 84177A5E085A197E000C01D8, - 84177A5F085A1980000C01D8, - 84177A61085A1985000C01D8, - 84177A62085A1986000C01D8, - 84177A63085A1988000C01D8, - 84177A64085A1989000C01D8, - 84177A65085A198A000C01D8, - 84177A66085A198A000C01D8, - 84177A67085A198B000C01D8, - 84177A68085A198C000C01D8, - 84177A69085A198E000C01D8, - 84177A6B085A1994000C01D8, - 84177A6C085A1995000C01D8, - 84177A6D085A199D000C01D8, - 84177A6E085A19A0000C01D8, - 84177A6F085A19A1000C01D8, - 84177A70085A19A2000C01D8, - 84177A71085A19A4000C01D8, - 84177A72085A19A5000C01D8, - 84177A73085A19A6000C01D8, - 84177A74085A19A7000C01D8, - 84177A75085A19AC000C01D8, - 84177A76085A19AD000C01D8, - 84177A77085A19AE000C01D8, - 84177A78085A19AE000C01D8, - 84177A79085A19AF000C01D8, - 84177A7A085A19B0000C01D8, - 84177A7B085A19B3000C01D8, - 84177A7C085A19B4000C01D8, - 84177A7D085A19B5000C01D8, - 84177A7E085A19B7000C01D8, - 84177A7F085A19B8000C01D8, - 84177A80085A19B9000C01D8, - 84177A81085A19BA000C01D8, - 84177A82085A19BB000C01D8, - 84177A83085A19BB000C01D8, - 84177A84085A19BC000C01D8, - 84177A85085A19C1000C01D8, - 84177A86085A19C2000C01D8, - 84177A87085A19C3000C01D8, - 84177A88085A19C6000C01D8, - 84177A89085A19C7000C01D8, - 84177A8A085A19C9000C01D8, - 84177A8B085A19CC000C01D8, - 84177A8C085A19CD000C01D8, - 84177A8D085A19CF000C01D8, - 84177A8E085A19D0000C01D8, - 84177A90085A19D8000C01D8, - 84177A91085A19D9000C01D8, - 84177A92085A19DD000C01D8, - 84177A93085A19DF000C01D8, - 84177A94085A19E1000C01D8, - 84177A95085A19E3000C01D8, - 84177A96085A19E6000C01D8, - 8490D438085DF57B000C01D8, - 849603AA0A791C11000C01D8, - 6755C7B21017FE2500A80195, - 6755C7B31017FE2500A80195, - 6755C7B51017FE2500A80195, - 6755C7B71017FE2500A80195, - 6755C7B81017FE2500A80195, - 6755C84B1017FE4500A80195, - 6755C8651017FE4500A80195, - 677B5EC810180D4E00A80195, - 67B2D0C91018779900A80195, - ); - isa = PBXSourcesBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 841779DE085A138F000C01D8 = { - buildActionMask = 2147483647; - files = ( - 84C4E0410862096F000C01D8, - 84C4E0440862098A000C01D8, - 84C4E047086209D3000C01D8, - 84C4E04A086209FF000C01D8, - 84C4E04F08620A46000C01D8, - 84C4E05008620A46000C01D8, - 849BD31E0A7E45B3000C01D8, - ); - isa = PBXFrameworksBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 841779E0085A138F000C01D8 = { - buildPhases = ( - 841779DC085A138F000C01D8, - 841779DD085A138F000C01D8, - 841779DE085A138F000C01D8, - ); - buildSettings = { - DEBUGGING_SYMBOLS = NO; - FRAMEWORK_SEARCH_PATHS = "\"$(LOCAL_LIBRARY_DIR)/Frameworks\""; - HEADER_SEARCH_PATHS = "\"$(LOCAL_LIBRARY_DIR)/Frameworks/SDL.framework/Headers\" \"$(LOCAL_LIBRARY_DIR)/Frameworks/SDL_mixer.framework/Headers\" \"$(LOCAL_LIBRARY_DIR)/Frameworks/OpenAL.framework/Headers\" \"$(LOCAL_LIBRARY_DIR)/Frameworks/libpng.framework/Headers\""; - INSTALL_PATH = "$(HOME)/Applications"; - JAVA_COMPILER_DEBUGGING_SYMBOLS = NO; - OPTIMIZATION_CFLAGS = "-O2"; - OTHER_CFLAGS = "-DMAC_ALERT -DUNIXCOMMON -DSDLMAIN -DHAVE_MIXER -DHAVE_PNG -D_BIG_ENDIAN -DSTDC_HEADERS -DSDL -Wall -Winline -fno-strict-aliasing"; - OTHER_REZFLAGS = ""; - PREBINDING = NO; - PRODUCT_NAME = Srb2; - SECTORDER_FLAGS = ""; - USE_GCC3_PFE_SUPPORT = NO; - WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas -Wno-long-double"; - WRAPPER_EXTENSION = app; - }; - dependencies = ( - ); - isa = PBXApplicationTarget; - name = Srb2; - productInstallPath = "$(HOME)/Applications"; - productName = Srb2; - productReference = 841779E1085A138F000C01D8; - productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> -<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"> -<plist version=\"1.0\"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>English</string> - <key>CFBundleExecutable</key> - <string>Srb2</string> - <key>CFBundleGetInfoString</key> - <string></string> - <key>CFBundleIconFile</key> - <string>Srb2mac</string> - <key>CFBundleIdentifier</key> - <string></string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>Sonic Robo Blast 2</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>CFBundleShortVersionString</key> - <string>1.09</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1.09</string> - <key>NSMainNibFile</key> - <string>SDL_Main.nib</string> - <key>NSPrincipalClass</key> - <string>NSApplication</string> -</dict> -</plist> -"; - }; - 841779E1085A138F000C01D8 = { - isa = PBXApplicationReference; - path = Srb2.app; - refType = 3; - }; - 841779E2085A138F000C01D8 = { - children = ( - 841779E1085A138F000C01D8, - 841779EA085A13B1000C01D8, - ); - isa = PBXGroup; - name = Products; - refType = 4; - }; - 841779E6085A13B1000C01D8 = { - buildActionMask = 2147483647; - files = ( - 84177A98085A1A0B000C01D8, - 84177A99085A1A0E000C01D8, - 84177A9A085A1A0F000C01D8, - 84177A9B085A1A11000C01D8, - 84177A9C085A1A12000C01D8, - 84177A9D085A1A14000C01D8, - 84177A9E085A1A16000C01D8, - 84177A9F085A1A1E000C01D8, - 84177AA0085A1A1F000C01D8, - 84177AA1085A1A24000C01D8, - 84177AA2085A1A25000C01D8, - 84177AA3085A1A27000C01D8, - 84177AA4085A1A28000C01D8, - 84177AA5085A1A2B000C01D8, - 84177AA6085A1A2C000C01D8, - 84177AA7085A1A2D000C01D8, - 84177AA8085A1A2F000C01D8, - 84177AA9085A1A30000C01D8, - 84177AAA085A1A31000C01D8, - 84177AB4085A1A5E000C01D8, - 84177AB5085A1A60000C01D8, - 84177AB8085A1A65000C01D8, - 84177AB9085A1A65000C01D8, - 84177ABA085A1A66000C01D8, - 84177ABB085A1A67000C01D8, - 84177ABC085A1A67000C01D8, - 84177ABD085A1A68000C01D8, - 84177AC1085A1A70000C01D8, - 84177AC2085A1A72000C01D8, - 84177AC3085A1A77000C01D8, - 84177AC4085A1A78000C01D8, - 84177AC5085A1A7A000C01D8, - 84177AC6085A1A7B000C01D8, - 84177AC7085A1A7C000C01D8, - 84177AC8085A1A7D000C01D8, - 84177AC9085A1A7F000C01D8, - 84177ACA085A1A87000C01D8, - 84177ACB085A1A88000C01D8, - 84177ACC085A1A88000C01D8, - 84177ACD085A1A89000C01D8, - 84177ACE085A1A8A000C01D8, - 84177ACF085A1A8B000C01D8, - 84177AD0085A1A8C000C01D8, - 84177AD1085A1A8D000C01D8, - 84177AD2085A1A90000C01D8, - 84177AD4085A1A92000C01D8, - 84177AD5085A1A93000C01D8, - 84177AD6085A1A94000C01D8, - 84177AD7085A1A97000C01D8, - 84177AD8085A1A97000C01D8, - 84177AD9085A1A99000C01D8, - 84177ADA085A1A9F000C01D8, - 84177ADB085A1AA0000C01D8, - 84177ADC085A1AA2000C01D8, - 84177ADF085A1AA4000C01D8, - 84177AE0085A1AA6000C01D8, - 84177AE1085A1AA7000C01D8, - 84177AE2085A1AA8000C01D8, - 84177AE3085A1AA9000C01D8, - 84177AE4085A1AAA000C01D8, - 84177AE5085A1AAE000C01D8, - 84177AE7085A1AB5000C01D8, - 84177AE8085A1AB6000C01D8, - 84177AEB085A1ABD000C01D8, - 84177AEC085A1ABF000C01D8, - 84177AED085A1ABF000C01D8, - 8490D432085DF3D6000C01D8, - 8490D437085DF57B000C01D8, - 8490D43C085E0518000C01D8, - 8490D43D085E05F6000C01D8, - 8490D43E085E05F7000C01D8, - 8490D43F085E05F8000C01D8, - 8490D440085E05FA000C01D8, - 8490D441085E05FB000C01D8, - 8490D442085E05FC000C01D8, - 8490D443085E05FE000C01D8, - 8490D444085E05FF000C01D8, - 8490D445085E0606000C01D8, - 8490D446085E060A000C01D8, - 8490D447085E060B000C01D8, - 8490D448085E067E000C01D8, - 849603A90A791C11000C01D8, - 6755C7BB1017FE2500A80195, - 6755C7BC1017FE2500A80195, - 6755C7BD1017FE2500A80195, - 6755C7BE1017FE2500A80195, - 6755C7BF1017FE2500A80195, - 6755C7C01017FE2500A80195, - 6755C7C11017FE2500A80195, - 6755C8861017FE4500A80195, - 6755C8871017FE4500A80195, - 6755C8A01017FE4500A80195, - 67B2D0CA1018779D00A80195, - ); - isa = PBXSourcesBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 841779E7085A13B1000C01D8 = { - buildActionMask = 2147483647; - files = ( - 84C4E0400862096F000C01D8, - 84C4E0430862098A000C01D8, - 84C4E046086209D3000C01D8, - 84C4E049086209FF000C01D8, - 84C4E04E08620A46000C01D8, - 8494DFE80886EA0D000C01D8, - 849BD31D0A7E45B3000C01D8, - ); - isa = PBXFrameworksBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 841779E9085A13B1000C01D8 = { - buildPhases = ( - 840CE6B009198AA7000C01D8, - 6726EB5E10190F860074DCBA, - 6726EB5F10190FFC0074DCBA, - 841779E6085A13B1000C01D8, - 841779E7085A13B1000C01D8, - ); - buildSettings = { - FRAMEWORK_SEARCH_PATHS = "\"$(LOCAL_LIBRARY_DIR)/Frameworks\""; - HEADER_SEARCH_PATHS = "\"$(LOCAL_LIBRARY_DIR)/Frameworks/SDL.framework/Headers\" \"$(LOCAL_LIBRARY_DIR)/Frameworks/SDL_mixer.framework/Headers\" \"$(LOCAL_LIBRARY_DIR)/Frameworks/OpenAL.framework/Headers\" \"$(LOCAL_LIBRARY_DIR)/Frameworks/libpng.framework/Headers\""; - INSTALL_PATH = "$(HOME)/Applications"; - OPTIMIZATION_CFLAGS = "-O0"; - OTHER_CFLAGS = "-DMAC_ALERT -DUNIXCOMMON -DSDLMAIN -DHAVE_MIXER -DHAVE_PNG -D_BIG_ENDIAN -DSTDC_HEADERS -DSDL -Wall -W -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Wsign-compare -Waggregate-return -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -fno-strict-aliasing -fno-exceptions -D_DEBUG"; - OTHER_REZFLAGS = ""; - PREBINDING = NO; - PRODUCT_NAME = Srb2Debug; - SECTORDER_FLAGS = ""; - USE_GCC3_PFE_SUPPORT = NO; - WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas -Wno-long-double"; - WRAPPER_EXTENSION = app; - }; - dependencies = ( - ); - isa = PBXApplicationTarget; - name = Srb2Debug; - productInstallPath = "$(HOME)/Applications"; - productName = Srb2Debug; - productReference = 841779EA085A13B1000C01D8; - productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> -<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"> -<plist version=\"1.0\"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>English</string> - <key>CFBundleExecutable</key> - <string>Srb2Debug</string> - <key>CFBundleGetInfoString</key> - <string></string> - <key>CFBundleIconFile</key> - <string>srb2mac</string> - <key>CFBundleIdentifier</key> - <string></string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>Sonic Robo Blast 2</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>CFBundleShortVersionString</key> - <string>1.09</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1.09 Debug</string> - <key>NSMainNibFile</key> - <string>SDL_Main.nib</string> - <key>NSPrincipalClass</key> - <string>NSApplication</string> -</dict> -</plist> -"; - }; - 841779EA085A13B1000C01D8 = { - isa = PBXApplicationReference; - path = Srb2Debug.app; - refType = 3; - }; - 84177A2A085A18A8000C01D8 = { - fileRef = 84177713085A0FCE000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A2E085A18D2000C01D8 = { - fileRef = 84177717085A0FCE000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A30085A18D3000C01D8 = { - fileRef = 84177719085A0FCE000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A32085A18D4000C01D8 = { - fileRef = 8417771B085A0FCE000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A34085A18D5000C01D8 = { - fileRef = 8417771D085A0FCE000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A39085A18D8000C01D8 = { - fileRef = 84177722085A0FCE000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A41085A18E0000C01D8 = { - fileRef = 8417772A085A100E000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A43085A18E1000C01D8 = { - fileRef = 8417772C085A100E000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A46085A18E8000C01D8 = { - fileRef = 841778C4085A1295000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A4A085A18EA000C01D8 = { - fileRef = 8417772D085A1029000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A4E085A18EC000C01D8 = { - fileRef = 841779D4085A1296000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A50085A18F2000C01D8 = { - fileRef = 8417772F085A1029000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A52085A193F000C01D8 = { - fileRef = 841778C2085A1295000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A53085A1940000C01D8 = { - fileRef = 841778C0085A1295000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A54085A1942000C01D8 = { - fileRef = 841778BE085A1295000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A55085A1943000C01D8 = { - fileRef = 84177732085A1040000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A56085A195A000C01D8 = { - fileRef = 841779D2085A1296000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A57085A195B000C01D8 = { - fileRef = 841779D8085A1296000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A58085A1968000C01D8 = { - fileRef = 84177734085A106C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A59085A1969000C01D8 = { - fileRef = 84177735085A106C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A5A085A196B000C01D8 = { - fileRef = 84177739085A106C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A5B085A197A000C01D8 = { - fileRef = 8417773D085A106C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A5C085A197C000C01D8 = { - fileRef = 8417773F085A106C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A5D085A197D000C01D8 = { - fileRef = 84177741085A106C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A5E085A197E000C01D8 = { - fileRef = 84177743085A106C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A5F085A1980000C01D8 = { - fileRef = 84177745085A106C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A61085A1985000C01D8 = { - fileRef = 84177749085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A62085A1986000C01D8 = { - fileRef = 8417774B085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A63085A1988000C01D8 = { - fileRef = 8417774E085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A64085A1989000C01D8 = { - fileRef = 8417774F085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A65085A198A000C01D8 = { - fileRef = 84177750085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A66085A198A000C01D8 = { - fileRef = 84177751085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A67085A198B000C01D8 = { - fileRef = 84177752085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A68085A198C000C01D8 = { - fileRef = 84177753085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A69085A198E000C01D8 = { - fileRef = 84177755085A10AA000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A6B085A1994000C01D8 = { - fileRef = 841777AA085A1200000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A6C085A1995000C01D8 = { - fileRef = 841777AD085A1200000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A6D085A199D000C01D8 = { - fileRef = 8417774C085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A6E085A19A0000C01D8 = { - fileRef = 8417775A085A10EB000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A6F085A19A1000C01D8 = { - fileRef = 8417775C085A10EB000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A70085A19A2000C01D8 = { - fileRef = 8417775E085A10EB000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A71085A19A4000C01D8 = { - fileRef = 84177760085A10EB000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A72085A19A5000C01D8 = { - fileRef = 84177762085A10EB000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A73085A19A6000C01D8 = { - fileRef = 84177764085A10EB000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A74085A19A7000C01D8 = { - fileRef = 84177766085A10EB000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A75085A19AC000C01D8 = { - fileRef = 84177769085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A76085A19AD000C01D8 = { - fileRef = 8417776A085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A77085A19AE000C01D8 = { - fileRef = 8417776B085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A78085A19AE000C01D8 = { - fileRef = 8417776C085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A79085A19AF000C01D8 = { - fileRef = 8417776D085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A7A085A19B0000C01D8 = { - fileRef = 8417776E085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A7B085A19B3000C01D8 = { - fileRef = 84177770085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A7C085A19B4000C01D8 = { - fileRef = 84177771085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A7D085A19B5000C01D8 = { - fileRef = 84177773085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A7E085A19B7000C01D8 = { - fileRef = 84177776085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A7F085A19B8000C01D8 = { - fileRef = 84177778085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A80085A19B9000C01D8 = { - fileRef = 8417777A085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A81085A19BA000C01D8 = { - fileRef = 8417777B085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A82085A19BB000C01D8 = { - fileRef = 8417777D085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A83085A19BB000C01D8 = { - fileRef = 8417777E085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A84085A19BC000C01D8 = { - fileRef = 84177780085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A85085A19C1000C01D8 = { - fileRef = 84177781085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A86085A19C2000C01D8 = { - fileRef = 84177783085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A87085A19C3000C01D8 = { - fileRef = 84177786085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A88085A19C6000C01D8 = { - fileRef = 8417778B085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A89085A19C7000C01D8 = { - fileRef = 8417778D085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A8A085A19C9000C01D8 = { - fileRef = 8417778F085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A8B085A19CC000C01D8 = { - fileRef = 84177791085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A8C085A19CD000C01D8 = { - fileRef = 84177793085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A8D085A19CF000C01D8 = { - fileRef = 84177796085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A8E085A19D0000C01D8 = { - fileRef = 841777A2085A1197000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A90085A19D8000C01D8 = { - fileRef = 84177798085A1138000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A91085A19D9000C01D8 = { - fileRef = 8417779A085A1138000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A92085A19DD000C01D8 = { - fileRef = 8417779C085A114C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A93085A19DF000C01D8 = { - fileRef = 8417779F085A116B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A94085A19E1000C01D8 = { - fileRef = 841777A0085A117F000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A95085A19E3000C01D8 = { - fileRef = 841777AF085A1228000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A96085A19E6000C01D8 = { - fileRef = 841778BC085A122A000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A98085A1A0B000C01D8 = { - fileRef = 84177713085A0FCE000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A99085A1A0E000C01D8 = { - fileRef = 84177717085A0FCE000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A9A085A1A0F000C01D8 = { - fileRef = 84177719085A0FCE000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A9B085A1A11000C01D8 = { - fileRef = 8417771B085A0FCE000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A9C085A1A12000C01D8 = { - fileRef = 8417771D085A0FCE000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A9D085A1A14000C01D8 = { - fileRef = 84177722085A0FCE000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177A9F085A1A1E000C01D8 = { - fileRef = 8417772A085A100E000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AA0085A1A1F000C01D8 = { - fileRef = 8417772C085A100E000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AA1085A1A24000C01D8 = { - fileRef = 841778C4085A1295000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AA2085A1A25000C01D8 = { - fileRef = 8417772D085A1029000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AA3085A1A27000C01D8 = { - fileRef = 8417772F085A1029000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AA4085A1A28000C01D8 = { - fileRef = 841779D4085A1296000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AA5085A1A2B000C01D8 = { - fileRef = 841778BE085A1295000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AA6085A1A2C000C01D8 = { - fileRef = 841778C2085A1295000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AA7085A1A2D000C01D8 = { - fileRef = 841778C0085A1295000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AA8085A1A2F000C01D8 = { - fileRef = 84177732085A1040000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AA9085A1A30000C01D8 = { - fileRef = 841779D2085A1296000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AAA085A1A31000C01D8 = { - fileRef = 841779D8085A1296000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AB4085A1A5E000C01D8 = { - fileRef = 84177749085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AB5085A1A60000C01D8 = { - fileRef = 8417774B085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AB8085A1A65000C01D8 = { - fileRef = 8417774E085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AB9085A1A65000C01D8 = { - fileRef = 8417774F085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177ABA085A1A66000C01D8 = { - fileRef = 84177750085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177ABB085A1A67000C01D8 = { - fileRef = 84177751085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177ABC085A1A67000C01D8 = { - fileRef = 84177752085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177ABD085A1A68000C01D8 = { - fileRef = 84177753085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AC1085A1A70000C01D8 = { - fileRef = 841777AA085A1200000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AC2085A1A72000C01D8 = { - fileRef = 841777AD085A1200000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AC3085A1A77000C01D8 = { - fileRef = 8417775A085A10EB000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AC4085A1A78000C01D8 = { - fileRef = 8417775C085A10EB000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AC5085A1A7A000C01D8 = { - fileRef = 8417775E085A10EB000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AC6085A1A7B000C01D8 = { - fileRef = 84177760085A10EB000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AC7085A1A7C000C01D8 = { - fileRef = 84177762085A10EB000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AC8085A1A7D000C01D8 = { - fileRef = 84177764085A10EB000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AC9085A1A7F000C01D8 = { - fileRef = 84177766085A10EB000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177ACA085A1A87000C01D8 = { - fileRef = 84177769085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177ACB085A1A88000C01D8 = { - fileRef = 8417776A085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177ACC085A1A88000C01D8 = { - fileRef = 8417776B085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177ACD085A1A89000C01D8 = { - fileRef = 8417776C085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177ACE085A1A8A000C01D8 = { - fileRef = 8417776D085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177ACF085A1A8B000C01D8 = { - fileRef = 8417776E085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AD0085A1A8C000C01D8 = { - fileRef = 84177770085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AD1085A1A8D000C01D8 = { - fileRef = 84177771085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AD2085A1A90000C01D8 = { - fileRef = 84177773085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AD4085A1A92000C01D8 = { - fileRef = 84177778085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AD5085A1A93000C01D8 = { - fileRef = 8417777A085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AD6085A1A94000C01D8 = { - fileRef = 8417777B085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AD7085A1A97000C01D8 = { - fileRef = 8417777D085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AD8085A1A97000C01D8 = { - fileRef = 8417777E085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AD9085A1A99000C01D8 = { - fileRef = 84177780085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177ADA085A1A9F000C01D8 = { - fileRef = 84177781085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177ADB085A1AA0000C01D8 = { - fileRef = 84177783085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177ADC085A1AA2000C01D8 = { - fileRef = 84177786085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177ADF085A1AA4000C01D8 = { - fileRef = 8417778B085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AE0085A1AA6000C01D8 = { - fileRef = 8417778D085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AE1085A1AA7000C01D8 = { - fileRef = 8417778F085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AE2085A1AA8000C01D8 = { - fileRef = 84177791085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AE3085A1AA9000C01D8 = { - fileRef = 84177793085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AE4085A1AAA000C01D8 = { - fileRef = 84177796085A111B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AE5085A1AAE000C01D8 = { - fileRef = 841777A2085A1197000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AE7085A1AB5000C01D8 = { - fileRef = 84177798085A1138000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AE8085A1AB6000C01D8 = { - fileRef = 8417779A085A1138000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AEB085A1ABD000C01D8 = { - fileRef = 841777AF085A1228000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AEC085A1ABF000C01D8 = { - fileRef = 841777A0085A117F000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84177AED085A1ABF000C01D8 = { - fileRef = 841778BC085A122A000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 8490D432085DF3D6000C01D8 = { - fileRef = 84177776085A1104000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 8490D433085DF537000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = y_inter.h; - path = ../../y_inter.h; - refType = 2; - }; - 8490D436085DF57B000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = v_video.c; - path = ../../v_video.c; - refType = 2; - }; - 8490D437085DF57B000C01D8 = { - fileRef = 8490D436085DF57B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 8490D438085DF57B000C01D8 = { - fileRef = 8490D436085DF57B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 8490D43C085E0518000C01D8 = { - fileRef = 8417779F085A116B000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 8490D43D085E05F6000C01D8 = { - fileRef = 84177734085A106C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 8490D43E085E05F7000C01D8 = { - fileRef = 84177735085A106C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 8490D43F085E05F8000C01D8 = { - fileRef = 84177739085A106C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 8490D440085E05FA000C01D8 = { - fileRef = 8417773D085A106C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 8490D441085E05FB000C01D8 = { - fileRef = 8417773F085A106C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 8490D442085E05FC000C01D8 = { - fileRef = 84177741085A106C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 8490D443085E05FE000C01D8 = { - fileRef = 84177743085A106C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 8490D444085E05FF000C01D8 = { - fileRef = 84177745085A106C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 8490D445085E0606000C01D8 = { - fileRef = 8417774C085A1097000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 8490D446085E060A000C01D8 = { - fileRef = 84177755085A10AA000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 8490D447085E060B000C01D8 = { - fileRef = 84177758085A10D2000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 8490D448085E067E000C01D8 = { - fileRef = 8417779C085A114C000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 8494DFE80886EA0D000C01D8 = { - fileRef = 84C4E04B08620A46000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 849603A80A791C11000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = comptime.c; - path = ../../comptime.c; - refType = 2; - }; - 849603A90A791C11000C01D8 = { - fileRef = 849603A80A791C11000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 849603AA0A791C11000C01D8 = { - fileRef = 849603A80A791C11000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 849BD31C0A7E45B3000C01D8 = { - isa = PBXFrameworkReference; - name = libpng.framework; - path = /Library/Frameworks/libpng.framework; - refType = 0; - }; - 849BD31D0A7E45B3000C01D8 = { - fileRef = 849BD31C0A7E45B3000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 849BD31E0A7E45B3000C01D8 = { - fileRef = 849BD31C0A7E45B3000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 849BD32D0A7E471D000C01D8 = { - fileRef = 849BD31C0A7E45B3000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84C4E00D0862063C000C01D8 = { - children = ( - 6755C8BE101802C300A80195, - 6755C8BF101802C300A80195, - 6755C8C0101802C300A80195, - 6755C8C1101802C300A80195, - 6755C8C2101802C300A80195, - 6755C8C3101802C300A80195, - 6755C8C4101802C300A80195, - 6755C8C5101802C300A80195, - 6755C8C6101802C300A80195, - ); - isa = PBXGroup; - name = Data; - refType = 4; - }; - 84C4E03F0862096F000C01D8 = { - isa = PBXFrameworkReference; - name = AppKit.framework; - path = /System/Library/Frameworks/AppKit.framework; - refType = 0; - }; - 84C4E0400862096F000C01D8 = { - fileRef = 84C4E03F0862096F000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84C4E0410862096F000C01D8 = { - fileRef = 84C4E03F0862096F000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84C4E0420862098A000C01D8 = { - isa = PBXFrameworkReference; - name = Foundation.framework; - path = /System/Library/Frameworks/Foundation.framework; - refType = 0; - }; - 84C4E0430862098A000C01D8 = { - fileRef = 84C4E0420862098A000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84C4E0440862098A000C01D8 = { - fileRef = 84C4E0420862098A000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84C4E045086209D3000C01D8 = { - isa = PBXFrameworkReference; - name = CoreFoundation.framework; - path = /System/Library/Frameworks/CoreFoundation.framework; - refType = 0; - }; - 84C4E046086209D3000C01D8 = { - fileRef = 84C4E045086209D3000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84C4E047086209D3000C01D8 = { - fileRef = 84C4E045086209D3000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84C4E048086209FF000C01D8 = { - isa = PBXFrameworkReference; - name = ApplicationServices.framework; - path = /System/Library/Frameworks/ApplicationServices.framework; - refType = 0; - }; - 84C4E049086209FF000C01D8 = { - fileRef = 84C4E048086209FF000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84C4E04A086209FF000C01D8 = { - fileRef = 84C4E048086209FF000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84C4E04B08620A46000C01D8 = { - isa = PBXFrameworkReference; - name = SDL_mixer.framework; - path = /Library/Frameworks/SDL_mixer.framework; - refType = 0; - }; - 84C4E04C08620A46000C01D8 = { - isa = PBXFrameworkReference; - name = SDL.framework; - path = /Library/Frameworks/SDL.framework; - refType = 0; - }; - 84C4E04E08620A46000C01D8 = { - fileRef = 84C4E04C08620A46000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84C4E04F08620A46000C01D8 = { - fileRef = 84C4E04B08620A46000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84C4E05008620A46000C01D8 = { - fileRef = 84C4E04C08620A46000C01D8; - isa = PBXBuildFile; - settings = { - }; - }; - 84F202C708A92A5D000C01D8 = { - isa = PBXFrameworkReference; - name = OpenAL.framework; - path = /Library/Frameworks/OpenAL.framework; - refType = 0; - }; - 84F202CA08A92AA0000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = s_openal.c; - path = ../../hardware/s_openal/s_openal.c; - refType = 2; - }; - }; - rootObject = 84177702085A0C64000C01D8; -} diff --git a/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj b/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj deleted file mode 100644 index 6b3997b1f84983cc4318db6c6aea31b33be53bc7..0000000000000000000000000000000000000000 --- a/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj +++ /dev/null @@ -1,1515 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 44; - objects = { - -/* Begin PBXBuildFile section */ - 002F39FA09D0881F00EBEB88 /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F39F909D0881F00EBEB88 /* SDL.framework */; }; - 002F3A0009D0884600EBEB88 /* SDL.framework in Copy Frameworks into .app bundle */ = {isa = PBXBuildFile; fileRef = 002F39F909D0881F00EBEB88 /* SDL.framework */; }; - 1E308E720B71172D0015728C /* lzf.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44B2240B67EADE00BAD059 /* lzf.c */; }; - 1E32C4290B6E6D5D0029E058 /* libpng.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E32C4140B6E6D5D0029E058 /* libpng.framework */; }; - 1E32C42B0B6E6D6E0029E058 /* libpng.framework in Copy Frameworks into .app bundle */ = {isa = PBXBuildFile; fileRef = 1E32C4140B6E6D5D0029E058 /* libpng.framework */; }; - 1E44AE750B67CC2B00BAD059 /* hw_bsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE610B67CC2B00BAD059 /* hw_bsp.c */; }; - 1E44AE770B67CC2B00BAD059 /* hw3sound.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE630B67CC2B00BAD059 /* hw3sound.c */; }; - 1E44AE780B67CC2B00BAD059 /* hw_cache.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE640B67CC2B00BAD059 /* hw_cache.c */; }; - 1E44AE7C0B67CC2B00BAD059 /* hw_light.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE680B67CC2B00BAD059 /* hw_light.c */; }; - 1E44AE800B67CC2B00BAD059 /* hw_draw.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE6C0B67CC2B00BAD059 /* hw_draw.c */; }; - 1E44AE820B67CC2B00BAD059 /* hw_main.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE6E0B67CC2B00BAD059 /* hw_main.c */; }; - 1E44AE840B67CC2B00BAD059 /* hw_md2.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE700B67CC2B00BAD059 /* hw_md2.c */; }; - 1E44AE860B67CC2B00BAD059 /* hw_trick.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE720B67CC2B00BAD059 /* hw_trick.c */; }; - 1E44AEA40B67CC8500BAD059 /* d_clisrv.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE8D0B67CC8400BAD059 /* d_clisrv.c */; }; - 1E44AEA70B67CC8500BAD059 /* d_main.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE900B67CC8400BAD059 /* d_main.c */; }; - 1E44AEA80B67CC8500BAD059 /* d_net.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE910B67CC8500BAD059 /* d_net.c */; }; - 1E44AEAB0B67CC8500BAD059 /* d_netfil.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE940B67CC8500BAD059 /* d_netfil.c */; }; - 1E44AEAF0B67CC8500BAD059 /* d_netcmd.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE980B67CC8500BAD059 /* d_netcmd.c */; }; - 1E44AEB30B67CC8500BAD059 /* dehacked.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE9C0B67CC8500BAD059 /* dehacked.c */; }; - 1E44AEBF0B67CCA900BAD059 /* f_wipe.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEBC0B67CCA900BAD059 /* f_wipe.c */; }; - 1E44AEC00B67CCA900BAD059 /* f_finale.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEBD0B67CCA900BAD059 /* f_finale.c */; }; - 1E44AEC80B67CCC600BAD059 /* g_game.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEC30B67CCC600BAD059 /* g_game.c */; }; - 1E44AECC0B67CCC600BAD059 /* g_input.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEC70B67CCC600BAD059 /* g_input.c */; }; - 1E44AED00B67CCEE00BAD059 /* hu_stuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AECE0B67CCEE00BAD059 /* hu_stuff.c */; }; - 1E44AEDC0B67CD1300BAD059 /* i_tcp.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AED50B67CD1200BAD059 /* i_tcp.c */; }; - 1E44AEE30B67CD2B00BAD059 /* am_map.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEE10B67CD2B00BAD059 /* am_map.c */; }; - 1E44AEE90B67CD3F00BAD059 /* command.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEE70B67CD3F00BAD059 /* command.c */; }; - 1E44AEEC0B67CD4400BAD059 /* comptime.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEEB0B67CD4400BAD059 /* comptime.c */; }; - 1E44AEEF0B67CD5400BAD059 /* console.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEED0B67CD5400BAD059 /* console.c */; }; - 1E44AEF30B67CD7F00BAD059 /* filesrch.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEF10B67CD7F00BAD059 /* filesrch.c */; }; - 1E44AF070B67CDE900BAD059 /* m_argv.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEF80B67CDE900BAD059 /* m_argv.c */; }; - 1E44AF0A0B67CDE900BAD059 /* m_cheat.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEFB0B67CDE900BAD059 /* m_cheat.c */; }; - 1E44AF0B0B67CDE900BAD059 /* m_bbox.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEFC0B67CDE900BAD059 /* m_bbox.c */; }; - 1E44AF0D0B67CDE900BAD059 /* m_fixed.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEFE0B67CDE900BAD059 /* m_fixed.c */; }; - 1E44AF0F0B67CDE900BAD059 /* m_menu.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF000B67CDE900BAD059 /* m_menu.c */; }; - 1E44AF110B67CDE900BAD059 /* m_misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF020B67CDE900BAD059 /* m_misc.c */; }; - 1E44AF110B67CDE900BAD059 /* apng.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF020B67CDE900BAD059 /* apng.c */; }; - 1E44AF130B67CDE900BAD059 /* m_random.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF040B67CDE900BAD059 /* m_random.c */; }; - 1E44AF1A0B67CE2A00BAD059 /* info.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF180B67CE2A00BAD059 /* info.c */; }; - 1E44AF1E0B67CE3600BAD059 /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF1C0B67CE3600BAD059 /* md5.c */; }; - 1E44AF220B67CE4100BAD059 /* mserv.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF200B67CE4100BAD059 /* mserv.c */; }; - 1E44AF3C0B67CE5F00BAD059 /* p_enemy.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF240B67CE5F00BAD059 /* p_enemy.c */; }; - 1E44AF3D0B67CE5F00BAD059 /* p_inter.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF250B67CE5F00BAD059 /* p_inter.c */; }; - 1E44AF3E0B67CE5F00BAD059 /* p_fab.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF260B67CE5F00BAD059 /* p_fab.c */; }; - 1E44AF3F0B67CE5F00BAD059 /* p_lights.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF270B67CE5F00BAD059 /* p_lights.c */; }; - 1E44AF400B67CE5F00BAD059 /* p_map.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF280B67CE5F00BAD059 /* p_map.c */; }; - 1E44AF410B67CE5F00BAD059 /* p_maputl.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF290B67CE5F00BAD059 /* p_maputl.c */; }; - 1E44AF430B67CE5F00BAD059 /* p_mobj.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF2B0B67CE5F00BAD059 /* p_mobj.c */; }; - 1E44AF450B67CE5F00BAD059 /* p_floor.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF2D0B67CE5F00BAD059 /* p_floor.c */; }; - 1E44AF480B67CE5F00BAD059 /* p_saveg.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF300B67CE5F00BAD059 /* p_saveg.c */; }; - 1E44AF4A0B67CE5F00BAD059 /* p_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF320B67CE5F00BAD059 /* p_setup.c */; }; - 1E44AF4C0B67CE5F00BAD059 /* p_sight.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF340B67CE5F00BAD059 /* p_sight.c */; }; - 1E44AF4D0B67CE5F00BAD059 /* p_spec.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF350B67CE5F00BAD059 /* p_spec.c */; }; - 1E44AF4F0B67CE5F00BAD059 /* p_telept.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF370B67CE5F00BAD059 /* p_telept.c */; }; - 1E44AF500B67CE5F00BAD059 /* p_tick.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF380B67CE5F00BAD059 /* p_tick.c */; }; - 1E44AF520B67CE5F00BAD059 /* p_user.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF3A0B67CE5F00BAD059 /* p_user.c */; }; - 1E44AF530B67CE5F00BAD059 /* p_ceilng.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF3B0B67CE5F00BAD059 /* p_ceilng.c */; }; - 1E44AF6C0B67CEC200BAD059 /* r_bsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF550B67CEC100BAD059 /* r_bsp.c */; }; - 1E44AF6F0B67CEC200BAD059 /* r_data.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF580B67CEC100BAD059 /* r_data.c */; }; - 1E44AF700B67CEC200BAD059 /* r_draw.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF590B67CEC100BAD059 /* r_draw.c */; }; - 1E44AF730B67CEC200BAD059 /* r_main.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF5C0B67CEC100BAD059 /* r_main.c */; }; - 1E44AF780B67CEC200BAD059 /* r_plane.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF610B67CEC100BAD059 /* r_plane.c */; }; - 1E44AF7A0B67CEC200BAD059 /* r_segs.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF630B67CEC100BAD059 /* r_segs.c */; }; - 1E44AF7C0B67CEC200BAD059 /* r_sky.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF650B67CEC200BAD059 /* r_sky.c */; }; - 1E44AF7E0B67CEC200BAD059 /* r_splats.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF670B67CEC200BAD059 /* r_splats.c */; }; - 1E44AF810B67CEC200BAD059 /* r_things.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF6A0B67CEC200BAD059 /* r_things.c */; }; - 1E44AF870B67CEE000BAD059 /* s_sound.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF850B67CEE000BAD059 /* s_sound.c */; }; - 1E44AF8B0B67CEE900BAD059 /* screen.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF890B67CEE900BAD059 /* screen.c */; }; - 1E44AF8F0B67CEF000BAD059 /* sounds.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF8D0B67CEF000BAD059 /* sounds.c */; }; - 1E44AF930B67CEFF00BAD059 /* st_stuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF910B67CEFF00BAD059 /* st_stuff.c */; }; - 1E44AF9B0B67CF2E00BAD059 /* tables.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF990B67CF2E00BAD059 /* tables.c */; }; - 1E44AFA50B67CF5D00BAD059 /* v_video.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFA30B67CF5D00BAD059 /* v_video.c */; }; - 1E44AFA90B67CF6400BAD059 /* w_wad.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFA70B67CF6400BAD059 /* w_wad.c */; }; - 1E44AFAD0B67CF6F00BAD059 /* y_inter.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFAB0B67CF6F00BAD059 /* y_inter.c */; }; - 1E44AFB10B67CF7A00BAD059 /* z_zone.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFAF0B67CF7A00BAD059 /* z_zone.c */; }; - 1E44AFC40B67CFDC00BAD059 /* dosstr.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFB40B67CFDC00BAD059 /* dosstr.c */; }; - 1E44AFC50B67CFDC00BAD059 /* endtxt.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFB50B67CFDC00BAD059 /* endtxt.c */; }; - 1E44AFC70B67CFDC00BAD059 /* hwsym_sdl.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFB70B67CFDC00BAD059 /* hwsym_sdl.c */; }; - 1E44AFC90B67CFDC00BAD059 /* i_cdmus.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFB90B67CFDC00BAD059 /* i_cdmus.c */; }; - 1E44AFCA0B67CFDC00BAD059 /* i_main.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFBA0B67CFDC00BAD059 /* i_main.c */; }; - 1E44AFCB0B67CFDC00BAD059 /* i_net.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFBB0B67CFDC00BAD059 /* i_net.c */; }; - 1E44AFCD0B67CFDC00BAD059 /* i_system.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFBD0B67CFDC00BAD059 /* i_system.c */; }; - 1E44AFCE0B67CFDC00BAD059 /* i_video.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFBE0B67CFDC00BAD059 /* i_video.c */; }; - 1E44AFD00B67CFDC00BAD059 /* ogl_sdl.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFC00B67CFDC00BAD059 /* ogl_sdl.c */; }; - 1E44AFEA0B67D06200BAD059 /* Srb2mac.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1E44AFE70B67D06200BAD059 /* Srb2mac.icns */; }; - 1E44AFEB0B67D06200BAD059 /* mac_alert.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFE80B67D06200BAD059 /* mac_alert.c */; }; - 1E44AFED0B67D0AB00BAD059 /* r_opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFEC0B67D0AB00BAD059 /* r_opengl.c */; }; - 1E44B0590B67D81E00BAD059 /* SDL_macosx_main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E44B0570B67D81E00BAD059 /* SDL_macosx_main.m */; }; - 1E66921C0B690C5B00B7313A /* SDL_mixer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E66921B0B690C5B00B7313A /* SDL_mixer.framework */; }; - 1E66921D0B690C6B00B7313A /* SDL_mixer.framework in Copy Frameworks into .app bundle */ = {isa = PBXBuildFile; fileRef = 1E66921B0B690C5B00B7313A /* SDL_mixer.framework */; }; - 67259DFD18D2687D00F02971 /* lua_hudlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67259DFB18D2687D00F02971 /* lua_hudlib.c */; }; - 67259DFE18D2687D00F02971 /* lua_skinlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67259DFC18D2687D00F02971 /* lua_skinlib.c */; }; - 67259E0118D268AE00F02971 /* m_anigif.c in Sources */ = {isa = PBXBuildFile; fileRef = 67259DFF18D268AE00F02971 /* m_anigif.c */; }; - 67259E0618D268F700F02971 /* i_ttf.c in Sources */ = {isa = PBXBuildFile; fileRef = 67259E0218D268F600F02971 /* i_ttf.c */; }; - 67259E0718D268F700F02971 /* mixer_sound.c in Sources */ = {isa = PBXBuildFile; fileRef = 67259E0418D268F600F02971 /* mixer_sound.c */; }; - 67259E0818D268F700F02971 /* sdl_sound.c in Sources */ = {isa = PBXBuildFile; fileRef = 67259E0518D268F600F02971 /* sdl_sound.c */; }; - 67259E2E18D26D5700F02971 /* patch.dta in Resources */ = {isa = PBXBuildFile; fileRef = 67259E2B18D26D5700F02971 /* patch.dta */; }; - 67259E2F18D26D5700F02971 /* rings.dta in Resources */ = {isa = PBXBuildFile; fileRef = 67259E2C18D26D5700F02971 /* rings.dta */; }; - 67259E3018D26D5700F02971 /* srb2.srb in Resources */ = {isa = PBXBuildFile; fileRef = 67259E2D18D26D5700F02971 /* srb2.srb */; }; - 67259E3218D26DD200F02971 /* music.dta in Resources */ = {isa = PBXBuildFile; fileRef = 1E44AE440B67CBE800BAD059 /* music.dta */; }; - 67259E3318D26DD300F02971 /* player.dta in Resources */ = {isa = PBXBuildFile; fileRef = 67A1F91813FAD026009FA3E5 /* player.dta */; }; - 67259E3518D26DD500F02971 /* zones.dta in Resources */ = {isa = PBXBuildFile; fileRef = 6766C0AE11B057E50065F389 /* zones.dta */; }; - 676BB5200E0DE06100C95963 /* m_queue.c in Sources */ = {isa = PBXBuildFile; fileRef = 676BB51C0E0DE06100C95963 /* m_queue.c */; }; - 676BB5220E0DE06100C95963 /* p_polyobj.c in Sources */ = {isa = PBXBuildFile; fileRef = 676BB51E0E0DE06100C95963 /* p_polyobj.c */; }; - 67B83BFA14F57EAB00AAAE4E /* lapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BCB14F57EAB00AAAE4E /* lapi.c */; }; - 67B83BFB14F57EAB00AAAE4E /* lauxlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BCD14F57EAB00AAAE4E /* lauxlib.c */; }; - 67B83BFC14F57EAB00AAAE4E /* lbaselib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BCF14F57EAB00AAAE4E /* lbaselib.c */; }; - 67B83BFD14F57EAB00AAAE4E /* lcode.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BD014F57EAB00AAAE4E /* lcode.c */; }; - 67B83BFE14F57EAB00AAAE4E /* ldebug.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BD214F57EAB00AAAE4E /* ldebug.c */; }; - 67B83BFF14F57EAB00AAAE4E /* ldo.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BD414F57EAB00AAAE4E /* ldo.c */; }; - 67B83C0014F57EAB00AAAE4E /* ldump.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BD614F57EAB00AAAE4E /* ldump.c */; }; - 67B83C0114F57EAB00AAAE4E /* lfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BD714F57EAB00AAAE4E /* lfunc.c */; }; - 67B83C0214F57EAB00AAAE4E /* lgc.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BD914F57EAB00AAAE4E /* lgc.c */; }; - 67B83C0314F57EAB00AAAE4E /* linit.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BDB14F57EAB00AAAE4E /* linit.c */; }; - 67B83C0414F57EAB00AAAE4E /* llex.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BDC14F57EAB00AAAE4E /* llex.c */; }; - 67B83C0514F57EAB00AAAE4E /* lmem.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BDF14F57EAB00AAAE4E /* lmem.c */; }; - 67B83C0614F57EAB00AAAE4E /* lobject.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BE114F57EAB00AAAE4E /* lobject.c */; }; - 67B83C0714F57EAB00AAAE4E /* lopcodes.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BE314F57EAB00AAAE4E /* lopcodes.c */; }; - 67B83C0814F57EAB00AAAE4E /* lparser.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BE514F57EAB00AAAE4E /* lparser.c */; }; - 67B83C0914F57EAB00AAAE4E /* lstate.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BE714F57EAB00AAAE4E /* lstate.c */; }; - 67B83C0A14F57EAB00AAAE4E /* lstring.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BE914F57EAB00AAAE4E /* lstring.c */; }; - 67B83C0B14F57EAB00AAAE4E /* lstrlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BEB14F57EAB00AAAE4E /* lstrlib.c */; }; - 67B83C0C14F57EAB00AAAE4E /* ltable.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BEC14F57EAB00AAAE4E /* ltable.c */; }; - 67B83C0D14F57EAB00AAAE4E /* ltablib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BEE14F57EAB00AAAE4E /* ltablib.c */; }; - 67B83C0E14F57EAB00AAAE4E /* ltm.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BEF14F57EAB00AAAE4E /* ltm.c */; }; - 67B83C0F14F57EAB00AAAE4E /* lundump.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BF414F57EAB00AAAE4E /* lundump.c */; }; - 67B83C1014F57EAB00AAAE4E /* lvm.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BF614F57EAB00AAAE4E /* lvm.c */; }; - 67B83C1114F57EAB00AAAE4E /* lzio.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BF814F57EAB00AAAE4E /* lzio.c */; }; - 67B83C1414F57ECA00AAAE4E /* b_bot.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1214F57ECA00AAAE4E /* b_bot.c */; }; - 67B83C2214F57EE600AAAE4E /* lua_baselib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1514F57EE600AAAE4E /* lua_baselib.c */; }; - 67B83C2314F57EE600AAAE4E /* lua_consolelib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1614F57EE600AAAE4E /* lua_consolelib.c */; }; - 67B83C2414F57EE600AAAE4E /* lua_hooklib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1814F57EE600AAAE4E /* lua_hooklib.c */; }; - 67B83C2514F57EE600AAAE4E /* lua_infolib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1914F57EE600AAAE4E /* lua_infolib.c */; }; - 67B83C2614F57EE600AAAE4E /* lua_maplib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1B14F57EE600AAAE4E /* lua_maplib.c */; }; - 67B83C2714F57EE600AAAE4E /* lua_mathlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1C14F57EE600AAAE4E /* lua_mathlib.c */; }; - 67B83C2814F57EE600AAAE4E /* lua_mobjlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1D14F57EE600AAAE4E /* lua_mobjlib.c */; }; - 67B83C2914F57EE600AAAE4E /* lua_playerlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1E14F57EE600AAAE4E /* lua_playerlib.c */; }; - 67B83C2A14F57EE600AAAE4E /* lua_script.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1F14F57EE600AAAE4E /* lua_script.c */; }; - 67B83C2B14F57EE600AAAE4E /* lua_thinkerlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C2114F57EE600AAAE4E /* lua_thinkerlib.c */; }; - 67B83C3314F57F1500AAAE4E /* m_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C2F14F57F1500AAAE4E /* m_cond.c */; }; - 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; - 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 002F39FD09D0883400EBEB88 /* Copy Frameworks into .app bundle */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 12; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 1E32C42B0B6E6D6E0029E058 /* libpng.framework in Copy Frameworks into .app bundle */, - 1E66921D0B690C6B00B7313A /* SDL_mixer.framework in Copy Frameworks into .app bundle */, - 002F3A0009D0884600EBEB88 /* SDL.framework in Copy Frameworks into .app bundle */, - ); - name = "Copy Frameworks into .app bundle"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 002F39F909D0881F00EBEB88 /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = /Library/Frameworks/SDL.framework; sourceTree = "<absolute>"; }; - 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; }; - 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; }; - 1E32C4140B6E6D5D0029E058 /* libpng.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = libpng.framework; path = /Library/Frameworks/libpng.framework; sourceTree = "<absolute>"; }; - 1E44AE440B67CBE800BAD059 /* music.dta */ = {isa = PBXFileReference; lastKnownFileType = text; name = music.dta; path = ../../../bin/Resources/music.dta; sourceTree = SOURCE_ROOT; }; - 1E44AE4B0B67CBE800BAD059 /* srb2.wad */ = {isa = PBXFileReference; lastKnownFileType = text; name = srb2.wad; path = ../../../bin/Resources/srb2.wad; sourceTree = SOURCE_ROOT; }; - 1E44AE600B67CC2B00BAD059 /* hw3dsdrv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw3dsdrv.h; path = ../../hardware/hw3dsdrv.h; sourceTree = SOURCE_ROOT; }; - 1E44AE610B67CC2B00BAD059 /* hw_bsp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_bsp.c; path = ../../hardware/hw_bsp.c; sourceTree = SOURCE_ROOT; }; - 1E44AE620B67CC2B00BAD059 /* hw_defs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_defs.h; path = ../../hardware/hw_defs.h; sourceTree = SOURCE_ROOT; }; - 1E44AE630B67CC2B00BAD059 /* hw3sound.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw3sound.c; path = ../../hardware/hw3sound.c; sourceTree = SOURCE_ROOT; }; - 1E44AE640B67CC2B00BAD059 /* hw_cache.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_cache.c; path = ../../hardware/hw_cache.c; sourceTree = SOURCE_ROOT; }; - 1E44AE650B67CC2B00BAD059 /* hw_dll.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_dll.h; path = ../../hardware/hw_dll.h; sourceTree = SOURCE_ROOT; }; - 1E44AE660B67CC2B00BAD059 /* hw_drv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_drv.h; path = ../../hardware/hw_drv.h; sourceTree = SOURCE_ROOT; }; - 1E44AE670B67CC2B00BAD059 /* hw_glide.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_glide.h; path = ../../hardware/hw_glide.h; sourceTree = SOURCE_ROOT; }; - 1E44AE680B67CC2B00BAD059 /* hw_light.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_light.c; path = ../../hardware/hw_light.c; sourceTree = SOURCE_ROOT; }; - 1E44AE690B67CC2B00BAD059 /* hw_light.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_light.h; path = ../../hardware/hw_light.h; sourceTree = SOURCE_ROOT; }; - 1E44AE6A0B67CC2B00BAD059 /* hw3sound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw3sound.h; path = ../../hardware/hw3sound.h; sourceTree = SOURCE_ROOT; }; - 1E44AE6B0B67CC2B00BAD059 /* hw_data.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_data.h; path = ../../hardware/hw_data.h; sourceTree = SOURCE_ROOT; }; - 1E44AE6C0B67CC2B00BAD059 /* hw_draw.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_draw.c; path = ../../hardware/hw_draw.c; sourceTree = SOURCE_ROOT; }; - 1E44AE6D0B67CC2B00BAD059 /* hw_glob.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_glob.h; path = ../../hardware/hw_glob.h; sourceTree = SOURCE_ROOT; }; - 1E44AE6E0B67CC2B00BAD059 /* hw_main.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_main.c; path = ../../hardware/hw_main.c; sourceTree = SOURCE_ROOT; }; - 1E44AE6F0B67CC2B00BAD059 /* hw_main.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_main.h; path = ../../hardware/hw_main.h; sourceTree = SOURCE_ROOT; }; - 1E44AE700B67CC2B00BAD059 /* hw_md2.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_md2.c; path = ../../hardware/hw_md2.c; sourceTree = SOURCE_ROOT; }; - 1E44AE710B67CC2B00BAD059 /* hw_md2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_md2.h; path = ../../hardware/hw_md2.h; sourceTree = SOURCE_ROOT; }; - 1E44AE720B67CC2B00BAD059 /* hw_trick.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_trick.c; path = ../../hardware/hw_trick.c; sourceTree = SOURCE_ROOT; }; - 1E44AE730B67CC2B00BAD059 /* hws_data.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hws_data.h; path = ../../hardware/hws_data.h; sourceTree = SOURCE_ROOT; }; - 1E44AE8A0B67CC6000BAD059 /* asm_defs.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; name = asm_defs.inc; path = ../../asm_defs.inc; sourceTree = SOURCE_ROOT; }; - 1E44AE8D0B67CC8400BAD059 /* d_clisrv.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = d_clisrv.c; path = ../../d_clisrv.c; sourceTree = SOURCE_ROOT; }; - 1E44AE8E0B67CC8400BAD059 /* d_clisrv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_clisrv.h; path = ../../d_clisrv.h; sourceTree = SOURCE_ROOT; }; - 1E44AE8F0B67CC8400BAD059 /* d_event.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_event.h; path = ../../d_event.h; sourceTree = SOURCE_ROOT; }; - 1E44AE900B67CC8400BAD059 /* d_main.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = d_main.c; path = ../../d_main.c; sourceTree = SOURCE_ROOT; }; - 1E44AE910B67CC8500BAD059 /* d_net.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = d_net.c; path = ../../d_net.c; sourceTree = SOURCE_ROOT; }; - 1E44AE920B67CC8500BAD059 /* d_net.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_net.h; path = ../../d_net.h; sourceTree = SOURCE_ROOT; }; - 1E44AE930B67CC8500BAD059 /* d_netcmd.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_netcmd.h; path = ../../d_netcmd.h; sourceTree = SOURCE_ROOT; }; - 1E44AE940B67CC8500BAD059 /* d_netfil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = d_netfil.c; path = ../../d_netfil.c; sourceTree = SOURCE_ROOT; }; - 1E44AE950B67CC8500BAD059 /* d_player.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_player.h; path = ../../d_player.h; sourceTree = SOURCE_ROOT; }; - 1E44AE960B67CC8500BAD059 /* d_think.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_think.h; path = ../../d_think.h; sourceTree = SOURCE_ROOT; }; - 1E44AE980B67CC8500BAD059 /* d_netcmd.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = d_netcmd.c; path = ../../d_netcmd.c; sourceTree = SOURCE_ROOT; }; - 1E44AE990B67CC8500BAD059 /* d_ticcmd.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_ticcmd.h; path = ../../d_ticcmd.h; sourceTree = SOURCE_ROOT; }; - 1E44AE9A0B67CC8500BAD059 /* d_main.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_main.h; path = ../../d_main.h; sourceTree = SOURCE_ROOT; }; - 1E44AE9B0B67CC8500BAD059 /* d_netfil.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_netfil.h; path = ../../d_netfil.h; sourceTree = SOURCE_ROOT; }; - 1E44AE9C0B67CC8500BAD059 /* dehacked.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dehacked.c; path = ../../dehacked.c; sourceTree = SOURCE_ROOT; }; - 1E44AE9D0B67CC8500BAD059 /* dehacked.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dehacked.h; path = ../../dehacked.h; sourceTree = SOURCE_ROOT; }; - 1E44AE9E0B67CC8500BAD059 /* doomdata.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = doomdata.h; path = ../../doomdata.h; sourceTree = SOURCE_ROOT; }; - 1E44AE9F0B67CC8500BAD059 /* doomdef.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = doomdef.h; path = ../../doomdef.h; sourceTree = SOURCE_ROOT; }; - 1E44AEA00B67CC8500BAD059 /* doomstat.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = doomstat.h; path = ../../doomstat.h; sourceTree = SOURCE_ROOT; }; - 1E44AEA10B67CC8500BAD059 /* doomtype.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = doomtype.h; path = ../../doomtype.h; sourceTree = SOURCE_ROOT; }; - 1E44AEBC0B67CCA900BAD059 /* f_wipe.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = f_wipe.c; path = ../../f_wipe.c; sourceTree = SOURCE_ROOT; }; - 1E44AEBD0B67CCA900BAD059 /* f_finale.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = f_finale.c; path = ../../f_finale.c; sourceTree = SOURCE_ROOT; }; - 1E44AEBE0B67CCA900BAD059 /* f_finale.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = f_finale.h; path = ../../f_finale.h; sourceTree = SOURCE_ROOT; }; - 1E44AEC30B67CCC600BAD059 /* g_game.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = g_game.c; path = ../../g_game.c; sourceTree = SOURCE_ROOT; }; - 1E44AEC40B67CCC600BAD059 /* g_game.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = g_game.h; path = ../../g_game.h; sourceTree = SOURCE_ROOT; }; - 1E44AEC50B67CCC600BAD059 /* g_input.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = g_input.h; path = ../../g_input.h; sourceTree = SOURCE_ROOT; }; - 1E44AEC60B67CCC600BAD059 /* g_state.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = g_state.h; path = ../../g_state.h; sourceTree = SOURCE_ROOT; }; - 1E44AEC70B67CCC600BAD059 /* g_input.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = g_input.c; path = ../../g_input.c; sourceTree = SOURCE_ROOT; }; - 1E44AECE0B67CCEE00BAD059 /* hu_stuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hu_stuff.c; path = ../../hu_stuff.c; sourceTree = SOURCE_ROOT; }; - 1E44AECF0B67CCEE00BAD059 /* hu_stuff.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hu_stuff.h; path = ../../hu_stuff.h; sourceTree = SOURCE_ROOT; }; - 1E44AED30B67CD1200BAD059 /* i_net.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i_net.h; path = ../../i_net.h; sourceTree = SOURCE_ROOT; }; - 1E44AED40B67CD1200BAD059 /* i_sound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i_sound.h; path = ../../i_sound.h; sourceTree = SOURCE_ROOT; }; - 1E44AED50B67CD1200BAD059 /* i_tcp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = i_tcp.c; path = ../../i_tcp.c; sourceTree = SOURCE_ROOT; }; - 1E44AED60B67CD1200BAD059 /* i_tcp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i_tcp.h; path = ../../i_tcp.h; sourceTree = SOURCE_ROOT; }; - 1E44AED70B67CD1200BAD059 /* i_system.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i_system.h; path = ../../i_system.h; sourceTree = SOURCE_ROOT; }; - 1E44AED80B67CD1200BAD059 /* i_video.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i_video.h; path = ../../i_video.h; sourceTree = SOURCE_ROOT; }; - 1E44AED90B67CD1300BAD059 /* i_joy.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i_joy.h; path = ../../i_joy.h; sourceTree = SOURCE_ROOT; }; - 1E44AEE10B67CD2B00BAD059 /* am_map.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = am_map.c; path = ../../am_map.c; sourceTree = SOURCE_ROOT; }; - 1E44AEE20B67CD2B00BAD059 /* am_map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = am_map.h; path = ../../am_map.h; sourceTree = SOURCE_ROOT; }; - 1E44AEE50B67CD3200BAD059 /* byteptr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = byteptr.h; path = ../../byteptr.h; sourceTree = SOURCE_ROOT; }; - 1E44AEE70B67CD3F00BAD059 /* command.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = command.c; path = ../../command.c; sourceTree = SOURCE_ROOT; }; - 1E44AEE80B67CD3F00BAD059 /* command.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = command.h; path = ../../command.h; sourceTree = SOURCE_ROOT; }; - 1E44AEEB0B67CD4400BAD059 /* comptime.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = comptime.c; path = ../../comptime.c; sourceTree = SOURCE_ROOT; }; - 1E44AEED0B67CD5400BAD059 /* console.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = console.c; path = ../../console.c; sourceTree = SOURCE_ROOT; }; - 1E44AEEE0B67CD5400BAD059 /* console.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = console.h; path = ../../console.h; sourceTree = SOURCE_ROOT; }; - 1E44AEF10B67CD7F00BAD059 /* filesrch.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = filesrch.c; path = ../../filesrch.c; sourceTree = SOURCE_ROOT; }; - 1E44AEF20B67CD7F00BAD059 /* filesrch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = filesrch.h; path = ../../filesrch.h; sourceTree = SOURCE_ROOT; }; - 1E44AEF50B67CD9F00BAD059 /* keys.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = keys.h; path = ../../keys.h; sourceTree = SOURCE_ROOT; }; - 1E44AEF80B67CDE900BAD059 /* m_argv.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_argv.c; path = ../../m_argv.c; sourceTree = SOURCE_ROOT; }; - 1E44AEF90B67CDE900BAD059 /* m_bbox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_bbox.h; path = ../../m_bbox.h; sourceTree = SOURCE_ROOT; }; - 1E44AEFA0B67CDE900BAD059 /* m_argv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_argv.h; path = ../../m_argv.h; sourceTree = SOURCE_ROOT; }; - 1E44AEFB0B67CDE900BAD059 /* m_cheat.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_cheat.c; path = ../../m_cheat.c; sourceTree = SOURCE_ROOT; }; - 1E44AEFC0B67CDE900BAD059 /* m_bbox.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_bbox.c; path = ../../m_bbox.c; sourceTree = SOURCE_ROOT; }; - 1E44AEFD0B67CDE900BAD059 /* m_cheat.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_cheat.h; path = ../../m_cheat.h; sourceTree = SOURCE_ROOT; }; - 1E44AEFE0B67CDE900BAD059 /* m_fixed.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_fixed.c; path = ../../m_fixed.c; sourceTree = SOURCE_ROOT; }; - 1E44AEFF0B67CDE900BAD059 /* m_fixed.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_fixed.h; path = ../../m_fixed.h; sourceTree = SOURCE_ROOT; }; - 1E44AF000B67CDE900BAD059 /* m_menu.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_menu.c; path = ../../m_menu.c; sourceTree = SOURCE_ROOT; }; - 1E44AF010B67CDE900BAD059 /* m_menu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_menu.h; path = ../../m_menu.h; sourceTree = SOURCE_ROOT; }; - 1E44AF020B67CDE900BAD059 /* m_misc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_misc.c; path = ../../m_misc.c; sourceTree = SOURCE_ROOT; }; - 1E44AF030B67CDE900BAD059 /* m_misc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_misc.h; path = ../../m_misc.h; sourceTree = SOURCE_ROOT; }; - 1E44AF020B67CDE900BAD059 /* apng.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = apng.c; path = ../../m_misc.c; sourceTree = SOURCE_ROOT; }; - 1E44AF030B67CDE900BAD059 /* apng.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = apng.h; path = ../../m_misc.h; sourceTree = SOURCE_ROOT; }; - 1E44AF040B67CDE900BAD059 /* m_random.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_random.c; path = ../../m_random.c; sourceTree = SOURCE_ROOT; }; - 1E44AF050B67CDE900BAD059 /* m_random.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_random.h; path = ../../m_random.h; sourceTree = SOURCE_ROOT; }; - 1E44AF060B67CDE900BAD059 /* m_swap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_swap.h; path = ../../m_swap.h; sourceTree = SOURCE_ROOT; }; - 1E44AF180B67CE2A00BAD059 /* info.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = info.c; path = ../../info.c; sourceTree = SOURCE_ROOT; }; - 1E44AF190B67CE2A00BAD059 /* info.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = info.h; path = ../../info.h; sourceTree = SOURCE_ROOT; }; - 1E44AF1C0B67CE3600BAD059 /* md5.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = md5.c; path = ../../md5.c; sourceTree = SOURCE_ROOT; }; - 1E44AF1D0B67CE3600BAD059 /* md5.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = md5.h; path = ../../md5.h; sourceTree = SOURCE_ROOT; }; - 1E44AF200B67CE4100BAD059 /* mserv.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = mserv.c; path = ../../mserv.c; sourceTree = SOURCE_ROOT; }; - 1E44AF210B67CE4100BAD059 /* mserv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mserv.h; path = ../../mserv.h; sourceTree = SOURCE_ROOT; }; - 1E44AF240B67CE5F00BAD059 /* p_enemy.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_enemy.c; path = ../../p_enemy.c; sourceTree = SOURCE_ROOT; }; - 1E44AF250B67CE5F00BAD059 /* p_inter.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_inter.c; path = ../../p_inter.c; sourceTree = SOURCE_ROOT; }; - 1E44AF260B67CE5F00BAD059 /* p_fab.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_fab.c; path = ../../p_fab.c; sourceTree = SOURCE_ROOT; }; - 1E44AF270B67CE5F00BAD059 /* p_lights.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_lights.c; path = ../../p_lights.c; sourceTree = SOURCE_ROOT; }; - 1E44AF280B67CE5F00BAD059 /* p_map.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_map.c; path = ../../p_map.c; sourceTree = SOURCE_ROOT; }; - 1E44AF290B67CE5F00BAD059 /* p_maputl.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_maputl.c; path = ../../p_maputl.c; sourceTree = SOURCE_ROOT; }; - 1E44AF2A0B67CE5F00BAD059 /* p_maputl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = p_maputl.h; path = ../../p_maputl.h; sourceTree = SOURCE_ROOT; }; - 1E44AF2B0B67CE5F00BAD059 /* p_mobj.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_mobj.c; path = ../../p_mobj.c; sourceTree = SOURCE_ROOT; }; - 1E44AF2C0B67CE5F00BAD059 /* p_mobj.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = p_mobj.h; path = ../../p_mobj.h; sourceTree = SOURCE_ROOT; }; - 1E44AF2D0B67CE5F00BAD059 /* p_floor.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_floor.c; path = ../../p_floor.c; sourceTree = SOURCE_ROOT; }; - 1E44AF2E0B67CE5F00BAD059 /* p_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = p_local.h; path = ../../p_local.h; sourceTree = SOURCE_ROOT; }; - 1E44AF2F0B67CE5F00BAD059 /* p_pspr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = p_pspr.h; path = ../../p_pspr.h; sourceTree = SOURCE_ROOT; }; - 1E44AF300B67CE5F00BAD059 /* p_saveg.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_saveg.c; path = ../../p_saveg.c; sourceTree = SOURCE_ROOT; }; - 1E44AF310B67CE5F00BAD059 /* p_saveg.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = p_saveg.h; path = ../../p_saveg.h; sourceTree = SOURCE_ROOT; }; - 1E44AF320B67CE5F00BAD059 /* p_setup.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_setup.c; path = ../../p_setup.c; sourceTree = SOURCE_ROOT; }; - 1E44AF330B67CE5F00BAD059 /* p_setup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = p_setup.h; path = ../../p_setup.h; sourceTree = SOURCE_ROOT; }; - 1E44AF340B67CE5F00BAD059 /* p_sight.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_sight.c; path = ../../p_sight.c; sourceTree = SOURCE_ROOT; }; - 1E44AF350B67CE5F00BAD059 /* p_spec.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_spec.c; path = ../../p_spec.c; sourceTree = SOURCE_ROOT; }; - 1E44AF360B67CE5F00BAD059 /* p_spec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = p_spec.h; path = ../../p_spec.h; sourceTree = SOURCE_ROOT; }; - 1E44AF370B67CE5F00BAD059 /* p_telept.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_telept.c; path = ../../p_telept.c; sourceTree = SOURCE_ROOT; }; - 1E44AF380B67CE5F00BAD059 /* p_tick.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_tick.c; path = ../../p_tick.c; sourceTree = SOURCE_ROOT; }; - 1E44AF390B67CE5F00BAD059 /* p_tick.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = p_tick.h; path = ../../p_tick.h; sourceTree = SOURCE_ROOT; }; - 1E44AF3A0B67CE5F00BAD059 /* p_user.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_user.c; path = ../../p_user.c; sourceTree = SOURCE_ROOT; }; - 1E44AF3B0B67CE5F00BAD059 /* p_ceilng.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_ceilng.c; path = ../../p_ceilng.c; sourceTree = SOURCE_ROOT; }; - 1E44AF550B67CEC100BAD059 /* r_bsp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_bsp.c; path = ../../r_bsp.c; sourceTree = SOURCE_ROOT; }; - 1E44AF560B67CEC100BAD059 /* r_bsp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_bsp.h; path = ../../r_bsp.h; sourceTree = SOURCE_ROOT; }; - 1E44AF570B67CEC100BAD059 /* r_defs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_defs.h; path = ../../r_defs.h; sourceTree = SOURCE_ROOT; }; - 1E44AF580B67CEC100BAD059 /* r_data.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_data.c; path = ../../r_data.c; sourceTree = SOURCE_ROOT; }; - 1E44AF590B67CEC100BAD059 /* r_draw.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_draw.c; path = ../../r_draw.c; sourceTree = SOURCE_ROOT; }; - 1E44AF5A0B67CEC100BAD059 /* r_draw16.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_draw16.c; path = ../../r_draw16.c; sourceTree = SOURCE_ROOT; }; - 1E44AF5B0B67CEC100BAD059 /* r_draw8.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_draw8.c; path = ../../r_draw8.c; sourceTree = SOURCE_ROOT; }; - 1E44AF5C0B67CEC100BAD059 /* r_main.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_main.c; path = ../../r_main.c; sourceTree = SOURCE_ROOT; }; - 1E44AF5D0B67CEC100BAD059 /* r_main.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_main.h; path = ../../r_main.h; sourceTree = SOURCE_ROOT; }; - 1E44AF5E0B67CEC100BAD059 /* r_data.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_data.h; path = ../../r_data.h; sourceTree = SOURCE_ROOT; }; - 1E44AF5F0B67CEC100BAD059 /* r_draw.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_draw.h; path = ../../r_draw.h; sourceTree = SOURCE_ROOT; }; - 1E44AF600B67CEC100BAD059 /* r_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_local.h; path = ../../r_local.h; sourceTree = SOURCE_ROOT; }; - 1E44AF610B67CEC100BAD059 /* r_plane.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_plane.c; path = ../../r_plane.c; sourceTree = SOURCE_ROOT; }; - 1E44AF620B67CEC100BAD059 /* r_plane.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_plane.h; path = ../../r_plane.h; sourceTree = SOURCE_ROOT; }; - 1E44AF630B67CEC100BAD059 /* r_segs.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_segs.c; path = ../../r_segs.c; sourceTree = SOURCE_ROOT; }; - 1E44AF640B67CEC100BAD059 /* r_segs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_segs.h; path = ../../r_segs.h; sourceTree = SOURCE_ROOT; }; - 1E44AF650B67CEC200BAD059 /* r_sky.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_sky.c; path = ../../r_sky.c; sourceTree = SOURCE_ROOT; }; - 1E44AF660B67CEC200BAD059 /* r_sky.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_sky.h; path = ../../r_sky.h; sourceTree = SOURCE_ROOT; }; - 1E44AF670B67CEC200BAD059 /* r_splats.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_splats.c; path = ../../r_splats.c; sourceTree = SOURCE_ROOT; }; - 1E44AF680B67CEC200BAD059 /* r_splats.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_splats.h; path = ../../r_splats.h; sourceTree = SOURCE_ROOT; }; - 1E44AF690B67CEC200BAD059 /* r_state.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_state.h; path = ../../r_state.h; sourceTree = SOURCE_ROOT; }; - 1E44AF6A0B67CEC200BAD059 /* r_things.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_things.c; path = ../../r_things.c; sourceTree = SOURCE_ROOT; }; - 1E44AF6B0B67CEC200BAD059 /* r_things.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_things.h; path = ../../r_things.h; sourceTree = SOURCE_ROOT; }; - 1E44AF850B67CEE000BAD059 /* s_sound.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = s_sound.c; path = ../../s_sound.c; sourceTree = SOURCE_ROOT; }; - 1E44AF860B67CEE000BAD059 /* s_sound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = s_sound.h; path = ../../s_sound.h; sourceTree = SOURCE_ROOT; }; - 1E44AF890B67CEE900BAD059 /* screen.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = screen.c; path = ../../screen.c; sourceTree = SOURCE_ROOT; }; - 1E44AF8A0B67CEE900BAD059 /* screen.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = screen.h; path = ../../screen.h; sourceTree = SOURCE_ROOT; }; - 1E44AF8D0B67CEF000BAD059 /* sounds.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = sounds.c; path = ../../sounds.c; sourceTree = SOURCE_ROOT; }; - 1E44AF8E0B67CEF000BAD059 /* sounds.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sounds.h; path = ../../sounds.h; sourceTree = SOURCE_ROOT; }; - 1E44AF910B67CEFF00BAD059 /* st_stuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = st_stuff.c; path = ../../st_stuff.c; sourceTree = SOURCE_ROOT; }; - 1E44AF920B67CEFF00BAD059 /* st_stuff.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = st_stuff.h; path = ../../st_stuff.h; sourceTree = SOURCE_ROOT; }; - 1E44AF950B67CF1300BAD059 /* string.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = string.c; path = ../../string.c; sourceTree = SOURCE_ROOT; }; - 1E44AF990B67CF2E00BAD059 /* tables.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = tables.c; path = ../../tables.c; sourceTree = SOURCE_ROOT; }; - 1E44AF9A0B67CF2E00BAD059 /* tables.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tables.h; path = ../../tables.h; sourceTree = SOURCE_ROOT; }; - 1E44AF9D0B67CF3D00BAD059 /* tmap.nas */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = tmap.nas; path = ../../tmap.nas; sourceTree = SOURCE_ROOT; }; - 1E44AF9F0B67CF4900BAD059 /* tmap_mmx.nas */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = tmap_mmx.nas; path = ../../tmap_mmx.nas; sourceTree = SOURCE_ROOT; }; - 1E44AFA00B67CF4900BAD059 /* tmap_vc.nas */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = tmap_vc.nas; path = ../../tmap_vc.nas; sourceTree = SOURCE_ROOT; }; - 1E44AFA30B67CF5D00BAD059 /* v_video.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = v_video.c; path = ../../v_video.c; sourceTree = SOURCE_ROOT; }; - 1E44AFA40B67CF5D00BAD059 /* v_video.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = v_video.h; path = ../../v_video.h; sourceTree = SOURCE_ROOT; }; - 1E44AFA70B67CF6400BAD059 /* w_wad.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = w_wad.c; path = ../../w_wad.c; sourceTree = SOURCE_ROOT; }; - 1E44AFA80B67CF6400BAD059 /* w_wad.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = w_wad.h; path = ../../w_wad.h; sourceTree = SOURCE_ROOT; }; - 1E44AFAB0B67CF6F00BAD059 /* y_inter.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = y_inter.c; path = ../../y_inter.c; sourceTree = SOURCE_ROOT; }; - 1E44AFAC0B67CF6F00BAD059 /* y_inter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = y_inter.h; path = ../../y_inter.h; sourceTree = SOURCE_ROOT; }; - 1E44AFAF0B67CF7A00BAD059 /* z_zone.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = z_zone.c; path = ../../z_zone.c; sourceTree = SOURCE_ROOT; }; - 1E44AFB00B67CF7A00BAD059 /* z_zone.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = z_zone.h; path = ../../z_zone.h; sourceTree = SOURCE_ROOT; }; - 1E44AFB40B67CFDC00BAD059 /* dosstr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dosstr.c; path = ../dosstr.c; sourceTree = SOURCE_ROOT; }; - 1E44AFB50B67CFDC00BAD059 /* endtxt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = endtxt.c; path = ../endtxt.c; sourceTree = SOURCE_ROOT; }; - 1E44AFB60B67CFDC00BAD059 /* endtxt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = endtxt.h; path = ../endtxt.h; sourceTree = SOURCE_ROOT; }; - 1E44AFB70B67CFDC00BAD059 /* hwsym_sdl.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hwsym_sdl.c; path = ../hwsym_sdl.c; sourceTree = SOURCE_ROOT; }; - 1E44AFB80B67CFDC00BAD059 /* hwsym_sdl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hwsym_sdl.h; path = ../hwsym_sdl.h; sourceTree = SOURCE_ROOT; }; - 1E44AFB90B67CFDC00BAD059 /* i_cdmus.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = i_cdmus.c; path = ../i_cdmus.c; sourceTree = SOURCE_ROOT; }; - 1E44AFBA0B67CFDC00BAD059 /* i_main.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = i_main.c; path = ../i_main.c; sourceTree = SOURCE_ROOT; }; - 1E44AFBB0B67CFDC00BAD059 /* i_net.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = i_net.c; path = ../i_net.c; sourceTree = SOURCE_ROOT; }; - 1E44AFBD0B67CFDC00BAD059 /* i_system.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = i_system.c; path = ../i_system.c; sourceTree = SOURCE_ROOT; }; - 1E44AFBE0B67CFDC00BAD059 /* i_video.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = i_video.c; path = ../i_video.c; sourceTree = SOURCE_ROOT; }; - 1E44AFBF0B67CFDC00BAD059 /* IMG_xpm.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = IMG_xpm.c; path = ../IMG_xpm.c; sourceTree = SOURCE_ROOT; }; - 1E44AFC00B67CFDC00BAD059 /* ogl_sdl.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ogl_sdl.c; path = ../ogl_sdl.c; sourceTree = SOURCE_ROOT; }; - 1E44AFC10B67CFDC00BAD059 /* ogl_sdl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ogl_sdl.h; path = ../ogl_sdl.h; sourceTree = SOURCE_ROOT; }; - 1E44AFC20B67CFDC00BAD059 /* SDL_icon.xpm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = SDL_icon.xpm; path = ../SDL_icon.xpm; sourceTree = SOURCE_ROOT; }; - 1E44AFC30B67CFDC00BAD059 /* sdlmain.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sdlmain.h; path = ../sdlmain.h; sourceTree = SOURCE_ROOT; }; - 1E44AFD50B67D03100BAD059 /* filters.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = filters.c; path = ../filter/filters.c; sourceTree = SOURCE_ROOT; }; - 1E44AFD60B67D03100BAD059 /* filters.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = filters.h; path = ../filter/filters.h; sourceTree = SOURCE_ROOT; }; - 1E44AFD70B67D03100BAD059 /* hq2x.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hq2x.c; path = ../filter/hq2x.c; sourceTree = SOURCE_ROOT; }; - 1E44AFD80B67D03100BAD059 /* hq2x.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hq2x.h; path = ../filter/hq2x.h; sourceTree = SOURCE_ROOT; }; - 1E44AFD90B67D03100BAD059 /* interp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = interp.h; path = ../filter/interp.h; sourceTree = SOURCE_ROOT; }; - 1E44AFDA0B67D03100BAD059 /* lq2x.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lq2x.c; path = ../filter/lq2x.c; sourceTree = SOURCE_ROOT; }; - 1E44AFDB0B67D03100BAD059 /* lq2x.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lq2x.h; path = ../filter/lq2x.h; sourceTree = SOURCE_ROOT; }; - 1E44AFDC0B67D03100BAD059 /* main.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = main.c; path = ../filter/main.c; sourceTree = SOURCE_ROOT; }; - 1E44AFE60B67D06200BAD059 /* mac_alert.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mac_alert.h; sourceTree = SOURCE_ROOT; }; - 1E44AFE70B67D06200BAD059 /* Srb2mac.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Srb2mac.icns; sourceTree = SOURCE_ROOT; }; - 1E44AFE80B67D06200BAD059 /* mac_alert.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = mac_alert.c; sourceTree = SOURCE_ROOT; }; - 1E44AFEC0B67D0AB00BAD059 /* r_opengl.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_opengl.c; path = ../../hardware/r_opengl/r_opengl.c; sourceTree = SOURCE_ROOT; }; - 1E44B0560B67D81E00BAD059 /* SDL_macosx_main.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SDL_macosx_main.h; path = ../SDL_main/SDL_macosx_main.h; sourceTree = SOURCE_ROOT; }; - 1E44B0570B67D81E00BAD059 /* SDL_macosx_main.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = SDL_macosx_main.m; path = ../SDL_main/SDL_macosx_main.m; sourceTree = SOURCE_ROOT; }; - 1E44B2240B67EADE00BAD059 /* lzf.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lzf.c; path = ../../lzf.c; sourceTree = SOURCE_ROOT; }; - 1E44B2250B67EADE00BAD059 /* lzf.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lzf.h; path = ../../lzf.h; sourceTree = SOURCE_ROOT; }; - 1E66921B0B690C5B00B7313A /* SDL_mixer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL_mixer.framework; path = /Library/Frameworks/SDL_mixer.framework; sourceTree = "<absolute>"; }; - 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; }; - 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; }; - 67259DFA18D2687D00F02971 /* lua_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_hud.h; path = ../../lua_hud.h; sourceTree = SOURCE_ROOT; }; - 67259DFB18D2687D00F02971 /* lua_hudlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_hudlib.c; path = ../../lua_hudlib.c; sourceTree = SOURCE_ROOT; }; - 67259DFC18D2687D00F02971 /* lua_skinlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_skinlib.c; path = ../../lua_skinlib.c; sourceTree = SOURCE_ROOT; }; - 67259DFF18D268AE00F02971 /* m_anigif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = m_anigif.c; path = ../../m_anigif.c; sourceTree = SOURCE_ROOT; }; - 67259E0018D268AE00F02971 /* m_anigif.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m_anigif.h; path = ../../m_anigif.h; sourceTree = SOURCE_ROOT; }; - 67259E0218D268F600F02971 /* i_ttf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = i_ttf.c; path = ../i_ttf.c; sourceTree = SOURCE_ROOT; }; - 67259E0318D268F600F02971 /* i_ttf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = i_ttf.h; path = ../i_ttf.h; sourceTree = SOURCE_ROOT; }; - 67259E0418D268F600F02971 /* mixer_sound.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mixer_sound.c; path = ../mixer_sound.c; sourceTree = SOURCE_ROOT; }; - 67259E0518D268F600F02971 /* sdl_sound.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sdl_sound.c; path = ../sdl_sound.c; sourceTree = SOURCE_ROOT; }; - 67259E2B18D26D5700F02971 /* patch.dta */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = patch.dta; path = ../../../bin/Resources/patch.dta; sourceTree = SOURCE_ROOT; }; - 67259E2C18D26D5700F02971 /* rings.dta */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = rings.dta; path = ../../../bin/Resources/rings.dta; sourceTree = SOURCE_ROOT; }; - 67259E2D18D26D5700F02971 /* srb2.srb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = srb2.srb; path = ../../../bin/Resources/srb2.srb; sourceTree = SOURCE_ROOT; }; - 6766C0AE11B057E50065F389 /* zones.dta */ = {isa = PBXFileReference; lastKnownFileType = text; name = zones.dta; path = ../../../bin/Resources/zones.dta; sourceTree = SOURCE_ROOT; }; - 676BB51C0E0DE06100C95963 /* m_queue.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = m_queue.c; path = ../../m_queue.c; sourceTree = SOURCE_ROOT; }; - 676BB51D0E0DE06100C95963 /* m_queue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m_queue.h; path = ../../m_queue.h; sourceTree = SOURCE_ROOT; }; - 676BB51E0E0DE06100C95963 /* p_polyobj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = p_polyobj.c; path = ../../p_polyobj.c; sourceTree = SOURCE_ROOT; }; - 676BB51F0E0DE06100C95963 /* p_polyobj.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = p_polyobj.h; path = ../../p_polyobj.h; sourceTree = SOURCE_ROOT; }; - 67A1F91813FAD026009FA3E5 /* player.dta */ = {isa = PBXFileReference; lastKnownFileType = text; name = player.dta; path = ../../../bin/Resources/player.dta; sourceTree = SOURCE_ROOT; }; - 67B2071C1180FA8200E93654 /* vid_copy.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = vid_copy.s; path = ../../vid_copy.s; sourceTree = SOURCE_ROOT; }; - 67B83BCB14F57EAB00AAAE4E /* lapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lapi.c; path = ../../blua/lapi.c; sourceTree = SOURCE_ROOT; }; - 67B83BCC14F57EAB00AAAE4E /* lapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lapi.h; path = ../../blua/lapi.h; sourceTree = SOURCE_ROOT; }; - 67B83BCD14F57EAB00AAAE4E /* lauxlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lauxlib.c; path = ../../blua/lauxlib.c; sourceTree = SOURCE_ROOT; }; - 67B83BCE14F57EAB00AAAE4E /* lauxlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lauxlib.h; path = ../../blua/lauxlib.h; sourceTree = SOURCE_ROOT; }; - 67B83BCF14F57EAB00AAAE4E /* lbaselib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lbaselib.c; path = ../../blua/lbaselib.c; sourceTree = SOURCE_ROOT; }; - 67B83BD014F57EAB00AAAE4E /* lcode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lcode.c; path = ../../blua/lcode.c; sourceTree = SOURCE_ROOT; }; - 67B83BD114F57EAB00AAAE4E /* lcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lcode.h; path = ../../blua/lcode.h; sourceTree = SOURCE_ROOT; }; - 67B83BD214F57EAB00AAAE4E /* ldebug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ldebug.c; path = ../../blua/ldebug.c; sourceTree = SOURCE_ROOT; }; - 67B83BD314F57EAB00AAAE4E /* ldebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ldebug.h; path = ../../blua/ldebug.h; sourceTree = SOURCE_ROOT; }; - 67B83BD414F57EAB00AAAE4E /* ldo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ldo.c; path = ../../blua/ldo.c; sourceTree = SOURCE_ROOT; }; - 67B83BD514F57EAB00AAAE4E /* ldo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ldo.h; path = ../../blua/ldo.h; sourceTree = SOURCE_ROOT; }; - 67B83BD614F57EAB00AAAE4E /* ldump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ldump.c; path = ../../blua/ldump.c; sourceTree = SOURCE_ROOT; }; - 67B83BD714F57EAB00AAAE4E /* lfunc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lfunc.c; path = ../../blua/lfunc.c; sourceTree = SOURCE_ROOT; }; - 67B83BD814F57EAB00AAAE4E /* lfunc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lfunc.h; path = ../../blua/lfunc.h; sourceTree = SOURCE_ROOT; }; - 67B83BD914F57EAB00AAAE4E /* lgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lgc.c; path = ../../blua/lgc.c; sourceTree = SOURCE_ROOT; }; - 67B83BDA14F57EAB00AAAE4E /* lgc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lgc.h; path = ../../blua/lgc.h; sourceTree = SOURCE_ROOT; }; - 67B83BDB14F57EAB00AAAE4E /* linit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = linit.c; path = ../../blua/linit.c; sourceTree = SOURCE_ROOT; }; - 67B83BDC14F57EAB00AAAE4E /* llex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = llex.c; path = ../../blua/llex.c; sourceTree = SOURCE_ROOT; }; - 67B83BDD14F57EAB00AAAE4E /* llex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = llex.h; path = ../../blua/llex.h; sourceTree = SOURCE_ROOT; }; - 67B83BDE14F57EAB00AAAE4E /* llimits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = llimits.h; path = ../../blua/llimits.h; sourceTree = SOURCE_ROOT; }; - 67B83BDF14F57EAB00AAAE4E /* lmem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lmem.c; path = ../../blua/lmem.c; sourceTree = SOURCE_ROOT; }; - 67B83BE014F57EAB00AAAE4E /* lmem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lmem.h; path = ../../blua/lmem.h; sourceTree = SOURCE_ROOT; }; - 67B83BE114F57EAB00AAAE4E /* lobject.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lobject.c; path = ../../blua/lobject.c; sourceTree = SOURCE_ROOT; }; - 67B83BE214F57EAB00AAAE4E /* lobject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lobject.h; path = ../../blua/lobject.h; sourceTree = SOURCE_ROOT; }; - 67B83BE314F57EAB00AAAE4E /* lopcodes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lopcodes.c; path = ../../blua/lopcodes.c; sourceTree = SOURCE_ROOT; }; - 67B83BE414F57EAB00AAAE4E /* lopcodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lopcodes.h; path = ../../blua/lopcodes.h; sourceTree = SOURCE_ROOT; }; - 67B83BE514F57EAB00AAAE4E /* lparser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lparser.c; path = ../../blua/lparser.c; sourceTree = SOURCE_ROOT; }; - 67B83BE614F57EAB00AAAE4E /* lparser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lparser.h; path = ../../blua/lparser.h; sourceTree = SOURCE_ROOT; }; - 67B83BE714F57EAB00AAAE4E /* lstate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lstate.c; path = ../../blua/lstate.c; sourceTree = SOURCE_ROOT; }; - 67B83BE814F57EAB00AAAE4E /* lstate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lstate.h; path = ../../blua/lstate.h; sourceTree = SOURCE_ROOT; }; - 67B83BE914F57EAB00AAAE4E /* lstring.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lstring.c; path = ../../blua/lstring.c; sourceTree = SOURCE_ROOT; }; - 67B83BEA14F57EAB00AAAE4E /* lstring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lstring.h; path = ../../blua/lstring.h; sourceTree = SOURCE_ROOT; }; - 67B83BEB14F57EAB00AAAE4E /* lstrlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lstrlib.c; path = ../../blua/lstrlib.c; sourceTree = SOURCE_ROOT; }; - 67B83BEC14F57EAB00AAAE4E /* ltable.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ltable.c; path = ../../blua/ltable.c; sourceTree = SOURCE_ROOT; }; - 67B83BED14F57EAB00AAAE4E /* ltable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ltable.h; path = ../../blua/ltable.h; sourceTree = SOURCE_ROOT; }; - 67B83BEE14F57EAB00AAAE4E /* ltablib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ltablib.c; path = ../../blua/ltablib.c; sourceTree = SOURCE_ROOT; }; - 67B83BEF14F57EAB00AAAE4E /* ltm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ltm.c; path = ../../blua/ltm.c; sourceTree = SOURCE_ROOT; }; - 67B83BF014F57EAB00AAAE4E /* ltm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ltm.h; path = ../../blua/ltm.h; sourceTree = SOURCE_ROOT; }; - 67B83BF114F57EAB00AAAE4E /* lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua.h; path = ../../blua/lua.h; sourceTree = SOURCE_ROOT; }; - 67B83BF214F57EAB00AAAE4E /* luaconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = luaconf.h; path = ../../blua/luaconf.h; sourceTree = SOURCE_ROOT; }; - 67B83BF314F57EAB00AAAE4E /* lualib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lualib.h; path = ../../blua/lualib.h; sourceTree = SOURCE_ROOT; }; - 67B83BF414F57EAB00AAAE4E /* lundump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lundump.c; path = ../../blua/lundump.c; sourceTree = SOURCE_ROOT; }; - 67B83BF514F57EAB00AAAE4E /* lundump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lundump.h; path = ../../blua/lundump.h; sourceTree = SOURCE_ROOT; }; - 67B83BF614F57EAB00AAAE4E /* lvm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lvm.c; path = ../../blua/lvm.c; sourceTree = SOURCE_ROOT; }; - 67B83BF714F57EAB00AAAE4E /* lvm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lvm.h; path = ../../blua/lvm.h; sourceTree = SOURCE_ROOT; }; - 67B83BF814F57EAB00AAAE4E /* lzio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lzio.c; path = ../../blua/lzio.c; sourceTree = SOURCE_ROOT; }; - 67B83BF914F57EAB00AAAE4E /* lzio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lzio.h; path = ../../blua/lzio.h; sourceTree = SOURCE_ROOT; }; - 67B83C1214F57ECA00AAAE4E /* b_bot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = b_bot.c; path = ../../b_bot.c; sourceTree = SOURCE_ROOT; }; - 67B83C1314F57ECA00AAAE4E /* b_bot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = b_bot.h; path = ../../b_bot.h; sourceTree = SOURCE_ROOT; }; - 67B83C1514F57EE600AAAE4E /* lua_baselib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_baselib.c; path = ../../lua_baselib.c; sourceTree = SOURCE_ROOT; }; - 67B83C1614F57EE600AAAE4E /* lua_consolelib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_consolelib.c; path = ../../lua_consolelib.c; sourceTree = SOURCE_ROOT; }; - 67B83C1714F57EE600AAAE4E /* lua_hook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_hook.h; path = ../../lua_hook.h; sourceTree = SOURCE_ROOT; }; - 67B83C1814F57EE600AAAE4E /* lua_hooklib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_hooklib.c; path = ../../lua_hooklib.c; sourceTree = SOURCE_ROOT; }; - 67B83C1914F57EE600AAAE4E /* lua_infolib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_infolib.c; path = ../../lua_infolib.c; sourceTree = SOURCE_ROOT; }; - 67B83C1A14F57EE600AAAE4E /* lua_libs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_libs.h; path = ../../lua_libs.h; sourceTree = SOURCE_ROOT; }; - 67B83C1B14F57EE600AAAE4E /* lua_maplib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_maplib.c; path = ../../lua_maplib.c; sourceTree = SOURCE_ROOT; }; - 67B83C1C14F57EE600AAAE4E /* lua_mathlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_mathlib.c; path = ../../lua_mathlib.c; sourceTree = SOURCE_ROOT; }; - 67B83C1D14F57EE600AAAE4E /* lua_mobjlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_mobjlib.c; path = ../../lua_mobjlib.c; sourceTree = SOURCE_ROOT; }; - 67B83C1E14F57EE600AAAE4E /* lua_playerlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_playerlib.c; path = ../../lua_playerlib.c; sourceTree = SOURCE_ROOT; }; - 67B83C1F14F57EE600AAAE4E /* lua_script.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_script.c; path = ../../lua_script.c; sourceTree = SOURCE_ROOT; }; - 67B83C2014F57EE600AAAE4E /* lua_script.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_script.h; path = ../../lua_script.h; sourceTree = SOURCE_ROOT; }; - 67B83C2114F57EE600AAAE4E /* lua_thinkerlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_thinkerlib.c; path = ../../lua_thinkerlib.c; sourceTree = SOURCE_ROOT; }; - 67B83C2C14F57F1500AAAE4E /* fastcmp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fastcmp.h; path = ../../fastcmp.h; sourceTree = SOURCE_ROOT; }; - 67B83C2D14F57F1500AAAE4E /* i_addrinfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = i_addrinfo.c; path = ../../i_addrinfo.c; sourceTree = SOURCE_ROOT; }; - 67B83C2E14F57F1500AAAE4E /* i_addrinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = i_addrinfo.h; path = ../../i_addrinfo.h; sourceTree = SOURCE_ROOT; }; - 67B83C2F14F57F1500AAAE4E /* m_cond.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = m_cond.c; path = ../../m_cond.c; sourceTree = SOURCE_ROOT; }; - 67B83C3014F57F1500AAAE4E /* m_cond.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m_cond.h; path = ../../m_cond.h; sourceTree = SOURCE_ROOT; }; - 67B83C3114F57F1500AAAE4E /* m_dllist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m_dllist.h; path = ../../m_dllist.h; sourceTree = SOURCE_ROOT; }; - 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; }; - 8D1107320486CEB800E47090 /* Srb2mac.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Srb2mac.app; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 8D11072E0486CEB800E47090 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 002F39FA09D0881F00EBEB88 /* SDL.framework in Frameworks */, - 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, - 1E66921C0B690C5B00B7313A /* SDL_mixer.framework in Frameworks */, - 1E32C4290B6E6D5D0029E058 /* libpng.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 080E96DDFE201D6D7F000001 /* Classes */ = { - isa = PBXGroup; - children = ( - 1E44AE890B67CC4E00BAD059 /* A_Asm */, - 67B83BCA14F57DD400AAAE4E /* B_Bot */, - 67B83BC914F57D7F00AAAE4E /* BLUA */, - 1E44AE8C0B67CC6500BAD059 /* D_Doom */, - 1E44AEBB0B67CC9800BAD059 /* F_Frame */, - 1E44AEC20B67CCB500BAD059 /* G_Game */, - 1E44AECD0B67CCD200BAD059 /* H_Hud */, - 1E44AE5C0B67CC0F00BAD059 /* Hw_Hardware */, - 1E44AED20B67CCF600BAD059 /* I_Interface */, - 67B83BC814F57D6E00AAAE4E /* LUA */, - 1E44AEF70B67CDA900BAD059 /* M_Misc */, - 1E44AF160B67CDFB00BAD059 /* P_Play */, - 1E44AF540B67CE8C00BAD059 /* R_Render */, - 1E44AF830B67CEC900BAD059 /* S_Sound */, - 1E44AF170B67CE1000BAD059 /* W_Wad */, - ); - name = Classes; - sourceTree = "<group>"; - }; - 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { - isa = PBXGroup; - children = ( - 1E32C4140B6E6D5D0029E058 /* libpng.framework */, - 1E66921B0B690C5B00B7313A /* SDL_mixer.framework */, - 002F39F909D0881F00EBEB88 /* SDL.framework */, - 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, - ); - name = "Linked Frameworks"; - sourceTree = "<group>"; - }; - 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { - isa = PBXGroup; - children = ( - 29B97324FDCFA39411CA2CEA /* AppKit.framework */, - 29B97325FDCFA39411CA2CEA /* Foundation.framework */, - ); - name = "Other Frameworks"; - sourceTree = "<group>"; - }; - 19C28FACFE9D520D11CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 8D1107320486CEB800E47090 /* Srb2mac.app */, - ); - name = Products; - sourceTree = "<group>"; - }; - 1E44AE5C0B67CC0F00BAD059 /* Hw_Hardware */ = { - isa = PBXGroup; - children = ( - 1E44AE600B67CC2B00BAD059 /* hw3dsdrv.h */, - 1E44AE610B67CC2B00BAD059 /* hw_bsp.c */, - 1E44AE620B67CC2B00BAD059 /* hw_defs.h */, - 1E44AE630B67CC2B00BAD059 /* hw3sound.c */, - 1E44AE640B67CC2B00BAD059 /* hw_cache.c */, - 1E44AE650B67CC2B00BAD059 /* hw_dll.h */, - 1E44AE660B67CC2B00BAD059 /* hw_drv.h */, - 1E44AE670B67CC2B00BAD059 /* hw_glide.h */, - 1E44AE680B67CC2B00BAD059 /* hw_light.c */, - 1E44AE690B67CC2B00BAD059 /* hw_light.h */, - 1E44AE6A0B67CC2B00BAD059 /* hw3sound.h */, - 1E44AE6B0B67CC2B00BAD059 /* hw_data.h */, - 1E44AE6C0B67CC2B00BAD059 /* hw_draw.c */, - 1E44AE6D0B67CC2B00BAD059 /* hw_glob.h */, - 1E44AE6E0B67CC2B00BAD059 /* hw_main.c */, - 1E44AE6F0B67CC2B00BAD059 /* hw_main.h */, - 1E44AE700B67CC2B00BAD059 /* hw_md2.c */, - 1E44AE710B67CC2B00BAD059 /* hw_md2.h */, - 1E44AE720B67CC2B00BAD059 /* hw_trick.c */, - 1E44AE730B67CC2B00BAD059 /* hws_data.h */, - ); - name = Hw_Hardware; - sourceTree = "<group>"; - }; - 1E44AE890B67CC4E00BAD059 /* A_Asm */ = { - isa = PBXGroup; - children = ( - 67B2071C1180FA8200E93654 /* vid_copy.s */, - 1E44AE8A0B67CC6000BAD059 /* asm_defs.inc */, - 1E44AF9D0B67CF3D00BAD059 /* tmap.nas */, - 1E44AF9F0B67CF4900BAD059 /* tmap_mmx.nas */, - 1E44AFA00B67CF4900BAD059 /* tmap_vc.nas */, - ); - name = A_Asm; - sourceTree = "<group>"; - }; - 1E44AE8C0B67CC6500BAD059 /* D_Doom */ = { - isa = PBXGroup; - children = ( - 1E44AEEB0B67CD4400BAD059 /* comptime.c */, - 1E44AE8D0B67CC8400BAD059 /* d_clisrv.c */, - 1E44AE8E0B67CC8400BAD059 /* d_clisrv.h */, - 1E44AE8F0B67CC8400BAD059 /* d_event.h */, - 1E44AE900B67CC8400BAD059 /* d_main.c */, - 1E44AE910B67CC8500BAD059 /* d_net.c */, - 1E44AE920B67CC8500BAD059 /* d_net.h */, - 1E44AE930B67CC8500BAD059 /* d_netcmd.h */, - 1E44AE940B67CC8500BAD059 /* d_netfil.c */, - 1E44AE950B67CC8500BAD059 /* d_player.h */, - 1E44AE960B67CC8500BAD059 /* d_think.h */, - 1E44AE980B67CC8500BAD059 /* d_netcmd.c */, - 1E44AE990B67CC8500BAD059 /* d_ticcmd.h */, - 1E44AE9A0B67CC8500BAD059 /* d_main.h */, - 1E44AE9B0B67CC8500BAD059 /* d_netfil.h */, - 1E44AE9C0B67CC8500BAD059 /* dehacked.c */, - 1E44AE9D0B67CC8500BAD059 /* dehacked.h */, - 1E44AE9E0B67CC8500BAD059 /* doomdata.h */, - 1E44AE9F0B67CC8500BAD059 /* doomdef.h */, - 1E44AEA00B67CC8500BAD059 /* doomstat.h */, - 1E44AEA10B67CC8500BAD059 /* doomtype.h */, - 1E44AFAF0B67CF7A00BAD059 /* z_zone.c */, - 1E44AFB00B67CF7A00BAD059 /* z_zone.h */, - ); - name = D_Doom; - sourceTree = "<group>"; - }; - 1E44AEBB0B67CC9800BAD059 /* F_Frame */ = { - isa = PBXGroup; - children = ( - 1E44AEBC0B67CCA900BAD059 /* f_wipe.c */, - 1E44AEBD0B67CCA900BAD059 /* f_finale.c */, - 1E44AEBE0B67CCA900BAD059 /* f_finale.h */, - 1E44AFAB0B67CF6F00BAD059 /* y_inter.c */, - 1E44AFAC0B67CF6F00BAD059 /* y_inter.h */, - ); - name = F_Frame; - sourceTree = "<group>"; - }; - 1E44AEC20B67CCB500BAD059 /* G_Game */ = { - isa = PBXGroup; - children = ( - 1E44AEC30B67CCC600BAD059 /* g_game.c */, - 1E44AEC40B67CCC600BAD059 /* g_game.h */, - 1E44AEC50B67CCC600BAD059 /* g_input.h */, - 1E44AEC60B67CCC600BAD059 /* g_state.h */, - 1E44AEC70B67CCC600BAD059 /* g_input.c */, - ); - name = G_Game; - sourceTree = "<group>"; - }; - 1E44AECD0B67CCD200BAD059 /* H_Hud */ = { - isa = PBXGroup; - children = ( - 1E44AEE10B67CD2B00BAD059 /* am_map.c */, - 1E44AEE20B67CD2B00BAD059 /* am_map.h */, - 1E44AEE70B67CD3F00BAD059 /* command.c */, - 1E44AEE80B67CD3F00BAD059 /* command.h */, - 1E44AEED0B67CD5400BAD059 /* console.c */, - 1E44AEEE0B67CD5400BAD059 /* console.h */, - 1E44AECE0B67CCEE00BAD059 /* hu_stuff.c */, - 1E44AECF0B67CCEE00BAD059 /* hu_stuff.h */, - 1E44AF000B67CDE900BAD059 /* m_menu.c */, - 1E44AF010B67CDE900BAD059 /* m_menu.h */, - 1E44AF910B67CEFF00BAD059 /* st_stuff.c */, - 1E44AF920B67CEFF00BAD059 /* st_stuff.h */, - ); - name = H_Hud; - sourceTree = "<group>"; - }; - 1E44AED20B67CCF600BAD059 /* I_Interface */ = { - isa = PBXGroup; - children = ( - 67259E0218D268F600F02971 /* i_ttf.c */, - 67259E0318D268F600F02971 /* i_ttf.h */, - 67259E0418D268F600F02971 /* mixer_sound.c */, - 67259E0518D268F600F02971 /* sdl_sound.c */, - 1E44AFB30B67CF8500BAD059 /* SDL */, - 67B83C2D14F57F1500AAAE4E /* i_addrinfo.c */, - 67B83C2E14F57F1500AAAE4E /* i_addrinfo.h */, - 1E44AEE50B67CD3200BAD059 /* byteptr.h */, - 1E44AEF10B67CD7F00BAD059 /* filesrch.c */, - 1E44AEF20B67CD7F00BAD059 /* filesrch.h */, - 1E44AED30B67CD1200BAD059 /* i_net.h */, - 1E44AED40B67CD1200BAD059 /* i_sound.h */, - 1E44AED50B67CD1200BAD059 /* i_tcp.c */, - 1E44AED60B67CD1200BAD059 /* i_tcp.h */, - 1E44AED70B67CD1200BAD059 /* i_system.h */, - 1E44AED80B67CD1200BAD059 /* i_video.h */, - 1E44AED90B67CD1300BAD059 /* i_joy.h */, - 1E44AEF50B67CD9F00BAD059 /* keys.h */, - 1E44AF200B67CE4100BAD059 /* mserv.c */, - 1E44AF210B67CE4100BAD059 /* mserv.h */, - ); - name = I_Interface; - sourceTree = "<group>"; - }; - 1E44AEF70B67CDA900BAD059 /* M_Misc */ = { - isa = PBXGroup; - children = ( - 67259DFF18D268AE00F02971 /* m_anigif.c */, - 67259E0018D268AE00F02971 /* m_anigif.h */, - 1E44AEF80B67CDE900BAD059 /* m_argv.c */, - 1E44AEFA0B67CDE900BAD059 /* m_argv.h */, - 1E44AEFC0B67CDE900BAD059 /* m_bbox.c */, - 1E44AEF90B67CDE900BAD059 /* m_bbox.h */, - 1E44AEFB0B67CDE900BAD059 /* m_cheat.c */, - 1E44AEFD0B67CDE900BAD059 /* m_cheat.h */, - 67B83C2F14F57F1500AAAE4E /* m_cond.c */, - 67B83C3014F57F1500AAAE4E /* m_cond.h */, - 67B83C3114F57F1500AAAE4E /* m_dllist.h */, - 1E44AEFE0B67CDE900BAD059 /* m_fixed.c */, - 1E44AEFF0B67CDE900BAD059 /* m_fixed.h */, - 1E44AF020B67CDE900BAD059 /* m_misc.c */, - 1E44AF030B67CDE900BAD059 /* m_misc.h */, - 1E44AF020B67CDE900BAD059 /* apng.c */, - 1E44AF030B67CDE900BAD059 /* apng.h */, - 676BB51C0E0DE06100C95963 /* m_queue.c */, - 676BB51D0E0DE06100C95963 /* m_queue.h */, - 1E44AF040B67CDE900BAD059 /* m_random.c */, - 1E44AF050B67CDE900BAD059 /* m_random.h */, - 1E44AF060B67CDE900BAD059 /* m_swap.h */, - 1E44AF950B67CF1300BAD059 /* string.c */, - ); - name = M_Misc; - sourceTree = "<group>"; - }; - 1E44AF160B67CDFB00BAD059 /* P_Play */ = { - isa = PBXGroup; - children = ( - 1E44AF180B67CE2A00BAD059 /* info.c */, - 1E44AF190B67CE2A00BAD059 /* info.h */, - 1E44AF3B0B67CE5F00BAD059 /* p_ceilng.c */, - 1E44AF240B67CE5F00BAD059 /* p_enemy.c */, - 1E44AF250B67CE5F00BAD059 /* p_inter.c */, - 1E44AF260B67CE5F00BAD059 /* p_fab.c */, - 1E44AF270B67CE5F00BAD059 /* p_lights.c */, - 1E44AF280B67CE5F00BAD059 /* p_map.c */, - 1E44AF290B67CE5F00BAD059 /* p_maputl.c */, - 1E44AF2A0B67CE5F00BAD059 /* p_maputl.h */, - 1E44AF2B0B67CE5F00BAD059 /* p_mobj.c */, - 1E44AF2C0B67CE5F00BAD059 /* p_mobj.h */, - 1E44AF2D0B67CE5F00BAD059 /* p_floor.c */, - 1E44AF2E0B67CE5F00BAD059 /* p_local.h */, - 676BB51E0E0DE06100C95963 /* p_polyobj.c */, - 676BB51F0E0DE06100C95963 /* p_polyobj.h */, - 1E44AF2F0B67CE5F00BAD059 /* p_pspr.h */, - 1E44AF300B67CE5F00BAD059 /* p_saveg.c */, - 1E44AF310B67CE5F00BAD059 /* p_saveg.h */, - 1E44AF320B67CE5F00BAD059 /* p_setup.c */, - 1E44AF330B67CE5F00BAD059 /* p_setup.h */, - 1E44AF340B67CE5F00BAD059 /* p_sight.c */, - 1E44AF350B67CE5F00BAD059 /* p_spec.c */, - 1E44AF360B67CE5F00BAD059 /* p_spec.h */, - 1E44AF370B67CE5F00BAD059 /* p_telept.c */, - 1E44AF380B67CE5F00BAD059 /* p_tick.c */, - 1E44AF390B67CE5F00BAD059 /* p_tick.h */, - 1E44AF3A0B67CE5F00BAD059 /* p_user.c */, - 1E44AF990B67CF2E00BAD059 /* tables.c */, - 1E44AF9A0B67CF2E00BAD059 /* tables.h */, - ); - name = P_Play; - sourceTree = "<group>"; - }; - 1E44AF170B67CE1000BAD059 /* W_Wad */ = { - isa = PBXGroup; - children = ( - 1E44B2240B67EADE00BAD059 /* lzf.c */, - 1E44B2250B67EADE00BAD059 /* lzf.h */, - 1E44AF1C0B67CE3600BAD059 /* md5.c */, - 1E44AF1D0B67CE3600BAD059 /* md5.h */, - 1E44AFA70B67CF6400BAD059 /* w_wad.c */, - 1E44AFA80B67CF6400BAD059 /* w_wad.h */, - ); - name = W_Wad; - sourceTree = "<group>"; - }; - 1E44AF540B67CE8C00BAD059 /* R_Render */ = { - isa = PBXGroup; - children = ( - 1E44AF550B67CEC100BAD059 /* r_bsp.c */, - 1E44AF560B67CEC100BAD059 /* r_bsp.h */, - 1E44AF570B67CEC100BAD059 /* r_defs.h */, - 1E44AF580B67CEC100BAD059 /* r_data.c */, - 1E44AF590B67CEC100BAD059 /* r_draw.c */, - 1E44AF5A0B67CEC100BAD059 /* r_draw16.c */, - 1E44AF5B0B67CEC100BAD059 /* r_draw8.c */, - 1E44AF5C0B67CEC100BAD059 /* r_main.c */, - 1E44AF5D0B67CEC100BAD059 /* r_main.h */, - 1E44AF5E0B67CEC100BAD059 /* r_data.h */, - 1E44AF5F0B67CEC100BAD059 /* r_draw.h */, - 1E44AF600B67CEC100BAD059 /* r_local.h */, - 1E44AF610B67CEC100BAD059 /* r_plane.c */, - 1E44AF620B67CEC100BAD059 /* r_plane.h */, - 1E44AF630B67CEC100BAD059 /* r_segs.c */, - 1E44AF640B67CEC100BAD059 /* r_segs.h */, - 1E44AF650B67CEC200BAD059 /* r_sky.c */, - 1E44AF660B67CEC200BAD059 /* r_sky.h */, - 1E44AF670B67CEC200BAD059 /* r_splats.c */, - 1E44AF680B67CEC200BAD059 /* r_splats.h */, - 1E44AF690B67CEC200BAD059 /* r_state.h */, - 1E44AF6A0B67CEC200BAD059 /* r_things.c */, - 1E44AF6B0B67CEC200BAD059 /* r_things.h */, - 1E44AF890B67CEE900BAD059 /* screen.c */, - 1E44AF8A0B67CEE900BAD059 /* screen.h */, - 1E44AFA30B67CF5D00BAD059 /* v_video.c */, - 1E44AFA40B67CF5D00BAD059 /* v_video.h */, - ); - name = R_Render; - sourceTree = "<group>"; - }; - 1E44AF830B67CEC900BAD059 /* S_Sound */ = { - isa = PBXGroup; - children = ( - 1E44AF850B67CEE000BAD059 /* s_sound.c */, - 1E44AF860B67CEE000BAD059 /* s_sound.h */, - 1E44AF8D0B67CEF000BAD059 /* sounds.c */, - 1E44AF8E0B67CEF000BAD059 /* sounds.h */, - ); - name = S_Sound; - sourceTree = "<group>"; - }; - 1E44AFB30B67CF8500BAD059 /* SDL */ = { - isa = PBXGroup; - children = ( - 1E44AFE50B67D04900BAD059 /* macosx */, - 1E44AFD40B67D03100BAD059 /* filter */, - 1E44AFB40B67CFDC00BAD059 /* dosstr.c */, - 1E44AFB50B67CFDC00BAD059 /* endtxt.c */, - 1E44AFB60B67CFDC00BAD059 /* endtxt.h */, - 1E44AFB70B67CFDC00BAD059 /* hwsym_sdl.c */, - 1E44AFB80B67CFDC00BAD059 /* hwsym_sdl.h */, - 1E44AFB90B67CFDC00BAD059 /* i_cdmus.c */, - 1E44AFBA0B67CFDC00BAD059 /* i_main.c */, - 1E44AFBB0B67CFDC00BAD059 /* i_net.c */, - 1E44AFBD0B67CFDC00BAD059 /* i_system.c */, - 1E44AFBE0B67CFDC00BAD059 /* i_video.c */, - 1E44AFBF0B67CFDC00BAD059 /* IMG_xpm.c */, - 1E44AFEC0B67D0AB00BAD059 /* r_opengl.c */, - 1E44AFC00B67CFDC00BAD059 /* ogl_sdl.c */, - 1E44AFC10B67CFDC00BAD059 /* ogl_sdl.h */, - 1E44AFC20B67CFDC00BAD059 /* SDL_icon.xpm */, - 1E44AFC30B67CFDC00BAD059 /* sdlmain.h */, - ); - name = SDL; - sourceTree = "<group>"; - }; - 1E44AFD40B67D03100BAD059 /* filter */ = { - isa = PBXGroup; - children = ( - 1E44AFD50B67D03100BAD059 /* filters.c */, - 1E44AFD60B67D03100BAD059 /* filters.h */, - 1E44AFD70B67D03100BAD059 /* hq2x.c */, - 1E44AFD80B67D03100BAD059 /* hq2x.h */, - 1E44AFD90B67D03100BAD059 /* interp.h */, - 1E44AFDA0B67D03100BAD059 /* lq2x.c */, - 1E44AFDB0B67D03100BAD059 /* lq2x.h */, - 1E44AFDC0B67D03100BAD059 /* main.c */, - ); - name = filter; - path = ../filter; - sourceTree = SOURCE_ROOT; - }; - 1E44AFE50B67D04900BAD059 /* macosx */ = { - isa = PBXGroup; - children = ( - 1E44AFE60B67D06200BAD059 /* mac_alert.h */, - 1E44AFE70B67D06200BAD059 /* Srb2mac.icns */, - 1E44AFE80B67D06200BAD059 /* mac_alert.c */, - 1E44B0560B67D81E00BAD059 /* SDL_macosx_main.h */, - 1E44B0570B67D81E00BAD059 /* SDL_macosx_main.m */, - ); - name = macosx; - sourceTree = "<group>"; - }; - 29B97314FDCFA39411CA2CEA /* Srb2mac */ = { - isa = PBXGroup; - children = ( - 080E96DDFE201D6D7F000001 /* Classes */, - 29B97315FDCFA39411CA2CEA /* Other Sources */, - 29B97317FDCFA39411CA2CEA /* Resources */, - 29B97323FDCFA39411CA2CEA /* Frameworks */, - 19C28FACFE9D520D11CA2CBB /* Products */, - ); - name = Srb2mac; - sourceTree = "<group>"; - }; - 29B97315FDCFA39411CA2CEA /* Other Sources */ = { - isa = PBXGroup; - children = ( - ); - name = "Other Sources"; - sourceTree = "<group>"; - }; - 29B97317FDCFA39411CA2CEA /* Resources */ = { - isa = PBXGroup; - children = ( - 67259E2B18D26D5700F02971 /* patch.dta */, - 67259E2C18D26D5700F02971 /* rings.dta */, - 67259E2D18D26D5700F02971 /* srb2.srb */, - 67A1F91813FAD026009FA3E5 /* player.dta */, - 6766C0AE11B057E50065F389 /* zones.dta */, - 1E44AE440B67CBE800BAD059 /* music.dta */, - 1E44AE4B0B67CBE800BAD059 /* srb2.wad */, - 8D1107310486CEB800E47090 /* Info.plist */, - 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, - ); - name = Resources; - sourceTree = "<group>"; - }; - 29B97323FDCFA39411CA2CEA /* Frameworks */ = { - isa = PBXGroup; - children = ( - 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, - 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, - ); - name = Frameworks; - sourceTree = "<group>"; - }; - 67B83BC814F57D6E00AAAE4E /* LUA */ = { - isa = PBXGroup; - children = ( - 67259DFA18D2687D00F02971 /* lua_hud.h */, - 67259DFB18D2687D00F02971 /* lua_hudlib.c */, - 67259DFC18D2687D00F02971 /* lua_skinlib.c */, - 67B83C2C14F57F1500AAAE4E /* fastcmp.h */, - 67B83C1514F57EE600AAAE4E /* lua_baselib.c */, - 67B83C1614F57EE600AAAE4E /* lua_consolelib.c */, - 67B83C1714F57EE600AAAE4E /* lua_hook.h */, - 67B83C1814F57EE600AAAE4E /* lua_hooklib.c */, - 67B83C1914F57EE600AAAE4E /* lua_infolib.c */, - 67B83C1A14F57EE600AAAE4E /* lua_libs.h */, - 67B83C1B14F57EE600AAAE4E /* lua_maplib.c */, - 67B83C1C14F57EE600AAAE4E /* lua_mathlib.c */, - 67B83C1D14F57EE600AAAE4E /* lua_mobjlib.c */, - 67B83C1E14F57EE600AAAE4E /* lua_playerlib.c */, - 67B83C1F14F57EE600AAAE4E /* lua_script.c */, - 67B83C2014F57EE600AAAE4E /* lua_script.h */, - 67B83C2114F57EE600AAAE4E /* lua_thinkerlib.c */, - ); - name = LUA; - sourceTree = "<group>"; - }; - 67B83BC914F57D7F00AAAE4E /* BLUA */ = { - isa = PBXGroup; - children = ( - 67B83BCB14F57EAB00AAAE4E /* lapi.c */, - 67B83BCC14F57EAB00AAAE4E /* lapi.h */, - 67B83BCD14F57EAB00AAAE4E /* lauxlib.c */, - 67B83BCE14F57EAB00AAAE4E /* lauxlib.h */, - 67B83BCF14F57EAB00AAAE4E /* lbaselib.c */, - 67B83BD014F57EAB00AAAE4E /* lcode.c */, - 67B83BD114F57EAB00AAAE4E /* lcode.h */, - 67B83BD214F57EAB00AAAE4E /* ldebug.c */, - 67B83BD314F57EAB00AAAE4E /* ldebug.h */, - 67B83BD414F57EAB00AAAE4E /* ldo.c */, - 67B83BD514F57EAB00AAAE4E /* ldo.h */, - 67B83BD614F57EAB00AAAE4E /* ldump.c */, - 67B83BD714F57EAB00AAAE4E /* lfunc.c */, - 67B83BD814F57EAB00AAAE4E /* lfunc.h */, - 67B83BD914F57EAB00AAAE4E /* lgc.c */, - 67B83BDA14F57EAB00AAAE4E /* lgc.h */, - 67B83BDB14F57EAB00AAAE4E /* linit.c */, - 67B83BDC14F57EAB00AAAE4E /* llex.c */, - 67B83BDD14F57EAB00AAAE4E /* llex.h */, - 67B83BDE14F57EAB00AAAE4E /* llimits.h */, - 67B83BDF14F57EAB00AAAE4E /* lmem.c */, - 67B83BE014F57EAB00AAAE4E /* lmem.h */, - 67B83BE114F57EAB00AAAE4E /* lobject.c */, - 67B83BE214F57EAB00AAAE4E /* lobject.h */, - 67B83BE314F57EAB00AAAE4E /* lopcodes.c */, - 67B83BE414F57EAB00AAAE4E /* lopcodes.h */, - 67B83BE514F57EAB00AAAE4E /* lparser.c */, - 67B83BE614F57EAB00AAAE4E /* lparser.h */, - 67B83BE714F57EAB00AAAE4E /* lstate.c */, - 67B83BE814F57EAB00AAAE4E /* lstate.h */, - 67B83BE914F57EAB00AAAE4E /* lstring.c */, - 67B83BEA14F57EAB00AAAE4E /* lstring.h */, - 67B83BEB14F57EAB00AAAE4E /* lstrlib.c */, - 67B83BEC14F57EAB00AAAE4E /* ltable.c */, - 67B83BED14F57EAB00AAAE4E /* ltable.h */, - 67B83BEE14F57EAB00AAAE4E /* ltablib.c */, - 67B83BEF14F57EAB00AAAE4E /* ltm.c */, - 67B83BF014F57EAB00AAAE4E /* ltm.h */, - 67B83BF114F57EAB00AAAE4E /* lua.h */, - 67B83BF214F57EAB00AAAE4E /* luaconf.h */, - 67B83BF314F57EAB00AAAE4E /* lualib.h */, - 67B83BF414F57EAB00AAAE4E /* lundump.c */, - 67B83BF514F57EAB00AAAE4E /* lundump.h */, - 67B83BF614F57EAB00AAAE4E /* lvm.c */, - 67B83BF714F57EAB00AAAE4E /* lvm.h */, - 67B83BF814F57EAB00AAAE4E /* lzio.c */, - 67B83BF914F57EAB00AAAE4E /* lzio.h */, - ); - name = BLUA; - sourceTree = "<group>"; - }; - 67B83BCA14F57DD400AAAE4E /* B_Bot */ = { - isa = PBXGroup; - children = ( - 67B83C1214F57ECA00AAAE4E /* b_bot.c */, - 67B83C1314F57ECA00AAAE4E /* b_bot.h */, - ); - name = B_Bot; - sourceTree = "<group>"; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 8D1107260486CEB800E47090 /* Srb2mac */ = { - isa = PBXNativeTarget; - buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Srb2mac" */; - buildPhases = ( - 8D1107290486CEB800E47090 /* Resources */, - 677E4CB30E1765500034519D /* Get SCM Info */, - 8D11072C0486CEB800E47090 /* Sources */, - 8D11072E0486CEB800E47090 /* Frameworks */, - 002F39FD09D0883400EBEB88 /* Copy Frameworks into .app bundle */, - 679B708A102B872300AA9E4C /* Make DMG */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Srb2mac; - productInstallPath = "$(HOME)/Applications"; - productName = Srb2mac; - productReference = 8D1107320486CEB800E47090 /* Srb2mac.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 29B97313FDCFA39411CA2CEA /* Project object */ = { - isa = PBXProject; - buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Srb2mac" */; - compatibilityVersion = "Xcode 2.4"; - hasScannedForEncodings = 1; - mainGroup = 29B97314FDCFA39411CA2CEA /* Srb2mac */; - projectDirPath = ""; - projectRoot = ../../..; - targets = ( - 8D1107260486CEB800E47090 /* Srb2mac */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 8D1107290486CEB800E47090 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */, - 1E44AFEA0B67D06200BAD059 /* Srb2mac.icns in Resources */, - 67259E2E18D26D5700F02971 /* patch.dta in Resources */, - 67259E2F18D26D5700F02971 /* rings.dta in Resources */, - 67259E3018D26D5700F02971 /* srb2.srb in Resources */, - 67259E3218D26DD200F02971 /* music.dta in Resources */, - 67259E3318D26DD300F02971 /* player.dta in Resources */, - 67259E3518D26DD500F02971 /* zones.dta in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 677E4CB30E1765500034519D /* Get SCM Info */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - comments = "update the time and date stamps in src/comptime.c"; - files = ( - ); - inputPaths = ( - ); - name = "Get SCM Info"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "PATH=\"/usr/local/bin:$PATH\" $SRCROOT/../../../comptime.sh $SRCROOT/../../"; - }; - 679B708A102B872300AA9E4C /* Make DMG */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - comments = "make DMG file for Release builds"; - files = ( - ); - inputPaths = ( - $BUILT_PRODUCTS_DIR/$WRAPPER_NAME, - ); - name = "Make DMG"; - outputPaths = ( - $BUILT_PRODUCTS_DIR/$TARGET_NAME.nodata.dmg, - $BUILT_PRODUCTS_DIR/$TARGET_NAME.dmg, - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "set -ex\n\n[ \"$ACTION\" = build ] || exit 0\n[ \"$CURRENT_VARIANT\" = \"normal\" ] || exit 0\n[ \"$BUILD_STYLE\" = \"Release\" ] || exit 0\n\ndir=\"$TEMP_FILES_DIR/$TARGET_NAME.disk\"\ndmg=\"$BUILT_PRODUCTS_DIR/$TARGET_NAME.dmg\"\ndmg_nodata=\"$BUILT_PRODUCTS_DIR/$TARGET_NAME.nodata.dmg\"\n\nrm -rf -- \"$dir\"\nmkdir \"$dir\"\ncp -R \"$BUILT_PRODUCTS_DIR/$WRAPPER_NAME\" \"$dir\"\nrm -f -- \"$dmg\"\nhdiutil create -ov -fs HFS+ -srcfolder \"$dir\" -volname \"$TARGET_NAME\" \"$dmg\"\nhdiutil internet-enable -yes \"$dmg\"\ncd \"$dir/$WRAPPER_NAME/Contents/Resources\"\nrm -f -- *.wad\nrm -f -- *.dta\nrm -f -- *.plr\nrm -f -- *.wpn\nrm -f -- *.srb2\ncd \"$OLDPWD\"\nrm -f -- \"$dmg_nodata\"\nhdiutil create -ov -fs HFS+ -srcfolder \"$dir\" -volname \"$TARGET_NAME Lite\" \"$dmg_nodata\"\nhdiutil internet-enable -yes \"$dmg_nodata\"\nrm -rf -- \"$dir\""; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 8D11072C0486CEB800E47090 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 1E44AE750B67CC2B00BAD059 /* hw_bsp.c in Sources */, - 1E44AE770B67CC2B00BAD059 /* hw3sound.c in Sources */, - 1E44AE780B67CC2B00BAD059 /* hw_cache.c in Sources */, - 1E44AE7C0B67CC2B00BAD059 /* hw_light.c in Sources */, - 1E44AE800B67CC2B00BAD059 /* hw_draw.c in Sources */, - 1E44AE820B67CC2B00BAD059 /* hw_main.c in Sources */, - 1E44AE840B67CC2B00BAD059 /* hw_md2.c in Sources */, - 1E44AE860B67CC2B00BAD059 /* hw_trick.c in Sources */, - 1E44AEA40B67CC8500BAD059 /* d_clisrv.c in Sources */, - 1E44AEA70B67CC8500BAD059 /* d_main.c in Sources */, - 1E44AEA80B67CC8500BAD059 /* d_net.c in Sources */, - 1E44AEAB0B67CC8500BAD059 /* d_netfil.c in Sources */, - 1E44AEAF0B67CC8500BAD059 /* d_netcmd.c in Sources */, - 1E44AEB30B67CC8500BAD059 /* dehacked.c in Sources */, - 1E44AEBF0B67CCA900BAD059 /* f_wipe.c in Sources */, - 1E44AEC00B67CCA900BAD059 /* f_finale.c in Sources */, - 1E44AEC80B67CCC600BAD059 /* g_game.c in Sources */, - 1E44AECC0B67CCC600BAD059 /* g_input.c in Sources */, - 1E44AED00B67CCEE00BAD059 /* hu_stuff.c in Sources */, - 1E44AEDC0B67CD1300BAD059 /* i_tcp.c in Sources */, - 1E44AEE30B67CD2B00BAD059 /* am_map.c in Sources */, - 1E44AEE90B67CD3F00BAD059 /* command.c in Sources */, - 1E44AEEC0B67CD4400BAD059 /* comptime.c in Sources */, - 1E44AEEF0B67CD5400BAD059 /* console.c in Sources */, - 1E44AEF30B67CD7F00BAD059 /* filesrch.c in Sources */, - 1E44AF070B67CDE900BAD059 /* m_argv.c in Sources */, - 1E44AF0A0B67CDE900BAD059 /* m_cheat.c in Sources */, - 1E44AF0B0B67CDE900BAD059 /* m_bbox.c in Sources */, - 1E44AF0D0B67CDE900BAD059 /* m_fixed.c in Sources */, - 1E44AF0F0B67CDE900BAD059 /* m_menu.c in Sources */, - 1E44AF110B67CDE900BAD059 /* m_misc.c in Sources */, - 1E44AF130B67CDE900BAD059 /* m_random.c in Sources */, - 1E44AF1A0B67CE2A00BAD059 /* info.c in Sources */, - 1E44AF1E0B67CE3600BAD059 /* md5.c in Sources */, - 1E44AF220B67CE4100BAD059 /* mserv.c in Sources */, - 1E44AF3C0B67CE5F00BAD059 /* p_enemy.c in Sources */, - 1E44AF3D0B67CE5F00BAD059 /* p_inter.c in Sources */, - 1E44AF3E0B67CE5F00BAD059 /* p_fab.c in Sources */, - 1E44AF3F0B67CE5F00BAD059 /* p_lights.c in Sources */, - 1E44AF400B67CE5F00BAD059 /* p_map.c in Sources */, - 1E44AF410B67CE5F00BAD059 /* p_maputl.c in Sources */, - 1E44AF430B67CE5F00BAD059 /* p_mobj.c in Sources */, - 1E44AF450B67CE5F00BAD059 /* p_floor.c in Sources */, - 1E44AF480B67CE5F00BAD059 /* p_saveg.c in Sources */, - 1E44AF4A0B67CE5F00BAD059 /* p_setup.c in Sources */, - 1E44AF4C0B67CE5F00BAD059 /* p_sight.c in Sources */, - 1E44AF4D0B67CE5F00BAD059 /* p_spec.c in Sources */, - 1E44AF4F0B67CE5F00BAD059 /* p_telept.c in Sources */, - 1E44AF500B67CE5F00BAD059 /* p_tick.c in Sources */, - 1E44AF520B67CE5F00BAD059 /* p_user.c in Sources */, - 1E44AF530B67CE5F00BAD059 /* p_ceilng.c in Sources */, - 1E44AF6C0B67CEC200BAD059 /* r_bsp.c in Sources */, - 1E44AF6F0B67CEC200BAD059 /* r_data.c in Sources */, - 1E44AF700B67CEC200BAD059 /* r_draw.c in Sources */, - 1E44AF730B67CEC200BAD059 /* r_main.c in Sources */, - 1E44AF780B67CEC200BAD059 /* r_plane.c in Sources */, - 1E44AF7A0B67CEC200BAD059 /* r_segs.c in Sources */, - 1E44AF7C0B67CEC200BAD059 /* r_sky.c in Sources */, - 1E44AF7E0B67CEC200BAD059 /* r_splats.c in Sources */, - 1E44AF810B67CEC200BAD059 /* r_things.c in Sources */, - 1E44AF870B67CEE000BAD059 /* s_sound.c in Sources */, - 1E44AF8B0B67CEE900BAD059 /* screen.c in Sources */, - 1E44AF8F0B67CEF000BAD059 /* sounds.c in Sources */, - 1E44AF930B67CEFF00BAD059 /* st_stuff.c in Sources */, - 1E44AF9B0B67CF2E00BAD059 /* tables.c in Sources */, - 1E44AFA50B67CF5D00BAD059 /* v_video.c in Sources */, - 1E44AFA90B67CF6400BAD059 /* w_wad.c in Sources */, - 1E44AFAD0B67CF6F00BAD059 /* y_inter.c in Sources */, - 1E44AFB10B67CF7A00BAD059 /* z_zone.c in Sources */, - 1E44AFC40B67CFDC00BAD059 /* dosstr.c in Sources */, - 1E44AFC50B67CFDC00BAD059 /* endtxt.c in Sources */, - 1E44AFC70B67CFDC00BAD059 /* hwsym_sdl.c in Sources */, - 1E44AFC90B67CFDC00BAD059 /* i_cdmus.c in Sources */, - 1E44AFCA0B67CFDC00BAD059 /* i_main.c in Sources */, - 1E44AFCB0B67CFDC00BAD059 /* i_net.c in Sources */, - 1E44AFCD0B67CFDC00BAD059 /* i_system.c in Sources */, - 1E44AFCE0B67CFDC00BAD059 /* i_video.c in Sources */, - 1E44AFD00B67CFDC00BAD059 /* ogl_sdl.c in Sources */, - 1E44AFEB0B67D06200BAD059 /* mac_alert.c in Sources */, - 1E44AFED0B67D0AB00BAD059 /* r_opengl.c in Sources */, - 1E44B0590B67D81E00BAD059 /* SDL_macosx_main.m in Sources */, - 1E308E720B71172D0015728C /* lzf.c in Sources */, - 676BB5200E0DE06100C95963 /* m_queue.c in Sources */, - 676BB5220E0DE06100C95963 /* p_polyobj.c in Sources */, - 67B83BFA14F57EAB00AAAE4E /* lapi.c in Sources */, - 67B83BFB14F57EAB00AAAE4E /* lauxlib.c in Sources */, - 67B83BFC14F57EAB00AAAE4E /* lbaselib.c in Sources */, - 67B83BFD14F57EAB00AAAE4E /* lcode.c in Sources */, - 67B83BFE14F57EAB00AAAE4E /* ldebug.c in Sources */, - 67B83BFF14F57EAB00AAAE4E /* ldo.c in Sources */, - 67B83C0014F57EAB00AAAE4E /* ldump.c in Sources */, - 67B83C0114F57EAB00AAAE4E /* lfunc.c in Sources */, - 67B83C0214F57EAB00AAAE4E /* lgc.c in Sources */, - 67B83C0314F57EAB00AAAE4E /* linit.c in Sources */, - 67B83C0414F57EAB00AAAE4E /* llex.c in Sources */, - 67B83C0514F57EAB00AAAE4E /* lmem.c in Sources */, - 67B83C0614F57EAB00AAAE4E /* lobject.c in Sources */, - 67B83C0714F57EAB00AAAE4E /* lopcodes.c in Sources */, - 67B83C0814F57EAB00AAAE4E /* lparser.c in Sources */, - 67B83C0914F57EAB00AAAE4E /* lstate.c in Sources */, - 67B83C0A14F57EAB00AAAE4E /* lstring.c in Sources */, - 67B83C0B14F57EAB00AAAE4E /* lstrlib.c in Sources */, - 67B83C0C14F57EAB00AAAE4E /* ltable.c in Sources */, - 67B83C0D14F57EAB00AAAE4E /* ltablib.c in Sources */, - 67B83C0E14F57EAB00AAAE4E /* ltm.c in Sources */, - 67B83C0F14F57EAB00AAAE4E /* lundump.c in Sources */, - 67B83C1014F57EAB00AAAE4E /* lvm.c in Sources */, - 67B83C1114F57EAB00AAAE4E /* lzio.c in Sources */, - 67B83C1414F57ECA00AAAE4E /* b_bot.c in Sources */, - 67B83C2214F57EE600AAAE4E /* lua_baselib.c in Sources */, - 67B83C2314F57EE600AAAE4E /* lua_consolelib.c in Sources */, - 67B83C2414F57EE600AAAE4E /* lua_hooklib.c in Sources */, - 67B83C2514F57EE600AAAE4E /* lua_infolib.c in Sources */, - 67B83C2614F57EE600AAAE4E /* lua_maplib.c in Sources */, - 67B83C2714F57EE600AAAE4E /* lua_mathlib.c in Sources */, - 67B83C2814F57EE600AAAE4E /* lua_mobjlib.c in Sources */, - 67B83C2914F57EE600AAAE4E /* lua_playerlib.c in Sources */, - 67B83C2A14F57EE600AAAE4E /* lua_script.c in Sources */, - 67B83C2B14F57EE600AAAE4E /* lua_thinkerlib.c in Sources */, - 67B83C3314F57F1500AAAE4E /* m_cond.c in Sources */, - 67259DFD18D2687D00F02971 /* lua_hudlib.c in Sources */, - 67259DFE18D2687D00F02971 /* lua_skinlib.c in Sources */, - 67259E0118D268AE00F02971 /* m_anigif.c in Sources */, - 67259E0618D268F700F02971 /* i_ttf.c in Sources */, - 67259E0718D268F700F02971 /* mixer_sound.c in Sources */, - 67259E0818D268F700F02971 /* sdl_sound.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 089C165DFE840E0CC02AAC07 /* English */, - ); - name = InfoPlist.strings; - sourceTree = "<group>"; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - C01FCF4B08A954540054247B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CURRENT_PROJECT_VERSION = 2.1.24; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - NORMALSRB2, - ); - PRODUCT_NAME = Srb2mac; - }; - name = Debug; - }; - C01FCF4C08A954540054247B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CURRENT_PROJECT_VERSION = 2.1.24; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - NORMALSRB2, - ); - PRODUCT_NAME = Srb2mac; - }; - name = Release; - }; - C01FCF4F08A954540054247B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = ( - i386, - ppc, - ); - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.0.0; - DEBUG_INFORMATION_FORMAT = dwarf; - DSTROOT = "$(HOME)/Applications"; - FRAMEWORK_SEARCH_PATHS = ( - "$(HOME)/Library/Frameworks", - /Library/Frameworks, - "$(FRAMEWORK_SEARCH_PATHS)", - ); - GCC_ENABLE_CPP_EXCEPTIONS = NO; - GCC_ENABLE_CPP_RTTI = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_ENABLE_OBJC_EXCEPTIONS = NO; - GCC_ENABLE_PASCAL_STRINGS = NO; - GCC_FAST_OBJC_DISPATCH = NO; - "GCC_MODEL_TUNING[arch=ppc]" = G3; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - MAC_ALERT, - SDLMAIN, - HAVE_SDL, - HAVE_MIXER, - HAVE_PNG, - HAVE_BLUA, - LUA_USE_POSIX, - COMPVERSION, - ); - GCC_THREADSAFE_STATICS = NO; - GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; - GCC_TREAT_NONCONFORMANT_CODE_ERRORS_AS_WARNINGS = YES; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - GCC_VERSION_i386 = 4.0; - GCC_VERSION_ppc0 = 3.3; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_GLOBAL_CONSTRUCTORS = YES; - GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; - GCC_WARN_ABOUT_MISSING_NEWLINE = YES; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = YES; - GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; - GCC_WARN_EFFECTIVE_CPLUSPLUS_VIOLATIONS = YES; - GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; - GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; - GCC_WARN_INHIBIT_ALL_WARNINGS = NO; - GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; - GCC_WARN_MISSING_PARENTHESES = YES; - GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = NO; - GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; - GCC_WARN_PEDANTIC = NO; - GCC_WARN_PROTOTYPE_CONVERSION = NO; - GCC_WARN_SHADOW = NO; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_STRICT_SELECTOR_MATCH = YES; - GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = NO; - GCC_WARN_UNKNOWN_PRAGMAS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_LABEL = YES; - GCC_WARN_UNUSED_PARAMETER = YES; - GCC_WARN_UNUSED_VALUE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - GGG_MODEL_TUNING_ppc = G3; - HEADER_SEARCH_PATHS = ( - "$(HOME)/Library/Frameworks/SDL.framework/Headers", - /Library/Frameworks/SDL.framework/Headers, - "$(HOME)/Library/Frameworks/SDL_mixer.framework/Headers", - /Library/Frameworks/SDL_mixer.framework/Headers, - "$(HOME)/Library/Frameworks/libz.framework/Headers", - /Library/Frameworks/libz.framework/Headers, - "$(HOME)/Library/Frameworks/libpng.framework/Headers", - /Library/Frameworks/libpng.framework/Headers, - "$(HEADER_SEARCH_PATHS)", - ); - INFOPLIST_FILE = Info.plist; - MACH_O_TYPE = mh_execute; - MACOSX_DEPLOYMENT_TARGET = 10.4; - "MACOSX_DEPLOYMENT_TARGET[arch=i386]" = 10.4; - "MACOSX_DEPLOYMENT_TARGET[arch=ppc64]" = 10.5; - "MACOSX_DEPLOYMENT_TARGET[arch=ppc]" = 10.2; - "MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5; - MACOSX_DEPLOYMENT_TARGET_i386 = 10.4; - MACOSX_DEPLOYMENT_TARGET_ppc = 10.2; - OBJROOT = "$(inherited)/$(PRODUCT_NAME)/$(CURRENT_PROJECT_VERSION)"; - OTHER_CFLAGS_normal = "-D_DEBUG -DPARANOIA -DRANGECHECK"; - PREBINDING = NO; - PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; - PRODUCT_NAME = SRB2dummy; - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; - "SDKROOT[arch=i386]" = macosx10.4; - "SDKROOT[arch=ppc]" = macosx10.3.9; - SDKROOT_i386 = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; - SDKROOT_ppc = "$(DEVELOPER_SDK_DIR)/MacOSX10.3.9.sdk"; - STRIP_INSTALLED_PRODUCT = NO; - SYMROOT = "$(inherited)/$(PRODUCT_NAME)/$(CURRENT_PROJECT_VERSION)"; - WARNING_CFLAGS = ( - "-Wall", - "-W", - "-Wno-undef", - "-Wpointer-arith", - "-Wbad-function-cast", - "-Wno-cast-qual", - "-Wcast-align", - "-Wwrite-strings", - "-Waggregate-return", - "-Wmissing-prototypes", - "-Wmissing-declarations", - "-Wno-missing-noreturn", - "-Wnested-externs", - "-Winline", - ); - WRAPPER_EXTENSION = app; - }; - name = Debug; - }; - C01FCF5008A954540054247B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = ( - i386, - ppc, - ); - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.0.0; - DSTROOT = "$(HOME)/Applications"; - FRAMEWORK_SEARCH_PATHS = ( - "$(HOME)/Library/Frameworks", - /Library/Frameworks, - "$(FRAMEWORK_SEARCH_PATHS)", - ); - GCC_ENABLE_CPP_EXCEPTIONS = NO; - GCC_ENABLE_CPP_RTTI = NO; - GCC_ENABLE_OBJC_EXCEPTIONS = NO; - GCC_ENABLE_PASCAL_STRINGS = NO; - GCC_FAST_OBJC_DISPATCH = NO; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; - "GCC_MODEL_TUNING[arch=ppc]" = G3; - GCC_OPTIMIZATION_LEVEL = 2; - GCC_PREPROCESSOR_DEFINITIONS = ( - MAC_ALERT, - SDLMAIN, - HAVE_SDL, - HAVE_MIXER, - HAVE_PNG, - HAVE_BLUA, - LUA_USE_POSIX, - COMPVERSION, - ); - GCC_THREADSAFE_STATICS = NO; - GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; - GCC_TREAT_NONCONFORMANT_CODE_ERRORS_AS_WARNINGS = YES; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - GCC_VERSION_i386 = 4.0; - GCC_VERSION_ppc0 = 3.3; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_GLOBAL_CONSTRUCTORS = YES; - GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; - GCC_WARN_ABOUT_MISSING_NEWLINE = YES; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = YES; - GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; - GCC_WARN_EFFECTIVE_CPLUSPLUS_VIOLATIONS = YES; - GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; - GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; - GCC_WARN_INHIBIT_ALL_WARNINGS = NO; - GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; - GCC_WARN_MISSING_PARENTHESES = YES; - GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = NO; - GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; - GCC_WARN_PEDANTIC = NO; - GCC_WARN_PROTOTYPE_CONVERSION = NO; - GCC_WARN_SHADOW = NO; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_STRICT_SELECTOR_MATCH = YES; - GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNKNOWN_PRAGMAS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_LABEL = YES; - GCC_WARN_UNUSED_PARAMETER = YES; - GCC_WARN_UNUSED_VALUE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - GGG_MODEL_TUNING_ppc = G3; - HEADER_SEARCH_PATHS = ( - "$(HOME)/Library/Frameworks/SDL.framework/Headers", - /Library/Frameworks/SDL.framework/Headers, - "$(HOME)/Library/Frameworks/SDL_mixer.framework/Headers", - /Library/Frameworks/SDL_mixer.framework/Headers, - "$(HOME)/Library/Frameworks/libz.framework/Headers", - /Library/Frameworks/libz.framework/Headers, - "$(HOME)/Library/Frameworks/libpng.framework/Headers", - /Library/Frameworks/libpng.framework/Headers, - "$(HEADER_SEARCH_PATHS)", - ); - INFOPLIST_FILE = Info.plist; - MACH_O_TYPE = mh_execute; - MACOSX_DEPLOYMENT_TARGET = 10.4; - "MACOSX_DEPLOYMENT_TARGET[arch=i386]" = 10.4; - "MACOSX_DEPLOYMENT_TARGET[arch=ppc64]" = 10.5; - "MACOSX_DEPLOYMENT_TARGET[arch=ppc]" = 10.2; - "MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5; - MACOSX_DEPLOYMENT_TARGET_i386 = 10.4; - MACOSX_DEPLOYMENT_TARGET_ppc = 10.2; - OBJROOT = "$(inherited)/$(PRODUCT_NAME)/$(CURRENT_PROJECT_VERSION)"; - OTHER_CFLAGS_normal = "-DNDEBUG"; - PREBINDING = NO; - PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; - PRODUCT_NAME = SRB2dummy; - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; - "SDKROOT[arch=i386]" = macosx10.4; - "SDKROOT[arch=ppc]" = macosx10.3.9; - SDKROOT_i386 = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; - SDKROOT_ppc = "$(DEVELOPER_SDK_DIR)/MacOSX10.3.9.sdk"; - STRIP_INSTALLED_PRODUCT = NO; - SYMROOT = "$(inherited)/$(PRODUCT_NAME)/$(CURRENT_PROJECT_VERSION)"; - WARNING_CFLAGS = ( - "-Wall", - "-W", - "-Wno-undef", - "-Wpointer-arith", - "-Wbad-function-cast", - "-Wno-cast-qual", - "-Wcast-align", - "-Wwrite-strings", - "-Waggregate-return", - "-Wmissing-prototypes", - "-Wmissing-declarations", - "-Wno-missing-noreturn", - "-Wnested-externs", - "-Winline", - "-Wno-aggregate-return", - ); - WRAPPER_EXTENSION = app; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Srb2mac" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C01FCF4B08A954540054247B /* Debug */, - C01FCF4C08A954540054247B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Srb2mac" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C01FCF4F08A954540054247B /* Debug */, - C01FCF5008A954540054247B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; -/* End XCConfigurationList section */ - }; - rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; -} diff --git a/src/sdl12/macosx/mac_alert.c b/src/sdl12/macosx/mac_alert.c deleted file mode 100644 index 455e36509547e40af0a4a65f13f0e5517fb5dc24..0000000000000000000000000000000000000000 --- a/src/sdl12/macosx/mac_alert.c +++ /dev/null @@ -1,45 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1993-1996 by id Software, Inc. -// Portions Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief Graphical Alerts for MacOSX -/// -/// Shows alerts, since we can't just print these to the screen when -/// launched graphically on a mac. - -#ifdef __APPLE_CC__ - -#include "mac_alert.h" -#include <CoreFoundation/CoreFoundation.h> - -int MacShowAlert(const char *title, const char *message, const char *button1, const char *button2, const char *button3) -{ - CFOptionFlags results; - - CFUserNotificationDisplayAlert(0, - kCFUserNotificationStopAlertLevel | kCFUserNotificationNoDefaultButtonFlag, - NULL, NULL, NULL, - CFStringCreateWithCString(NULL, title, kCFStringEncodingASCII), - CFStringCreateWithCString(NULL, message, kCFStringEncodingASCII), - button1 != NULL ? CFStringCreateWithCString(NULL, button1, kCFStringEncodingASCII) : NULL, - button2 != NULL ? CFStringCreateWithCString(NULL, button2, kCFStringEncodingASCII) : NULL, - button3 != NULL ? CFStringCreateWithCString(NULL, button3, kCFStringEncodingASCII) : NULL, - &results); - - return (int)results; -} - -#endif diff --git a/src/sdl12/macosx/mac_alert.h b/src/sdl12/macosx/mac_alert.h deleted file mode 100644 index 82a28d12023bcc1fe5954359c6a466306ca85a88..0000000000000000000000000000000000000000 --- a/src/sdl12/macosx/mac_alert.h +++ /dev/null @@ -1,27 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1993-1996 by id Software, Inc. -// Portions Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief Graphical Alerts for MacOSX -/// -/// Shows alerts, since we can't just print these to the screen when -/// launched graphically on a mac. - -#ifdef __APPLE_CC__ - -extern int MacShowAlert(const char *title, const char *message, const char *button1, const char *button2, const char *button3); - -#endif diff --git a/src/sdl12/mixer_sound.c b/src/sdl12/mixer_sound.c deleted file mode 100644 index dcae19b053e51cdf58c7fbfe0c26a2689a356a54..0000000000000000000000000000000000000000 --- a/src/sdl12/mixer_sound.c +++ /dev/null @@ -1,832 +0,0 @@ -// SONIC ROBO BLAST 2 -//----------------------------------------------------------------------------- -// Copyright (C) 2008-2018 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 -/// \brief SDL Mixer interface for sound - -#include "../doomdef.h" - -#if defined(HAVE_SDL) && defined(HAVE_MIXER) && SOUND==SOUND_MIXER - -#include "../sounds.h" -#include "../s_sound.h" -#include "../i_sound.h" -#include "../w_wad.h" -#include "../z_zone.h" -#include "../byteptr.h" - -#ifdef _MSC_VER -#pragma warning(disable : 4214 4244) -#endif -#include "SDL.h" -#ifdef _MSC_VER -#pragma warning(default : 4214 4244) -#endif - -#include "SDL_mixer.h" - -/* This is the version number macro for the current SDL_mixer version: */ -#ifndef SDL_MIXER_COMPILEDVERSION -#define SDL_MIXER_COMPILEDVERSION \ - SDL_VERSIONNUM(MIX_MAJOR_VERSION, MIX_MINOR_VERSION, MIX_PATCHLEVEL) -#endif - -/* This macro will evaluate to true if compiled with SDL_mixer at least X.Y.Z */ -#ifndef SDL_MIXER_VERSION_ATLEAST -#define SDL_MIXER_VERSION_ATLEAST(X, Y, Z) \ - (SDL_MIXER_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) -#endif - -#ifdef HAVE_LIBGME -#include "gme/gme.h" -#define GME_TREBLE 5.0 -#define GME_BASS 1.0 -#ifdef HAVE_PNG /// TODO: compile with zlib support without libpng - -#define HAVE_ZLIB - -#ifndef _MSC_VER -#ifndef _WII -#ifndef _LARGEFILE64_SOURCE -#define _LARGEFILE64_SOURCE -#endif -#endif -#endif - -#ifndef _LFS64_LARGEFILE -#define _LFS64_LARGEFILE -#endif - -#ifndef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 0 -#endif - -#include "zlib.h" -#endif -#endif - -UINT8 sound_started = false; - -static boolean midimode; -static Mix_Music *music; -static UINT8 music_volume, midi_volume, sfx_volume; -static float loop_point; - -#ifdef HAVE_LIBGME -static Music_Emu *gme; -static INT32 current_track; -#endif - -void I_StartupSound(void) -{ - I_Assert(!sound_started); - sound_started = true; - - midimode = false; - music = NULL; - music_volume = midi_volume = sfx_volume = 0; - -#if SDL_MIXER_VERSION_ATLEAST(1,2,11) - Mix_Init(MIX_INIT_FLAC|MIX_INIT_MOD|MIX_INIT_MP3|MIX_INIT_OGG); -#endif - Mix_OpenAudio(44100, AUDIO_S16LSB, 2, 2048); - Mix_AllocateChannels(256); -} - -void I_ShutdownSound(void) -{ - I_Assert(sound_started); - sound_started = false; - - Mix_CloseAudio(); -#if SDL_MIXER_VERSION_ATLEAST(1,2,11) - Mix_Quit(); -#endif -#ifdef HAVE_LIBGME - if (gme) - gme_delete(gme); -#endif -} - -void I_UpdateSound(void) -{ -} - -// this is as fast as I can possibly make it. -// sorry. more asm needed. -static Mix_Chunk *ds2chunk(void *stream) -{ - UINT16 ver,freq; - UINT32 samples, i, newsamples; - UINT8 *sound; - - SINT8 *s; - INT16 *d; - INT16 o; - fixed_t step, frac; - - // lump header - ver = READUINT16(stream); // sound version format? - if (ver != 3) // It should be 3 if it's a doomsound... - return NULL; // onos! it's not a doomsound! - freq = READUINT16(stream); - samples = READUINT32(stream); - - // convert from signed 8bit ???hz to signed 16bit 44100hz. - switch(freq) - { - case 44100: - if (samples >= UINT32_MAX>>2) - return NULL; // would wrap, can't store. - newsamples = samples; - break; - case 22050: - if (samples >= UINT32_MAX>>3) - return NULL; // would wrap, can't store. - newsamples = samples<<1; - break; - case 11025: - if (samples >= UINT32_MAX>>4) - return NULL; // would wrap, can't store. - newsamples = samples<<2; - break; - default: - frac = (44100 << FRACBITS) / (UINT32)freq; - if (!(frac & 0xFFFF)) // other solid multiples (change if FRACBITS != 16) - newsamples = samples * (frac >> FRACBITS); - else // strange and unusual fractional frequency steps, plus anything higher than 44100hz. - newsamples = FixedMul(FixedDiv(samples, freq), 44100) + 1; // add 1 to counter truncation. - if (newsamples >= UINT32_MAX>>2) - return NULL; // would and/or did wrap, can't store. - break; - } - sound = Z_Malloc(newsamples<<2, PU_SOUND, NULL); // samples * frequency shift * bytes per sample * channels - - s = (SINT8 *)stream; - d = (INT16 *)sound; - - i = 0; - switch(freq) - { - case 44100: // already at the same rate? well that makes it simple. - while(i++ < samples) - { - o = ((INT16)(*s++)+0x80)<<8; // changed signedness and shift up to 16 bits - *d++ = o; // left channel - *d++ = o; // right channel - } - break; - case 22050: // unwrap 2x - while(i++ < samples) - { - o = ((INT16)(*s++)+0x80)<<8; // changed signedness and shift up to 16 bits - *d++ = o; // left channel - *d++ = o; // right channel - *d++ = o; // left channel - *d++ = o; // right channel - } - break; - case 11025: // unwrap 4x - while(i++ < samples) - { - o = ((INT16)(*s++)+0x80)<<8; // changed signedness and shift up to 16 bits - *d++ = o; // left channel - *d++ = o; // right channel - *d++ = o; // left channel - *d++ = o; // right channel - *d++ = o; // left channel - *d++ = o; // right channel - *d++ = o; // left channel - *d++ = o; // right channel - } - break; - default: // convert arbitrary hz to 44100. - step = 0; - frac = ((UINT32)freq << FRACBITS) / 44100; - while (i < samples) - { - o = (INT16)(*s+0x80)<<8; // changed signedness and shift up to 16 bits - while (step < FRACUNIT) // this is as fast as I can make it. - { - *d++ = o; // left channel - *d++ = o; // right channel - step += frac; - } - do { - i++; s++; - step -= FRACUNIT; - } while (step >= FRACUNIT); - } - break; - } - - // return Mixer Chunk. - return Mix_QuickLoad_RAW(sound, (UINT8*)d-sound); -} - -void *I_GetSfx(sfxinfo_t *sfx) -{ - void *lump; - Mix_Chunk *chunk; -#ifdef HAVE_LIBGME - Music_Emu *emu; - gme_info_t *info; -#endif - - if (sfx->lumpnum == LUMPERROR) - sfx->lumpnum = S_GetSfxLumpNum(sfx); - sfx->length = W_LumpLength(sfx->lumpnum); - - lump = W_CacheLumpNum(sfx->lumpnum, PU_SOUND); - - // convert from standard DoomSound format. - chunk = ds2chunk(lump); - if (chunk) - { - Z_Free(lump); - return chunk; - } - - // Not a doom sound? Try something else. -#ifdef HAVE_LIBGME - // VGZ format - if (((UINT8 *)lump)[0] == 0x1F - && ((UINT8 *)lump)[1] == 0x8B) - { -#ifdef HAVE_ZLIB - UINT8 *inflatedData; - size_t inflatedLen; - z_stream stream; - int zErr; // Somewhere to handle any error messages zlib tosses out - - memset(&stream, 0x00, sizeof (z_stream)); // Init zlib stream - // Begin the inflation process - inflatedLen = *(UINT32 *)lump + (sfx->length-4); // Last 4 bytes are the decompressed size, typically - inflatedData = (UINT8 *)Z_Malloc(inflatedLen, PU_SOUND, NULL); // Make room for the decompressed data - stream.total_in = stream.avail_in = sfx->length; - stream.total_out = stream.avail_out = inflatedLen; - stream.next_in = (UINT8 *)lump; - stream.next_out = inflatedData; - - zErr = inflateInit2(&stream, 32 + MAX_WBITS); - if (zErr == Z_OK) // We're good to go - { - zErr = inflate(&stream, Z_FINISH); - if (zErr == Z_STREAM_END) { - // Run GME on new data - if (!gme_open_data(inflatedData, inflatedLen, &emu, 44100)) - { - short *mem; - UINT32 len; - gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; - - Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around - Z_Free(lump); // We're done with the uninflated lump now, too. - - gme_start_track(emu, 0); - gme_set_equalizer(emu, &eq); - gme_track_info(emu, &info, 0); - - len = (info->play_length * 441 / 10) << 2; - mem = Z_Malloc(len, PU_SOUND, NULL); - gme_play(emu, len >> 1, mem); - gme_delete(emu); - - return Mix_QuickLoad_RAW((Uint8 *)mem, len); - } - } - else - { - const char *errorType; - switch (zErr) - { - case Z_ERRNO: - errorType = "Z_ERRNO"; break; - case Z_STREAM_ERROR: - errorType = "Z_STREAM_ERROR"; break; - case Z_DATA_ERROR: - errorType = "Z_DATA_ERROR"; break; - case Z_MEM_ERROR: - errorType = "Z_MEM_ERROR"; break; - case Z_BUF_ERROR: - errorType = "Z_BUF_ERROR"; break; - case Z_VERSION_ERROR: - errorType = "Z_VERSION_ERROR"; break; - default: - errorType = "unknown error"; - } - CONS_Alert(CONS_ERROR,"Encountered %s when running inflate: %s\n", errorType, stream.msg); - } - (void)inflateEnd(&stream); - } - else // Hold up, zlib's got a problem - { - const char *errorType; - switch (zErr) - { - case Z_ERRNO: - errorType = "Z_ERRNO"; break; - case Z_STREAM_ERROR: - errorType = "Z_STREAM_ERROR"; break; - case Z_DATA_ERROR: - errorType = "Z_DATA_ERROR"; break; - case Z_MEM_ERROR: - errorType = "Z_MEM_ERROR"; break; - case Z_BUF_ERROR: - errorType = "Z_BUF_ERROR"; break; - case Z_VERSION_ERROR: - errorType = "Z_VERSION_ERROR"; break; - default: - errorType = "unknown error"; - } - CONS_Alert(CONS_ERROR,"Encountered %s when running inflateInit: %s\n", errorType, stream.msg); - } - Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up -#else - //CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n"); -#endif - } - // Try to read it as a GME sound - else if (!gme_open_data(lump, sfx->length, &emu, 44100)) - { - short *mem; - UINT32 len; - gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; - - Z_Free(lump); - - gme_start_track(emu, 0); - gme_set_equalizer(emu, &eq); - gme_track_info(emu, &info, 0); - - len = (info->play_length * 441 / 10) << 2; - mem = Z_Malloc(len, PU_SOUND, NULL); - gme_play(emu, len >> 1, mem); - gme_delete(emu); - - return Mix_QuickLoad_RAW((Uint8 *)mem, len); - } -#endif - - // Try to load it as a WAVE or OGG using Mixer. - return Mix_LoadWAV_RW(SDL_RWFromMem(lump, sfx->length), 1); -} - -void I_FreeSfx(sfxinfo_t *sfx) -{ - if (sfx->data) - Mix_FreeChunk(sfx->data); - sfx->data = NULL; -} - -INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel) -{ - UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127 - INT32 handle = Mix_PlayChannel(channel, S_sfx[id].data, 0); - Mix_Volume(handle, volume); - Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff)); - (void)pitch; // Mixer can't handle pitch - (void)priority; // priority and channel management is handled by SRB2... - return handle; -} - -void I_StopSound(INT32 handle) -{ - Mix_HaltChannel(handle); -} - -boolean I_SoundIsPlaying(INT32 handle) -{ - return Mix_Playing(handle); -} - -void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch) -{ - UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127 - Mix_Volume(handle, volume); - Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff)); - (void)pitch; -} - -void I_SetSfxVolume(UINT8 volume) -{ - sfx_volume = volume; -} - -// -// Music -// - -// Music hooks -static void music_loop(void) -{ - Mix_PlayMusic(music, 0); - Mix_SetMusicPosition(loop_point); -} - -#ifdef HAVE_LIBGME -static void mix_gme(void *udata, Uint8 *stream, int len) -{ - int i; - short *p; - - (void)udata; - - // no gme? no music. - if (!gme || gme_track_ended(gme)) - return; - - // play gme into stream - gme_play(gme, len/2, (short *)stream); - - // apply volume to stream - for (i = 0, p = (short *)stream; i < len/2; i++, p++) - *p = ((INT32)*p) * music_volume / 31; -} -#endif - -void I_InitMusic(void) -{ -} - -void I_ShutdownMusic(void) -{ - I_ShutdownDigMusic(); - I_ShutdownMIDIMusic(); -} - -void I_PauseSong(INT32 handle) -{ - (void)handle; - Mix_PauseMusic(); -} - -void I_ResumeSong(INT32 handle) -{ - (void)handle; - Mix_ResumeMusic(); -} - -// -// Digital Music -// - -void I_InitDigMusic(void) -{ -#ifdef HAVE_LIBGME - gme = NULL; - current_track = -1; -#endif -} - -void I_ShutdownDigMusic(void) -{ - if (midimode) - return; -#ifdef HAVE_LIBGME - if (gme) - { - Mix_HookMusic(NULL, NULL); - gme_delete(gme); - gme = NULL; - } -#endif - if (!music) - return; - Mix_HookMusicFinished(NULL); - Mix_FreeMusic(music); - music = NULL; -} - -boolean I_StartDigSong(const char *musicname, boolean looping) -{ - char *data; - size_t len; - lumpnum_t lumpnum = W_CheckNumForName(va("O_%s",musicname)); - - I_Assert(!music); -#ifdef HAVE_LIBGME - I_Assert(!gme); -#endif - - if (lumpnum == LUMPERROR) - { - lumpnum = W_CheckNumForName(va("D_%s",musicname)); - if (lumpnum == LUMPERROR) - return false; - midimode = true; - } - else - midimode = false; - - data = (char *)W_CacheLumpNum(lumpnum, PU_MUSIC); - len = W_LumpLength(lumpnum); - -#ifdef HAVE_LIBGME - if ((UINT8)data[0] == 0x1F - && (UINT8)data[1] == 0x8B) - { -#ifdef HAVE_ZLIB - UINT8 *inflatedData; - size_t inflatedLen; - z_stream stream; - int zErr; // Somewhere to handle any error messages zlib tosses out - - memset(&stream, 0x00, sizeof (z_stream)); // Init zlib stream - // Begin the inflation process - inflatedLen = *(UINT32 *)(data + (len-4)); // Last 4 bytes are the decompressed size, typically - inflatedData = (UINT8 *)Z_Calloc(inflatedLen, PU_MUSIC, NULL); // Make room for the decompressed data - stream.total_in = stream.avail_in = len; - stream.total_out = stream.avail_out = inflatedLen; - stream.next_in = (UINT8 *)data; - stream.next_out = inflatedData; - - zErr = inflateInit2(&stream, 32 + MAX_WBITS); - if (zErr == Z_OK) // We're good to go - { - zErr = inflate(&stream, Z_FINISH); - if (zErr == Z_STREAM_END) { - // Run GME on new data - if (!gme_open_data(inflatedData, inflatedLen, &gme, 44100)) - { - gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; - gme_start_track(gme, 0); - current_track = 0; - gme_set_equalizer(gme, &eq); - Mix_HookMusic(mix_gme, gme); - Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around - return true; - } - } - else - { - const char *errorType; - switch (zErr) - { - case Z_ERRNO: - errorType = "Z_ERRNO"; break; - case Z_STREAM_ERROR: - errorType = "Z_STREAM_ERROR"; break; - case Z_DATA_ERROR: - errorType = "Z_DATA_ERROR"; break; - case Z_MEM_ERROR: - errorType = "Z_MEM_ERROR"; break; - case Z_BUF_ERROR: - errorType = "Z_BUF_ERROR"; break; - case Z_VERSION_ERROR: - errorType = "Z_VERSION_ERROR"; break; - default: - errorType = "unknown error"; - } - CONS_Alert(CONS_ERROR,"Encountered %s when running inflate: %s\n", errorType, stream.msg); - } - (void)inflateEnd(&stream); - } - else // Hold up, zlib's got a problem - { - const char *errorType; - switch (zErr) - { - case Z_ERRNO: - errorType = "Z_ERRNO"; break; - case Z_STREAM_ERROR: - errorType = "Z_STREAM_ERROR"; break; - case Z_DATA_ERROR: - errorType = "Z_DATA_ERROR"; break; - case Z_MEM_ERROR: - errorType = "Z_MEM_ERROR"; break; - case Z_BUF_ERROR: - errorType = "Z_BUF_ERROR"; break; - case Z_VERSION_ERROR: - errorType = "Z_VERSION_ERROR"; break; - default: - errorType = "unknown error"; - } - CONS_Alert(CONS_ERROR,"Encountered %s when running inflateInit: %s\n", errorType, stream.msg); - } - Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up -#else - //CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n"); -#endif - } - else if (!gme_open_data(data, len, &gme, 44100)) - { - gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; - gme_start_track(gme, 0); - current_track = 0; - gme_set_equalizer(gme, &eq); - Mix_HookMusic(mix_gme, gme); - return true; - } -#endif - - music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len)); - if (!music) - { - CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError()); - return true; - } - - // Find the OGG loop point. - loop_point = 0.0f; - if (looping) - { - const char *key1 = "LOOP"; - const char *key2 = "POINT="; - const char *key3 = "MS="; - const UINT8 key1len = strlen(key1); - const UINT8 key2len = strlen(key2); - const UINT8 key3len = strlen(key3); - char *p = data; - while ((UINT32)(p - data) < len) - { - if (strncmp(p++, key1, key1len)) - continue; - p += key1len-1; // skip OOP (the L was skipped in strncmp) - if (!strncmp(p, key2, key2len)) // is it LOOPPOINT=? - { - p += key2len; // skip POINT= - loop_point = (float)((44.1L+atoi(p)) / 44100.0L); // LOOPPOINT works by sample count. - // because SDL_Mixer is USELESS and can't even tell us - // something simple like the frequency of the streaming music, - // we are unfortunately forced to assume that ALL MUSIC is 44100hz. - // This means a lot of tracks that are only 22050hz for a reasonable downloadable file size will loop VERY badly. - } - else if (!strncmp(p, key3, key3len)) // is it LOOPMS=? - { - p += key3len; // skip MS= - loop_point = atoi(p) / 1000.0L; // LOOPMS works by real time, as miliseconds. - // Everything that uses LOOPMS will work perfectly with SDL_Mixer. - } - // Neither?! Continue searching. - } - } - - if (Mix_PlayMusic(music, looping && loop_point == 0.0f ? -1 : 0) == -1) - { - CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError()); - return true; - } - if (midimode) - Mix_VolumeMusic((UINT32)midi_volume*128/31); - else - Mix_VolumeMusic((UINT32)music_volume*128/31); - - if (loop_point != 0.0f) - Mix_HookMusicFinished(music_loop); - return true; -} - -void I_StopDigSong(void) -{ - if (midimode) - return; -#ifdef HAVE_LIBGME - if (gme) - { - Mix_HookMusic(NULL, NULL); - gme_delete(gme); - gme = NULL; - current_track = -1; - return; - } -#endif - if (!music) - return; - Mix_HookMusicFinished(NULL); - Mix_FreeMusic(music); - music = NULL; -} - -void I_SetDigMusicVolume(UINT8 volume) -{ - music_volume = volume; - if (midimode || !music) - return; - Mix_VolumeMusic((UINT32)volume*128/31); -} - -boolean I_SetSongSpeed(float speed) -{ - if (speed > 250.0f) - speed = 250.0f; //limit speed up to 250x -#ifdef HAVE_LIBGME - if (gme) - { - SDL_LockAudio(); - gme_set_tempo(gme, speed); - SDL_UnlockAudio(); - return true; - } -#else - (void)speed; -#endif - return false; -} - -boolean I_SetSongTrack(int track) -{ -#ifdef HAVE_LIBGME - if (current_track == track) - return false; - - // If the specified track is within the number of tracks playing, then change it - if (gme) - { - SDL_LockAudio(); - if (track >= 0 - && track < gme_track_count(gme)) - { - gme_err_t gme_e = gme_start_track(gme, track); - if (gme_e != NULL) - { - CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e); - return false; - } - current_track = track; - SDL_UnlockAudio(); - return true; - } - SDL_UnlockAudio(); - return false; - } -#endif - (void)track; - return false; -} - -// -// MIDI Music -// - -void I_InitMIDIMusic(void) -{ -} - -void I_ShutdownMIDIMusic(void) -{ - if (!midimode || !music) - return; - Mix_FreeMusic(music); - music = NULL; -} - -void I_SetMIDIMusicVolume(UINT8 volume) -{ - midi_volume = volume; - if (!midimode || !music) - return; - Mix_VolumeMusic((UINT32)volume*128/31); -} - -INT32 I_RegisterSong(void *data, size_t len) -{ - music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len)); - if (!music) - { - CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError()); - return -1; - } - return 1337; -} - -boolean I_PlaySong(INT32 handle, boolean looping) -{ - (void)handle; - - midimode = true; - - if (Mix_PlayMusic(music, looping ? -1 : 0) == -1) - { - CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError()); - return false; - } - Mix_VolumeMusic((UINT32)music_volume*128/31); - return true; -} - -void I_StopSong(INT32 handle) -{ - if (!midimode || !music) - return; - - (void)handle; - Mix_HaltMusic(); -} - -void I_UnRegisterSong(INT32 handle) -{ - if (!midimode || !music) - return; - - (void)handle; - Mix_FreeMusic(music); - music = NULL; -} - -#endif diff --git a/src/sdl12/ogl_sdl.c b/src/sdl12/ogl_sdl.c deleted file mode 100644 index eb7e9996dba228f1f626670705e52220c18df670..0000000000000000000000000000000000000000 --- a/src/sdl12/ogl_sdl.c +++ /dev/null @@ -1,317 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -//----------------------------------------------------------------------------- -/// \file -/// \brief SDL specific part of the OpenGL API for SRB2 - -#ifdef _MSC_VER -#pragma warning(disable : 4214 4244) -#endif - -#ifdef HAVE_SDL - -#include "SDL.h" - -#ifdef _MSC_VER -#pragma warning(default : 4214 4244) -#endif - -#include "../doomdef.h" - -#ifdef HWRENDER -#include "../hardware/r_opengl/r_opengl.h" -#include "ogl_sdl.h" -#include "../i_system.h" -#include "hwsym_sdl.h" -#include "../m_argv.h" - -#ifdef DEBUG_TO_FILE -#include <stdarg.h> -#if defined (_WIN32) && !defined (__CYGWIN__) -#include <direct.h> -#else -#include <unistd.h> -#endif -#include <sys/types.h> -#include <sys/stat.h> -#endif - -#ifdef USE_WGL_SWAP -PFNWGLEXTSWAPCONTROLPROC wglSwapIntervalEXT = NULL; -#else -typedef int (*PFNGLXSWAPINTERVALPROC) (int); -PFNGLXSWAPINTERVALPROC glXSwapIntervalSGIEXT = NULL; -#endif - -#ifndef STATIC_OPENGL -PFNglClear pglClear; -PFNglGetIntegerv pglGetIntegerv; -PFNglGetString pglGetString; -#endif - -#ifdef _PSP -static const Uint32 WOGLFlags = SDL_HWSURFACE|SDL_OPENGL/*|SDL_RESIZABLE*/; -static const Uint32 FOGLFlags = SDL_HWSURFACE|SDL_OPENGL|SDL_FULLSCREEN; -#else -static const Uint32 WOGLFlags = SDL_OPENGL/*|SDL_RESIZABLE*/; -static const Uint32 FOGLFlags = SDL_OPENGL|SDL_FULLSCREEN; -#endif - -/** \brief SDL video display surface -*/ -SDL_Surface *vidSurface = NULL; -INT32 oglflags = 0; -void *GLUhandle = NULL; - -#ifndef STATIC_OPENGL -void *GetGLFunc(const char *proc) -{ - if (strncmp(proc, "glu", 3) == 0) - { - if (GLUhandle) - return hwSym(proc, GLUhandle); - else - return NULL; - } - return SDL_GL_GetProcAddress(proc); -} -#endif - -boolean LoadGL(void) -{ -#ifndef STATIC_OPENGL - const char *OGLLibname = NULL; - const char *GLULibname = NULL; - - if (M_CheckParm ("-OGLlib") && M_IsNextParm()) - OGLLibname = M_GetNextParm(); - - if (SDL_GL_LoadLibrary(OGLLibname) != 0) - { - I_OutputMsg("Could not load OpenGL Library: %s\n" - "Falling back to Software mode.\n", SDL_GetError()); - if (!M_CheckParm ("-OGLlib")) - I_OutputMsg("If you know what is the OpenGL library's name, use -OGLlib\n"); - return 0; - } - -#if 0 - GLULibname = "/proc/self/exe"; -#elif defined (_WIN32) - GLULibname = "GLU32.DLL"; -#elif defined (__MACH__) - GLULibname = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGLU.dylib"; -#elif defined (macintos) - GLULibname = "OpenGLLibrary"; -#elif defined (__unix__) - GLULibname = "libGLU.so.1"; -#elif defined (__HAIKU__) - GLULibname = "libGLU.so"; -#else - GLULibname = NULL; -#endif - - if (M_CheckParm ("-GLUlib") && M_IsNextParm()) - GLULibname = M_GetNextParm(); - - if (GLULibname) - { - GLUhandle = hwOpen(GLULibname); - if (GLUhandle) - return SetupGLfunc(); - else - { - I_OutputMsg("Could not load GLU Library: %s\n", GLULibname); - if (!M_CheckParm ("-GLUlib")) - I_OutputMsg("If you know what is the GLU library's name, use -GLUlib\n"); - } - } - else - { - I_OutputMsg("Could not load GLU Library\n"); - I_OutputMsg("If you know what is the GLU library's name, use -GLUlib\n"); - } -#endif - return SetupGLfunc(); -} - -/** \brief The OglSdlSurface function - - \param w width - \param h height - \param isFullscreen if true, go fullscreen - - \return if true, changed video mode -*/ -boolean OglSdlSurface(INT32 w, INT32 h, boolean isFullscreen) -{ - INT32 cbpp; - Uint32 OGLFlags; - const GLvoid *glvendor = NULL, *glrenderer = NULL, *glversion = NULL; - - cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value; - - if (vidSurface) - { - //Alam: SDL_Video system free vidSurface for me -#ifdef VOODOOSAFESWITCHING - SDL_QuitSubSystem(SDL_INIT_VIDEO); - SDL_InitSubSystem(SDL_INIT_VIDEO); -#endif - } - - if (isFullscreen) - OGLFlags = FOGLFlags; - else - OGLFlags = WOGLFlags; - - cbpp = SDL_VideoModeOK(w, h, cbpp, OGLFlags); - if (cbpp < 16) - return true; //Alam: Let just say we did, ok? - - vidSurface = SDL_SetVideoMode(w, h, cbpp, OGLFlags); - if (!vidSurface) - return false; - - glvendor = pglGetString(GL_VENDOR); - // Get info and extensions. - //BP: why don't we make it earlier ? - //Hurdler: we cannot do that before intialising gl context - glrenderer = pglGetString(GL_RENDERER); - glversion = pglGetString(GL_VERSION); - gl_extensions = pglGetString(GL_EXTENSIONS); - - DBG_Printf("Vendor : %s\n", glvendor); - DBG_Printf("Renderer : %s\n", glrenderer); - DBG_Printf("Version : %s\n", glversion); - DBG_Printf("Extensions : %s\n", gl_extensions); - oglflags = 0; - -#ifdef _WIN32 - // BP: disable advenced feature that don't work on somes hardware - // Hurdler: Now works on G400 with bios 1.6 and certified drivers 6.04 - if (strstr(glrenderer, "810")) oglflags |= GLF_NOZBUFREAD; -#elif defined (unix) || defined (UNIXCOMMON) - // disable advanced features not working on somes hardware - if (strstr(glrenderer, "G200")) oglflags |= GLF_NOTEXENV; - if (strstr(glrenderer, "G400")) oglflags |= GLF_NOTEXENV; -#endif - DBG_Printf("oglflags : 0x%X\n", oglflags ); - -#ifdef USE_PALETTED_TEXTURE - if (isExtAvailable("GL_EXT_paletted_texture", gl_extensions)) - glColorTableEXT = SDL_GL_GetProcAddress("glColorTableEXT"); - else - glColorTableEXT = NULL; -#endif - -#ifdef USE_WGL_SWAP - if (isExtAvailable("WGL_EXT_swap_control", gl_extensions)) - wglSwapIntervalEXT = SDL_GL_GetProcAddress("wglSwapIntervalEXT"); - else - wglSwapIntervalEXT = NULL; -#else - if (isExtAvailable("GLX_SGI_swap_control", gl_extensions)) - glXSwapIntervalSGIEXT = SDL_GL_GetProcAddress("glXSwapIntervalSGI"); - else - glXSwapIntervalSGIEXT = NULL; -#endif - -#ifndef KOS_GL_COMPATIBILITY - if (isExtAvailable("GL_EXT_texture_filter_anisotropic", gl_extensions)) - pglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnisotropy); - else -#endif - maximumAnisotropy = 0; - - SetupGLFunc13(); - - granisotropicmode_cons_t[1].value = maximumAnisotropy; - - SetModelView(w, h); - SetStates(); - pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); - - HWR_Startup(); -#ifdef KOS_GL_COMPATIBILITY - textureformatGL = GL_ARGB4444; -#else - textureformatGL = cbpp > 16 ? GL_RGBA : GL_RGB5_A1; -#endif - - return true; -} - -/** \brief The OglSdlFinishUpdate function - - \param vidwait wait for video sync - - \return void -*/ -void OglSdlFinishUpdate(boolean waitvbl) -{ - static boolean oldwaitvbl = false; - if (oldwaitvbl != waitvbl) - { -#ifdef USE_WGL_SWAP - if (wglSwapIntervalEXT) - wglSwapIntervalEXT(waitvbl); -#else - if (glXSwapIntervalSGIEXT) - glXSwapIntervalSGIEXT(waitvbl); -#endif - } - oldwaitvbl = waitvbl; - - SDL_GL_SwapBuffers(); -} - -EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette, RGBA_t *pgamma) -{ - INT32 i = -1; - UINT32 redgamma = pgamma->s.red, greengamma = pgamma->s.green, - bluegamma = pgamma->s.blue; - -#if 0 // changing the gamma to 127 is a bad idea - i = SDL_SetGamma(byteasfloat(redgamma), byteasfloat(greengamma), byteasfloat(bluegamma)); -#endif - if (i == 0) redgamma = greengamma = bluegamma = 0x7F; //Alam: cool - for (i = 0; i < 256; i++) - { - myPaletteData[i].s.red = (UINT8)MIN((palette[i].s.red * redgamma) /127, 255); - myPaletteData[i].s.green = (UINT8)MIN((palette[i].s.green * greengamma)/127, 255); - myPaletteData[i].s.blue = (UINT8)MIN((palette[i].s.blue * bluegamma) /127, 255); - myPaletteData[i].s.alpha = palette[i].s.alpha; - } -#ifdef USE_PALETTED_TEXTURE - if (glColorTableEXT) - { - for (i = 0; i < 256; i++) - { - palette_tex[(3*i)+0] = palette[i].s.red; - palette_tex[(3*i)+1] = palette[i].s.green; - palette_tex[(3*i)+2] = palette[i].s.blue; - } - glColorTableEXT(GL_TEXTURE_2D, GL_RGB8, 256, GL_RGB, GL_UNSIGNED_BYTE, palette_tex); - } -#endif - // on a chang�de palette, il faut recharger toutes les textures - // jaja, und noch viel mehr ;-) - Flush(); -} - -#endif //HWRENDER -#endif //SDL diff --git a/src/sdl12/ogl_sdl.h b/src/sdl12/ogl_sdl.h deleted file mode 100644 index 43c28fa422a0b42e6367da418e62aa5ce3aa1fb0..0000000000000000000000000000000000000000 --- a/src/sdl12/ogl_sdl.h +++ /dev/null @@ -1,30 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief SDL specific part of the OpenGL API for SRB2 - -#include "../v_video.h" - -extern SDL_Surface *vidSurface; -extern void *GLUhandle; - -boolean OglSdlSurface(INT32 w, INT32 h, boolean isFullscreen); - -void OglSdlFinishUpdate(boolean vidwait); - -#ifdef _CREATE_DLL_ -EXPORT void HWRAPI( OglSdlSetPalette ) (RGBA_t *palette, RGBA_t *pgamma); -#endif diff --git a/src/sdl12/sdl_sound.c b/src/sdl12/sdl_sound.c deleted file mode 100644 index ed1afd8e23a2981069bcce2afe15f1103cc261bd..0000000000000000000000000000000000000000 --- a/src/sdl12/sdl_sound.c +++ /dev/null @@ -1,2031 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1993-1996 by id Software, Inc. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// The source is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief SDL interface for sound - -#include <math.h> -#include "../doomdef.h" - -#ifdef _MSC_VER -#pragma warning(disable : 4214 4244) -#endif - -#if defined(HAVE_SDL) && SOUND==SOUND_SDL - -#include "SDL.h" - -#ifdef _MSC_VER -#pragma warning(default : 4214 4244) -#endif - -#ifdef HAVE_MIXER -#include "SDL_mixer.h" -/* This is the version number macro for the current SDL_mixer version: */ -#ifndef SDL_MIXER_COMPILEDVERSION -#define SDL_MIXER_COMPILEDVERSION \ - SDL_VERSIONNUM(MIX_MAJOR_VERSION, MIX_MINOR_VERSION, MIX_PATCHLEVEL) -#endif - -/* This macro will evaluate to true if compiled with SDL_mixer at least X.Y.Z */ -#ifndef SDL_MIXER_VERSION_ATLEAST -#define SDL_MIXER_VERSION_ATLEAST(X, Y, Z) \ - (SDL_MIXER_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) -#endif - -#else -#define MIX_CHANNELS 8 -#endif - -#if defined (_WIN32) && !defined (_WIN32_WCE) && !defined (_XBOX) -#include <direct.h> -#elif defined (__GNUC__) -#include <unistd.h> -#endif -#include "../z_zone.h" - -#include "../m_swap.h" -#include "../i_system.h" -#include "../i_sound.h" -#include "../m_argv.h" -#include "../m_misc.h" -#include "../w_wad.h" -#include "../screen.h" //vid.WndParent -#include "../doomdef.h" -#include "../doomstat.h" -#include "../s_sound.h" - -#include "../d_main.h" - -#ifdef HW3SOUND -#include "../hardware/hw3dsdrv.h" -#include "../hardware/hw3sound.h" -#include "hwsym_sdl.h" -#endif - -#ifdef HAVE_LIBGME -#include "gme/gme.h" -#endif - -// The number of internal mixing channels, -// the samples calculated for each mixing step, -// the size of the 16bit, 2 hardware channel (stereo) -// mixing buffer, and the samplerate of the raw data. - -// Needed for calling the actual sound output. -#if defined (_WIN32_WCE) || defined (DC) || defined (PSP) || defined(GP2X) -#define NUM_CHANNELS MIX_CHANNELS -#else -#define NUM_CHANNELS MIX_CHANNELS*4 -#endif - -#define INDEXOFSFX(x) ((sfxinfo_t *)x - S_sfx) - -#if defined (_WIN32_WCE) || defined (DC) || defined (PSP) -static Uint16 samplecount = 512; //Alam: .5KB samplecount at 11025hz is 46.439909297052154195011337868481ms of buffer -#elif defined(GP2X) -static Uint16 samplecount = 128; -#else -static Uint16 samplecount = 1024; //Alam: 1KB samplecount at 22050hz is 46.439909297052154195011337868481ms of buffer -#endif - -typedef struct chan_struct -{ - // The channel data pointers, start and end. - Uint8 *data; //static unsigned char *channels[NUM_CHANNELS]; - Uint8 *end; //static unsigned char *channelsend[NUM_CHANNELS]; - - // pitch - Uint32 realstep; // The channel step amount... - Uint32 step; //static UINT32 channelstep[NUM_CHANNELS]; - Uint32 stepremainder; //static UINT32 channelstepremainder[NUM_CHANNELS]; - Uint32 samplerate; // ... and a 0.16 bit remainder of last step. - - // Time/gametic that the channel started playing, - // used to determine oldest, which automatically - // has lowest priority. - tic_t starttic; //static INT32 channelstart[NUM_CHANNELS]; - - // The sound handle, determined on registration, - // used to unregister/stop/modify, - INT32 handle; //static INT32 channelhandles[NUM_CHANNELS]; - - // SFX id of the playing sound effect. - void *id; // Used to catch duplicates (like chainsaw). - sfxenum_t sfxid; //static INT32 channelids[NUM_CHANNELS]; - INT32 vol; //the channel volume - INT32 sep; //the channel pan - - // Hardware left and right channel volume lookup. - Sint16* leftvol_lookup; //static INT32 *channelleftvol_lookup[NUM_CHANNELS]; - Sint16* rightvol_lookup; //static INT32 *channelrightvol_lookup[NUM_CHANNELS]; -} chan_t; - -static chan_t channels[NUM_CHANNELS]; - -// Pitch to stepping lookup -static INT32 steptable[256]; - -// Volume lookups. -static Sint16 vol_lookup[128 * 256]; - -UINT8 sound_started = false; -static SDL_mutex *Snd_Mutex = NULL; - -//SDL's Audio -static SDL_AudioSpec audio; - -static SDL_bool musicStarted = SDL_FALSE; -#ifdef HAVE_MIXER -static SDL_mutex *Msc_Mutex = NULL; -/* FIXME: Make this file instance-specific */ -#ifdef _arch_dreamcast -#define MIDI_PATH "/ram" -#elif defined(GP2X) -#define MIDI_PATH "/mnt/sd/srb2" -#define MIDI_PATH2 "/tmp/mnt/sd/srb2" -#else -#define MIDI_PATH srb2home -#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) -#define MIDI_PATH2 "/tmp" -#endif -#endif -#define MIDI_TMPFILE "srb2music" -#define MIDI_TMPFILE2 "srb2wav" -static INT32 musicvol = 62; - -#if SDL_MIXER_VERSION_ATLEAST(1,2,2) -#define MIXER_POS //Mix_FadeInMusicPos in 1.2.2+ -static void SDLCALL I_FinishMusic(void); -static double loopstartDig = 0.0l; -static SDL_bool loopingDig = SDL_FALSE; -static SDL_bool canlooping = SDL_TRUE; -#endif - -#if SDL_MIXER_VERSION_ATLEAST(1,2,7) -#define USE_RWOPS // ok, USE_RWOPS is in here -#if defined (DC) || defined (_WIN32_WCE) || defined (_XBOX) //|| defined(_WIN32) || defined(GP2X) -#undef USE_RWOPS -#endif -#endif - -#if SDL_MIXER_VERSION_ATLEAST(1,2,10) -//#define MIXER_INIT -#endif - -#ifdef USE_RWOPS -static void * Smidi[2] = { NULL, NULL }; -static SDL_bool canuseRW = SDL_TRUE; -#endif -static const char *fmidi[2] = { MIDI_TMPFILE, MIDI_TMPFILE2}; - -static const INT32 MIDIfade = 500; -static const INT32 Digfade = 0; - -static Mix_Music *music[2] = { NULL, NULL }; -#endif - -typedef struct srb2audio_s { - void *userdata; -#ifdef HAVE_LIBGME - Music_Emu *gme_emu; - UINT8 gme_pause; - UINT8 gme_loop; -#endif -} srb2audio_t; - -static srb2audio_t localdata; - -static void Snd_LockAudio(void) //Alam: Lock audio data and uninstall audio callback -{ - if (Snd_Mutex) SDL_LockMutex(Snd_Mutex); - else if (nosound) return; - else if (nomidimusic && nodigimusic -#ifdef HW3SOUND - && hws_mode == HWS_DEFAULT_MODE -#endif - ) SDL_LockAudio(); -#ifdef HAVE_MIXER - else if (musicStarted) Mix_SetPostMix(NULL, NULL); -#endif -} - -static void Snd_UnlockAudio(void) //Alam: Unlock audio data and reinstall audio callback -{ - if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); - else if (nosound) return; - else if (nomidimusic && nodigimusic -#ifdef HW3SOUND - && hws_mode == HWS_DEFAULT_MODE -#endif - ) SDL_UnlockAudio(); -#ifdef HAVE_MIXER - else if (musicStarted) Mix_SetPostMix(audio.callback, audio.userdata); -#endif -} - -static inline Uint16 Snd_LowerRate(Uint16 sr) -{ - if (sr <= audio.freq) // already lowered rate? - return sr; // good then - for (;sr > audio.freq;) // not good? - { // then let see... - if (sr % 2) // can we div by half? - return sr; // no, just use the currect rate - sr /= 2; // we can? wonderful - } // let start over again - if (sr == audio.freq) // did we drop to the desired rate? - return sr; // perfect! but if not - return sr*2; // just keep it just above the output sample rate -} - -#ifdef _MSC_VER -#pragma warning(disable : 4200) -#pragma pack(1) -#endif - -typedef struct -{ - Uint16 header; // 3? - Uint16 samplerate; // 11025+ - Uint16 samples; // number of samples - Uint16 dummy; // 0 - Uint8 data[0]; // data; -} ATTRPACK dssfx_t; - -#ifdef _MSC_VER -#pragma pack() -#pragma warning(default : 4200) -#endif - -// -// This function loads the sound data from the WAD lump, -// for single sound. -// -static void *getsfx(lumpnum_t sfxlump, size_t *len) -{ - dssfx_t *sfx, *paddedsfx; - Uint16 sr , csr; - size_t size = *len; - SDL_AudioCVT sfxcvt; - - sfx = (dssfx_t *)malloc(size); - if (sfx) W_ReadLump(sfxlump, (void *)sfx); - else return NULL; - sr = SHORT(sfx->samplerate); - csr = Snd_LowerRate(sr); - - if (sr > csr && SDL_BuildAudioCVT(&sfxcvt, AUDIO_U8, 1, sr, AUDIO_U8, 1, csr)) - {//Alam: Setup the AudioCVT for the SFX - - sfxcvt.len = (INT32)size-8; //Alam: Chop off the header - sfxcvt.buf = malloc(sfxcvt.len * sfxcvt.len_mult); //Alam: make room - if (sfxcvt.buf) M_Memcpy(sfxcvt.buf, &(sfx->data), sfxcvt.len); //Alam: copy the sfx sample - - if (sfxcvt.buf && SDL_ConvertAudio(&sfxcvt) == 0) //Alam: let convert it! - { - size = sfxcvt.len_cvt + 8; - *len = sfxcvt.len_cvt; - - // Allocate from zone memory. - paddedsfx = (dssfx_t *) Z_Malloc(size, PU_SOUND, NULL); - - // Now copy and pad. - M_Memcpy(paddedsfx->data, sfxcvt.buf, sfxcvt.len_cvt); - free(sfxcvt.buf); - M_Memcpy(paddedsfx,sfx,8); - paddedsfx->samplerate = SHORT(csr); // new freq - } - else //Alam: the convert failed, not needed or I couldn't malloc the buf - { - if (sfxcvt.buf) free(sfxcvt.buf); - *len = size - 8; - - // Allocate from zone memory then copy and pad - paddedsfx = (dssfx_t *)M_Memcpy(Z_Malloc(size, PU_SOUND, NULL), sfx, size); - } - } - else - { - // Pads the sound effect out to the mixing buffer size. - // The original realloc would interfere with zone memory. - *len = size - 8; - - // Allocate from zone memory then copy and pad - paddedsfx = (dssfx_t *)M_Memcpy(Z_Malloc(size, PU_SOUND, NULL), sfx, size); - } - - // Remove the cached lump. - free(sfx); - - // Return allocated padded data. - return paddedsfx; -} - -// used to (re)calculate channel params based on vol, sep, pitch -static void I_SetChannelParams(chan_t *c, INT32 vol, INT32 sep, INT32 step) -{ - INT32 leftvol; - INT32 rightvol; - c->vol = vol; - c->sep = sep; - c->step = c->realstep = step; - - if (step != steptable[128]) - c->step += (((c->samplerate<<16)/audio.freq)-65536); - else if (c->samplerate != (unsigned)audio.freq) - c->step = ((c->samplerate<<16)/audio.freq); - // x^2 separation, that is, orientation/stereo. - // range is: 0 (left) - 255 (right) - - // Volume arrives in range 0..255 and it must be in 0..cv_soundvolume... - vol = (vol * cv_soundvolume.value) >> 7; - // note: >> 6 would use almost the entire dynamical range, but - // then there would be no "dynamical room" for other sounds :-/ - - leftvol = vol - ((vol*sep*sep) >> 16); ///(256*256); - sep = 255 - sep; - rightvol = vol - ((vol*sep*sep) >> 16); - - // Sanity check, clamp volume. - if (rightvol < 0) - rightvol = 0; - else if (rightvol > 127) - rightvol = 127; - if (leftvol < 0) - leftvol = 0; - else if (leftvol > 127) - leftvol = 127; - - // Get the proper lookup table piece - // for this volume level - c->leftvol_lookup = &vol_lookup[leftvol*256]; - c->rightvol_lookup = &vol_lookup[rightvol*256]; -} - -static INT32 FindChannel(INT32 handle) -{ - INT32 i; - - for (i = 0; i < NUM_CHANNELS; i++) - if (channels[i].handle == handle) - return i; - - // not found - return -1; -} - -// -// This function adds a sound to the -// list of currently active sounds, -// which is maintained as a given number -// (eight, usually) of internal channels. -// Returns a handle. -// -static INT32 addsfx(sfxenum_t sfxid, INT32 volume, INT32 step, INT32 seperation) -{ - static UINT16 handlenums = 0; - INT32 i, slot, oldestnum = 0; - tic_t oldest = gametic; - - // Play these sound effects only one at a time. -#if 1 - if ( -#if 0 - sfxid == sfx_stnmov || sfxid == sfx_sawup || sfxid == sfx_sawidl || sfxid == sfx_sawful || sfxid == sfx_sawhit || sfxid == sfx_pistol -#else - ( sfx_litng1 <= sfxid && sfxid >= sfx_litng4 ) - || sfxid == sfx_trfire || sfxid == sfx_alarm || sfxid == sfx_spin - || sfxid == sfx_athun1 || sfxid == sfx_athun2 || sfxid == sfx_rainin -#endif - ) - { - // Loop all channels, check. - for (i = 0; i < NUM_CHANNELS; i++) - { - // Active, and using the same SFX? - if ((channels[i].end) && (channels[i].sfxid == sfxid)) - { - // Reset. - channels[i].end = NULL; - // We are sure that iff, - // there will only be one. - break; - } - } - } -#endif - - // Loop all channels to find oldest SFX. - for (i = 0; (i < NUM_CHANNELS) && (channels[i].end); i++) - { - if (channels[i].starttic < oldest) - { - oldestnum = i; - oldest = channels[i].starttic; - } - } - - // Tales from the cryptic. - // If we found a channel, fine. - // If not, we simply overwrite the first one, 0. - // Probably only happens at startup. - if (i == NUM_CHANNELS) - slot = oldestnum; - else - slot = i; - - channels[slot].end = NULL; - // Okay, in the less recent channel, - // we will handle the new SFX. - // Set pointer to raw data. - channels[slot].data = (Uint8 *)S_sfx[sfxid].data; - channels[slot].samplerate = (channels[slot].data[3]<<8)+channels[slot].data[2]; - channels[slot].data += 8; //Alam: offset of the sound header - - while (FindChannel(handlenums)!=-1) - { - handlenums++; - // Reset current handle number, limited to 0..65535. - if (handlenums == UINT16_MAX) - handlenums = 0; - } - - // Assign current handle number. - // Preserved so sounds could be stopped. - channels[slot].handle = handlenums; - - // Restart steper - channels[slot].stepremainder = 0; - // Should be gametic, I presume. - channels[slot].starttic = gametic; - - I_SetChannelParams(&channels[slot], volume, seperation, step); - - // Preserve sound SFX id, - // e.g. for avoiding duplicates of chainsaw. - channels[slot].id = S_sfx[sfxid].data; - - channels[slot].sfxid = sfxid; - - // Set pointer to end of raw data. - channels[slot].end = channels[slot].data + S_sfx[sfxid].length; - - - // You tell me. - return handlenums; -} - -// -// SFX API -// Note: this was called by S_Init. -// However, whatever they did in the -// old DPMS based DOS version, this -// were simply dummies in the Linux -// version. -// See soundserver initdata(). -// -// Well... To keep compatibility with legacy doom, I have to call this in -// I_InitSound since it is not called in S_Init... (emanne@absysteme.fr) - -static inline void I_SetChannels(void) -{ - // Init internal lookups (raw data, mixing buffer, channels). - // This function sets up internal lookups used during - // the mixing process. - INT32 i; - INT32 j; - - INT32 *steptablemid = steptable + 128; - - if (nosound) - return; - - // This table provides step widths for pitch parameters. - for (i = -128; i < 128; i++) - { - const double po = pow((double)(2.0l), (double)(i / 64.0l)); - steptablemid[i] = (INT32)(po * 65536.0l); - } - - // Generates volume lookup tables - // which also turn the unsigned samples - // into signed samples. - for (i = 0; i < 128; i++) - for (j = 0; j < 256; j++) - { - //From PrDoom - // proff - made this a little bit softer, because with - // full volume the sound clipped badly - vol_lookup[i * 256 + j] = (Sint16)((i * (j - 128) * 256) / 127); - } -} - -void I_SetSfxVolume(UINT8 volume) -{ - INT32 i; - - (void)volume; - //Snd_LockAudio(); - - for (i = 0; i < NUM_CHANNELS; i++) - if (channels[i].end) I_SetChannelParams(&channels[i], channels[i].vol, channels[i].sep, channels[i].realstep); - - //Snd_UnlockAudio(); -} - -void *I_GetSfx(sfxinfo_t *sfx) -{ - if (sfx->lumpnum == LUMPERROR) - sfx->lumpnum = S_GetSfxLumpNum(sfx); -// else if (sfx->lumpnum != S_GetSfxLumpNum(sfx)) -// I_FreeSfx(sfx); - -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - return HW3S_GetSfx(sfx); -#endif - - if (sfx->data) - return sfx->data; //Alam: I have it done! - - sfx->length = W_LumpLength(sfx->lumpnum); - - return getsfx(sfx->lumpnum, &sfx->length); - -} - -void I_FreeSfx(sfxinfo_t * sfx) -{ -// if (sfx->lumpnum<0) -// return; - -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - { - HW3S_FreeSfx(sfx); - } - else -#endif - { - size_t i; - - for (i = 1; i < NUMSFX; i++) - { - // Alias? Example is the chaingun sound linked to pistol. - if (S_sfx[i].data == sfx->data) - { - if (S_sfx+i != sfx) S_sfx[i].data = NULL; - S_sfx[i].lumpnum = LUMPERROR; - S_sfx[i].length = 0; - } - } - //Snd_LockAudio(); //Alam: too much? - // Loop all channels, check. - for (i = 0; i < NUM_CHANNELS; i++) - { - // Active, and using the same SFX? - if (channels[i].end && channels[i].id == sfx->data) - { - channels[i].end = NULL; // Reset. - } - } - //Snd_UnlockAudio(); //Alam: too much? - Z_Free(sfx->data); - } - sfx->data = NULL; - sfx->lumpnum = LUMPERROR; -} - -// -// Starting a sound means adding it -// to the current list of active sounds -// in the internal channels. -// As the SFX info struct contains -// e.g. a pointer to the raw data, -// it is ignored. -// As our sound handling does not handle -// priority, it is ignored. -// Pitching (that is, increased speed of playback) -// is set, but currently not used by mixing. -// -INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel) -{ - (void)priority; - (void)pitch; - (void)channel; - - if (nosound) - return 0; - - if (S_sfx[id].data == NULL) return -1; - - Snd_LockAudio(); - id = addsfx(id, vol, steptable[pitch], sep); - Snd_UnlockAudio(); - - return id; // Returns a handle (not used). -} - -void I_StopSound(INT32 handle) -{ - // You need the handle returned by StartSound. - // Would be looping all channels, - // tracking down the handle, - // an setting the channel to zero. - INT32 i; - - i = FindChannel(handle); - - if (i != -1) - { - //Snd_LockAudio(); //Alam: too much? - channels[i].end = NULL; - //Snd_UnlockAudio(); //Alam: too much? - channels[i].handle = -1; - channels[i].starttic = 0; - } - -} - -boolean I_SoundIsPlaying(INT32 handle) -{ - boolean isplaying = false; - int chan = FindChannel(handle); - if (chan != -1) - isplaying = (channels[chan].end != NULL); - return isplaying; -} - -FUNCINLINE static ATTRINLINE void I_UpdateStream8S(Uint8 *stream, int len) -{ - // Mix current sound data. - // Data, from raw sound - register Sint16 dr; // Right 8bit stream - register Uint8 sample; // Center 8bit sfx - register Sint16 dl; // Left 8bit stream - - // Pointers in audio stream - Sint8 *rightout = (Sint8 *)stream; // currect right - Sint8 *leftout = rightout + 1;// currect left - const Uint8 step = 2; // Step in stream, left and right, thus two. - - INT32 chan; // Mixing channel index. - - // Determine end of the stream - len /= 2; // not 8bit mono samples, 8bit stereo ones - - if (Snd_Mutex) SDL_LockMutex(Snd_Mutex); - - // Mix sounds into the mixing buffer. - // Loop over len - while (len--) - { - // Reset left/right value. - dl = *leftout; - dr = *rightout; - - // Love thy L2 cache - made this a loop. - // Now more channels could be set at compile time - // as well. Thus loop those channels. - for (chan = 0; chan < NUM_CHANNELS; chan++) - { - // Check channel, if active. - if (channels[chan].end) - { -#if 1 - // Get the raw data from the channel. - sample = channels[chan].data[0]; -#else - // linear filtering from PrDoom - sample = (((Uint32)channels[chan].data[0] *(0x10000 - channels[chan].stepremainder)) - + ((Uint32)channels[chan].data[1]) * (channels[chan].stepremainder))) >> 16; -#endif - // Add left and right part - // for this channel (sound) - // to the current data. - // Adjust volume accordingly. - dl = (Sint16)(dl+(channels[chan].leftvol_lookup[sample]>>8)); - dr = (Sint16)(dr+(channels[chan].rightvol_lookup[sample]>>8)); - // Increment stepage - channels[chan].stepremainder += channels[chan].step; - // Check whether we are done. - if (channels[chan].data + (channels[chan].stepremainder >> 16) >= channels[chan].end) - channels[chan].end = NULL; - else - { - // step to next sample - channels[chan].data += (channels[chan].stepremainder >> 16); - // Limit to LSB??? - channels[chan].stepremainder &= 0xffff; - } - } - } - - // Clamp to range. Left hardware channel. - // Has been char instead of short. - - if (dl > 0x7f) - *leftout = 0x7f; - else if (dl < -0x80) - *leftout = -0x80; - else - *leftout = (Sint8)dl; - - // Same for right hardware channel. - if (dr > 0x7f) - *rightout = 0x7f; - else if (dr < -0x80) - *rightout = -0x80; - else - *rightout = (Sint8)dr; - - // Increment current pointers in stream - leftout += step; - rightout += step; - - } - if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); -} - -FUNCINLINE static ATTRINLINE void I_UpdateStream8M(Uint8 *stream, int len) -{ - // Mix current sound data. - // Data, from raw sound - register Sint16 d; // Mono 8bit stream - register Uint8 sample; // Center 8bit sfx - - // Pointers in audio stream - Sint8 *monoout = (Sint8 *)stream; // currect mono - const Uint8 step = 1; // Step in stream, left and right, thus two. - - INT32 chan; // Mixing channel index. - - // Determine end of the stream - //len /= 1; // not 8bit mono samples, 8bit mono ones? - - if (Snd_Mutex) SDL_LockMutex(Snd_Mutex); - - // Mix sounds into the mixing buffer. - // Loop over len - while (len--) - { - // Reset left/right value. - d = *monoout; - - // Love thy L2 cache - made this a loop. - // Now more channels could be set at compile time - // as well. Thus loop those channels. - for (chan = 0; chan < NUM_CHANNELS; chan++) - { - // Check channel, if active. - if (channels[chan].end) - { -#if 1 - // Get the raw data from the channel. - sample = channels[chan].data[0]; -#else - // linear filtering from PrDoom - sample = (((Uint32)channels[chan].data[0] *(0x10000 - channels[chan].stepremainder)) - + ((Uint32)channels[chan].data[1]) * (channels[chan].stepremainder))) >> 16; -#endif - // Add left and right part - // for this channel (sound) - // to the current data. - // Adjust volume accordingly. - d = (Sint16)(d+((channels[chan].leftvol_lookup[sample] + channels[chan].rightvol_lookup[sample])>>9)); - // Increment stepage - channels[chan].stepremainder += channels[chan].step; - // Check whether we are done. - if (channels[chan].data + (channels[chan].stepremainder >> 16) >= channels[chan].end) - channels[chan].end = NULL; - else - { - // step to next sample - channels[chan].data += (channels[chan].stepremainder >> 16); - // Limit to LSB??? - channels[chan].stepremainder &= 0xffff; - } - } - } - - // Clamp to range. Left hardware channel. - // Has been char instead of short. - - if (d > 0x7f) - *monoout = 0x7f; - else if (d < -0x80) - *monoout = -0x80; - else - *monoout = (Sint8)d; - - // Increment current pointers in stream - monoout += step; - } - if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); -} - -FUNCINLINE static ATTRINLINE void I_UpdateStream16S(Uint8 *stream, int len) -{ - // Mix current sound data. - // Data, from raw sound - register Sint32 dr; // Right 16bit stream - register Uint8 sample; // Center 8bit sfx - register Sint32 dl; // Left 16bit stream - - // Pointers in audio stream - Sint16 *rightout = (Sint16 *)(void *)stream; // currect right - Sint16 *leftout = rightout + 1;// currect left - const Uint8 step = 2; // Step in stream, left and right, thus two. - - INT32 chan; // Mixing channel index. - - // Determine end of the stream - len /= 4; // not 8bit mono samples, 16bit stereo ones - - if (Snd_Mutex) SDL_LockMutex(Snd_Mutex); - - // Mix sounds into the mixing buffer. - // Loop over len - while (len--) - { - // Reset left/right value. - dl = *leftout; - dr = *rightout; - - // Love thy L2 cache - made this a loop. - // Now more channels could be set at compile time - // as well. Thus loop those channels. - for (chan = 0; chan < NUM_CHANNELS; chan++) - { - // Check channel, if active. - if (channels[chan].end) - { -#if 1 - // Get the raw data from the channel. - sample = channels[chan].data[0]; -#else - // linear filtering from PrDoom - sample = (((Uint32)channels[chan].data[0] *(0x10000 - channels[chan].stepremainder)) - + ((Uint32)channels[chan].data[1]) * (channels[chan].stepremainder))) >> 16; -#endif - // Add left and right part - // for this channel (sound) - // to the current data. - // Adjust volume accordingly. - dl += channels[chan].leftvol_lookup[sample]; - dr += channels[chan].rightvol_lookup[sample]; - // Increment stepage - channels[chan].stepremainder += channels[chan].step; - // Check whether we are done. - if (channels[chan].data + (channels[chan].stepremainder >> 16) >= channels[chan].end) - channels[chan].end = NULL; - else - { - // step to next sample - channels[chan].data += (channels[chan].stepremainder >> 16); - // Limit to LSB??? - channels[chan].stepremainder &= 0xffff; - } - } - } - - // Clamp to range. Left hardware channel. - // Has been char instead of short. - - if (dl > 0x7fff) - *leftout = 0x7fff; - else if (dl < -0x8000) - *leftout = -0x8000; - else - *leftout = (Sint16)dl; - - // Same for right hardware channel. - if (dr > 0x7fff) - *rightout = 0x7fff; - else if (dr < -0x8000) - *rightout = -0x8000; - else - *rightout = (Sint16)dr; - - // Increment current pointers in stream - leftout += step; - rightout += step; - - } - if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); -} - -FUNCINLINE static ATTRINLINE void I_UpdateStream16M(Uint8 *stream, int len) -{ - // Mix current sound data. - // Data, from raw sound - register Sint32 d; // Mono 16bit stream - register Uint8 sample; // Center 8bit sfx - - // Pointers in audio stream - Sint16 *monoout = (Sint16 *)(void *)stream; // currect mono - const Uint8 step = 1; // Step in stream, left and right, thus two. - - INT32 chan; // Mixing channel index. - - // Determine end of the stream - len /= 2; // not 8bit mono samples, 16bit mono ones - - if (Snd_Mutex) SDL_LockMutex(Snd_Mutex); - - // Mix sounds into the mixing buffer. - // Loop over len - while (len--) - { - // Reset left/right value. - d = *monoout; - - // Love thy L2 cache - made this a loop. - // Now more channels could be set at compile time - // as well. Thus loop those channels. - for (chan = 0; chan < NUM_CHANNELS; chan++) - { - // Check channel, if active. - if (channels[chan].end) - { -#if 1 - // Get the raw data from the channel. - sample = channels[chan].data[0]; -#else - // linear filtering from PrDoom - sample = (((Uint32)channels[chan].data[0] *(0x10000 - channels[chan].stepremainder)) - + ((Uint32)channels[chan].data[1]) * (channels[chan].stepremainder))) >> 16; -#endif - // Add left and right part - // for this channel (sound) - // to the current data. - // Adjust volume accordingly. - d += (channels[chan].leftvol_lookup[sample] + channels[chan].rightvol_lookup[sample])>>1; - // Increment stepage - channels[chan].stepremainder += channels[chan].step; - // Check whether we are done. - if (channels[chan].data + (channels[chan].stepremainder >> 16) >= channels[chan].end) - channels[chan].end = NULL; - else - { - // step to next sample - channels[chan].data += (channels[chan].stepremainder >> 16); - // Limit to LSB??? - channels[chan].stepremainder &= 0xffff; - } - } - } - - // Clamp to range. Left hardware channel. - // Has been char instead of short. - - if (d > 0x7fff) - *monoout = 0x7fff; - else if (d < -0x8000) - *monoout = -0x8000; - else - *monoout = (Sint16)d; - - // Increment current pointers in stream - monoout += step; - } - if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); -} - -#ifdef HAVE_LIBGME -static void I_UpdateSteamGME(Music_Emu *emu, INT16 *stream, int len, UINT8 looping) -{ - #define GME_BUFFER_LEN 44100*2048 - // Mix current sound data. - // Data, from raw sound - register Sint32 da; - - static short gme_buffer[GME_BUFFER_LEN]; // a large buffer for gme - Sint16 *in = gme_buffer; - - do - { - int out = min(GME_BUFFER_LEN, len); - if ( gme_play( emu, len, gme_buffer ) ) { } // ignore error - len -= out; - while (out--) - { - //Left - da = *in; - in++; - da += *stream; - stream++; - //Right - da = *in; - in++; - da += *stream; - stream++; - } - if (gme_track_ended( emu )) - { - if (looping) - gme_seek( emu, 0); - else - break; - } - } while ( len ); - #undef GME_BUFFER_LEN -} -#endif - -static void SDLCALL I_UpdateStream(void *userdata, Uint8 *stream, int len) -{ - if (!sound_started || !userdata) - return; - -#if SDL_VERSION_ATLEAST(1,3,0) - if (musicStarted) - memset(stream, 0x00, len); // only work in !AUDIO_U8, that needs 0x80 -#endif - - if ((audio.channels != 1 && audio.channels != 2) || - (audio.format != AUDIO_S8 && audio.format != AUDIO_S16SYS)) - ; // no function to encode this type of stream - else if (audio.channels == 1 && audio.format == AUDIO_S8) - I_UpdateStream8M(stream, len); - else if (audio.channels == 2 && audio.format == AUDIO_S8) - I_UpdateStream8S(stream, len); - else if (audio.channels == 1 && audio.format == AUDIO_S16SYS) - I_UpdateStream16M(stream, len); - else if (audio.channels == 2 && audio.format == AUDIO_S16SYS) - { - I_UpdateStream16S(stream, len); -#ifdef HAVE_LIBGME - if (userdata) - { - srb2audio_t *sa_userdata = userdata; - if (!sa_userdata->gme_pause) - I_UpdateSteamGME(sa_userdata->gme_emu, (INT16 *)stream, len/4, sa_userdata->gme_loop); - } -#endif - - } -} - -void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch) -{ - // Would be using the handle to identify - // on which channel the sound might be active, - // and resetting the channel parameters. - - INT32 i = FindChannel(handle); - - if (i != -1 && channels[i].end) - { - //Snd_LockAudio(); //Alam: too much? - I_SetChannelParams(&channels[i], vol, sep, steptable[pitch]); - //Snd_UnlockAudio(); //Alam: too much? - } - -} - -#ifdef HW3SOUND - -static void *soundso = NULL; - -static INT32 Init3DSDriver(const char *soName) -{ - if (soName) soundso = hwOpen(soName); -#if defined (_WIN32) && defined (_X86_) && !defined (STATIC3DS) - HW3DS.pfnStartup = hwSym("Startup@8",soundso); - HW3DS.pfnShutdown = hwSym("Shutdown@0",soundso); - HW3DS.pfnAddSfx = hwSym("AddSfx@4",soundso); - HW3DS.pfnAddSource = hwSym("AddSource@8",soundso); - HW3DS.pfnStartSource = hwSym("StartSource@4",soundso); - HW3DS.pfnStopSource = hwSym("StopSource@4",soundso); - HW3DS.pfnGetHW3DSVersion = hwSym("GetHW3DSVersion@0",soundso); - HW3DS.pfnBeginFrameUpdate = hwSym("BeginFrameUpdate@0",soundso); - HW3DS.pfnEndFrameUpdate = hwSym("EndFrameUpdate@0",soundso); - HW3DS.pfnIsPlaying = hwSym("IsPlaying@4",soundso); - HW3DS.pfnUpdateListener = hwSym("UpdateListener@8",soundso); - HW3DS.pfnUpdateSourceParms = hwSym("UpdateSourceParms@12",soundso); - HW3DS.pfnSetCone = hwSym("SetCone@8",soundso); - HW3DS.pfnSetGlobalSfxVolume = hwSym("SetGlobalSfxVolume@4",soundso); - HW3DS.pfnUpdate3DSource = hwSym("Update3DSource@8",soundso); - HW3DS.pfnReloadSource = hwSym("ReloadSource@8",soundso); - HW3DS.pfnKillSource = hwSym("KillSource@4",soundso); - HW3DS.pfnKillSfx = hwSym("KillSfx@4",soundso); - HW3DS.pfnGetHW3DSTitle = hwSym("GetHW3DSTitle@8",soundso); -#else - HW3DS.pfnStartup = hwSym("Startup",soundso); - HW3DS.pfnShutdown = hwSym("Shutdown",soundso); - HW3DS.pfnAddSfx = hwSym("AddSfx",soundso); - HW3DS.pfnAddSource = hwSym("AddSource",soundso); - HW3DS.pfnStartSource = hwSym("StartSource",soundso); - HW3DS.pfnStopSource = hwSym("StopSource",soundso); - HW3DS.pfnGetHW3DSVersion = hwSym("GetHW3DSVersion",soundso); - HW3DS.pfnBeginFrameUpdate = hwSym("BeginFrameUpdate",soundso); - HW3DS.pfnEndFrameUpdate = hwSym("EndFrameUpdate",soundso); - HW3DS.pfnIsPlaying = hwSym("IsPlaying",soundso); - HW3DS.pfnUpdateListener = hwSym("UpdateListener",soundso); - HW3DS.pfnUpdateSourceParms = hwSym("UpdateSourceParms",soundso); - HW3DS.pfnSetCone = hwSym("SetCone",soundso); - HW3DS.pfnSetGlobalSfxVolume = hwSym("SetGlobalSfxVolume",soundso); - HW3DS.pfnUpdate3DSource = hwSym("Update3DSource",soundso); - HW3DS.pfnReloadSource = hwSym("ReloadSource",soundso); - HW3DS.pfnKillSource = hwSym("KillSource",soundso); - HW3DS.pfnKillSfx = hwSym("KillSfx",soundso); - HW3DS.pfnGetHW3DSTitle = hwSym("GetHW3DSTitle",soundso); -#endif - -// if (HW3DS.pfnUpdateListener2 && HW3DS.pfnUpdateListener2 != soundso) - return true; -// else -// return false; -} -#endif - -void I_ShutdownSound(void) -{ - if (nosound || !sound_started) - return; - - CONS_Printf("I_ShutdownSound: "); - -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - { - HW3S_Shutdown(); - hwClose(soundso); - return; - } -#endif - - if (nomidimusic && nodigimusic) - SDL_CloseAudio(); - CONS_Printf("%s", M_GetText("shut down\n")); - sound_started = false; - SDL_QuitSubSystem(SDL_INIT_AUDIO); - if (Snd_Mutex) - SDL_DestroyMutex(Snd_Mutex); - Snd_Mutex = NULL; -} - -void I_UpdateSound(void) -{ -} - -void I_StartupSound(void) -{ -#ifdef HW3SOUND - const char *sdrv_name = NULL; -#endif -#ifndef HAVE_MIXER - nomidimusic = nodigimusic = true; -#endif -#ifdef DC - //nosound = true; -#ifdef HAVE_MIXER - nomidimusic = true; - nodigimusic = true; -#endif -#endif - - memset(channels, 0, sizeof (channels)); //Alam: Clean it - - audio.format = AUDIO_S16SYS; - audio.channels = 2; - audio.callback = I_UpdateStream; - audio.userdata = &localdata; - - if (dedicated) - { - nosound = nomidimusic = nodigimusic = true; - return; - } - - // Configure sound device - CONS_Printf("I_StartupSound:\n"); - - // Open the audio device - if (M_CheckParm ("-freq") && M_IsNextParm()) - { - audio.freq = atoi(M_GetNextParm()); - if (!audio.freq) audio.freq = cv_samplerate.value; - audio.samples = (Uint16)((samplecount/2)*(INT32)(audio.freq/11025)); //Alam: to keep it around the same XX ms - CONS_Printf (M_GetText(" requested frequency of %d hz\n"), audio.freq); - } - else - { - audio.samples = samplecount; - audio.freq = cv_samplerate.value; - } - - if (M_CheckParm ("-mono")) - { - audio.channels = 1; - audio.samples /= 2; - } - -#if defined (_PSP) && defined (HAVE_MIXER) // Bug in PSP's SDL_OpenAudio, can not open twice - I_SetChannels(); - sound_started = true; - Snd_Mutex = SDL_CreateMutex(); -#else - if (nosound) -#endif - return; - -#ifdef HW3SOUND -#ifdef STATIC3DS - if (M_CheckParm("-3dsound") || M_CheckParm("-ds3d")) - { - hws_mode = HWS_OPENAL; - } -#elif defined (_WIN32) - if (M_CheckParm("-ds3d")) - { - hws_mode = HWS_DS3D; - sdrv_name = "s_ds3d.dll"; - } - else if (M_CheckParm("-fmod3d")) - { - hws_mode = HWS_FMOD3D; - sdrv_name = "s_fmod.dll"; - } - else if (M_CheckParm("-openal")) - { - hws_mode = HWS_OPENAL; - sdrv_name = "s_openal.dll"; - } -#else - if (M_CheckParm("-fmod3d")) - { - hws_mode = HWS_FMOD3D; - sdrv_name = "./s_fmod.so"; - } - else if (M_CheckParm("-openal")) - { - hws_mode = HWS_OPENAL; - sdrv_name = "./s_openal.so"; - } -#endif - else if (M_CheckParm("-sounddriver") && M_IsNextParm()) - { - hws_mode = HWS_OTHER; - sdrv_name = M_GetNextParm(); - } - if (hws_mode != HWS_DEFAULT_MODE) - { - if (Init3DSDriver(sdrv_name)) - { - snddev_t snddev; - - //nosound = true; - //I_AddExitFunc(I_ShutdownSound); - snddev.bps = 16; - snddev.sample_rate = audio.freq; - snddev.numsfxs = NUMSFX; -#if defined (_WIN32) && !defined (_XBOX) - snddev.cooplevel = 0x00000002; - snddev.hWnd = vid.WndParent; -#endif - if (HW3S_Init(I_Error, &snddev)) - { - audio.userdata = NULL; - CONS_Printf("%s", M_GetText(" Using 3D sound driver\n")); - return; - } - CONS_Printf("%s", M_GetText(" Failed loading 3D sound driver\n")); - // Falls back to default sound system - HW3S_Shutdown(); - hwClose(soundso); - } - CONS_Printf("%s", M_GetText(" Failed loading 3D sound driver\n")); - hws_mode = HWS_DEFAULT_MODE; - } -#endif - if (!musicStarted && SDL_OpenAudio(&audio, &audio) < 0) - { - CONS_Printf("%s", M_GetText(" couldn't open audio with desired format\n")); - nosound = true; - return; - } - else - { - char ad[100]; - CONS_Printf(M_GetText(" Starting up with audio driver : %s\n"), SDL_AudioDriverName(ad, (int)sizeof ad)); - } - samplecount = audio.samples; - CV_SetValue(&cv_samplerate, audio.freq); - CONS_Printf(M_GetText(" configured audio device with %d samples/slice at %ikhz(%dms buffer)\n"), samplecount, audio.freq/1000, (INT32) (((float)audio.samples * 1000.0f) / audio.freq)); - // Finished initialization. - CONS_Printf("%s", M_GetText(" Sound module ready\n")); - //[segabor] - if (!musicStarted) SDL_PauseAudio(0); - //Mix_Pause(0); - I_SetChannels(); - sound_started = true; - Snd_Mutex = SDL_CreateMutex(); -} - -// -// MUSIC API. -// - -void I_ShutdownMIDIMusic(void) -{ - nomidimusic = false; - if (nodigimusic) I_ShutdownMusic(); -} - -#ifdef HAVE_LIBGME -static void I_ShutdownGMEMusic(void) -{ - Snd_LockAudio(); - if (localdata.gme_emu) - gme_delete(localdata.gme_emu); - localdata.gme_emu = NULL; - Snd_UnlockAudio(); -} -#endif - -void I_ShutdownDigMusic(void) -{ - nodigimusic = false; - if (nomidimusic) I_ShutdownMusic(); -} - -#ifdef HAVE_MIXER -static boolean LoadSong(void *data, size_t lumplength, size_t selectpos) -{ - FILE *midfile; - const char *tempname; -#ifdef USE_RWOPS - if (canuseRW) - { - SDL_RWops *SDLRW; - void *olddata = Smidi[selectpos]; //quick shortcut to set - - Z_Free(olddata); //free old memory - Smidi[selectpos] = NULL; - - if (!data) - return olddata != NULL; //was there old data? - - SDLRW = SDL_RWFromConstMem(data, (int)lumplength); //new RWops from Z_zone - if (!SDLRW) //ERROR while making RWops! - { - CONS_Printf(M_GetText("Couldn't load music lump: %s\n"), SDL_GetError()); - Z_Free(data); - return false; - } - - music[selectpos] = Mix_LoadMUS_RW(SDLRW); // new Mix_Chuck from RWops - if (music[selectpos]) - Smidi[selectpos] = data; //all done - else //ERROR while making Mix_Chuck - { - CONS_Printf(M_GetText("Couldn't load music data: %s\n"), Mix_GetError()); - Z_Free(data); - SDL_RWclose(SDLRW); - Smidi[selectpos] = NULL; - } - return true; - } -#endif - tempname = va("%s/%s", MIDI_PATH, fmidi[selectpos]); - - if (!data) - { - if (FIL_FileExists(tempname)) - return unlink(tempname)+1; -#ifdef MIDI_PATH2 - else if (FIL_FileExists(tempname = va("%s/%s", MIDI_PATH2, fmidi[selectpos]))) - return unlink(tempname)+1; -#endif - else - return false; - } - - midfile = fopen(tempname, "wb"); - -#ifdef MIDI_PATH2 - if (!midfile) - { - tempname = va("%s/%s", MIDI_PATH2, fmidi[selectpos]); - midfile = fopen(tempname, "wb"); - } -#endif - - if (!midfile) - { - CONS_Printf(M_GetText("Couldn't open file %s to write music in\n"), tempname); - Z_Free(data); - return false; - } - - if (fwrite(data, lumplength, 1, midfile) == 0) - { - CONS_Printf(M_GetText("Couldn't write music into file %s because %s\n"), tempname, strerror(ferror(midfile))); - Z_Free(data); - fclose(midfile); - return false; - } - - fclose(midfile); - - Z_Free(data); - - music[selectpos] = Mix_LoadMUS(tempname); - if (!music[selectpos]) //ERROR while making Mix_Chuck - { - CONS_Printf(M_GetText("Couldn't load music file %s: %s\n"), tempname, Mix_GetError()); - return false; - } - return true; -} -#endif - - -void I_ShutdownMusic(void) -{ -#ifdef HAVE_MIXER - if ((nomidimusic && nodigimusic) || !musicStarted) - return; - - CONS_Printf("%s", M_GetText("I_ShutdownMusic: ")); - - I_UnRegisterSong(0); - I_StopDigSong(); - Mix_CloseAudio(); -#ifdef MIX_INIT - Mix_Quit(); -#endif - CONS_Printf("%s", M_GetText("shut down\n")); - musicStarted = SDL_FALSE; - if (Msc_Mutex) - SDL_DestroyMutex(Msc_Mutex); - Msc_Mutex = NULL; -#endif -} - -void I_InitMIDIMusic(void) -{ - if (nodigimusic) I_InitMusic(); -} - -void I_InitDigMusic(void) -{ - if (nomidimusic) I_InitMusic(); -} - -void I_InitMusic(void) -{ -#ifdef HAVE_MIXER - char ad[100]; - SDL_version MIXcompiled; - const SDL_version *MIXlinked; -#ifdef MIXER_INIT - const int mixstart = MIX_INIT_OGG; - int mixflags; -#endif -#endif -#ifdef HAVE_LIBGME - I_AddExitFunc(I_ShutdownGMEMusic); -#endif - - if ((nomidimusic && nodigimusic) || dedicated) - return; - -#ifdef HAVE_MIXER - MIX_VERSION(&MIXcompiled) - MIXlinked = Mix_Linked_Version(); - I_OutputMsg("Compiled for SDL_mixer version: %d.%d.%d\n", - MIXcompiled.major, MIXcompiled.minor, MIXcompiled.patch); -#ifdef MIXER_POS -#ifndef _WII - if (MIXlinked->major == 1 && MIXlinked->minor == 2 && MIXlinked->patch < 7) -#endif - canlooping = SDL_FALSE; -#endif -#ifdef USE_RWOPS - if (M_CheckParm("-noRW")) - canuseRW = SDL_FALSE; -#endif - I_OutputMsg("Linked with SDL_mixer version: %d.%d.%d\n", - MIXlinked->major, MIXlinked->minor, MIXlinked->patch); -#if !(defined (DC) || defined (PSP) || defined(GP2X) || defined (WII)) - if (audio.freq < 44100 && !M_CheckParm ("-freq")) //I want atleast 44Khz - { - audio.samples = (Uint16)(audio.samples*(INT32)(44100/audio.freq)); - audio.freq = 44100; //Alam: to keep it around the same XX ms - } -#endif - - if (sound_started -#ifdef HW3SOUND - && hws_mode == HWS_DEFAULT_MODE -#endif - ) - { - I_OutputMsg("Temp Shutdown of SDL Audio System"); - SDL_CloseAudio(); - I_OutputMsg(" Done\n"); - } - - CONS_Printf("%s", M_GetText("I_InitMusic:")); - -#ifdef MIXER_INIT - mixflags = Mix_Init(mixstart); - if ((mixstart & MIX_INIT_FLAC) != (mixflags & MIX_INIT_FLAC)) - { - CONS_Printf("%s", M_GetText(" Unable to load FLAC support\n")); - } - if ((mixstart & MIX_INIT_MOD ) != (mixflags & MIX_INIT_MOD )) - { - CONS_Printf("%s", M_GetText(" Unable to load MOD support\n")); - } - if ((mixstart & MIX_INIT_MP3 ) != (mixflags & MIX_INIT_MP3 )) - { - CONS_Printf("%s", M_GetText(" Unable to load MP3 support\n")); - } - if ((mixstart & MIX_INIT_OGG ) != (mixflags & MIX_INIT_OGG )) - { - CONS_Printf("%s", M_GetText(" Unable to load OGG support\n")); - } -#endif - - if (Mix_OpenAudio(audio.freq, audio.format, audio.channels, audio.samples) < 0) //open_music(&audio) - { - CONS_Printf(M_GetText(" Unable to open music: %s\n"), Mix_GetError()); - nomidimusic = nodigimusic = true; - if (sound_started -#ifdef HW3SOUND - && hws_mode == HWS_DEFAULT_MODE -#endif - ) - { - if (SDL_OpenAudio(&audio, NULL) < 0) //retry - { - CONS_Printf("%s", M_GetText(" couldn't open audio with desired format\n")); - nosound = true; - sound_started = false; - } - else - { - CONS_Printf(M_GetText(" Starting with audio driver : %s\n"), SDL_AudioDriverName(ad, (int)sizeof ad)); - } - } - return; - } - else - CONS_Printf(M_GetText(" Starting up with audio driver : %s with SDL_Mixer\n"), SDL_AudioDriverName(ad, (int)sizeof ad)); - - samplecount = audio.samples; - CV_SetValue(&cv_samplerate, audio.freq); - if (sound_started -#ifdef HW3SOUND - && hws_mode == HWS_DEFAULT_MODE -#endif - ) - I_OutputMsg(" Reconfigured SDL Audio System"); - else I_OutputMsg(" Configured SDL_Mixer System"); - I_OutputMsg(" with %d samples/slice at %ikhz(%dms buffer)\n", samplecount, audio.freq/1000, (INT32) ((audio.samples * 1000.0f) / audio.freq)); - Mix_SetPostMix(audio.callback, audio.userdata); // after mixing music, add sound effects - Mix_Resume(-1); - CONS_Printf("%s", M_GetText("Music initialized\n")); - musicStarted = SDL_TRUE; - Msc_Mutex = SDL_CreateMutex(); -#endif -} - -boolean I_PlaySong(INT32 handle, boolean looping) -{ - (void)handle; -#ifdef HAVE_MIXER - if (nomidimusic || !musicStarted || !music[handle]) - return false; - -#ifdef MIXER_POS - if (canlooping) - Mix_HookMusicFinished(NULL); -#endif - - if (Mix_FadeInMusic(music[handle], looping ? -1 : 0, MIDIfade) == -1) - CONS_Printf(M_GetText("Couldn't play song because %s\n"), Mix_GetError()); - else - { - Mix_VolumeMusic(musicvol); - return true; - } -#else - (void)looping; -#endif - return false; -} - -static void I_PauseGME(void) -{ -#ifdef HAVE_LIBGME - localdata.gme_pause = true; -#endif -} - -void I_PauseSong(INT32 handle) -{ - (void)handle; - I_PauseGME(); -#ifdef HAVE_MIXER - if ((nomidimusic && nodigimusic) || !musicStarted) - return; - - Mix_PauseMusic(); - //I_StopSong(handle); -#endif -} - -static void I_ResumeGME(void) -{ -#ifdef HAVE_LIBGME - localdata.gme_pause = false; -#endif -} - -void I_ResumeSong(INT32 handle) -{ - (void)handle; - I_ResumeGME(); -#ifdef HAVE_MIXER - if ((nomidimusic && nodigimusic) || !musicStarted) - return; - - Mix_VolumeMusic(musicvol); - Mix_ResumeMusic(); - //I_PlaySong(handle, true); -#endif -} - -void I_StopSong(INT32 handle) -{ - (void)handle; -#ifdef HAVE_MIXER - if (nomidimusic || !musicStarted) - return; - Mix_FadeOutMusic(MIDIfade); -#endif -} - -void I_UnRegisterSong(INT32 handle) -{ -#ifdef HAVE_MIXER - - if (nomidimusic || !musicStarted) - return; - - Mix_HaltMusic(); - while (Mix_PlayingMusic()) - ; - - if (music[handle]) - Mix_FreeMusic(music[handle]); - music[handle] = NULL; - LoadSong(NULL, 0, handle); -#else - (void)handle; -#endif -} - -INT32 I_RegisterSong(void *data, size_t len) -{ -#ifdef HAVE_MIXER - if (nomidimusic || !musicStarted) - return false; - - if (!LoadSong(data, len, 0)) - return false; - - if (music[0]) - return true; - - CONS_Printf(M_GetText("Couldn't load MIDI: %s\n"), Mix_GetError()); -#else - (void)len; - (void)data; -#endif - return false; -} - -void I_SetMIDIMusicVolume(UINT8 volume) -{ -#ifdef HAVE_MIXER - if ((nomidimusic && nodigimusic) || !musicStarted) - return; - - if (Msc_Mutex) SDL_LockMutex(Msc_Mutex); - musicvol = volume * 2; - if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex); - Mix_VolumeMusic(musicvol); -#else - (void)volume; -#endif -} - -#ifdef HAVE_LIBGME -static void I_CleanupGME(void *userdata) -{ - Z_Free(userdata); -} -#endif - -static boolean I_StartGMESong(const char *musicname, boolean looping) -{ -#ifdef HAVE_LIBGME - XBOXSTATIC char filename[9]; - void *data; - lumpnum_t lumpnum; - size_t lumplength; - Music_Emu *emu; - const char* gme_err; - - Snd_LockAudio(); - if (localdata.gme_emu) - gme_delete(localdata.gme_emu); - localdata.gme_emu = NULL; - Snd_UnlockAudio(); - - snprintf(filename, sizeof filename, "o_%s", musicname); - - lumpnum = W_CheckNumForName(filename); - - if (lumpnum == LUMPERROR) - { - return false; // No music found. Oh well! - } - else - lumplength = W_LumpLength(lumpnum); - - data = W_CacheLumpNum(lumpnum, PU_MUSIC); - - gme_err = gme_open_data(data, (long)lumplength, &emu, audio.freq); - if (gme_err != NULL) { - //I_OutputMsg("I_StartGMESong: error %s\n",gme_err); - return false; - } - gme_set_user_data(emu, data); - gme_set_user_cleanup(emu, I_CleanupGME); - gme_start_track(emu, 0); - gme_set_fade(emu, Digfade); - - Snd_LockAudio(); - localdata.gme_emu = emu; - localdata.gme_pause = false; - localdata.gme_loop = (UINT8)looping; - Snd_UnlockAudio(); - - return true; -#else - (void)musicname; - (void)looping; -#endif - return false; -} - -boolean I_StartDigSong(const char *musicname, boolean looping) -{ -#ifdef HAVE_MIXER - XBOXSTATIC char filename[9]; - void *data; - lumpnum_t lumpnum; - size_t lumplength; -#endif - - if(I_StartGMESong(musicname, looping)) - return true; - -#ifdef HAVE_MIXER - if (nodigimusic) - return false; - - snprintf(filename, sizeof filename, "o_%s", musicname); - - lumpnum = W_CheckNumForName(filename); - - I_StopDigSong(); - - if (lumpnum == LUMPERROR) - { - // Alam_GBC: like in win32/win_snd.c: Graue 02-29-2004: don't worry about missing music, there might still be a MIDI - //I_OutputMsg("Music lump %s not found!\n", filename); - return false; // No music found. Oh well! - } - else - lumplength = W_LumpLength(lumpnum); - - data = W_CacheLumpNum(lumpnum, PU_MUSIC); - - if (Msc_Mutex) SDL_LockMutex(Msc_Mutex); - -#ifdef MIXER_POS - if (canlooping && (loopingDig = looping) == SDL_TRUE && strcmp(data, "OggS") == 0) - looping = false; // Only on looping Ogg files, will we will do our own looping - - // Scan the Ogg Vorbis file for the COMMENT= field for a custom - // loop point - if (!looping && loopingDig) - { - size_t scan; - const char *dataum = data; - XBOXSTATIC char looplength[64]; - UINT32 loopstart = 0; - UINT8 newcount = 0; - - Mix_HookMusicFinished(I_FinishMusic); - - for (scan = 0; scan < lumplength; scan++) - { - if (*dataum++ == 'C'){ - if (*dataum++ == 'O'){ - if (*dataum++ == 'M'){ - if (*dataum++ == 'M'){ - if (*dataum++ == 'E'){ - if (*dataum++ == 'N'){ - if (*dataum++ == 'T'){ - if (*dataum++ == '='){ - if (*dataum++ == 'L'){ - if (*dataum++ == 'O'){ - if (*dataum++ == 'O'){ - if (*dataum++ == 'P'){ - if (*dataum++ == 'P'){ - if (*dataum++ == 'O'){ - if (*dataum++ == 'I'){ - if (*dataum++ == 'N'){ - if (*dataum++ == 'T'){ - if (*dataum++ == '=') - { - - while (*dataum != 1 && newcount != 63) - looplength[newcount++] = *dataum++; - - looplength[newcount] = '\0'; - - loopstart = atoi(looplength); - - } - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - } - - if (loopstart > 0) - { - loopstartDig = (double)((44.1l+loopstart) / 44100.0l); //8 PCM chucks off and PCM to secs -//#ifdef GP2X//#ifdef PARANOIA - //I_OutputMsg("I_StartDigSong: setting looping point to %ul PCMs(%f seconds)\n", loopstart, loopstartDig); -//#endif - } - else - { - looping = true; // loopingDig true, but couldn't find start loop point - } - } - else - loopstartDig = 0.0l; -#else - if (looping && strcmp(data, "OggS") == 0) - I_OutputMsg("I_StartDigSong: SRB2 was not compiled with looping music support(no Mix_FadeInMusicPos)\n"); -#endif - - if (!LoadSong(data, lumplength, 1)) - { - if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex); - return false; - } - - // Note: LoadSong() frees the data. Let's make sure - // we don't try to use the data again. - data = NULL; - - if (Mix_FadeInMusic(music[1], looping ? -1 : 0, Digfade) == -1) - { - if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex); - I_OutputMsg("I_StartDigSong: Couldn't play song %s because %s\n", musicname, Mix_GetError()); - return false; - } - Mix_VolumeMusic(musicvol); - - if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex); - return true; -#else - (void)looping; - (void)musicname; - return false; -#endif -} - -static void I_StopGME(void) -{ -#ifdef HAVE_LIBGME - Snd_LockAudio(); - gme_seek(localdata.gme_emu, 0); - Snd_UnlockAudio(); -#endif -} - -void I_StopDigSong(void) -{ - I_StopGME(); -#ifdef HAVE_MIXER - if (nodigimusic) - return; - -#ifdef MIXER_POS - if (canlooping) - Mix_HookMusicFinished(NULL); -#endif - - Mix_HaltMusic(); - while (Mix_PlayingMusic()) - ; - - if (music[1]) - Mix_FreeMusic(music[1]); - music[1] = NULL; - LoadSong(NULL, 0, 1); -#endif -} - -void I_SetDigMusicVolume(UINT8 volume) -{ - I_SetMIDIMusicVolume(volume); -} - -boolean I_SetSongSpeed(float speed) -{ - - (void)speed; - return false; -} - -boolean I_SetSongTrack(int track) -{ - (void)track; - return false; -} - -#ifdef MIXER_POS -static void SDLCALL I_FinishMusic(void) -{ - if (!music[1]) - return; - else if (Msc_Mutex) SDL_LockMutex(Msc_Mutex); -// I_OutputMsg("I_FinishMusic: Loopping song to %g seconds\n", loopstartDig); - - if (Mix_FadeInMusicPos(music[1], loopstartDig ? 0 : -1, Digfade, loopstartDig) == 0) - Mix_VolumeMusic(musicvol); - else - I_OutputMsg("I_FinishMusic: Couldn't loop song because %s\n", Mix_GetError()); - - if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex); -} -#endif -#endif //HAVE_SDL diff --git a/src/sdl12/sdlmain.h b/src/sdl12/sdlmain.h deleted file mode 100644 index d08236bdd39b9ad2283c128e2341f6136d5866fd..0000000000000000000000000000000000000000 --- a/src/sdl12/sdlmain.h +++ /dev/null @@ -1,65 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 2006-2018 by Sonic Team Jr. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief System specific interface stuff. - -#ifndef __sdlmain__ -#define __sdlmain__ - -extern SDL_bool consolevent; -extern SDL_bool framebuffer; - -/** \brief The JoyInfo_s struct - - info about joystick -*/ -typedef struct SDLJoyInfo_s -{ - /// Joystick handle - SDL_Joystick *dev; - /// number of old joystick - int oldjoy; - /// number of axies - int axises; - /// scale of axises - INT32 scale; - /// number of buttons - int buttons; - /// number of hats - int hats; - /// number of balls - int balls; - -} SDLJoyInfo_t; - -/** \brief SDL info about joystick 1 -*/ -extern SDLJoyInfo_t JoyInfo; - -/** \brief joystick axis deadzone -*/ -#define SDL_JDEADZONE 153 -#undef SDL_JDEADZONE - -/** \brief SDL inof about joystick 2 -*/ -extern SDLJoyInfo_t JoyInfo2; - -void I_GetConsoleEvents(void); - -void SDLforceUngrabMouse(void); - -#endif diff --git a/src/sdl12/srb2.ttf b/src/sdl12/srb2.ttf deleted file mode 100644 index 53f4c6a28a2adc0c97df4a7570ace24cf4949580..0000000000000000000000000000000000000000 Binary files a/src/sdl12/srb2.ttf and /dev/null differ diff --git a/src/sounds.c b/src/sounds.c index 47dc281781443604abd28c913d01b9c8c8182280..56de4a9c5bdbaf98bb5edba8cfc4c73fd2c5c542 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -32,439 +32,463 @@ sfxinfo_t S_sfx[NUMSFX] = various flags. See soundflags_t. *****/ // S_sfx[0] needs to be a dummy for odd reasons. (don't modify this comment) -// name, singularity, priority, pitch, volume, data, length, skinsound, usefulness, lumpnum - {"none" , false, 0, 0, -1, NULL, 0, -1, -1, LUMPERROR}, +// name, singularity, priority, pitch, volume, data, length, skinsound, usefulness, lumpnum, caption + {"none" , false, 0, 0, -1, NULL, 0, -1, -1, LUMPERROR, "///////////////////////////////"}, // maximum length // Skin Sounds - {"altdi1", false, 192, 16, -1, NULL, 0, SKSPLDET1, -1, LUMPERROR}, - {"altdi2", false, 192, 16, -1, NULL, 0, SKSPLDET2, -1, LUMPERROR}, - {"altdi3", false, 192, 16, -1, NULL, 0, SKSPLDET3, -1, LUMPERROR}, - {"altdi4", false, 192, 16, -1, NULL, 0, SKSPLDET4, -1, LUMPERROR}, - {"altow1", false, 192, 16, -1, NULL, 0, SKSPLPAN1, -1, LUMPERROR}, - {"altow2", false, 192, 16, -1, NULL, 0, SKSPLPAN2, -1, LUMPERROR}, - {"altow3", false, 192, 16, -1, NULL, 0, SKSPLPAN3, -1, LUMPERROR}, - {"altow4", false, 192, 16, -1, NULL, 0, SKSPLPAN4, -1, LUMPERROR}, - {"victr1", false, 64, 16, -1, NULL, 0, SKSPLVCT1, -1, LUMPERROR}, - {"victr2", false, 64, 16, -1, NULL, 0, SKSPLVCT2, -1, LUMPERROR}, - {"victr3", false, 64, 16, -1, NULL, 0, SKSPLVCT3, -1, LUMPERROR}, - {"victr4", false, 64, 16, -1, NULL, 0, SKSPLVCT4, -1, LUMPERROR}, - {"gasp" , false, 64, 0, -1, NULL, 0, SKSGASP, -1, LUMPERROR}, - {"jump" , false, 140, 0, -1, NULL, 0, SKSJUMP, -1, LUMPERROR}, - {"pudpud", false, 64, 0, -1, NULL, 0, SKSPUDPUD, -1, LUMPERROR}, - {"putput", false, 64, 0, -1, NULL, 0, SKSPUTPUT, -1, LUMPERROR}, // not as high a priority - {"spin" , false, 100, 0, -1, NULL, 0, SKSSPIN, -1, LUMPERROR}, - {"spndsh", false, 64, 1, -1, NULL, 0, SKSSPNDSH, -1, LUMPERROR}, - {"thok" , false, 96, 0, -1, NULL, 0, SKSTHOK, -1, LUMPERROR}, - {"zoom" , false, 120, 1, -1, NULL, 0, SKSZOOM, -1, LUMPERROR}, - {"skid", false, 64, 32, -1, NULL, 0, SKSSKID, -1, LUMPERROR}, + {"altdi1", false, 192, 16, -1, NULL, 0, SKSPLDET1, -1, LUMPERROR, "Dying"}, + {"altdi2", false, 192, 16, -1, NULL, 0, SKSPLDET2, -1, LUMPERROR, "Dying"}, + {"altdi3", false, 192, 16, -1, NULL, 0, SKSPLDET3, -1, LUMPERROR, "Dying"}, + {"altdi4", false, 192, 16, -1, NULL, 0, SKSPLDET4, -1, LUMPERROR, "Dying"}, + {"altow1", false, 192, 16, -1, NULL, 0, SKSPLPAN1, -1, LUMPERROR, "Ring loss"}, + {"altow2", false, 192, 16, -1, NULL, 0, SKSPLPAN2, -1, LUMPERROR, "Ring loss"}, + {"altow3", false, 192, 16, -1, NULL, 0, SKSPLPAN3, -1, LUMPERROR, "Ring loss"}, + {"altow4", false, 192, 16, -1, NULL, 0, SKSPLPAN4, -1, LUMPERROR, "Ring loss"}, + {"victr1", false, 64, 16, -1, NULL, 0, SKSPLVCT1, -1, LUMPERROR, "/"}, + {"victr2", false, 64, 16, -1, NULL, 0, SKSPLVCT2, -1, LUMPERROR, "/"}, + {"victr3", false, 64, 16, -1, NULL, 0, SKSPLVCT3, -1, LUMPERROR, "/"}, + {"victr4", false, 64, 16, -1, NULL, 0, SKSPLVCT4, -1, LUMPERROR, "/"}, + {"gasp" , false, 64, 0, -1, NULL, 0, SKSGASP, -1, LUMPERROR, "Bubble gasp"}, + {"jump" , false, 140, 0, -1, NULL, 0, SKSJUMP, -1, LUMPERROR, "Jump"}, + {"pudpud", false, 64, 0, -1, NULL, 0, SKSPUDPUD, -1, LUMPERROR, "Tired flight"}, + {"putput", false, 64, 0, -1, NULL, 0, SKSPUTPUT, -1, LUMPERROR, "Flight"}, // not as high a priority + {"spin" , false, 100, 0, -1, NULL, 0, SKSSPIN, -1, LUMPERROR, "Spin"}, + {"spndsh", false, 64, 1, -1, NULL, 0, SKSSPNDSH, -1, LUMPERROR, "Spindash"}, + {"thok" , false, 96, 0, -1, NULL, 0, SKSTHOK, -1, LUMPERROR, "Thok"}, + {"zoom" , false, 120, 1, -1, NULL, 0, SKSZOOM, -1, LUMPERROR, "Spin launch"}, + {"skid", false, 64, 32, -1, NULL, 0, SKSSKID, -1, LUMPERROR, "Skid"}, // Ambience/background objects/etc - {"ambint", true, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"ambint", true, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Obnoxious disco music"}, - {"alarm", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"buzz1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"buzz2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"buzz3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"buzz4", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"crumbl", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Platform Crumble Tails 03-16-2001 - {"fire", false, 8, 32, -1, NULL, 0, -1, -1, LUMPERROR}, - {"grind", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"laser", true, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR}, - {"mswing", false, 16, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"pstart", false, 100, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"pstop", false, 100, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"steam1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Tails 06-19-2001 - {"steam2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Tails 06-19-2001 - {"wbreak", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"alarm", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Alarm"}, + {"buzz1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Electric zap"}, + {"buzz2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Electric zap"}, + {"buzz3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wacky worksurface"}, + {"buzz4", true, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Buzz"}, + {"crumbl", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Crumbling"}, // Platform Crumble Tails 03-16-2001 + {"fire", false, 8, 32, -1, NULL, 0, -1, -1, LUMPERROR, "Flamethrower"}, + {"grind", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Metallic grinding"}, + {"laser", true, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Laser hum"}, + {"mswing", false, 16, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging mace"}, + {"pstart", false, 100, 0, -1, NULL, 0, -1, -1, LUMPERROR, "/"}, + {"pstop", false, 100, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Crusher stomp"}, + {"steam1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Steam jet"}, // Tails 06-19-2001 + {"steam2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Steam jet"}, // Tails 06-19-2001 + {"wbreak", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wood breaking"}, + {"ambmac", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Machinery"}, + {"spsmsh", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Heavy impact"}, - {"rainin", true, 24, 4, -1, NULL, 0, -1, -1, LUMPERROR}, - {"litng1", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR}, - {"litng2", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR}, - {"litng3", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR}, - {"litng4", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR}, - {"athun1", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR}, - {"athun2", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR}, + {"rainin", true, 24, 4, -1, NULL, 0, -1, -1, LUMPERROR, "Rain"}, + {"litng1", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Lightning"}, + {"litng2", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Lightning"}, + {"litng3", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Lightning"}, + {"litng4", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Lightning"}, + {"athun1", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Thunder"}, + {"athun2", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Thunder"}, - {"amwtr1", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"amwtr2", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"amwtr3", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"amwtr4", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"amwtr5", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"amwtr6", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"amwtr7", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"amwtr8", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bubbl1", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bubbl2", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bubbl3", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bubbl4", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bubbl5", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"floush", false, 16, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"splash", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"splish", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Splish Tails 12-08-2000 - {"wdrip1", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"wdrip2", false, 8 , 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"wdrip3", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"wdrip4", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"wdrip5", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"wdrip6", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"wdrip7", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"wdrip8", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"wslap", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Water Slap Tails 12-13-2000 + {"amwtr1", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr2", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr3", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr4", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr5", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr6", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr7", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr8", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"bubbl1", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"}, + {"bubbl2", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"}, + {"bubbl3", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"}, + {"bubbl4", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"}, + {"bubbl5", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"}, + {"floush", false, 16, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"}, + {"splash", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"}, // labeling sfx_splash as "glub" and sfx_splish as "splash" seems wrong but isn't + {"splish", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Splash"}, // Splish Tails 12-08-2000 + {"wdrip1", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drip"}, + {"wdrip2", false, 8 , 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drip"}, + {"wdrip3", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drip"}, + {"wdrip4", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drip"}, + {"wdrip5", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drip"}, + {"wdrip6", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drip"}, + {"wdrip7", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drip"}, + {"wdrip8", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drip"}, + {"wslap", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Splash"}, // Water Slap Tails 12-13-2000 - {"doora1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"doorb1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"doorc1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"doorc2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"doord1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"doord2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"eleva1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"eleva2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"eleva3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"elevb1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"elevb2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"elevb3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"doora1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sliding open"}, + {"doorb1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sliding open"}, + {"doorc1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wooden door opening"}, + {"doorc2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Slamming shut"}, + {"doord1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Creaking open"}, + {"doord2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Slamming shut"}, + {"eleva1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Starting elevator"}, + {"eleva2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Moving elevator"}, + {"eleva3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stopping elevator"}, + {"elevb1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Starting elevator"}, + {"elevb2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Moving elevator"}, + {"elevb3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stopping elevator"}, - {"ambin2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"lavbub", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR}, - {"rocks1", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"rocks2", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"rocks3", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"rocks4", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"rumbam", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"rumble", false, 64, 24, -1, NULL, 0, -1, -1, LUMPERROR}, + {"ambin2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Natural vibrations"}, + {"lavbub", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Bubbling lava"}, + {"rocks1", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Falling rocks"}, + {"rocks2", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Falling rocks"}, + {"rocks3", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Falling rocks"}, + {"rocks4", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Falling rocks"}, + {"rumbam", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, + {"rumble", false, 64, 24, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, // Game objects, etc - {"appear", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bkpoof", false, 70, 8, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bnce1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Boing! - {"bnce2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Boing! - {"cannon", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR}, - {"cgot" , true, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Got Emerald! Tails 09-02-2001 - {"cybdth", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"deton", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"ding", false, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR}, - {"dmpain", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"drown", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"fizzle", false, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR}, - {"gbeep", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Grenade beep - {"gclose", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"ghit" , false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"gloop", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"gspray", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"gravch", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"itemup", true, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"jet", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"jshard", true, 167, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"lose" , false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"lvpass", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"mindig", false, 8, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"mixup", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"pogo" , false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"pop" , false, 78, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"rail1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"rail2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"rlaunc", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"shield", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"shldls", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"spdpad", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"spkdth", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"spring", false, 112, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"statu1", true, 64, 2, -1, NULL, 0, -1, -1, LUMPERROR}, - {"statu2", true, 64, 2, -1, NULL, 0, -1, -1, LUMPERROR}, - {"strpst", true, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Starpost Sound Tails 07-04-2002 - {"supert", true, 127, 2, -1, NULL, 0, -1, -1, LUMPERROR}, - {"telept", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"tink" , false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"token" , true, 224, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // SS token - {"trfire", true, 60, 8, -1, NULL, 0, -1, -1, LUMPERROR}, - {"trpowr", true, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR}, - {"turhit", false, 40, 8, -1, NULL, 0, -1, -1, LUMPERROR}, - {"wdjump", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"mswarp", false, 60, 16, -1, NULL, 0, -1, -1, LUMPERROR}, - {"mspogo", false, 60, 8, -1, NULL, 0, -1, -1, LUMPERROR}, + {"appear", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Appearing platform"}, + {"bkpoof", false, 70, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Armageddon explosion"}, + {"bnce1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bounce"}, // Boing! + {"bnce2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Scatter"}, // Boing! + {"cannon", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Powerful shot"}, + {"cgot" , true, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got Emerald"}, // Got Emerald! Tails 09-02-2001 + {"cybdth", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Explosion"}, + {"deton", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Threatening beeping"}, + {"ding", false, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Ding"}, + {"dmpain", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Machine damage"}, + {"drown", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drowning"}, + {"fizzle", false, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Electric fizzle"}, + {"gbeep", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Threatening beeping"}, // Grenade beep + {"wepfir", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing weapon"}, // defaults to thok + {"ghit" , false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Goop splash"}, + {"gloop", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Splash"}, + {"gspray", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Goop sling"}, + {"gravch", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Recycler"}, + {"itemup", true, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sparkle"}, + {"jet", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Jet engine"}, + {"jshard", true, 167, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Life transfer"}, // placeholder repurpose; original string was "Got Shard" + {"lose" , false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Failure"}, + {"lvpass", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spinning signpost"}, + {"mindig", false, 8, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Tunnelling"}, + {"mixup", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Teleport"}, + {"monton", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Golden Monitor activated"}, + {"pogo" , false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Mechanical pogo"}, + {"pop" , false, 78, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pop"}, + {"rail1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing rail"}, + {"rail2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Crashing rail"}, + {"rlaunc", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing"}, + {"shield", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pity Shield"}, // generic GET! + {"wirlsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Whirlwind Shield"}, // Whirlwind GET! + {"forcsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Force Shield"}, // Force GET! + {"elemsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Elemental Shield"}, // Elemental GET! + {"armasg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Armageddon Shield"}, // Armaggeddon GET! + {"attrsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Attraction Shield"}, // Attract GET! + {"shldls", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hurt"}, // You LOSE! + {"spdpad", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Speedpad"}, + {"spkdth", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spiked"}, + {"spring", false, 112, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spring"}, + {"statu1", true, 64, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Pushing a statue"}, + {"statu2", true, 64, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Pushing a statue"}, + {"strpst", true, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Starpost"}, + {"supert", true, 127, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Transformation"}, + {"telept", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Dash"}, + {"tink" , false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Tink"}, + {"token" , true, 224, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got Token"}, + {"trfire", true, 60, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Laser fired"}, + {"trpowr", true, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Powering up"}, + {"turhit", false, 40, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Laser hit"}, + {"wdjump", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Whirlwind jump"}, + {"shrpsp", true, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spincushion"}, + {"shrpgo", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Launch"}, + {"mswarp", false, 60, 16, -1, NULL, 0, -1, -1, LUMPERROR, "Spinning out"}, + {"mspogo", false, 60, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Breaking through"}, + {"boingf", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bouncing"}, + {"corkp", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cork fired"}, + {"corkh", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cork hit"}, + {"bowl", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bowling"}, + {"chuchu", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Train horn"}, // Menu, interface - {"chchng", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"dwnind", false, 212, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"emfind", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"flgcap", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"menu1", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"oneup", true, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"ptally", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Point tally is identical to menu for now - {"radio", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"wepchg", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Weapon switch is identical to menu for now - {"wtrdng", true, 212, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // make sure you can hear the DING DING! Tails 03-08-2000 - {"zelda", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"chchng", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Score"}, + {"dwnind", false, 212, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Thinking about air"}, + {"emfind", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Radar beep"}, + {"flgcap", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flag captured"}, + {"menu1", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Menu beep"}, + {"oneup", true, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "One-up"}, + {"ptally", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Tally"}, // Point tally is identical to menu for now + {"radio", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Notification"}, + {"wepchg", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Weapon change"}, // Weapon switch is identical to menu for now + {"wtrdng", true, 212, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aquaphobia"}, // make sure you can hear the DING DING! Tails 03-08-2000 + {"zelda", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Discovery"}, // NiGHTS - {"ideya", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"xideya", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Xmas - {"nbmper", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"nxbump", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Xmas - {"ncitem", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"nxitem", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Xmas - {"ngdone", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"nxdone", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Xmas - {"drill1", false, 48, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"drill2", false, 48, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"ncspec", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Tails 12-15-2003 - {"nghurt", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"ngskid", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"hoop1", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"hoop2", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"hoop3", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"hidden", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"prloop", false, 104, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"timeup", true, 256, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"ideya", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Success"}, + {"xideya", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Success"}, // Xmas + {"nbmper", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bumper"}, + {"nxbump", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bumper"}, // Xmas + {"ncchip", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got chip"}, + {"ncitem", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got special"}, + {"nxitem", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got special"}, // Xmas + {"ngdone", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bonus time start"}, + {"nxdone", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bonus time start"}, // Xmas + {"drill1", false, 48, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drill"}, + {"drill2", false, 48, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drill"}, + {"ncspec", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Power-up"}, // Tails 12-15-2003 + {"nghurt", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hurt"}, + {"ngskid", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Force stop"}, + {"hoop1", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hoop"}, + {"hoop2", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hoop+"}, + {"hoop3", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hoop++"}, + {"hidden", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Discovery"}, + {"prloop", false, 104, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Gust of wind"}, + {"timeup", true, 256, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous Countdown"}, + {"ngjump", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Jump"}, + {"peww", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pew"}, + + // Halloween + {"lntsit", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cacolantern awake"}, + {"lntdie", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cacolantern death"}, + {"pumpkn", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pumpkin smash"}, // idspispopd + {"ghosty", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Laughter"}, // Mario - {"koopfr" , true, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR}, - {"mario1", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"mario2", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"mario3", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"mario4", true, 78, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"mario5", false, 78, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"mario6", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"mario7", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"mario8", false, 48, 8, -1, NULL, 0, -1, -1, LUMPERROR}, - {"mario9", true, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"marioa", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"thwomp", true, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR}, + {"koopfr" , true, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Fire"}, + {"mario1", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hit"}, + {"mario2", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bonk"}, + {"mario3", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Power-up"}, + {"mario4", true, 78, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got coin"}, + {"mario5", false, 78, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Boot-stomp"}, + {"mario6", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Jump"}, + {"mario7", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Fire"}, + {"mario8", false, 48, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Hurt"}, + {"mario9", true, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Emerging power-up"}, + {"marioa", true, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "One-up"}, + {"thwomp", true, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Thwomp"}, // Black Eggman - {"bebomb", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bechrg", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"becrsh", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bedeen", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bedie1", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bedie2", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"beeyow", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"befall", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"befire", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"beflap", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"begoop", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"begrnd", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"behurt", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bejet1", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"belnch", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"beoutb", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"beragh", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"beshot", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bestep", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bestp2", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bewar1", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bewar2", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bewar3", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bewar4", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bexpld", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"bgxpld", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, + {"bebomb", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Big explosion"}, + {"bechrg", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Powering up"}, + {"becrsh", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Crash"}, + {"bedeen", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Metallic crash"}, + {"bedie1", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Eggman crying"}, + {"bedie2", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Eggman crying"}, + {"beeyow", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Failing machinery"}, + {"befall", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Metallic slam"}, + {"befire", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Firing goop"}, + {"beflap", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Mechanical jump"}, + {"begoop", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Powerful shot"}, + {"begrnd", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Metallic grinding"}, + {"behurt", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Eggman shocked"}, + {"bejet1", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Jetpack charge"}, + {"belnch", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Mechanical jump"}, + {"beoutb", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Failed shot"}, + {"beragh", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Eggman screaming"}, + {"beshot", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Firing missile"}, + {"bestep", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Mechanical stomp"}, + {"bestp2", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Mechanical stomp"}, + {"bewar1", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Eggman laughing"}, + {"bewar2", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Eggman laughing"}, + {"bewar3", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Eggman laughing"}, + {"bewar4", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Eggman laughing"}, + {"bexpld", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Explosion"}, + {"bgxpld", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Explosion"}, // Cybrakdemon - {"beelec", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"brakrl", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, - {"brakrx", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, + {"beelec", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Electricity"}, + {"brakrl", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Rocket launch"}, + {"brakrx", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Rocket explosion"}, // S3&K sounds - {"s3k33", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k34", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k35", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k36", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k37", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k38", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k39", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k3a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k3b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k3c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k3d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k3e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k3f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k40", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k41", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k42", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k43", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k44", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k45", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k46", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k47", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k48", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k49", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k4a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k4b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k4c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k4d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k4e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k4f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k50", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k51", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k52", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k53", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k54", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, // MetalSonic shot fire - {"s3k55", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k56", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k57", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k58", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k59", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k5a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k5b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k5c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k5d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k5e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k5f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k60", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k61", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k64", false, 64, 2, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k65", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Blue Spheres - {"s3k66", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k69", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k6a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k6b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k6c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k6d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k6e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k6f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k70", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k71", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k72", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k73", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k74", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k75", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k76", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k77", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k78", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k79", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k7a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k7b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k7c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k7d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k7e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k7f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k80", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k81", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k82", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k83", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k84", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k85", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k86", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k87", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k88", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k89", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k8a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k8b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k8c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k8d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k8e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k8f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k90", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k91", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k92", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k93", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k94", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k95", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k96", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k97", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k98", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k99", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k9a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k9b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k9c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k9d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k9e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3k9f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3ka0", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3ka1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3ka2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3ka3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3ka4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3ka5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3ka6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3ka7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3ka8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3ka9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kaa", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kab", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kac", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kad", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kae", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kaf", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kb0", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kb1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kb2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kb3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kb4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kb5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kb6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kb7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kb8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kb9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kba", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kbb", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kbcs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kbcl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kbds", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kbdl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kbes", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kbel", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kbfs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kbfl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc0s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc0l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc1s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc1l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc2s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc2l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc3s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc3l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc4s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc4l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc5s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc5l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc6s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc6l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc8s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc8l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc9s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kc9l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kcas", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kcal", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kcbs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kcbl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kccs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kccl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kcds", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kcdl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kces", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kcel", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kcfs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kcfl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd0s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd0l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd1s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd1l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd2s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd2l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd3s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd3l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd4s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd4l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd5s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd5l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd6s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd6l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd7s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd7l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd8s", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, // Sharp Spin (maybe use the long/L version?) - {"s3kd8l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd9s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kd9l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kdas", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kdal", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kdbs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, - {"s3kdbl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, + {"s3k33", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sparkle"}, // stereo in original game, identical to latter + {"s3k34", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sparkle"}, // mono in original game, identical to previous + {"s3k35", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hurt"}, + {"s3k36", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Skid"}, + {"s3k37", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spiked"}, + {"s3k38", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bubble gasp"}, + {"s3k39", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Splash"}, + {"s3k3a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Shield"}, + {"s3k3b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drowning"}, + {"s3k3c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spin"}, + {"s3k3d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pop"}, + {"s3k3e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flame Shield"}, + {"s3k3f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bubble Shield"}, + {"s3k40", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Attraction blast"}, + {"s3k41", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Lightning Shield"}, + {"s3k42", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Twinspin"}, + {"s3k43", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flame burst"}, + {"s3k44", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bubble bounce"}, + {"s3k45", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Lightning zap"}, + {"s3k46", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Transformation"}, + {"s3k47", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rising dust"}, + {"s3k48", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pulse"}, + {"s3k49", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Impact"}, + {"s3k4a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Grab"}, + {"s3k4b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Splash"}, + {"s3k4c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Heavy hit"}, + {"s3k4d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing bullet"}, + {"s3k4e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Big explosion"}, + {"s3k4f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flamethrower"}, + {"s3k50", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Siren"}, + {"s3k51", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling"}, + {"s3k52", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spike"}, + {"s3k53", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powering up"}, + {"s3k54", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Firing"}, // MetalSonic shot fire + {"s3k55", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Mechanical movement"}, + {"s3k56", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Heavy landing"}, + {"s3k57", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Burst"}, + {"s3k58", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Mechanical movement"}, + {"s3k59", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Crumbling"}, + {"s3k5a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aiming"}, + {"s3k5b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Menu beep"}, + {"s3k5c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Electric spark"}, + {"s3k5d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Heavy hit"}, + {"s3k5e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing laser"}, + {"s3k5f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Crusher stomp"}, + {"s3k60", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flying away"}, + {"s3k61", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drilling"}, + {"s3k62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Jump"}, + {"s3k63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Starpost"}, + {"s3k64", false, 64, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Clatter"}, + {"s3k65", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got sphere"}, // Blue Spheres + {"s3k66", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Special stage end"}, + {"s3k67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing missile"}, + {"s3k68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Discovery"}, + {"s3k69", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Switch click"}, + {"s3k6a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Special stage clear"}, + {"s3k6b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Punch"}, + {"s3k6c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Burst"}, + {"s3k6d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"s3k6e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Mechanical damage"}, + {"s3k6f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, + {"s3k70", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Burst"}, + {"s3k71", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Basic Shield"}, + {"s3k72", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Movement"}, + {"s3k73", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Warp"}, + {"s3k74", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Gong"}, + {"s3k75", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rising"}, + {"s3k76", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Click"}, + {"s3k77", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Balloon pop"}, + {"s3k78", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Magnet"}, + {"s3k79", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Electric charge"}, + {"s3k7a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rising from lava"}, + {"s3k7b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Soft bounce"}, + {"s3k7c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Magnet"}, + {"s3k7d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"s3k7e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Dust"}, + {"s3k7f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Freeze"}, + {"s3k80", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ice spike burst"}, + {"s3k81", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Burst"}, + {"s3k82", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Burst"}, + {"s3k83", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Collapsing"}, + {"s3k84", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powering up"}, + {"s3k85", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powering down"}, + {"s3k86", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Alarm"}, + {"s3k87", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bounce"}, + {"s3k88", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Metallic squeak"}, + {"s3k89", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Advanced tech"}, + {"s3k8a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Boing"}, + {"s3k8b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powerful hit"}, + {"s3k8c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Humming power"}, + {"s3k8d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"s3k8e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Accelerating"}, + {"s3k8f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Opening"}, + {"s3k90", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Impact"}, + {"s3k91", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Closed"}, + {"s3k92", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ghost"}, + {"s3k93", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Gas release"}, + {"s3k94", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spike"}, + {"s3k95", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Lava burst"}, + {"s3k96", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Landing"}, + {"s3k97", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wind"}, + {"s3k98", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling spike"}, + {"s3k99", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bounce"}, + {"s3k9a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Click"}, + {"s3k9b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Crusher stomp"}, + {"s3k9c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got Super Emerald"}, + {"s3k9d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Targeting"}, + {"s3k9e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wham"}, + {"s3k9f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Transformation"}, + {"s3ka0", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Launch"}, + {"s3ka1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"s3ka2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Launch"}, + {"s3ka3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Lift"}, + {"s3ka4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powering up"}, + {"s3ka5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"s3ka6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Attraction fizzle"}, + {"s3ka7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Countdown beep"}, + {"s3ka8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Energy"}, + {"s3ka9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aquaphobia"}, + {"s3kaa", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bumper"}, + {"s3kab", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kac", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got Continue"}, + {"s3kad", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "GO!"}, + {"s3kae", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pinball flipper"}, + {"s3kaf", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "To Special Stage"}, + {"s3kb0", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Score"}, + {"s3kb1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spring"}, + {"s3kb2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Failure"}, + {"s3kb3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Warp"}, + {"s3kb4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Explosion"}, + {"s3kb5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Clink"}, + {"s3kb6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spin launch"}, + {"s3kb7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Tumbler"}, + {"s3kb8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling signpost"}, + {"s3kb9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ring loss"}, + {"s3kba", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flight"}, + {"s3kbb", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Tired flight"}, + {"s3kbcs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"s3kbcl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // long version of previous + {"s3kbds", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flying fortress"}, + {"s3kbdl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flying fortress"}, // ditto + {"s3kbes", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flying away"}, + {"s3kbel", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flying away"}, // ditto + {"s3kbfs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Turbine"}, + {"s3kbfl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Turbine"}, // ditto + {"s3kc0s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Turbine"}, + {"s3kc0l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Turbine"}, // ditto + {"s3kc1s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Fan"}, + {"s3kc1l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Fan"}, // ditto + {"s3kc2s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flamethrower"}, + {"s3kc2l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flamethrower"}, // ditto + {"s3kc3s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Levitation"}, + {"s3kc3l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Levitation"}, // ditto + {"s3kc4s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing laser"}, + {"s3kc4l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing laser"}, // ditto + {"s3kc5s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Revving up"}, + {"s3kc5l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Revving up"}, // ditto + {"s3kc6s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Orbiting"}, + {"s3kc6l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Orbiting"}, // ditto + {"s3kc7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aiming"}, + {"s3kc8s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sliding"}, + {"s3kc8l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sliding"}, // ditto + {"s3kc9s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging"}, + {"s3kc9l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging"}, // ditto + {"s3kcas", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Energy"}, + {"s3kcal", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Energy"}, // ditto + {"s3kcbs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, + {"s3kcbl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, // ditto + {"s3kccs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Collapsing"}, + {"s3kccl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Collapsing"}, // ditto + {"s3kcds", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, + {"s3kcdl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, // ditto + {"s3kces", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wind tunnel"}, + {"s3kcel", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Dust devil"}, // ditto + {"s3kcfs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"s3kcfl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // ditto + {"s3kd0s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rising"}, + {"s3kd0l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rising"}, // ditto + {"s3kd1s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"s3kd1l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // ditto + {"s3kd2s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Turning"}, + {"s3kd2l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Moving chain"}, // ditto + {"s3kd3s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Digging"}, + {"s3kd3l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Digging"}, // ditto + {"s3kd4s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Engine"}, + {"s3kd4l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Engine"}, // ditto + {"s3kd5s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling lava"}, + {"s3kd5l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling lava"}, // ditto + {"s3kd6s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"s3kd6l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // ditto + {"s3kd7s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Movement"}, + {"s3kd7l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Movement"}, // ditto + {"s3kd8s", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Acceleration"}, // Sharp Spin (maybe use the long/L version?) + {"s3kd8l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Acceleration"}, // ditto + {"s3kd9s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Magnetism"}, + {"s3kd9l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Magnetism"}, // ditto + {"s3kdas", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Click"}, + {"s3kdal", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Click"}, // ditto + {"s3kdbs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running on water"}, + {"s3kdbl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running on water"}, // ditto // skin sounds free slots to add sounds at run time (Boris HACK!!!) // initialized to NULL @@ -504,6 +528,8 @@ void S_InitRuntimeSounds (void) S_sfx[i].skinsound = -1; S_sfx[i].usefulness = -1; S_sfx[i].lumpnum = LUMPERROR; + //strlcpy(S_sfx[i].caption, "", 1); + S_sfx[i].caption[0] = '\0'; } } diff --git a/src/sounds.h b/src/sounds.h index 3c74d56e699ef85a44f05c97f0078b34dfb2f458..47530912133953fafcd166198a5166ab5bbb192a 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -84,6 +84,9 @@ struct sfxinfo_struct // lump number of sfx lumpnum_t lumpnum; + + // closed caption info/wiki table bait + char caption[32]; }; // the complete set of sound effects @@ -139,6 +142,8 @@ typedef enum sfx_steam1, sfx_steam2, sfx_wbreak, + sfx_ambmac, + sfx_spsmsh, sfx_rainin, sfx_litng1, @@ -210,7 +215,7 @@ typedef enum sfx_drown, sfx_fizzle, sfx_gbeep, - sfx_gclose, + sfx_wepfir, sfx_ghit, sfx_gloop, sfx_gspray, @@ -222,12 +227,18 @@ typedef enum sfx_lvpass, sfx_mindig, sfx_mixup, + sfx_monton, sfx_pogo, sfx_pop, sfx_rail1, sfx_rail2, sfx_rlaunc, sfx_shield, + sfx_wirlsg, + sfx_forcsg, + sfx_elemsg, + sfx_armasg, + sfx_attrsg, sfx_shldls, sfx_spdpad, sfx_spkdth, @@ -243,8 +254,15 @@ typedef enum sfx_trpowr, sfx_turhit, sfx_wdjump, + sfx_shrpsp, + sfx_shrpgo, sfx_mswarp, sfx_mspogo, + sfx_boingf, + sfx_corkp, + sfx_corkh, + sfx_bowl, + sfx_chuchu, // Menu, interface sfx_chchng, @@ -264,6 +282,7 @@ typedef enum sfx_xideya, // Xmas sfx_nbmper, sfx_nxbump, // Xmas + sfx_ncchip, sfx_ncitem, sfx_nxitem, // Xmas sfx_ngdone, @@ -278,7 +297,15 @@ typedef enum sfx_hoop3, sfx_hidden, sfx_prloop, - sfx_timeup, // Was gonna be played when less than ten seconds are on the clock; uncomment uses of this to see it in-context + sfx_timeup, + sfx_ngjump, + sfx_peww, + + // Halloween + sfx_lntsit, + sfx_lntdie, + sfx_pumpkn, + sfx_ghosty, // Mario sfx_koopfr, diff --git a/src/st_stuff.c b/src/st_stuff.c index 287aea134ba4e81bb5f50848696516d11990a9bb..f0f40ed32cf350002025ae5c326d89c9f6bf0ad8 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -27,6 +27,8 @@ #include "i_system.h" #include "m_menu.h" #include "m_cheat.h" +#include "m_misc.h" // moviemode +#include "m_anigif.h" // cv_gif_downscale #include "p_setup.h" // NiGHTS grading //random index @@ -67,7 +69,8 @@ static patch_t *sborings; static patch_t *sboover; static patch_t *timeover; static patch_t *stlivex; -static patch_t *rrings; +static patch_t *sboredrings; +static patch_t *sboredtime; static patch_t *getall; // Special Stage HUD static patch_t *timeup; // Special Stage HUD static patch_t *hunthoming[6]; @@ -76,14 +79,7 @@ static patch_t *race1; static patch_t *race2; static patch_t *race3; static patch_t *racego; -static patch_t *ttlnum; static patch_t *nightslink; -static patch_t *count5; -static patch_t *count4; -static patch_t *count3; -static patch_t *count2; -static patch_t *count1; -static patch_t *count0; static patch_t *curweapon; static patch_t *normring; static patch_t *bouncering; @@ -99,10 +95,14 @@ static patch_t *ringshield; static patch_t *watershield; static patch_t *bombshield; static patch_t *pityshield; +static patch_t *flameshield; +static patch_t *bubbleshield; +static patch_t *thundershield; static patch_t *invincibility; static patch_t *sneakers; static patch_t *gravboots; static patch_t *nonicon; +static patch_t *nonicon2; static patch_t *bluestat; static patch_t *byelstat; static patch_t *orngstat; @@ -111,6 +111,8 @@ static patch_t *yelstat; static patch_t *nbracket; static patch_t *nhud[12]; static patch_t *nsshud; +static patch_t *nbon[12]; +static patch_t *nssbon; static patch_t *narrow[9]; static patch_t *nredar[8]; // Red arrow static patch_t *drillbar; @@ -127,41 +129,32 @@ static boolean facefreed[MAXPLAYERS]; hudinfo_t hudinfo[NUMHUDITEMS] = { - { 34, 176}, // HUD_LIVESNAME - { 16, 176}, // HUD_LIVESPIC - { 74, 184}, // HUD_LIVESNUM - { 38, 186}, // HUD_LIVESX - - { 16, 42}, // HUD_RINGS - { 220, 10}, // HUD_RINGSSPLIT - { 112, 42}, // HUD_RINGSNUM - { 288, 10}, // HUD_RINGSNUMSPLIT - - { 16, 10}, // HUD_SCORE - { 128, 10}, // HUD_SCORENUM - - { 17, 26}, // HUD_TIME - { 136, 10}, // HUD_TIMESPLIT - { 88, 26}, // HUD_MINUTES - { 188, 10}, // HUD_MINUTESSPLIT - { 88, 26}, // HUD_TIMECOLON - { 188, 10}, // HUD_TIMECOLONSPLIT - { 112, 26}, // HUD_SECONDS - { 212, 10}, // HUD_SECONDSSPLIT - { 112, 26}, // HUD_TIMETICCOLON - { 136, 26}, // HUD_TICS - - { 112, 56}, // HUD_SS_TOTALRINGS - { 288, 40}, // HUD_SS_TOTALRINGS_SPLIT - - { 110, 93}, // HUD_GETRINGS - { 160, 93}, // HUD_GETRINGSNUM - { 124, 160}, // HUD_TIMELEFT - { 168, 176}, // HUD_TIMELEFTNUM - { 130, 93}, // HUD_TIMEUP - { 152, 168}, // HUD_HUNTPICS - { 152, 24}, // HUD_GRAVBOOTSICO - { 240, 160}, // HUD_LAP + { 16, 176, V_SNAPTOLEFT|V_SNAPTOBOTTOM}, // HUD_LIVES + + { 16, 42, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_RINGS + { 96, 42, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_RINGSNUM + { 120, 42, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_RINGSNUMTICS + + { 16, 10, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SCORE + { 120, 10, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SCORENUM + + { 16, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TIME + { 72, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_MINUTES + { 72, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TIMECOLON + { 96, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SECONDS + { 96, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TIMETICCOLON + { 120, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TICS + + { 0, 56, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SS_TOTALRINGS + + { 110, 93, 0}, // HUD_GETRINGS + { 160, 93, 0}, // HUD_GETRINGSNUM + { 124, 160, 0}, // HUD_TIMELEFT + { 168, 176, 0}, // HUD_TIMELEFTNUM + { 130, 93, 0}, // HUD_TIMEUP + { 152, 168, 0}, // HUD_HUNTPICS + + { 288, 176, V_SNAPTORIGHT|V_SNAPTOBOTTOM}, // HUD_POWERUPS }; // @@ -248,16 +241,20 @@ void ST_LoadGraphics(void) // but load them in R_AddSkins, that gets called // first anyway // cache the status bar overlay icons (fullscreen mode) - sborings = W_CachePatchName("SBORINGS", PU_HUDGFX); - sboscore = W_CachePatchName("SBOSCORE", PU_HUDGFX); + + // Prefix "STT" is whitelisted (doesn't trigger ISGAMEMODIFIED), btw + sborings = W_CachePatchName("STTRINGS", PU_HUDGFX); + sboredrings = W_CachePatchName("STTRRING", PU_HUDGFX); + sboscore = W_CachePatchName("STTSCORE", PU_HUDGFX); + sbotime = W_CachePatchName("STTTIME", PU_HUDGFX); // Time logo + sboredtime = W_CachePatchName("STTRTIME", PU_HUDGFX); + sbocolon = W_CachePatchName("STTCOLON", PU_HUDGFX); // Colon for time + sboperiod = W_CachePatchName("STTPERIO", PU_HUDGFX); // Period for time centiseconds + sboover = W_CachePatchName("SBOOVER", PU_HUDGFX); timeover = W_CachePatchName("TIMEOVER", PU_HUDGFX); stlivex = W_CachePatchName("STLIVEX", PU_HUDGFX); livesback = W_CachePatchName("STLIVEBK", PU_HUDGFX); - rrings = W_CachePatchName("RRINGS", PU_HUDGFX); - sbotime = W_CachePatchName("SBOTIME", PU_HUDGFX); // Time logo - sbocolon = W_CachePatchName("SBOCOLON", PU_HUDGFX); // Colon for time - sboperiod = W_CachePatchName("SBOPERIO", PU_HUDGFX); // Period for time centiseconds nrec_timer = W_CachePatchName("NGRTIMER", PU_HUDGFX); // Timer for NiGHTS getall = W_CachePatchName("GETALL", PU_HUDGFX); // Special Stage HUD timeup = W_CachePatchName("TIMEUP", PU_HUDGFX); // Special Stage HUD @@ -266,12 +263,6 @@ void ST_LoadGraphics(void) race3 = W_CachePatchName("RACE3", PU_HUDGFX); racego = W_CachePatchName("RACEGO", PU_HUDGFX); nightslink = W_CachePatchName("NGHTLINK", PU_HUDGFX); - count5 = W_CachePatchName("DRWNF0", PU_HUDGFX); - count4 = W_CachePatchName("DRWNE0", PU_HUDGFX); - count3 = W_CachePatchName("DRWND0", PU_HUDGFX); - count2 = W_CachePatchName("DRWNC0", PU_HUDGFX); - count1 = W_CachePatchName("DRWNB0", PU_HUDGFX); - count0 = W_CachePatchName("DRWNA0", PU_HUDGFX); for (i = 0; i < 6; ++i) { @@ -288,15 +279,18 @@ void ST_LoadGraphics(void) scatterring = W_CachePatchName("SCATIND", PU_HUDGFX); grenadering = W_CachePatchName("GRENIND", PU_HUDGFX); railring = W_CachePatchName("RAILIND", PU_HUDGFX); - jumpshield = W_CachePatchName("WHTVB0", PU_HUDGFX); - forceshield = W_CachePatchName("BLTVB0", PU_HUDGFX); - ringshield = W_CachePatchName("YLTVB0", PU_HUDGFX); - watershield = W_CachePatchName("ELTVB0", PU_HUDGFX); - bombshield = W_CachePatchName("BKTVB0", PU_HUDGFX); - pityshield = W_CachePatchName("GRTVB0", PU_HUDGFX); - invincibility = W_CachePatchName("PINVB0", PU_HUDGFX); - sneakers = W_CachePatchName("SHTVB0", PU_HUDGFX); - gravboots = W_CachePatchName("GBTVB0", PU_HUDGFX); + jumpshield = W_CachePatchName("TVWWICON", PU_HUDGFX); + forceshield = W_CachePatchName("TVFOICON", PU_HUDGFX); + ringshield = W_CachePatchName("TVATICON", PU_HUDGFX); + watershield = W_CachePatchName("TVELICON", PU_HUDGFX); + bombshield = W_CachePatchName("TVARICON", PU_HUDGFX); + pityshield = W_CachePatchName("TVPIICON", PU_HUDGFX); + flameshield = W_CachePatchName("TVFLICON", PU_HUDGFX); + bubbleshield = W_CachePatchName("TVBBICON", PU_HUDGFX); + thundershield = W_CachePatchName("TVZPICON", PU_HUDGFX); + invincibility = W_CachePatchName("TVIVICON", PU_HUDGFX); + sneakers = W_CachePatchName("TVSSICON", PU_HUDGFX); + gravboots = W_CachePatchName("TVGVICON", PU_HUDGFX); tagico = W_CachePatchName("TAGICO", PU_HUDGFX); rflagico = W_CachePatchName("RFLAGICO", PU_HUDGFX); @@ -306,6 +300,7 @@ void ST_LoadGraphics(void) gotrflag = W_CachePatchName("GOTRFLAG", PU_HUDGFX); gotbflag = W_CachePatchName("GOTBFLAG", PU_HUDGFX); nonicon = W_CachePatchName("NONICON", PU_HUDGFX); + nonicon2 = W_CachePatchName("NONICON2", PU_HUDGFX); // NiGHTS HUD things bluestat = W_CachePatchName("BLUESTAT", PU_HUDGFX); @@ -315,8 +310,12 @@ void ST_LoadGraphics(void) yelstat = W_CachePatchName("YELSTAT", PU_HUDGFX); nbracket = W_CachePatchName("NBRACKET", PU_HUDGFX); for (i = 0; i < 12; ++i) + { nhud[i] = W_CachePatchName(va("NHUD%d", i+1), PU_HUDGFX); + nbon[i] = W_CachePatchName(va("NBON%d", i+1), PU_HUDGFX); + } nsshud = W_CachePatchName("NSSHUD", PU_HUDGFX); + nssbon = W_CachePatchName("NSSBON", PU_HUDGFX); minicaps = W_CachePatchName("MINICAPS", PU_HUDGFX); for (i = 0; i < 8; ++i) @@ -347,15 +346,6 @@ void ST_LoadFaceGraphics(char *facestr, char *superstr, INT32 skinnum) facefreed[skinnum] = false; } -#ifdef DELFILE -void ST_UnLoadFaceGraphics(INT32 skinnum) -{ - Z_Free(faceprefix[skinnum]); - Z_Free(superprefix[skinnum]); - facefreed[skinnum] = true; -} -#endif - void ST_ReloadSkinFaceGraphics(void) { INT32 i; @@ -427,98 +417,22 @@ void ST_changeDemoView(void) boolean st_overlay; -static INT32 SCZ(INT32 z) -{ - return FixedInt(FixedMul(z<<FRACBITS, vid.fdupy)); -} - -static INT32 SCY(INT32 y) -{ - //31/10/99: fixed by Hurdler so it _works_ also in hardware mode - // do not scale to resolution for hardware accelerated - // because these modes always scale by default - y = SCZ(y); // scale to resolution - if (splitscreen) - { - y >>= 1; - if (stplyr != &players[displayplayer]) - y += vid.height / 2; - } - return y; -} - -static INT32 STRINGY(INT32 y) -{ - //31/10/99: fixed by Hurdler so it _works_ also in hardware mode - // do not scale to resolution for hardware accelerated - // because these modes always scale by default - if (splitscreen) - { - y >>= 1; - if (stplyr != &players[displayplayer]) - y += BASEVIDHEIGHT / 2; - } - return y; -} - -static INT32 SPLITFLAGS(INT32 f) -{ - // Pass this V_SNAPTO(TOP|BOTTOM) and it'll trim them to account for splitscreen! -Red - if (splitscreen) - { - if (stplyr != &players[displayplayer]) - f &= ~V_SNAPTOTOP; - else - f &= ~V_SNAPTOBOTTOM; - } - return f; -} - -static INT32 SCX(INT32 x) -{ - return FixedInt(FixedMul(x<<FRACBITS, vid.fdupx)); -} - -#if 0 -static INT32 SCR(INT32 r) -{ - fixed_t y; - //31/10/99: fixed by Hurdler so it _works_ also in hardware mode - // do not scale to resolution for hardware accelerated - // because these modes always scale by default - y = FixedMul(r*FRACUNIT, vid.fdupy); // scale to resolution - if (splitscreen) - { - y >>= 1; - if (stplyr != &players[displayplayer]) - y += vid.height / 2; - } - return FixedInt(FixedDiv(y, vid.fdupy)); -} -#endif - // ========================================================================= // INTERNAL DRAWING // ========================================================================= -#define ST_DrawOverlayNum(x,y,n) V_DrawTallNum(x, y, V_NOSCALESTART|V_HUDTRANS, n) -#define ST_DrawPaddedOverlayNum(x,y,n,d) V_DrawPaddedTallNum(x, y, V_NOSCALESTART|V_HUDTRANS, n, d) -#define ST_DrawOverlayPatch(x,y,p) V_DrawScaledPatch(x, y, V_NOSCALESTART|V_HUDTRANS, p) -#define ST_DrawMappedOverlayPatch(x,y,p,c) V_DrawMappedScaledPatch(x, y, V_NOSCALESTART|V_HUDTRANS, p, c) -#define ST_DrawNumFromHud(h,n) V_DrawTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|V_HUDTRANS, n) -#define ST_DrawPadNumFromHud(h,n,q) V_DrawPaddedTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|V_HUDTRANS, n, q) -#define ST_DrawPatchFromHud(h,p) V_DrawScaledPatch(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|V_HUDTRANS, p) -#define ST_DrawNumFromHudWS(h,n) V_DrawTallNum(SCX(hudinfo[h+!!splitscreen].x), SCY(hudinfo[h+!!splitscreen].y), V_NOSCALESTART|V_HUDTRANS, n) -#define ST_DrawPadNumFromHudWS(h,n,q) V_DrawPaddedTallNum(SCX(hudinfo[h+!!splitscreen].x), SCY(hudinfo[h+!!splitscreen].y), V_NOSCALESTART|V_HUDTRANS, n, q) -#define ST_DrawPatchFromHudWS(h,p) V_DrawScaledPatch(SCX(hudinfo[h+!!splitscreen].x), SCY(hudinfo[h+!!splitscreen].y), V_NOSCALESTART|V_HUDTRANS, p) +#define ST_DrawTopLeftOverlayPatch(x,y,p) V_DrawScaledPatch(x, y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, p) +#define ST_DrawNumFromHud(h,n,flags) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f|V_PERPLAYER|flags, n) +#define ST_DrawPadNumFromHud(h,n,q,flags) V_DrawPaddedTallNum(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f|V_PERPLAYER|flags, n, q) +#define ST_DrawPatchFromHud(h,p,flags) V_DrawScaledPatch(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f|V_PERPLAYER|flags, p) // Draw a number, scaled, over the view, maybe with set translucency // Always draw the number completely since it's overlay // // Supports different colors! woo! -static void ST_DrawNightsOverlayNum(INT32 x /* right border */, INT32 y, INT32 a, - INT32 num, patch_t **numpat, skincolors_t colornum) +static void ST_DrawNightsOverlayNum(fixed_t x /* right border */, fixed_t y, fixed_t s, INT32 a, + UINT32 num, patch_t **numpat, skincolors_t colornum) { - INT32 w = SHORT(numpat[0]->width); + fixed_t w = SHORT(numpat[0]->width)*s; const UINT8 *colormap; // I want my V_SNAPTOx flags. :< -Red @@ -529,65 +443,60 @@ static void ST_DrawNightsOverlayNum(INT32 x /* right border */, INT32 y, INT32 a else // Uses the player colors. colormap = R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE); - I_Assert(num >= 0); // this function does not draw negative numbers + //I_Assert(num >= 0); // this function does not draw negative numbers // draw the number do { x -= w; - V_DrawTranslucentMappedPatch(x, y, a, numpat[num % 10], colormap); + V_DrawFixedPatch(x, y, s, a, numpat[num % 10], colormap); num /= 10; } while (num); // Sorry chum, this function only draws UNSIGNED values! + // then why is num not UINT32? ~toast } // Devmode information static void ST_drawDebugInfo(void) { - INT32 height = 192; + INT32 height = 0, h = 8, w = 18, lowh; + void (*textfunc)(INT32, INT32, INT32, const char *); - if (!stplyr->mo) + if (!(stplyr->mo && cv_debug)) return; - if (cv_debug & DBG_BASIC) - { - const fixed_t d = AngleFixed(stplyr->mo->angle); - V_DrawRightAlignedString(320, 168, V_MONOSPACE, va("X: %6d", stplyr->mo->x>>FRACBITS)); - V_DrawRightAlignedString(320, 176, V_MONOSPACE, va("Y: %6d", stplyr->mo->y>>FRACBITS)); - V_DrawRightAlignedString(320, 184, V_MONOSPACE, va("Z: %6d", stplyr->mo->z>>FRACBITS)); - V_DrawRightAlignedString(320, 192, V_MONOSPACE, va("A: %6d", FixedInt(d))); +#define VFLAGS V_MONOSPACE|V_SNAPTOTOP|V_SNAPTORIGHT - height = 152; + if ((moviemode == MM_GIF && cv_gif_downscale.value) || vid.dupx == 1) + { + textfunc = V_DrawRightAlignedString; + lowh = ((vid.height/vid.dupy) - 16); } - - if (cv_debug & DBG_DETAILED) + else { - V_DrawRightAlignedString(320, height - 104, V_MONOSPACE, va("SHIELD: %5x", stplyr->powers[pw_shield])); - V_DrawRightAlignedString(320, height - 96, V_MONOSPACE, va("SCALE: %5d%%", (stplyr->mo->scale*100)/FRACUNIT)); - V_DrawRightAlignedString(320, height - 88, V_MONOSPACE, va("DASH: %3d/%3d", stplyr->dashspeed>>FRACBITS, FixedMul(stplyr->maxdash,stplyr->mo->scale)>>FRACBITS)); - V_DrawRightAlignedString(320, height - 80, V_MONOSPACE, va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime])); - - // Flags - V_DrawRightAlignedString(304-64, height - 72, V_MONOSPACE, "Flags:"); - V_DrawString(304-60, height - 72, (stplyr->jumping) ? V_GREENMAP : V_REDMAP, "JM"); - V_DrawString(304-40, height - 72, (stplyr->pflags & PF_JUMPED) ? V_GREENMAP : V_REDMAP, "JD"); - V_DrawString(304-20, height - 72, (stplyr->pflags & PF_SPINNING) ? V_GREENMAP : V_REDMAP, "SP"); - V_DrawString(304, height - 72, (stplyr->pflags & PF_STARTDASH) ? V_GREENMAP : V_REDMAP, "ST"); + textfunc = V_DrawRightAlignedSmallString; + h /= 2; + w /= 2; + lowh = 0; + } - V_DrawRightAlignedString(320, height - 64, V_MONOSPACE, va("CEILZ: %6d", stplyr->mo->ceilingz>>FRACBITS)); - V_DrawRightAlignedString(320, height - 56, V_MONOSPACE, va("FLOORZ: %6d", stplyr->mo->floorz>>FRACBITS)); +#define V_DrawDebugLine(str) if (lowh && (height > lowh))\ + {\ + V_DrawRightAlignedThinString(320, 8+lowh, VFLAGS|V_REDMAP, "SOME INFO NOT VISIBLE");\ + return;\ + }\ + textfunc(320, height, VFLAGS, str);\ + height += h; - V_DrawRightAlignedString(320, height - 48, V_MONOSPACE, va("CNVX: %6d", stplyr->cmomx>>FRACBITS)); - V_DrawRightAlignedString(320, height - 40, V_MONOSPACE, va("CNVY: %6d", stplyr->cmomy>>FRACBITS)); - V_DrawRightAlignedString(320, height - 32, V_MONOSPACE, va("PLTZ: %6d", stplyr->mo->pmomz>>FRACBITS)); +#define V_DrawDebugFlag(f, str) textfunc(width, height, VFLAGS|f, str);\ + width -= w - V_DrawRightAlignedString(320, height - 24, V_MONOSPACE, va("MOMX: %6d", stplyr->rmomx>>FRACBITS)); - V_DrawRightAlignedString(320, height - 16, V_MONOSPACE, va("MOMY: %6d", stplyr->rmomy>>FRACBITS)); - V_DrawRightAlignedString(320, height - 8, V_MONOSPACE, va("MOMZ: %6d", stplyr->mo->momz>>FRACBITS)); - V_DrawRightAlignedString(320, height, V_MONOSPACE, va("SPEED: %6d", stplyr->speed>>FRACBITS)); + if (cv_debug & DBG_MEMORY) + { + V_DrawDebugLine(va("Heap: %8sKB", sizeu1(Z_TotalUsage()>>10))); - height -= 120; + height += h/2; } if (cv_debug & DBG_RANDOMIZER) // randomizer testing @@ -596,40 +505,158 @@ static void ST_drawDebugInfo(void) peekres *= 10000; // Change from fixed point peekres >>= FRACBITS; // to displayable decimal - V_DrawRightAlignedString(320, height - 16, V_MONOSPACE, va("Init: %08x", P_GetInitSeed())); - V_DrawRightAlignedString(320, height - 8, V_MONOSPACE, va("Seed: %08x", P_GetRandSeed())); - V_DrawRightAlignedString(320, height, V_MONOSPACE, va("== : .%04d", peekres)); + V_DrawDebugLine(va("Init: %08x", P_GetInitSeed())); + V_DrawDebugLine(va("Seed: %08x", P_GetRandSeed())); + V_DrawDebugLine(va("== : .%04d", peekres)); - height -= 32; + height += h/2; } - if (cv_debug & DBG_MEMORY) + if (cv_debug & DBG_PLAYER) { - V_DrawRightAlignedString(320, height, V_MONOSPACE, va("Heap used: %7sKB", sizeu1(Z_TagsUsage(0, INT32_MAX)>>10))); + INT32 width = 320; + const fixed_t d = AngleFixed(stplyr->drawangle); + + V_DrawDebugLine(va("SHIELD: %5x", stplyr->powers[pw_shield])); + V_DrawDebugLine(va("SCALE: %5d%%", (stplyr->mo->scale*100)>>FRACBITS)); + V_DrawDebugLine(va("CARRY: %5x", stplyr->powers[pw_carry])); + V_DrawDebugLine(va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime])); + V_DrawDebugLine(va("ABILITY: %3d, %3d", stplyr->charability, stplyr->charability2)); + V_DrawDebugLine(va("ACTIONSPD: %5d", stplyr->actionspd>>FRACBITS)); + V_DrawDebugLine(va("PEEL: %3d", stplyr->dashmode)); + V_DrawDebugLine(va("SCOREADD: %3d", stplyr->scoreadd)); + + // Flags + V_DrawDebugFlag(((stplyr->pflags & PF_SHIELDABILITY) ? V_GREENMAP : V_REDMAP), "SH"); + V_DrawDebugFlag(((stplyr->pflags & PF_THOKKED) ? V_GREENMAP : V_REDMAP), "TH"); + V_DrawDebugFlag(((stplyr->pflags & PF_STARTDASH) ? V_GREENMAP : V_REDMAP), "ST"); + V_DrawDebugFlag(((stplyr->pflags & PF_SPINNING) ? V_GREENMAP : V_REDMAP), "SP"); + V_DrawDebugFlag(((stplyr->pflags & PF_NOJUMPDAMAGE) ? V_GREENMAP : V_REDMAP), "ND"); + V_DrawDebugFlag(((stplyr->pflags & PF_JUMPED) ? V_GREENMAP : V_REDMAP), "JD"); + V_DrawDebugFlag(((stplyr->pflags & PF_STARTJUMP) ? V_GREENMAP : V_REDMAP), "SJ"); + V_DrawDebugFlag(0, "PF/SF:"); + height += h; + width = 320; + V_DrawDebugFlag(((stplyr->pflags & PF_INVIS) ? V_GREENMAP : V_REDMAP), "*I"); + V_DrawDebugFlag(((stplyr->pflags & PF_NOCLIP) ? V_GREENMAP : V_REDMAP), "*C"); + V_DrawDebugFlag(((stplyr->pflags & PF_GODMODE) ? V_GREENMAP : V_REDMAP), "*G"); + V_DrawDebugFlag(((stplyr->charflags & SF_SUPER) ? V_GREENMAP : V_REDMAP), "SU"); + V_DrawDebugFlag(((stplyr->pflags & PF_APPLYAUTOBRAKE) ? V_GREENMAP : V_REDMAP), "AA"); + V_DrawDebugFlag(((stplyr->pflags & PF_SLIDING) ? V_GREENMAP : V_REDMAP), "SL"); + V_DrawDebugFlag(((stplyr->pflags & PF_BOUNCING) ? V_GREENMAP : V_REDMAP), "BO"); + V_DrawDebugFlag(((stplyr->pflags & PF_GLIDING) ? V_GREENMAP : V_REDMAP), "GL"); + height += h; + + V_DrawDebugLine(va("DRAWANGLE: %6d", FixedInt(d))); + + height += h/2; } + + if (cv_debug & DBG_DETAILED) + { + INT32 width = 320; + + V_DrawDebugLine(va("CEILINGZ: %6d", stplyr->mo->ceilingz>>FRACBITS)); + V_DrawDebugLine(va("FLOORZ: %6d", stplyr->mo->floorz>>FRACBITS)); + + V_DrawDebugLine(va("CMOMX: %6d", stplyr->cmomx>>FRACBITS)); + V_DrawDebugLine(va("CMOMY: %6d", stplyr->cmomy>>FRACBITS)); + V_DrawDebugLine(va("PMOMZ: %6d", stplyr->mo->pmomz>>FRACBITS)); + + width = 320; + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_APPLYPMOMZ) ? V_GREENMAP : V_REDMAP), "AP"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_SPRUNG) ? V_GREENMAP : V_REDMAP), "SP"); + //V_DrawDebugFlag(((stplyr->mo->eflags & MFE_PUSHED) ? V_GREENMAP : V_REDMAP), "PU"); -- not relevant to players + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_GOOWATER) ? V_GREENMAP : V_REDMAP), "GW"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_VERTICALFLIP) ? V_GREENMAP : V_REDMAP), "VF"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_JUSTSTEPPEDDOWN) ? V_GREENMAP : V_REDMAP), "JS"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_UNDERWATER) ? V_GREENMAP : V_REDMAP), "UW"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_TOUCHWATER) ? V_GREENMAP : V_REDMAP), "TW"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_JUSTHITFLOOR) ? V_GREENMAP : V_REDMAP), "JH"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_ONGROUND) ? V_GREENMAP : V_REDMAP), "OG"); + V_DrawDebugFlag(0, "MFE:"); + height += h; + + V_DrawDebugLine(va("MOMX: %6d", stplyr->rmomx>>FRACBITS)); + V_DrawDebugLine(va("MOMY: %6d", stplyr->rmomy>>FRACBITS)); + V_DrawDebugLine(va("MOMZ: %6d", stplyr->mo->momz>>FRACBITS)); + + V_DrawDebugLine(va("SPEED: %6d", stplyr->speed>>FRACBITS)); + + height += h/2; + } + + if (cv_debug & DBG_BASIC) + { + const fixed_t d = AngleFixed(stplyr->mo->angle); + V_DrawDebugLine(va("X: %6d", stplyr->mo->x>>FRACBITS)); + V_DrawDebugLine(va("Y: %6d", stplyr->mo->y>>FRACBITS)); + V_DrawDebugLine(va("Z: %6d", stplyr->mo->z>>FRACBITS)); + V_DrawDebugLine(va("A: %6d", FixedInt(d))); + + //height += h/2; + } + +#undef V_DrawDebugFlag +#undef V_DrawDebugLine +#undef VFLAGS } static void ST_drawScore(void) { + if (F_GetPromptHideHud(hudinfo[HUD_SCORE].y)) + return; + // SCORE: - ST_DrawPatchFromHud(HUD_SCORE, sboscore); + ST_DrawPatchFromHud(HUD_SCORE, sboscore, V_HUDTRANS); if (objectplacing) { if (op_displayflags > UINT16_MAX) - ST_DrawOverlayPatch(SCX(hudinfo[HUD_SCORENUM].x-tallminus->width), SCY(hudinfo[HUD_SCORENUM].y), tallminus); + ST_DrawTopLeftOverlayPatch((hudinfo[HUD_SCORENUM].x-tallminus->width), hudinfo[HUD_SCORENUM].y, tallminus); else - ST_DrawNumFromHud(HUD_SCORENUM, op_displayflags); + ST_DrawNumFromHud(HUD_SCORENUM, op_displayflags, V_HUDTRANS); } else - ST_DrawNumFromHud(HUD_SCORENUM, stplyr->score); + ST_DrawNumFromHud(HUD_SCORENUM, stplyr->score, V_HUDTRANS); +} + +static void ST_drawRaceNum(INT32 time) +{ + INT32 height, bounce; + patch_t *racenum; + + time += TICRATE; + height = ((3*BASEVIDHEIGHT)>>2) - 8; + bounce = TICRATE - (1 + (time % TICRATE)); + + switch (time/TICRATE) + { + case 3: + racenum = race3; + break; + case 2: + racenum = race2; + break; + case 1: + racenum = race1; + break; + default: + racenum = racego; + break; + } + if (bounce < 3) + { + height -= (2 - bounce); + if (!(P_AutoPause() || paused) && !bounce) + S_StartSound(0, ((racenum == racego) ? sfx_s3kad : sfx_s3ka7)); + } + V_DrawScaledPatch(((BASEVIDWIDTH - SHORT(racenum->width))/2), height, V_PERPLAYER, racenum); } static void ST_drawTime(void) { INT32 seconds, minutes, tictrn, tics; - - // TIME: - ST_DrawPatchFromHudWS(HUD_TIME, sbotime); + boolean downwards = false; if (objectplacing) { @@ -640,126 +667,519 @@ static void ST_drawTime(void) } else { - tics = stplyr->realtime; - seconds = G_TicsToSeconds(tics); + // Counting down the hidetime? + if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (stplyr->realtime <= (hidetime*TICRATE))) + { + tics = (hidetime*TICRATE - stplyr->realtime); + if (tics < 3*TICRATE) + ST_drawRaceNum(tics); + downwards = true; + } + else + { + // Hidetime finish! + if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (stplyr->realtime < ((hidetime+1)*TICRATE))) + ST_drawRaceNum(hidetime*TICRATE - stplyr->realtime); + + // Time limit? + if (gametype != GT_COOP && gametype != GT_RACE && gametype != GT_COMPETITION && cv_timelimit.value && timelimitintics > 0) + { + if (timelimitintics >= stplyr->realtime) + { + tics = (timelimitintics - stplyr->realtime); + if (tics < 3*TICRATE) + ST_drawRaceNum(tics); + } + else // Overtime! + tics = 0; + downwards = true; + } + // Post-hidetime normal. + else if (gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + tics = stplyr->realtime - hidetime*TICRATE; + // "Shadow! What are you doing? Hurry and get back here + // right now before the island blows up with you on it!" + // "Blows up??" *awkward silence* "I've got to get outta + // here and find Amy and Tails right away!" + else if (mapheaderinfo[gamemap-1]->countdown) + { + tics = countdowntimer; + downwards = true; + } + // Normal. + else + tics = stplyr->realtime; + } + minutes = G_TicsToMinutes(tics, true); + seconds = G_TicsToSeconds(tics); tictrn = G_TicsToCentiseconds(tics); } - if (cv_timetic.value == 1) // Tics only -- how simple is this? - ST_DrawNumFromHudWS(HUD_SECONDS, tics); + if (F_GetPromptHideHud(hudinfo[HUD_TIME].y)) + return; + + // TIME: + ST_DrawPatchFromHud(HUD_TIME, ((downwards && (tics < 30*TICRATE) && (leveltime/5 & 1)) ? sboredtime : sbotime), V_HUDTRANS); + + if (!tics && downwards && (leveltime/5 & 1)) // overtime! + return; + + if (cv_timetic.value == 3) // Tics only -- how simple is this? + ST_DrawNumFromHud(HUD_SECONDS, tics, V_HUDTRANS); else { - ST_DrawNumFromHudWS(HUD_MINUTES, minutes); // Minutes - ST_DrawPatchFromHudWS(HUD_TIMECOLON, sbocolon); // Colon - ST_DrawPadNumFromHudWS(HUD_SECONDS, seconds, 2); // Seconds + ST_DrawNumFromHud(HUD_MINUTES, minutes, V_HUDTRANS); // Minutes + ST_DrawPatchFromHud(HUD_TIMECOLON, sbocolon, V_HUDTRANS); // Colon + ST_DrawPadNumFromHud(HUD_SECONDS, seconds, 2, V_HUDTRANS); // Seconds - if (!splitscreen && (cv_timetic.value == 2 || modeattacking)) // there's not enough room for tics in splitscreen, don't even bother trying! + if (cv_timetic.value == 1 || cv_timetic.value == 2 || modeattacking) // there's not enough room for tics in splitscreen, don't even bother trying! { - ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod); // Period - ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2); // Tics + ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod, V_HUDTRANS); // Period + ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2, V_HUDTRANS); // Tics } } } static inline void ST_drawRings(void) { - INT32 ringnum = max(stplyr->health-1, 0); + INT32 ringnum; - ST_DrawPatchFromHudWS(HUD_RINGS, ((stplyr->health <= 1 && leveltime/5 & 1) ? rrings : sborings)); + if (F_GetPromptHideHud(hudinfo[HUD_RINGS].y)) + return; - if (objectplacing) - ringnum = op_currentdoomednum; - else if (!useNightsSS && G_IsSpecialStage(gamemap)) - { - INT32 i; - ringnum = 0; - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].mo && players[i].mo->health > 1) - ringnum += players[i].mo->health - 1; - } + ST_DrawPatchFromHud(HUD_RINGS, ((!stplyr->spectator && stplyr->rings <= 0 && leveltime/5 & 1) ? sboredrings : sborings), ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); - ST_DrawNumFromHudWS(HUD_RINGSNUM, ringnum); + ringnum = ((objectplacing) ? op_currentdoomednum : max(stplyr->rings, 0)); + + if (cv_timetic.value == 2) // Yes, even in modeattacking + ST_DrawNumFromHud(HUD_RINGSNUMTICS, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); + else + ST_DrawNumFromHud(HUD_RINGSNUM, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); } -static void ST_drawLives(void) +static void ST_drawLivesArea(void) { - const INT32 v_splitflag = (splitscreen && stplyr == &players[displayplayer] ? V_SPLITSCREEN : 0); + INT32 v_colmap = V_YELLOWMAP, livescount; + boolean notgreyedout; if (!stplyr->skincolor) return; // Just joined a server, skin isn't loaded yet! + if (F_GetPromptHideHud(hudinfo[HUD_LIVES].y)) + return; + // face background - V_DrawSmallScaledPatch(hudinfo[HUD_LIVESPIC].x, hudinfo[HUD_LIVESPIC].y + (v_splitflag ? -12 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, livesback); + V_DrawSmallScaledPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, + hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, livesback); // face - if (stplyr->mo && stplyr->mo->color) + if (stplyr->spectator) + { + // spectator face + UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, SKINCOLOR_CLOUDY, GTC_CACHE); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, + hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANSHALF, faceprefix[stplyr->skin], colormap); + } + else if (stplyr->mo && stplyr->mo->color) { // skincolor face/super UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->mo->color, GTC_CACHE); patch_t *face = faceprefix[stplyr->skin]; - if (stplyr->powers[pw_super] || stplyr->pflags & PF_NIGHTSMODE) + if (stplyr->powers[pw_super]) face = superprefix[stplyr->skin]; - V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, hudinfo[HUD_LIVESPIC].y + (v_splitflag ? -12 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag,face, colormap); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, + hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, face, colormap); + if (cv_translucenthud.value == 10 && stplyr->powers[pw_super] == 1 && stplyr->mo->tracer) + { + INT32 v_supertrans = (stplyr->mo->tracer->frame & FF_TRANSMASK) >> FF_TRANSSHIFT; + if (v_supertrans < 10) + { + v_supertrans <<= V_ALPHASHIFT; + colormap = R_GetTranslationColormap(stplyr->skin, stplyr->mo->tracer->color, GTC_CACHE); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, + hudinfo[HUD_LIVES].f|V_PERPLAYER|v_supertrans, face, colormap); + } + } } else if (stplyr->skincolor) { // skincolor face UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->skincolor, GTC_CACHE); - V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, hudinfo[HUD_LIVESPIC].y + (v_splitflag ? -12 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag,faceprefix[stplyr->skin], colormap); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, + hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, faceprefix[stplyr->skin], colormap); + } + + // Lives number + if (G_GametypeUsesLives() || gametype == GT_RACE) + { + // x + V_DrawScaledPatch(hudinfo[HUD_LIVES].x+22, hudinfo[HUD_LIVES].y+10, + hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, stlivex); + + // lives number + if (gametype == GT_RACE) + { + livescount = INFLIVES; + notgreyedout = true; + } + else if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) + { + INT32 i; + livescount = 0; + notgreyedout = (stplyr->lives > 0); + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].lives < 1) + continue; + + if (players[i].lives > 1) + notgreyedout = true; + + if (players[i].lives == INFLIVES) + { + livescount = INFLIVES; + break; + } + else if (livescount < 99) + livescount += (players[i].lives); + } + } + else + { + livescount = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? INFLIVES : stplyr->lives); + notgreyedout = true; + } + + if (livescount == INFLIVES) + V_DrawCharacter(hudinfo[HUD_LIVES].x+50, hudinfo[HUD_LIVES].y+8, + '\x16' | 0x80 | hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, false); + else + { + if (livescount > 99) + livescount = 99; + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, + hudinfo[HUD_LIVES].f|V_PERPLAYER|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), va("%d",livescount)); + } + } + // Spectator + else if (stplyr->spectator) + v_colmap = V_GRAYMAP; + // Tag + else if (gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + { + if (stplyr->pflags & PF_TAGIT) + { + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "IT!"); + v_colmap = V_ORANGEMAP; + } + } + // Team name + else if (G_GametypeHasTeams()) + { + if (stplyr->ctfteam == 1) + { + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "RED"); + v_colmap = V_REDMAP; + } + else if (stplyr->ctfteam == 2) + { + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "BLUE"); + v_colmap = V_BLUEMAP; + } } // name - if (strlen(skins[stplyr->skin].hudname) > 8) - V_DrawThinString(hudinfo[HUD_LIVESNAME].x, hudinfo[HUD_LIVESNAME].y + (v_splitflag ? -12 : 0), - V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_MONOSPACE|V_YELLOWMAP|v_splitflag, skins[stplyr->skin].hudname); + v_colmap |= (V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER); + if (strlen(skins[stplyr->skin].hudname) <= 5) + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname); + else if (V_ThinStringWidth(skins[stplyr->skin].hudname, v_colmap) <= 40) + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname); else - V_DrawString(hudinfo[HUD_LIVESNAME].x, hudinfo[HUD_LIVESNAME].y + (v_splitflag ? -12 : 0), - V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_MONOSPACE|V_YELLOWMAP|v_splitflag, skins[stplyr->skin].hudname); - // x - V_DrawScaledPatch(hudinfo[HUD_LIVESX].x, hudinfo[HUD_LIVESX].y + (v_splitflag ? -4 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, stlivex); - // lives - V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, va("%d",stplyr->lives)); + V_DrawThinString(hudinfo[HUD_LIVES].x+18, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname); + + // Power Stones collected + if (G_RingSlingerGametype() +#ifdef HAVE_BLUA + && LUA_HudEnabled(hud_powerstones) +#endif + ) + { + INT32 workx = hudinfo[HUD_LIVES].x+1, j; + if ((leveltime & 1) && stplyr->powers[pw_invulnerability] && (stplyr->powers[pw_sneakers] == stplyr->powers[pw_invulnerability])) // hack; extremely unlikely to be activated unintentionally + { + for (j = 0; j < 7; ++j) // "super" indicator + { + V_DrawScaledPatch(workx, hudinfo[HUD_LIVES].y-9, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, emeraldpics[1][j]); + workx += 8; + } + } + else + { + for (j = 0; j < 7; ++j) // powerstones + { + if (stplyr->powers[pw_emeralds] & (1 << j)) + V_DrawScaledPatch(workx, hudinfo[HUD_LIVES].y-9, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, emeraldpics[1][j]); + workx += 8; + } + } + } } -static void ST_drawLevelTitle(void) +static void ST_drawInput(void) +{ + const INT32 accent = V_SNAPTOLEFT|V_SNAPTOBOTTOM|(stplyr->skincolor ? Color_Index[stplyr->skincolor-1][4] : 0); + INT32 col; + UINT8 offs; + + INT32 x = hudinfo[HUD_LIVES].x, y = hudinfo[HUD_LIVES].y; + + if (stplyr->powers[pw_carry] == CR_NIGHTSMODE) + y -= 16; + + if (F_GetPromptHideHud(y)) + return; + + // O backing + V_DrawFill(x, y-1, 16, 16, hudinfo[HUD_LIVES].f|20); + V_DrawFill(x, y+15, 16, 1, hudinfo[HUD_LIVES].f|29); + + if (cv_showinputjoy.value) // joystick render! + { + /*V_DrawFill(x , y , 16, 1, hudinfo[HUD_LIVES].f|16); + V_DrawFill(x , y+15, 16, 1, hudinfo[HUD_LIVES].f|16); + V_DrawFill(x , y+ 1, 1, 14, hudinfo[HUD_LIVES].f|16); + V_DrawFill(x+15, y+ 1, 1, 14, hudinfo[HUD_LIVES].f|16); -- red's outline*/ + if (stplyr->cmd.sidemove || stplyr->cmd.forwardmove) + { + // joystick hole + V_DrawFill(x+5, y+4, 6, 6, hudinfo[HUD_LIVES].f|29); + // joystick top + V_DrawFill(x+3+stplyr->cmd.sidemove/12, + y+2-stplyr->cmd.forwardmove/12, + 10, 10, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+3+stplyr->cmd.sidemove/9, + y+1-stplyr->cmd.forwardmove/9, + 10, 10, accent); + } + else + { + // just a limited, greyed out joystick top + V_DrawFill(x+3, y+11, 10, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+3, + y+1, + 10, 10, hudinfo[HUD_LIVES].f|16); + } + } + else // arrows! + { + // < + if (stplyr->cmd.sidemove < 0) + { + offs = 0; + col = accent; + } + else + { + offs = 1; + col = hudinfo[HUD_LIVES].f|16; + V_DrawFill(x- 2, y+10, 6, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+ 4, y+ 9, 1, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+ 5, y+ 8, 1, 1, hudinfo[HUD_LIVES].f|29); + } + V_DrawFill(x- 2, y+ 5-offs, 6, 6, col); + V_DrawFill(x+ 4, y+ 6-offs, 1, 4, col); + V_DrawFill(x+ 5, y+ 7-offs, 1, 2, col); + + // ^ + if (stplyr->cmd.forwardmove > 0) + { + offs = 0; + col = accent; + } + else + { + offs = 1; + col = hudinfo[HUD_LIVES].f|16; + V_DrawFill(x+ 5, y+ 3, 1, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+ 6, y+ 4, 1, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+ 7, y+ 5, 2, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+ 9, y+ 4, 1, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+10, y+ 3, 1, 1, hudinfo[HUD_LIVES].f|29); + } + V_DrawFill(x+ 5, y- 2-offs, 6, 6, col); + V_DrawFill(x+ 6, y+ 4-offs, 4, 1, col); + V_DrawFill(x+ 7, y+ 5-offs, 2, 1, col); + + // > + if (stplyr->cmd.sidemove > 0) + { + offs = 0; + col = accent; + } + else + { + offs = 1; + col = hudinfo[HUD_LIVES].f|16; + V_DrawFill(x+12, y+10, 6, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+11, y+ 9, 1, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+10, y+ 8, 1, 1, hudinfo[HUD_LIVES].f|29); + } + V_DrawFill(x+12, y+ 5-offs, 6, 6, col); + V_DrawFill(x+11, y+ 6-offs, 1, 4, col); + V_DrawFill(x+10, y+ 7-offs, 1, 2, col); + + // v + if (stplyr->cmd.forwardmove < 0) + { + offs = 0; + col = accent; + } + else + { + offs = 1; + col = hudinfo[HUD_LIVES].f|16; + V_DrawFill(x+ 5, y+17, 6, 1, hudinfo[HUD_LIVES].f|29); + } + V_DrawFill(x+ 5, y+12-offs, 6, 6, col); + V_DrawFill(x+ 6, y+11-offs, 4, 1, col); + V_DrawFill(x+ 7, y+10-offs, 2, 1, col); + } + +#define drawbutt(xoffs, yoffs, butt, symb)\ + if (stplyr->cmd.buttons & butt)\ + {\ + offs = 0;\ + col = accent;\ + }\ + else\ + {\ + offs = 1;\ + col = hudinfo[HUD_LIVES].f|16;\ + V_DrawFill(x+16+(xoffs), y+9+(yoffs), 10, 1, hudinfo[HUD_LIVES].f|29);\ + }\ + V_DrawFill(x+16+(xoffs), y+(yoffs)-offs, 10, 10, col);\ + V_DrawCharacter(x+16+1+(xoffs), y+1+(yoffs)-offs, hudinfo[HUD_LIVES].f|symb, false) + + drawbutt( 4,-3, BT_JUMP, 'J'); + drawbutt(15,-3, BT_USE, 'S'); + + V_DrawFill(x+16+4, y+8, 21, 10, hudinfo[HUD_LIVES].f|20); // sundial backing + if (stplyr->mo) + { + UINT8 i, precision; + angle_t ang = (stplyr->powers[pw_carry] == CR_NIGHTSMODE) + ? (FixedAngle((stplyr->flyangle-90)<<FRACBITS)>>ANGLETOFINESHIFT) + : (stplyr->mo->angle - R_PointToAngle(stplyr->mo->x, stplyr->mo->y))>>ANGLETOFINESHIFT; + fixed_t xcomp = FINESINE(ang)>>13; + fixed_t ycomp = FINECOSINE(ang)>>14; + if (ycomp == 4) + ycomp = 3; + + if (ycomp > 0) + V_DrawFill(x+16+13-xcomp, y+11-ycomp, 3, 3, accent); // point (behind) + + precision = max(3, abs(xcomp)); + for (i = 0; i < precision; i++) // line + { + V_DrawFill(x+16+14-(i*xcomp)/precision, + y+12-(i*ycomp)/precision, + 1, 1, hudinfo[HUD_LIVES].f|16); + } + + if (ycomp <= 0) + V_DrawFill(x+16+13-xcomp, y+11-ycomp, 3, 3, accent); // point (in front) + } + +#undef drawbutt + + // text above + x -= 2; + y -= 13; + if (stplyr->powers[pw_carry] != CR_NIGHTSMODE) + { + if (stplyr->pflags & PF_AUTOBRAKE) + { + V_DrawThinString(x, y, + hudinfo[HUD_LIVES].f| + ((!stplyr->powers[pw_carry] + && (stplyr->pflags & PF_APPLYAUTOBRAKE) + && !(stplyr->cmd.sidemove || stplyr->cmd.forwardmove) + && (stplyr->rmomx || stplyr->rmomy) + && (!stplyr->capsule || (stplyr->capsule->reactiontime != (stplyr-players)+1))) + ? 0 : V_GRAYMAP), + "AUTOBRAKE"); + y -= 8; + } + if (stplyr->pflags & PF_ANALOGMODE) + { + V_DrawThinString(x, y, hudinfo[HUD_LIVES].f, "ANALOG"); + y -= 8; + } + } + if (!demosynced) // should always be last, so it doesn't push anything else around + V_DrawThinString(x, y, hudinfo[HUD_LIVES].f|((leveltime & 4) ? V_YELLOWMAP : V_REDMAP), "BAD DEMO!!"); +} + +void ST_drawLevelTitle(tic_t titletime) { char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl; char *subttl = mapheaderinfo[gamemap-1]->subttl; INT32 actnum = mapheaderinfo[gamemap-1]->actnum; - INT32 lvlttlxpos; + INT32 lvlttly, zoney, lvlttlxpos, ttlnumxpos, zonexpos; INT32 subttlxpos = BASEVIDWIDTH/2; - INT32 ttlnumxpos; - INT32 zonexpos; - INT32 lvlttly; - INT32 zoney; - - if (!(timeinmap > 2 && timeinmap-3 < 110)) + if (!(titletime > 2 && titletime-3 < 110)) return; + lvlttlxpos = ((BASEVIDWIDTH/2) - (V_LevelNameWidth(lvlttl)/2)); + if (actnum > 0) - { - ttlnum = W_CachePatchName(va("TTL%.2d", actnum), PU_CACHE); - lvlttlxpos = ((BASEVIDWIDTH/2) - (V_LevelNameWidth(lvlttl)/2)) - SHORT(ttlnum->width); - } - else - lvlttlxpos = ((BASEVIDWIDTH/2) - (V_LevelNameWidth(lvlttl)/2)); + lvlttlxpos -= V_LevelActNumWidth(actnum); ttlnumxpos = lvlttlxpos + V_LevelNameWidth(lvlttl); zonexpos = ttlnumxpos - V_LevelNameWidth(M_GetText("ZONE")); + ttlnumxpos++; if (lvlttlxpos < 0) lvlttlxpos = 0; +#if 0 // toaster's experiment. srb2&toast.exe one day, maybe? Requires stuff below to be converted to fixed point. +#define MIDTTLY 79 +#define MIDZONEY 105 +#define MIDDIFF 4 + + if (titletime < 10) + { + fixed_t z = ((titletime - 3)<<FRACBITS)/7; + INT32 ttlh = V_LevelNameHeight(lvlttl); + zoney = (200<<FRACBITS) - ((200 - (MIDZONEY + MIDDIFF))*z); + lvlttly = ((MIDTTLY + ttlh - MIDDIFF)*z) - (ttlh<<FRACBITS); + } + else if (titletime < 105) + { + fixed_t z = (((titletime - 10)*MIDDIFF)<<(FRACBITS+1))/95; + zoney = ((MIDZONEY + MIDDIFF)<<FRACBITS) - z; + lvlttly = ((MIDTTLY - MIDDIFF)<<FRACBITS) + z; + } + else + { + fixed_t z = ((titletime - 105)<<FRACBITS)/7; + INT32 zoneh = V_LevelNameHeight(M_GetText("ZONE")); + zoney = (MIDZONEY + zoneh - MIDDIFF)*(FRACUNIT - z) - (zoneh<<FRACBITS); + lvlttly = ((MIDTTLY + MIDDIFF)<<FRACBITS) + ((200 - (MIDTTLY + MIDDIFF))*z); + } + +#undef MIDTTLY +#undef MIDZONEY +#undef MIDDIFF +#else // There's no consistent algorithm that can accurately define the old positions - // so I just ended up resorting to a single switct statement to define them - switch (timeinmap-3) + // so I just ended up resorting to a single switch statement to define them + switch (titletime-3) { case 0: zoney = 200; lvlttly = 0; break; case 1: zoney = 188; lvlttly = 12; break; @@ -775,345 +1195,411 @@ static void ST_drawLevelTitle(void) case 109: zoney = 0; lvlttly = 200; break; default: zoney = 104; lvlttly = 80; break; } +#endif if (actnum) - V_DrawScaledPatch(ttlnumxpos, zoney, 0, ttlnum); + V_DrawLevelActNum(ttlnumxpos, zoney, V_PERPLAYER, actnum); - V_DrawLevelTitle(lvlttlxpos, lvlttly, 0, lvlttl); + V_DrawLevelTitle(lvlttlxpos, lvlttly, V_PERPLAYER, lvlttl); if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) - V_DrawLevelTitle(zonexpos, zoney, 0, M_GetText("ZONE")); + V_DrawLevelTitle(zonexpos, zoney, V_PERPLAYER, M_GetText("ZONE")); if (lvlttly+48 < 200) - V_DrawCenteredString(subttlxpos, lvlttly+48, V_ALLOWLOWERCASE, subttl); + V_DrawCenteredString(subttlxpos, lvlttly+48, V_PERPLAYER|V_ALLOWLOWERCASE, subttl); } -static void ST_drawFirstPersonHUD(void) +static void ST_drawPowerupHUD(void) { - player_t *player = stplyr; patch_t *p = NULL; UINT16 invulntime = 0; + INT32 offs = hudinfo[HUD_POWERUPS].x; + const UINT8 q = ((splitscreen && stplyr == &players[secondarydisplayplayer]) ? 1 : 0); + static INT32 flagoffs[2] = {0, 0}, shieldoffs[2] = {0, 0}; +#define ICONSEP (16+4) // matches weapon rings HUD + + if (F_GetPromptHideHud(hudinfo[HUD_POWERUPS].y)) + return; - if (player->playerstate != PST_LIVE) + if (stplyr->spectator || stplyr->playerstate != PST_LIVE) return; +// ------- +// Shields +// ------- + // Graue 06-18-2004: no V_NOSCALESTART, no SCX, no SCY, snap to right - if (player->powers[pw_shield] & SH_FORCE) + if (stplyr->powers[pw_shield] & SH_NOSTACK) { - if ((player->powers[pw_shield] & 0xFF) > 0 || leveltime & 1) - p = forceshield; - } - else switch (player->powers[pw_shield] & SH_NOSTACK) - { - case SH_JUMP: p = jumpshield; break; - case SH_ELEMENTAL: p = watershield; break; - case SH_BOMB: p = bombshield; break; - case SH_ATTRACT: p = ringshield; break; - case SH_PITY: p = pityshield; break; - default: break; - } + shieldoffs[q] = ICONSEP; - if (p) - { - if (splitscreen) - V_DrawSmallScaledPatch(312, STRINGY(24), V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); + if ((stplyr->powers[pw_shield] & SH_NOSTACK & ~SH_FORCEHP) == SH_FORCE) + { + UINT8 i, max = (stplyr->powers[pw_shield] & SH_FORCEHP); + for (i = 0; i <= max; i++) + { + V_DrawSmallScaledPatch(offs-(i<<1), hudinfo[HUD_POWERUPS].y-(i<<1), (V_PERPLAYER|hudinfo[HUD_POWERUPS].f)|((i == max) ? V_HUDTRANS : V_HUDTRANSHALF), forceshield); + } + } else - V_DrawScaledPatch(304, 24, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); - } + { + switch (stplyr->powers[pw_shield] & SH_NOSTACK) + { + case SH_WHIRLWIND: p = jumpshield; break; + case SH_ELEMENTAL: p = watershield; break; + case SH_ARMAGEDDON: p = bombshield; break; + case SH_ATTRACT: p = ringshield; break; + case SH_PITY: p = pityshield; break; + case SH_FLAMEAURA: p = flameshield; break; + case SH_BUBBLEWRAP: p = bubbleshield; break; + case SH_THUNDERCOIN: p = thundershield; break; + default: break; + } - // pw_flashing just sets the icon to flash no matter what. - invulntime = player->powers[pw_flashing] ? 1 : player->powers[pw_invulnerability]; - if (invulntime > 3*TICRATE || (invulntime && leveltime & 1)) + if (p) + V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, p); + } + } + else if (shieldoffs[q]) { - if (splitscreen) - V_DrawSmallScaledPatch(312, STRINGY(24) + 14, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, invincibility); + if (shieldoffs[q] > 1) + shieldoffs[q] = 2*shieldoffs[q]/3; else - V_DrawScaledPatch(304, 24 + 28, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, invincibility); + shieldoffs[q] = 0; } - if (player->powers[pw_sneakers] > 3*TICRATE || (player->powers[pw_sneakers] && leveltime & 1)) + offs -= shieldoffs[q]; + +// --------- +// CTF flags +// --------- + + // YOU have a flag. Display a monitor-like icon for it. + if (stplyr->gotflag) { - if (splitscreen) - V_DrawSmallScaledPatch(312, STRINGY(24) + 28, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, sneakers); + flagoffs[q] = ICONSEP; + p = (stplyr->gotflag & GF_REDFLAG) ? gotrflag : gotbflag; + V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, p); + } + else if (flagoffs[q]) + { + if (flagoffs[q] > 1) + flagoffs[q] = 2*flagoffs[q]/3; else - V_DrawScaledPatch(304, 24 + 56, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, sneakers); + flagoffs[q] = 0; } - p = NULL; + offs -= flagoffs[q]; - // Display the countdown drown numbers! - if ((player->powers[pw_underwater] <= 11*TICRATE + 1 - && player->powers[pw_underwater] >= 10*TICRATE + 1) - || (player->powers[pw_spacetime] <= 11*TICRATE + 1 - && player->powers[pw_spacetime] >= 10*TICRATE + 1)) - { - p = count5; - } - else if ((player->powers[pw_underwater] <= 9*TICRATE + 1 - && player->powers[pw_underwater] >= 8*TICRATE + 1) - || (player->powers[pw_spacetime] <= 9*TICRATE + 1 - && player->powers[pw_spacetime] >= 8*TICRATE + 1)) +// -------------------- +// Timer-based powerups +// -------------------- + +#define DRAWTIMERICON(patch, timer) \ + V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, patch); \ + V_DrawRightAlignedThinString(offs + 16, hudinfo[HUD_POWERUPS].y + 8, V_PERPLAYER|hudinfo[HUD_POWERUPS].f, va("%d", timer/TICRATE)); + + // Invincibility, both from monitor and after being hit + invulntime = stplyr->powers[pw_flashing] ? stplyr->powers[pw_flashing] : stplyr->powers[pw_invulnerability]; + // Note: pw_flashing always makes the icon flicker regardless of time, unlike pw_invulnerability + if (stplyr->powers[pw_invulnerability] > 3*TICRATE || (invulntime && leveltime & 1)) { - p = count4; + DRAWTIMERICON(invincibility, invulntime) } - else if ((player->powers[pw_underwater] <= 7*TICRATE + 1 - && player->powers[pw_underwater] >= 6*TICRATE + 1) - || (player->powers[pw_spacetime] <= 7*TICRATE + 1 - && player->powers[pw_spacetime] >= 6*TICRATE + 1)) + + if (invulntime > 7) + offs -= ICONSEP; + else { - p = count3; + UINT8 a = ICONSEP, b = 7-invulntime; + while (b--) + a = 2*a/3; + offs -= a; } - else if ((player->powers[pw_underwater] <= 5*TICRATE + 1 - && player->powers[pw_underwater] >= 4*TICRATE + 1) - || (player->powers[pw_spacetime] <= 5*TICRATE + 1 - && player->powers[pw_spacetime] >= 4*TICRATE + 1)) + + // Super Sneakers + if (stplyr->powers[pw_sneakers] > 3*TICRATE || (stplyr->powers[pw_sneakers] && leveltime & 1)) { - p = count2; + DRAWTIMERICON(sneakers, stplyr->powers[pw_sneakers]) } - else if ((player->powers[pw_underwater] <= 3*TICRATE + 1 - && player->powers[pw_underwater] >= 2*TICRATE + 1) - || (player->powers[pw_spacetime] <= 3*TICRATE + 1 - && player->powers[pw_spacetime] >= 2*TICRATE + 1)) + + if (stplyr->powers[pw_sneakers] > 7) + offs -= ICONSEP; + else { - p = count1; + UINT8 a = ICONSEP, b = 7-stplyr->powers[pw_sneakers]; + while (b--) + a = 2*a/3; + offs -= a; } - else if ((player->powers[pw_underwater] <= 1*TICRATE + 1 - && player->powers[pw_underwater] > 1) - || (player->powers[pw_spacetime] <= 1*TICRATE + 1 - && player->powers[pw_spacetime] > 1)) + + // Gravity Boots + if (stplyr->powers[pw_gravityboots] > 3*TICRATE || (stplyr->powers[pw_gravityboots] && leveltime & 1)) { - p = count0; + DRAWTIMERICON(gravboots, stplyr->powers[pw_gravityboots]) } - if (p) - V_DrawScaledPatch(SCX((BASEVIDWIDTH/2) - (SHORT(p->width)/2) + SHORT(p->leftoffset)), SCY(60 - SHORT(p->topoffset)), - V_NOSCALESTART|V_OFFSET|V_TRANSLUCENT, p); +#undef DRAWTIMERICON +#undef ICONSEP } -// [21:42] <+Rob> Beige - Lavender - Steel Blue - Peach - Orange - Purple - Silver - Yellow - Pink - Red - Blue - Green - Cyan - Gold -static skincolors_t linkColor[14] = -{SKINCOLOR_BEIGE, SKINCOLOR_LAVENDER, SKINCOLOR_STEELBLUE, SKINCOLOR_PEACH, SKINCOLOR_ORANGE, - SKINCOLOR_PURPLE, SKINCOLOR_SILVER, SKINCOLOR_SUPER4, SKINCOLOR_PINK, SKINCOLOR_RED, - SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD}; +static void ST_drawFirstPersonHUD(void) +{ + patch_t *p = NULL; + UINT32 airtime; + spriteframe_t *sprframe; + // If both air timers are active, use the air timer with the least time left + if (stplyr->powers[pw_underwater] && stplyr->powers[pw_spacetime]) + airtime = min(stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime]); + else // Use whichever one is active otherwise + airtime = (stplyr->powers[pw_spacetime]) ? stplyr->powers[pw_spacetime] : stplyr->powers[pw_underwater]; + + if (airtime < 1) + return; // No air timers are active, nothing would be drawn anyway + + airtime--; // The original code was all n*TICRATE + 1, so let's remove 1 tic for simplicity + + if (airtime > 11*TICRATE) + return; // Not time to draw any drown numbers yet + + if (!((airtime > 10*TICRATE - 5) + || (airtime <= 9*TICRATE && airtime > 8*TICRATE - 5) + || (airtime <= 7*TICRATE && airtime > 6*TICRATE - 5) + || (airtime <= 5*TICRATE && airtime > 4*TICRATE - 5) + || (airtime <= 3*TICRATE && airtime > 2*TICRATE - 5) + || (airtime <= 1*TICRATE))) + return; // Don't draw anything between numbers + + if (!((airtime % 10) < 5)) + return; // Keep in line with the flashing thing from third person. + + airtime /= (2*TICRATE); // To be strictly accurate it'd need to be ((airtime/TICRATE) - 1)/2, but integer division rounds down for us + + if (stplyr->charflags & SF_MACHINE) + airtime += 6; // Robots use different drown numbers + + // Get the front angle patch for the frame + sprframe = &sprites[SPR_DRWN].spriteframes[airtime]; + p = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + + // Display the countdown drown numbers! + if (p && !F_GetPromptHideHud(60 - SHORT(p->topoffset))) + V_DrawScaledPatch((BASEVIDWIDTH/2) - (SHORT(p->width)/2) + SHORT(p->leftoffset), 60 - SHORT(p->topoffset), + V_PERPLAYER|V_PERPLAYER|V_TRANSLUCENT, p); +} static void ST_drawNightsRecords(void) { - INT32 aflag = 0; + INT32 aflag = V_PERPLAYER; if (!stplyr->texttimer) return; if (stplyr->texttimer < TICRATE/2) - aflag = (9 - 9*stplyr->texttimer/(TICRATE/2)) << V_ALPHASHIFT; + aflag |= (9 - 9*stplyr->texttimer/(TICRATE/2)) << V_ALPHASHIFT; - // A "Bonus Time Start" by any other name... - if (stplyr->textvar == 1) + switch (stplyr->textvar) { - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(52), V_GREENMAP|aflag, M_GetText("GET TO THE GOAL!")); - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(60), aflag, M_GetText("SCORE MULTIPLIER START!")); - - if (stplyr->finishedtime) + case 1: // A "Bonus Time Start" by any other name... { - V_DrawString(BASEVIDWIDTH/2 - 48, STRINGY(140), aflag, "TIME:"); - V_DrawString(BASEVIDWIDTH/2 - 48, STRINGY(148), aflag, "BONUS:"); - V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, STRINGY(140), V_ORANGEMAP|aflag, va("%d", (stplyr->startedtime - stplyr->finishedtime)/TICRATE)); - V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, STRINGY(148), V_ORANGEMAP|aflag, va("%d", (stplyr->finishedtime/TICRATE) * 100)); - } - } + V_DrawCenteredString(BASEVIDWIDTH/2, 52, V_GREENMAP|aflag, M_GetText("GET TO THE GOAL!")); + V_DrawCenteredString(BASEVIDWIDTH/2, 60, aflag, M_GetText("SCORE MULTIPLIER START!")); - // Get n [more] Spheres - else if (stplyr->textvar <= 3 && stplyr->textvar >= 2) - { - if (!stplyr->capsule) - return; - - // Yes, this string is an abomination. - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(60), aflag, - va(M_GetText("\x80GET\x82 %d\x80 %s%s%s!"), stplyr->capsule->health, - (stplyr->textvar == 3) ? M_GetText("MORE ") : "", - (G_IsSpecialStage(gamemap)) ? "SPHERE" : "RING", - (stplyr->capsule->health > 1) ? "S" : "")); - } - - // End Bonus - else if (stplyr->textvar == 4) - { - V_DrawString(BASEVIDWIDTH/2 - 48, STRINGY(140), aflag, (G_IsSpecialStage(gamemap)) ? "ORBS:" : "RINGS:"); - V_DrawString(BASEVIDWIDTH/2 - 48, STRINGY(148), aflag, "BONUS:"); - V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, STRINGY(140), V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings)); - V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, STRINGY(148), V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings * 50)); - ST_DrawNightsOverlayNum(BASEVIDWIDTH/2 + 48, STRINGY(160), aflag, stplyr->lastmarescore, nightsnum, SKINCOLOR_STEELBLUE); - - // If new record, say so! - if (!(netgame || multiplayer) && G_GetBestNightsScore(gamemap, stplyr->lastmare + 1) <= stplyr->lastmarescore) + if (stplyr->finishedtime) + { + V_DrawString(BASEVIDWIDTH/2 - 48, 140, aflag, "TIME:"); + V_DrawString(BASEVIDWIDTH/2 - 48, 148, aflag, "BONUS:"); + V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, 140, V_ORANGEMAP|aflag, va("%d", (stplyr->startedtime - stplyr->finishedtime)/TICRATE)); + V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, 148, V_ORANGEMAP|aflag, va("%d", (stplyr->finishedtime/TICRATE) * 100)); + } + break; + } + case 2: // Get n Spheres + case 3: // Get n more Spheres { - if (stplyr->texttimer & 16) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(184), V_YELLOWMAP|aflag, "* NEW RECORD *"); + if (!stplyr->capsule) + return; + + // Yes, this string is an abomination. + V_DrawCenteredString(BASEVIDWIDTH/2, 60, aflag, + va(M_GetText("\x80GET\x82 %d\x80 %s%s%s!"), stplyr->capsule->health, + (stplyr->textvar == 3) ? M_GetText("MORE ") : "", + (G_IsSpecialStage(gamemap)) ? "SPHERE" : "CHIP", + (stplyr->capsule->health > 1) ? "S" : "")); + break; } - - if (P_HasGrades(gamemap, stplyr->lastmare + 1)) + case 4: // End Bonus { - if (aflag) - V_DrawTranslucentPatch(BASEVIDWIDTH/2 + 60, STRINGY(160), aflag, - ngradeletters[P_GetGrade(stplyr->lastmarescore, gamemap, stplyr->lastmare)]); - else - V_DrawScaledPatch(BASEVIDWIDTH/2 + 60, STRINGY(160), 0, - ngradeletters[P_GetGrade(stplyr->lastmarescore, gamemap, stplyr->lastmare)]); + V_DrawString(BASEVIDWIDTH/2 - 56, 140, aflag, (G_IsSpecialStage(gamemap)) ? "SPHERES:" : "CHIPS:"); + V_DrawString(BASEVIDWIDTH/2 - 56, 148, aflag, "BONUS:"); + V_DrawRightAlignedString(BASEVIDWIDTH/2 + 56, 140, V_ORANGEMAP|aflag, va("%d", stplyr->finishedspheres)); + V_DrawRightAlignedString(BASEVIDWIDTH/2 + 56, 148, V_ORANGEMAP|aflag, va("%d", stplyr->finishedspheres * 50)); + ST_DrawNightsOverlayNum((BASEVIDWIDTH/2 + 56)<<FRACBITS, 160<<FRACBITS, FRACUNIT, aflag, stplyr->lastmarescore, nightsnum, SKINCOLOR_AZURE); + + // If new record, say so! + if (!(netgame || multiplayer) && G_GetBestNightsScore(gamemap, stplyr->lastmare + 1) <= stplyr->lastmarescore) + { + if (stplyr->texttimer & 16) + V_DrawCenteredString(BASEVIDWIDTH/2, 184, V_YELLOWMAP|aflag, "* NEW RECORD *"); + } + + if (P_HasGrades(gamemap, stplyr->lastmare + 1)) + { + if (aflag) + V_DrawTranslucentPatch(BASEVIDWIDTH/2 + 60, 160, aflag, + ngradeletters[P_GetGrade(stplyr->lastmarescore, gamemap, stplyr->lastmare)]); + else + V_DrawScaledPatch(BASEVIDWIDTH/2 + 60, 160, 0, + ngradeletters[P_GetGrade(stplyr->lastmarescore, gamemap, stplyr->lastmare)]); + } + break; } + default: + break; } } -static void ST_drawNiGHTSHUD(void) +// 2.0-1: [21:42] <+Rob> Beige - Lavender - Steel Blue - Peach - Orange - Purple - Silver - Yellow - Pink - Red - Blue - Green - Cyan - Gold +/*#define NUMLINKCOLORS 14 +static skincolors_t linkColor[NUMLINKCOLORS] = +{SKINCOLOR_BEIGE, SKINCOLOR_LAVENDER, SKINCOLOR_AZURE, SKINCOLOR_PEACH, SKINCOLOR_ORANGE, + SKINCOLOR_MAGENTA, SKINCOLOR_SILVER, SKINCOLOR_SUPERGOLD4, SKINCOLOR_PINK, SKINCOLOR_RED, + SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD};*/ + +// 2.2 indev list: (unix time 1470866042) <Rob> Emerald, Aqua, Cyan, Blue, Pastel, Purple, Magenta, Rosy, Red, Orange, Gold, Yellow, Peridot +/*#define NUMLINKCOLORS 13 +static skincolors_t linkColor[NUMLINKCOLORS] = +{SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_BLUE, SKINCOLOR_PASTEL, + SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, + SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT};*/ + +// 2.2 indev list again: [19:59:52] <baldobo> Ruby > Red > Flame > Sunset > Orange > Gold > Yellow > Lime > Green > Aqua > cyan > Sky > Blue > Pastel > Purple > Bubblegum > Magenta > Rosy > repeat +// [20:00:25] <baldobo> Also Icy for the link freeze text color +// [20:04:03] <baldobo> I would start it on lime +/*#define NUMLINKCOLORS 18 +static skincolors_t linkColor[NUMLINKCOLORS] = +{SKINCOLOR_LIME, SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_SKY, + SKINCOLOR_SAPPHIRE, SKINCOLOR_PASTEL, SKINCOLOR_PURPLE, SKINCOLOR_BUBBLEGUM, SKINCOLOR_MAGENTA, + SKINCOLOR_ROSY, SKINCOLOR_RUBY, SKINCOLOR_RED, SKINCOLOR_FLAME, SKINCOLOR_SUNSET, + SKINCOLOR_ORANGE, SKINCOLOR_GOLD, SKINCOLOR_YELLOW};*/ + +// 2.2+ list for real this time: https://wiki.srb2.org/wiki/User:Rob/Sandbox (check history around 31/10/17, spoopy) +#define NUMLINKCOLORS 12 +static skincolors_t linkColor[2][NUMLINKCOLORS] = { +{SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_SKY, SKINCOLOR_BLUE, SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, + SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT}, +{SKINCOLOR_SEAFOAM, SKINCOLOR_CYAN, SKINCOLOR_WAVE, SKINCOLOR_SAPPHIRE, SKINCOLOR_VAPOR, SKINCOLOR_BUBBLEGUM, + SKINCOLOR_VIOLET, SKINCOLOR_RUBY, SKINCOLOR_FLAME, SKINCOLOR_SUNSET, SKINCOLOR_SANDY, SKINCOLOR_LIME}}; + +static void ST_drawNiGHTSLink(void) { - INT32 origamount; - INT32 minlink = 1; - INT32 total_ringcount; - boolean nosshack = false; + static INT32 prevsel[2] = {0, 0}, prevtime[2] = {0, 0}; + const UINT8 q = ((splitscreen && stplyr == &players[secondarydisplayplayer]) ? 1 : 0); + INT32 sel = ((stplyr->linkcount-1) / 5) % NUMLINKCOLORS, aflag = V_PERPLAYER, mag = ((stplyr->linkcount-1 >= 300) ? 1 : 0); + skincolors_t colornum; + fixed_t x, y, scale; - // When debugging, show "0 Link". - if (cv_debug & DBG_NIGHTSBASIC) - minlink = 0; + if (sel != prevsel[q]) + { + prevsel[q] = sel; + prevtime[q] = 2 + mag; + } - // Cheap hack: don't display when the score is showing (it popping up for a split second when exiting a map is intentional) - if (stplyr->texttimer && stplyr->textvar == 4) - minlink = INT32_MAX; + if (stplyr->powers[pw_nights_linkfreeze] && (!(stplyr->powers[pw_nights_linkfreeze] & 2) || (stplyr->powers[pw_nights_linkfreeze] > flashingtics))) + colornum = SKINCOLOR_ICY; + else + colornum = linkColor[mag][sel]; - if (G_IsSpecialStage(gamemap)) - { // Since special stages share score, time, rings, etc. - // disable splitscreen mode for its HUD. - if (stplyr != &players[displayplayer]) - return; - nosshack = splitscreen; - splitscreen = false; - } + aflag |= ((stplyr->linktimer < (UINT32)nightslinktics/3) + ? (9 - 9*stplyr->linktimer/(nightslinktics/3)) << V_ALPHASHIFT + : 0); - // Link drawing - if ( -#ifdef HAVE_BLUA - LUA_HudEnabled(hud_nightslink) && -#endif - stplyr->linkcount > minlink) + y = (160+11)<<FRACBITS; + aflag |= V_SNAPTOBOTTOM; + + x = (160+4)<<FRACBITS; + + if (prevtime[q]) { - skincolors_t colornum = linkColor[((stplyr->linkcount-1) / 5) % (sizeof(linkColor) / sizeof(skincolors_t))]; - if (stplyr->powers[pw_nights_linkfreeze]) - colornum = SKINCOLOR_WHITE; + scale = ((32 + prevtime[q])<<FRACBITS)/32; + prevtime[q]--; + } + else + scale = FRACUNIT; - if (stplyr->linktimer < 2*TICRATE/3) - { - INT32 linktrans = (9 - 9*stplyr->linktimer/(2*TICRATE/3)) << V_ALPHASHIFT; + y -= (11*scale); - if (splitscreen) - { - ST_DrawNightsOverlayNum(256, STRINGY(152), SPLITFLAGS(V_SNAPTOBOTTOM)|V_SNAPTORIGHT|linktrans, (stplyr->linkcount-1), nightsnum, colornum); - V_DrawTranslucentMappedPatch(264, STRINGY(152), SPLITFLAGS(V_SNAPTOBOTTOM)|V_SNAPTORIGHT|linktrans, nightslink, - colornum == 0 ? colormaps : R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE)); - } - else - { - ST_DrawNightsOverlayNum(160, 160, V_SNAPTOBOTTOM|linktrans, (stplyr->linkcount-1), nightsnum, colornum); - V_DrawTranslucentMappedPatch(168, 160, V_SNAPTOBOTTOM|linktrans, nightslink, - colornum == 0 ? colormaps : R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE)); - } - } - else // normal, fullbright - { -#if 0 // Cool but silly number effect where the previous link number fades away - if (stplyr->linkcount > 2 && stplyr->linktimer > (2*TICRATE) - 9) - { - INT32 offs = 10 - (stplyr->linktimer - (2*TICRATE - 9)); - INT32 ghosttrans = offs << V_ALPHASHIFT; - ST_DrawNightsOverlayNum(160, STRINGY(160+offs), SPLITFLAGS(V_SNAPTOBOTTOM)|ghosttrans, (stplyr->linkcount-2), - nightsnum, colornum); - } -#endif + ST_DrawNightsOverlayNum(x-(4*scale), y, scale, aflag, (stplyr->linkcount-1), nightsnum, colornum); + V_DrawFixedPatch(x+(4*scale), y, scale, aflag, nightslink, + colornum == 0 ? colormaps : R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE)); + + // Show remaining link time left in debug + if (cv_debug & DBG_NIGHTSBASIC) + V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_SNAPTOBOTTOM, va("End in %d.%02d", stplyr->linktimer/TICRATE, G_TicsToCentiseconds(stplyr->linktimer))); +} - if (splitscreen) - { - ST_DrawNightsOverlayNum(256, STRINGY(152), SPLITFLAGS(V_SNAPTOBOTTOM)|V_SNAPTORIGHT, (stplyr->linkcount-1), nightsnum, colornum); - V_DrawMappedPatch(264, STRINGY(152), SPLITFLAGS(V_SNAPTOBOTTOM)|V_SNAPTORIGHT, nightslink, - colornum == 0 ? colormaps : R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE)); - } - else - { - ST_DrawNightsOverlayNum(160, 160, V_SNAPTOBOTTOM, (stplyr->linkcount-1), nightsnum, colornum); - V_DrawMappedPatch(168, 160, V_SNAPTOBOTTOM, nightslink, - colornum == 0 ? colormaps : R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE)); - } - } - // Show remaining link time left in debug - if (cv_debug & DBG_NIGHTSBASIC) - V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_SNAPTOBOTTOM, va("End in %d.%02d", stplyr->linktimer/TICRATE, G_TicsToCentiseconds(stplyr->linktimer))); - } +static void ST_drawNiGHTSHUD(void) +{ + INT32 origamount; + INT32 total_spherecount; + const boolean oldspecialstage = (G_IsSpecialStage(gamemap) && !(maptol & TOL_NIGHTS)); // Drill meter if ( #ifdef HAVE_BLUA LUA_HudEnabled(hud_nightsdrill) && #endif - stplyr->pflags & PF_NIGHTSMODE) + stplyr->powers[pw_carry] == CR_NIGHTSMODE) { - INT32 locx, locy; + INT32 locx = 16, locy = 180; INT32 dfill; UINT8 fillpatch; - if (splitscreen || nosshack) - { - locx = 110; - locy = 188; - } - else - { - locx = 16; - locy = 180; - } - // Use which patch? if (stplyr->pflags & PF_DRILLING) fillpatch = (stplyr->drillmeter & 1) + 1; else fillpatch = 0; - if (splitscreen) - { // 11-5-14 Replaced the old hack with a slightly better hack. -Red - V_DrawScaledPatch(locx, STRINGY(locy)-3, SPLITFLAGS(V_SNAPTOBOTTOM)|V_HUDTRANS, drillbar); - for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill) - V_DrawScaledPatch(locx + 2 + dfill, STRINGY(locy + 3), SPLITFLAGS(V_SNAPTOBOTTOM)|V_HUDTRANS, drillfill[fillpatch]); - } - else if (nosshack) - { // Even dirtier hack-of-a-hack to draw seperate drill meters in splitscreen special stages but nothing else. - splitscreen = true; - V_DrawScaledPatch(locx, STRINGY(locy)-3, V_HUDTRANS, drillbar); - for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill) - V_DrawScaledPatch(locx + 2 + dfill, STRINGY(locy + 3), V_HUDTRANS, drillfill[fillpatch]); - stplyr = &players[secondarydisplayplayer]; - if (stplyr->pflags & PF_DRILLING) - fillpatch = (stplyr->drillmeter & 1) + 1; - else - fillpatch = 0; - V_DrawScaledPatch(locx, STRINGY(locy-3), V_SNAPTOBOTTOM|V_HUDTRANS, drillbar); - for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill) - V_DrawScaledPatch(locx + 2 + dfill, STRINGY(locy + 3), V_SNAPTOBOTTOM|V_HUDTRANS, drillfill[fillpatch]); - stplyr = &players[displayplayer]; - splitscreen = false; - } - else - { // Draw normally. <:3 - V_DrawScaledPatch(locx, locy, V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, drillbar); - for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill) - V_DrawScaledPatch(locx + 2 + dfill, locy + 3, V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, drillfill[fillpatch]); - } + V_DrawScaledPatch(locx, locy, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, drillbar); + for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill) + V_DrawScaledPatch(locx + 2 + dfill, locy + 3, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, drillfill[fillpatch]); // Display actual drill amount and bumper time - if (cv_debug & DBG_NIGHTSBASIC) + if (!splitscreen && (cv_debug & DBG_NIGHTSBASIC)) { if (stplyr->bumpertime) - V_DrawString(SCX(locx), SCY(locy - 8), V_NOSCALESTART|V_REDMAP|V_MONOSPACE, va("BUMPER: 0.%02d", G_TicsToCentiseconds(stplyr->bumpertime))); + V_DrawString(locx, locy - 8, V_REDMAP|V_MONOSPACE, va("BUMPER: 0.%02d", G_TicsToCentiseconds(stplyr->bumpertime))); else - V_DrawString(SCX(locx), SCY(locy - 8), V_NOSCALESTART|V_MONOSPACE, va("Drill: %3d%%", (stplyr->drillmeter*100)/(96*20))); + V_DrawString(locx, locy - 8, V_MONOSPACE, va("Drill: %3d%%", (stplyr->drillmeter*100)/(96*20))); } } + /*if (G_IsSpecialStage(gamemap)) + { // Since special stages share score, time, rings, etc. + // disable splitscreen mode for its HUD. + // -------------------------------------- + // NOPE! Consistency between different splitscreen stuffs + // now we've got the screen squashing instead. ~toast + if (stplyr != &players[displayplayer]) + return; + nosshack = splitscreen; + splitscreen = false; + }*/ + + // Link drawing + if (!oldspecialstage + // Don't display when the score is showing (it popping up for a split second when exiting a map is intentional) + && !(stplyr->texttimer && stplyr->textvar == 4) +#ifdef HAVE_BLUA + && LUA_HudEnabled(hud_nightslink) +#endif + && ((cv_debug & DBG_NIGHTSBASIC) || stplyr->linkcount > 1)) // When debugging, show "0 Link". + { + ST_drawNiGHTSLink(); + } + if (gametype == GT_RACE || gametype == GT_COMPETITION) { ST_drawScore(); @@ -1123,25 +1609,38 @@ static void ST_drawNiGHTSHUD(void) // Begin drawing brackets/chip display #ifdef HAVE_BLUA - if (LUA_HudEnabled(hud_nightsrings)) + if (LUA_HudEnabled(hud_nightsspheres)) { #endif - ST_DrawOverlayPatch(SCX(16), SCY(8), nbracket); + ST_DrawTopLeftOverlayPatch(16, 8, nbracket); if (G_IsSpecialStage(gamemap)) - ST_DrawOverlayPatch(SCX(24), SCY(8) + SCZ(8), nsshud); +#ifdef MANIASPHERES + ST_DrawTopLeftOverlayPatch(24, 16, ( + (stplyr->bonustime && (leveltime & 4)) ? nssbon : nsshud)); +#else + ST_DrawTopLeftOverlayPatch(24, 16, (nsshud)); +#endif else - ST_DrawOverlayPatch(SCX(24), SCY(8) + SCZ(8), nhud[(leveltime/2)%12]); + ST_DrawTopLeftOverlayPatch(24, 16, *(((stplyr->bonustime) ? nbon : nhud)+((leveltime/2)%12))); if (G_IsSpecialStage(gamemap)) { INT32 i; - total_ringcount = 0; + total_spherecount = 0; for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] /*&& players[i].pflags & PF_NIGHTSMODE*/ && players[i].health) - total_ringcount += players[i].health - 1; + if (playeringame[i] /*&& players[i].powers[pw_carry] == CR_NIGHTSMODE*/ && players[i].spheres) + total_spherecount += players[i].spheres; } else - total_ringcount = stplyr->health-1; + total_spherecount = stplyr->spheres; + + /*if (oldspecialstage) + { + if (total_spherecount < ssspheres) + total_spherecount = ssspheres - total_spherecount; + else + total_spherecount = 0; + }*/ if (stplyr->capsule) { @@ -1151,8 +1650,8 @@ static void ST_drawNiGHTSHUD(void) origamount = stplyr->capsule->spawnpoint->angle; I_Assert(origamount > 0); // should not happen now - ST_DrawOverlayPatch(SCX(72), SCY(8), nbracket); - ST_DrawOverlayPatch(SCX(74), SCY(8) + SCZ(4), minicaps); + ST_DrawTopLeftOverlayPatch(72, 8, nbracket); + ST_DrawTopLeftOverlayPatch(74, 8 + 4, minicaps); if (stplyr->capsule->reactiontime != 0) { @@ -1161,10 +1660,10 @@ static void ST_drawNiGHTSHUD(void) for (r = 0; r < 5; r++) { - ST_DrawOverlayPatch(SCX(230 - (7*r)), SCY(144), redstat); - ST_DrawOverlayPatch(SCX(188 - (7*r)), SCY(144), orngstat); - ST_DrawOverlayPatch(SCX(146 - (7*r)), SCY(144), yelstat); - ST_DrawOverlayPatch(SCX(104 - (7*r)), SCY(144), byelstat); + V_DrawScaledPatch(230 - (7*r), 144, V_PERPLAYER|V_HUDTRANS, redstat); + V_DrawScaledPatch(188 - (7*r), 144, V_PERPLAYER|V_HUDTRANS, orngstat); + V_DrawScaledPatch(146 - (7*r), 144, V_PERPLAYER|V_HUDTRANS, yelstat); + V_DrawScaledPatch(104 - (7*r), 144, V_PERPLAYER|V_HUDTRANS, byelstat); } amount = (origamount - stplyr->capsule->health); @@ -1183,7 +1682,7 @@ static void ST_drawNiGHTSHUD(void) if (r > 10) ++t; if (r > 5) ++t; - ST_DrawOverlayPatch(SCX(69 + (7*t)), SCY(144), bluestat); + V_DrawScaledPatch(69 + (7*t), 144, V_PERPLAYER|V_HUDTRANS, bluestat); } } } @@ -1192,40 +1691,58 @@ static void ST_drawNiGHTSHUD(void) INT32 cfill; // Lil' white box! - V_DrawScaledPatch(15, STRINGY(8) + 34, V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulebar); + V_DrawScaledPatch(15, 8 + 34, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulebar); amount = (origamount - stplyr->capsule->health); amount = (amount * length)/origamount; - for (cfill = 0; cfill < amount && cfill < 88; ++cfill) - V_DrawScaledPatch(15 + cfill + 1, STRINGY(8) + 35, V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulefill); + for (cfill = 0; cfill < amount && cfill < length; ++cfill) + V_DrawScaledPatch(15 + cfill + 1, 8 + 35, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulefill); } - if (total_ringcount >= stplyr->capsule->health) - ST_DrawOverlayPatch(SCX(40), SCY(8) + SCZ(5), nredar[leveltime%8]); + if (total_spherecount >= stplyr->capsule->health) + ST_DrawTopLeftOverlayPatch(40, 8 + 5, nredar[leveltime&7]); else - ST_DrawOverlayPatch(SCX(40), SCY(8) + SCZ(5), narrow[(leveltime/2)%8]); + ST_DrawTopLeftOverlayPatch(40, 8 + 5, narrow[(leveltime/2)&7]); + } + else if (oldspecialstage && total_spherecount < (INT32)ssspheres) + { + INT32 cfill, amount; + const INT32 length = 88; + UINT8 em = P_GetNextEmerald(); + ST_DrawTopLeftOverlayPatch(72, 8, nbracket); + + if (em <= 7) + ST_DrawTopLeftOverlayPatch(80, 8 + 8, emeraldpics[0][em]); + + ST_DrawTopLeftOverlayPatch(40, 8 + 5, narrow[(leveltime/2)&7]); + + // Lil' white box! + V_DrawScaledPatch(15, 8 + 34, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulebar); + + amount = (total_spherecount * length)/ssspheres; + + for (cfill = 0; cfill < amount && cfill < length; ++cfill) + V_DrawScaledPatch(15 + cfill + 1, 8 + 35, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulefill); } else - ST_DrawOverlayPatch(SCX(40), SCY(8) + SCZ(5), narrow[8]); + ST_DrawTopLeftOverlayPatch(40, 8 + 5, narrow[8]); - if (total_ringcount >= 100) - ST_DrawOverlayNum((total_ringcount >= 1000) ? SCX(76) : SCX(72), SCY(8) + SCZ(11), total_ringcount); + if (total_spherecount >= 100) + V_DrawTallNum((total_spherecount >= 1000) ? 76 : 72, 8 + 11, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, total_spherecount); else - ST_DrawOverlayNum(SCX(68), SCY(8) + SCZ(11), total_ringcount); + V_DrawTallNum(68, 8 + 11, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, total_spherecount); #ifdef HAVE_BLUA } #endif // Score - if (!stplyr->exiting + if (!stplyr->exiting && !oldspecialstage #ifdef HAVE_BLUA && LUA_HudEnabled(hud_nightsscore) #endif ) - { - ST_DrawNightsOverlayNum(304, STRINGY(16), SPLITFLAGS(V_SNAPTOTOP)|V_SNAPTORIGHT, stplyr->marescore, nightsnum, SKINCOLOR_STEELBLUE); - } + ST_DrawNightsOverlayNum(304<<FRACBITS, 14<<FRACBITS, FRACUNIT, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTORIGHT, stplyr->marescore, nightsnum, SKINCOLOR_AZURE); if (!stplyr->exiting #ifdef HAVE_BLUA @@ -1237,22 +1754,21 @@ static void ST_drawNiGHTSHUD(void) if (modeattacking == ATTACKING_NIGHTS) { INT32 maretime = max(stplyr->realtime - stplyr->marebegunat, 0); - fixed_t cornerx = vid.width, cornery = vid.height-SCZ(20); -#define ASSISHHUDFIX(n) (n*vid.dupx) - ST_DrawOverlayPatch(cornerx-ASSISHHUDFIX(22), cornery, W_CachePatchName("NGRTIMER", PU_HUDGFX)); - ST_DrawPaddedOverlayNum(cornerx-ASSISHHUDFIX(22), cornery, G_TicsToCentiseconds(maretime), 2); - ST_DrawOverlayPatch(cornerx-ASSISHHUDFIX(46), cornery, sboperiod); +#define VFLAGS V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_PERPLAYER|V_HUDTRANS + V_DrawScaledPatch(BASEVIDWIDTH-22, BASEVIDHEIGHT-20, VFLAGS, W_CachePatchName("NGRTIMER", PU_HUDGFX)); + V_DrawPaddedTallNum(BASEVIDWIDTH-22, BASEVIDHEIGHT-20, VFLAGS, G_TicsToCentiseconds(maretime), 2); + V_DrawScaledPatch(BASEVIDWIDTH-46, BASEVIDHEIGHT-20, VFLAGS, sboperiod); if (maretime < 60*TICRATE) - ST_DrawOverlayNum(cornerx-ASSISHHUDFIX(46), cornery, G_TicsToSeconds(maretime)); + V_DrawTallNum(BASEVIDWIDTH-46, BASEVIDHEIGHT-20, VFLAGS, G_TicsToSeconds(maretime)); else { - ST_DrawPaddedOverlayNum(cornerx-ASSISHHUDFIX(46), cornery, G_TicsToSeconds(maretime), 2); - ST_DrawOverlayPatch(cornerx-ASSISHHUDFIX(70), cornery, sbocolon); - ST_DrawOverlayNum(cornerx-ASSISHHUDFIX(70), cornery, G_TicsToMinutes(maretime, true)); + V_DrawPaddedTallNum(BASEVIDWIDTH-46, BASEVIDHEIGHT-20, VFLAGS, G_TicsToSeconds(maretime), 2); + V_DrawScaledPatch(BASEVIDWIDTH-70, BASEVIDHEIGHT-20, VFLAGS, sbocolon); + V_DrawTallNum(BASEVIDWIDTH-70, BASEVIDHEIGHT-20, VFLAGS, G_TicsToMinutes(maretime, true)); } +#undef VFLAGS } -#undef ASSISHHUDFIX } // Ideya time remaining @@ -1264,27 +1780,28 @@ static void ST_drawNiGHTSHUD(void) { INT32 realnightstime = stplyr->nightstime/TICRATE; INT32 numbersize; + UINT8 col = ((realnightstime < 10) ? SKINCOLOR_RED : SKINCOLOR_SUPERGOLD4); if (G_IsSpecialStage(gamemap)) { tic_t lowest_time = stplyr->nightstime; INT32 i; for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE && players[i].nightstime < lowest_time) + if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE && players[i].nightstime < lowest_time) lowest_time = players[i].nightstime; realnightstime = lowest_time/TICRATE; } - if (stplyr->powers[pw_flashing] > TICRATE ) // was hit + if (stplyr->powers[pw_flashing] > TICRATE) // was hit { UINT16 flashingLeft = stplyr->powers[pw_flashing]-(TICRATE); if (flashingLeft < TICRATE/2) // Start fading out { UINT32 fadingFlag = (9 - 9*flashingLeft/(TICRATE/2)) << V_ALPHASHIFT; - V_DrawTranslucentPatch(SCX(160 - (minus5sec->width/2)), SCY(28), V_NOSCALESTART|fadingFlag, minus5sec); + V_DrawTranslucentPatch(160 - (minus5sec->width/2), 28, V_PERPLAYER|fadingFlag, minus5sec); } else - V_DrawScaledPatch(SCX(160 - (minus5sec->width/2)), SCY(28), V_NOSCALESTART, minus5sec); + V_DrawScaledPatch(160 - (minus5sec->width/2), 28, V_PERPLAYER, minus5sec); } if (realnightstime < 10) @@ -1294,56 +1811,91 @@ static void ST_drawNiGHTSHUD(void) else numbersize = 48/2; - if (realnightstime < 10) - ST_DrawNightsOverlayNum(160 + numbersize, STRINGY(12), SPLITFLAGS(V_SNAPTOTOP), realnightstime, - nightsnum, SKINCOLOR_RED); - else - ST_DrawNightsOverlayNum(160 + numbersize, STRINGY(12), SPLITFLAGS(V_SNAPTOTOP), realnightstime, - nightsnum, SKINCOLOR_SUPER4); + if ((oldspecialstage && leveltime & 2) + && (stplyr->mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER))) + col = SKINCOLOR_ORANGE; + + ST_DrawNightsOverlayNum((160 + numbersize)<<FRACBITS, 14<<FRACBITS, FRACUNIT, V_PERPLAYER|V_SNAPTOTOP, realnightstime, nightsnum, col); // Show exact time in debug if (cv_debug & DBG_NIGHTSBASIC) V_DrawString(160 + numbersize + 8, 24, V_SNAPTOTOP|((realnightstime < 10) ? V_REDMAP : V_YELLOWMAP), va("%02d", G_TicsToCentiseconds(stplyr->nightstime))); } - // Show pickup durations - if (cv_debug & DBG_NIGHTSBASIC) + if (oldspecialstage) { - UINT16 pwr; - - if (stplyr->powers[pw_nights_superloop]) + if (leveltime < 5*TICRATE) { - pwr = stplyr->powers[pw_nights_superloop]; - V_DrawSmallScaledPatch(SCX(110), SCY(44), V_NOSCALESTART, W_CachePatchName("NPRUA0",PU_CACHE)); - V_DrawThinString(SCX(106), SCY(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); + INT32 aflag = V_PERPLAYER; + tic_t drawtime = (5*TICRATE) - leveltime; + if (drawtime < TICRATE/2) + aflag |= (9 - 9*drawtime/(TICRATE/2)) << V_ALPHASHIFT; + // This one, not quite as much so. + V_DrawCenteredString(BASEVIDWIDTH/2, 60, aflag, + va(M_GetText("\x80GET\x82 %d\x80 SPHERE%s!"), ssspheres, + (ssspheres > 1) ? "S" : "")); } - - if (stplyr->powers[pw_nights_helper]) + } + else + { + // Show pickup durations + if (cv_debug & DBG_NIGHTSBASIC) { - pwr = stplyr->powers[pw_nights_helper]; - V_DrawSmallScaledPatch(SCX(150), SCY(44), V_NOSCALESTART, W_CachePatchName("NPRUC0",PU_CACHE)); - V_DrawThinString(SCX(146), SCY(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); - } + UINT16 pwr; - if (stplyr->powers[pw_nights_linkfreeze]) - { - pwr = stplyr->powers[pw_nights_linkfreeze]; - V_DrawSmallScaledPatch(SCX(190), SCY(44), V_NOSCALESTART, W_CachePatchName("NPRUE0",PU_CACHE)); - V_DrawThinString(SCX(186), SCY(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); + if (stplyr->powers[pw_nights_superloop]) + { + pwr = stplyr->powers[pw_nights_superloop]; + V_DrawSmallScaledPatch(110, 44, 0, W_CachePatchName("NPRUA0",PU_CACHE)); + V_DrawThinString(106, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); + } + + if (stplyr->powers[pw_nights_helper]) + { + pwr = stplyr->powers[pw_nights_helper]; + V_DrawSmallScaledPatch(150, 44, 0, W_CachePatchName("NPRUC0",PU_CACHE)); + V_DrawThinString(146, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); + } + + if (stplyr->powers[pw_nights_linkfreeze]) + { + pwr = stplyr->powers[pw_nights_linkfreeze]; + V_DrawSmallScaledPatch(190, 44, 0, W_CachePatchName("NPRUE0",PU_CACHE)); + V_DrawThinString(186, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); + } } - } - // Records/extra text + // Records/extra text #ifdef HAVE_BLUA - if (LUA_HudEnabled(hud_nightsrecords)) + if (LUA_HudEnabled(hud_nightsrecords)) #endif - ST_drawNightsRecords(); + ST_drawNightsRecords(); + } +} - if (nosshack) - splitscreen = true; +static void ST_drawWeaponSelect(INT32 xoffs, INT32 y) +{ + INT32 q = stplyr->weapondelay, del = 0, p = 16; + while (q) + { + if (q > p) + { + del += p; + q -= p; + q /= 2; + if (p > 1) + p /= 2; + } + else + { + del += q; + break; + } + } + V_DrawScaledPatch(6 + xoffs, y-2 - del/2, V_PERPLAYER|V_SNAPTOBOTTOM, curweapon); } -static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, INT32 xoffs, patch_t *pat) +static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, INT32 xoffs, INT32 y, patch_t *pat) { INT32 txtflags = 0, patflags = 0; @@ -1353,31 +1905,31 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I txtflags |= V_YELLOWMAP; if (weapon == pw_infinityring - || (stplyr->ringweapons & rwflag && stplyr->health > 1)) - txtflags |= V_20TRANS; + || (stplyr->ringweapons & rwflag)) + ; //txtflags |= V_20TRANS; else { txtflags |= V_TRANSLUCENT; patflags = V_80TRANS; } - V_DrawScaledPatch(8 + xoffs, STRINGY(162), V_SNAPTOLEFT|patflags, pat); - - if (stplyr->powers[weapon] > 99) - V_DrawThinString(8 + xoffs + 1, STRINGY(162), V_SNAPTOLEFT|txtflags, va("%d", stplyr->powers[weapon])); - else - V_DrawString(8 + xoffs, STRINGY(162), V_SNAPTOLEFT|txtflags, va("%d", stplyr->powers[weapon])); + V_DrawScaledPatch(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|patflags, pat); + V_DrawRightAlignedThinString(24 + xoffs, y + 8, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon])); if (stplyr->currentweapon == wepflag) - V_DrawScaledPatch(6 + xoffs, STRINGY(162 - (splitscreen ? 4 : 2)), V_SNAPTOLEFT, curweapon); + ST_drawWeaponSelect(xoffs, y); } else if (stplyr->ringweapons & rwflag) - V_DrawScaledPatch(8 + xoffs, STRINGY(162), V_SNAPTOLEFT|V_TRANSLUCENT, pat); + V_DrawScaledPatch(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|V_TRANSLUCENT, pat); } static void ST_drawMatchHUD(void) { - INT32 offset = (BASEVIDWIDTH / 2) - (NUM_WEAPONS * 10); + const INT32 y = 176; // HUD_LIVES + INT32 offset = (BASEVIDWIDTH / 2) - (NUM_WEAPONS * 10) - 6; + + if (F_GetPromptHideHud(y)) + return; if (!G_RingSlingerGametype()) return; @@ -1385,234 +1937,275 @@ static void ST_drawMatchHUD(void) if (G_TagGametype() && !(stplyr->pflags & PF_TAGIT)) return; -#ifdef HAVE_BLUA - if (LUA_HudEnabled(hud_weaponrings)) { -#endif + { + if (stplyr->powers[pw_infinityring]) + ST_drawWeaponRing(pw_infinityring, 0, 0, offset, y, infinityring); + else + { + if (stplyr->rings > 0) + V_DrawScaledPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM, normring); + else + V_DrawTranslucentPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM|V_80TRANS, normring); - if (stplyr->powers[pw_infinityring]) - ST_drawWeaponRing(pw_infinityring, 0, 0, offset, infinityring); - else if (stplyr->health > 1) - V_DrawScaledPatch(8 + offset, STRINGY(162), V_SNAPTOLEFT, normring); - else - V_DrawTranslucentPatch(8 + offset, STRINGY(162), V_SNAPTOLEFT|V_80TRANS, normring); - - if (!stplyr->currentweapon) - V_DrawScaledPatch(6 + offset, STRINGY(162 - (splitscreen ? 4 : 2)), V_SNAPTOLEFT, curweapon); - - offset += 20; - ST_drawWeaponRing(pw_automaticring, RW_AUTO, WEP_AUTO, offset, autoring); - offset += 20; - ST_drawWeaponRing(pw_bouncering, RW_BOUNCE, WEP_BOUNCE, offset, bouncering); - offset += 20; - ST_drawWeaponRing(pw_scatterring, RW_SCATTER, WEP_SCATTER, offset, scatterring); - offset += 20; - ST_drawWeaponRing(pw_grenadering, RW_GRENADE, WEP_GRENADE, offset, grenadering); - offset += 20; - ST_drawWeaponRing(pw_explosionring, RW_EXPLODE, WEP_EXPLODE, offset, explosionring); - offset += 20; - ST_drawWeaponRing(pw_railring, RW_RAIL, WEP_RAIL, offset, railring); + if (!stplyr->currentweapon) + ST_drawWeaponSelect(offset, y); + } -#ifdef HAVE_BLUA + offset += 20; + ST_drawWeaponRing(pw_automaticring, RW_AUTO, WEP_AUTO, offset, y, autoring); + offset += 20; + ST_drawWeaponRing(pw_bouncering, RW_BOUNCE, WEP_BOUNCE, offset, y, bouncering); + offset += 20; + ST_drawWeaponRing(pw_scatterring, RW_SCATTER, WEP_SCATTER, offset, y, scatterring); + offset += 20; + ST_drawWeaponRing(pw_grenadering, RW_GRENADE, WEP_GRENADE, offset, y, grenadering); + offset += 20; + ST_drawWeaponRing(pw_explosionring, RW_EXPLODE, WEP_EXPLODE, offset, y, explosionring); + offset += 20; + ST_drawWeaponRing(pw_railring, RW_RAIL, WEP_RAIL, offset, y, railring); } +} - if (LUA_HudEnabled(hud_powerstones)) { -#endif +static void ST_drawTextHUD(void) +{ + INT32 y = 42 + 16; // HUD_RINGS + boolean donef12 = false; - // Power Stones collected - offset = 136; // Used for Y now +#define textHUDdraw(str) \ +{\ + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, str);\ + y += 8;\ +} - if (stplyr->powers[pw_emeralds] & EMERALD1) - V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[0]); + if (F_GetPromptHideHud(y)) + return; - offset += 8; + if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE)) + textHUDdraw(M_GetText("\x86""Spectator mode:")) - if (stplyr->powers[pw_emeralds] & EMERALD2) - V_DrawScaledPatch(40, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[1]); + if (circuitmap) + { + if (stplyr->exiting) + textHUDdraw(M_GetText("\x82""FINISHED!")) + else + textHUDdraw(va("Lap:""\x82 %u/%d", stplyr->laps+1, cv_numlaps.value)) + } - if (stplyr->powers[pw_emeralds] & EMERALD6) - V_DrawScaledPatch(16, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[5]); + if (!stplyr->spectator && stplyr->exiting && cv_playersforexit.value && gametype == GT_COOP) + { + INT32 i, total = 0, exiting = 0; - offset += 16; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + if (players[i].lives <= 0) + continue; - if (stplyr->powers[pw_emeralds] & EMERALD3) - V_DrawScaledPatch(40, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[2]); + total++; + if (players[i].exiting) + exiting++; + } - if (stplyr->powers[pw_emeralds] & EMERALD5) - V_DrawScaledPatch(16, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[4]); + if (cv_playersforexit.value != 4) + { + total *= cv_playersforexit.value; + if (total & 3) + total += 4; // round up + total /= 4; + } - offset += 8; + if (exiting < total) + { + if (!splitscreen && !donef12) + { + textHUDdraw(M_GetText("\x82""VIEWPOINT:""\x80 Switch view")) + donef12 = true; + } + total -= exiting; + textHUDdraw(va(M_GetText("%d player%s remaining"), total, ((total == 1) ? "" : "s"))) + } + } + else if (gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1))) + { + if (!splitscreen && !donef12) + { + textHUDdraw(M_GetText("\x82""VIEWPOINT:""\x80 Switch view")) + donef12 = true; + } + } + else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. + { + INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; - if (stplyr->powers[pw_emeralds] & EMERALD4) - V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[3]); + if (respawntime > 0 && !stplyr->spectator) + textHUDdraw(va(M_GetText("Respawn in %d..."), respawntime)) + else + textHUDdraw(M_GetText("\x82""JUMP:""\x80 Respawn")) + } + else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE)) + { + if (!splitscreen && !donef12) + { + textHUDdraw(M_GetText("\x82""VIEWPOINT:""\x80 Switch view")) + donef12 = true; + } - offset -= 16; + textHUDdraw(M_GetText("\x82""JUMP:""\x80 Rise")) + textHUDdraw(M_GetText("\x82""SPIN:""\x80 Lower")) - if (stplyr->powers[pw_emeralds] & EMERALD7) - V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[6]); + if (G_IsSpecialStage(gamemap) && (maptol & TOL_NIGHTS)) + textHUDdraw(M_GetText("\x82""Wait for the stage to end...")) + else if (gametype == GT_COOP) + { + if (stplyr->lives <= 0 + && cv_cooplives.value == 2 + && (netgame || multiplayer)) + { + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; -#ifdef HAVE_BLUA - } -#endif -} + if (&players[i] == stplyr) + continue; -static inline void ST_drawRaceHUD(void) -{ - if (leveltime > TICRATE && leveltime <= 2*TICRATE) - V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(race3->width))/2), (INT32)(SCY(BASEVIDHEIGHT/2)), V_NOSCALESTART, race3); - else if (leveltime > 2*TICRATE && leveltime <= 3*TICRATE) - V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(race2->width))/2), (INT32)(SCY(BASEVIDHEIGHT/2)), V_NOSCALESTART, race2); - else if (leveltime > 3*TICRATE && leveltime <= 4*TICRATE) - V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(race1->width))/2), (INT32)(SCY(BASEVIDHEIGHT/2)), V_NOSCALESTART, race1); - else if (leveltime > 4*TICRATE && leveltime <= 5*TICRATE) - V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(racego->width))/2), (INT32)(SCY(BASEVIDHEIGHT/2)), V_NOSCALESTART, racego); + if (players[i].lives > 1) + break; + } - if (circuitmap) - { - if (stplyr->exiting) - V_DrawString(hudinfo[HUD_LAP].x, STRINGY(hudinfo[HUD_LAP].y), V_YELLOWMAP, "FINISHED!"); + if (i != MAXPLAYERS) + textHUDdraw(M_GetText("You'll steal a life on respawn...")) + else + textHUDdraw(M_GetText("Wait to respawn...")) + } + else + textHUDdraw(M_GetText("Wait to respawn...")) + } else - V_DrawString(hudinfo[HUD_LAP].x, STRINGY(hudinfo[HUD_LAP].y), 0, va("Lap: %u/%d", stplyr->laps+1, cv_numlaps.value)); + textHUDdraw(M_GetText("\x82""FIRE:""\x80 Enter game")) } -} -static void ST_drawTagHUD(void) -{ - char pstime[33] = ""; - char pstext[33] = ""; - - // Figure out what we're going to print. - if (leveltime < hidetime * TICRATE) //during the hide time, the seeker and hiders have different messages on their HUD. + if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator)) { - if (hidetime) - sprintf(pstime, "%d", (hidetime - leveltime/TICRATE)); //hide time is in seconds, not tics. - - if (stplyr->pflags & PF_TAGIT && !stplyr->spectator) - sprintf(pstext, "%s", M_GetText("WAITING FOR PLAYERS TO HIDE...")); - else + if (leveltime < hidetime * TICRATE) { - if (!stplyr->spectator) //spectators get a generic HUD message rather than a gametype specific one. + if (stplyr->pflags & PF_TAGIT) { - if (gametype == GT_HIDEANDSEEK) //hide and seek. - sprintf(pstext, "%s", M_GetText("HIDE BEFORE TIME RUNS OUT!")); - else //default - sprintf(pstext, "%s", M_GetText("FLEE BEFORE YOU ARE HUNTED!")); + textHUDdraw(M_GetText("\x82""You are blindfolded!")) + textHUDdraw(M_GetText("Waiting for players to hide...")) } + else if (gametype == GT_HIDEANDSEEK) + textHUDdraw(M_GetText("Hide before time runs out!")) else - sprintf(pstext, "%s", M_GetText("HIDE TIME REMAINING:")); + textHUDdraw(M_GetText("Flee before you are hunted!")) } - } - else - { - if (cv_timelimit.value && timelimitintics >= leveltime) - sprintf(pstime, "%d", (timelimitintics-leveltime)/TICRATE); - - if (stplyr->pflags & PF_TAGIT) - sprintf(pstext, "%s", M_GetText("YOU'RE IT!")); - else + else if (gametype == GT_HIDEANDSEEK && !(stplyr->pflags & PF_TAGIT)) { - if (cv_timelimit.value) - sprintf(pstext, "%s", M_GetText("TIME REMAINING:")); - else //Since having no hud message in tag is not characteristic: - sprintf(pstext, "%s", M_GetText("NO TIME LIMIT")); + if (!splitscreen && !donef12) + { + textHUDdraw(M_GetText("\x82""VIEWPOINT:""\x80 Switch view")) + donef12 = true; + } + textHUDdraw(M_GetText("You cannot move while hiding.")) } } - // Print the stuff. - if (pstext[0]) - { - if (splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(168), 0, pstext); - else - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(184), 0, pstext); - } - if (pstime[0]) - { - if (splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(184), 0, pstime); - else - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(192), 0, pstime); - } +#undef textHUDdraw + } -static void ST_drawCTFHUD(void) +static inline void ST_drawRaceHUD(void) { - INT32 i; - UINT16 whichflag = 0; + if (leveltime > TICRATE && leveltime <= 5*TICRATE) + ST_drawRaceNum(4*TICRATE - leveltime); +} - // Draw the flags - V_DrawSmallScaledPatch(256, (splitscreen) ? STRINGY(160) : STRINGY(176), V_HUDTRANS, rflagico); - V_DrawSmallScaledPatch(288, (splitscreen) ? STRINGY(160) : STRINGY(176), V_HUDTRANS, bflagico); +static void ST_drawTeamHUD(void) +{ + patch_t *p; +#define SEP 20 - for (i = 0; i < MAXPLAYERS; i++) - { - if (players[i].gotflag & GF_REDFLAG) // Red flag isn't at base - V_DrawScaledPatch(256, (splitscreen) ? STRINGY(156) : STRINGY(174), V_HUDTRANS, nonicon); - else if (players[i].gotflag & GF_BLUEFLAG) // Blue flag isn't at base - V_DrawScaledPatch(288, (splitscreen) ? STRINGY(156) : STRINGY(174), V_HUDTRANS, nonicon); + if (F_GetPromptHideHud(0)) // y base is 0 + return; - whichflag |= players[i].gotflag; - if ((whichflag & (GF_REDFLAG|GF_BLUEFLAG)) == (GF_REDFLAG|GF_BLUEFLAG)) - break; // both flags were found, let's stop early - } + if (gametype == GT_CTF) + p = bflagico; + else + p = bmatcico; - // YOU have a flag. Display a monitor-like icon for it. - if (stplyr->gotflag) - { - patch_t *p = (stplyr->gotflag & GF_REDFLAG) ? gotrflag : gotbflag; + V_DrawSmallScaledPatch(BASEVIDWIDTH/2 - SEP - SHORT(p->width)/4, 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, p); - if (splitscreen) - V_DrawSmallScaledPatch(312, STRINGY(24) + 42, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); - else - V_DrawScaledPatch(304, 24 + 84, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); - } + if (gametype == GT_CTF) + p = rflagico; + else + p = rmatcico; + + V_DrawSmallScaledPatch(BASEVIDWIDTH/2 + SEP - SHORT(p->width)/4, 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, p); - // Display a countdown timer showing how much time left until the flag your team dropped returns to base. + if (gametype != GT_CTF) + goto num; { - char timeleft[33]; - if (redflag && redflag->fuse > 1) + INT32 i; + UINT16 whichflag = 0; + + // Show which flags aren't at base. + for (i = 0; i < MAXPLAYERS; i++) { - sprintf(timeleft, "%u", (redflag->fuse / TICRATE)); - V_DrawCenteredString(268, STRINGY(184), V_YELLOWMAP|V_HUDTRANS, timeleft); + if (players[i].gotflag & GF_BLUEFLAG) // Blue flag isn't at base + V_DrawScaledPatch(BASEVIDWIDTH/2 - SEP - SHORT(nonicon->width)/2, 0, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, nonicon); + if (players[i].gotflag & GF_REDFLAG) // Red flag isn't at base + V_DrawScaledPatch(BASEVIDWIDTH/2 + SEP - SHORT(nonicon2->width)/2, 0, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, nonicon2); + + whichflag |= players[i].gotflag; + if ((whichflag & (GF_REDFLAG|GF_BLUEFLAG)) == (GF_REDFLAG|GF_BLUEFLAG)) + break; // both flags were found, let's stop early } - if (blueflag && blueflag->fuse > 1) + // Display a countdown timer showing how much time left until the flag returns to base. { - sprintf(timeleft, "%u", (blueflag->fuse / TICRATE)); - V_DrawCenteredString(300, STRINGY(184), V_YELLOWMAP|V_HUDTRANS, timeleft); + if (blueflag && blueflag->fuse > 1) + V_DrawCenteredString(BASEVIDWIDTH/2 - SEP, 8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", (blueflag->fuse / TICRATE))); + + if (redflag && redflag->fuse > 1) + V_DrawCenteredString(BASEVIDWIDTH/2 + SEP, 8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", (redflag->fuse / TICRATE))); } } -} -// Draws "Red Team", "Blue Team", or "Spectator" for team gametypes. -static inline void ST_drawTeamName(void) -{ - if (stplyr->ctfteam == 1) - V_DrawString(256, (splitscreen) ? STRINGY(184) : STRINGY(192), V_HUDTRANSHALF, "RED TEAM"); - else if (stplyr->ctfteam == 2) - V_DrawString(248, (splitscreen) ? STRINGY(184) : STRINGY(192), V_HUDTRANSHALF, "BLUE TEAM"); - else - V_DrawString(244, (splitscreen) ? STRINGY(184) : STRINGY(192), V_HUDTRANSHALF, "SPECTATOR"); +num: + V_DrawCenteredString(BASEVIDWIDTH/2 - SEP, 16, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", bluescore)); + V_DrawCenteredString(BASEVIDWIDTH/2 + SEP, 16, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", redscore)); + +#undef SEP } -static void ST_drawSpecialStageHUD(void) +/*static void ST_drawSpecialStageHUD(void) { - if (totalrings > 0) - ST_DrawNumFromHudWS(HUD_SS_TOTALRINGS, totalrings); + if (ssspheres > 0) + { + if (hudinfo[HUD_SS_TOTALRINGS].x) + ST_DrawNumFromHud(HUD_SS_TOTALRINGS, ssspheres, V_HUDTRANS); + else if (cv_timetic.value == 2) + V_DrawTallNum(hudinfo[HUD_RINGSNUMTICS].x, hudinfo[HUD_SS_TOTALRINGS].y, hudinfo[HUD_RINGSNUMTICS].f|V_PERPLAYER|V_HUDTRANS, ssspheres); + else + V_DrawTallNum(hudinfo[HUD_RINGSNUM].x, hudinfo[HUD_SS_TOTALRINGS].y, hudinfo[HUD_RINGSNUM].f|V_PERPLAYER|V_HUDTRANS, ssspheres); + } - if (leveltime < 5*TICRATE && totalrings > 0) + if (leveltime < 5*TICRATE && ssspheres > 0) { - ST_DrawPatchFromHud(HUD_GETRINGS, getall); - ST_DrawNumFromHud(HUD_GETRINGSNUM, totalrings); + ST_DrawPatchFromHud(HUD_GETRINGS, getall, V_HUDTRANS); + ST_DrawNumFromHud(HUD_GETRINGSNUM, ssspheres, V_HUDTRANS); } if (sstimer) { - V_DrawString(hudinfo[HUD_TIMELEFT].x, STRINGY(hudinfo[HUD_TIMELEFT].y), V_HUDTRANS, M_GetText("TIME LEFT")); - ST_DrawNumFromHud(HUD_TIMELEFTNUM, sstimer/TICRATE); + V_DrawString(hudinfo[HUD_TIMELEFT].x, hudinfo[HUD_TIMELEFT].y, hudinfo[HUD_TIMELEFT].f|V_PERPLAYER|V_HUDTRANS, M_GetText("TIME LEFT")); + ST_DrawNumFromHud(HUD_TIMELEFTNUM, sstimer/TICRATE, V_HUDTRANS); } else - ST_DrawPatchFromHud(HUD_TIMEUP, timeup); -} + ST_DrawPatchFromHud(HUD_TIMEUP, timeup, V_HUDTRANS); +}*/ static INT32 ST_drawEmeraldHuntIcon(mobj_t *hunt, patch_t **patches, INT32 offset) { @@ -1650,7 +2243,8 @@ static INT32 ST_drawEmeraldHuntIcon(mobj_t *hunt, patch_t **patches, INT32 offse interval = 0; } - V_DrawScaledPatch(hudinfo[HUD_HUNTPICS].x+offset, STRINGY(hudinfo[HUD_HUNTPICS].y), V_HUDTRANS, patches[i]); + if (!F_GetPromptHideHud(hudinfo[HUD_HUNTPICS].y)) + V_DrawScaledPatch(hudinfo[HUD_HUNTPICS].x+offset, hudinfo[HUD_HUNTPICS].y, hudinfo[HUD_HUNTPICS].f|V_PERPLAYER|V_HUDTRANS, patches[i]); return interval; } @@ -1748,7 +2342,8 @@ static void ST_overlayDrawer(void) //hu_showscores = auto hide score/time/rings when tab rankings are shown if (!(hu_showscores && (netgame || multiplayer))) { - if (maptol & TOL_NIGHTS) + if ((maptol & TOL_NIGHTS || G_IsSpecialStage(gamemap)) && + !F_GetPromptHideHudAll()) ST_drawNiGHTSHUD(); else { @@ -1764,17 +2359,22 @@ static void ST_overlayDrawer(void) if (LUA_HudEnabled(hud_rings)) #endif ST_drawRings(); - if (G_GametypeUsesLives() + + if (!modeattacking #ifdef HAVE_BLUA && LUA_HudEnabled(hud_lives) #endif ) - ST_drawLives(); + ST_drawLivesArea(); } } // GAME OVER pic - if (G_GametypeUsesLives() && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer))) + if ((gametype == GT_COOP) + && (netgame || multiplayer) + && (cv_cooplives.value == 0)) + ; + else if (G_GametypeUsesLives() && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer))) { patch_t *p; @@ -1783,49 +2383,74 @@ static void ST_overlayDrawer(void) else p = sboover; - V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, STRINGY(BASEVIDHEIGHT/2 - (SHORT(p->height)/2)), 0, p); + if ((gametype == GT_COOP) + && (netgame || multiplayer) + && (cv_cooplives.value != 1)) + { + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (&players[i] == stplyr) + continue; + + if (players[i].lives > 0) + { + p = NULL; + break; + } + } + } + + if (p) + V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, BASEVIDHEIGHT/2 - (SHORT(p->height)/2), V_PERPLAYER|(stplyr->spectator ? V_HUDTRANSHALF : V_HUDTRANS), p); } + if (G_GametypeHasTeams()) + ST_drawTeamHUD(); if (!hu_showscores) // hide the following if TAB is held { // Countdown timer for Race Mode - if (countdown) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(176), 0, va("%d", countdown/TICRATE)); - - // If you are in overtime, put a big honkin' flashin' message on the screen. - if (G_RingSlingerGametype() && cv_overtime.value - && (leveltime > (timelimitintics + TICRATE/2)) && cv_timelimit.value && (leveltime/TICRATE % 2 == 0)) + if (countdown > 1) { - if (splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(168), 0, M_GetText("OVERTIME!")); + tic_t time = countdown/TICRATE + 1; + if (time < 4) + ST_drawRaceNum(countdown); else - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(184), 0, M_GetText("OVERTIME!")); + { + tic_t num = time; + INT32 sz = SHORT(tallnum[0]->width)/2, width = 0; + do + { + width += sz; + num /= 10; + } while (num); + V_DrawTallNum((BASEVIDWIDTH/2) + width, ((3*BASEVIDHEIGHT)>>2) - 7, V_PERPLAYER, time); + //V_DrawCenteredString(BASEVIDWIDTH/2, 176, V_PERPLAYER, va("%d", countdown/TICRATE + 1)); + } } + // If you are in overtime, put a big honkin' flashin' message on the screen. + if (G_RingSlingerGametype() && cv_overtime.value + && (leveltime > (timelimitintics + TICRATE/2)) && cv_timelimit.value && (leveltime/TICRATE % 2 == 0)) + V_DrawCenteredString(BASEVIDWIDTH/2, 184, V_PERPLAYER, M_GetText("OVERTIME!")); + // Draw Match-related stuff //\note Match HUD is drawn no matter what gametype. // ... just not if you're a spectator. - if (!stplyr->spectator) + if (!stplyr->spectator +#ifdef HAVE_BLUA + && (LUA_HudEnabled(hud_weaponrings)) +#endif + ) ST_drawMatchHUD(); // Race HUD Stuff if (gametype == GT_RACE || gametype == GT_COMPETITION) ST_drawRaceHUD(); - // Tag HUD Stuff - else if (gametype == GT_TAG || gametype == GT_HIDEANDSEEK) - ST_drawTagHUD(); - // CTF HUD Stuff - else if (gametype == GT_CTF) - ST_drawCTFHUD(); - - // Team names for team gametypes - if (G_GametypeHasTeams()) - ST_drawTeamName(); - - // Special Stage HUD - if (!useNightsSS && G_IsSpecialStage(gamemap) && stplyr == &players[displayplayer]) - ST_drawSpecialStageHUD(); // Emerald Hunt Indicators if (cv_itemfinder.value && M_SecretUnlocked(SECRET_ITEMFINDER)) @@ -1833,9 +2458,6 @@ static void ST_overlayDrawer(void) else ST_doHuntIconsAndSound(); - if (stplyr->powers[pw_gravityboots] > 3*TICRATE || (stplyr->powers[pw_gravityboots] && leveltime & 1)) - V_DrawScaledPatch(hudinfo[HUD_GRAVBOOTSICO].x, STRINGY(hudinfo[HUD_GRAVBOOTSICO].y), V_SNAPTORIGHT, gravboots); - if(!P_IsLocalPlayer(stplyr)) { char name[MAXPLAYERNAME+1]; @@ -1848,12 +2470,21 @@ static void ST_overlayDrawer(void) } // This is where we draw all the fun cheese if you have the chasecam off! - if ((stplyr == &players[displayplayer] && !camera.chase) - || ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase)) + if (!(maptol & TOL_NIGHTS)) { - ST_drawFirstPersonHUD(); + if ((stplyr == &players[displayplayer] && !camera.chase) + || ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase)) + { + ST_drawFirstPersonHUD(); + if (cv_powerupdisplay.value) + ST_drawPowerupHUD(); // same as it ever was... + } + else if (cv_powerupdisplay.value == 2) + ST_drawPowerupHUD(); // same as it ever was... } } + else if (!(netgame || multiplayer) && cv_powerupdisplay.value == 2) + ST_drawPowerupHUD(); // same as it ever was... #ifdef HAVE_BLUA if (!(netgame || multiplayer) || !hu_showscores) @@ -1866,43 +2497,17 @@ static void ST_overlayDrawer(void) && LUA_HudEnabled(hud_stagetitle) #endif ) - ST_drawLevelTitle(); + ST_drawLevelTitle(timeinmap+70); - if (!hu_showscores && !splitscreen && netgame && displayplayer == consoleplayer) - { - if (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press Viewpoint Key to watch a player.")); - else if (gametype == GT_HIDEANDSEEK && - (!stplyr->spectator && !(stplyr->pflags & PF_TAGIT)) && (leveltime > hidetime * TICRATE)) - { - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(116), 0, M_GetText("You cannot move while hiding.")); - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press Viewpoint Key to watch a player.")); - } - else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. - { - INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; - if (respawntime > 0 && !stplyr->spectator) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, va(M_GetText("Respawn in: %d second%s."), respawntime, respawntime == 1 ? "" : "s")); - else - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Jump to respawn.")); - } - else if (stplyr->spectator + if (!hu_showscores && (netgame || multiplayer) #ifdef HAVE_BLUA && LUA_HudEnabled(hud_textspectator) #endif - ) - { - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(60), V_HUDTRANSHALF, M_GetText("You are a spectator.")); - if (G_GametypeHasTeams()) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team.")); - else if (G_IsSpecialStage(gamemap) && useNightsSS) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("You cannot join the game until the stage has ended.")); - else - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to enter the game.")); - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(148), V_HUDTRANSHALF, M_GetText("Press Viewpoint Key to watch a player.")); - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(164), V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); - } - } + ) + ST_drawTextHUD(); + + if (modeattacking && !(demoplayback && hu_showscores)) + ST_drawInput(); ST_drawDebugInfo(); } @@ -1912,15 +2517,26 @@ void ST_Drawer(void) #ifdef SEENAMES if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo) { - if (cv_seenames.value == 1) - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2 + 15, V_HUDTRANSHALF, player_names[seenplayer-players]); - else if (cv_seenames.value == 2) - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2 + 15, V_HUDTRANSHALF, - va("%s%s", G_GametypeHasTeams() ? ((seenplayer->ctfteam == 1) ? "\x85" : "\x84") : "", player_names[seenplayer-players])); - else //if (cv_seenames.value == 3) - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2 + 15, V_HUDTRANSHALF, - va("%s%s", !G_RingSlingerGametype() || (G_GametypeHasTeams() && players[consoleplayer].ctfteam == seenplayer->ctfteam) - ? "\x83" : "\x85", player_names[seenplayer-players])); + INT32 c = 0; + switch (cv_seenames.value) + { + case 1: // Colorless + break; + case 2: // Team + if (G_GametypeHasTeams()) + c = (seenplayer->ctfteam == 1) ? V_REDMAP : V_BLUEMAP; + break; + case 3: // Ally/Foe + default: + // Green = Ally, Red = Foe + if (G_GametypeHasTeams()) + c = (players[consoleplayer].ctfteam == seenplayer->ctfteam) ? V_GREENMAP : V_REDMAP; + else // Everyone is an ally, or everyone is a foe! + c = (G_RingSlingerGametype()) ? V_REDMAP : V_GREENMAP; + break; + } + + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2 + 15, V_HUDTRANSHALF|c, player_names[seenplayer-players]); } #endif @@ -1941,6 +2557,22 @@ void ST_Drawer(void) #endif if (rendermode != render_none) ST_doPaletteStuff(); + // Blindfold! + if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + && (leveltime < hidetime * TICRATE)) + { + if (players[displayplayer].pflags & PF_TAGIT) + { + stplyr = &players[displayplayer]; + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31|V_PERPLAYER); + } + else if (splitscreen && players[secondarydisplayplayer].pflags & PF_TAGIT) + { + stplyr = &players[secondarydisplayplayer]; + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31|V_PERPLAYER); + } + } + if (st_overlay) { // No deadview! diff --git a/src/st_stuff.h b/src/st_stuff.h index 6f05bbf3ee6987a7ef9a37c74752d9b6272fe16f..aca4e60d2949aacc618d27a93c6b6fc3d92b291e 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -44,12 +44,12 @@ void ST_LoadGraphics(void); // face load graphics, called when skin changes void ST_LoadFaceGraphics(char *facestr, char *superstr, INT32 playernum); void ST_ReloadSkinFaceGraphics(void); -#ifdef DELFILE -void ST_UnLoadFaceGraphics(INT32 skinnum); -#endif void ST_doPaletteStuff(void); +// level title draw +void ST_drawLevelTitle(tic_t titletime); + // return if player a is in the same team as player b boolean ST_SameTeam(player_t *a, player_t *b); @@ -76,37 +76,28 @@ extern patch_t *ngradeletters[7]; */ typedef struct { - INT32 x, y; + INT32 x, y, f; } hudinfo_t; typedef enum { - HUD_LIVESNAME, - HUD_LIVESPIC, - HUD_LIVESNUM, - HUD_LIVESX, + HUD_LIVES, HUD_RINGS, - HUD_RINGSSPLIT, HUD_RINGSNUM, - HUD_RINGSNUMSPLIT, + HUD_RINGSNUMTICS, HUD_SCORE, HUD_SCORENUM, HUD_TIME, - HUD_TIMESPLIT, HUD_MINUTES, - HUD_MINUTESSPLIT, HUD_TIMECOLON, - HUD_TIMECOLONSPLIT, HUD_SECONDS, - HUD_SECONDSSPLIT, HUD_TIMETICCOLON, HUD_TICS, HUD_SS_TOTALRINGS, - HUD_SS_TOTALRINGS_SPLIT, HUD_GETRINGS, HUD_GETRINGSNUM, @@ -114,8 +105,7 @@ typedef enum HUD_TIMELEFTNUM, HUD_TIMEUP, HUD_HUNTPICS, - HUD_GRAVBOOTSICO, - HUD_LAP, + HUD_POWERUPS, NUMHUDITEMS } hudnum_t; diff --git a/src/tables.c b/src/tables.c index 7d5137075f041b805f9b5b2a03443bbc7b9b71d7..a31572d706183cdf56c0e6e7caa9a143a03c5369 100644 --- a/src/tables.c +++ b/src/tables.c @@ -168,12 +168,10 @@ angle_t FixedAngle(fixed_t fa) } -#if !(defined _NDS) || !(defined NONET) #include "t_ftan.c" #include "t_fsin.c" fixed_t *finecosine = &finesine[FINEANGLES/4]; -#endif #include "t_tan2a.c" diff --git a/src/tables.h b/src/tables.h index e82b147dfcbccaebb4dbf19cb2f5f51950b81c78..60db2b5a6750a0314f128a14698ed79aba00f073 100644 --- a/src/tables.h +++ b/src/tables.h @@ -25,7 +25,6 @@ #define ANGLETOFINESHIFT 19 // 0x100000000 to 0x2000 #define FINEANGLE_C(x) ((FixedAngle((x)*FRACUNIT)>>ANGLETOFINESHIFT) & FINEMASK) // ((x*(ANGLE_45/45))>>ANGLETOFINESHIFT) & FINEMASK -#if !(defined _NDS) || !(defined NONET) // Effective size is 10240. extern fixed_t finesine[5*FINEANGLES/4]; @@ -34,7 +33,6 @@ extern fixed_t *finecosine; // Effective size is 4096. extern fixed_t finetangent[FINEANGLES/2]; -#endif #define ANG1 0x00B60B61 //0.B6~ #define ANG2 0x016C16C1 //.6C1~ @@ -114,17 +112,9 @@ void FM_Rotate(matrix_t *dest, angle_t angle, fixed_t x, fixed_t y, fixed_t z); // The table values in tables.c are calculated with this many fractional bits. #define FINE_FRACBITS 16 -#if (defined _NDS) && (defined NONET) -// Use the NDS's trig functions. This would break netplay, so we only do -// it if NONET is defined. -#define FINESINE(n) ((fixed_t)sinLerp((INT16)(((INT32)(n))<<(ANGLETOFINESHIFT-17))) << (FRACBITS - 12)) -#define FINECOSINE(n) ((fixed_t)cosLerp((INT16)(((INT32)(n))<<(ANGLETOFINESHIFT-17))) << (FRACBITS - 12)) -#define FINETANGENT(n) ((fixed_t)tanLerp((INT16)(((INT32)(n)-(FINEANGLES>>2))<<(ANGLETOFINESHIFT-17))) << (FRACBITS - 12)) -#else // These macros should be used in case FRACBITS < FINE_FRACBITS. #define FINESINE(n) (finesine[n]>>(FINE_FRACBITS-FRACBITS)) #define FINECOSINE(n) (finecosine[n]>>(FINE_FRACBITS-FRACBITS)) #define FINETANGENT(n) (finetangent[n]>>(FINE_FRACBITS-FRACBITS)) -#endif #endif diff --git a/src/tmap.nas b/src/tmap.nas index 78840106ff488a2d86627d2e03eaa08199f753a5..c72c1890aab39ed44d2739ab2a26f8877cdcdba5 100644 --- a/src/tmap.nas +++ b/src/tmap.nas @@ -17,7 +17,7 @@ [BITS 32] %define FRACBITS 16 -%define TRANSPARENTPIXEL 247 +%define TRANSPARENTPIXEL 255 %ifdef LINUX %macro cextern 1 diff --git a/src/tmap.s b/src/tmap.s index babd4ec1aac78cdd4cfe84f3fa54f2406032b202..05c644798f445e2377f6ef92db323913180a6f37 100644 --- a/src/tmap.s +++ b/src/tmap.s @@ -60,7 +60,7 @@ 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) && !defined( __OS2__) +#if !defined( LINUX) .text #endif .globl C(ASM_PatchRowBytes) @@ -616,7 +616,7 @@ vskydone: ystep: .long 0 xstep: .long 0 C(texwidth): .long 64 // texture width -#if !defined( LINUX) && !defined( __OS2__) +#if !defined( LINUX) .text #endif #ifdef LINUX @@ -1338,7 +1338,7 @@ wdone: .data advancetable: .long 0, 0 -#if !defined( LINUX) && !defined( __OS2__) +#if !defined( LINUX) .text #endif #ifdef LINUX diff --git a/src/tmap_mmx.nas b/src/tmap_mmx.nas index 39380a06528392abab41495f3f7e34046861fa14..c512de8e9d6b62411157e24941a49b990a3bf1d7 100644 --- a/src/tmap_mmx.nas +++ b/src/tmap_mmx.nas @@ -18,7 +18,7 @@ [BITS 32] %define FRACBITS 16 -%define TRANSPARENTPIXEL 247 +%define TRANSPARENTPIXEL 255 %ifdef LINUX %macro cextern 1 diff --git a/src/v_video.c b/src/v_video.c index c9435deb24ce8ed18329964b557e04ab8214971c..ec5e592ce2bc0c5babbd41fa96f70050664f232a 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -15,6 +15,8 @@ #include "doomdef.h" #include "r_local.h" +#include "p_local.h" // stplyr +#include "g_game.h" // players #include "v_video.h" #include "hu_stuff.h" #include "r_draw.h" @@ -38,11 +40,39 @@ UINT8 *screens[5]; // screens[3] = fade screen start // screens[4] = fade screen end, postimage tempoarary buffer -static CV_PossibleValue_t gamma_cons_t[] = {{0, "MIN"}, {4, "MAX"}, {0, NULL}}; -static void CV_usegamma_OnChange(void); - consvar_t cv_ticrate = {"showfps", "No", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_usegamma = {"gamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_usegamma_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +static void CV_palette_OnChange(void); + +static CV_PossibleValue_t gamma_cons_t[] = {{-15, "MIN"}, {5, "MAX"}, {0, NULL}}; +consvar_t cv_globalgamma = {"gamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +static CV_PossibleValue_t saturation_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}}; +consvar_t cv_globalsaturation = {"saturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +#define huecoloursteps 4 + +static CV_PossibleValue_t hue_cons_t[] = {{0, "MIN"}, {(huecoloursteps*6)-1, "MAX"}, {0, NULL}}; +consvar_t cv_rhue = {"rhue", "0", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_yhue = {"yhue", "4", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_ghue = {"ghue", "8", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_chue = {"chue", "12", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_bhue = {"bhue", "16", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_mhue = {"mhue", "20", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_rgamma = {"rgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_ygamma = {"ygamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_ggamma = {"ggamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cgamma = {"cgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_bgamma = {"bgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_mgamma = {"mgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_rsaturation = {"rsaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_ysaturation = {"ysaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_gsaturation = {"gsaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_csaturation = {"csaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_bsaturation = {"bsaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_msaturation = {"msaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_allcaps = {"allcaps", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -83,8 +113,209 @@ consvar_t cv_grmdls = {"gr_mdls", "Off", CV_SAVE, CV_MD2, NULL, 0, NULL, NULL, 0 consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif -const UINT8 gammatable[5][256] = +// local copy of the palette for V_GetColor() +RGBA_t *pLocalPalette = NULL; +RGBA_t *pMasterPalette = NULL; + +/* +The following was an extremely helpful resource when developing my Colour Cube LUT. +http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter24.html +Please check it out if you're trying to maintain this. +toast 18/04/17 +*/ +float Cubepal[2][2][2][3]; + +// returns whether to apply cube, selectively avoiding expensive operations +static boolean InitCube(void) { + boolean apply = false; + UINT8 q; + float working[2][2][2][3] = // the initial positions of the corners of the colour cube! + { + { + { + {0.0, 0.0, 0.0}, // black corner + {0.0, 0.0, 1.0} // blue corner + }, + { + {0.0, 1.0, 0.0}, // green corner + {0.0, 1.0, 1.0} // cyan corner + } + }, + { + { + {1.0, 0.0, 0.0}, // red corner + {1.0, 0.0, 1.0} // magenta corner + }, + { + {1.0, 1.0, 0.0}, // yellow corner + {1.0, 1.0, 1.0} // white corner + } + } + }; + float desatur[3]; // grey + float globalgammamul, globalgammaoffs; + boolean doinggamma; + +#define diffcons(cv) (cv.value != atoi(cv.defaultvalue)) + + doinggamma = diffcons(cv_globalgamma); + +#define gammascale 8 + globalgammamul = (cv_globalgamma.value ? ((255 - (gammascale*abs(cv_globalgamma.value)))/255.0) : 1.0); + globalgammaoffs = ((cv_globalgamma.value > 0) ? ((gammascale*cv_globalgamma.value)/255.0) : 0.0); + desatur[0] = desatur[1] = desatur[2] = globalgammaoffs + (0.33*globalgammamul); + + if (doinggamma + || diffcons(cv_rhue) + || diffcons(cv_yhue) + || diffcons(cv_ghue) + || diffcons(cv_chue) + || diffcons(cv_bhue) + || diffcons(cv_mhue) + || diffcons(cv_rgamma) + || diffcons(cv_ygamma) + || diffcons(cv_ggamma) + || diffcons(cv_cgamma) + || diffcons(cv_bgamma) + || diffcons(cv_mgamma)) // set the gamma'd/hued positions (saturation is done later) + { + float mod, tempgammamul, tempgammaoffs; + + apply = true; + + working[0][0][0][0] = working[0][0][0][1] = working[0][0][0][2] = globalgammaoffs; + working[1][1][1][0] = working[1][1][1][1] = working[1][1][1][2] = globalgammaoffs+globalgammamul; + +#define dohue(hue, gamma, loc) \ + tempgammamul = (gamma ? ((255 - (gammascale*abs(gamma)))/255.0)*globalgammamul : globalgammamul);\ + tempgammaoffs = ((gamma > 0) ? ((gammascale*gamma)/255.0) + globalgammaoffs : globalgammaoffs);\ + mod = ((hue % huecoloursteps)*(tempgammamul)/huecoloursteps);\ + switch (hue/huecoloursteps)\ + {\ + case 0:\ + default:\ + loc[0] = tempgammaoffs+tempgammamul;\ + loc[1] = tempgammaoffs+mod;\ + loc[2] = tempgammaoffs;\ + break;\ + case 1:\ + loc[0] = tempgammaoffs+tempgammamul-mod;\ + loc[1] = tempgammaoffs+tempgammamul;\ + loc[2] = tempgammaoffs;\ + break;\ + case 2:\ + loc[0] = tempgammaoffs;\ + loc[1] = tempgammaoffs+tempgammamul;\ + loc[2] = tempgammaoffs+mod;\ + break;\ + case 3:\ + loc[0] = tempgammaoffs;\ + loc[1] = tempgammaoffs+tempgammamul-mod;\ + loc[2] = tempgammaoffs+tempgammamul;\ + break;\ + case 4:\ + loc[0] = tempgammaoffs+mod;\ + loc[1] = tempgammaoffs;\ + loc[2] = tempgammaoffs+tempgammamul;\ + break;\ + case 5:\ + loc[0] = tempgammaoffs+tempgammamul;\ + loc[1] = tempgammaoffs;\ + loc[2] = tempgammaoffs+tempgammamul-mod;\ + break;\ + } + dohue(cv_rhue.value, cv_rgamma.value, working[1][0][0]); + dohue(cv_yhue.value, cv_ygamma.value, working[1][1][0]); + dohue(cv_ghue.value, cv_ggamma.value, working[0][1][0]); + dohue(cv_chue.value, cv_cgamma.value, working[0][1][1]); + dohue(cv_bhue.value, cv_bgamma.value, working[0][0][1]); + dohue(cv_mhue.value, cv_mgamma.value, working[1][0][1]); +#undef dohue + } + +#define dosaturation(a, e) a = ((1 - work)*e + work*a) +#define docvsat(cv_sat, hue, gamma, r, g, b) \ + if diffcons(cv_sat)\ + {\ + float work, mod, tempgammamul, tempgammaoffs;\ + apply = true;\ + work = (cv_sat.value/10.0);\ + mod = ((hue % huecoloursteps)*(1.0)/huecoloursteps);\ + if (hue & huecoloursteps)\ + mod = 2-mod;\ + else\ + mod += 1;\ + tempgammamul = (gamma ? ((255 - (gammascale*abs(gamma)))/255.0)*globalgammamul : globalgammamul);\ + tempgammaoffs = ((gamma > 0) ? ((gammascale*gamma)/255.0) + globalgammaoffs : globalgammaoffs);\ + for (q = 0; q < 3; q++)\ + dosaturation(working[r][g][b][q], (tempgammaoffs+(desatur[q]*mod*tempgammamul)));\ + } + + docvsat(cv_rsaturation, cv_rhue.value, cv_rgamma.value, 1, 0, 0); + docvsat(cv_ysaturation, cv_yhue.value, cv_ygamma.value, 1, 1, 0); + docvsat(cv_gsaturation, cv_ghue.value, cv_ggamma.value, 0, 1, 0); + docvsat(cv_csaturation, cv_chue.value, cv_cgamma.value, 0, 1, 1); + docvsat(cv_bsaturation, cv_bhue.value, cv_bgamma.value, 0, 0, 1); + docvsat(cv_msaturation, cv_mhue.value, cv_mgamma.value, 1, 0, 1); + +#undef gammascale + + if diffcons(cv_globalsaturation) + { + float work = (cv_globalsaturation.value/10.0); + + apply = true; + + for (q = 0; q < 3; q++) + { + dosaturation(working[1][0][0][q], desatur[q]); + dosaturation(working[0][1][0][q], desatur[q]); + dosaturation(working[0][0][1][q], desatur[q]); + + dosaturation(working[1][1][0][q], 2*desatur[q]); + dosaturation(working[0][1][1][q], 2*desatur[q]); + dosaturation(working[1][0][1][q], 2*desatur[q]); + } + } + +#undef dosaturation + +#undef diffcons + + if (!apply) + return false; + +#define dowork(i, j, k, l) \ + if (working[i][j][k][l] > 1.0)\ + working[i][j][k][l] = 1.0;\ + else if (working[i][j][k][l] < 0.0)\ + working[i][j][k][l] = 0.0;\ + Cubepal[i][j][k][l] = working[i][j][k][l] + for (q = 0; q < 3; q++) + { + dowork(0, 0, 0, q); + dowork(1, 0, 0, q); + dowork(0, 1, 0, q); + dowork(1, 1, 0, q); + dowork(0, 0, 1, q); + dowork(1, 0, 1, q); + dowork(0, 1, 1, q); + dowork(1, 1, 1, q); + } +#undef dowork + + return true; +} + +/* +So it turns out that the way gamma was implemented previously, the default +colour profile of the game was messed up. Since this bad decision has been +around for a long time, and the intent is to keep the base game looking the +same, I'm not gonna be the one to remove this base modification. +toast 20/04/17 +*/ +const UINT8 correctiontable[256] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32, 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48, @@ -100,95 +331,67 @@ const UINT8 gammatable[5][256] = 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, - 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255}, - - {2,4,5,7,8,10,11,12,14,15,16,18,19,20,21,23,24,25,26,27,29,30,31, - 32,33,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,54,55, - 56,57,58,59,60,61,62,63,64,65,66,67,69,70,71,72,73,74,75,76,77, - 78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98, - 99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114, - 115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,129, - 130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, - 146,147,148,148,149,150,151,152,153,154,155,156,157,158,159,160, - 161,162,163,163,164,165,166,167,168,169,170,171,172,173,174,175, - 175,176,177,178,179,180,181,182,183,184,185,186,186,187,188,189, - 190,191,192,193,194,195,196,196,197,198,199,200,201,202,203,204, - 205,205,206,207,208,209,210,211,212,213,214,214,215,216,217,218, - 219,220,221,222,222,223,224,225,226,227,228,229,230,230,231,232, - 233,234,235,236,237,237,238,239,240,241,242,243,244,245,245,246, - 247,248,249,250,251,252,252,253,254,255}, - - {4,7,9,11,13,15,17,19,21,22,24,26,27,29,30,32,33,35,36,38,39,40,42, - 43,45,46,47,48,50,51,52,54,55,56,57,59,60,61,62,63,65,66,67,68,69, - 70,72,73,74,75,76,77,78,79,80,82,83,84,85,86,87,88,89,90,91,92,93, - 94,95,96,97,98,100,101,102,103,104,105,106,107,108,109,110,111,112, - 113,114,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128, - 129,130,131,132,133,133,134,135,136,137,138,139,140,141,142,143,144, - 144,145,146,147,148,149,150,151,152,153,153,154,155,156,157,158,159, - 160,160,161,162,163,164,165,166,166,167,168,169,170,171,172,172,173, - 174,175,176,177,178,178,179,180,181,182,183,183,184,185,186,187,188, - 188,189,190,191,192,193,193,194,195,196,197,197,198,199,200,201,201, - 202,203,204,205,206,206,207,208,209,210,210,211,212,213,213,214,215, - 216,217,217,218,219,220,221,221,222,223,224,224,225,226,227,228,228, - 229,230,231,231,232,233,234,235,235,236,237,238,238,239,240,241,241, - 242,243,244,244,245,246,247,247,248,249,250,251,251,252,253,254,254, - 255}, - - {8,12,16,19,22,24,27,29,31,34,36,38,40,41,43,45,47,49,50,52,53,55, - 57,58,60,61,63,64,65,67,68,70,71,72,74,75,76,77,79,80,81,82,84,85, - 86,87,88,90,91,92,93,94,95,96,98,99,100,101,102,103,104,105,106,107, - 108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124, - 125,126,127,128,129,130,131,132,133,134,135,135,136,137,138,139,140, - 141,142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155, - 155,156,157,158,159,160,160,161,162,163,164,165,165,166,167,168,169, - 169,170,171,172,173,173,174,175,176,176,177,178,179,180,180,181,182, - 183,183,184,185,186,186,187,188,189,189,190,191,192,192,193,194,195, - 195,196,197,197,198,199,200,200,201,202,202,203,204,205,205,206,207, - 207,208,209,210,210,211,212,212,213,214,214,215,216,216,217,218,219, - 219,220,221,221,222,223,223,224,225,225,226,227,227,228,229,229,230, - 231,231,232,233,233,234,235,235,236,237,237,238,238,239,240,240,241, - 242,242,243,244,244,245,246,246,247,247,248,249,249,250,251,251,252, - 253,253,254,254,255}, - - {16,23,28,32,36,39,42,45,48,50,53,55,57,60,62,64,66,68,69,71,73,75,76, - 78,80,81,83,84,86,87,89,90,92,93,94,96,97,98,100,101,102,103,105,106, - 107,108,109,110,112,113,114,115,116,117,118,119,120,121,122,123,124, - 125,126,128,128,129,130,131,132,133,134,135,136,137,138,139,140,141, - 142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155,155, - 156,157,158,159,159,160,161,162,163,163,164,165,166,166,167,168,169, - 169,170,171,172,172,173,174,175,175,176,177,177,178,179,180,180,181, - 182,182,183,184,184,185,186,187,187,188,189,189,190,191,191,192,193, - 193,194,195,195,196,196,197,198,198,199,200,200,201,202,202,203,203, - 204,205,205,206,207,207,208,208,209,210,210,211,211,212,213,213,214, - 214,215,216,216,217,217,218,219,219,220,220,221,221,222,223,223,224, - 224,225,225,226,227,227,228,228,229,229,230,230,231,232,232,233,233, - 234,234,235,235,236,236,237,237,238,239,239,240,240,241,241,242,242, - 243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251, - 251,252,252,253,254,254,255,255} -}; - -// local copy of the palette for V_GetColor() -RGBA_t *pLocalPalette = NULL; + 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255}; // keep a copy of the palette so that we can get the RGB value for a color index at any time. static void LoadPalette(const char *lumpname) { - const UINT8 *usegamma = gammatable[cv_usegamma.value]; + boolean cube = InitCube(); lumpnum_t lumpnum = W_GetNumForName(lumpname); size_t i, palsize = W_LumpLength(lumpnum)/3; UINT8 *pal; Z_Free(pLocalPalette); + Z_Free(pMasterPalette); pLocalPalette = Z_Malloc(sizeof (*pLocalPalette)*palsize, PU_STATIC, NULL); + pMasterPalette = Z_Malloc(sizeof (*pMasterPalette)*palsize, PU_STATIC, NULL); pal = W_CacheLumpNum(lumpnum, PU_CACHE); for (i = 0; i < palsize; i++) { - pLocalPalette[i].s.red = usegamma[*pal++]; - pLocalPalette[i].s.green = usegamma[*pal++]; - pLocalPalette[i].s.blue = usegamma[*pal++]; - pLocalPalette[i].s.alpha = 0xFF; + pMasterPalette[i].s.red = pLocalPalette[i].s.red = correctiontable[*pal++]; + pMasterPalette[i].s.green = pLocalPalette[i].s.green = correctiontable[*pal++]; + pMasterPalette[i].s.blue = pLocalPalette[i].s.blue = correctiontable[*pal++]; + pMasterPalette[i].s.alpha = pLocalPalette[i].s.alpha = 0xFF; + + // lerp of colour cubing! + if (cube) + { + float working[4][3]; + float linear; + UINT8 q; + + linear = (pLocalPalette[i].s.red/255.0); +#define dolerp(e1, e2) ((1 - linear)*e1 + linear*e2) + for (q = 0; q < 3; q++) + { + working[0][q] = dolerp(Cubepal[0][0][0][q], Cubepal[1][0][0][q]); + working[1][q] = dolerp(Cubepal[0][1][0][q], Cubepal[1][1][0][q]); + working[2][q] = dolerp(Cubepal[0][0][1][q], Cubepal[1][0][1][q]); + working[3][q] = dolerp(Cubepal[0][1][1][q], Cubepal[1][1][1][q]); + } + linear = (pLocalPalette[i].s.green/255.0); + for (q = 0; q < 3; q++) + { + working[0][q] = dolerp(working[0][q], working[1][q]); + working[1][q] = dolerp(working[2][q], working[3][q]); + } + linear = (pLocalPalette[i].s.blue/255.0); + for (q = 0; q < 3; q++) + { + working[0][q] = 255*dolerp(working[0][q], working[1][q]); + if (working[0][q] > 255.0) + working[0][q] = 255.0; + else if (working[0][q] < 0.0) + working[0][q] = 0.0; + } +#undef dolerp + + pLocalPalette[i].s.red = (UINT8)(working[0][0]); + pLocalPalette[i].s.green = (UINT8)(working[0][1]); + pLocalPalette[i].s.blue = (UINT8)(working[0][2]); + } } } @@ -250,7 +453,7 @@ void V_SetPaletteLump(const char *pal) I_SetPalette(pLocalPalette); } -static void CV_usegamma_OnChange(void) +static void CV_palette_OnChange(void) { // reload palette LoadMapPalette(); @@ -340,6 +543,8 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t fixed_t pwidth; // patch width fixed_t offx = 0; // x offset + UINT8 perplayershuffle = 0; + if (rendermode == render_none) return; @@ -366,11 +571,12 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t if (alphalevel >= 10) return; // invis - } - if (alphalevel) - { - v_translevel = transtables + ((alphalevel-1)<<FF_TRANSSHIFT); - patchdrawfunc = translucentpdraw; + + if (alphalevel) + { + v_translevel = transtables + ((alphalevel-1)<<FF_TRANSSHIFT); + patchdrawfunc = translucentpdraw; + } } v_colormap = NULL; @@ -433,8 +639,74 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t y -= offsety; } - if (scrn & V_SPLITSCREEN) - y>>=1; + if (splitscreen && (scrn & V_PERPLAYER)) + { + fixed_t adjusty = ((scrn & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)<<(FRACBITS-1); + fdup >>= 1; + rowfrac <<= 1; + y >>= 1; +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + fixed_t adjustx = ((scrn & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)<<(FRACBITS-1)); + colfrac <<= 1; + x >>= 1; + if (stplyr == &players[displayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; + scrn &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + } + else if (stplyr == &players[secondarydisplayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; + x += adjustx; + scrn &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; + } + else if (stplyr == &players[thirddisplayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; + y += adjusty; + scrn &= ~V_SNAPTOTOP|V_SNAPTORIGHT; + } + else //if (stplyr == &players[fourthdisplayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; + x += adjustx; + y += adjusty; + scrn &= ~V_SNAPTOTOP|V_SNAPTOLEFT; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[displayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle = 1; + scrn &= ~V_SNAPTOBOTTOM; + } + else //if (stplyr == &players[secondarydisplayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle = 2; + y += adjusty; + scrn &= ~V_SNAPTOTOP; + } + } + } desttop = screens[scrn&V_PARAMMASK]; @@ -466,6 +738,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t source = (const UINT8 *)(column) + 3; V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); } + if (vid.width != BASEVIDWIDTH * dupx) { // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, @@ -474,20 +747,26 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t x += (vid.width - (BASEVIDWIDTH * dupx)); else if (!(scrn & V_SNAPTOLEFT)) x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + if (perplayershuffle & 4) + x -= (vid.width - (BASEVIDWIDTH * dupx)) / 4; + else if (perplayershuffle & 8) + x += (vid.width - (BASEVIDWIDTH * dupx)) / 4; } if (vid.height != BASEVIDHEIGHT * dupy) { // same thing here - if ((scrn & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM)) - y += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy)); - else if (scrn & V_SNAPTOBOTTOM) + if (scrn & V_SNAPTOBOTTOM) y += (vid.height - (BASEVIDHEIGHT * dupy)); else if (!(scrn & V_SNAPTOTOP)) y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + if (perplayershuffle & 1) + y -= (vid.height - (BASEVIDHEIGHT * dupy)) / 4; + else if (perplayershuffle & 2) + y += (vid.height - (BASEVIDHEIGHT * dupy)) / 4; } - - desttop += (y*vid.width) + x; } + + desttop += (y*vid.width) + x; } if (pscale != FRACUNIT) // scale width properly @@ -548,12 +827,18 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t // Draws a patch cropped and scaled to arbitrary size. void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t *patch, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h) { + UINT8 (*patchdrawfunc)(const UINT8*, const UINT8*, fixed_t); + UINT32 alphalevel = 0; + // boolean flip = false; + fixed_t col, ofs, colfrac, rowfrac, fdup; INT32 dupx, dupy; const column_t *column; UINT8 *desttop, *dest; const UINT8 *source, *deststop; + UINT8 perplayershuffle = 0; + if (rendermode == render_none) return; @@ -566,6 +851,28 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ } #endif + patchdrawfunc = standardpdraw; + + v_translevel = NULL; + if ((alphalevel = ((scrn & V_ALPHAMASK) >> V_ALPHASHIFT))) + { + if (alphalevel == 13) + alphalevel = hudminusalpha[cv_translucenthud.value]; + else if (alphalevel == 14) + alphalevel = 10 - cv_translucenthud.value; + else if (alphalevel == 15) + alphalevel = hudplusalpha[cv_translucenthud.value]; + + if (alphalevel >= 10) + return; // invis + + if (alphalevel) + { + v_translevel = transtables + ((alphalevel-1)<<FF_TRANSSHIFT); + patchdrawfunc = translucentpdraw; + } + } + // only use one dup, to avoid stretching (har har) dupx = dupy = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); fdup = FixedMul(dupx<<FRACBITS, pscale); @@ -575,6 +882,84 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ y -= FixedMul(SHORT(patch->topoffset)<<FRACBITS, pscale); x -= FixedMul(SHORT(patch->leftoffset)<<FRACBITS, pscale); + if (splitscreen && (scrn & V_PERPLAYER)) + { + fixed_t adjusty = ((scrn & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)<<(FRACBITS-1); + fdup >>= 1; + rowfrac <<= 1; + y >>= 1; + sy >>= 1; + h >>= 1; +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + fixed_t adjustx = ((scrn & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)<<(FRACBITS-1)); + colfrac <<= 1; + x >>= 1; + sx >>= 1; + w >>= 1; + if (stplyr == &players[displayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; + scrn &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + } + else if (stplyr == &players[secondarydisplayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; + x += adjustx; + sx += adjustx; + scrn &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; + } + else if (stplyr == &players[thirddisplayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; + y += adjusty; + sy += adjusty; + scrn &= ~V_SNAPTOTOP|V_SNAPTORIGHT; + } + else //if (stplyr == &players[fourthdisplayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; + x += adjustx; + sx += adjustx; + y += adjusty; + sy += adjusty; + scrn &= ~V_SNAPTOTOP|V_SNAPTOLEFT; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[displayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + scrn &= ~V_SNAPTOBOTTOM; + } + else //if (stplyr == &players[secondarydisplayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + y += adjusty; + sy += adjusty; + scrn &= ~V_SNAPTOTOP; + } + } + } + desttop = screens[scrn&V_PARAMMASK]; if (!desttop) @@ -604,6 +989,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ source = (const UINT8 *)(column) + 3; V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); } + if (vid.width != BASEVIDWIDTH * dupx) { // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, @@ -612,6 +998,10 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ x += (vid.width - (BASEVIDWIDTH * dupx)); else if (!(scrn & V_SNAPTOLEFT)) x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + if (perplayershuffle & 4) + x -= (vid.width - (BASEVIDWIDTH * dupx)) / 4; + else if (perplayershuffle & 8) + x += (vid.width - (BASEVIDWIDTH * dupx)) / 4; } if (vid.height != BASEVIDHEIGHT * dupy) { @@ -620,13 +1010,17 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ y += (vid.height - (BASEVIDHEIGHT * dupy)); else if (!(scrn & V_SNAPTOTOP)) y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + if (perplayershuffle & 1) + y -= (vid.height - (BASEVIDHEIGHT * dupy)) / 4; + else if (perplayershuffle & 2) + y += (vid.height - (BASEVIDHEIGHT * dupy)) / 4; } } desttop += (y*vid.width) + x; } - for (col = sx<<FRACBITS; (col>>FRACBITS) < SHORT(patch->width) && (col>>FRACBITS) < w; col += colfrac, ++x, desttop++) + for (col = sx<<FRACBITS; (col>>FRACBITS) < SHORT(patch->width) && ((col>>FRACBITS) - sx) < w; col += colfrac, ++x, desttop++) { INT32 topdelta, prevdelta = -1; if (x < 0) // don't draw off the left of the screen (WRAP PREVENTION) @@ -645,10 +1039,10 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ dest = desttop; dest += FixedInt(FixedMul(topdelta<<FRACBITS,fdup))*vid.width; - for (ofs = sy<<FRACBITS; dest < deststop && (ofs>>FRACBITS) < column->length && (ofs>>FRACBITS) < h; ofs += rowfrac) + for (ofs = sy<<FRACBITS; dest < deststop && (ofs>>FRACBITS) < column->length && (((ofs>>FRACBITS) - sy) + topdelta) < h; ofs += rowfrac) { if (dest >= screens[scrn&V_PARAMMASK]) // don't draw off the top of the screen (CRASH PREVENTION) - *dest = source[ofs>>FRACBITS]; + *dest = patchdrawfunc(dest, source, ofs); dest += vid.width; } column = (const column_t *)((const UINT8 *)column + column->length + 4); @@ -663,10 +1057,10 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor) { if (skinnum < 0 || skinnum >= numskins || (skins[skinnum].flags & SF_HIRES)) - V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE)); // Draw a star + V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE)); else - { // Find front angle of the first waiting frame of the character's actual sprites - spriteframe_t *sprframe = &skins[skinnum].spritedef.spriteframes[2 & FF_FRAMEMASK]; + { + spriteframe_t *sprframe = &skins[skinnum].sprites[SPR2_WAIT].spriteframes[0]; patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE); @@ -766,6 +1160,8 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) UINT8 *dest; const UINT8 *deststop; + UINT8 perplayershuffle = 0; + if (rendermode == render_none) return; @@ -777,6 +1173,74 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) } #endif + if (splitscreen && (c & V_PERPLAYER)) + { + fixed_t adjusty = ((c & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)>>1; + h >>= 1; + y >>= 1; +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + fixed_t adjustx = ((c & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)>>1; + w >>= 1; + x >>= 1; + if (stplyr == &players[displayplayer]) + { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; + c &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + } + else if (stplyr == &players[secondarydisplayplayer]) + { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; + x += adjustx; + c &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; + } + else if (stplyr == &players[thirddisplayplayer]) + { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; + y += adjusty; + c &= ~V_SNAPTOTOP|V_SNAPTORIGHT; + } + else //if (stplyr == &players[fourthdisplayplayer]) + { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; + x += adjustx; + y += adjusty; + c &= ~V_SNAPTOTOP|V_SNAPTOLEFT; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[displayplayer]) + { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + c &= ~V_SNAPTOBOTTOM; + } + else //if (stplyr == &players[secondarydisplayplayer]) + { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + y += adjusty; + c &= ~V_SNAPTOTOP; + } + } + } + if (!(c & V_NOSCALESTART)) { INT32 dupx = vid.dupx, dupy = vid.dupy; @@ -801,6 +1265,10 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) x += (vid.width - (BASEVIDWIDTH * dupx)); else if (!(c & V_SNAPTOLEFT)) x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + if (perplayershuffle & 4) + x -= (vid.width - (BASEVIDWIDTH * dupx)) / 4; + else if (perplayershuffle & 8) + x += (vid.width - (BASEVIDWIDTH * dupx)) / 4; } if (vid.height != BASEVIDHEIGHT * dupy) { @@ -809,6 +1277,10 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) y += (vid.height - (BASEVIDHEIGHT * dupy)); else if (!(c & V_SNAPTOTOP)) y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + if (perplayershuffle & 1) + y -= (vid.height - (BASEVIDHEIGHT * dupy)) / 4; + else if (perplayershuffle & 2) + y += (vid.height - (BASEVIDHEIGHT * dupy)) / 4; } } @@ -849,7 +1321,7 @@ static UINT32 V_GetHWConsBackColor(void) switch (cons_backcolor.value) { case 0: hwcolor = 0xffffff00; break; // White - case 1: hwcolor = 0x80808000; break; // Gray + case 1: hwcolor = 0x80808000; break; // Black case 2: hwcolor = 0xdeb88700; break; // Sepia case 3: hwcolor = 0x40201000; break; // Brown case 4: hwcolor = 0xfa807200; break; // Pink @@ -1093,25 +1565,34 @@ void V_DrawPatchFill(patch_t *pat) // // Fade all the screen buffer, so that the menu is more readable, // especially now that we use the small hufont in the menus... +// If color is 0x00 to 0xFF, draw transtable (strength range 0-9). +// Else, use COLORMAP lump (strength range 0-31). +// IF YOU ARE NOT CAREFUL, THIS CAN AND WILL CRASH! +// I have kept the safety checks out of this function; +// the v.fadeScreen Lua interface handles those. // -void V_DrawFadeScreen(void) +void V_DrawFadeScreen(UINT16 color, UINT8 strength) { - const UINT8 *fadetable = (UINT8 *)colormaps + 16*256; - const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - UINT8 *buf = screens[0]; - #ifdef HWRENDER if (rendermode != render_soft && rendermode != render_none) { - HWR_FadeScreenMenuBack(0x01010160, 0); // hack, 0 means full height + HWR_FadeScreenMenuBack(color, strength); return; } #endif - // heavily simplified -- we don't need to know x or y - // position when we're doing a full screen fade - for (; buf < deststop; ++buf) - *buf = fadetable[*buf]; + { + const UINT8 *fadetable = ((color & 0xFF00) // Color is not palette index? + ? ((UINT8 *)colormaps + strength*256) // Do COLORMAP fade. + : ((UINT8 *)transtables + ((9-strength)<<FF_TRANSSHIFT) + color*256)); // Else, do TRANSMAP** fade. + const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; + UINT8 *buf = screens[0]; + + // heavily simplified -- we don't need to know x or y + // position when we're doing a full screen fade + for (; buf < deststop; ++buf) + *buf = fadetable[*buf]; + } } // Simple translucency with one color, over a set number of lines starting from the top. @@ -1135,26 +1616,95 @@ void V_DrawFadeConsBack(INT32 plines) *buf = consolebgmap[*buf]; } +// Very similar to F_DrawFadeConsBack, except we draw from the middle(-ish) of the screen to the bottom. +void V_DrawPromptBack(INT32 boxheight, INT32 color) +{ + UINT8 *deststop, *buf; + + boxheight *= vid.dupy; + + if (color == INT32_MAX) + color = cons_backcolor.value; + +#ifdef HWRENDER + if (rendermode != render_soft && rendermode != render_none) + { + UINT32 hwcolor; + switch (color) + { + case 0: hwcolor = 0xffffff00; break; // White + case 1: hwcolor = 0x00000000; break; // Black // Note this is different from V_DrawFadeConsBack + case 2: hwcolor = 0xdeb88700; break; // Sepia + case 3: hwcolor = 0x40201000; break; // Brown + case 4: hwcolor = 0xfa807200; break; // Pink + case 5: hwcolor = 0xff69b400; break; // Raspberry + case 6: hwcolor = 0xff000000; break; // Red + case 7: hwcolor = 0xffd68300; break; // Creamsicle + case 8: hwcolor = 0xff800000; break; // Orange + case 9: hwcolor = 0xdaa52000; break; // Gold + case 10: hwcolor = 0x80800000; break; // Yellow + case 11: hwcolor = 0x00ff0000; break; // Emerald + case 12: hwcolor = 0x00800000; break; // Green + case 13: hwcolor = 0x4080ff00; break; // Cyan + case 14: hwcolor = 0x4682b400; break; // Steel + case 15: hwcolor = 0x1e90ff00; break; // Periwinkle + case 16: hwcolor = 0x0000ff00; break; // Blue + case 17: hwcolor = 0xff00ff00; break; // Purple + case 18: hwcolor = 0xee82ee00; break; // Lavender + // Default green + default: hwcolor = 0x00800000; break; + } + HWR_DrawTutorialBack(hwcolor, boxheight); + return; + } +#endif + + CON_SetupBackColormapEx(color, true); + + // heavily simplified -- we don't need to know x or y position, + // just the start and stop positions + deststop = screens[0] + vid.rowbytes * vid.height; + buf = deststop - vid.rowbytes * ((boxheight * 4) + (boxheight/2)*5); // 4 lines of space plus gaps between and some leeway + for (; buf < deststop; ++buf) + *buf = promptbgmap[*buf]; +} + // Gets string colormap, used for 0x80 color codes // UINT8 *V_GetStringColormap(INT32 colorflags) { switch ((colorflags & V_CHARCOLORMASK) >> V_CHARCOLORSHIFT) { - case 1: // 0x81, purple - return purplemap; - case 2: // 0x82, yellow + case 1: // 0x81, magenta + return magentamap; + case 2: // 0x82, yellow return yellowmap; - case 3: // 0x83, lgreen + case 3: // 0x83, lgreen return lgreenmap; - case 4: // 0x84, blue + case 4: // 0x84, blue return bluemap; - case 5: // 0x85, red + case 5: // 0x85, red return redmap; - case 6: // 0x86, gray + case 6: // 0x86, gray return graymap; - case 7: // 0x87, orange + case 7: // 0x87, orange return orangemap; + case 8: // 0x88, sky + return skymap; + case 9: // 0x89, purple + return purplemap; + case 10: // 0x8A, aqua + return aquamap; + case 11: // 0x8B, peridot + return peridotmap; + case 12: // 0x8C, azure + return azuremap; + case 13: // 0x8D, brown + return brownmap; + case 14: // 0x8E, rosy + return rosymap; + case 15: // 0x8F, invert + return invertmap; default: // reset return NULL; } @@ -1289,7 +1839,7 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string) { INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, center = 0, left = 0; const char *ch = string; - INT32 charflags = 0; + INT32 charflags = (option & V_CHARCOLORMASK); const UINT8 *colormap = NULL; INT32 spacewidth = 4, charwidth = 0; @@ -1310,8 +1860,6 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string) scrwidth -= left; } - charflags = (option & V_CHARCOLORMASK); - switch (option & V_SPACINGMASK) { case V_MONOSPACE: @@ -1482,6 +2030,7 @@ void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string) } else w = SHORT(hu_font[c]->width) * dupx / 2; + if (cx > scrwidth) break; if (cx+left + w < 0) //left boundary check @@ -1745,6 +2294,16 @@ void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits) } while (--digits); } +// Draw an act number for a level title +// Todo: actually draw two-digit numbers as two act num patches +void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, INT32 num) +{ + if (num < 0 || num > 19) + return; // not supported + + V_DrawScaledPatch(x, y, flags, ttlnum[num]); +} + // Write a string using the credit font // NOTE: the text is centered for screens larger than the base width // @@ -1825,6 +2384,8 @@ void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string) { INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, left = 0; const char *ch = string; + INT32 charflags = (option & V_CHARCOLORMASK); + const UINT8 *colormap = NULL; if (option & V_NOSCALESTART) { @@ -1840,19 +2401,25 @@ void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string) scrwidth -= left; } - for (;;) + for (;;ch++) { - c = *ch++; - if (!c) + if (!*ch) break; - if (c == '\n') + if (*ch & 0x80) //color parsing -x 2.16.09 + { + // manually set flags override color codes + if (!(option & V_CHARCOLORMASK)) + charflags = ((*ch & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK; + continue; + } + if (*ch == '\n') { cx = x; cy += 12*dupy; continue; } - c = toupper(c) - LT_FONTSTART; + c = toupper(*ch) - LT_FONTSTART; if (c < 0 || c >= LT_FONTSIZE || !lt_font[c]) { cx += 16*dupx; @@ -1860,16 +2427,18 @@ void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string) } w = SHORT(lt_font[c]->width) * dupx; + if (cx > scrwidth) break; if (cx+left + w < 0) //left boundary check - { cx += w; continue; } - V_DrawScaledPatch(cx, cy, option, lt_font[c]); + colormap = V_GetStringColormap(charflags); + V_DrawFixedPatch(cx<<FRACBITS, cy<<FRACBITS, FRACUNIT, option, lt_font[c], colormap); + cx += w; } } @@ -1883,6 +2452,8 @@ INT32 V_LevelNameWidth(const char *string) for (i = 0; i < strlen(string); i++) { + if (string[i] & 0x80) + continue; c = toupper(string[i]) - LT_FONTSTART; if (c < 0 || c >= LT_FONTSIZE || !lt_font[c]) w += 16; @@ -1913,6 +2484,16 @@ INT32 V_LevelNameHeight(const char *string) return w; } +// For ST_drawLevelTitle +// Returns the width of the act num patch +INT32 V_LevelActNumWidth(INT32 num) +{ + if (num < 0 || num > 19) + return 0; // not a valid number + + return SHORT(ttlnum[num]->width); +} + // // Find string width from hu_font chars // @@ -1938,17 +2519,18 @@ INT32 V_StringWidth(const char *string, INT32 option) for (i = 0; i < strlen(string); i++) { - c = string[i]; - if ((UINT8)c >= 0x80 && (UINT8)c <= 0x89) //color parsing! -Inuyasha 2.16.09 + if (string[i] & 0x80) continue; - - c = toupper(c) - HU_FONTSTART; + c = toupper(string[i]) - HU_FONTSTART; if (c < 0 || c >= HU_FONTSIZE || !hu_font[c]) w += spacewidth; else w += (charwidth ? charwidth : SHORT(hu_font[c]->width)); } + if (option & V_NOSCALESTART) + w *= vid.dupx; + return w; } @@ -1977,11 +2559,9 @@ INT32 V_SmallStringWidth(const char *string, INT32 option) for (i = 0; i < strlen(string); i++) { - c = string[i]; - if ((UINT8)c >= 0x80 && (UINT8)c <= 0x89) //color parsing! -Inuyasha 2.16.09 + if (string[i] & 0x80) continue; - - c = toupper(c) - HU_FONTSTART; + c = toupper(string[i]) - HU_FONTSTART; if (c < 0 || c >= HU_FONTSIZE || !hu_font[c]) w += spacewidth; else @@ -2016,11 +2596,9 @@ INT32 V_ThinStringWidth(const char *string, INT32 option) for (i = 0; i < strlen(string); i++) { - c = string[i]; - if ((UINT8)c >= 0x80 && (UINT8)c <= 0x89) //color parsing! -Inuyasha 2.16.09 + if (string[i] & 0x80) continue; - - c = toupper(c) - HU_FONTSTART; + c = toupper(string[i]) - HU_FONTSTART; if (c < 0 || c >= HU_FONTSIZE || !tny_font[c]) w += spacewidth; else diff --git a/src/v_video.h b/src/v_video.h index 877a619b5ac56ad60bb423918f1647b7dbb7d0af..43748692e706acd43098d840588dc85470394436 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -27,8 +27,12 @@ extern UINT8 *screens[5]; -extern const UINT8 gammatable[5][256]; -extern consvar_t cv_ticrate, cv_usegamma, cv_allcaps, cv_constextsize; +extern consvar_t cv_ticrate, cv_constextsize,\ +cv_globalgamma, cv_globalsaturation, \ +cv_rhue, cv_yhue, cv_ghue, cv_chue, cv_bhue, cv_mhue,\ +cv_rgamma, cv_ygamma, cv_ggamma, cv_cgamma, cv_bgamma, cv_mgamma, \ +cv_rsaturation, cv_ysaturation, cv_gsaturation, cv_csaturation, cv_bsaturation, cv_msaturation,\ +cv_allcaps; // Allocates buffer screens, call before R_Init. void V_Init(void); @@ -42,6 +46,7 @@ const char *R_GetPalname(UINT16 num); const char *GetPalette(void); extern RGBA_t *pLocalPalette; +extern RGBA_t *pMasterPalette; // Retrieve the ARGB value from a palette color index #define V_GetColor(color) (pLocalPalette[color&0xFF]) @@ -69,13 +74,21 @@ extern RGBA_t *pLocalPalette; #define V_CHARCOLORSHIFT 12 #define V_CHARCOLORMASK 0x0000F000 // for simplicity's sake, shortcuts to specific colors -#define V_PURPLEMAP 0x00001000 +#define V_MAGENTAMAP 0x00001000 #define V_YELLOWMAP 0x00002000 #define V_GREENMAP 0x00003000 #define V_BLUEMAP 0x00004000 #define V_REDMAP 0x00005000 #define V_GRAYMAP 0x00006000 #define V_ORANGEMAP 0x00007000 +#define V_SKYMAP 0x00008000 +#define V_PURPLEMAP 0x00009000 +#define V_AQUAMAP 0x0000A000 +#define V_PERIDOTMAP 0x0000B000 +#define V_AZUREMAP 0x0000C000 +#define V_BROWNMAP 0x0000D000 +#define V_ROSYMAP 0x0000E000 +#define V_INVERTMAP 0x0000F000 // use bits 17-20 for alpha transparency #define V_ALPHASHIFT 16 @@ -108,8 +121,8 @@ extern RGBA_t *pLocalPalette; #define V_WRAPX 0x10000000 // Don't clamp texture on X (for HW mode) #define V_WRAPY 0x20000000 // Don't clamp texture on Y (for HW mode) -#define V_NOSCALESTART 0x40000000 // don't scale x, y, start coords -#define V_SPLITSCREEN 0x80000000 +#define V_NOSCALESTART 0x40000000 // don't scale x, y, start coords +#define V_PERPLAYER 0x80000000 // automatically adjust coordinates/scaling for splitscreen mode // defines for old functions #define V_DrawPatch(x,y,s,p) V_DrawFixedPatch((x)<<FRACBITS, (y)<<FRACBITS, FRACUNIT, s|V_NOSCALESTART|V_NOSCALEPATCH, p, NULL) @@ -144,9 +157,10 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c); void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum); // fade down the screen buffer before drawing the menu over -void V_DrawFadeScreen(void); +void V_DrawFadeScreen(UINT16 color, UINT8 strength); void V_DrawFadeConsBack(INT32 plines); +void V_DrawPromptBack(INT32 boxheight, INT32 color); // draw a single character void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed); @@ -179,10 +193,12 @@ void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string) // Draw tall nums, used for menu, HUD, intermission void V_DrawTallNum(INT32 x, INT32 y, INT32 flags, INT32 num); void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits); +void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, INT32 num); // Find string width from lt_font chars INT32 V_LevelNameWidth(const char *string); INT32 V_LevelNameHeight(const char *string); +INT32 V_LevelActNumWidth(INT32 num); // act number width void V_DrawCreditString(fixed_t x, fixed_t y, INT32 option, const char *string); INT32 V_CreditStringWidth(const char *string); diff --git a/src/w_wad.c b/src/w_wad.c index 26a98bfdff0420a0e07fb4a49bd17170fbb7c52a..4fc9dd5a13819d66c2a63d1d54576a23fa998d7d 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -18,14 +18,26 @@ #define ZWAD #ifdef ZWAD -#ifdef _WIN32_WCE -#define AVOID_ERRNO -#else #include <errno.h> -#endif #include "lzf.h" #endif +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 0 +#endif + +#ifndef _LARGEFILE64_SOURCE +#define _LARGEFILE64_SOURCE +#endif + +#ifndef _LFS64_LARGEFILE +#define _LFS64_LARGEFILE +#endif + +//#ifdef HAVE_ZLIB +#include "zlib.h" +//#endif // HAVE_ZLIB + #include "doomdef.h" #include "doomstat.h" #include "doomtype.h" @@ -121,6 +133,7 @@ void W_Shutdown(void) Z_Free(wadfiles[numwadfiles]->filename); while (wadfiles[numwadfiles]->numlumps--) Z_Free(wadfiles[numwadfiles]->lumpinfo[wadfiles[numwadfiles]->numlumps].name2); + Z_Free(wadfiles[numwadfiles]->lumpinfo); Z_Free(wadfiles[numwadfiles]); } @@ -188,7 +201,7 @@ FILE *W_OpenWadFile(const char **filename, boolean useerrors) } // Look for all DEHACKED and Lua scripts inside a PK3 archive. -static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum) +static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile) { UINT16 posStart, posEnd; #ifdef HAVE_BLUA @@ -196,7 +209,7 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum) if (posStart != INT16_MAX) { posEnd = W_CheckNumForFolderEndPK3("Lua/", wadnum, posStart); - posStart++; + posStart++; // first "lump" will be "Lua/" folder itself, so ignore it for (; posStart < posEnd; posStart++) LUA_LoadLump(wadnum, posStart); } @@ -205,7 +218,8 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum) if (posStart != INT16_MAX) { posEnd = W_CheckNumForFolderEndPK3("SOC/", wadnum, posStart); - posStart++; + + posStart++; // first "lump" will be "SOC/" folder itself, so ignore it for(; posStart < posEnd; posStart++) { lumpinfo_t *lump_p = &wadfiles[wadnum]->lumpinfo[posStart]; @@ -214,15 +228,14 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum) sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->name2); name[length] = '\0'; CONS_Printf(M_GetText("Loading SOC from %s\n"), name); - DEH_LoadDehackedLumpPwad(wadnum, posStart); + DEH_LoadDehackedLumpPwad(wadnum, posStart, mainfile); free(name); } - } } // search for all DEHACKED lump in all wads and load it -static inline void W_LoadDehackedLumps(UINT16 wadnum) +static inline void W_LoadDehackedLumps(UINT16 wadnum, boolean mainfile) { UINT16 lump; @@ -247,18 +260,18 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum) name[length] = '\0'; CONS_Printf(M_GetText("Loading SOC from %s\n"), name); - DEH_LoadDehackedLumpPwad(wadnum, lump); + DEH_LoadDehackedLumpPwad(wadnum, lump, mainfile); free(name); } else if (memcmp(lump_p->name,"MAINCFG",8)==0) // Check for MAINCFG { CONS_Printf(M_GetText("Loading main config from %s\n"), wadfiles[wadnum]->filename); - DEH_LoadDehackedLumpPwad(wadnum, lump); + DEH_LoadDehackedLumpPwad(wadnum, lump, mainfile); } else if (memcmp(lump_p->name,"OBJCTCFG",8)==0) // Check for OBJCTCFG { CONS_Printf(M_GetText("Loading object config from %s\n"), wadfiles[wadnum]->filename); - DEH_LoadDehackedLumpPwad(wadnum, lump); + DEH_LoadDehackedLumpPwad(wadnum, lump, mainfile); } } @@ -650,7 +663,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) // // Can now load dehacked files (.soc) // -UINT16 W_InitFile(const char *filename) +UINT16 W_InitFile(const char *filename, boolean mainfile) { FILE *handle; lumpinfo_t *lumpinfo = NULL; @@ -760,6 +773,7 @@ UINT16 W_InitFile(const char *filename) // wadfile = Z_Malloc(sizeof (*wadfile), PU_STATIC, NULL); wadfile->filename = Z_StrDup(filename); + wadfile->type = type; wadfile->handle = handle; wadfile->numlumps = (UINT16)numlumps; wadfile->lumpinfo = lumpinfo; @@ -792,14 +806,14 @@ UINT16 W_InitFile(const char *filename) switch (wadfile->type) { case RET_WAD: - W_LoadDehackedLumps(numwadfiles - 1); + W_LoadDehackedLumps(numwadfiles - 1, mainfile); break; case RET_PK3: - W_LoadDehackedLumpsPK3(numwadfiles - 1); + W_LoadDehackedLumpsPK3(numwadfiles - 1, mainfile); break; case RET_SOC: CONS_Printf(M_GetText("Loading SOC from %s\n"), wadfile->filename); - DEH_LoadDehackedLumpPwad(numwadfiles - 1, 0); + DEH_LoadDehackedLumpPwad(numwadfiles - 1, 0, mainfile); break; #ifdef HAVE_BLUA case RET_LUA: @@ -814,38 +828,6 @@ UINT16 W_InitFile(const char *filename) return wadfile->numlumps; } -#ifdef DELFILE -void W_UnloadWadFile(UINT16 num) -{ - INT32 i; - wadfile_t *delwad = wadfiles[num]; - lumpcache_t *lumpcache; - if (num == 0) - return; - CONS_Printf(M_GetText("Removing WAD %s...\n"), wadfiles[num]->filename); - - DEH_UnloadDehackedWad(num); - wadfiles[num] = NULL; - lumpcache = delwad->lumpcache; - numwadfiles--; -#ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) - HWR_FreeTextureCache(); - M_AATreeFree(delwad->hwrcache); -#endif - if (*lumpcache) - { - for (i = 0;i < delwad->numlumps;i++) - Z_ChangeTag(lumpcache[i], PU_PURGELEVEL); - } - Z_Free(lumpcache); - fclose(delwad->handle); - Z_Free(delwad->filename); - Z_Free(delwad); - CONS_Printf(M_GetText("Done unloading WAD.\n")); -} -#endif - /** Tries to load a series of files. * All files are wads unless they have an extension of ".soc" or ".lua". * @@ -857,7 +839,7 @@ void W_UnloadWadFile(UINT16 num) * \return 1 if all files were loaded, 0 if at least one was missing or * invalid. */ -INT32 W_InitMultipleFiles(char **filenames) +INT32 W_InitMultipleFiles(char **filenames, UINT16 mainfiles) { INT32 rc = 1; @@ -868,7 +850,7 @@ INT32 W_InitMultipleFiles(char **filenames) for (; *filenames; filenames++) { //CONS_Debug(DBG_SETUP, "Loading %s\n", *filenames); - rc &= (W_InitFile(*filenames) != INT16_MAX) ? 1 : 0; + rc &= (W_InitFile(*filenames, numwadfiles < mainfiles) != INT16_MAX) ? 1 : 0; } if (!numwadfiles) @@ -936,10 +918,8 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump) { lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump; for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++) - { if (memcmp(lump_p->name,uname,8) == 0) return i; - } } // not found. @@ -1179,7 +1159,7 @@ boolean W_IsLumpFolder(UINT16 wad, UINT16 lump) /* report a zlib or i/o error */ void zerr(int ret) { - CONS_Printf("zpipe: "); + CONS_Printf("zpipe: "); switch (ret) { case Z_ERRNO: if (ferror(stdin)) @@ -1356,7 +1336,6 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si } else { - CONS_Printf("whopet\n"); size = 0; zerr(zErr); } @@ -1373,7 +1352,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si default: I_Error("wad %d, lump %d: unsupported compression type!", wad, lump); } - return -1; + return 0; } size_t W_ReadLumpHeader(lumpnum_t lumpnum, void *dest, size_t size, size_t offset) @@ -1757,8 +1736,7 @@ int W_VerifyNMUSlumps(const char *filename) {"TTL", 3}, // Act number changes {"STCFN", 5}, // Console font changes {"TNYFN", 5}, // Tiny console font changes - {"SBO", 3}, // Acceptable HUD changes (Score Time Rings) - {"RRINGS", 6}, // Rings HUD (not named as SBO) + {"STT", 3}, // Acceptable HUD changes (Score Time Rings) {"YB_", 3}, // Intermission graphics, goes with the above {"M_", 2}, // As does menu stuff diff --git a/src/w_wad.h b/src/w_wad.h index 87566c3ee8c103d33d554199d520cee4a501c91b..6517388504d39b66945f284b9bd294aa1bcaae18 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -96,7 +96,6 @@ typedef enum restype RET_UNKNOWN, } restype_t; - typedef struct wadfile_s { char *filename; @@ -110,7 +109,8 @@ typedef struct wadfile_s FILE *handle; UINT32 filesize; // for network UINT8 md5sum[16]; - boolean important; + + boolean important; // also network - !W_VerifyNMUSlumps } wadfile_t; #define WADFILENUM(lumpnum) (UINT16)((lumpnum)>>16) // wad flumpnum>>16) // wad file number in upper word @@ -126,14 +126,11 @@ void W_Shutdown(void); // Opens a WAD file. Returns the FILE * handle for the file, or NULL if not found or could not be opened FILE *W_OpenWadFile(const char **filename, boolean useerrors); // Load and add a wadfile to the active wad files, returns numbers of lumps, INT16_MAX on error -UINT16 W_InitFile(const char *filename); -#ifdef DELFILE -void W_UnloadWadFile(UINT16 num); -#endif +UINT16 W_InitFile(const char *filename, boolean mainfile); // W_InitMultipleFiles returns 1 if all is okay, 0 otherwise, // so that it stops with a message if a file was not found, but not if all is okay. -INT32 W_InitMultipleFiles(char **filenames); +INT32 W_InitMultipleFiles(char **filenames, UINT16 mainfiles); const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump); const char *W_CheckNameForNum(lumpnum_t lumpnum); diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg index 1880abf18bcdc5c686c32a2199aeaa08150eba07..11f3c91404d8cef06ab1fe0e6a23448670e2f938 100644 --- a/src/win32/Makefile.cfg +++ b/src/win32/Makefile.cfg @@ -10,12 +10,24 @@ ifdef MINGW64 HAVE_LIBGME=1 LIBGME_CFLAGS=-I../libs/gme/include LIBGME_LDFLAGS=-L../libs/gme/win64 -lgme + +ifdef HAVE_OPENMPT + LIBOPENMPT_CFLAGS?=-I../libs/libopenmpt/inc + LIBOPENMPT_LDFLAGS?=-L../libs/libopenmpt/lib/x86_64/mingw -lopenmpt +endif + SDL_CFLAGS?=-I../libs/SDL2/x86_64-w64-mingw32/include/SDL2 -I../libs/SDL2_mixer/x86_64-w64-mingw32/include/SDL2 -Dmain=SDL_main SDL_LDFLAGS?=-L../libs/SDL2/x86_64-w64-mingw32/lib -L../libs/SDL2_mixer/x86_64-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows else HAVE_LIBGME=1 LIBGME_CFLAGS=-I../libs/gme/include LIBGME_LDFLAGS=-L../libs/gme/win32 -lgme + +ifdef HAVE_OPENMPT + LIBOPENMPT_CFLAGS?=-I../libs/libopenmpt/inc + LIBOPENMPT_LDFLAGS?=-L../libs/libopenmpt/lib/x86/mingw -lopenmpt +endif + SDL_CFLAGS?=-I../libs/SDL2/i686-w64-mingw32/include/SDL2 -I../libs/SDL2_mixer/i686-w64-mingw32/include/SDL2 -Dmain=SDL_main SDL_LDFLAGS?=-L../libs/SDL2/i686-w64-mingw32/lib -L../libs/SDL2_mixer/i686-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows endif diff --git a/src/win32/Srb2win-vc10.vcxproj.filters b/src/win32/Srb2win-vc10.vcxproj.filters index 8f607796971841cb543a447e368407872c729ea9..fa4535491a666390e157578701c5ef7d3a0a2e37 100644 --- a/src/win32/Srb2win-vc10.vcxproj.filters +++ b/src/win32/Srb2win-vc10.vcxproj.filters @@ -453,10 +453,21 @@ <ClCompile Include="..\string.c"> <Filter>M_Misc</Filter> </ClCompile> - <ClCompile Include="..\hardware\hw_md2load.c" /> - <ClCompile Include="..\hardware\hw_md3load.c" /> - <ClCompile Include="..\hardware\hw_model.c" /> - <ClCompile Include="..\hardware\u_list.c" /> + <ClCompile Include="..\hardware\hw_md2load.c"> + <Filter>Hw_Hardware</Filter> + </ClCompile> + <ClCompile Include="..\hardware\hw_md3load.c"> + <Filter>Hw_Hardware</Filter> + </ClCompile> + <ClCompile Include="..\hardware\hw_model.c"> + <Filter>Hw_Hardware</Filter> + </ClCompile> + <ClCompile Include="..\hardware\u_list.c"> + <Filter>Hw_Hardware</Filter> + </ClCompile> + <ClCompile Include="..\hardware\hw_clip.c"> + <Filter>Hw_Hardware</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="afxres.h"> @@ -867,6 +878,9 @@ <ClInclude Include="..\fastcmp.h"> <Filter>O_Other</Filter> </ClInclude> + <ClInclude Include="..\hardware\hw_clip.h"> + <Filter>Hw_Hardware</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <Image Include="Srb2win.ico"> diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index cca7810b3b76209f117b35798fa08bceebac758b..e2f32fa618d2ff646f1b81a2f156e798cc88f154 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -323,7 +323,7 @@ static inline boolean I_SkipFrame(void) if (!paused) return false; /* FALLTHRU */ - case GS_TIMEATTACK: + //case GS_TIMEATTACK: -- sorry optimisation but now we have a cool level platter and that being laggardly looks terrible #ifndef CLIENT_LOADINGSCREEN case GS_WAITINGPLAYERS: #endif @@ -363,6 +363,10 @@ void I_FinishUpdate(void) if (I_SkipFrame()) return; + // draw captions if enabled + if (cv_closedcaptioning.value) + SCR_ClosedCaptions(); + // display a graph of ticrate if (cv_ticrate.value) SCR_DisplayTicRate(); diff --git a/src/win32ce/GameX.h b/src/win32ce/GameX.h deleted file mode 100644 index 241fdd5bec9b7c3b3c9ee4d4c9c5cdace6ea642c..0000000000000000000000000000000000000000 --- a/src/win32ce/GameX.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - - GameX - WindowsCE Game Library for High Performance. - - Copyright (C) 1999 Hayes C. Haugen, all rights reserved. - - */ - -/* - * Need better way for host app to keep track of direct vs blit - drawing. Right now GetFBAddress() is the way to do it. - - - */ - - -#pragma once -#include <windows.h> // For VK codes. - -// Defines - -// display property flags - -const unsigned long kfDPGrey = 0x0001; -const unsigned long kfDPGrey2Bit = 0x0002; -const unsigned long kfDPGrey4Bit = 0x0004; -const unsigned long kfDPColor = 0x0008; -const unsigned long kfDPColor8Bit = 0x0010; -const unsigned long kfDPColor16Bit = 0x0020; -const unsigned long kfDPColor24Bit = 0x0040; -const unsigned long kfDPColor32Bit = 0x0080; -const unsigned long kfDPFormatNormal = 0x0100; // fb start is upper left, inc goes across -const unsigned long kfDPFormatRot270 = 0x0200; // fb start is lower left, inc goes up - -// Machine property flags - -const unsigned long kfMPPSPC = 0x0001; // Palm Sized PC - 240 x 320 -const unsigned long kfMPPSPC1 = 0x0002; // 1st gen pspc -const unsigned long kfMPPSPC2 = 0x0004; // Wyverns -const unsigned long kfMPHPC = 0x0008; // Handheld PC -const unsigned long kfMPHPC1 = 0x0010; // HPC 1, 480 x 240 -const unsigned long kfMPHPC2 = 0x0020; // HPC 2, 640 x 240 -const unsigned long kfMPHPC3 = 0x0040; // HPC Pro, 640 x 240, big keys -const unsigned long kfMPPro = 0x0080; // -const unsigned long kfMPAutoPC = 0x0100; -const unsigned long kfMPHasKeyboard = 0x0200; -const unsigned long kfMPHasMouse = 0x0400; -const unsigned long kfMPHasRumble = 0x0800; -const unsigned long kfMPHasTouch = 0x1000; - -// Rotations - -const int kiRotate0 = 0; // no rotation -const int kiRotate90 = 1; // 90 degrees clockwise -const int kiRotate180 = 2; // 180 degrees clockwise (upside down, Rotate 0 flipped) -const int kiRotate270 = 3; // 270 degrees clockwise (Rotate 1 flipped) - -class GameX { -public: - HWND SetButtonNotificationWindow(HWND hWnd); - GameX(); - ~GameX(); - - bool OpenGraphics(); - bool OpenSound(); - bool OpenButtons(HWND hwndButtonNotify); // Window that will get button messages or NULL if you just want to use GetAsyncKeyState(); - bool CloseGraphics(); - bool CloseSound(); - bool CloseButtons(); - - bool IsColor(); - bool IsPSPC(); - bool IsHPC(); - bool IsHPCPro(); - bool HasMouse(); - bool HasKeyboard(); // better than inferring from hpc/pspc/etc. - bool HasRumble(); - bool HasTouch(); // for completeness. At least 1 doesn't. - - int IsForeground(); - bool Suspend(); // release buttons, don't draw, etc. - bool Resume(); // regrab buttons, etc. - - bool BeginDraw(); - bool EndDraw(); - bool FindFrameBuffer(); - void * GetFBAddress(); // simple way to get things that makes code - long GetFBModulo(); // more readable. - long GetFBBpp(); - bool GetScreenRect(RECT * prc); - unsigned long GetDisplayProperties(); - - bool GetButton(int VK); // buttons init themselves on first button call?? - unsigned short GetDefaultButtonID(long id, long rotate); // gets the best button for use as specified by need and rotation - bool ReleaseButton(int VK); - bool BeginDetectButtons(); // grabs all buttons so user can indicate a button in a config dialog - bool EndDetectButtons(); // releases all buttons (except GetButton() ones) - - bool Rumble(); - bool Backlight(bool fOn); -private: -// LRESULT CALLBACK TaskBarWndProc(HWND hWnd, UINT message, WPARAM uParam, LPARAM lParam); - -private: - int m_iMP; // index into amp table for current machine. - void * m_pvFrameBuffer; - long m_cbFBModulo; // count of bytes to next line - unsigned long m_ffMachineProperties; - unsigned long m_ffDisplayProperties; - int m_cBitsPP; - - long m_dwPrevMode; // for Begin/EndDraw() - bool m_fActive; // true if active (resume), false if inactive (suspend). - - HWND m_hwndTaskbar; // Taskbar is official cap, change TaskBar's -}; - - -/* - -kmtCasioE10 -kmtCasioE11 -kmtCasioE15 -kmtCasioE55 -kmtCasioE100 -kmtLGPhenomII - -stuff for memory size and presence/absence of CF - -// Rotations that make sense for this device or default rotation: - -Rotate0 // no rotation -Rotate1 // 90 degrees clockwise -Rotate2 // 180 degrees clockwise (upside down, Rotate 0 flipped) -Rotate3 // 270 degrees clockwise (Rotate 1 flipped) - -kmtAccessNone // no direct framebuffer access -kmtAccess1 // write to fixed address -kmtAccess2 // find framebuffer memory aperture in GWES.EXE memory space. - -OriginUpperLeft -OriginUpperRight -OriginLowerRight -OriginLowerLeft - -MappedHorizontal // increasing fb address goes across screen -MappedVertical // increasing fb address goes up/down screen (Compaq) - -A machine entry: -=========================================== - machine kmtCasioE10, - type kmtPSPC | kmtPSPC1, - displaytype kmtGrey | kmtGrey2Bit | kmtAccess1, - pvFrameBuffer 0xAA000000, - cbFBModulo 1024 // count of bytes to next line - cbppFB 2, // bits per pixel - cxDisp 240, - cyDisp 320, - format OriginUpperLeft, MappedHorizontal - - rotate0 // for rotate mode 0, these are the best keys - vkUp VK_UP - vkDown VK_DOWN - vkLeft 0xC1 - vkRight 0xC2 - vkA 0xC3 - vkB 0 - rotate1 - vkUp 0xC1 - vkDown 0xC2 - vkLeft VK_DOWN - ... - ...*/ - diff --git a/src/win32ce/SRB2CE.zip b/src/win32ce/SRB2CE.zip deleted file mode 100644 index 3ac8530dcb124cbda512a7d469da933c3fc974bf..0000000000000000000000000000000000000000 Binary files a/src/win32ce/SRB2CE.zip and /dev/null differ diff --git a/src/win32ce/Srb2win.ico b/src/win32ce/Srb2win.ico deleted file mode 100644 index 700276fd4b9ac2810a6981eb054921f3708c702b..0000000000000000000000000000000000000000 Binary files a/src/win32ce/Srb2win.ico and /dev/null differ diff --git a/src/win32ce/afxres.h b/src/win32ce/afxres.h deleted file mode 100644 index 7f5245404eef8c9fac3efe28c48f31b22cb657d1..0000000000000000000000000000000000000000 --- a/src/win32ce/afxres.h +++ /dev/null @@ -1,17 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief needed if mfc not installed (if I remember well) diff --git a/src/win32ce/gapi_c.cpp b/src/win32ce/gapi_c.cpp deleted file mode 100644 index 60c7adfa2f1eec4e047515c03a43b803d1dd19d5..0000000000000000000000000000000000000000 --- a/src/win32ce/gapi_c.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include <stdlib.h> -#include <windows.h> - -#define _USE_GAPI_ - - -#ifndef _USE_GAPI_ - #include "GameX.h" - -struct GXDisplayProperties -{ - DWORD cxWidth; - DWORD cyHeight; - long cbxPitch; - long cbyPitch; - long cBPP; - DWORD ffFormat; -}; - -#define kfPalette 0x10 // Pixel values are indexes into a palette -#define kfDirect565 0x80 // 5 red bits, 6 green bits and 5 blue bits per pixel - - - GameX* gx = new GameX; -#else - #include "gx.h" -#endif - -extern "C" -{ - #include "gapi_c.h" -} - -extern "C" int GXOPENDISPLAY(HWND hWnd, DWORD dwFlags) -{ - #ifndef _USE_GAPI_ - if(!gx) - return 0; - - //gx->OpenSound(); - if(!gx->OpenGraphics()) - { - delete gx; - gx = 0; - return 0; - } - - return TRUE; - - #else - return GXOpenDisplay(hWnd,dwFlags); - #endif -} - -extern "C" int GXCLOSEDISPLAY() -{ - #ifndef _USE_GAPI_ - gx->CloseGraphics(); - return TRUE; - #else - return GXCloseDisplay(); - #endif -} - -extern "C" void * GXBEGINDRAW() -{ - #ifndef _USE_GAPI_ - if(gx->BeginDraw()) - return gx->GetFBAddress(); - - return NULL; - #else - return GXBeginDraw(); - #endif -} - -extern "C" int GXENDDRAW() -{ - #ifndef _USE_GAPI_ - return gx->EndDraw(); - #else - return GXEndDraw(); - #endif - -} - -extern "C" struct GXDisplayProperties GXGETDISPLAYPROPERTIES() -{ - #ifndef _USE_GAPI_ - RECT r; - GXDisplayProperties gxdp; - - gxdp.cbyPitch = gx->GetFBModulo(); - gxdp.cBPP = gx->GetFBBpp(); - gxdp.cbxPitch = (gxdp.cBPP >> 3); - - gx->GetScreenRect(&r); - gxdp.cxWidth = (r.right - r.left); - gxdp.cyHeight = (r.bottom - r.top); - - if(gxdp.cBPP = 16) - gxdp.ffFormat = kfDirect565; - else if(gxdp.cBPP = 8) - gxdp.ffFormat = kfPalette; - - return gxdp; - - #else - return GXGetDisplayProperties(); - #endif -} - -extern "C" int GXSUSPEND() -{ - #ifndef _USE_GAPI_ - return gx->Suspend(); - #else - return GXSuspend(); - #endif -} - -extern "C" int GXRESUME() -{ - #ifndef _USE_GAPI_ - return gx->Resume(); - #else - return GXResume(); - #endif -} \ No newline at end of file diff --git a/src/win32ce/gapi_c.h b/src/win32ce/gapi_c.h deleted file mode 100644 index 40e7799ffc664691964b614dffe5c7af7f4bb809..0000000000000000000000000000000000000000 --- a/src/win32ce/gapi_c.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef GAPI_H -#define GAPI_H - -int GXOPENDISPLAY(HWND hWnd, DWORD dwFlags); -int GXCLOSEDISPLAY(); -void * GXBEGINDRAW(); -int GXENDDRAW(); -struct GXDisplayProperties GXGETDISPLAYPROPERTIES(); -int GXSUSPEND(); -int GXRESUME(); - -#endif \ No newline at end of file diff --git a/src/win32ce/gxgapilib.c b/src/win32ce/gxgapilib.c deleted file mode 100644 index 8ff57092d168461bc83eadee79614d936d05b3ee..0000000000000000000000000000000000000000 --- a/src/win32ce/gxgapilib.c +++ /dev/null @@ -1,636 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -//----------------------------------------------------------------------------- -/// \file -/// \brief Zak Larue-Buckley's GX and GAPI library v1.0 - -#include "../doomdef.h" -//#define WIN32_LEAN_AND_MEAN -#define RPC_NO_WINDOWS_H -#include <windows.h> -#include <windowsx.h> -#include "../i_system.h" -#include "dx_error.h" - -#include "fabdxlib.h" - -#define NT4COMPAT //always defined, always compatible - - -// globals - -IDirectDraw2* DDr2 = NULL; -IDirectDrawSurface* ScreenReal = NULL; // DirectDraw primary surface -IDirectDrawSurface* ScreenVirtual = NULL; // DirectDraw back surface -IDirectDrawPalette* DDPalette = NULL; // The primary surface palette -static IDirectDrawClipper *windclip = NULL; // clipper for windowed mode - -BOOL bAppFullScreen; // true for fullscreen exclusive mode, - -int windowPosX = 0; // current position in windowed mode -int windowPosY = 0; - -int ScreenWidth; -int ScreenHeight; -BOOL ScreenLocked; // Screen surface is being locked -int ScreenPitch; // offset from one line to the next -LPBYTE ScreenPtr; // memory of the surface - - -// -// CreateNewSurface -// -static inline IDirectDrawSurface* CreateNewSurface(int dwWidth, - int dwHeight, - int dwSurfaceCaps) -{ - DDSURFACEDESC ddsd; - HRESULT hr; - LPDIRECTDRAWSURFACE psurf; - - ZeroMemory(&ddsd, sizeof (ddsd)); - ddsd.dwSize = sizeof (ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH; - - ddsd.ddsCaps.dwCaps = dwSurfaceCaps; - - ddsd.dwHeight = dwHeight; - ddsd.dwWidth = dwWidth; - - hr = IDirectDraw2_CreateSurface (DDr2, &ddsd, &psurf, NULL); - - if (hr == DD_OK) - { - //DDCOLORKEY ddck; - IDirectDrawSurface_Restore(psurf); - - //hr = IDirectDrawSurface_GetColorKey(DDCKEY_SRCBLT, &ddck); - //psurf->SetColorKey(DDCKEY_SRCBLT, &ddck); - } - else - psurf = NULL; - - return psurf; -} - -// -// wow! from 320x200x8 up to 1600x1200x32 thanks Banshee! :) -// -static HRESULT WINAPI myEnumModesCallback (LPDDSURFACEDESC surf, LPVOID lpContext) -{ - APPENUMMODESCALLBACK pfnContext = lpContext; - - if (pfnContext) pfnContext(surf->dwWidth, - surf->dwHeight,surf->ddpfPixelFormat. -#ifdef DUMMYUNIONNAMEN - DUMMYUNIONNAMEN(1). -#endif - dwRGBBitCount - ); - - /*CONS_Printf ("%dx%dx%d bpp %d refresh\n", - surf->dwWidth, - surf->dwHeight, - surf->ddpfPixelFormat.dwRGBBitCount, - surf->dwRefreshRate);*/ - - return DDENUMRET_OK; -} - - -// -// Application call here to enumerate display modes -// -BOOL EnumDirectDrawDisplayModes (APPENUMMODESCALLBACK appFunc) -{ - LPVOID lpappFunc = appFunc; - - if (DDr2 == NULL) - return FALSE; - - // enumerate display modes - // Carl: DirectX 3.x apparently does not support VGA modes. Who cares. :) - // faB: removed DDEDM_REFRESHRATES, detects too many modes, plus we don't care of refresh rate. - if (bDX0300) - IDirectDraw2_EnumDisplayModes (DDr2, 0 /*| DDEDM_REFRESHRATES*/, - NULL, lpappFunc, myEnumModesCallback); - else - IDirectDraw2_EnumDisplayModes (DDr2, DDEDM_STANDARDVGAMODES /*| DDEDM_REFRESHRATES*/, - NULL, lpappFunc, myEnumModesCallback); - return TRUE; -} - - -// -// Create the DirectDraw object for later -// -BOOL CreateDirectDrawInstance (VOID) -{ - HRESULT hr; - IDirectDraw* DDr; - IDirectDraw** rp = &DDr; - IDirectDraw2** rp2 = &DDr2; - LPVOID *tp = (LPVOID *)rp2; - - // - // create an instance of DirectDraw object - // - if (FAILED(hr = DirectDrawCreate(NULL, rp, NULL))) - I_Error("DirectDrawCreate FAILED: %s", DXErrorToString(hr)); - - // change interface to IDirectDraw2 - if (FAILED(hr = IDirectDraw_QueryInterface (DDr, &IID_IDirectDraw2, tp))) - I_Error("Failed to query DirectDraw2 interface: %s", DXErrorToString(hr)); - - // release the interface we don't need - IDirectDraw_Release (DDr); - return TRUE; -} - - -// -// - returns true if DirectDraw was initialized properly -// -int InitDirectDrawe (HWND appWin, int width, int height, int bpp, int fullScr) -{ - DDSURFACEDESC ddsd; // DirectDraw surface description for allocating - DDSCAPS ddscaps; - HRESULT ddrval; - - DWORD dwStyle; - RECT rect; - - // enumerate directdraw devices - //if (FAILED(DirectDrawEnumerate (myEnumDDDevicesCallback, NULL))) - // I_Error("Error with DirectDrawEnumerate"); - - if (!DDr2) - CreateDirectDrawInstance(); - - // remember what screen mode we are in - bAppFullScreen = fullScr; - ScreenHeight = height; - ScreenWidth = width; - - if (bAppFullScreen) - { - // Change window attributes - dwStyle = WS_POPUP | WS_VISIBLE; - SetWindowLong (appWin, GWL_STYLE, dwStyle); - SetWindowPos(appWin, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | - SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); - - // Get exclusive mode - ddrval = IDirectDraw2_SetCooperativeLevel(DDr2, appWin, DDSCL_EXCLUSIVE | - DDSCL_FULLSCREEN | - DDSCL_ALLOWREBOOT); - if (ddrval != DD_OK) - I_Error("SetCooperativeLevel FAILED: %s\n", DXErrorToString(ddrval)); - - // Switch from windows desktop to fullscreen - -#ifdef NT4COMPAT - ddrval = IDirectDraw2_SetDisplayMode(DDr2, width, height, bpp, 0, 0); -#else - ddrval = IDirectDraw2_SetDisplayMode(DDr2, width, height, bpp, 0, DDSDM_STANDARDVGAMODE); -#endif - if (ddrval != DD_OK) - I_Error("SetDisplayMode FAILED: %s\n", DXErrorToString(ddrval)); - - // This is not really needed, except in certain cases. One case - // is while using MFC. When the desktop is initally at 16bpp, a mode - // switch to 8bpp somehow causes the MFC window to not fully initialize - // and a CreateSurface will fail with DDERR_NOEXCLUSIVEMODE. This will - // ensure that the window is initialized properly after a mode switch. - - ShowWindow(appWin, SW_SHOW); - - // Create the primary surface with 1 back buffer. Always zero the - // DDSURFACEDESC structure and set the dwSize member! - - ZeroMemory(&ddsd, sizeof (ddsd)); - ddsd.dwSize = sizeof (ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; - - // for fullscreen we use page flipping, for windowed mode, we blit the hidden surface to - // the visible surface, in both cases we have a visible (or 'real') surface, and a hidden - // (or 'virtual', or 'backbuffer') surface. - ddsd.dwBackBufferCount = 1; - - ddrval = IDirectDraw2_CreateSurface(DDr2,&ddsd, &ScreenReal, NULL); - if (ddrval != DD_OK) - I_Error("CreateSurface Primary Screen FAILED"); - - // Get a pointer to the back buffer - - ddscaps.dwCaps = DDSCAPS_BACKBUFFER; - ddrval = IDirectDrawSurface_GetAttachedSurface(ScreenReal,&ddscaps, &ScreenVirtual); - if (ddrval != DD_OK) - I_Error("GetAttachedSurface FAILED"); - } - else - { - rect.top = 0; - rect.left = 0; - rect.bottom = height-1; - rect.right = width-1; - - // Change window attributes - - dwStyle = GetWindowStyle(appWin); - dwStyle &= ~WS_POPUP; - dwStyle |= WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION; - - SetWindowLong(appWin, GWL_STYLE, dwStyle); - - // Resize the window so that the client area is the requested width/height - - AdjustWindowRectEx(&rect, GetWindowStyle(appWin), GetMenu(appWin) != NULL, - GetWindowExStyle(appWin)); - - // Just in case the window was moved off the visible area of the - // screen. - - SetWindowPos(appWin, NULL, 0, 0, rect.right-rect.left, - rect.bottom-rect.top, SWP_NOMOVE | SWP_NOZORDER | - SWP_NOACTIVATE); - - SetWindowPos(appWin, HWND_NOTOPMOST, 0, 0, 0, 0, - SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); - - // Exclusive mode is normal since it's in windowed mode and needs - // to cooperate with GDI - - ddrval = IDirectDraw2_SetCooperativeLevel(DDr2,appWin, DDSCL_NORMAL); - if (ddrval != DD_OK) - I_Error("SetCooperativeLevel FAILED"); - - // Always zero the DDSURFACEDESC structure and set the dwSize member! - - ZeroMemory(&ddsd, sizeof (ddsd)); - ddsd.dwSize = sizeof (ddsd); - ddsd.dwFlags = DDSD_CAPS; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - - // Create the primary surface - - ddrval = IDirectDraw2_CreateSurface(DDr2,&ddsd, &ScreenReal, NULL); - if (ddrval != DD_OK) - I_Error("CreateSurface Primary Screen FAILED"); - - // Create a back buffer for offscreen rendering, this will be used to - // blt to the primary - - ScreenVirtual = CreateNewSurface(width, height, DDSCAPS_OFFSCREENPLAIN | - DDSCAPS_SYSTEMMEMORY); - if (ScreenVirtual == NULL) - I_Error("CreateSurface Secondary Screen FAILED"); - - /// \todo get the desktop bit depth, and build a lookup table - /// for quick conversions of 8bit color indexes 0-255 to desktop colors - /// eg: 256 entries of equivalent of palette colors 0-255 in 15,16,24,32 bit format - /// when blit virtual to real, convert pixels through lookup table.. - - // Use a clipper object for clipping when in windowed mode - // (make sure our drawing doesn't affect other windows) - - ddrval = IDirectDraw2_CreateClipper (DDr2, 0, &windclip, 0); - if (ddrval != DD_OK) - I_Error("CreateClipper FAILED"); - - // Associate the clipper with the window. - ddrval = IDirectDrawClipper_SetHWnd (windclip,0, appWin); - if (ddrval != DD_OK) - I_Error("Clipper -> SetHWnd FAILED"); - - // Attach the clipper to the surface. - ddrval = IDirectDrawSurface_SetClipper (ScreenReal,windclip); - if (ddrval != DD_OK) - I_Error("PrimaryScreen -> SetClipperClipper FAILED"); - } - - return TRUE; -} - - -// -// Free all memory -// -VOID CloseDirectDraw (VOID) -{ - ReleaseChtuff(); - if (DDr2) - { - IDirectDraw2_Release(DDr2); - DDr2 = NULL; - } -} - - -// -// Release DirectDraw stuff before display mode change -// -VOID ReleaseChtuff (VOID) -{ - if (!DDr2) - return; - if (windclip) - { - IDirectDrawClipper_Release(windclip); - windclip = NULL; - } - if (DDPalette) - { - IDirectDrawPalette_Release(DDPalette); - DDPalette = NULL; - } - // If the app is fullscreen, the back buffer is attached to the - // primary. Releasing the primary buffer will also release any - // attached buffers, so explicitly releasing the back buffer is not - // necessary. - - if (!bAppFullScreen && ScreenVirtual) - { - IDirectDrawSurface_Release(ScreenVirtual); // release hidden surface - ScreenVirtual = NULL; - } - if (ScreenReal) - { - IDirectDrawSurface_Release(ScreenReal); // and attached backbuffers for bAppFullScreen mode - ScreenReal = NULL; - } -} - - -// -// Clear the surface to color -// -VOID ClearSurface(IDirectDrawSurface* surface, int color) -{ - DDBLTFX ddbltfx; - - // Use the blter to do a color fill to clear the back buffer - ddbltfx.dwSize = sizeof (ddbltfx); - ddbltfx. -#ifdef DUMMYUNIONNAMEN - DUMMYUNIONNAMEN(5). -#endif - dwFillColor = color; - IDirectDrawSurface_Blt(surface,NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); - -} - -// -// Flip the real page with virtual page -// - in bAppFullScreen mode, do page flipping -// - in windowed mode, copy the hidden surface to the visible surface -// -// waitflip : if not 0, wait for page flip to end -BOOL ScreenFlip(int waitflip) -{ - HRESULT hr; - RECT rect; - - waitflip = 0; - if (bAppFullScreen) - { - //hr = IDirectDrawSurface_GetFlipStatus (ScreenReal, DDGFS_); - - // In full-screen exclusive mode, do a hardware flip. - hr = IDirectDrawSurface_Flip(ScreenReal, NULL, DDFLIP_WAIT); //return immediately - - // If the surface was lost, restore it. - if (hr == DDERR_SURFACELOST) - { - IDirectDrawSurface_Restore(ScreenReal); - - // The restore worked, so try the flip again. - hr = IDirectDrawSurface_Flip(ScreenReal, 0, DDFLIP_WAIT); - } - } - else - { - rect.left = windowPosX; - rect.top = windowPosY; - rect.right = windowPosX + ScreenWidth - 1; - rect.bottom = windowPosY + ScreenHeight - 1; - - // Copy the back buffer to front. - hr = IDirectDrawSurface_Blt(ScreenReal, &rect, ScreenVirtual, 0, DDBLT_WAIT, 0); - - if (hr != DD_OK) - { - // If the surfaces were lost, restore them. - if (IDirectDrawSurface_IsLost(ScreenReal) == DDERR_SURFACELOST) - IDirectDrawSurface_Restore(ScreenReal); - - if (IDirectDrawSurface_IsLost(ScreenVirtual) == DDERR_SURFACELOST) - IDirectDrawSurface_Restore(ScreenVirtual); - - // Retry the copy. - hr = IDirectDrawSurface_Blt(ScreenReal,&rect, ScreenVirtual, 0, DDBLT_WAIT, 0); - } - } - - if (hr != DD_OK) - I_Error("ScreenFlip() : couldn't Flip surfaces"); - - return FALSE; -} - -// -// Print a text to the surface -// -VOID TextPrint(int x, int y, LPCSTR message) -{ - HRESULT hr; - HDC hdc = NULL; - - // Get the device context handle. - hr = IDirectDrawSurface_GetDC(ScreenVirtual,&hdc); - if (hr != DD_OK) - return; - - // Write the message. - SetBkMode(hdc, TRANSPARENT); - SetTextColor(hdc, RGB(255, 255, 255)); - TextOutA(hdc, x, y, message, (int)strlen(message)); - - // Release the device context. - hr = IDirectDrawSurface_ReleaseDC(ScreenVirtual,hdc); -} - -// -// Lock surface before multiple drawings by hand, for speed -// -boolean LockScreen(VOID) -{ - DDSURFACEDESC ddsd; - HRESULT ddrval; - - ZeroMemory(&ddsd, sizeof (ddsd)); - ddsd.dwSize = sizeof (ddsd); - - // attempt to Lock the surface - ddrval = IDirectDrawSurface_Lock(ScreenVirtual, NULL, &ddsd, DDLOCK_WAIT, NULL); - - // Always, always check for errors with DirectX! - // If the surface was lost, restore it. - if (ddrval == DDERR_SURFACELOST) - { - ddrval = IDirectDrawSurface_Restore(ScreenReal); - - // now retry to get the lock - ddrval = IDirectDrawSurface_Lock(ScreenVirtual, NULL, &ddsd, DDLOCK_WAIT, NULL); - } - - if (ddrval == DD_OK) - { - ScreenLocked = TRUE; - ScreenPtr = (LPBYTE)ddsd.lpSurface; - ScreenPitch = ddsd. -#ifdef DUMMYUNIONNAMEN - DUMMYUNIONNAMEN(1). -#endif - lPitch; - } - else - { - ScreenLocked = FALSE; - ScreenPtr = NULL; - ScreenPitch = 0; - //I_Error("LockScreen() : couldn't restore the surface."); - return false; - } - return true; -} - -// -// Unlock surface -// -VOID UnlockScreen(VOID) -{ - if (DD_OK != IDirectDrawSurface_Unlock(ScreenVirtual,NULL)) - I_Error("Couldn't UnLock the renderer!"); - - ScreenLocked = FALSE; - ScreenPtr = NULL; - ScreenPitch = 0; -} - -// Blit virtual screen to real screen -//faB: note: testing 14/03/1999, see if it is faster than memcopy of virtual to -/* -static LPDIRECTDRAWSURFACE lpDDS = NULL; -VOID BlitScreen(VOID) -{ - HRESULT hr; - - if (!lpDDS) - I_Error("lpDDS NULL"); - - hr = IDirectDrawSurface_BltFast(ScreenVirtual, - 0, 0, // Upper left xy of destination - lpDDS, // Source surface - NULL, // Source rectangle = entire surface - DDBLTFAST_WAIT | DDBLTFAST_NOCOLORKEY); - if (FAILED(hr)) - I_Error("BltFast FAILED"); -} - -VOID MakeScreen(int width, int height, BYTE* lpSurface) -{ - HRESULT hr; - DDSURFACEDESC ddsd; - - // Initialize the surface description. - ZeroMemory (&ddsd, sizeof ddsd); - ZeroMemory (&ddsd.ddpfPixelFormat, sizeof (DDPIXELFORMAT)); - ddsd.dwSize = sizeof ddsd; - ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | //DDSD_LPSURFACE | - DDSD_PITCH | DDSD_PIXELFORMAT | DDSD_CAPS; - ddsd.dwWidth = width; - ddsd.dwHeight= height; - ddsd.lPitch = width; - ddsd.lpSurface = lpSurface; - ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN; - - // Set up the pixel format for 8-bit - ddsd.ddpfPixelFormat.dwSize = sizeof (DDPIXELFORMAT); - ddsd.ddpfPixelFormat.dwFlags= DDPF_RGB | DDPF_PALETTEINDEXED8; - ddsd.ddpfPixelFormat.dwRGBBitCount = 8; - - // - ddsd.ddpfPixelFormat.dwRGBBitCount = (DWORD)DEPTH*8; - ddsd.ddpfPixelFormat.dwRBitMask = 0x00FF0000; - ddsd.ddpfPixelFormat.dwGBitMask = 0x0000FF00; - ddsd.ddpfPixelFormat.dwBBitMask = 0x000000FF; - - // Create the surface - hr = IDirectDraw2_CreateSurface(DDr2, &ddsd, &lpDDS, NULL); - if (FAILED(hr)) - I_Error("MakeScreen FAILED: %s",DDError(hr)); - //ddsd.lpSurface = lpSurface; -} -*/ - -// -// Create a palette object -// -VOID CreateDDPalette (PALETTEENTRY* colorTable) -{ - HRESULT ddrval; - ddrval = IDirectDraw2_CreatePalette(DDr2,DDPCAPS_8BIT|DDPCAPS_ALLOW256, colorTable, &DDPalette, NULL); - if (ddrval != DD_OK) - I_Error("couldn't CreatePalette"); -}; - - -// -// Free the palette object -// -VOID DestroyDDPalette (VOID) -{ - if (DDPalette) - { - IDirectDrawPalette_Release(DDPalette); - DDPalette = NULL; - } -} - -// -// Set a a full palette of 256 PALETTEENTRY entries -// -VOID SetDDPalette(PALETTEENTRY* pal) -{ - // create palette first time - if (DDPalette == NULL) - CreateDDPalette(pal); - else - IDirectDrawPalette_SetEntries(DDPalette, 0, 0, 256, pal); - // setting the same palette to the same surface again does not increase - // the reference count - IDirectDrawSurface_SetPalette(ScreenReal, DDPalette); -} - -// -// Wait for vsync, gross -// -VOID WaitVbl(VOID) -{ - IDirectDraw2_WaitForVerticalBlank(DDr2, DDWAITVB_BLOCKBEGIN, NULL); -} diff --git a/src/win32ce/gxgapilib.h b/src/win32ce/gxgapilib.h deleted file mode 100644 index 189cc15b8804d77bd4c0db4558421668f84e655c..0000000000000000000000000000000000000000 --- a/src/win32ce/gxgapilib.h +++ /dev/null @@ -1,81 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief Zak Larue-Buckley's GX and GAPI library v1.0 - -#ifndef _H_GXGAPILIB_ -#define _H_GXGAPILIB_ - -//#define WIN32_LEAN_AND_MEAN -#define RPC_NO_WINDOWS_H -#include <windows.h> -#ifdef __MINGW32__ -//#define NONAMELESSUNION -#endif -#ifdef _MSC_VER -#pragma warning(disable : 4201) -#endif -#include <ddraw.h> -#if (defined (DIRECTDRAW_VERSION) && (DIRECTDRAW_VERSION >= 0x0700)) -#undef DUMMYUNIONNAMEN -#endif -// format of function in app called with width,height -typedef BOOL (*APPENUMMODESCALLBACK)(int width, int height, int bpp); - - -// globals -extern IDirectDraw2* DDr2; -extern IDirectDrawSurface* ScreenReal; -extern IDirectDrawSurface* ScreenVirtual; -extern IDirectDrawPalette* DDPalette; - -extern BOOL bAppFullScreen; // main code might need this to know the current - // fullscreen or windowed state - -extern int windowPosX; // current position in windowed mode -extern int windowPosY; - -extern int ScreenWidth; -extern int ScreenHeight; -extern BOOL ScreenLocked; // Screen surface is being locked -extern int ScreenPitch; // offset from one line to the next -extern LPBYTE ScreenPtr; // memory of the surface - -extern BOOL bDX0300; - -BOOL EnumDirectDrawDisplayModes (APPENUMMODESCALLBACK appFunc); -BOOL CreateDirectDrawInstance (VOID); - -int InitDirectDrawe (HWND appWin, int width, int height, int bpp, int fullScr); -VOID CloseDirectDraw (VOID); - -VOID ReleaseChtuff (VOID); - -VOID ClearSurface (IDirectDrawSurface* surface, int color); -BOOL ScreenFlip (int wait); -VOID TextPrint (int x, int y, LPCSTR message); - -VOID CreateDDPalette (PALETTEENTRY* colorTable); -VOID DestroyDDPalette (VOID); -VOID SetDDPalette (PALETTEENTRY* pal); - -VOID WaitVbl (VOID); - -boolean LockScreen (VOID); -VOID UnlockScreen (VOID); - - -#endif /* _H_FABDXLIB_ */ diff --git a/src/win32ce/midstuff.h b/src/win32ce/midstuff.h deleted file mode 100644 index 08ee80add3fa310a3110867633d21e1ab7a1d3f2..0000000000000000000000000000000000000000 --- a/src/win32ce/midstuff.h +++ /dev/null @@ -1,150 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief MIDI structures and definitions -/// used by the MSTREAM sample application in -/// converting a MID file to a MIDI stream for -/// playback using the midiStream API. -/// Inpired by DirectX5 SDK examples - -#ifndef __MIDSTUFF_H__ -#define __MIDSTUFF_H__ - -// MIDI file constants -// -#define MThd 0x6468544D // Start of file -#define MTrk 0x6B72544D // Start of track - -#define MIDI_SYSEX ((BYTE)0xF0) // SysEx begin -#define MIDI_SYSEXEND ((BYTE)0xF7) // SysEx begin -#define MIDI_META ((BYTE)0xFF) // Meta event begin -#define MIDI_META_TEMPO ((BYTE)0x51) // Tempo change -#define MIDI_META_EOT ((BYTE)0x2F) // End-of-track - -#define MIDI_NOTEOFF ((BYTE)0x80) // + note + velocity -#define MIDI_NOTEON ((BYTE)0x90) // + note + velocity -#define MIDI_POLYPRESS ((BYTE)0xA0) // + pressure (2 bytes) -#define MIDI_CTRLCHANGE ((BYTE)0xB0) // + ctrlr + value -#define MIDI_PRGMCHANGE ((BYTE)0xC0) // + new patch -#define MIDI_CHANPRESS ((BYTE)0xD0) // + pressure (1 byte) -#define MIDI_PITCHBEND ((BYTE)0xE0) // + pitch bend (2 bytes) - -#define NUM_CHANNELS 16 - -#define MIDICTRL_VOLUME ((BYTE)0x07) -#define MIDICTRL_VOLUME_LSB ((BYTE)0x27) -#define MIDICTRL_PAN ((BYTE)0x0A) - -#define MIDIEVENT_CHANNEL(dw) (dw & 0x0000000F) -#define MIDIEVENT_TYPE(dw) (dw & 0x000000F0) -#define MIDIEVENT_DATA1(dw) ((dw & 0x0000FF00) >> 8) -#define MIDIEVENT_VOLUME(dw) ((dw & 0x007F0000) >> 16) - -// Macros for swapping hi/lo-endian data -// -#define WORDSWAP(w) (((w) >> 8) | \ - (((w) << 8) & 0xFF00)) - -#define DWORDSWAP(dw) (((dw) >> 24) | \ - (((dw) >> 8) & 0x0000FF00) | \ - (((dw) << 8) & 0x00FF0000) | \ - (((dw) << 24) & 0xFF000000)) - -// In debug builds, TRACKERR will show us where the parser died -// -//#define TRACKERR(p,sz) ShowTrackError(p,sz); -#define TRACKERR(p,sz) - - -// Make a little distinction here so the various structure members are a bit -// more clearly labelled -- we have offsets and byte counts to keep track of -// that deal with both in-memory buffers and the file on disk - -#define FILEOFF DWORD - - -// These structures are stored in MIDI files; they need to be byte aligned. -// -#if defined(_MSC_VER) -#pragma pack(1) -#endif - -// Chunk header. dwTag is either MTrk or MThd. -// -typedef struct -{ - DWORD dwTag; // Type - DWORD dwChunkLength; // Length (hi-lo) -} ATTRPACK MIDICHUNK; - -// Contents of MThd chunk. -typedef struct -{ - WORD wFormat; // Format (hi-lo) - WORD wTrackCount; // # tracks (hi-lo) - WORD wTimeDivision; // Time division (hi-lo) -} ATTRPACK MIDIFILEHDR; - -#if defined(_MSC_VER) -#pragma pack() // End of need for byte-aligned structures -#endif - - -// Temporary event structure which stores event data until we're ready to -// dump it into a stream buffer -// -typedef struct -{ - DWORD tkEvent; // Absolute time of event - BYTE byShortData[4]; // Event type and parameters if channel msg - DWORD dwEventLength; // Length of data which follows if meta or sysex - LPBYTE pLongData; // -> Event data if applicable -} TEMPEVENT, *PTEMPEVENT; - -#define ITS_F_ENDOFTRK 0x00000001 - -// Description of a track open for read -// -typedef struct -{ - DWORD fdwTrack; // Track status - DWORD dwTrackLength; // Total bytes in track - DWORD dwLeftInBuffer; // Bytes left unread in track buffer - LPBYTE pTrackStart; // -> start of track data buffer - LPBYTE pTrackCurrent; // -> next byte to read in buffer - DWORD tkNextEventDue; // Absolute time of next event in track - BYTE byRunningStatus;// Running status from last channel msg - - FILEOFF foTrackStart; // Start of track -- used for walking the file - FILEOFF foNextReadStart;// File offset of next read from disk - DWORD dwLeftOnDisk; // Bytes left unread on disk -#ifdef DEBUG - DWORD nTrack; // # of this track for debugging -#endif -} INTRACKSTATE, *PINTRACKSTATE; - -// Description of the input MIDI file -// -typedef struct -{ - DWORD cbFileLength; // Total bytes in file - DWORD dwTimeDivision; // Original time division - DWORD dwFormat; // Original format - DWORD dwTrackCount; // Track count (specifies pitsTracks size) - INTRACKSTATE *pitsTracks; // -> array of tracks in this file -} INFILESTATE, *PINFILESTATE; - -#endif //__MIDSTUFF_H__ diff --git a/src/win32ce/resource.h b/src/win32ce/resource.h deleted file mode 100644 index a712f14d6117427ec865278e0f634b44063d80b4..0000000000000000000000000000000000000000 --- a/src/win32ce/resource.h +++ /dev/null @@ -1,18 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Srb2win.rc -// -#define IDI_DLICON1 101 -#define IDC_DLCURSOR1 103 -#define IDI_ICON1 106 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 114 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/src/win32ce/win_cd.c b/src/win32ce/win_cd.c deleted file mode 100644 index 940f59ff2205575ddd38e791baa1ab1e09b2c012..0000000000000000000000000000000000000000 --- a/src/win32ce/win_cd.c +++ /dev/null @@ -1,529 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief cd music interface (uses MCI). - -#include "../doomdef.h" -#include "win_main.h" -#include <mmsystem.h> - -#include "../command.h" -#include "../doomtype.h" -#include "../i_sound.h" -#include "../i_system.h" - -#include "../s_sound.h" - -#define MAX_CD_TRACKS 255 - -typedef struct { - BOOL IsAudio; - DWORD Start, End; - DWORD Length; // minutes -} CDTrack; - -// ------- -// private -// ------- -static CDTrack m_nTracks[MAX_CD_TRACKS]; -static int m_nTracksCount; // up to MAX_CD_TRACKS -static MCI_STATUS_PARMS m_MCIStatus; -static MCI_OPEN_PARMS m_MCIOpen; - -// ------ -// protos -// ------ -static void Command_Cd_f (void); - - -// ------------------- -// MCIErrorMessageBox -// Retrieve error message corresponding to return value from -// mciSendCommand() or mciSenString() -// ------------------- -static VOID MCIErrorMessageBox (MCIERROR iErrorCode) -{ - char szErrorText[128]; - if (!mciGetErrorStringA (iErrorCode, szErrorText, sizeof (szErrorText))) - wsprintfA(szErrorText,"MCI CD Audio Unknow Error #%d\n", iErrorCode); - CONS_Printf (szErrorText); - /*MessageBox (GetActiveWindow(), szTemp+1, "LEGACY", - MB_OK | MB_ICONSTOP);*/ -} - - -// -------- -// CD_Reset -// -------- -static void CD_Reset (void) -{ - // no win32 equivalent - //faB: for DOS, some odd drivers like to be reset sometimes.. useless in MCI I guess -} - - -// ---------------- -// CD_ReadTrackInfo -// Read in number of tracks, and length of each track in minutes/seconds -// returns true if error -// ---------------- -static BOOL CD_ReadTrackInfo (void) -{ - int i; - int nTrackLength; - MCIERROR iErr; - - m_nTracksCount = 0; - - m_MCIStatus.dwItem = MCI_STATUS_NUMBER_OF_TRACKS; - iErr = mciSendCommand(m_MCIOpen.wDeviceID, MCI_STATUS, MCI_STATUS_ITEM|MCI_WAIT, (DWORD_PTR)&m_MCIStatus); - if (iErr) - { - MCIErrorMessageBox (iErr); - return FALSE; - } - m_nTracksCount = (int)m_MCIStatus.dwReturn; - if (m_nTracksCount > MAX_CD_TRACKS) - m_nTracksCount = MAX_CD_TRACKS; - - for (i = 0; i < m_nTracksCount; i++) - { - m_MCIStatus.dwTrack = (DWORD)(i+1); - m_MCIStatus.dwItem = MCI_STATUS_LENGTH; - iErr = mciSendCommand(m_MCIOpen.wDeviceID, MCI_STATUS, MCI_TRACK|MCI_STATUS_ITEM|MCI_WAIT, (DWORD_PTR)&m_MCIStatus); - if (iErr) - { - MCIErrorMessageBox (iErr); - return FALSE; - } - nTrackLength = (DWORD)(MCI_MSF_MINUTE(m_MCIStatus.dwReturn)*60 + MCI_MSF_SECOND(m_MCIStatus.dwReturn)); - m_nTracks[i].Length = nTrackLength; - - m_MCIStatus.dwItem = MCI_CDA_STATUS_TYPE_TRACK; - iErr = mciSendCommand(m_MCIOpen.wDeviceID, MCI_STATUS, MCI_TRACK|MCI_STATUS_ITEM|MCI_WAIT, (DWORD_PTR)&m_MCIStatus); - if (iErr) - { - MCIErrorMessageBox (iErr); - return FALSE; - } - m_nTracks[i].IsAudio = (m_MCIStatus.dwReturn == MCI_CDA_TRACK_AUDIO); - } - - return TRUE; -} - - -// ------------ -// CD_TotalTime -// returns total time for all audio tracks in seconds -// ------------ -static int CD_TotalTime (void) -{ - int nTotalLength = 0; - int nTrack; - for (nTrack = 0; nTrack < m_nTracksCount; nTrack++) - { - if (m_nTracks[nTrack].IsAudio) - nTotalLength = nTotalLength + m_nTracks[nTrack].Length; - } - return nTotalLength; -} - - -//====================================================================== -// CD AUDIO MUSIC SUBSYSTEM -//====================================================================== - -UINT8 cdaudio_started = 0; // for system startup/shutdown - -static boolean cdPlaying = false; -static int cdPlayTrack; // when cdPlaying is true -static boolean cdLooping = false; -static UINT8 cdRemap[MAX_CD_TRACKS]; -static boolean cdEnabled = true; // cd info available -static boolean cdValid; // true when last cd audio info was ok -static boolean wasPlaying; -//static int cdVolume = 0; // current cd volume (0-31) - -// 0-31 like Music & Sfx, though CD hardware volume is 0-255. -consvar_t cd_volume = {"cd_volume","18",CV_SAVE,soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; - -// allow Update for next/loop track -// some crap cd drivers take up to -// a second for a simple 'busy' check.. -// (on those Update can be disabled) -consvar_t cdUpdate = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; - -// hour,minutes,seconds -static char *hms(int seconds) -{ - int hours, minutes; - static char s[9]; - - minutes = seconds / 60; - seconds %= 60; - hours = minutes / 60; - minutes %= 60; - if (hours > 0) - sprintf (s, "%d:%02d:%02d", hours, minutes, seconds); - else - sprintf (s, "%2d:%02d", minutes, seconds); - return s; -} - -static void Command_Cd_f (void) -{ - LPCSTR s; - int i,j; - - if (!cdaudio_started) - return; - - if (COM_Argc()<2) - { - CONS_Printf ("cd [on] [off] [remap] [reset] [open]\n" - " [info] [play <track>] [loop <track>]\n" - " [stop] [resume]\n"); - return; - } - - s = COM_Argv(1); - - // activate cd music - if (!strncmp(s,"on",2)) - { - cdEnabled = true; - return; - } - - // stop/deactivate cd music - if (!strncmp(s,"off",3)) - { - if (cdPlaying) - I_StopCD (); - cdEnabled = false; - return; - } - - // remap tracks - if (!strncmp(s,"remap",5)) - { - i = (int)COM_Argc() - 2; - if (i <= 0) - { - CONS_Printf ("CD tracks remapped in that order :\n"); - for (j = 1; j < MAX_CD_TRACKS; j++) - if (cdRemap[j] != j) - CONS_Printf (" %2d -> %2d\n", j, cdRemap[j]); - return; - } - for (j = 1; j <= i; j++) - cdRemap[j] = (UINT8)atoi (COM_Argv (j+1)); - return; - } - - // reset the CD driver, useful on some odd cd's - if (!strncmp(s,"reset",5)) - { - cdEnabled = true; - if (cdPlaying) - I_StopCD (); - for (i = 0; i < MAX_CD_TRACKS; i++) - cdRemap[i] = (UINT8)i; - CD_Reset(); - cdValid = CD_ReadTrackInfo(); - return; - } - - // any other command is not allowed until we could retrieve cd information - if (!cdValid) - { - CONS_Printf ("CD is not ready.\n"); - return; - } - - /* faB: not with MCI, didn't find it, useless anyway - if (!strncmp(s,"open",4)) - { - if (cdPlaying) - I_StopCD (); - bcd_open_door(); - cdValid = false; - return; - }*/ - - if (!strncmp(s,"info",4)) - { - if (!CD_ReadTrackInfo()) - { - cdValid = false; - return; - } - - cdValid = true; - - if (m_nTracksCount <= 0) - CONS_Printf ("No audio tracks\n"); - else - { - // display list of tracks - // highlight current playing track - for (i = 0; i < m_nTracksCount; i++) - { - CONS_Printf("%s%2d. %s %s\n", - cdPlaying && (cdPlayTrack == i) ? "\2 " : " ", - i+1, m_nTracks[i].IsAudio ? "audio" : "data ", - hms(m_nTracks[i].Length)); - } - CONS_Printf ("\2Total time : %s\n", hms(CD_TotalTime())); - } - if (cdPlaying) - { - CONS_Printf ("%s track : %d\n", cdLooping ? "looping" : "playing", - cdPlayTrack); - } - return; - } - - if (!strncmp(s,"play",4)) - { - I_PlayCD ((UINT8)atoi(COM_Argv (2)), false); - return; - } - - if (!strncmp(s,"stop",4)) - { - I_StopCD (); - return; - } - - if (!strncmp(s,"loop",4)) - { - I_PlayCD ((UINT8)atoi(COM_Argv (2)), true); - return; - } - - if (!strncmp(s,"resume",4)) - { - I_ResumeCD (); - return; - } - - CONS_Printf ("cd command '%s' unknown\n", s); -} - - -// ------------ -// I_ShutdownCD -// Shutdown CD Audio subsystem, release whatever was allocated -// ------------ -void I_ShutdownCD (void) -{ - MCIERROR iErr; - - if (!cdaudio_started) - return; - - CONS_Printf("I_ShutdownCD()\n"); - - I_StopCD(); - - // closes MCI CD - iErr = mciSendCommand(m_MCIOpen.wDeviceID, MCI_CLOSE, 0, 0); - if (iErr) - MCIErrorMessageBox (iErr); -} - - -// -------- -// I_InitCD -// Init CD Audio subsystem -// -------- -void I_InitCD (void) -{ - MCI_SET_PARMS mciSet; - MCIERROR iErr; - int i; - - // We don't have an open device yet - m_MCIOpen.wDeviceID = 0; - m_nTracksCount = 0; - - cdaudio_started = false; - - m_MCIOpen.lpstrDeviceType = (LPCTSTR)MCI_DEVTYPE_CD_AUDIO; - iErr = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID, (DWORD_PTR)&m_MCIOpen); - if (iErr) - { - MCIErrorMessageBox (iErr); - return; - } - - // Set the time format to track/minute/second/frame (TMSF). - mciSet.dwTimeFormat = MCI_FORMAT_TMSF; - iErr = mciSendCommand(m_MCIOpen.wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)&mciSet); - if (iErr) - { - MCIErrorMessageBox (iErr); - mciSendCommand(m_MCIOpen.wDeviceID, MCI_CLOSE, 0, 0); - return; - } - - I_AddExitFunc (I_ShutdownCD); - cdaudio_started = true; - - CONS_Printf("I_InitCD: Init CD audio\n"); - - // last saved in config.cfg - i = cd_volume.value; - //I_SetVolumeCD (0); // initialize to 0 for some odd cd drivers - I_SetVolumeCD (i); // now set the last saved volume - - for (i = 0; i < MAX_CD_TRACKS; i++) - cdRemap[i] = (UINT8)i; - - if (!CD_ReadTrackInfo()) - { - CONS_Printf("\2I_InitCD: no CD in player.\n"); - cdEnabled = false; - cdValid = false; - } - else - { - cdEnabled = true; - cdValid = true; - } - - COM_AddCommand ("cd", Command_Cd_f); -} - - - -// loop/go to next track when track is finished (if cd_update var is true) -// update the volume when it has changed (from console/menu) -void I_UpdateCD (void) -{ - /// \todo check for cd change and restart music ? -} - - -// -void I_PlayCD (UINT8 nTrack, UINT8 bLooping) -{ - MCI_PLAY_PARMS mciPlay; - MCIERROR iErr; - - if (!cdaudio_started || !cdEnabled) - return; - - //faB: try again if it didn't work (just free the user of typing 'cd reset' command) - if (!cdValid) - cdValid = CD_ReadTrackInfo(); - if (!cdValid) - return; - - // tracks start at 0 in the code.. - nTrack--; - if (nTrack < 0 || nTrack >= m_nTracksCount) - nTrack = nTrack % m_nTracksCount; - - nTrack = cdRemap[nTrack]; - - if (cdPlaying) - { - if (cdPlayTrack == nTrack) - return; - I_StopCD (); - } - - cdPlayTrack = nTrack; - - if (!m_nTracks[nTrack].IsAudio) - { - //CONS_Printf ("\2CD Play: not an audio track\n"); // Tails 03-25-2001 - return; - } - - cdLooping = bLooping; - - //faB: stop MIDI music, MIDI music will restart if volume is upped later - cv_digmusicvolume.value = 0; - cv_midimusicvolume.value = 0; - I_StopSong (0); - - //faB: I don't use the notify message, I'm trying to minimize the delay - mciPlay.dwCallback = (DWORD_PTR)((size_t)hWndMain); - mciPlay.dwFrom = MCI_MAKE_TMSF(nTrack+1, 0, 0, 0); - iErr = mciSendCommand(m_MCIOpen.wDeviceID, MCI_PLAY, MCI_FROM|MCI_NOTIFY, (DWORD_PTR)&mciPlay); - if (iErr) - { - MCIErrorMessageBox (iErr); - cdValid = false; - cdPlaying = false; - return; - } - - cdPlaying = true; -} - - -// pause cd music -void I_StopCD (void) -{ - MCIERROR iErr; - - if (!cdaudio_started || !cdEnabled) - return; - - iErr = mciSendCommand(m_MCIOpen.wDeviceID, MCI_PAUSE, MCI_WAIT, 0); - if (iErr) - MCIErrorMessageBox (iErr); - else - { - wasPlaying = cdPlaying; - cdPlaying = false; - } -} - - -// continue after a pause -void I_ResumeCD (void) -{ - MCIERROR iErr; - - if (!cdaudio_started || !cdEnabled) - return; - - if (!cdValid) - return; - - if (!wasPlaying) - return; - - iErr = mciSendCommand(m_MCIOpen.wDeviceID, MCI_RESUME, MCI_WAIT, 0); - if (iErr) - MCIErrorMessageBox (iErr); - else - cdPlaying = true; -} - - -// volume : logical cd audio volume 0-31 (hardware is 0-255) -int I_SetVolumeCD (int volume) -{ - (void)volume; - return 1; -} diff --git a/src/win32ce/win_dbg.c b/src/win32ce/win_dbg.c deleted file mode 100644 index 9cfe77636a9fa19aa8be572029b1d8adb4dff404..0000000000000000000000000000000000000000 --- a/src/win32ce/win_dbg.c +++ /dev/null @@ -1,629 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief Sources from GameDeveloper magazine article, January 1998, by Bruce Dawson. -/// this source file contains the exception handler for recording error -/// information after crashes. - -#include <tchar.h> -#include "win_main.h" -#include "../doomdef.h" //just for VERSION -#include "win_dbg.h" -#include "../m_argv.h" //print the parameter in the log - - -#define NumCodeBytes 16 // Number of code bytes to record. -#define MaxStackDump 2048 // Maximum number of DWORDS in stack dumps. -#define StackColumns 8 // Number of columns in stack dump. - -#define ONEK 1024 -#define SIXTYFOURK (64*ONEK) -#define ONEM (ONEK*ONEK) -#define ONEG (ONEK*ONEK*ONEK) - - -// -------------------------------------------------------------------------- -// return a description for an ExceptionCode -// -------------------------------------------------------------------------- -static LPCSTR GetExceptionDescription (DWORD ExceptionCode) -{ - unsigned int i; - - struct ExceptionNames - { - DWORD ExceptionCode; - LPCSTR ExceptionName; - }; - - struct ExceptionNames ExceptionMap[] = - { - {EXCEPTION_ACCESS_VIOLATION, "an Access Violation"}, - {EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "a Array Bounds Exceeded"}, - {EXCEPTION_BREAKPOINT, "a Breakpoint"}, - {EXCEPTION_DATATYPE_MISALIGNMENT, "a Datatype Misalignment"}, - {EXCEPTION_FLT_DENORMAL_OPERAND, "a Float Denormal Operand"}, - {EXCEPTION_FLT_DIVIDE_BY_ZERO, "a Float Divide By Zero"}, - {EXCEPTION_FLT_INEXACT_RESULT, "a Float Inexact Result"}, - {EXCEPTION_FLT_INVALID_OPERATION, "a Float Invalid Operation"}, - {EXCEPTION_FLT_OVERFLOW, "a Float Overflow"}, - {EXCEPTION_FLT_STACK_CHECK, "a Float Stack Check"}, - {EXCEPTION_FLT_UNDERFLOW, "a Float Underflow"}, - {EXCEPTION_ILLEGAL_INSTRUCTION, "an Illegal Instruction"}, - {EXCEPTION_IN_PAGE_ERROR, "an In Page Error"}, - {EXCEPTION_INT_DIVIDE_BY_ZERO, "an Integer Divide By Zero"}, - {EXCEPTION_INT_OVERFLOW, "an Integer Overflow"}, - {EXCEPTION_INVALID_DISPOSITION, "an Invalid Disposition"}, - {EXCEPTION_NONCONTINUABLE_EXCEPTION, "Noncontinuable Exception"}, - {EXCEPTION_PRIV_INSTRUCTION, "a Privileged Instruction"}, - {EXCEPTION_SINGLE_STEP, "a Single Step"}, - {EXCEPTION_STACK_OVERFLOW, "a Stack Overflow"}, - {0x40010005, "a Control-C"}, - {0x40010008, "a Control-Break"}, - {0xc0000006, "an In Page Error"}, - {0xc0000017, "a No Memory"}, - {0xc000001d, "an Illegal Instruction"}, - {0xc0000025, "a Noncontinuable Exception"}, - {0xc0000142, "a DLL Initialization Failed"}, - {0xe06d7363, "a Microsoft C++ Exception"}, - }; - - for (i = 0; i < (sizeof (ExceptionMap) / sizeof (ExceptionMap[0])); i++) - if (ExceptionCode == ExceptionMap[i].ExceptionCode) - return ExceptionMap[i].ExceptionName; - - return "Unknown exception type"; -} - - -// -------------------------------------------------------------------------- -// Directly output a formatted string to the errorlog file, using win32 funcs -// -------------------------------------------------------------------------- -static VOID FPrintf (HANDLE fileHandle, LPCSTR lpFmt, ...) -{ - CHAR str[1999]; - va_list arglist; - DWORD bytesWritten; - - va_start (arglist, lpFmt); - vsprintf (str, lpFmt, arglist); - va_end (arglist); - - WriteFile (fileHandle, str, (DWORD)strlen(str), &bytesWritten, NULL); -} - -// -------------------------------------------------------------------------- -// Print the specified FILETIME to output in a human readable format, -// without using the C run time. -// -------------------------------------------------------------------------- -static VOID PrintTime (LPSTR output, FILETIME TimeToPrint) -{ - WORD Date, Time; - if (FileTimeToLocalFileTime (&TimeToPrint, &TimeToPrint) && - FileTimeToDosDateTime (&TimeToPrint, &Date, &Time)) - { - // What a silly way to print out the file date/time. - wsprintfA(output, "%d/%d/%d %02d:%02d:%02d", - (Date / 32) & 15, Date & 31, (Date / 512) + 1980, - (Time / 2048), (Time / 32) & 63, (Time & 31) * 2); - } - else - output[0] = 0; -} - - -static LPTSTR GetFilePart(LPTSTR source) -{ - LPTSTR result = _tcsrchr(source, '\\'); - if (result) - result++; - else - result = source; - return result; -} - -// -------------------------------------------------------------------------- -// Print information about a code module (DLL or EXE) such as its size, -// location, time stamp, etc. -// -------------------------------------------------------------------------- -static VOID ShowModuleInfo(HANDLE LogFile, HMODULE ModuleHandle) -{ - CHAR ModName[MAX_PATH]; - IMAGE_DOS_HEADER *DosHeader; - IMAGE_NT_HEADERS *NTHeader; - HANDLE ModuleFile; - CHAR TimeBuffer[100] = ""; - DWORD FileSize = 0; -#ifdef NO_SEH_MINGW - __try1(EXCEPTION_EXECUTE_HANDLER) -#else - __try -#endif - { - if (GetModuleFileNameA(ModuleHandle, ModName, sizeof (ModName)) > 0) - { - // If GetModuleFileName returns greater than zero then this must - // be a valid code module address. Therefore we can try to walk - // our way through its structures to find the link time stamp. - DosHeader = (IMAGE_DOS_HEADER*)ModuleHandle; - if (IMAGE_DOS_SIGNATURE != DosHeader->e_magic) - return; - NTHeader = (IMAGE_NT_HEADERS*)((char *)DosHeader - + DosHeader->e_lfanew); - if (IMAGE_NT_SIGNATURE != NTHeader->Signature) - return; - // Open the code module file so that we can get its file date - // and size. - ModuleFile = CreateFileA(ModName, GENERIC_READ, - FILE_SHARE_READ, 0, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, 0); - if (ModuleFile != INVALID_HANDLE_VALUE) - { - FILETIME LastWriteTime; - FileSize = GetFileSize(ModuleFile, 0); - if (GetFileTime(ModuleFile, 0, 0, &LastWriteTime)) - { - wsprintfA(TimeBuffer, " - file date is "); - PrintTime(TimeBuffer + strlen(TimeBuffer), LastWriteTime); - } - CloseHandle(ModuleFile); - } - FPrintf (LogFile, "%s, loaded at 0x%08x - %d bytes - %08x%s\r\n", - ModName, ModuleHandle, FileSize, - NTHeader->FileHeader.TimeDateStamp, TimeBuffer); - } - } - // Handle any exceptions by continuing from this point. -#ifdef NO_SEH_MINGW - __except1 -#else - __except(EXCEPTION_EXECUTE_HANDLER) -#endif - { - } -} - -// -------------------------------------------------------------------------- -// Scan memory looking for code modules (DLLs or EXEs). VirtualQuery is used -// to find all the blocks of address space that were reserved or committed, -// and ShowModuleInfo will display module information if they are code -// modules. -// -------------------------------------------------------------------------- -static VOID RecordModuleList(HANDLE LogFile) -{ - SYSTEM_INFO SystemInfo; - size_t PageSize; - size_t NumPages; - size_t pageNum = 0; - LPVOID LastAllocationBase = 0; - - FPrintf (LogFile, "\r\n" - "\tModule list: names, addresses, sizes, time stamps " - "and file times:\r\n"); - - // Set NumPages to the number of pages in the 4GByte address space, - // while being careful to avoid overflowing ints. - GetSystemInfo(&SystemInfo); - PageSize = SystemInfo.dwPageSize; - NumPages = 4 * (unsigned int)(ONEG / PageSize); - while (pageNum < NumPages) - { - MEMORY_BASIC_INFORMATION MemInfo; - if (VirtualQuery((LPVOID)(pageNum * PageSize), &MemInfo, - sizeof (MemInfo))) - { - if (MemInfo.RegionSize > 0) - { - // Adjust the page number to skip over this block of memory. - pageNum += MemInfo.RegionSize / PageSize; - if (MemInfo.State == MEM_COMMIT && MemInfo.AllocationBase > - LastAllocationBase) - { - // Look for new blocks of committed memory, and try - // recording their module names - this will fail - // gracefully if they aren't code modules. - LastAllocationBase = MemInfo.AllocationBase; - ShowModuleInfo(LogFile, (HMODULE)LastAllocationBase); - } - } - else - pageNum += SIXTYFOURK / PageSize; - } - else - pageNum += SIXTYFOURK / PageSize; - // If VirtualQuery fails we advance by 64K because that is the - // granularity of address space doled out by VirtualAlloc(). - } -} - - -// -------------------------------------------------------------------------- -// Record information about the user's system, such as processor type, amount -// of memory, etc. -// -------------------------------------------------------------------------- -static VOID RecordSystemInformation(HANDLE fileHandle) -{ - FILETIME CurrentTime; - CHAR TimeBuffer[100]; - CHAR ModuleName[MAX_PATH]; - CHAR UserName[200]; - DWORD UserNameSize; - SYSTEM_INFO SystemInfo; - MEMORYSTATUS MemInfo; - - GetSystemTimeAsFileTime (&CurrentTime); - PrintTime (TimeBuffer, CurrentTime); - FPrintf(fileHandle, "Error occurred at %s.\r\n", TimeBuffer); - - if (GetModuleFileNameA(NULL, ModuleName, sizeof (ModuleName)) <= 0) - strcpy (ModuleName, "Unknown"); - UserNameSize = sizeof (UserName); - if (!GetUserNameA(UserName, &UserNameSize)) - strcpy (UserName, "Unknown"); - FPrintf(fileHandle, "%s, run by %s.\r\n", ModuleName, UserName); - - GetSystemInfo (&SystemInfo); - FPrintf (fileHandle, "%d processor(s), type %d %d.%d.\r\n" - "Program Memory from 0x%p to 0x%p\r\n", - SystemInfo.dwNumberOfProcessors, - SystemInfo.dwProcessorType, - SystemInfo.wProcessorLevel, - SystemInfo.wProcessorRevision, - SystemInfo.lpMinimumApplicationAddress, - SystemInfo.lpMaximumApplicationAddress); - - MemInfo.dwLength = sizeof (MemInfo); - GlobalMemoryStatus(&MemInfo); - // Print out the amount of physical memory, rounded up. - FPrintf(fileHandle, "%d MBytes physical memory.\r\n", (MemInfo.dwTotalPhys + - ONEM - 1) / ONEM); -} - -// -------------------------------------------------------------------------- -// What we do here is trivial : open a file, write out the register information -// from the PEXCEPTION_POINTERS structure, then return EXCEPTION_CONTINUE_SEARCH -// whose magic value tells Win32 to proceed with its normal error handling -// mechanism. This is important : an error dialog will popup if possible and -// the debugger will hopefully coexist peacefully with the structured exception -// handler. -// -------------------------------------------------------------------------- -int __cdecl RecordExceptionInfo (PEXCEPTION_POINTERS data/*, LPCSTR Message, LPSTR lpCmdLine*/) -{ - PEXCEPTION_RECORD Exception; - PCONTEXT Context; - TCHAR ModuleName[MAX_PATH]; - TCHAR FileName[MAX_PATH] = TEXT("Unknown"); - LPTSTR FilePart, lastperiod; - TCHAR CrashModulePathName[MAX_PATH]; - LPCTSTR CrashModuleFileName = TEXT("Unknown"); - MEMORY_BASIC_INFORMATION MemInfo; - static int BeenHere = false; - HANDLE fileHandle; - UINT8 *code; - int codebyte,i; - - if (data) - { - Exception = data->ExceptionRecord; - Context = data->ContextRecord; - } - else - { - return EXCEPTION_CONTINUE_SEARCH; - } - - if (BeenHere) // Going recursive! That must mean this routine crashed! - return EXCEPTION_CONTINUE_SEARCH; - BeenHere = true; - - // Create a filename to record the error information to. - // Store it in the executable directory. - if (GetModuleFileName(NULL, ModuleName, sizeof (ModuleName)) <= 0) - ModuleName[0] = 0; - FilePart = GetFilePart(ModuleName); - - // Extract the file name portion and remove it's file extension. We'll - // use that name shortly. - lstrcpy (FileName, FilePart); - lastperiod = _tcsrchr (FileName, '.'); - if (lastperiod) - lastperiod[0] = 0; - // Replace the executable filename with our error log file name. - lstrcpy (FilePart, TEXT("errorlog.txt")); - fileHandle = CreateFile (ModuleName, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL); - if (fileHandle == INVALID_HANDLE_VALUE) - { - OutputDebugString (TEXT("Error creating exception report")); - return EXCEPTION_CONTINUE_SEARCH; - } - - // Append to the error log. - SetFilePointer (fileHandle, 0, 0, FILE_END); - - // Print out some blank lines to separate this error log from any previous ones. - FPrintf (fileHandle, "Email Sonic Team Junior so we can fix the bugs\r\n"); // Tails - FPrintf (fileHandle, "Make sure you tell us what you were doing to cause the crash, and if possible, record a demo!\r\n"); // Tails - FPrintf (fileHandle, "\r\n\r\n\r\n\r\n"); - FPrintf (fileHandle, "SRB2 %s -ERROR LOG-\r\n\r\n", VERSIONSTRING); - FPrintf (fileHandle, "\r\n"); - // VirtualQuery can be used to get the allocation base associated with a - // code address, which is the same as the ModuleHandle. This can be used - // to get the filename of the module that the crash happened in. - if (VirtualQuery ((LPVOID)(size_t)Context->Eip, &MemInfo, sizeof (MemInfo)) && - GetModuleFileName ((HMODULE)MemInfo.AllocationBase, - CrashModulePathName, - sizeof (CrashModulePathName)) > 0) - CrashModuleFileName = GetFilePart(CrashModulePathName); - - // Print out the beginning of the error log in a Win95 error window - // compatible format. - FPrintf (fileHandle, "%s caused an %s in module %s at %04x:%08x.\r\n", - FileName, GetExceptionDescription(Exception->ExceptionCode), - CrashModuleFileName, Context->SegCs, Context->Eip); - //if (&Message = Null) - FPrintf (fileHandle, "Exception handler called in %s.\r\n", "main thread"); - //else - //FPrintf (fileHandle, "Exception handler called in %s.\r\n", Message); - - RecordSystemInformation (fileHandle); - - // If the exception was an access violation, print out some additional - // information, to the error log and the debugger. - if (Exception->ExceptionCode == STATUS_ACCESS_VIOLATION && - Exception->NumberParameters >= 2) - { - TCHAR DebugMessage[1000]; - LPCTSTR readwrite = TEXT("Read from"); - if (Exception->ExceptionInformation[0]) - readwrite = TEXT("Write to"); - wsprintf(DebugMessage, TEXT("%s location %08x caused an access violation.\r\n"), - readwrite, Exception->ExceptionInformation[1]); -#ifdef _DEBUG - // The VisualC++ debugger doesn't actually tell you whether a read - // or a write caused the access violation, nor does it tell what - // address was being read or written. So I fixed that. - OutputDebugString(TEXT("Exception handler: ")); - OutputDebugString(DebugMessage); -#endif - FPrintf(fileHandle, "%s", DebugMessage); - } - - FPrintf(fileHandle, "\r\n"); - - // Print out the register values in a Win95 error window compatible format. - if ((Context->ContextFlags & CONTEXT_FULL) == CONTEXT_FULL) - { - FPrintf (fileHandle, "Registers:\r\n"); - FPrintf (fileHandle, "EAX=%.8lx CS=%.4x EIP=%.8lx EFLGS=%.8lx\r\n", - Context->Eax,Context->SegCs,Context->Eip,Context->EFlags); - FPrintf (fileHandle, "EBX=%.8lx SS=%.4x ESP=%.8lx EBP=%.8lx\r\n", - Context->Ebx,Context->SegSs,Context->Esp,Context->Ebp); - FPrintf (fileHandle, "ECX=%.8lx DS=%.4x ESI=%.8lx FS=%.4x\r\n", - Context->Ecx,Context->SegDs,Context->Esi,Context->SegFs); - FPrintf (fileHandle, "EDX=%.8lx ES=%.4x EDI=%.8lx GS=%.4x\r\n", - Context->Edx,Context->SegEs,Context->Edi,Context->SegGs); - } - - // moved down because it was causing the printout to stop - FPrintf (fileHandle, "Command Line parameters: "); - for (i = 1;i < myargc;i++) - FPrintf (fileHandle, "%s ", myargv[i]); - - FPrintf (fileHandle, "Bytes at CS : EIP:\r\n"); - - // Print out the bytes of code at the instruction pointer. Since the - // crash may have been caused by an instruction pointer that was bad, - // this code needs to be wrapped in an exception handler, in case there - // is no memory to read. If the dereferencing of code[] fails, the - // exception handler will print '??'. - code = (UINT8 *)(size_t)Context->Eip; - for (codebyte = 0; codebyte < NumCodeBytes; codebyte++) - { -#ifdef NO_SEH_MINGW - __try1(EXCEPTION_EXECUTE_HANDLER) -#else - __try -#endif - { - FPrintf (fileHandle, "%02x ", code[codebyte]); - } -#ifdef NO_SEH_MINGW - __except1 -#else - __except(EXCEPTION_EXECUTE_HANDLER) -#endif - { - FPrintf (fileHandle, "?? "); - } - } - - // Time to print part or all of the stack to the error log. This allows - // us to figure out the call stack, parameters, local variables, etc. - FPrintf (fileHandle, "\r\n" - "Stack dump:\r\n"); -#ifdef NO_SEH_MINGW - __try1(EXCEPTION_EXECUTE_HANDLER) -#else - __try -#endif - { - // Esp contains the bottom of the stack, or at least the bottom of - // the currently used area. - DWORD* pStack = (DWORD *)(size_t)Context->Esp; - DWORD* pStackTop = NULL; - size_t Count = 0; - TCHAR buffer[1000] = TEXT(""); - const int safetyzone = 50; - LPTSTR nearend = buffer + sizeof (buffer) - safetyzone*sizeof (TCHAR); - LPTSTR output = buffer; - const void *Suffix; - - // Load the top (highest address) of the stack from the - // thread information block. It will be found there in - // Win9x and Windows NT. -#ifdef __GNUC__ - __asm__("movl %%fs : 4, %%eax": "=a"(pStackTop)); -#else - __asm - { - mov eax, fs:[4] - mov pStackTop, eax - } -#endif - if (pStackTop == NULL) - goto StackSkip; - else if (pStackTop > pStack + MaxStackDump) - pStackTop = pStack + MaxStackDump; - // Too many calls to WriteFile can take a long time, causing - // confusing delays when programs crash. Therefore I implemented - // simple buffering for the stack dumping code instead of calling - // FPrintf directly. - while (pStack + 1 <= pStackTop) - { - if ((Count % StackColumns) == 0) - output += wsprintf(output, TEXT("%08x: "), pStack); - if ((++Count % StackColumns) == 0 || pStack + 2 > pStackTop) - Suffix = TEXT("\r\n"); - else - Suffix = TEXT(" "); - output += wsprintf(output, TEXT("%08x%s"), *pStack, Suffix); - pStack++; - // Check for when the buffer is almost full, and flush it to disk. - if (output > nearend) - { - FPrintf (fileHandle, "%s", buffer); - buffer[0] = 0; - output = buffer; - } - } - // Print out any final characters from the cache. - StackSkip: - FPrintf (fileHandle, "%s", buffer); - } -#ifdef NO_SEH_MINGW - __except1 -#else - __except(EXCEPTION_EXECUTE_HANDLER) -#endif - { - FPrintf(fileHandle, "Exception encountered during stack dump.\r\n"); - } - - RecordModuleList (fileHandle); - - CloseHandle (fileHandle); - - // Return the magic value which tells Win32 that this handler didn't - // actually handle the exception - so that things will proceed as per - // normal. - //BP: should put message for end user to send this file to fix any bug - return EXCEPTION_CONTINUE_SEARCH; -} - - /* - // - //FPrintf ("e-mail this file to legacy@newdoom.com, so that we can fix the problem.\r\n\r\n"); - - FPrintf ("Exception handler called in %s.\r\n", Message); - - GetSystemTime (&systemTime); - FPrintf ("Error occured at %02d/%02d/%04d %02d:%02d:%02d.\r\n", - systemTime.wMonth, systemTime.wDay, systemTime.wYear, - systemTime.wHour, systemTime.wMinute, systemTime.wSecond); - - - FPrintf ("%s\r\n", filename); - FPrintf ("Cmd-line: %s\r\n", lpCmdLine); - - // Nested exceptions can occur, get info for each one - - nER = 1; - while (ER) - { - if (nER++>1) - FPrintf ("Exception Record %d.\r\n", nER); - - FPrintf ("application caused an %s", GetExceptionCodeStr(Exception->ExceptionCode)); - - if (Context->ContextFlags & CONTEXT_CONTROL) - FPrintf (" at %.4x:%.8x.\r\n", Context->SegCs, Context->Eip); - - // in case of.. - if (Context->Eip != (unsigned long)Exception->ExceptionAddress) - FPrintf ("Exception Address = %.8x\r\n", Exception->ExceptionAddress); - - if (Exception->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) - { - FPrintf ("\r\n%s location 0x%x caused an access violation.\r\n", - (Exception->ExceptionInformation[0] ? "Write to" : "Read from"), - Exception->ExceptionInformation[1]); - } - - ER = Exception->ExceptionRecord; - } - - - if (Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) - { - FPrintf ("\r\nDebug Registers:\r\n"); - FPrintf ("Dr0=%.8x Dr1=%.8x Dr2=%.8x\r\n" - "Dr3=%.8x Dr6=%.8x Dr7=%.8x\r\n", - Context->Dr0, Context->Dr1, Context->Dr2, - Context->Dr3, Context->Dr6, Context->Dr7); - } - - if (Context->ContextFlags & CONTEXT_FLOATING_POINT) - { - FPrintf ("\r\nFloating Save Area:\r\n"); - FPrintf ("ControlWord =%.8x TagWord =%.8x ErrorSelector=%.8x DataSelector =%.8x\r\n" - "StatusWord =%.8x ErrorOffset =%.8x DataOffset =%.8x Cr0NpxState =%.8x\r\n", - Context->FloatSave.ControlWord, Context->FloatSave.TagWord, Context->FloatSave.ErrorSelector, Context->FloatSave.DataSelector, - Context->FloatSave.StatusWord, Context->FloatSave.ErrorOffset, Context->FloatSave.DataOffset, Context->FloatSave.Cr0NpxState - ); - - //BYTE RegisterArea[SIZE_OF_80387_REGISTERS]; - } - - - // in case of... - if ((Context->ContextFlags & CONTEXT_FULL) != CONTEXT_FULL) - { - if (!(Context->ContextFlags & CONTEXT_SEGMENTS)) - FPrintf ("Note! GS,FS,ES,DS are unspecified\r\n"); - if (!(Context->ContextFlags & CONTEXT_INTEGER)) - FPrintf ("Note! EDI,ESI,EBX,EDX,ECX,EAX are unspecified\r\n"); - if (!(Context->ContextFlags & CONTEXT_CONTROL)) - FPrintf ("Note! EBP,CS : EIP,EFlags,SS : ESP are unspecified\r\n"); - } - - FPrintf ("\r\nBytes at CS : EIP:\r\n"); - ucptr = (UINT8 *)Context->Eip; - for (i = 0; i < 16; i++) - FPrintf ("%.2x ", *ucptr++); - - FPrintf ("\r\n\r\nStack dump:\r\n"); - ulptr = (unsigned long*)Context->Esp; - for (i = 0; i < 16; i++) - FPrintf ("%.8x ", *ulptr++); - - //FPrintf ("Bytes at CS : EIP:\r\n"); - //FPrintf ("%.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x "); - - for (i = 0; i < 16; i++) - { - FPrintf ("%x - } -*/ diff --git a/src/win32ce/win_dbg.h b/src/win32ce/win_dbg.h deleted file mode 100644 index acee896e61795636d0d9650c1360b02a78dd49d0..0000000000000000000000000000000000000000 --- a/src/win32ce/win_dbg.h +++ /dev/null @@ -1,54 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief exception handler - -//#define WIN32_LEAN_AND_MEAN -#define RPC_NO_WINDOWS_H -#include <windows.h> - -// called in the exception filter of the __try block, writes all useful debugging information -// to a file, using only win32 functions in case the C runtime is in a bad state. -int __cdecl RecordExceptionInfo (PEXCEPTION_POINTERS data/*, LPCSTR Message, LPSTR lpCmdLine*/); - -#ifdef __MINGW32__ - -#include <excpt.h> - -#ifndef TRYLEVEL_NONE - -#define NO_SEH_MINGW //Alam:? -FUNCINLINE static ATTRINLINE struct _EXCEPTION_POINTERS *GetExceptionInformation(VOID) -{ - LPVOID SEHINFO = NULL; - //__asm__("movl -20(%%ebp), %%eax": "=a"(SEHINFO)); - return SEHINFO; -} - -//Alam_GBC: use __try1(seh) -#ifndef __try -#define __try -#endif //__try - -//#undef NO_SEH_MINGW //Alam: win_dbg's code not working with MINGW -//Alam_GBC: use __except1 -#ifndef __except -#define __except(x) if (0) -#endif //__except - -#endif // !__TRYLEVEL_NONE - -#endif // __MINGW32__ diff --git a/src/win32ce/win_dll.c b/src/win32ce/win_dll.c deleted file mode 100644 index 8b88f84ddcec13c160b570bd2c5c56a96e0b651c..0000000000000000000000000000000000000000 --- a/src/win32ce/win_dll.c +++ /dev/null @@ -1,164 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief load and initialise the 3D driver DLL - -#include "../doomdef.h" -#ifdef HWRENDER -#include "../hardware/hw_drv.h" // get the standard 3D Driver DLL exports prototypes -#endif - -#ifdef HW3SOUND -#include "../hardware/hw3dsdrv.h" // get the 3D sound driver DLL export prototypes -#endif - -#include "win_dll.h" -#include "win_main.h" // I_GetLastErrorMsgBox() - -#if defined(HWRENDER) || defined(HW3SOUND) -typedef struct loadfunc_s { - LPCSTR fnName; - LPVOID fnPointer; -} loadfunc_t; - -// -------------------------------------------------------------------------- -// Load a DLL, returns the HMODULE handle or NULL -// -------------------------------------------------------------------------- -static inline HMODULE LoadDLL (LPCSTR dllName, loadfunc_t *funcTable) -{ - LPVOID funcPtr; - loadfunc_t *loadfunc; - HMODULE hModule; - - if ((hModule = LoadLibraryA(dllName)) != NULL) - { - // get function pointers for all functions we use - for (loadfunc = funcTable; loadfunc->fnName != NULL; loadfunc++) - { - funcPtr = GetProcAddress(hModule, loadfunc->fnName); - if (!funcPtr) { - //I_GetLastErrorMsgBox (); - MessageBoxA(NULL, va("The '%s' haven't the good specification (function %s missing)\n\n" - "You must use dll from the same zip of this exe\n", dllName, loadfunc->fnName), - "Error", MB_OK|MB_ICONINFORMATION); - return FALSE; - } - // store function address - *((LPVOID*)loadfunc->fnPointer) = funcPtr; - } - } - else - { - MessageBoxA(NULL, va("LoadLibrary() FAILED : couldn't load '%s'\r\n", dllName), "Warning", MB_OK|MB_ICONINFORMATION); - //I_GetLastErrorMsgBox (); - } - - return hModule; -} - - -// -------------------------------------------------------------------------- -// Unload the DLL -// -------------------------------------------------------------------------- -static inline VOID UnloadDLL (HMODULE* pModule) -{ - if (FreeLibrary(*pModule)) - *pModule = NULL; - else - I_GetLastErrorMsgBox (); -} -#endif - -// ========================================================================== -// STANDARD 3D DRIVER DLL FOR DOOM LEGACY -// ========================================================================== - -// note : the 3D driver loading should be put somewhere else.. - -#ifdef HWRENDER -static HMODULE hwdModule = NULL; - -static loadfunc_t hwdFuncTable[] = { - {"_Init@4", &hwdriver.pfnInit}, - {"_Shutdown@0", &hwdriver.pfnShutdown}, - {"_GetModeList@8", &hwdriver.pfnGetModeList}, - {"_SetPalette@8", &hwdriver.pfnSetPalette}, - {"_FinishUpdate@4", &hwdriver.pfnFinishUpdate}, - {"_Draw2DLine@12", &hwdriver.pfnDraw2DLine}, - {"_DrawPolygon@16", &hwdriver.pfnDrawPolygon}, - {"_SetBlend@4", &hwdriver.pfnSetBlend}, - {"_ClearBuffer@12", &hwdriver.pfnClearBuffer}, - {"_SetTexture@4", &hwdriver.pfnSetTexture}, - {"_ReadRect@24", &hwdriver.pfnReadRect}, - {"_GClipRect@20", &hwdriver.pfnGClipRect}, - {"_ClearMipMapCache@0",&hwdriver.pfnClearMipMapCache}, - {"_SetSpecialState@8", &hwdriver.pfnSetSpecialState}, - {"_DrawMD2@16", &hwdriver.pfnDrawMD2}, - {"_SetTransform@4", &hwdriver.pfnSetTransform}, - {"_GetTextureUsed@0", &hwdriver.pfnGetTextureUsed}, - {"_GetRenderVersion@0",&hwdriver.pfnGetRenderVersion}, - {NULL,NULL} -}; - -BOOL Init3DDriver (LPCSTR dllName) -{ - hwdModule = LoadDLL(dllName, hwdFuncTable); - return (hwdModule != NULL); -} - -VOID Shutdown3DDriver (VOID) -{ - UnloadDLL(&hwdModule); -} -#endif - -#ifdef HW3SOUND -static HMODULE hwsModule = NULL; - -static loadfunc_t hwsFuncTable[] = { - {"_Startup@8", &hw3ds_driver.pfnStartup}, - {"_Shutdown@0", &hw3ds_driver.pfnShutdown}, - {"_AddSfx@4", &hw3ds_driver.pfnAddSfx}, - {"_AddSource@8", &hw3ds_driver.pfnAddSource}, - {"_StartSource@4", &hw3ds_driver.pfnStartSource}, - {"_StopSource@4", &hw3ds_driver.pfnStopSource}, - {"_GetHW3DSVersion@0", &hw3ds_driver.pfnGetHW3DSVersion}, - {"_BeginFrameUpdate@0", &hw3ds_driver.pfnBeginFrameUpdate}, - {"_EndFrameUpdate@0", &hw3ds_driver.pfnEndFrameUpdate}, - {"_IsPlaying@4", &hw3ds_driver.pfnIsPlaying}, - {"_UpdateListener@8", &hw3ds_driver.pfnUpdateListener}, - {"_UpdateSourceParms@12", &hw3ds_driver.pfnUpdateSourceParms}, - {"_SetCone@8", &hw3ds_driver.pfnSetCone}, - {"_SetGlobalSfxVolume@4", &hw3ds_driver.pfnSetGlobalSfxVolume}, - {"_Update3DSource@8", &hw3ds_driver.pfnUpdate3DSource}, - {"_ReloadSource@8", &hw3ds_driver.pfnReloadSource}, - {"_KillSource@4", &hw3ds_driver.pfnKillSource}, - {"_KillSfx@4", &hw3ds_driver.pfnKillSfx}, - {"_GetHW3DSTitle@8", &hw3ds_driver.pfnGetHW3DSTitle}, - {NULL, NULL} -}; - -BOOL Init3DSDriver(LPCSTR dllName) -{ - hwsModule = LoadDLL(dllName, hwsFuncTable); - return (hwsModule != NULL); -} - -VOID Shutdown3DSDriver (VOID) -{ - UnloadDLL(&hwsModule); -} -#endif diff --git a/src/win32ce/win_dll.h b/src/win32ce/win_dll.h deleted file mode 100644 index b4b259587caacbf91dd97523c850bf7a96a1b57a..0000000000000000000000000000000000000000 --- a/src/win32ce/win_dll.h +++ /dev/null @@ -1,31 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief load/unload a DLL at run-time - -//#define WIN32_LEAN_AND_MEAN -#define RPC_NO_WINDOWS_H -#include <windows.h> - -#ifdef HWRENDER -BOOL Init3DDriver (LPCSTR dllName); -VOID Shutdown3DDriver (VOID); -#endif - -#ifdef HW3SOUND -BOOL Init3DSDriver(LPCSTR dllName); -VOID Shutdown3DSDriver(VOID); -#endif diff --git a/src/win32ce/win_file.c b/src/win32ce/win_file.c deleted file mode 100644 index f9f6210119febd5bbbba2976eaa8ca80e2f889c5..0000000000000000000000000000000000000000 --- a/src/win32ce/win_file.c +++ /dev/null @@ -1,123 +0,0 @@ -#include <stdlib.h> -#include <windows.h> -#include "win_file.h" - - -int FileAccess(LPCTSTR FileName, DWORD mode) -{ - HANDLE hFile; - - hFile = CreateFile( FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); - - if (hFile == INVALID_HANDLE_VALUE) - return -1; - else - { - FileClose(hFile); - return 0; - } -} - -HANDLE FileCreate(LPCTSTR FileName) -{ - HANDLE hFile; - - if (FileAccess( FileName, 0) == 0) - hFile = CreateFile( FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); - else - hFile = CreateFile( FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); - - return hFile; -} - -void FileClose(HANDLE hFile) -{ - CloseHandle(hFile); -} - -DWORD FileLength(HANDLE hFile) -{ - return GetFileSize(hFile, NULL); -} - -HANDLE FileOpen(LPCTSTR FileName) -{ - HANDLE hFile; - - hFile = CreateFile( FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); - - return hFile; -} - -HANDLE FileAppend(LPCTSTR FileName) -{ - HANDLE hFile; - - hFile = CreateFile( FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); - FileSeek(hFile, 0, FILE_END ); - - return hFile; -} - -DWORD FileRead(HANDLE hFile, LPVOID data, DWORD size) -{ - DWORD readin = 0; - - ReadFile(hFile, data, size, &readin, NULL); - - return readin; -} - -DWORD FileSeek(HANDLE hFile, LONG distance, DWORD method) -{ - DWORD position; - - position = SetFilePointer(hFile, distance, NULL, method); - - return position; -} - -DWORD FileWrite(HANDLE hFile, LPCVOID data, DWORD size) -{ - DWORD written = 0; - - WriteFile(hFile, data, size, &written, NULL); - - return written; -} - -//These functions are provided as CRT replacements. (missing from WinCE) - -int access(char* file,int type) -{ - FILE* file_access = 0; - - file_access = fopen(file,"rb"); - - if(file_access) - { - fclose(file_access); - return 0; - } - - return -1; -} - -unsigned int file_len(char* file) -{ - FILE* file_access; - unsigned int len = 0; - - file_access = fopen(file,"rb"); - - if(!file_access) - return 0; - - fseek(file_access,0,SEEK_END); - - len = ftell(file_access); - - fclose(file_access); - - return len; -} diff --git a/src/win32ce/win_file.h b/src/win32ce/win_file.h deleted file mode 100644 index d1dc5e9c75ebc4df260bdf3f268d201236fe9c8b..0000000000000000000000000000000000000000 --- a/src/win32ce/win_file.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef FILE_H -#define FILE_H - -// New File I/O functions - -int FileAccess(LPCTSTR, DWORD); -HANDLE FileAppend(LPCTSTR FileName); -void FileClose(HANDLE); -HANDLE FileCreate(LPCTSTR); -DWORD FileLength(HANDLE); -HANDLE FileOpen(LPCTSTR); -DWORD FileRead(HANDLE, LPCVOID, DWORD); -DWORD FileSeek(HANDLE hFile, LONG distance, DWORD method); -DWORD FileWrite(HANDLE, LPCVOID, DWORD); - -int access(char* file,int type); -unsigned int file_len(char* file); - -#endif \ No newline at end of file diff --git a/src/win32ce/win_main.c b/src/win32ce/win_main.c deleted file mode 100644 index a8a5c7cf20f2f1c92c094d6a4987254ac1798d16..0000000000000000000000000000000000000000 --- a/src/win32ce/win_main.c +++ /dev/null @@ -1,539 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief Win32 WinMain Entry Point -/// -/// Win32 Sonic Robo Blast 2 -/// -/// NOTE: -/// To compile WINDOWS SRB2 version : define a '_WINDOWS' symbol. -/// to do this go to Project/Settings/ menu, click C/C++ tab, in -/// 'Preprocessor definitions:' add '_WINDOWS' - -#include "../doomdef.h" -#include <stdio.h> - -#include "../doomstat.h" // netgame -#include "resource.h" - -#include "../m_argv.h" -#include "../d_main.h" -#include "../i_system.h" - -#include "../keys.h" //hack quick test - -#include "../console.h" - -#include "fabdxlib.h" -#include "win_main.h" -#include "win_dbg.h" -#include "../i_sound.h" // midi pause/unpause -#include "../g_input.h" // KEY_MOUSEWHEELxxx - -// MSWheel support for Win95/NT3.51 -#include <zmouse.h> - -#ifndef WM_XBUTTONDOWN -#define WM_XBUTTONDOWN 523 -#endif -#ifndef WM_XBUTTONUP -#define WM_XBUTTONUP 524 -#endif -#ifndef MK_XBUTTON1 -#define MK_XBUTTON1 32 -#endif -#ifndef MK_XBUTTON2 -#define MK_XBUTTON2 64 -#endif - -typedef BOOL (WINAPI *MyFunc)(VOID); - -HINSTANCE myInstance = NULL; -HWND hWndMain = NULL; -static HCURSOR windowCursor = NULL; // main window cursor - -boolean appActive = false; // app window is active - -#ifdef LOGMESSAGES -// this is were I log debug text, cons_printf, I_error ect for window port debugging -HANDLE logstream; -#endif - -BOOL nodinput = FALSE; - -static LRESULT CALLBACK MainWndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - event_t ev; //Doom input event - int mouse_keys; - - // judgecutor: - // Response MSH Mouse Wheel event - - if (message == MSHWheelMessage) - { - message = WM_MOUSEWHEEL; - if (win9x) - wParam <<= 16; - } - - - switch (message) - { - case WM_CREATE: - nodinput = M_CheckParm("-nodinput"); - break; - - case WM_ACTIVATEAPP: // Handle task switching - appActive = (int)wParam; - // pause music when alt-tab - if (appActive && !paused) - I_ResumeSong(0); - else if (!paused) - I_PauseSong(0); - { - HANDLE ci = GetStdHandle(STD_INPUT_HANDLE); - if (ci != INVALID_HANDLE_VALUE && GetFileType(ci) == FILE_TYPE_CHAR) - appActive = true; - } - InvalidateRect (hWnd, NULL, TRUE); - break; - - //for MIDI music - case WM_MSTREAM_UPDATEVOLUME: - I_SetMidiChannelVolume((DWORD)wParam, dwVolumePercent); - break; - - case WM_PAINT: - if (!appActive && !bAppFullScreen && !netgame) - // app becomes inactive (if windowed) - { - // Paint "Game Paused" in the middle of the screen - PAINTSTRUCT ps; - RECT rect; - HDC hdc = BeginPaint (hWnd, &ps); - GetClientRect (hWnd, &rect); - DrawText (hdc, TEXT("Game Paused"), -1, &rect, - DT_SINGLELINE | DT_CENTER | DT_VCENTER); - EndPaint (hWnd, &ps); - return 0; - } - break; - - //case WM_RBUTTONDOWN: - //case WM_LBUTTONDOWN: - - case WM_MOVE: - if (bAppFullScreen) - { - SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE); - return 0; - } - else - { - windowPosX = (SHORT) LOWORD(lParam); // horizontal position - windowPosY = (SHORT) HIWORD(lParam); // vertical position - break; - } - break; - - // This is where switching windowed/fullscreen is handled. DirectDraw - // objects must be destroyed, recreated, and artwork reloaded. - - case WM_DISPLAYCHANGE: - case WM_SIZE: - break; - - case WM_SETCURSOR: - if (bAppFullScreen) - SetCursor(NULL); - else - SetCursor(windowCursor); - return TRUE; - - case WM_KEYUP: - ev.type = ev_keyup; - goto handleKeyDoom; - break; - - case WM_KEYDOWN: - ev.type = ev_keydown; - - handleKeyDoom: - ev.data1 = 0; - if (wParam == VK_PAUSE) - // intercept PAUSE key - { - ev.data1 = KEY_PAUSE; - } - else if (!keyboard_started) - // post some keys during the game startup - // (allow escaping from network synchronization, or pressing enter after - // an error message in the console) - { - switch (wParam) - { - case VK_ESCAPE: ev.data1 = KEY_ESCAPE; break; - case VK_RETURN: ev.data1 = KEY_ENTER; break; - default: ev.data1 = MapVirtualKey((DWORD)wParam,2); // convert in to char - } - } - - if (ev.data1) - D_PostEvent (&ev); - - return 0; - break; - - // judgecutor: - // Handle mouse events - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_XBUTTONDOWN: - case WM_XBUTTONUP: - case WM_MOUSEMOVE: - if (nodinput) - { - mouse_keys = 0; - if (wParam & MK_LBUTTON) - mouse_keys |= 1; - if (wParam & MK_RBUTTON) - mouse_keys |= 2; - if (wParam & MK_MBUTTON) - mouse_keys |= 4; - if (wParam & MK_XBUTTON1) - mouse_keys |= 8; - if (wParam & MK_XBUTTON2) - mouse_keys |= 16; - I_GetSysMouseEvents(mouse_keys); - } - break; - - - case WM_MOUSEWHEEL: - //CONS_Printf("MW_WHEEL dispatched.\n"); - ev.type = ev_keydown; - if ((INT16)HIWORD(wParam) > 0) - ev.data1 = KEY_MOUSEWHEELUP; - else - ev.data1 = KEY_MOUSEWHEELDOWN; - D_PostEvent(&ev); - break; - - case WM_SETTEXT: - COM_BufAddText((LPCSTR)lParam); - return TRUE; - break; - - case WM_CLOSE: - PostQuitMessage(0); //to quit while in-game - ev.data1 = KEY_ESCAPE; //to exit network synchronization - ev.type = ev_keydown; - D_PostEvent (&ev); - return 0; - case WM_DESTROY: - //faB: main app loop will exit the loop and proceed with I_Quit() - PostQuitMessage(0); - break; - - default: - break; - } - - return DefWindowProc(hWnd, message, wParam, lParam); -} - - -static inline VOID OpenTextConsole(void) -{ - HANDLE ci, co; - const BOOL tco = M_CheckParm("-console") != 0; - dedicated = M_CheckParm("-dedicated") != 0; - if (!(dedicated || tco)) - return; - FreeConsole(); - AllocConsole(); //Let get the real console HANDLE, because Mingw's Bash is bad! - ci = CreateFile(TEXT("CONIN$") , GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - co = CreateFile(TEXT("CONOUT$"), GENERIC_WRITE|GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (ci != (HANDLE)-1) - { - const DWORD CM = ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT; - SetStdHandle(STD_INPUT_HANDLE,ci); - if(GetFileType(ci) == FILE_TYPE_CHAR) - SetConsoleMode(ci,CM); //default mode but no ENABLE_MOUSE_INPUT - } - if(co != (HANDLE)-1) - { - SetStdHandle(STD_OUTPUT_HANDLE,co); - SetStdHandle(STD_ERROR_HANDLE,co); //maybe logstream? - } -} - -// -// Do that Windows initialization stuff... -// -static HWND OpenMainWindow (HINSTANCE hInstance, int nCmdShow, LPSTR wTitle) -{ - HWND hWnd; - WNDCLASS wc; - - // Set up and register window class - nCmdShow = 0; - wc.style = CS_HREDRAW | CS_VREDRAW /*| CS_DBLCLKS*/; - wc.lpfnWndProc = MainWndproc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DLICON1)); - windowCursor = LoadCursor(NULL, IDC_WAIT); //LoadCursor(hInstance, MAKEINTRESOURCE(IDC_DLCURSOR1)); - wc.hCursor = windowCursor; - wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); - wc.lpszMenuName = NULL; - wc.lpszClassName = TEXT("SRB2WC"); - if (!RegisterClass(&wc)) - return (HANDLE)-1; - - // Create a window - // CreateWindowEx - seems to create just the interior, not the borders - - hWnd = CreateWindowExA( -#ifdef _DEBUG - 0, //ExStyle -#else - dedicated ? 0:WS_EX_TOPMOST, //ExStyle -#endif - "SRB2WC", //Classname - wTitle, //Windowname - WS_CAPTION|WS_POPUP|WS_SYSMENU, //dwStyle //WS_VISIBLE|WS_POPUP for bAppFullScreen - 0, - 0, - dedicated ? 0:BASEVIDWIDTH, //GetSystemMetrics(SM_CXSCREEN), - dedicated ? 0:BASEVIDHEIGHT, //GetSystemMetrics(SM_CYSCREEN), - NULL, //hWnd Parent - NULL, //hMenu Menu - hInstance, - NULL); - - return hWnd; -} - - -static inline BOOL tlErrorMessage(const TCHAR *err) -{ - /* make the cursor visible */ - SetCursor(LoadCursor(NULL, IDC_ARROW)); - - // - // warn user if there is one - // - printf("Error %s..\n", err); - fflush(stdout); - - MessageBox(hWndMain, err, TEXT("ERROR"), MB_OK); - return FALSE; -} - - -// ------------------ -// Command line stuff -// ------------------ -#define MAXCMDLINEARGS 64 -static char * myWargv[MAXCMDLINEARGS+1]; -static char myCmdline[512]; - -static VOID GetArgcArgv (LPSTR cmdline) -{ - LPSTR token; - size_t i = 0, len; - char cSep = ' '; - BOOL bCvar = FALSE, prevCvar = FALSE; - - // split arguments of command line into argv - strncpy (myCmdline, cmdline, 511); // in case window's cmdline is in protected memory..for strtok - len = strlen (myCmdline); - - myargc = 0; - while (myargc < MAXCMDLINEARGS) - { - // get token - while (myCmdline[i] == cSep) - i++; - if (i >= len) - break; - token = myCmdline + i; - if (myCmdline[i] == '"') - { - cSep = '"'; - i++; - if (!prevCvar) //cvar leave the "" in - token++; - } - else - cSep = ' '; - - //cvar - if (myCmdline[i] == '+' && cSep == ' ') //a + begins a cvarname, but not after quotes - bCvar = TRUE; - else - bCvar = FALSE; - - while (myCmdline[i] && - myCmdline[i] != cSep) - i++; - - if (myCmdline[i] == '"') - { - cSep = ' '; - if (prevCvar) - i++; // get ending " quote in arg - } - - prevCvar = bCvar; - - if (myCmdline + i > token) - { - myWargv[myargc++] = token; - } - - if (!myCmdline[i] || i >= len) - break; - - myCmdline[i++] = '\0'; - } - myWargv[myargc] = NULL; - - // m_argv.c uses myargv[], we used myWargv because we fill the arguments ourselves - // and myargv is just a pointer, so we set it to point myWargv - myargv = myWargv; -} - - -static inline VOID MakeCodeWritable(VOID) -{ -#ifdef USEASM - // Disable write-protection of code segment - DWORD OldRights; - BYTE *pBaseOfImage = (BYTE *)GetModuleHandle(NULL); - IMAGE_OPTIONAL_HEADER *pHeader = (IMAGE_OPTIONAL_HEADER *) - (pBaseOfImage + ((IMAGE_DOS_HEADER*)pBaseOfImage)->e_lfanew + - sizeof (IMAGE_NT_SIGNATURE) + sizeof (IMAGE_FILE_HEADER)); - if (!VirtualProtect(pBaseOfImage+pHeader->BaseOfCode,pHeader->SizeOfCode,PAGE_EXECUTE_READWRITE,&OldRights)) - I_Error("Could not make code writable\n"); -#endif -} - - - - -// ----------------------------------------------------------------------------- -// HandledWinMain : called by exception handler -// ----------------------------------------------------------------------------- -static int WINAPI HandledWinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) -{ - int i; - LPSTR args; - - lpCmdLine = NULL; - hPrevInstance = NULL; -#ifdef LOGMESSAGES - // DEBUG!!! - set logstream to NULL to disable debug log - logstream = INVALID_HANDLE_VALUE; - - logstream = CreateFile (TEXT("log.txt"), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL); //file flag writethrough? -#endif - - // fill myargc,myargv for m_argv.c retrieval of cmdline arguments - CONS_Printf("GetArgcArgv() ...\n"); - args = GetCommandLineA(); - CONS_Printf("lpCmdLine is '%s'\n", args); - GetArgcArgv(args); - // Create a text console window - OpenTextConsole(); - - CONS_Printf("Myargc: %d\n", myargc); - for (i = 0; i < myargc; i++) - CONS_Printf("myargv[%d] : '%s'\n", i, myargv[i]); - - // store for later use, will we need it ? - myInstance = hInstance; - - // open a dummy window, both OpenGL and DirectX need one. - if ((hWndMain = OpenMainWindow(hInstance,nCmdShow, - va("SRB2 "VERSIONSTRING))) == (HANDLE)-1) - { - tlErrorMessage(TEXT("Couldn't open window")); - return FALSE; - } - - // currently starts DirectInput - CONS_Printf("I_StartupSystem() ...\n"); - I_StartupSystem(); - MakeCodeWritable(); - - // startup SRB2 - CONS_Printf("D_SRB2Main() ...\n"); - D_SRB2Main(); - CONS_Printf("Entering main app loop...\n"); - // never return - D_SRB2Loop(); - - // back to Windoze - return 0; -} - -// ----------------------------------------------------------------------------- -// Exception handler calls WinMain for catching exceptions -// ----------------------------------------------------------------------------- -int WINAPI WinMain (HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) -{ - int Result = -1; -#if 1 - HMODULE h = GetModuleHandleA("kernel32.dll"); - MyFunc pfnIsDebuggerPresent = NULL; - if (h) - pfnIsDebuggerPresent = (MyFunc)GetProcAddress(h,"IsDebuggerPresent"); - if (!pfnIsDebuggerPresent || !pfnIsDebuggerPresent()) - LoadLibrary("exchndl.dll"); -#endif -#ifdef NO_SEH_MINGW - __try1(RecordExceptionInfo(GetExceptionInformation()/*, "main thread", lpCmdLine*/)) -#else - __try -#endif - { - Result = HandledWinMain (hInstance, hPrevInstance, lpCmdLine, nCmdShow); - } -#ifdef NO_SEH_MINGW - __except1 -#else - __except (RecordExceptionInfo(GetExceptionInformation()/*, "main thread", lpCmdLine*/)) -#endif - { - SetUnhandledExceptionFilter(EXCEPTION_CONTINUE_SEARCH); //Do nothing here. - } - - return Result; -} diff --git a/src/win32ce/win_main.h b/src/win32ce/win_main.h deleted file mode 100644 index fef25327d44b3c7b7cd7bc8f5243223cd82ab9ba..0000000000000000000000000000000000000000 --- a/src/win32ce/win_main.h +++ /dev/null @@ -1,55 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief Win32 Sharing - -//#define WIN32_LEAN_AND_MEAN -#define RPC_NO_WINDOWS_H -#include <windows.h> -#include <stdio.h> - -extern HINSTANCE myInstance; -extern HWND hWndMain; - -// debugging CONS_Printf to file -#ifdef LOGMESSAGES -extern HANDLE logstream; -#endif -extern int appActive; - -// the MIDI callback is another thread, and Midi volume is delayed here in window proc -VOID I_SetMidiChannelVolume(DWORD dwChannel, DWORD dwVolumePercent); -extern DWORD dwVolumePercent; - -VOID I_GetSysMouseEvents(int mouse_state); -extern unsigned int MSHWheelMessage; - -extern BOOL nodinput; -extern BOOL win9x; - -//faB: midi channel Volume set is delayed by the MIDI stream callback thread, see win_snd.c -#define WM_MSTREAM_UPDATEVOLUME (WM_USER + 101) - -// defined in win_sys.c -VOID I_BeginProfile(VOID); //for timing code -DWORD I_EndProfile(VOID); - -VOID I_GetLastErrorMsgBox(VOID); -VOID I_LoadingScreen (LPCSTR msg); - -void I_RestartSysMouse(void); -void I_DoStartupMouse(void); -BOOL I_SaveMemToFile(const void *pData, size_t iLength, const char *sFileName); diff --git a/src/win32ce/win_net.c b/src/win32ce/win_net.c deleted file mode 100644 index dac1bed53cd29ebb68134076a57b4ad90989d103..0000000000000000000000000000000000000000 --- a/src/win32ce/win_net.c +++ /dev/null @@ -1,39 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief Win32 network interface - -#include "../doomdef.h" -#include "../m_argv.h" -#include "../i_net.h" - -// -// NETWORKING -// - -// -// I_InitNetwork -// -boolean I_InitNetwork (void) -{ - if (M_CheckParm ("-net")) - { - I_Error("The Win32 version of SRB2 doesn't work with external drivers like ipxsetup, sersetup, or doomatic\n" - "Read the documentation about \"-server\" and \"-connect\" parameters or just use the launcher\n"); - } - - return false; -} diff --git a/src/win32ce/win_snd.c b/src/win32ce/win_snd.c deleted file mode 100644 index 14ce4add4dd42f0b42d42d1f82122acbf35cc211..0000000000000000000000000000000000000000 --- a/src/win32ce/win_snd.c +++ /dev/null @@ -1,2408 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief interface level code for sound -/// -/// Uses the midiStream* Win32 functions to play MIDI data -/// with low latency and low processor overhead. -#include "../doomdef.h" - -#include "win_main.h" -#include <mmsystem.h> -#define DIRECTSOUND_VERSION 0x0600 /* version 6.0 */ -#define DIRECTINPUT_VERSION 0x0700 -#define DXVERSION_NTCOMPATIBLE 0x0300 -#ifdef _MSC_VER -#pragma warning(disable : 4201) -#endif -#include <dsound.h> - -#include "../command.h" -#include "../i_sound.h" -#include "../s_sound.h" -#include "../i_system.h" -#include "../m_argv.h" -#include "../w_wad.h" -#include "../z_zone.h" -#include "../doomstat.h" - -#include "dx_error.h" - -#include "mid2strm.h" - -#ifdef HW3SOUND -#include "../hardware/hw3dsdrv.h" -#include "../hardware/hw3sound.h" -#include "win_dll.h" -#endif - -#ifndef SURROUND -#define SURROUND // comment out this to disable the SurroundSound code -#endif - -#ifdef SURROUND -ATTRNOINLINE static FUNCNOINLINE void CopyAndInvertMemory(void *dest, void *src, int bytes); //Can't inline ASM that haves lables -#endif - -#define FMODSOUND // comment out this to disable MOD/IT/MP3/OGG music playback - -/////////////////////////////////////////////////////////// -#ifdef FMODSOUND -#ifdef __MINGW32__ -#include <FMOD/fmod.h> -#else -#include <fmod.h> -#endif -#ifdef FSOUND_INIT_DONTLATENCYADJUST //Alam: why didn't I think about this before? :) -#define FSOUND_Stream_OpenFile(name,mode,length) FSOUND_Stream_Open(name,mode,0,length) -#else -#define FSOUND_INIT_DONTLATENCYADJUST 0 -#endif -#ifdef __MINGW32__ -#include <FMOD/fmod_errors.h> -#else -#include <fmod_errors.h> /* optional */ -#endif -//#include <conio.h> -#endif -///////////////////////////////////////////////////////// - -//#define TESTCODE // remove this for release version - -/* briefly described here for convenience: -typedef struct { - WORD wFormatTag; // WAVE_FORMAT_PCM is the only format accepted for DirectSound: - // this tag indicates Pulse Code Modulation (PCM), an uncompressed format - // in which each samples represents the amplitude of the signal at the time - // of sampling. - WORD nChannels; // either one (mono) or two (stereo) - DWORD nSamplesPerSec; // the sampling rate, or frequency, in hertz. - // Typical values are 11,025, 22,050, and 44,100 - DWORD nAvgBytesPerSec; // nAvgBytesPerSec is the product of nBlockAlign and nSamplesPerSec - WORD nBlockAlign; // the number of bytes required for each complete sample, for PCM formats - // is equal to (wBitsPerSample * nChannels / 8). - WORD wBitsPerSample; // gives the size of each sample, generally 8 or 16 bits - WORD cbSize; // cbSize gives the size of any extra fields required to describe a - // specialized wave format. This member is always zero for PCM formats. -} WAVEFORMATEX; -*/ - -// Tails 11-21-2002 -#ifdef FMODSOUND -static FMUSIC_MODULE *mod = NULL; -static int fsoundchannel = -1; -static int fsoundfreq = 0; -static int fmodvol = 127; -static FSOUND_STREAM *fmus = NULL; -#endif - -// -------------------------------------------------------------------------- -// DirectSound stuff -// -------------------------------------------------------------------------- -static LPDIRECTSOUND DSnd = NULL; -static LPDIRECTSOUNDBUFFER DSndPrimary = NULL; ; - -// Stack sounds means sounds put on top of each other, since DirectSound can't play -// the same sound buffer at different locations at the same time, we need to dupli- -// cate existing buffers to play multiple instances of the same sound in the same -// time frame. A duplicate sound is freed when it is no more used. The priority that -// comes from the s_sound engine, is kept so that the lowest priority sounds are -// stopped to make place for the new sound, unless the new sound has a lower priority -// than all playing sounds, in which case the sound is not started. -#define MAXSTACKSOUNDS 32 // this is the absolute number of sounds that - // can play simultaneously, whatever the value - // of cv_numChannels -typedef struct { - LPDIRECTSOUNDBUFFER lpSndBuf; -#ifdef SURROUND - // judgecutor: - // Need for produce surround sound - LPDIRECTSOUNDBUFFER lpSurround; -#endif - int priority; - boolean duplicate; -} StackSound_t; -static StackSound_t StackSounds[MAXSTACKSOUNDS]; - -// -------------------------------------------------------------------------- -// Fill the DirectSoundBuffer with data from a sample, made separate so that -// sound data cna be reloaded if a sound buffer was lost. -// -------------------------------------------------------------------------- -static boolean CopySoundData (LPDIRECTSOUNDBUFFER dsbuffer, LPBYTE data, DWORD length) -{ - LPVOID lpvAudio1; // receives address of lock start - DWORD dwBytes1; // receives number of bytes locked - LPVOID lpvAudio2; // receives address of lock start - DWORD dwBytes2; // receives number of bytes locked - HRESULT hr; - - // Obtain memory address of write block. - hr = IDirectSoundBuffer_Lock (dsbuffer, 0, length, &lpvAudio1, &dwBytes1, &lpvAudio2, &dwBytes2, 0); - - // If DSERR_BUFFERLOST is returned, restore and retry lock. - if (hr == DSERR_BUFFERLOST) - { - hr = IDirectSoundBuffer_Restore (dsbuffer); - if (FAILED (hr)) - I_Error("Restore fail on %x, %s\n",dsbuffer,DXErrorToString(hr)); - hr = IDirectSoundBuffer_Lock (dsbuffer, 0, length, &lpvAudio1, &dwBytes1, &lpvAudio2, &dwBytes2, 0); - if (FAILED (hr)) - I_Error("Lock fail(2) on %x, %s\n",dsbuffer,DXErrorToString(hr)); - } - else - if (FAILED (hr)) - I_Error("Lock fail(1) on %x, %s\n",dsbuffer,DXErrorToString(hr)); - - // copy wave data into the buffer (note: dwBytes1 should equal to dsbdesc->dwBufferBytes ...) - CopyMemory (lpvAudio1, data, dwBytes1); - - if (dwBytes2 && lpvAudio2) - CopyMemory(lpvAudio2, data+dwBytes1, dwBytes2); - - // finally, unlock the buffer - hr = IDirectSoundBuffer_Unlock (dsbuffer, lpvAudio1, dwBytes1, lpvAudio2, dwBytes2); - - if (FAILED (hr)) - I_Error("Unlock fail on %x, %s\n",dsbuffer,DXErrorToString(hr)); - - return true; -} - -#ifdef SURROUND -// judgecutor: -// Hmmm... May be this function is not too good... -static void CopyAndInvertMemory(void *dest, void *src, int bytes) -{ -#ifdef __GNUC__ - __asm__("CAIM:;lodsb;neg %%al;stosb;loop CAIM;"::"c"(bytes),"D"(dest),"S"(src): "memory","cc"); -#else - _asm - { - push esi - push edi - push ecx - mov ecx,bytes - mov esi,src - mov edi,dest -a: - lodsb - neg al - stosb - loop a - pop ecx - pop edi - pop esi - } -#endif -} - -// judgecutor: -// Like normal CopySoundData but sound data will be inverted -static boolean CopyAndInvertSoundData(LPDIRECTSOUNDBUFFER dsbuffer, LPBYTE data, DWORD length) -{ - LPVOID lpvAudio1 = NULL; // receives address of lock start - DWORD dwBytes1 = 0; // receives number of bytes locked - LPVOID lpvAudio2 = NULL; - DWORD dwBytes2 = 0; - HRESULT hr; - - // Obtain memory address of write block. - hr = IDirectSoundBuffer_Lock (dsbuffer, 0, length, &lpvAudio1, &dwBytes1, &lpvAudio2, &dwBytes2, 0); - - // If DSERR_BUFFERLOST is returned, restore and retry lock. - if (hr == DSERR_BUFFERLOST) - { - hr = IDirectSoundBuffer_Restore (dsbuffer); - if (FAILED (hr)) - I_Error("CopyAndInvert: Restore fail on %x, %s\n",dsbuffer,DXErrorToString(hr)); - hr = IDirectSoundBuffer_Lock (dsbuffer, 0, length, &lpvAudio1, &dwBytes1, &lpvAudio2, &dwBytes2, 0); - if (FAILED (hr)) - I_Error("CopyAndInvert: Lock fail(2) on %x, %s\n",dsbuffer,DXErrorToString(hr)); - } else if (FAILED (hr)) - I_Error("CopyAndInvetrt: Lock fail(1) on %x, %s\n",dsbuffer,DXErrorToString(hr)); - - // copy wave data into the buffer (note: dwBytes1 should equal to dsbdesc->dwBufferBytes ...) - CopyAndInvertMemory (lpvAudio1, data, dwBytes1); - - if (dwBytes2 && lpvAudio2) - CopyAndInvertMemory(lpvAudio2, data+dwBytes1, dwBytes2); - - hr = IDirectSoundBuffer_Unlock (dsbuffer, lpvAudio1, dwBytes1, lpvAudio2, dwBytes2); - if (FAILED (hr)) - I_Error("CopyAndInvert: Unlock fail on %x, %s\n",dsbuffer,DXErrorToString(hr)); - - return false; -} -#endif - -static DWORD sound_buffer_flags = DSBCAPS_CTRLPAN | - DSBCAPS_CTRLVOLUME | - DSBCAPS_STICKYFOCUS | - //DSBCAPS_LOCSOFTWARE | - DSBCAPS_STATIC; - -// -------------------------------------------------------------------------- -// raw2DS : convert a raw sound data, returns a LPDIRECTSOUNDBUFFER -// -------------------------------------------------------------------------- -// dsdata points a 4 UINT16 header: -// +0 : value 3 what does it mean? -// +2 : sample rate, either 11025 or 22050. -// +4 : number of samples, each sample is a single byte since it's 8bit -// +6 : value 0 -// -#ifdef SURROUND -// judgecutor: -// We need an another function definition for supporting the surround sound -// Invert just cause to copy an inverted sound data -static LPDIRECTSOUNDBUFFER raw2DS(LPBYTE *dsdata, size_t len, UINT8 invert) -#else -static LPDIRECTSOUNDBUFFER raw2DS(LPBYTE *dsdata, size_t len) -#endif -{ - HRESULT hr; - WAVEFORMATEX wfm; - DSBUFFERDESC dsbdesc; - LPDIRECTSOUNDBUFFER dsbuffer; - - // initialise WAVEFORMATEX structure describing the wave format - ZeroMemory (&wfm, sizeof (WAVEFORMATEX)); - wfm.wFormatTag = WAVE_FORMAT_PCM; - wfm.nChannels = 1; - wfm.nSamplesPerSec = (dsdata[3]<<8)+dsdata[2]; //mostly 11025, but some at 22050. - wfm.wBitsPerSample = 8; - wfm.nBlockAlign = (WORD)(wfm.wBitsPerSample / 8 * wfm.nChannels); - wfm.nAvgBytesPerSec = wfm.nSamplesPerSec * wfm.nBlockAlign; - - // Set up DSBUFFERDESC structure. - ZeroMemory (&dsbdesc, sizeof (DSBUFFERDESC)); - dsbdesc.dwSize = sizeof (DSBUFFERDESC); -/* dsbdesc.dwFlags = DSBCAPS_CTRLPAN | - DSBCAPS_CTRLVOLUME | - DSBCAPS_STICKYFOCUS | - //DSBCAPS_LOCSOFTWARE | - DSBCAPS_STATIC - | DSBCAPS_CTRLFREQUENCY; // This one for pitching -*/ - dsbdesc.dwFlags = sound_buffer_flags; - dsbdesc.dwBufferBytes = len-8; - dsbdesc.lpwfxFormat = &wfm; // pointer to WAVEFORMATEX structure - - // Create the sound buffer - hr = IDirectSound_CreateSoundBuffer (DSnd, &dsbdesc, &dsbuffer, NULL); - - if (hr == DSERR_CONTROLUNAVAIL) - { - CONS_Printf("\tSoundBufferCreate error - a buffer control is not available.\n\tTrying to disable frequency control.\n"); - - sound_buffer_flags &= ~DSBCAPS_CTRLFREQUENCY; - dsbdesc.dwFlags = sound_buffer_flags; - - hr = IDirectSound_CreateSoundBuffer (DSnd, &dsbdesc, &dsbuffer, NULL); - } - - if (FAILED(hr)) - I_Error("CreateSoundBuffer() FAILED: %s\n", DXErrorToString(hr)); - -#ifdef SURROUND - if (invert) - // just invert a sound data for producing the surround sound - CopyAndInvertSoundData(dsbuffer, (LPBYTE)dsdata + 8, dsbdesc.dwBufferBytes); - else - // Do a normal operation -#endif - // fill the DirectSoundBuffer waveform data - CopySoundData (dsbuffer, (LPBYTE)dsdata + 8, dsbdesc.dwBufferBytes); - - return dsbuffer; -} - - -// -------------------------------------------------------------------------- -// This function loads the sound data from the WAD lump, for single sound. -// -------------------------------------------------------------------------- -void *I_GetSfx (sfxinfo_t * sfx) -{ - LPBYTE dssfx; - - if (sfx->lumpnum < 0) - sfx->lumpnum = S_GetSfxLumpNum (sfx); - -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - return HW3S_GetSfx(sfx); -#endif - - sfx->length = W_LumpLength (sfx->lumpnum); - - // PU_CACHE because the data is copied to the DIRECTSOUNDBUFFER, the one here will not be used - dssfx = (LPBYTE) W_CacheLumpNum (sfx->lumpnum, PU_CACHE); - -#ifdef SURROUND - // Make a normal (not inverted) sound buffer - return (void *)raw2DS (dssfx, sfx->length, FALSE); -#else - // return the LPDIRECTSOUNDBUFFER, which will be stored in S_sfx[].data - return (void *)raw2DS (dssfx, sfx->length); -#endif -} - - -// -------------------------------------------------------------------------- -// Free all allocated resources for a single sound -// -------------------------------------------------------------------------- -void I_FreeSfx (sfxinfo_t *sfx) -{ - LPDIRECTSOUNDBUFFER dsbuffer; - - if (sfx->lumpnum < 0) - return; - -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - { - HW3S_FreeSfx(sfx); - } - else -#endif - { - //CONS_Printf("I_FreeSfx(%d)\n", sfx->lumpnum); - - // free DIRECTSOUNDBUFFER - dsbuffer = (LPDIRECTSOUNDBUFFER) sfx->data; - if (dsbuffer) - { - size_t i; - for (i = 0; i < MAXSTACKSOUNDS; i++) - { - if (StackSounds[i].lpSndBuf == dsbuffer) - { - StackSounds[i].lpSndBuf = NULL; -#ifdef SURROUND - if (StackSounds[i].lpSurround) - { - IDirectSoundBuffer_Stop(StackSounds[i].lpSurround); - IDirectSoundBuffer_Release(StackSounds[i].lpSurround); - } - StackSounds[i].lpSurround = NULL; -#endif - } - } - IDirectSoundBuffer_Stop (dsbuffer); - IDirectSoundBuffer_Release (dsbuffer); - } - } - sfx->data = NULL; - sfx->lumpnum = -1; -} - - -// -------------------------------------------------------------------------- -// Set the global volume for sound effects -// -------------------------------------------------------------------------- -void I_SetSfxVolume(INT32 volume) -{ - int vol; - HRESULT hr; - - if (nosound || !sound_started) - return; - - // use the last quarter of volume range - if (volume) - vol = (volume * ((DSBVOLUME_MAX-DSBVOLUME_MIN)/4)) / 31 + - (DSBVOLUME_MAX - ((DSBVOLUME_MAX-DSBVOLUME_MIN)/4)); - else - vol = DSBVOLUME_MIN; // make sure 0 is silence - //CONS_Printf("setvolume to %d\n", vol); - hr = IDirectSoundBuffer_SetVolume (DSndPrimary, vol); - //if (FAILED(hr)) - // CONS_Printf("setvolumne failed\n"); -} - - -// -------------------------------------------------------------------------- -// Update the volume for a secondary buffer, make sure it was created with -// DSBCAPS_CTRLVOLUME -// -------------------------------------------------------------------------- -static void I_UpdateSoundVolume (LPDIRECTSOUNDBUFFER lpSnd, int volume) -{ - HRESULT hr; - volume = (volume * ((DSBVOLUME_MAX-DSBVOLUME_MIN)/4)) / 256 + - (DSBVOLUME_MAX - ((DSBVOLUME_MAX-DSBVOLUME_MIN)/4)); - hr = IDirectSoundBuffer_SetVolume (lpSnd, volume); - //if (FAILED(hr)) - // CONS_Printf("\2SetVolume FAILED\n"); -} - - -// -------------------------------------------------------------------------- -// Update the panning for a secondary buffer, make sure it was created with -// DSBCAPS_CTRLPAN -// -------------------------------------------------------------------------- -#define DSBPAN_RANGE (DSBPAN_RIGHT-(DSBPAN_LEFT)) -#define SEP_RANGE 256 //Doom sounds pan range 0-255 (128 is centre) -static void I_UpdateSoundPanning (LPDIRECTSOUNDBUFFER lpSnd, int sep) -{ - HRESULT hr; - hr = IDirectSoundBuffer_SetPan (lpSnd, (sep * DSBPAN_RANGE)/SEP_RANGE - DSBPAN_RIGHT); - //if (FAILED(hr)) - // CONS_Printf("SetPan FAILED for sep %d pan %d\n", sep, (sep * DSBPAN_RANGE)/SEP_RANGE - DSBPAN_RIGHT); -} - -// search a free slot in the stack, free it if needed -static int GetFreeStackNum(int newpriority) -{ - int lowestpri = 256,lowestprihandle = 0; - int i; - // DirectSound can't play multiple instances of the same sound buffer - // unless they are duplicated, so if the sound buffer is in use, make a duplicate - for (i = 0; i < MAXSTACKSOUNDS; i++) - { - // find a free 'playing sound slot' to use - if (StackSounds[i].lpSndBuf == NULL) - { - //CONS_Printf("\t\tfound free slot %d\n", i); - return i; - } - else if (!I_SoundIsPlaying(i)) // check for sounds that finished playing, and can be freed - { - //CONS_Printf("\t\tfinished sound in slot %d\n", i); - //stop sound and free the 'slot' - I_StopSound (i); - // we can use this one since it's now freed - return i; - } - else if (StackSounds[i].priority < lowestpri) //remember lowest priority sound - { - lowestpri = StackSounds[i].priority; - lowestprihandle = i; - } - } - - // the maximum of sounds playing at the same time is reached, if we have at least - // one sound playing with a lower priority, stop it and replace it with the new one - - //CONS_Printf("\t\tall slots occupied..\n"); - if (newpriority >= lowestpri) - { - I_StopSound (lowestprihandle); - return lowestprihandle; - //CONS_Printf(" kicking out lowest priority slot: %d pri: %d, my priority: %d\n", - // handle, lowestpri, priority); - } - - return -1; -} - -#ifdef SURROUND -static LPDIRECTSOUNDBUFFER CreateInvertedSound(int id) -{ - lumpnnum_t lumpnum; - LBYPTE dsdata; - - lumpnum = S_sfx[id].lumpnum; - if (lumpnum < 0) - lumpnum = S_GetSfxLumpNum (&S_sfx[id]); - dsdata = W_CacheLumpNum (lumpnum, PU_CACHE); - return raw2DS(dsdata, S_sfx[id].length, TRUE); -} -#endif - -// Calculate internal pitch from Doom pitch -#if 0 -static float recalc_pitch(int doom_pitch) -{ - return doom_pitch < NORMAL_PITCH ? - (float)(doom_pitch + NORMAL_PITCH) / (NORMAL_PITCH * 2) - :(float)doom_pitch / (float)NORMAL_PITCH; -} -#endif - -// -------------------------------------------------------------------------- -// Start the given S_sfx[id] sound with given properties (panning, volume..) -// -------------------------------------------------------------------------- -INT32 I_StartSound (sfxenum_t id, - INT32 vol, - INT32 sep, - INT32 pitch, - INT32 priority, - INT32 channel) -{ - HRESULT hr; - LPDIRECTSOUNDBUFFER dsbuffer; - DWORD dwStatus; - int handle; - int i; - //DWORD freq; -#ifdef SURROUND - LPDIRECTSOUNDBUFFER dssurround; -#endif - (void)channel; - - if (nosound) - return -1; - - //CONS_Printf("I_StartSound:\n\t\tS_sfx[%d]\n", id); - handle = GetFreeStackNum(priority); - if (handle < 0) - return -1; - - //CONS_Printf("\t\tusing handle %d\n", handle); - - // if the original buffer is playing, duplicate it (DirectSound specific) - // else, use the original buffer - dsbuffer = (LPDIRECTSOUNDBUFFER) S_sfx[id].data; - IDirectSoundBuffer_GetStatus (dsbuffer, &dwStatus); - if (dwStatus & (DSBSTATUS_PLAYING | DSBSTATUS_LOOPING)) - { - //CONS_Printf("\t\toriginal sound S_sfx[%d] is playing, duplicating.. ", id); - hr = IDirectSound_DuplicateSoundBuffer(DSnd, (LPDIRECTSOUNDBUFFER) S_sfx[id].data, &dsbuffer); - if (FAILED(hr)) - { - //CONS_Printf("Cound't duplicate sound buffer\n"); - // re-use the original then.. - dsbuffer = (LPDIRECTSOUNDBUFFER) S_sfx[id].data; - // clean up stacksounds info - for (i = 0; i < MAXSTACKSOUNDS; i++) - if (handle != i && - StackSounds[i].lpSndBuf == dsbuffer) - { - StackSounds[i].lpSndBuf = NULL; - } - } - // stop the duplicate or the re-used original - IDirectSoundBuffer_Stop (dsbuffer); - } - - //judgecutor: Sound pitching -#if 0 - if (cv_rndsoundpitch.value) - { - // At first reset the buffer back to original frequency - hr = IDirectSoundBuffer_SetFrequency(dsbuffer, DSBFREQUENCY_ORIGINAL); - if (SUCCEEDED (hr)) - { - - IDirectSoundBuffer_GetFrequency(dsbuffer, &freq); - - // Now pitch it - freq *= recalc_pitch(pitch); - IDirectSoundBuffer_SetFrequency(dsbuffer, freq); - } - else - cv_rndsoundpitch = 0; - } -#else - pitch = 0; -#endif - // store information on the playing sound - StackSounds[handle].lpSndBuf = dsbuffer; - StackSounds[handle].priority = priority; - StackSounds[handle].duplicate = (dsbuffer != (LPDIRECTSOUNDBUFFER)S_sfx[id].data); - - //CONS_Printf("StackSounds[%d].lpSndBuf is %s\n", handle, StackSounds[handle].lpSndBuf == NULL ? "Null":"valid"); - //CONS_Printf("StackSounds[%d].priority is %d\n", handle, StackSounds[handle].priority); - //CONS_Printf("StackSounds[%d].duplicate is %s\n", handle, StackSounds[handle].duplicate ? "TRUE":"FALSE"); - - I_UpdateSoundVolume (dsbuffer, vol); - -#ifdef SURROUND - // Prepare the surround sound buffer - // Use a normal sound data for the left channel (with pan == 0) - // and an inverted sound data for the right channel (with pan == 255) - - dssurround = CreateInvertedSound(id); - - // Surround must be pitched too -#if 0 - if (cv_rndsoundpitch.value) - IDirectSoundBuffer_SetFrequency(dssurround, freq); -#endif - if (sep == -128) - { - I_UpdateSoundPanning(dssurround, 255); - I_UpdateSoundVolume(dssurround, vol); - I_UpdateSoundPanning(dsbuffer, 0); - IDirectSoundBuffer_SetCurrentPosition(dssurround, 0); - } - else - // Perform normal operation -#endif - - I_UpdateSoundPanning (dsbuffer, sep); - - IDirectSoundBuffer_SetCurrentPosition (dsbuffer, 0); - - hr = IDirectSoundBuffer_Play (dsbuffer, 0, 0, 0); - if (hr == DSERR_BUFFERLOST) - { - //CONS_Printf("buffer lost\n"); - // restores the buffer memory and all other settings for the buffer - hr = IDirectSoundBuffer_Restore (dsbuffer); - if (SUCCEEDED (hr)) - { - LPBYTE dsdata; - // reload sample data here - int lumpnum = S_sfx[id].lumpnum; - if (lumpnum < 0) - lumpnum = S_GetSfxLumpNum (&S_sfx[id]); - dsdata = W_CacheLumpNum (lumpnum, PU_CACHE); - - // Well... Data lenght must be -8!!! - CopySoundData (dsbuffer, dsdata + 8, S_sfx[id].length - 8); - - // play - hr = IDirectSoundBuffer_Play (dsbuffer, 0, 0, 0); - } - else - I_Error("I_StartSound : ->Restore FAILED, %s",DXErrorToString(hr)); - } - -#ifdef SURROUND - if (sep == -128) - { - hr = IDirectSoundBuffer_Play (dssurround, 0, 0, 0); - //CONS_Printf("Surround playback\n"); - if (hr == DSERR_BUFFERLOST) - { - // restores the buffer memory and all other settings for the surround buffer - hr = IDirectSoundBuffer_Restore (dssurround); - if (SUCCEEDED (hr)) - { - LPBYTE dsdata; - lumpnumt_t lumpnum = S_sfx[id].lumpnum; - - if (lumpnum < 0) - lumpnum = S_GetSfxLumpNum (&S_sfx[id]); - dsdata = W_CacheLumpNum (lumpnum, PU_CACHE); - CopyAndInvertSoundData (dssurround, (LPBYTE)dsdata + 8, S_sfx[id].length - 8); - - hr = IDirectSoundBuffer_Play (dssurround, 0, 0, 0); - } - else - I_Error("I_StartSound : ->Restore FAILED, %s",DXErrorToString(hr)); - } - } - StackSounds[handle].lpSurround = dssurround; -#endif - - // Returns a handle - return handle; -} - - -// -------------------------------------------------------------------------- -// Stop a sound if it is playing, -// free the corresponding 'playing sound slot' in StackSounds[] -// -------------------------------------------------------------------------- -void I_StopSound (INT32 handle) -{ - LPDIRECTSOUNDBUFFER dsbuffer; - HRESULT hr; - - if (nosound || handle < 0) - return; - - //CONS_Printf("I_StopSound (%d)\n", handle); - - dsbuffer = StackSounds[handle].lpSndBuf; - hr = IDirectSoundBuffer_Stop (dsbuffer); - - // free duplicates of original sound buffer (DirectSound hassles) - if (StackSounds[handle].duplicate) - { - //CONS_Printf("\t\trelease a duplicate..\n"); - IDirectSoundBuffer_Release (dsbuffer); - } - -#ifdef SURROUND - // Stop and release the surround sound buffer - dsbuffer = StackSounds[handle].lpSurround; - if (dsbuffer != NULL) - { - IDirectSoundBuffer_Stop(dsbuffer); - IDirectSoundBuffer_Release(dsbuffer); - } - StackSounds[handle].lpSurround = NULL; -#endif - - StackSounds[handle].lpSndBuf = NULL; -} - - -// -------------------------------------------------------------------------- -// Returns whether the sound is currently playing or not -// -------------------------------------------------------------------------- -INT32 I_SoundIsPlaying(INT32 handle) -{ - LPDIRECTSOUNDBUFFER dsbuffer; - DWORD dwStatus; - - if (nosound || handle == -1) - return FALSE; - - dsbuffer = StackSounds[handle].lpSndBuf; - if (dsbuffer) - { - IDirectSoundBuffer_GetStatus (dsbuffer, &dwStatus); - if (dwStatus & (DSBSTATUS_PLAYING | DSBSTATUS_LOOPING)) - return TRUE; - } - - return FALSE; -} - - -// -------------------------------------------------------------------------- -// Update properties of a sound currently playing -// -------------------------------------------------------------------------- -void I_UpdateSoundParams(INT32 handle, - INT32 vol, - INT32 sep, - INT32 pitch) -{ - LPDIRECTSOUNDBUFFER dsbuffer; -#ifdef SURROUND - LPDIRECTSOUNDBUFFER dssurround; - DWORD dwStatus; - DWORD pos; - boolean surround_inuse = FALSE; -#endif - - if (nosound) - return; - - pitch = 0; /// \todo pitch setup - dsbuffer = StackSounds[handle].lpSndBuf; - -#ifdef SURROUND - if (dsbuffer == NULL) - return; - - dssurround = StackSounds[handle].lpSurround; - if (dssurround) - { - IDirectSoundBuffer_GetStatus(dssurround, &dwStatus); - surround_inuse = (dwStatus & (DSBSTATUS_PLAYING | DSBSTATUS_LOOPING)); - } - // If pan changed to stereo... - if (sep != -128) - { - if (surround_inuse) - { - IDirectSoundBuffer_Stop(dssurround); - surround_inuse = FALSE; - } - } - else if (!surround_inuse) // Just update volumes and start the surround if need - { - I_UpdateSoundVolume(dssurround, vol); - I_UpdateSoundPanning(dsbuffer, 0); - IDirectSoundBuffer_GetCurrentPosition(dsbuffer, &pos, NULL); - IDirectSoundBuffer_SetCurrentPosition(dssurround, pos); - IDirectSoundBuffer_Play(dssurround, 0, 0, 0); - surround_inuse = TRUE; - } - else - I_UpdateSoundVolume(dssurround, vol); - I_UpdateSoundVolume(dsbuffer, vol); - - if (!surround_inuse) - I_UpdateSoundPanning(dsbuffer, sep); -#else - if (dsbuffer) - { - I_UpdateSoundVolume (dsbuffer, vol); - I_UpdateSoundPanning (dsbuffer, sep); - } -#endif -} - - -// -// Shutdown DirectSound -// -void I_ShutdownSound(void) -{ - int i; - - CONS_Printf("I_ShutdownSound()\n"); - -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - { - HW3S_Shutdown(); - Shutdown3DSDriver(); - return; - } -#endif - // release any temporary 'duplicated' secondary buffers - for (i = 0; i < MAXSTACKSOUNDS; i++) - if (StackSounds[i].lpSndBuf) - // stops the sound and release it if it is a duplicate - I_StopSound (i); - - if (DSnd) - { - IDirectSound_Release(DSnd); - DSnd = NULL; - } -} - - -// ========================================================================== -// Startup DirectSound -// ========================================================================== -void I_StartupSound(void) -{ - HRESULT hr; - LPDIRECTSOUNDBUFFER lpDsb; - DSBUFFERDESC dsbdesc; - WAVEFORMATEX wfm; - int cooplevel; - int frequency; - -#ifdef HW3SOUND - const char *sdrv_name = NULL; - snddev_t snddev; -#endif - - sound_started = false; - - if (dedicated) - return; - - if (nosound) - return; - - // Secure and configure sound device first. - CONS_Printf("I_StartupSound: "); - - // frequency of primary buffer may be set at cmd-line - if (M_CheckParm ("-freq") && M_IsNextParm()) - { - frequency = atoi(M_GetNextParm()); - CONS_Printf(" requested frequency of %d hz\n", frequency); - CV_SetValue(&cv_samplerate,frequency); - } - else - frequency = cv_samplerate.value; - - // Set cooperative level - // Cooperative sound with other applications can be requested at cmd-line - if (M_CheckParm("-coopsound")) - cooplevel = DSSCL_PRIORITY; - else - cooplevel = DSSCL_EXCLUSIVE; - -#ifdef HW3SOUND - if (M_CheckParm("-ds3d")) - { - hws_mode = HWS_DS3D; - sdrv_name = "s_ds3d.dll"; - } -#if 1 - else if (M_CheckParm("-fmod3d")) - { - hws_mode = HWS_FMOD3D; - sdrv_name = "s_fmod.dll"; - } - else if (M_CheckParm("-sounddriver") && M_IsNextParm()) - { - hws_mode = HWS_OTHER; - sdrv_name = M_GetNextParm(); - } -#else - else if (M_CheckParm("-sounddriver") && M_IsNextParm()) - { - hws_mode = HWS_OTHER; - sdrv_name = M_GetNextParm(); - } - else if (!M_CheckParm("-nosd")) - { - hws_mode = HWS_FMOD3D; - sdrv_name = "s_fmod.dll"; - } -#endif - - // There must be further sound drivers (such as A3D and EAX)!!! - - if (hws_mode != HWS_DEFAULT_MODE && sdrv_name != NULL) - { - if (Init3DSDriver(sdrv_name)) - { - //nosound = true; - snddev.sample_rate = frequency; - snddev.bps = 16; - snddev.numsfxs = NUMSFX; - snddev.cooplevel = cooplevel; - snddev.hWnd = hWndMain; - if (HW3S_Init(I_Error, &snddev)) - { - CONS_Printf("Using external sound driver %s\n", sdrv_name); - I_AddExitFunc(I_ShutdownSound); - return; - } - // Falls back to default sound system - CONS_Printf("Not using external sound driver %s\n", sdrv_name); - HW3S_Shutdown(); - Shutdown3DSDriver(); - } - hws_mode = HWS_DEFAULT_MODE; - } -#endif - - // Create DirectSound, use the default sound device - hr = DirectSoundCreate(NULL, &DSnd, NULL); - if (FAILED(hr)) - { - CONS_Printf(" DirectSoundCreate FAILED\n" - " there is no sound device or the sound device is under\n" - " the control of another application\n"); - nosound = true; - return; - } - - // register exit code, now that we have at least DirectSound to close - I_AddExitFunc(I_ShutdownSound); - hr = IDirectSound_SetCooperativeLevel (DSnd, hWndMain, cooplevel); - if (FAILED(hr)) - { - CONS_Printf(" SetCooperativeLevel FAILED\n"); - nosound = true; - return; - } - - // Set up DSBUFFERDESC structure. - ZeroMemory (&dsbdesc, sizeof (DSBUFFERDESC)); - dsbdesc.dwSize = sizeof (DSBUFFERDESC); - dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER | - DSBCAPS_CTRLVOLUME; - dsbdesc.dwBufferBytes = 0; // Must be 0 for primary buffer - dsbdesc.lpwfxFormat = NULL; // Must be NULL for primary buffer - - // Set up structure for the desired format - ZeroMemory (&wfm, sizeof (WAVEFORMATEX)); - wfm.wFormatTag = WAVE_FORMAT_PCM; - wfm.nChannels = 2; //STEREO SOUND! - wfm.nSamplesPerSec = frequency; - wfm.wBitsPerSample = 16; - wfm.nBlockAlign = (WORD)(wfm.wBitsPerSample / 8 * wfm.nChannels); - wfm.nAvgBytesPerSec = wfm.nSamplesPerSec * wfm.nBlockAlign; - - // Gain access to the primary buffer - hr = IDirectSound_CreateSoundBuffer (DSnd, &dsbdesc, &lpDsb, NULL); - if (FAILED(hr)) - { - CONS_Printf("CreateSoundBuffer FAILED: %s (ErrNo %d)\n", DXErrorToString(hr), hr); - nosound = true; - return; - } - - // Set the primary buffer to the desired format, - // but only if we are allowed to do it - if (cooplevel >= DSSCL_PRIORITY) - { - if (SUCCEEDED (hr)) - { - // Set primary buffer to the desired format. If this fails, - // we'll just ignore and go with the default. - hr = IDirectSoundBuffer_SetFormat (lpDsb, &wfm); - if (FAILED(hr)) - CONS_Printf("I_StartupSound : couldn't set primary buffer format.\n"); - else - CV_SetValue(&cv_samplerate,wfm.nSamplesPerSec); - } - // move any on-board sound memory into a contiguous block - // to make the largest portion of free memory available. - - CONS_Printf(" Compacting onboard sound-memory..."); - hr = IDirectSound_Compact (DSnd); - CONS_Printf(" %s\n", SUCCEEDED(hr) ? "Done\n" : "Failed\n")); - } - - // set the primary buffer to play continuously, for performance - // "... this method will ensure that the primary buffer is playing even when no secondary - // buffers are playing; in that case, silence will be played. This can reduce processing - // overhead when sounds are started and stopped in sequence, because the primary buffer - // will be playing continuously rather than stopping and starting between secondary buffers." - hr = IDirectSoundBuffer_Play (lpDsb, 0, 0, DSBPLAY_LOOPING); - if (FAILED (hr)) - CONS_Printf(" Primary buffer continuous play FAILED\n"); - -#ifdef DEBUGSOUND - { - DSCAPS DSCaps; - DSCaps.dwSize = sizeof (DSCAPS); - hr = IDirectSound_GetCaps (DSnd, &DSCaps); - if (SUCCEEDED (hr)) - { - if (DSCaps.dwFlags & DSCAPS_CERTIFIED) - CONS_Printf("This driver has been certified by Microsoft\n"); - if (DSCaps.dwFlags & DSCAPS_EMULDRIVER) - CONS_Printf("No driver with DirectSound support installed (no hardware mixing)\n"); - if (DSCaps.dwFlags & DSCAPS_PRIMARY16BIT) - CONS_Printf("Supports 16-bit primary buffer\n"); - if (DSCaps.dwFlags & DSCAPS_PRIMARY8BIT) - CONS_Printf("Supports 8-bit primary buffer\n"); - if (DSCaps.dwFlags & DSCAPS_SECONDARY16BIT) - CONS_Printf("Supports 16-bit, hardware-mixed secondary buffers\n"); - if (DSCaps.dwFlags & DSCAPS_SECONDARY8BIT) - CONS_Printf("Supports 8-bit, hardware-mixed secondary buffers\n"); - - CONS_Printf("Maximum number of hardware buffers: %d\n", DSCaps.dwMaxHwMixingStaticBuffers); - CONS_Printf("Size of total hardware memory: %d\n", DSCaps.dwTotalHwMemBytes); - CONS_Printf("Size of free hardware memory= %d\n", DSCaps.dwFreeHwMemBytes); - CONS_Printf("Play Cpu Overhead (%% cpu cycles): %d\n", DSCaps.dwPlayCpuOverheadSwBuffers); - } - else - CONS_Printf(" couldn't get sound device caps.\n"); - } -#endif - - // save pointer to the primary DirectSound buffer for volume changes - DSndPrimary = lpDsb; - - ZeroMemory (StackSounds, sizeof (StackSounds)); - - CONS_Printf("sound initialised.\n"); - sound_started = true; -} - - -// ========================================================================== -// -// MUSIC API using MidiStream -// -// ========================================================================== - -#define SPECIAL_HANDLE_CLEANMIDI -1999 // tell I_StopSong() to do a full (slow) midiOutReset() on exit - -static BOOL bMusicStarted; - -static UINT uMIDIDeviceID, uCallbackStatus; -static HMIDISTRM hStream; -static HANDLE hBufferReturnEvent; // for synch between the callback thread and main program thread - // (we need to synch when we decide to stop/free stream buffers) - -static int nCurrentBuffer = 0, nEmptyBuffers; - -static BOOL bBuffersPrepared = FALSE; -static DWORD dwVolCache[MAX_MIDI_IN_TRACKS]; - DWORD dwVolumePercent; // accessed by win_main.c - - // this is accessed by mid2strm.c conversion code - BOOL bMidiLooped = FALSE; -static BOOL bMidiPlaying = FALSE; -static BOOL bMidiPaused = FALSE; -static CONVERTINFO ciStreamBuffers[NUM_STREAM_BUFFERS]; - -#define STATUS_KILLCALLBACK 100 // Signals that the callback should die -#define STATUS_CALLBACKDEAD 200 // Signals callback is done processing -#define STATUS_WAITINGFOREND 300 // Callback's waiting for buffers to play - -#define DEBUG_CALLBACK_TIMEOUT 2000 // Wait 2 seconds for callback - // faB: don't freeze the main code if we debug.. - -#define VOL_CACHE_INIT 127 // for dwVolCache[] - -static BOOL bMidiCanSetVolume; // midi caps - -static void Mid2StreamFreeBuffers(void); -static void CALLBACK MidiStreamCallback (HMIDIIN hMidi, UINT uMsg, DWORD dwInstance, - DWORD dwParam1, DWORD dwParam2); -static BOOL StreamBufferSetup(LPBYTE pMidiData, size_t iMidiSize); - -// ------------------- -// MidiErrorMessageBox -// Calls the midiOutGetErrorText() function and displays the text which -// corresponds to a midi subsystem error code. -// ------------------- -static void MidiErrorMessageBox(MMRESULT mmr) -{ - char szTemp[256] = ""; - - /*szTemp[0] = '\2'; //white text to stand out*/ - if((MMSYSERR_NOERROR == midiOutGetErrorTextA(mmr, szTemp/*+1*/, sizeof (szTemp))) && *szTemp) - CONS_Printf("%s\n",szTemp); - /*MessageBox (GetActiveWindow(), szTemp+1, "LEGACY", - MB_OK | MB_ICONSTOP);*/ - //wsprintf(szDebug, "Midi subsystem error: %s", szTemp); -} - - -// ---------------- -// I_InitAudioMixer -// ---------------- -#ifdef TESTCODE -void I_InitAudioMixer (void) -{ - UINT cMixerDevs = mixerGetNumDevs(); - CONS_Printf("%d mixer devices available\n", cMixerDevs); -} -#endif - -// ----------- -// I_InitDigMusic -// Startup Digital device for streaming output -// ----------- -void I_InitDigMusic(void) -{ - if (dedicated) - nodigimusic = true; - else - CONS_Printf("I_InitDigMusic()\n"); - -#ifdef FMODSOUND - if (!nodigimusic) - { - // Tails 11-21-2002 - if (FSOUND_GetVersion() < FMOD_VERSION) - { - //I_Error("FMOD Error : You are using the wrong DLL version!\nYou should be using FMOD %s\n", "FMOD_VERSION"); - CONS_Printf("FMOD Error : You are using the wrong DLL version!\nYou should be using FMOD %s\n", "FMOD_VERSION"); - nodigimusic = true; - } - - /* - INITIALIZE - */ -#if 1 - if (!FSOUND_SetHWND(hWndMain)) - { -// I_Error("FMOD(Init,FSOUND_SetHWND): %s\n", FMOD_ErrorString(FSOUND_GetError())); - //FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND); - } - //else -#endif - - if (!FSOUND_Init(44100, 32, FSOUND_INIT_DONTLATENCYADJUST)) - { - //I_Error("FMOD(Init,FSOUND_Init): %s\n", FMOD_ErrorString(FSOUND_GetError())); - CONS_Printf("FMOD(Init,FSOUND_Init): %s\n", FMOD_ErrorString(FSOUND_GetError())); - nodigimusic = true; - } - else - I_AddExitFunc(I_ShutdownDigMusic); - } -#endif -} - -// ----------- -// I_InitMIDIMusic -// Startup Midi device for streaming output -// ----------- -void I_InitMIDIMusic(void) -{ - DWORD idx; - MMRESULT mmrRetVal; - UINT cMidiDevs; - MIDIOUTCAPS MidiOutCaps; - const char *szTechnology; - - bMusicStarted = false; - - if (dedicated) - nomidimusic = true; - else - CONS_Printf("I_InitMIDIMusic()\n"); - - if (nomidimusic) - return; - - // check out number of MIDI devices available - // - cMidiDevs = midiOutGetNumDevs(); - if (!cMidiDevs) - { - CONS_Printf("No MIDI devices available, music is disabled\n"); - nomidimusic = true; - return; - } -#ifdef DEBUGMIDISTREAM - else - { - CONS_Printf("%d MIDI devices available\n", cMidiDevs); - } -#endif - - if (M_CheckParm("-winmidi") && M_IsNextParm()) - uMIDIDeviceID = atoi(M_GetNextParm()); - else - uMIDIDeviceID = MIDI_MAPPER; - - // get MIDI device caps - // - if ((mmrRetVal = midiOutGetDevCaps (uMIDIDeviceID, &MidiOutCaps, sizeof (MIDIOUTCAPS))) != - MMSYSERR_NOERROR) - { - CONS_Printf("midiOutGetCaps FAILED : \n"); - MidiErrorMessageBox (mmrRetVal); - } - else - { - CONS_Printf("MIDI product name: %s\n", MidiOutCaps.szPname); - switch (MidiOutCaps.wTechnology) - { - case MOD_FMSYNTH: szTechnology = "FM Synth"; break; - case MOD_MAPPER: szTechnology = "Microsoft MIDI Mapper"; break; - case MOD_MIDIPORT: szTechnology = "MIDI hardware port"; break; - case MOD_SQSYNTH: szTechnology = "Square wave synthesizer"; break; - case MOD_SYNTH: szTechnology = "Synthesizer"; break; - default: szTechnology = "unknown"; break; - } - CONS_Printf("MIDI technology: %s\n", szTechnology); - CONS_Printf("MIDI caps:\n"); - if (MidiOutCaps.dwSupport & MIDICAPS_CACHE) - CONS_Printf("-Patch caching\n"); - if (MidiOutCaps.dwSupport & MIDICAPS_LRVOLUME) - CONS_Printf("-Separate left and right volume control\n"); - if (MidiOutCaps.dwSupport & MIDICAPS_STREAM) - CONS_Printf("-Direct support for midiStreamOut()\n"); - if (MidiOutCaps.dwSupport & MIDICAPS_VOLUME) - CONS_Printf("-Volume control\n"); - bMidiCanSetVolume = ((MidiOutCaps.dwSupport & MIDICAPS_VOLUME)!=0); - } - -#ifdef TESTCODE - I_InitAudioMixer (); -#endif - - // ---------------------------------------------------------------------- - // Midi2Stream initialization - // ---------------------------------------------------------------------- - - // create event for synch'ing the callback thread to main program thread - // when we will need it - hBufferReturnEvent = CreateEvent(NULL, FALSE, FALSE, - TEXT("SRB2 Midi Playback: Wait For Buffer Return")); - - if (!hBufferReturnEvent) - { - I_GetLastErrorMsgBox(); - nomidimusic = true; - return; - } - - if ((mmrRetVal = midiStreamOpen(&hStream, - &uMIDIDeviceID, - (DWORD)1, (DWORD_PTR)MidiStreamCallback/*NULL*/, - (DWORD)0, - CALLBACK_FUNCTION /*CALLBACK_NULL*/)) != MMSYSERR_NOERROR) - { - CONS_Printf("I_RegisterSong: midiStreamOpen FAILED\n"); - MidiErrorMessageBox(mmrRetVal); - nomidimusic = true; - return; - } - - // stream buffers are initially unallocated (set em NULL) - for (idx = 0; idx < NUM_STREAM_BUFFERS; idx++) - ZeroMemory (&ciStreamBuffers[idx].mhBuffer, sizeof (MIDIHDR)); - // ---------------------------------------------------------------------- - - // register exit code - I_AddExitFunc(I_ShutdownMIDIMusic); - - bMusicStarted = true; -} - -// --------------- -// I_InitMusic -// --------------- -void I_InitMusic(void) -{ - I_InitDigMusic(); - I_InitMIDIMusic(); -} - -// --------------- -// I_ShutdownDigMusic -// --------------- -void I_ShutdownDigMusic(void) -{ - CONS_Printf("I_ShutdownDigMusic: \n"); - -#ifdef FMODSOUND - if (!nodigimusic && FSOUND_GetError() != FMOD_ERR_UNINITIALIZED) - { - if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_CHANNEL_ALLOC && FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) - if (devparm) CONS_Printf("FMOD(Shutdown,Unknown): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (mod) - { - if (FMUSIC_IsPlaying(mod)) - if (!FMUSIC_StopSong(mod)) - if (devparm) CONS_Printf("FMOD(Shutdown,FMUSIC_StopSong): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (!FMUSIC_FreeSong(mod)) - if (devparm) CONS_Printf("FMOD(Shutdown,FMUSIC_FreeSong): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - if (fmus) - { - if (FSOUND_IsPlaying(fsoundchannel)) - if (!FSOUND_Stream_Stop(fmus)) - if (devparm) CONS_Printf("FMOD(Shutdown,FSOUND_Stream_Stop): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (!FSOUND_Stream_Close(fmus)) - if (devparm) CONS_Printf("FMOD(Shutdown,FSOUND_Stream_Close): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - FSOUND_Close(); - remove("fmod.tmp"); // Delete the temp file - //if (!FSOUND_StopSound(FSOUND_ALL)) - //if (FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) CONS_Printf("FMOD(Shutdown,FSOUND_StopSound): %s\n", FMOD_ErrorString(FSOUND_GetError())); - //FMUSIC_StopAllSongs(); - //if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) CONS_Printf("FMOD(Shutdown,FMUSIC_StopAllSongs): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } -#endif -} - -// --------------- -// I_ShutdownMIDIMusic -// --------------- -void I_ShutdownMIDIMusic(void) -{ - DWORD idx; - MMRESULT mmrRetVal; - HGLOBAL lp = NULL; - - CONS_Printf("I_ShutdownMIDIMusic: \n"); - - if (nomidimusic) - return; - - if (!bMusicStarted) - return; - - if (hStream) - { - I_StopSong (SPECIAL_HANDLE_CLEANMIDI); - } - - Mid2StreamConverterCleanup(); - Mid2StreamFreeBuffers(); - - // Free our stream buffers - for (idx = 0; idx < NUM_STREAM_BUFFERS; idx++) - { - if (ciStreamBuffers[idx].mhBuffer.lpData) - { - //GlobalFreePtr(ciStreamBuffers[idx].mhBuffer.lpData); - lp = GlobalPtrHandle(ciStreamBuffers[idx].mhBuffer.lpData); - GlobalUnlock(lp); - GlobalFree(lp); - ciStreamBuffers[idx].mhBuffer.lpData = NULL; - } - } - - if (hStream) - { - if ((mmrRetVal = midiStreamClose(hStream)) != MMSYSERR_NOERROR) - MidiErrorMessageBox(mmrRetVal); - hStream = NULL; - } - - CloseHandle(hBufferReturnEvent); - - bMusicStarted = false; -} - -// --------------- -// I_ShutdownMusic -// --------------- -void I_ShutdownMusic(void) -{ - if (!nodigimusic) - I_ShutdownDigMusic(); - - if (!nomidimusic) - I_ShutdownMIDIMusic(); -} - -// -------------------- -// SetAllChannelVolumes -// Given a percent in tenths of a percent, sets volume on all channels to -// reflect the new value. -// -------------------- -static void SetAllChannelVolumes(DWORD dwVolumePercent) -{ - DWORD dwEvent, dwStatus, dwVol, idx; - MMRESULT mmrRetVal; - - if (!bMidiPlaying) - return; - - for (idx = 0, dwStatus = MIDI_CTRLCHANGE; idx < MAX_MIDI_IN_TRACKS; idx++, dwStatus++) - { - dwVol = (dwVolCache[idx] * dwVolumePercent) / 1000; - //CONS_Printf("channel %d vol %d\n", idx, dwVol); - dwEvent = dwStatus | ((DWORD)MIDICTRL_VOLUME << 8) - | ((DWORD)dwVol << 16); - if ((mmrRetVal = midiOutShortMsg((HMIDIOUT)hStream, dwEvent)) - != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - return; - } - } -} - - -// ---------------- -// I_SetMusicVolume -// Set the midi output volume -// ---------------- -void I_SetMIDIMusicVolume(INT32 volume) -{ - MMRESULT mmrRetVal; - int iVolume; - - if (nomidimusic) - return; - - if (bMidiCanSetVolume) - { - // method A - // current volume is 0-31, we need 0-0xFFFF in each word (left/right channel) - iVolume = (volume << 11) | (volume << 27); - if ((mmrRetVal = midiOutSetVolume ((HMIDIOUT)(size_t)uMIDIDeviceID, iVolume)) != MMSYSERR_NOERROR) - { - CONS_Printf("I_SetMusicVolume: couldn't set volume\n"); - MidiErrorMessageBox(mmrRetVal); - } - } - else - { - // method B - dwVolumePercent = (volume * 1000) / 32; - SetAllChannelVolumes (dwVolumePercent); - } -} - -void I_SetDigMusicVolume(INT32 volume) -{ -#ifdef FMODSOUND - if (volume != -1) - fmodvol = (volume<<3)+(volume>>2); - if (!nodigimusic) - { - if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_CHANNEL_ALLOC && FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) - if (devparm) CONS_Printf("FMOD(Volume,Unknown): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (mod) - { - if (FMUSIC_GetType(mod) != FMUSIC_TYPE_NONE) - { - if (!FMUSIC_SetMasterVolume(mod, fmodvol) && devparm) - CONS_Printf("FMOD(Volume,FMUSIC_SetMasterVolume): %s\n", - FMOD_ErrorString(FSOUND_GetError())); - } - else if (devparm) - CONS_Printf("FMOD(Volume,FMUSIC_GetType): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - if (fmus) - { - if (!FSOUND_SetVolume(fsoundchannel, fmodvol)) - if (devparm) CONS_Printf("FMOD(Volume,FSOUND_SetVolume): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - } -#else - (void)volume; -#endif -} - - -// ---------- -// I_PlaySong -// Note: doesn't use the handle, would be useful to switch between mid's after -// some trigger (would do several RegisterSong, then PlaySong the chosen one) -// ---------- -boolean I_PlaySong(INT32 handle, INT32 bLooping) -{ - MMRESULT mmrRetVal; - - if (nomidimusic) - return false; - -#ifdef DEBUGMIDISTREAM - CONS_Printf("I_PlaySong: looping %d\n", bLooping); -#endif - - // unpause the song first if it was paused - if (bMidiPaused) - I_PauseSong(handle); - - // Clear the status of our callback so it will handle - // MOM_DONE callbacks once more - uCallbackStatus = 0; - bMidiPlaying = FALSE; - if ((mmrRetVal = midiStreamRestart(hStream)) != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - Mid2StreamConverterCleanup(); - Mid2StreamFreeBuffers(); - midiStreamClose(hStream); - //I_Error("I_PlaySong: midiStreamRestart error"); - midiStreamOpen(&hStream, &uMIDIDeviceID, (DWORD)1, - (DWORD_PTR)MidiStreamCallback/*NULL*/, - (DWORD)0, CALLBACK_FUNCTION /*CALLBACK_NULL*/); - } - else bMidiPlaying = TRUE; - bMidiLooped = bLooping; - return bMidiPlaying; -} - - -// ----------- -// I_PauseSong -// calls midiStreamPause() to pause the midi playback -// ----------- -void I_PauseSong (INT32 handle) -{ - (void)handle; -#ifdef FMODSOUND - if (!nodigimusic) - { - if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_CHANNEL_ALLOC && FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) - if (devparm) CONS_Printf("FMOD(Pause,Unknown): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (mod) - { - if (!FMUSIC_GetPaused(mod)) - if (!FMUSIC_SetPaused(mod, true)) - if (devparm) CONS_Printf("FMOD(Pause,FMUSIC_SetPaused): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - if (fmus) - { - if (!FSOUND_GetPaused(fsoundchannel)) - if (!FSOUND_SetPaused(fsoundchannel, true)) - if (devparm) CONS_Printf("FMOD(Pause,FSOUND_SetPaused): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - } -#endif - - if (nomidimusic) - return; - -#ifdef DEBUGMIDISTREAM - CONS_Printf("I_PauseSong: \n"); -#endif - - if (!bMidiPaused) - { - midiStreamPause(hStream); - bMidiPaused = true; - } -} - - -// ------------ -// I_ResumeSong -// un-pause the midi song with midiStreamRestart -// ------------ -void I_ResumeSong (INT32 handle) -{ - (void)handle; -#ifdef FMODSOUND - if (!nodigimusic) - { - if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_CHANNEL_ALLOC && FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) - if (devparm) CONS_Printf("FMOD(Resume,Unknown): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (mod != NULL) - { - if (FMUSIC_GetPaused(mod)) - if (!FMUSIC_SetPaused(mod, false)) - if (devparm) CONS_Printf("FMOD(Resume,FMUSIC_SetPaused): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - if (fmus != NULL) - { - if (FSOUND_GetPaused(fsoundchannel)) - if (!FSOUND_SetPaused(fsoundchannel, false)) - if (devparm) CONS_Printf("FMOD(Resume,FSOUND_SetPaused): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - } -#endif - - if (nomidimusic) - return; - -#ifdef DEBUGMIDISTREAM - CONS_Printf("I_ResumeSong: \n"); -#endif - - if (bMidiPaused) - { - midiStreamRestart(hStream); - bMidiPaused = false; - } -} - - -// ---------- -// I_StopSong -// ---------- -// faB: -1999 is a special handle here, it means we stop the midi when exiting -// Legacy, this will do a midiOutReset() for a more 'sure' midi off. -void I_StopSong(INT32 handle) -{ - MMRESULT mmrRetVal; - - if (nomidimusic) - return; - -#ifdef DEBUGMIDISTREAM - CONS_Printf("I_StopSong: \n"); -#endif - - if (bMidiPlaying || (uCallbackStatus != STATUS_CALLBACKDEAD)) - { - bMidiPlaying = bMidiPaused = FALSE; - if (uCallbackStatus != STATUS_CALLBACKDEAD && - uCallbackStatus != STATUS_WAITINGFOREND) - uCallbackStatus = STATUS_KILLCALLBACK; - - //CONS_Printf("a: %d\n",I_GetTime()); - if ((mmrRetVal = midiStreamStop(hStream)) != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - return; - } - - //faB: if we don't call midiOutReset() seems we have to stop the buffers - // ourselves (or it doesn't play anymore) - if (!bMidiPaused && (handle != SPECIAL_HANDLE_CLEANMIDI)) - { - midiStreamPause(hStream); - } - //CONS_Printf("b: %d\n",I_GetTime()); - else - //faB: this damn call takes 1 second and a half !!! still do it on exit - // to be sure everything midi is cleaned as much as possible - if (handle == SPECIAL_HANDLE_CLEANMIDI) - { - if ((mmrRetVal = midiOutReset((HMIDIOUT)hStream)) != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - return; - } - } - //CONS_Printf("c: %d\n",I_GetTime()); - - // Wait for the callback thread to release this thread, which it will do by - // calling SetEvent() once all buffers are returned to it - if ((devparm) - && (WaitForSingleObject(hBufferReturnEvent, DEBUG_CALLBACK_TIMEOUT) - == WAIT_TIMEOUT)) - { - // Note, this is a risky move because the callback may be genuinely busy, but - // when we're debugging, it's safer and faster than freezing the application, - // which leaves the MIDI device locked up and forces a system reset... - CONS_Printf("Timed out waiting for MIDI callback\n"); - uCallbackStatus = STATUS_CALLBACKDEAD; - } - //CONS_Printf("d: %d\n",I_GetTime()); - } - - if (uCallbackStatus == STATUS_CALLBACKDEAD) - { - uCallbackStatus = 0; - Mid2StreamConverterCleanup(); - Mid2StreamFreeBuffers(); - //faB: we could close the stream here and re-open later to avoid - // a little quirk in mmsystem (see DirectX6 mstream note) - midiStreamClose(hStream); - midiStreamOpen(&hStream, &uMIDIDeviceID, (DWORD)1, - (DWORD_PTR)MidiStreamCallback/*NULL*/, - (DWORD)0, CALLBACK_FUNCTION /*CALLBACK_NULL*/); - } -} - -void I_StopDigSong(void) -{ -#ifdef FMODSOUND - if (!nodigimusic) - { - if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_INVALID_PARAM && FSOUND_GetError() != FMOD_ERR_CHANNEL_ALLOC && FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) - if (devparm) CONS_Printf("FMOD(Stop,Unknown): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (mod) - { - if (FMUSIC_IsPlaying(mod)) - { - if (!FMUSIC_StopSong(mod)) - if (devparm) CONS_Printf("FMOD(Stop,FMUSIC_StopSong): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - } - if (fmus) - { - if (FSOUND_IsPlaying(fsoundchannel)) - { - if (!FSOUND_Stream_Stop(fmus)) - if (devparm) CONS_Printf("FMOD(Stop,FSOUND_Stream_Stop): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - } - //if (!FSOUND_StopSound(FSOUND_ALL)) - //if (FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) CONS_Printf("FMOD(Stop,FSOUND_StopSound): %s\n", FMOD_ErrorString(FSOUND_GetError())); - //FMUSIC_StopAllSongs(); - //if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) CONS_Printf("FMOD(Stop,FMUSIC_StopAllSongs): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } -#endif -} - -void I_UnRegisterSong(INT32 handle) -{ - handle = 0; - if (nomidimusic) - return; - - //faB: we might free here whatever is allocated per-music - // (but we don't cause I hate malloc's) - Mid2StreamConverterCleanup(); - -#ifdef DEBUGMIDISTREAM - CONS_Printf("I_UnregisterSong: \n"); -#endif -} - -int I_SetSongSpeed(unsigned int speed) -{ -#ifdef FMODSOUND - if (music_disabled || nodigimusic) - return 0; //there no music or FMOD is not loaded - - if((!fmus || !FSOUND_IsPlaying(fsoundchannel)) && (!mod || !FMUSIC_IsPlaying(mod))) - return 0; //there no FMOD music playing - - if (speed == 0) - return 1; //yes, we can set the speed - - if (fmus) - { - if (FSOUND_IsPlaying(fsoundchannel) - && !FSOUND_SetFrequency(fsoundchannel,(int)(((float)speed*(float)fsoundfreq)/100.0f))) - { - if (devparm) - CONS_Printf("FMOD(ChangeSpeed,FSOUND_SetFrequency): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - else - return 1; - } - else if (mod) - { - if (FMUSIC_IsPlaying(mod) - && !FMUSIC_SetMasterSpeed(mod,(float)speed/100.0f)) - { - if (devparm) - CONS_Printf("FMOD(ChangeSpeed,FMUSIC_SetMasterSpeed): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - else - return 1; - } -#else - (void)speed; -#endif - return 0; -} - -// Special FMOD support Tails 11-21-2002 -boolean I_StartDigSong(const char *musicname, INT32 looping) -{ -#ifdef FMODSOUND - char filename[9]; - void *data; - int lumpnum; - - if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_CHANNEL_ALLOC && - FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER && FSOUND_GetError() != FMOD_ERR_INVALID_PARAM) - if (devparm) CONS_Printf("FMOD(Start,Unknown): %s\n", FMOD_ErrorString(FSOUND_GetError())); - - if (fmus) - { - if (FSOUND_IsPlaying(fsoundchannel)) - if (!FSOUND_Stream_Stop(fmus)) - if (devparm) CONS_Printf("FMOD(Start,FSOUND_Stream_Stop): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (!FSOUND_Stream_Close(fmus)) - if (devparm) CONS_Printf("FMOD(Start,FSOUND_Stream_Close): %s\n", FMOD_ErrorString(FSOUND_GetError())); - fsoundchannel = -1; - fmus = NULL; - } - if (mod) - { - if (FMUSIC_IsPlaying(mod)) - if (!FMUSIC_StopSong(mod)) - if (devparm) CONS_Printf("FMOD(Start,FMUSIC_StopSong): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (!FMUSIC_FreeSong(mod)) - if (devparm) CONS_Printf("FMOD(Start,FMUSIC_FreeSong): %s\n", FMOD_ErrorString(FSOUND_GetError())); - mod = NULL; - } - //if (!FSOUND_StopSound(FSOUND_ALL)) - //if (FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) CONS_Printf("FMOD(Start,FSOUND_StopSound): %s\n", FMOD_ErrorString(FSOUND_GetError())); - //FMUSIC_StopAllSongs(); - //if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) CONS_Printf("FMOD(Start,FMUSIC_StopAllSongs): %s\n", FMOD_ErrorString(FSOUND_GetError())); - - // Create the filename we need - sprintf(filename, "o_%s", musicname); - - lumpnum = W_CheckNumForName(filename); - - if (lumpnum == -1) - { - // Graue 02-29-2004: don't worry about missing music, there might still be a MIDI - return false; // No music found. Oh well! - } - - data = W_CacheLumpName (filename, PU_CACHE); - - I_SaveMemToFile (data, W_LumpLength(lumpnum), "fmod.tmp"); - - Z_Free(data); - - mod = FMUSIC_LoadSong("fmod.tmp"); - - if (FSOUND_GetError() != FMOD_ERR_NONE) - { - if (FSOUND_GetError() != FMOD_ERR_FILE_FORMAT) - if (devparm) CONS_Printf("FMOD(Start,FMUSIC_LoadSong): %s\n", FMOD_ErrorString(FSOUND_GetError())); - - if (mod) - { - if (FMUSIC_IsPlaying(mod)) - if (!FMUSIC_StopSong(mod)) - if (devparm) CONS_Printf("FMOD(Start,FMUSIC_StopSong): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (!FMUSIC_FreeSong(mod)) - if (devparm) CONS_Printf("FMOD(Start,FMUSIC_FreeSong): %s\n", FMOD_ErrorString(FSOUND_GetError())); - mod = NULL; - } - } - - if (mod) - { - if (!FMUSIC_SetLooping(mod, (signed char)looping)) - { - if (devparm) CONS_Printf("FMOD(Start,FMUSIC_SetLooping): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } -// else if (FMUSIC_GetType(mod) == FMUSIC_TYPE_MOD || FMUSIC_GetType(mod) == FMUSIC_TYPE_S3M) -// { -// if (!FMUSIC_SetPanSeperation(mod, 0.85f)) /* 15% crossover */ -// CONS_Printf("FMOD(Start,FMUSIC_SetPanSeperation): %s\n", FMOD_ErrorString(FSOUND_GetError())); -// } - else if (!FMUSIC_SetPanSeperation(mod, 0.0f)) - { - if (devparm) CONS_Printf("FMOD(Start,FMUSIC_SetPanSeperation): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - } - else - { - fmus = FSOUND_Stream_OpenFile("fmod.tmp", ((looping) ? (FSOUND_LOOP_NORMAL) : (0)),0); - if (fmus == NULL) - { - if (devparm) CONS_Printf("FMOD(Start,FSOUND_Stream_Open): %s\n", FMOD_ErrorString(FSOUND_GetError())); - return false; - } - } - - // Scan the Ogg Vorbis file for the COMMENT= field for a custom loop point - if (fmus && looping) - { - int scan; - char *dataum; - char looplength[64]; - unsigned int loopstart = 0; - int newcount = 0; - const int freq = 44100; - int lumplength = W_LumpLength(lumpnum); - int length = FSOUND_Stream_GetLengthMs(fmus); - - if (length == 0) - { - if (devparm) CONS_Printf("FMOD(Start,FSOUND_Stream_GetLengthMs): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - else - { - //freq = FSOUND_GetFrequency(fsoundchannel); - - data = W_CacheLumpName (filename, PU_CACHE); - - dataum = (char *)data; - - for (scan = 0;scan < lumplength; scan++) - { - if (*dataum++ == 'C'){ - if (*dataum++ == 'O'){ - if (*dataum++ == 'M'){ - if (*dataum++ == 'M'){ - if (*dataum++ == 'E'){ - if (*dataum++ == 'N'){ - if (*dataum++ == 'T'){ - if (*dataum++ == '='){ - if (*dataum++ == 'L'){ - if (*dataum++ == 'O'){ - if (*dataum++ == 'O'){ - if (*dataum++ == 'P'){ - if (*dataum++ == 'P'){ - if (*dataum++ == 'O'){ - if (*dataum++ == 'I'){ - if (*dataum++ == 'N'){ - if (*dataum++ == 'T'){ - if (*dataum++ == '=') - { - - while (*dataum != 1 && newcount != 63) - { - looplength[newcount++] = *dataum++; - } - - looplength[newcount] = '\n'; - - loopstart = atoi(looplength); - } - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - } - - Z_Free(data); - } - - if (loopstart > 0) - { - const unsigned int loopend = (unsigned int)((freq/1000.0f)*length-(freq/1000.0f)); - //const unsigned int loopend = (((freq/2)*length)/500)-8; - if (!FSOUND_Stream_SetLoopPoints(fmus, loopstart, loopend) && devparm) - CONS_Printf("FMOD(Start,FSOUND_Stream_SetLoopPoints): %s\n", - FMOD_ErrorString(FSOUND_GetError())); - } - } - - /* - PLAY SONG - */ - if (mod) - { - if (FMUSIC_PlaySong(mod)) - { - fsoundchannel = -1; - I_SetDigMusicVolume(-1); - return true; - } - else - { - if (devparm) - CONS_Printf("FMOD(Start,FMUSIC_PlaySong): %s\n", - FMOD_ErrorString(FSOUND_GetError())); - return false; - } - } - if (fmus) - { - fsoundchannel = FSOUND_Stream_PlayEx(FSOUND_FREE, fmus, NULL, TRUE); - - if (fsoundchannel == -1) - { - if (devparm) - CONS_Printf("FMOD(Start,FSOUND_Stream_PlayEx): %s\n", - FMOD_ErrorString(FSOUND_GetError())); - return false; - } - else if (!FSOUND_SetPaused(fsoundchannel, FALSE)) - { - if (devparm) - CONS_Printf("FMOD(Start,FSOUND_SetPaused): %s\n", - FMOD_ErrorString(FSOUND_GetError())); - return false; - } - - I_SetDigMusicVolume(-1); - fsoundfreq = FSOUND_GetFrequency(fsoundchannel); - return true; - } -#else - (void)musicname; - (void)looping; -#endif - return false; - -///////////////////////////////////////////////////////////////////////////////// -} - -// -------------- -// I_RegisterSong -// Prepare a song for playback -// - setup midi stream buffers, and activate the callback procedure -// which will continually fill the buffers with new data -// -------------- - -INT32 I_RegisterSong(void *data, int len) -{ - char *pMidiFileData = NULL; // MIDI music buffer to be played or NULL - - if (nomidimusic) - return 1; - if (!data || !len) - return 0; - -#ifdef DEBUGMIDISTREAM - CONS_Printf("I_RegisterSong: \n"); -#endif - // check for MID format file - if (!memcmp(data, "MThd", 4)) - pMidiFileData = data; - else - { - CONS_Printf("Music lump is not MID music format\n"); - return 0; - } - -#ifdef DEBUGMIDISTREAM - I_SaveMemToFile(pMidiFileData, len, "debug.mid"); -#endif - - // setup midi stream buffer - if (StreamBufferSetup((LPBYTE)pMidiFileData, len)) - { - Mid2StreamConverterCleanup(); - I_Error("I_RegisterSong: StreamBufferSetup FAILED"); - } - - return 1; -} - -// ----------------- -// StreamBufferSetup -// This function uses the filename stored in the global character array to -// open a MIDI file. Then it goes about converting at least the first part of -// that file into a midiStream buffer for playback. -// ----------------- - -// ----------------- -// StreamBufferSetup -// - returns TRUE if a problem occurs -// ----------------- -static BOOL StreamBufferSetup(LPBYTE pMidiData, size_t iMidiSize) -{ - MMRESULT mmrRetVal; - MIDIPROPTIMEDIV mptd; - BOOL bFoundEnd = FALSE; - int dwConvertFlag, nChkErr, idx; - -#ifdef DEBUGMIDISTREAM - if (hStream == NULL) - I_Error("StreamBufferSetup: hStream is NULL!"); -#endif - - // pause midi stream before manipulating the buffers - midiStreamPause(hStream); - - // allocate the stream buffers (only once) - for (idx = 0; idx < NUM_STREAM_BUFFERS; idx++) - { - ciStreamBuffers[idx].mhBuffer.dwBufferLength = OUT_BUFFER_SIZE; - if (!ciStreamBuffers[idx].mhBuffer.lpData) - { - ciStreamBuffers[idx].mhBuffer.lpData = GlobalAllocPtr(GHND, OUT_BUFFER_SIZE); - if (!ciStreamBuffers[idx].mhBuffer.lpData) - return FALSE; - } - } - - // returns TRUE in case of conversion error - if (Mid2StreamConverterInit(pMidiData, iMidiSize)) - return TRUE; - - // Initialize the volume cache array to some pre-defined value - for (idx = 0; idx < MAX_MIDI_IN_TRACKS; idx++) - dwVolCache[idx] = VOL_CACHE_INIT; - - mptd.cbStruct = sizeof (mptd); - mptd.dwTimeDiv = ifs.dwTimeDivision; - if ((mmrRetVal = midiStreamProperty(hStream, (LPBYTE)&mptd, MIDIPROP_SET|MIDIPROP_TIMEDIV)) - != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - return TRUE; - } - - nEmptyBuffers = 0; - dwConvertFlag = CONVERTF_RESET; - - for (nCurrentBuffer = 0; nCurrentBuffer < NUM_STREAM_BUFFERS; nCurrentBuffer++) - { - // Tell the converter to convert up to one entire buffer's length of output - // data. Also, set a flag so it knows to reset any saved state variables it - // may keep from call to call. - ciStreamBuffers[nCurrentBuffer].dwStartOffset = 0; - ciStreamBuffers[nCurrentBuffer].dwMaxLength = OUT_BUFFER_SIZE; - ciStreamBuffers[nCurrentBuffer].tkStart = 0; - ciStreamBuffers[nCurrentBuffer].bTimesUp = FALSE; - - if ((nChkErr = Mid2StreamConvertToBuffer(dwConvertFlag, &ciStreamBuffers[nCurrentBuffer])) - != CONVERTERR_NOERROR) - { - if (nChkErr == CONVERTERR_DONE) - bFoundEnd = TRUE; - else - { - CONS_Printf("StreamBufferSetup: initial conversion pass failed\n"); - return TRUE; - } - } - ciStreamBuffers[nCurrentBuffer].mhBuffer.dwBytesRecorded - = ciStreamBuffers[nCurrentBuffer].dwBytesRecorded; - - if (!bBuffersPrepared) - { - if ((mmrRetVal = midiOutPrepareHeader((HMIDIOUT)hStream, - &ciStreamBuffers[nCurrentBuffer].mhBuffer, sizeof (MIDIHDR))) != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - return TRUE; - } - } - if ((mmrRetVal = midiStreamOut(hStream, &ciStreamBuffers[nCurrentBuffer].mhBuffer, - sizeof (MIDIHDR))) != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - break; - } - dwConvertFlag = 0; - - if (bFoundEnd) - break; - } - - bBuffersPrepared = TRUE; - nCurrentBuffer = 0; - - // MIDI volume - dwVolumePercent = (cv_midimusicvolume.value * 1000) / 32; - if (hStream) - SetAllChannelVolumes(dwVolumePercent); - - return FALSE; -} - -// ---------------- -// SetChannelVolume -// Call here delayed by MIDI stream callback, to adapt the volume event of the -// midi stream to our own set volume percentage. -// ---------------- -void I_SetMidiChannelVolume(DWORD dwChannel, DWORD dwVolumePercent) -{ - DWORD dwEvent, dwVol; - MMRESULT mmrRetVal; - - if (!bMidiPlaying) - return; - - dwVol = (dwVolCache[dwChannel] * dwVolumePercent) / 1000; - dwEvent = MIDI_CTRLCHANGE|dwChannel|((DWORD)MIDICTRL_VOLUME << 8)|((DWORD)dwVol << 16); - if ((mmrRetVal = midiOutShortMsg((HMIDIOUT)hStream, dwEvent)) != MMSYSERR_NOERROR) - { -#ifdef DEBUGMIDISTREAM - MidiErrorMessageBox(mmrRetVal); -#endif - return; - } -} - -// ------------------ -// MidiStreamCallback -// This is the callback handler which continually refills MIDI data buffers -// as they're returned to us from the audio subsystem. -// ------------------ -static void CALLBACK MidiStreamCallback(HMIDIIN hMidi, UINT uMsg, DWORD dwInstance, - DWORD dwParam1, DWORD dwParam2) -{ - MMRESULT mmrRetVal; - int nChkErr; - MIDIEVENT* pme; - MIDIHDR* pmh; - - hMidi = NULL; - dwParam1 = dwParam2 = dwInstance = 0; - switch (uMsg) - { - case MOM_DONE: - // dwParam1 is LPMIDIHDR - if (uCallbackStatus == STATUS_CALLBACKDEAD) - return; - - nEmptyBuffers++; - - // we reached end of song, but we wait until all the buffers are returned - if (uCallbackStatus == STATUS_WAITINGFOREND) - { - if (nEmptyBuffers < NUM_STREAM_BUFFERS) - return; - else - { - // stop the song when end reached (was not looping) - uCallbackStatus = STATUS_CALLBACKDEAD; - SetEvent(hBufferReturnEvent); - I_StopSong(0); - return; - } - } - - // This flag is set whenever the callback is waiting for all buffers to come back. - if (uCallbackStatus == STATUS_KILLCALLBACK) - { - // Count NUM_STREAM_BUFFERS-1 being returned for the last time - if (nEmptyBuffers < NUM_STREAM_BUFFERS) - return; - // Then send a stop message when we get the last buffer back... - else - { - // Change the status to callback dead - uCallbackStatus = STATUS_CALLBACKDEAD; - SetEvent(hBufferReturnEvent); - return; - } - } - - dwProgressBytes += ciStreamBuffers[nCurrentBuffer].mhBuffer.dwBytesRecorded; - - // ------------------------------------------------- - // Fill an available buffer with audio data again... - // ------------------------------------------------- - - if (bMidiPlaying && nEmptyBuffers) - { - ciStreamBuffers[nCurrentBuffer].dwStartOffset = 0; - ciStreamBuffers[nCurrentBuffer].dwMaxLength = OUT_BUFFER_SIZE; - ciStreamBuffers[nCurrentBuffer].tkStart = 0; - ciStreamBuffers[nCurrentBuffer].dwBytesRecorded = 0; - ciStreamBuffers[nCurrentBuffer].bTimesUp = FALSE; - - if ((nChkErr = Mid2StreamConvertToBuffer(0, &ciStreamBuffers[nCurrentBuffer])) - != CONVERTERR_NOERROR) - { - if (nChkErr == CONVERTERR_DONE) - { - // Don't include this one in the count - uCallbackStatus = STATUS_WAITINGFOREND; - return; - } - else - { - // We're not in the main thread, so we can't call I_Error() now. - // Log the error message out, and post exit message. - CONS_Printf("MidiStreamCallback(): conversion pass failed!\n"); - PostMessage(hWndMain, WM_CLOSE, 0, 0); - return; - } - } - - ciStreamBuffers[nCurrentBuffer].mhBuffer.dwBytesRecorded - = ciStreamBuffers[nCurrentBuffer].dwBytesRecorded; - - if ((mmrRetVal = midiStreamOut(hStream, &ciStreamBuffers[nCurrentBuffer].mhBuffer, - sizeof (MIDIHDR))) != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - Mid2StreamConverterCleanup(); - return; - } - - nCurrentBuffer = (nCurrentBuffer + 1) % NUM_STREAM_BUFFERS; - nEmptyBuffers--; - } - - break; - case MOM_POSITIONCB: - pmh = (MIDIHDR*)(size_t)dwParam1; - pme = (MIDIEVENT*)(pmh->lpData + pmh->dwOffset); - if (MIDIEVENT_TYPE(pme->dwEvent) == MIDI_CTRLCHANGE) - { -#ifdef DEBUGMIDISTREAM - if (MIDIEVENT_DATA1(pme->dwEvent) == MIDICTRL_VOLUME_LSB) - { - CONS_Printf("Got an LSB volume event\n"); - PostMessage(hWndMain, WM_CLOSE, 0, 0); // can't I_Error() here - break; - } -#endif - // this is meant to respond to our own intention, from mid2strm.c - if (MIDIEVENT_DATA1(pme->dwEvent) != MIDICTRL_VOLUME) - break; - - // Mask off the channel number and cache the volume data byte - dwVolCache[MIDIEVENT_CHANNEL(pme->dwEvent)] = MIDIEVENT_VOLUME(pme->dwEvent); - // call SetChannelVolume() later to adjust MIDI volume control message to our - // own current volume level. - PostMessage(hWndMain, WM_MSTREAM_UPDATEVOLUME, - MIDIEVENT_CHANNEL(pme->dwEvent), 0L); - } - break; - default: - break; - } - - return; -} - -// --------------------- -// Mid2StreamFreeBuffers -// This function unprepares and frees all our buffers -- something we must -// do to work around a bug in MMYSYSTEM that prevents a device from playing -// back properly unless it is closed and reopened after each stop. -// --------------------- -static void Mid2StreamFreeBuffers(void) -{ - DWORD idx; - MMRESULT mmrRetVal; - - if (bBuffersPrepared) - { - for (idx = 0; idx < NUM_STREAM_BUFFERS; idx++) - { - if ((mmrRetVal = midiOutUnprepareHeader((HMIDIOUT)hStream, - &ciStreamBuffers[idx].mhBuffer, sizeof (MIDIHDR))) != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - } - } - bBuffersPrepared = FALSE; - } - - // Don't free the stream buffers here, but rather allocate them once at startup, - // and free them at shutdown. -} diff --git a/src/win32ce/win_sys.c b/src/win32ce/win_sys.c deleted file mode 100644 index 3b6a472587cc161f214736005c48df406dde9925..0000000000000000000000000000000000000000 --- a/src/win32ce/win_sys.c +++ /dev/null @@ -1,3542 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief win32 system i/o -/// -/// Startup & Shutdown routines for music,sound,timer,keyboard,... -/// Signal handler to trap errors and exit cleanly. - -#include "../doomdef.h" -#include <stdlib.h> -#include <signal.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <io.h> -#include <stdarg.h> -#include <direct.h> - -#include <mmsystem.h> - -#include "../m_misc.h" -#include "../i_video.h" -#include "../i_sound.h" -#include "../i_system.h" - -#include "../d_net.h" -#include "../g_game.h" - -#include "../d_main.h" - -#include "../m_argv.h" - -#include "../w_wad.h" -#include "../z_zone.h" -#include "../g_input.h" - -#include "../keys.h" - -#include "../screen.h" - -// Wheel support for Win95/WinNT3.51 -#include <zmouse.h> - -// Taken from Win98/NT4.0 -#ifndef SM_MOUSEWHEELPRESENT -#define SM_MOUSEWHEELPRESENT 75 -#endif - -#ifndef MSH_MOUSEWHEEL -#ifdef UNICODE -#define MSH_MOUSEWHEEL L"MSWHEEL_ROLLMSG" -#else -#define MSH_MOUSEWHEEL "MSWHEEL_ROLLMSG" -#endif -#endif - -#include "win_main.h" -#include "../i_joy.h" - -#define DIRECTINPUT_VERSION 0x700 -// Force dinput.h to generate old DX3 headers. -#define DXVERSION_NTCOMPATIBLE 0x0300 -#include <dinput.h> - -#include "fabdxlib.h" - -#ifdef __DEBUG__ -#undef NDEBUG -#endif - -/// \brief max number of joystick buttons -#define JOYBUTTONS_MAX 32 // rgbButtons[32] -/// \brief max number of joystick button events -#define JOYBUTTONS_MIN min((JOYBUTTONS),(JOYBUTTONS_MAX)) - -/// \brief max number of joysick axies -#define JOYAXISSET_MAX 4 // (lX, lY), (lZ,lRx), (lRy, lRz), rglSlider[2] is very diff -/// \brief max number ofjoystick axis events -#define JOYAXISSET_MIN min((JOYAXISSET),(JOYAXISSET_MAX)) - -/// \brief max number of joystick hats -#define JOYHATS_MAX 4 // rgdwPOV[4]; -/// \brief max number of joystick hat events -#define JOYHATS_MIN min((JOYHATS),(JOYHATS_MAX)) - -/// \brief max number of mouse buttons -#define MOUSEBUTTONS_MAX 8 // 8 bit of BYTE and DIMOFS_BUTTON7 -/// \brief max number of muse button events -#define MOUSEBUTTONS_MIN min((MOUSEBUTTONS),(MOUSEBUTTONS_MAX)) - -// ================== -// DIRECT INPUT STUFF -// ================== -BOOL bDX0300; // if true, we created a DirectInput 0x0300 version -static LPDIRECTINPUT lpDI = NULL; -static LPDIRECTINPUTDEVICE lpDIK = NULL; // Keyboard -static LPDIRECTINPUTDEVICE lpDIM = NULL; // mice -static LPDIRECTINPUTDEVICE lpDIJ = NULL; // joystick 1P -static LPDIRECTINPUTEFFECT lpDIE[NumberofForces]; // joystick 1Es -static LPDIRECTINPUTDEVICE2 lpDIJA = NULL; // joystick 1I -static LPDIRECTINPUTDEVICE lpDIJ2 = NULL; // joystick 2P -static LPDIRECTINPUTEFFECT lpDIE2[NumberofForces]; // joystick 1Es -static LPDIRECTINPUTDEVICE2 lpDIJ2A = NULL;// joystick 2I - -// Do not execute cleanup code more than once. See Shutdown_xxx() routines. -UINT8 graphics_started = 0; -UINT8 keyboard_started = 0; -UINT8 sound_started = 0; -static boolean mouse_enabled = false; -static boolean joystick_detected = false; -static boolean joystick2_detected = false; - -static void I_ShutdownKeyboard(void); -static void I_GetKeyboardEvents(void); -static void I_ShutdownJoystick(void); -static void I_ShutdownJoystick2 (void); - -static boolean entering_con_command = false; - -// -// Why would this be system specific?? hmmmm.... -// -// it is for virtual reality system, next incoming feature :) -static ticcmd_t emptycmd; -ticcmd_t *I_BaseTiccmd(void) -{ - return &emptycmd; -} - -static ticcmd_t emptycmd2; -ticcmd_t *I_BaseTiccmd2(void) -{ - return &emptycmd2; -} - -// Allocates the base zone memory, -// this function returns a valid pointer and size, -// else it should interrupt the program immediately. -// -// now checks if mem could be allocated, this is still -// prehistoric... there's a lot to do here: memory locking, detection -// of win95 etc... -// - -BOOL win9x; - -/** \brief WinNT system platform -*/ -static BOOL winnt; - -static void I_DetectWin9x(void) -{ - OSVERSIONINFO osvi; - - osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); - GetVersionEx(&osvi); - - winnt = (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT); - // 95 or 98 what the hell - win9x = true; -} - -// return free and total memory in the system -UINT32 I_GetFreeMem(UINT32* total) -{ - MEMORYSTATUS info; - - info.dwLength = sizeof (MEMORYSTATUS); - GlobalMemoryStatus(&info); - if (total) - *total = (ULONG)info.dwTotalPhys; - return (ULONG)info.dwAvailPhys; -} - -// --------- -// I_Profile -// Two little functions to profile our code using the high resolution timer -// --------- -static LARGE_INTEGER ProfileCount; -void I_BeginProfile(void) -{ - if (!QueryPerformanceCounter(&ProfileCount)) - I_Error("I_BeginProfile failed"); // can't profile without the high res timer -} - -// we're supposed to use this to measure very small amounts of time, -// that's why we return a DWORD and not a 64bit value -DWORD I_EndProfile(void) -{ - LARGE_INTEGER CurrTime; - DWORD ret; - if (!QueryPerformanceCounter (&CurrTime)) - I_Error("I_EndProfile failed"); - if (CurrTime.QuadPart - ProfileCount.QuadPart > (LONGLONG)0xFFFFFFFFUL) - I_Error("I_EndProfile overflow"); - ret = (DWORD)(CurrTime.QuadPart - ProfileCount.QuadPart); - // we can call I_EndProfile() several time, I_BeginProfile() need be called just once - ProfileCount = CurrTime; - - return ret; -} - -// --------- -// I_GetTime -// Use the High Resolution Timer if available, -// else use the multimedia timer which has 1 millisecond precision on Windowz 95, -// but lower precision on Windows NT -// --------- -static long hacktics = 0; // used locally for keyboard repeat keys -static DWORD starttickcount = 0; // hack for win2k time bug - -tic_t I_GetTime(void) -{ - tic_t newtics = 0; - - if (!starttickcount) // high precision timer - { - LARGE_INTEGER currtime; // use only LowPart if high resolution counter is not available - static LARGE_INTEGER basetime = {{0, 0}}; - - // use this if High Resolution timer is found - static LARGE_INTEGER frequency; - - if (!basetime.LowPart) - { - if (!QueryPerformanceFrequency(&frequency)) - frequency.QuadPart = 0; - else - QueryPerformanceCounter(&basetime); - } - - if (frequency.LowPart && QueryPerformanceCounter(&currtime)) - { - newtics = (int)((currtime.QuadPart - basetime.QuadPart) * TICRATE - / frequency.QuadPart); - } - else - { - currtime.LowPart = timeGetTime(); - if (!basetime.LowPart) - basetime.LowPart = currtime.LowPart; - newtics = ((currtime.LowPart - basetime.LowPart)/(1000/TICRATE)); - } - } - else - newtics = (GetTickCount() - starttickcount)/(1000/TICRATE); - - hacktics = newtics; // a local counter for keyboard repeat key - return newtics; -} - - -void I_Sleep(void) -{ - if (cv_sleep.value != -1) - Sleep(cv_sleep.value); -} - - -// should move to i_video -void I_WaitVBL(INT32 count) -{ - count = 0; -} - -// this is probably to activate the 'loading' disc icon -// it should set a flag, that I_FinishUpdate uses to know -// whether it draws a small 'loading' disc icon on the screen or not -// -// also it should explicitly draw the disc because the screen is -// possibly not refreshed while loading -// -void I_BeginRead(void) {} - -// see above, end the 'loading' disc icon, set the flag false -// -void I_EndRead(void) {} - -// =========================================================================================== -// EVENTS -// =========================================================================================== -static inline BOOL I_ReadyConsole(HANDLE ci) -{ - DWORD gotinput; - if (ci == (HANDLE)-1) return FALSE; - if (WaitForSingleObject(ci,0) != WAIT_OBJECT_0) return FALSE; - if (GetFileType(ci) != FILE_TYPE_CHAR) return FALSE; - return (GetNumberOfConsoleInputEvents(ci, &gotinput) && gotinput); -} - -static inline VOID I_GetConsoleEvents(VOID) -{ - event_t ev = {0,0,0,0}; - HANDLE ci = GetStdHandle(STD_INPUT_HANDLE); - HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO CSBI; - INPUT_RECORD input; - DWORD t; - - while (I_ReadyConsole(ci) && ReadConsoleInput(ci, &input, 1, &t) && t) - { - memset(&ev,0x00,sizeof (ev)); - switch (input.EventType) - { - case KEY_EVENT: - if (input.Event.KeyEvent.bKeyDown) - { - ev.type = ev_console; - entering_con_command = true; - switch (input.Event.KeyEvent.wVirtualKeyCode) - { - case VK_ESCAPE: - case VK_TAB: - ev.data1 = KEY_NULL; - break; - case VK_SHIFT: - ev.data1 = KEY_SHIFT; - break; - case VK_RETURN: - entering_con_command = false; - // Fall through. - default: - ev.data1 = MapVirtualKey(input.Event.KeyEvent.wVirtualKeyCode,2); // convert in to char - } - if (co != (HANDLE)-1 && GetFileType(co) == FILE_TYPE_CHAR) - { - if (ev.data1 && ev.data1 != KEY_SHIFT) - { -#ifdef _UNICODE - WriteConsole(co, &input.Event.KeyEvent.uChar.UnicodeChar, 1, &t, NULL); -#else - WriteConsole(co, &input.Event.KeyEvent.uChar.AsciiChar, 1, &t, NULL); -#endif - } - if (input.Event.KeyEvent.wVirtualKeyCode == VK_BACK - && GetConsoleScreenBufferInfo(co,&CSBI)) - { - WriteConsoleOutputCharacterA(co, " ",1, CSBI.dwCursorPosition, &t); - } - } - } - else - { - ev.type = ev_keyup; - switch (input.Event.KeyEvent.wVirtualKeyCode) - { - case VK_SHIFT: - ev.data1 = KEY_SHIFT; - break; - default: - break; - } - } - if (ev.data1) D_PostEvent(&ev); - break; - case MOUSE_EVENT: - case WINDOW_BUFFER_SIZE_EVENT: - case MENU_EVENT: - case FOCUS_EVENT: - break; - } - } -} - -// ---------- -// I_GetEvent -// Post new events for all sorts of user-input -// ---------- -void I_GetEvent(void) -{ - I_GetConsoleEvents(); - I_GetKeyboardEvents(); - I_GetMouseEvents(); - I_GetJoystickEvents(); - I_GetJoystick2Events(); -} - -// ---------- -// I_OsPolling -// ---------- -void I_OsPolling(void) -{ - MSG msg; - HANDLE ci = GetStdHandle(STD_INPUT_HANDLE); - - // we need to dispatch messages to the window - // so the window procedure can respond to messages and PostEvent() for keys - // during D_SRB2Main startup. - // this one replaces the main loop of windows since I_OsPolling is called in the main loop - do - { - while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) - { - if (GetMessage(&msg, NULL, 0, 0)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - else // winspec : this is quit message - I_Quit(); - } - if (!appActive && !netgame && !I_ReadyConsole(ci)) - WaitMessage(); - } while (!appActive && !netgame && !I_ReadyConsole(ci)); - - // this is called by the network synchronization, - // check keys and allow escaping - I_GetEvent(); - - // reset "emulated keys" - gamekeydown[KEY_MOUSEWHEELUP] = 0; - gamekeydown[KEY_MOUSEWHEELDOWN] = 0; -} - -// =========================================================================================== -// TIMER -// =========================================================================================== - -static void I_ShutdownTimer(void) -{ - timeEndPeriod(1); -} - -// -// Installs the timer interrupt handler with timer speed as TICRATE. -// -#define TIMER_ID 1 -#define TIMER_RATE (1000/TICRATE) -void I_StartupTimer(void) -{ - // for win2k time bug - if (M_CheckParm("-gettickcount")) - { - starttickcount = GetTickCount(); - CONS_Printf("Using GetTickCount()\n"); - } - timeBeginPeriod(1); - I_AddExitFunc(I_ShutdownTimer); -} - -// =========================================================================================== -// EXIT CODE, ERROR HANDLING -// =========================================================================================== - -static int errorcount = 0; // phuck recursive errors -static int shutdowning = false; - -// -// Used to trap various signals, to make sure things get shut down cleanly. -// -#ifdef NDEBUG -static void signal_handler(int num) -{ - //static char msg[] = "oh no! back to reality!\r\n"; - const char *sigmsg; - char sigdef[64]; - - D_QuitNetGame(); // Fix server freezes - I_ShutdownSystem(); - - switch (num) - { - case SIGINT: - sigmsg = "interrupt"; - break; - case SIGILL: - sigmsg = "illegal instruction - invalid function image"; - break; - case SIGFPE: - sigmsg = "floating point exception"; - break; - case SIGSEGV: - sigmsg = "segment violation"; - break; - case SIGTERM: - sigmsg = "software termination signal from kill"; - break; - case SIGBREAK: - sigmsg = "Ctrl-Break sequence"; - break; - case SIGABRT: - sigmsg = "abnormal termination triggered by abort call"; - break; - default: - sprintf(sigdef, "signal number %d", num); - sigmsg = sigdef; - } - -#ifdef LOGMESSAGES - if (logstream != INVALID_HANDLE_VALUE) - { - I_OutputMsg("signal_handler() error: %s\r\n", sigmsg); - CloseHandle(logstream); - logstream = INVALID_HANDLE_VALUE; - } -#endif - - MessageBoxA(hWndMain, va("signal_handler(): %s", sigmsg), "SRB2 error", MB_OK|MB_ICONERROR); - - signal(num, SIG_DFL); // default signal action - raise(num); -} -#endif - -// -// put an error message (with format) on stderr -// -void I_OutputMsg(const char *fmt, ...) -{ - HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD bytesWritten; - va_list argptr; - char txt[8192]; - - va_start(argptr,fmt); - vsprintf(txt, fmt, argptr); - va_end(argptr); - - OutputDebugStringA(txt); - if (co != (HANDLE)-1) - { - if (GetFileType(co) == FILE_TYPE_CHAR) - { - static COORD coordNextWrite = {0,0}; - char *oldLines = NULL; - DWORD oldLength = 0; - CONSOLE_SCREEN_BUFFER_INFO csbi; - - // Save the lines that we're going to obliterate. - GetConsoleScreenBufferInfo(co, &csbi); - oldLength = csbi.dwSize.X * (csbi.dwCursorPosition.Y - coordNextWrite.Y) + csbi.dwCursorPosition.X - coordNextWrite.X; - - if(oldLength > 0) - { - char *blank = malloc(oldLength); - oldLines = malloc(oldLength); - if(!oldLines || !blank) return; - - ReadConsoleOutputCharacterA(co, oldLines, oldLength, coordNextWrite, &bytesWritten); - - // Move to where we what to print - which is where we would've been, - // had console input not been in the way, - SetConsoleCursorPosition(co, coordNextWrite); - - // Blank out. - memset(blank, ' ', oldLength); - WriteConsoleA(co, blank, oldLength, &bytesWritten, NULL); - free(blank); - - // And back to where we want to print again. - SetConsoleCursorPosition(co, coordNextWrite); - } - - // Actually write the string now! - WriteConsoleA(co, txt, (DWORD)strlen(txt), &bytesWritten, NULL); - - // Next time, output where we left off. - GetConsoleScreenBufferInfo(co, &csbi); - coordNextWrite = csbi.dwCursorPosition; - - // Restore what was overwritten. - if(oldLines && entering_con_command) - { - WriteConsoleA(co, oldLines, oldLength, &bytesWritten, NULL); - free(oldLines); - } - } - else // Redirected to a file. - WriteFile(co, txt, (DWORD)strlen(txt), &bytesWritten, NULL); - } - -#ifdef LOGMESSAGES - if (logstream != (HANDLE)-1) - WriteFile (logstream, txt, (DWORD)strlen(txt), &bytesWritten, NULL); -#endif -} - -// display error messy after shutdowngfx -// -void I_Error(const char *error, ...) -{ - va_list argptr; - char txt[8192]; - - // added 11-2-98 recursive error detecting - if (shutdowning) - { - errorcount++; - // try to shutdown each subsystem separately - if (errorcount == 5) - I_ShutdownGraphics(); - if (errorcount == 6) - I_ShutdownSystem(); - if (errorcount == 7) - { - M_SaveConfig(NULL); - G_SaveGameData(); - } - if (errorcount > 20) - { - // Don't print garbage - va_start(argptr,error); - vsprintf(txt, error, argptr); - va_end(argptr); - - MessageBoxA(hWndMain, txt, "SRB2 Recursive Error", MB_OK|MB_ICONERROR); - exit(-1); // recursive errors detected - } - } - shutdowning = true; - - // put message to stderr - va_start(argptr, error); - wvsprintfA(txt, error, argptr); - va_end(argptr); - - CONS_Printf("I_Error(): %s\n", txt); - - // uncomment this line to print to stderr as well - //wsprintf(stderr, "I_Error(): %s\n", txt); - - // saving one time is enough! - if (!errorcount) - { - M_SaveConfig(NULL); // save game config, cvars.. - G_SaveGameData(); - } - - // save demo, could be useful for debug - // NOTE: demos are normally not saved here. - if (demorecording) - G_CheckDemoStatus(); - - D_QuitNetGame(); - - // shutdown everything that was started - I_ShutdownSystem(); - -#ifdef LOGMESSAGES - if (logstream != INVALID_HANDLE_VALUE) - { - CloseHandle(logstream); - logstream = INVALID_HANDLE_VALUE; - } -#endif - - MessageBoxA(hWndMain, txt, "SRB2 Error", MB_OK|MB_ICONERROR); - - exit(-1); -} - -static inline VOID ShowEndTxt(HANDLE co) -{ - int i; - UINT16 j, att = 0; - int nlflag = 1; - CONSOLE_SCREEN_BUFFER_INFO backupcon; - COORD resizewin = {80,-1}; - DWORD bytesWritten; - CHAR let = 0; - UINT16 *text; - void *data; - int endoomnum = W_GetNumForName("ENDOOM"); - //HANDLE ci = GetStdHandle(STD_INPUT_HANDLE); - - /* get the lump with the text */ - data = text = W_CacheLumpNum(endoomnum, PU_CACHE); - - backupcon.wAttributes = FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE; // Just in case - GetConsoleScreenBufferInfo(co, &backupcon); //Store old state - resizewin.Y = backupcon.dwSize.Y; - if (backupcon.dwSize.X < resizewin.X) - SetConsoleScreenBufferSize(co, resizewin); - - for (i = 1; i <= 80*25; i++) // print 80x25 text and deal with the attributes too - { - j = (UINT16)(*text >> 8); // attribute first - if (j != att) // attribute changed? - { - att = j; // save current attribute - SetConsoleTextAttribute(co, j); //set fg and bg color for buffer - } - - let = (char)(*text++ & 0xff); // now the text - WriteConsoleA(co, &let, 1, &bytesWritten, NULL); - - if (nlflag && !(i % 80) && backupcon.dwSize.X > resizewin.X) // do we need a nl? - { - att = backupcon.wAttributes; - SetConsoleTextAttribute(co, att); // all attributes off - WriteConsoleA(co, "\n", 1, &bytesWritten, NULL); - } - } - SetConsoleTextAttribute(co, backupcon.wAttributes); // all attributes off - //if (nlflag) - // WriteConsoleA(co, "\n", 1, &bytesWritten, NULL); - - getchar(); //pause! - - Z_Free(data); -} - - -// -// I_Quit: shutdown everything cleanly, in reverse order of Startup. -// -void I_Quit(void) -{ - HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); - // when recording a demo, should exit using 'q', - // but sometimes we forget and use Alt+F4, so save here too. - if (demorecording) - G_CheckDemoStatus(); - - M_SaveConfig(NULL); // save game config, cvars.. - G_SaveGameData(); - - // maybe it needs that the ticcount continues, - // or something else that will be finished by I_ShutdownSystem(), - // so do it before. - D_QuitNetGame(); - - // shutdown everything that was started - I_ShutdownSystem(); - - if (shutdowning || errorcount) - I_Error("Error detected (%d)", errorcount); - -#ifdef LOGMESSAGES - if (logstream != INVALID_HANDLE_VALUE) - { - I_OutputMsg("I_Quit(): end of logstream.\r\n"); - CloseHandle(logstream); - logstream = INVALID_HANDLE_VALUE; - } -#endif - if (!M_CheckParm("-noendtxt") && W_CheckNumForName("ENDOOM")!=-1 - && co != INVALID_HANDLE_VALUE && GetFileType(co) == FILE_TYPE_CHAR) - { - printf("\r"); - ShowEndTxt(co); - } - fflush(stderr); - exit(0); -} - -// -------------------------------------------------------------------------- -// I_ShowLastError -// Displays a GetLastError() error message in a MessageBox -// -------------------------------------------------------------------------- -void I_GetLastErrorMsgBox(void) -{ - LPSTR lpMsgBuf = NULL; - - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, - NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - lpMsgBuf, 0, NULL); - - // Display the string. - MessageBoxA(NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION); - - // put it in console too and log if any - CONS_Printf("Error: %s\n", lpMsgBuf); - - // Free the buffer. - LocalFree(lpMsgBuf); -} - -// =========================================================================================== -// CLEAN STARTUP & SHUTDOWN HANDLING, JUST CLOSE EVERYTHING YOU OPENED. -// =========================================================================================== -// -// -static quitfuncptr quit_funcs[MAX_QUIT_FUNCS] = -{ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; - -// Adds a function to the list that need to be called by I_SystemShutdown(). -// -void I_AddExitFunc(void (*func)()) -{ - int c; - - for (c = 0; c < MAX_QUIT_FUNCS; c++) - { - if (!quit_funcs[c]) - { - quit_funcs[c] = func; - break; - } - } -} - -// Removes a function from the list that need to be called by I_SystemShutdown(). -// -void I_RemoveExitFunc(void (*func)()) -{ - int c; - - for (c = 0; c < MAX_QUIT_FUNCS; c++) - { - if (quit_funcs[c] == func) - { - while (c < MAX_QUIT_FUNCS - 1) - { - quit_funcs[c] = quit_funcs[c+1]; - c++; - } - quit_funcs[MAX_QUIT_FUNCS-1] = NULL; - break; - } - } -} - -// =========================================================================================== -// DIRECT INPUT HELPER CODE -// =========================================================================================== - -// Create a DirectInputDevice interface, -// create a DirectInputDevice2 interface if possible -static void CreateDevice2(LPDIRECTINPUT di, REFGUID pguid, LPDIRECTINPUTDEVICE* lpDEV, - LPDIRECTINPUTDEVICE2* lpDEV2) -{ - HRESULT hr, hr2; - LPDIRECTINPUTDEVICE lpdid1; - LPDIRECTINPUTDEVICE2 lpdid2 = NULL; - - hr = IDirectInput_CreateDevice(di, pguid, &lpdid1, NULL); - - if (SUCCEEDED(hr)) - { - // get Device2 but only if we are not in DirectInput version 3 - if (!bDX0300 && lpDEV2) - { - LPDIRECTINPUTDEVICE2 *rp = &lpdid2; - LPVOID *tp = (LPVOID *)rp; - hr2 = IDirectInputDevice_QueryInterface(lpdid1, &IID_IDirectInputDevice2, tp); - if (FAILED(hr2)) - { - CONS_Printf("\2Could not create IDirectInput device 2"); - lpdid2 = NULL; - } - } - } - else - I_Error("Could not create IDirectInput device"); - - *lpDEV = lpdid1; - if (lpDEV2) // only if we requested it - *lpDEV2 = lpdid2; -} - -// =========================================================================================== -// DIRECT INPUT MOUSE -// =========================================================================================== - -#define DI_MOUSE_BUFFERSIZE 16 // number of data elements in mouse buffer - -// -// Initialise the mouse. -// -static void I_ShutdownMouse(void); - -void I_StartupMouse(void) -{ - // this gets called when cv_usemouse is initted - // for the win32 version, we want to startup the mouse later -} - -static HANDLE mouse2filehandle = INVALID_HANDLE_VALUE; - -static void I_ShutdownMouse2(void) -{ - if (mouse2filehandle != INVALID_HANDLE_VALUE) - { - event_t event; - int i; - - SetCommMask(mouse2filehandle, 0); - - EscapeCommFunction(mouse2filehandle, CLRDTR); - EscapeCommFunction(mouse2filehandle, CLRRTS); - - PurgeComm(mouse2filehandle, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); - - CloseHandle(mouse2filehandle); - - // emulate the up of all mouse buttons - for (i = 0; i < MOUSEBUTTONS; i++) - { - event.type = ev_keyup; - event.data1 = KEY_2MOUSE1 + i; - D_PostEvent(&event); - } - - mouse2filehandle = INVALID_HANDLE_VALUE; - } -} - -#define MOUSECOMBUFFERSIZE 256 -static int handlermouse2x, handlermouse2y, handlermouse2buttons; - -static void I_PoolMouse2(void) -{ - UINT8 buffer[MOUSECOMBUFFERSIZE]; - COMSTAT ComStat; - DWORD dwErrorFlags, dwLength; - char dx, dy; - - static int bytenum; - static UINT8 combytes[4]; - DWORD i; - - ClearCommError(mouse2filehandle, &dwErrorFlags, &ComStat); - dwLength = min(MOUSECOMBUFFERSIZE, ComStat.cbInQue); - - if (dwLength > 0) - { - if (!ReadFile(mouse2filehandle, buffer, dwLength, &dwLength, NULL)) - { - CONS_Printf("\2Read Error on secondary mouse port\n"); - return; - } - - // parse the mouse packets - for (i = 0; i < dwLength; i++) - { - if ((buffer[i] & 64) == 64) - bytenum = 0; - - if (bytenum < 4) - combytes[bytenum] = buffer[i]; - bytenum++; - - if (bytenum == 1) - { - handlermouse2buttons &= ~3; - handlermouse2buttons |= ((combytes[0] & (32+16)) >>4); - } - else if (bytenum == 3) - { - dx = (char)((combytes[0] & 3) << 6); - dy = (char)((combytes[0] & 12) << 4); - dx = (char)(dx + combytes[1]); - dy = (char)(dy + combytes[2]); - handlermouse2x += dx; - handlermouse2y += dy; - } - else if (bytenum == 4) // fourth byte (logitech mouses) - { - if (buffer[i] & 32) - handlermouse2buttons |= 4; - else - handlermouse2buttons &= ~4; - } - } - } -} - -// secondary mouse doesn't use DirectX, therefore forget all about grabbing, acquire, etc. -void I_StartupMouse2(void) -{ - DCB dcb; - - if (mouse2filehandle != INVALID_HANDLE_VALUE) - I_ShutdownMouse2(); - - if (!cv_usemouse2.value) - return; - - if (mouse2filehandle != INVALID_HANDLE_VALUE) - { - // COM file handle - mouse2filehandle = CreateFileA(cv_mouse2port.string, GENERIC_READ|GENERIC_WRITE, - 0, // exclusive access - NULL, // no security attrs - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (mouse2filehandle == INVALID_HANDLE_VALUE) - { - int e = GetLastError(); - if (e == 5) - CONS_Printf("\2Can't open %s: Access denied\n" - "The port is probably already used by another device (mouse, modem,...)\n", - cv_mouse2port.string); - else - CONS_Printf("\2Can't open %s: error %d\n", cv_mouse2port.string, e); - return; - } - } - - // buffers - SetupComm(mouse2filehandle, MOUSECOMBUFFERSIZE, MOUSECOMBUFFERSIZE); - - // purge buffers - PurgeComm(mouse2filehandle, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); - - // setup port to 1200 7N1 - dcb.DCBlength = sizeof (DCB); - - GetCommState(mouse2filehandle, &dcb); - - dcb.BaudRate = CBR_1200; - dcb.ByteSize = 7; - dcb.Parity = NOPARITY; - dcb.StopBits = ONESTOPBIT; - - dcb.fDtrControl = DTR_CONTROL_ENABLE; - dcb.fRtsControl = RTS_CONTROL_ENABLE; - - dcb.fBinary = dcb.fParity = TRUE; - - SetCommState(mouse2filehandle, &dcb); - - I_AddExitFunc(I_ShutdownMouse2); -} - -#define MAX_MOUSE_BTNS 5 -static int center_x, center_y; -static int old_mparms[3], new_mparms[3] = {0, 0, 1}; -static boolean restore_mouse = FALSE; -static int old_mouse_state = 0; -unsigned int MSHWheelMessage = 0; - -static void I_DoStartupSysMouse(void) -{ - boolean valid; - RECT w_rect; - - valid = SystemParametersInfo(SPI_GETMOUSE, 0, old_mparms, 0); - if (valid) - { - new_mparms[2] = old_mparms[2]; - restore_mouse = SystemParametersInfo(SPI_SETMOUSE, 0, new_mparms, 0); - } - - if (bAppFullScreen) - { - w_rect.top = 0; - w_rect.left = 0; - } - else - { - w_rect.top = windowPosY; - w_rect.left = windowPosX; - } - - w_rect.bottom = w_rect.top + VIDHEIGHT; - w_rect.right = w_rect.left + VIDWIDTH; - center_x = w_rect.left + (VIDWIDTH >> 1); - center_y = w_rect.top + (VIDHEIGHT >> 1); - SetCursor(NULL); - SetCursorPos(center_x, center_y); - SetCapture(hWndMain); - ClipCursor(&w_rect); -} - -static void I_ShutdownSysMouse(void) -{ - if (restore_mouse) - SystemParametersInfo(SPI_SETMOUSE, 0, old_mparms, 0); - ClipCursor(NULL); - ReleaseCapture(); -} - -void I_RestartSysMouse(void) -{ - if (nodinput) - { - I_ShutdownSysMouse(); - I_DoStartupSysMouse(); - } -} - -void I_GetSysMouseEvents(int mouse_state) -{ - int i; - event_t event; - int xmickeys = 0, ymickeys = 0; - POINT c_pos; - - for (i = 0; i < MAX_MOUSE_BTNS; i++) - { - // check if button pressed - if ((mouse_state & (1 << i)) && !(old_mouse_state & (1 << i))) - { - event.type = ev_keydown; - event.data1 = KEY_MOUSE1 + i; - D_PostEvent(&event); - } - // check if button released - if (!(mouse_state & (1 << i)) && (old_mouse_state & (1 << i))) - { - event.type = ev_keyup; - event.data1 = KEY_MOUSE1 + i; - D_PostEvent(&event); - } - } - old_mouse_state = mouse_state; - - // proceed mouse movements - GetCursorPos(&c_pos); - xmickeys = c_pos.x - center_x; - ymickeys = c_pos.y - center_y; - - if (xmickeys || ymickeys) - { - event.type = ev_mouse; - event.data1 = 0; - event.data2 = xmickeys; - event.data3 = -ymickeys; - D_PostEvent(&event); - SetCursorPos(center_x, center_y); - } -} - -// This is called just before entering the main game loop, -// when we are going fullscreen and the loading screen has finished. -void I_DoStartupMouse(void) -{ - DIPROPDWORD dip; - - // mouse detection may be skipped by setting usemouse false - if (!cv_usemouse.value || M_CheckParm("-nomouse")) - { - mouse_enabled = false; - return; - } - - if (nodinput) - { - CONS_Printf("\tMouse will not use DirectInput.\n"); - // System mouse input will be initiated by VID_SetMode - I_AddExitFunc(I_ShutdownMouse); - - MSHWheelMessage = RegisterWindowMessage(MSH_MOUSEWHEEL); - } - else if (!lpDIM) // acquire the mouse only once - { - CreateDevice2(lpDI, &GUID_SysMouse, &lpDIM, NULL); - - if (lpDIM) - { - if (FAILED(IDirectInputDevice_SetDataFormat(lpDIM, &c_dfDIMouse))) - I_Error("Couldn't set mouse data format"); - - // create buffer for buffered data - dip.diph.dwSize = sizeof (dip); - dip.diph.dwHeaderSize = sizeof (dip.diph); - dip.diph.dwObj = 0; - dip.diph.dwHow = DIPH_DEVICE; - dip.dwData = DI_MOUSE_BUFFERSIZE; - if (FAILED(IDirectInputDevice_SetProperty(lpDIM, DIPROP_BUFFERSIZE, &dip.diph))) - I_Error("Couldn't set mouse buffer size"); - - if (FAILED(IDirectInputDevice_SetCooperativeLevel(lpDIM, hWndMain, - DISCL_EXCLUSIVE|DISCL_FOREGROUND))) - { - I_Error("Couldn't set mouse coop level"); - } - I_AddExitFunc(I_ShutdownMouse); - } - else - I_Error("Couldn't create mouse input"); - } - - // if re-enabled while running, just set mouse_enabled true again, - // do not acquire the mouse more than once - mouse_enabled = true; -} - -// -// Shutdown Mouse DirectInput device -// -static void I_ShutdownMouse(void) -{ - int i; - event_t event; - - CONS_Printf("I_ShutdownMouse()\n"); - - if (lpDIM) - { - IDirectInputDevice_Unacquire(lpDIM); - IDirectInputDevice_Release(lpDIM); - lpDIM = NULL; - } - - // emulate the up of all mouse buttons - for (i = 0; i < MOUSEBUTTONS; i++) - { - event.type = ev_keyup; - event.data1 = KEY_MOUSE1 + i; - D_PostEvent(&event); - } - if (nodinput) - I_ShutdownSysMouse(); - - mouse_enabled = false; -} - -// -// Get buffered data from the mouse -// -void I_GetMouseEvents(void) -{ - DIDEVICEOBJECTDATA rgdod[DI_MOUSE_BUFFERSIZE]; - DWORD dwItems, d; - HRESULT hr; - - event_t event; - int xmickeys, ymickeys; - - if (mouse2filehandle != INVALID_HANDLE_VALUE) - { - //mouse movement - static UINT8 lastbuttons2 = 0; - - I_PoolMouse2(); - // post key event for buttons - if (handlermouse2buttons != lastbuttons2) - { - int i, j = 1, k; - k = handlermouse2buttons ^ lastbuttons2; // only changed bit to 1 - lastbuttons2 = (UINT8)handlermouse2buttons; - - for (i = 0; i < MOUSEBUTTONS; i++, j <<= 1) - if (k & j) - { - if (handlermouse2buttons & j) - event.type = ev_keydown; - else - event.type = ev_keyup; - event.data1 = KEY_2MOUSE1 + i; - D_PostEvent(&event); - } - } - - if (handlermouse2x || handlermouse2y) - { - event.type = ev_mouse2; - event.data1 = 0; - event.data2 = handlermouse2x<<1; - event.data3 = -handlermouse2y<<1; - handlermouse2x = 0; - handlermouse2y = 0; - - D_PostEvent(&event); - } - } - - if (!mouse_enabled || nodinput) - return; - -getBufferedData: - dwItems = DI_MOUSE_BUFFERSIZE; - hr = IDirectInputDevice_GetDeviceData(lpDIM, sizeof (DIDEVICEOBJECTDATA), rgdod, &dwItems, 0); - - // If data stream was interrupted, reacquire the device and try again. - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - { - hr = IDirectInputDevice_Acquire(lpDIM); - if (SUCCEEDED(hr)) - goto getBufferedData; - } - - // We got buffered input, act on it - if (SUCCEEDED(hr)) - { - xmickeys = ymickeys = 0; - - // dwItems contains number of elements read (could be 0) - for (d = 0; d < dwItems; d++) - { - if (rgdod[d].dwOfs >= DIMOFS_BUTTON0 && - rgdod[d].dwOfs < DIMOFS_BUTTON0 + MOUSEBUTTONS) - { - if (rgdod[d].dwData & 0x80) // Button down - event.type = ev_keydown; - else - event.type = ev_keyup; // Button up - - event.data1 = rgdod[d].dwOfs - DIMOFS_BUTTON0 + KEY_MOUSE1; - D_PostEvent(&event); - } - else if (rgdod[d].dwOfs == DIMOFS_X) - xmickeys += rgdod[d].dwData; - else if (rgdod[d].dwOfs == DIMOFS_Y) - ymickeys += rgdod[d].dwData; - - else if (rgdod[d].dwOfs == DIMOFS_Z) - { - // z-axes the wheel - if ((int)rgdod[d].dwData > 0) - event.data1 = KEY_MOUSEWHEELUP; - else - event.data1 = KEY_MOUSEWHEELDOWN; - event.type = ev_keydown; - D_PostEvent(&event); - } - - } - - if (xmickeys || ymickeys) - { - event.type = ev_mouse; - event.data1 = 0; - event.data2 = xmickeys; - event.data3 = -ymickeys; - D_PostEvent(&event); - } - } -} - -// =========================================================================================== -// DIRECT INPUT JOYSTICK -// =========================================================================================== - -struct DIJoyInfo_s -{ - BYTE X,Y,Z,Rx,Ry,Rz,U,V; - LONG ForceAxises; -}; -typedef struct DIJoyInfo_s DIJoyInfo_t; - -// private info - static BYTE iJoyNum; // used by enumeration - static DIJoyInfo_t JoyInfo; - static BYTE iJoy2Num; - static DIJoyInfo_t JoyInfo2; - -//----------------------------------------------------------------------------- -// Name: EnumAxesCallback() -// Desc: Callback function for enumerating the axes on a joystick and counting -// each force feedback enabled axis -//----------------------------------------------------------------------------- -static BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, - VOID* pContext) -{ - DWORD* pdwNumForceFeedbackAxis = (DWORD*) pContext; - - if ((pdidoi->dwFlags & DIDOI_FFACTUATOR) != 0) - (*pdwNumForceFeedbackAxis)++; - - return DIENUM_CONTINUE; -} - - -static HRESULT SetupForceTacile(LPDIRECTINPUTDEVICE2 DJI, LPDIRECTINPUTEFFECT *DJE, DWORD FFAXIS, FFType EffectType,REFGUID EffectGUID) -{ - HRESULT hr; - DIEFFECT eff; - DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y }; - LONG rglDirection[2] = { 0, 0 }; - DICONSTANTFORCE cf = { 0 }; // LONG lMagnitude - DIRAMPFORCE rf = {0,0}; // LONG lStart, lEnd; - DIPERIODIC pf = {0,0,0,0}; - ZeroMemory(&eff, sizeof (eff)); - if (FFAXIS > 2) - FFAXIS = 2; //up to 2 FFAXIS - eff.dwSize = sizeof (DIEFFECT); - eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; // Cartesian and data format offsets - eff.dwDuration = INFINITE; - eff.dwSamplePeriod = 0; - eff.dwGain = DI_FFNOMINALMAX; - eff.dwTriggerButton = DIEB_NOTRIGGER; - eff.dwTriggerRepeatInterval = 0; - eff.cAxes = FFAXIS; - eff.rgdwAxes = rgdwAxes; - eff.rglDirection = rglDirection; - eff.lpEnvelope = NULL; - eff.lpvTypeSpecificParams = NULL; - if (EffectType == ConstantForce) - { - eff.cbTypeSpecificParams = sizeof (cf); - eff.lpvTypeSpecificParams = &cf; - } - else if (EffectType == RampForce) - { - eff.cbTypeSpecificParams = sizeof (rf); - eff.lpvTypeSpecificParams = &rf; - } - else if (EffectType >= SquareForce && SawtoothDownForce >= EffectType) - { - eff.cbTypeSpecificParams = sizeof (pf); - eff.lpvTypeSpecificParams = &pf; - } -#if (DIRECTINPUT_VERSION >= 0x0600) - //eff.dwStartDelay = 0; -#endif - - // Create the prepared effect - if (FAILED(hr = IDirectInputDevice2_CreateEffect(DJI, EffectGUID, - &eff, DJE, NULL))) - { - return hr; - } - - if (NULL == *DJE) - return E_FAIL; - - return hr; -} - -static BOOL CALLBACK DIEnumEffectsCallback1(LPCDIEFFECTINFO pdei, LPVOID pvRef) -{ - LPDIRECTINPUTEFFECT *DJE = pvRef; - if (DIEFT_GETTYPE(pdei->dwEffType) == DIEFT_CONSTANTFORCE) - { - if (SUCCEEDED(SetupForceTacile(lpDIJA,DJE, JoyInfo.ForceAxises, ConstantForce, &pdei->guid))) - return DIENUM_STOP; - } - if (DIEFT_GETTYPE(pdei->dwEffType) == DIEFT_RAMPFORCE) - { - if (SUCCEEDED(SetupForceTacile(lpDIJA,DJE, JoyInfo.ForceAxises, RampForce, &pdei->guid))) - return DIENUM_STOP; - } - return DIENUM_CONTINUE; -} - -static BOOL CALLBACK DIEnumEffectsCallback2(LPCDIEFFECTINFO pdei, LPVOID pvRef) -{ - LPDIRECTINPUTEFFECT *DJE = pvRef; - if (DIEFT_GETTYPE(pdei->dwEffType) == DIEFT_CONSTANTFORCE) - { - if (SUCCEEDED(SetupForceTacile(lpDIJ2A,DJE, JoyInfo2.ForceAxises, ConstantForce, &pdei->guid))) - return DIENUM_STOP; - } - if (DIEFT_GETTYPE(pdei->dwEffType) == DIEFT_RAMPFORCE) - { - if (SUCCEEDED(SetupForceTacile(lpDIJ2A,DJE, JoyInfo2.ForceAxises, RampForce, &pdei->guid))) - return DIENUM_STOP; - } - return DIENUM_CONTINUE; -} - -static REFGUID DIETable[] = -{ - &GUID_ConstantForce, //ConstantForce - &GUID_RampForce, //RampForce - &GUID_Square, //SquareForce - &GUID_Sine, //SineForce - &GUID_Triangle, //TriangleForce - &GUID_SawtoothUp, //SawtoothUpForce - &GUID_SawtoothDown, //SawtoothDownForce - (REFGUID)-1, //NumberofForces -}; - -static HRESULT SetupAllForces(LPDIRECTINPUTDEVICE2 DJI, LPDIRECTINPUTEFFECT DJE[], DWORD FFAXIS) -{ - FFType ForceType = EvilForce; - if (DJI == lpDIJA) - { - IDirectInputDevice2_EnumEffects(DJI,DIEnumEffectsCallback1,&DJE[ConstantForce],DIEFT_CONSTANTFORCE); - IDirectInputDevice2_EnumEffects(DJI,DIEnumEffectsCallback1,&DJE[RampForce],DIEFT_RAMPFORCE); - } - else if (DJI == lpDIJA) - { - IDirectInputDevice2_EnumEffects(DJI,DIEnumEffectsCallback2,&DJE[ConstantForce],DIEFT_CONSTANTFORCE); - IDirectInputDevice2_EnumEffects(DJI,DIEnumEffectsCallback2,&DJE[RampForce],DIEFT_RAMPFORCE); - } - for (ForceType = SquareForce; ForceType > NumberofForces && DIETable[ForceType] != (REFGUID)-1; ForceType++) - if (DIETable[ForceType]) - SetupForceTacile(DJI,&DJE[ForceType], FFAXIS, ForceType, DIETable[ForceType]); - return S_OK; -} - -static void LimitEffect(LPDIEFFECT eff, FFType EffectType) -{ - LPDICONSTANTFORCE pCF = eff->lpvTypeSpecificParams; - LPDIPERIODIC pDP= eff->lpvTypeSpecificParams; - if (eff->rglDirection) - { - } -/* if (eff->dwDuration != INFINITE && eff->dwDuration < 0) - { - eff->dwDuration = 0; - }*/ - if (eff->dwGain != 0) - { - if (eff->dwGain > DI_FFNOMINALMAX) - eff->dwGain = DI_FFNOMINALMAX; - //else if (eff->dwGain < -DI_FFNOMINALMAX) - // eff->dwGain = DI_FFNOMINALMAX; - } - if (EffectType == ConstantForce && pCF->lMagnitude) - { - } - else if (EffectType >= SquareForce && SawtoothDownForce >= EffectType && pDP) - { - } - -} - -static HRESULT SetForceTacile(LPDIRECTINPUTEFFECT SDIE, const JoyFF_t *FF,DWORD FFAXIS, FFType EffectType) -{ - DIEFFECT eff; - HRESULT hr; - LONG Magnitude; - LONG rglDirection[2] = { 0, 0 }; - DICONSTANTFORCE cf = { 0 }; // LONG lMagnitude - DIRAMPFORCE rf = {0,0}; // LONG lStart, lEnd; - DIPERIODIC pf = {0,0,0,0}; - if (!FF) - IDirectInputEffect_Stop(SDIE); - Magnitude = FF->Magnitude; - ZeroMemory(&eff, sizeof (eff)); - eff.dwSize = sizeof (eff); - //DIEP_START - eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; // Cartesian and data format offsets - //DIEP_DURATION - eff.dwDuration = FF->Duration; - //DIEP_GAIN - eff.dwGain = FF->Gain; - //DIEP_DIRECTION - eff.rglDirection = rglDirection; - //DIEP_TYPESPECIFICPARAMS - if (FFAXIS > 1) - { - double dMagnitude; - dMagnitude = (double)Magnitude; - dMagnitude = hypot(dMagnitude, dMagnitude); - Magnitude = (DWORD)dMagnitude; - rglDirection[0] = FF->ForceX; - rglDirection[1] = FF->ForceY; - } - if (EffectType == ConstantForce) - { - cf.lMagnitude = Magnitude; - eff.cbTypeSpecificParams = sizeof (cf); - eff.lpvTypeSpecificParams = &cf; - } - else if (EffectType == RampForce) - { - rf.lStart = FF->Start; - rf.lEnd = FF->End; - eff.cbTypeSpecificParams = sizeof (rf); - eff.lpvTypeSpecificParams = &rf; - } - else if (EffectType >= SquareForce && SawtoothDownForce >= EffectType) - { - pf.dwMagnitude = Magnitude; - pf.lOffset = FF->Offset; - pf.dwPhase = FF->Phase; - pf.dwPeriod = FF->Period; - eff.cbTypeSpecificParams = sizeof (pf); - eff.lpvTypeSpecificParams = &pf; - } - - LimitEffect(&eff, EffectType); - - hr = IDirectInputEffect_SetParameters(SDIE, &eff, - DIEP_START|DIEP_DURATION|DIEP_GAIN|DIEP_DIRECTION|DIEP_TYPESPECIFICPARAMS); - return hr; -} - -void I_Tactile(FFType Type, const JoyFF_t *Effect) -{ - if (!lpDIJA) return; - if (FAILED(IDirectInputDevice2_Acquire(lpDIJA))) - return; - if (Type == EvilForce) - IDirectInputDevice2_SendForceFeedbackCommand(lpDIJA,DISFFC_STOPALL); - if (Type <= EvilForce || Type > NumberofForces || !lpDIE[Type]) - return; - SetForceTacile(lpDIE[Type], Effect, JoyInfo.ForceAxises, Type); -} - -void I_Tactile2(FFType Type, const JoyFF_t *Effect) -{ - if (!lpDIJ2A) return; - if (FAILED(IDirectInputDevice2_Acquire(lpDIJ2A))) - return; - if (Type == EvilForce) - IDirectInputDevice2_SendForceFeedbackCommand(lpDIJ2A,DISFFC_STOPALL); - if (Type <= EvilForce || Type > NumberofForces || !lpDIE2[Type]) - return; - SetForceTacile(lpDIE2[Type],Effect, JoyInfo2.ForceAxises, Type); -} - -// ------------------ -// SetDIDwordProperty (HELPER) -// Set a DWORD property on a DirectInputDevice. -// ------------------ -static HRESULT SetDIDwordProperty(LPDIRECTINPUTDEVICE pdev, - REFGUID guidProperty, - DWORD dwObject, - DWORD dwHow, - DWORD dwValue) -{ - DIPROPDWORD dipdw; - - dipdw.diph.dwSize = sizeof (dipdw); - dipdw.diph.dwHeaderSize = sizeof (dipdw.diph); - dipdw.diph.dwObj = dwObject; - dipdw.diph.dwHow = dwHow; - dipdw.dwData = dwValue; - - return IDirectInputDevice_SetProperty(pdev, guidProperty, &dipdw.diph); -} - - -// --------------- -// DIEnumJoysticks -// There is no such thing as a 'system' joystick, contrary to mouse, -// we must enumerate and choose one joystick device to use -// --------------- -static BOOL CALLBACK DIEnumJoysticks (LPCDIDEVICEINSTANCE lpddi, - LPVOID pvRef) //cv_usejoystick -{ - LPDIRECTINPUTDEVICE pdev; - DIPROPRANGE diprg; - DIDEVCAPS caps; - BOOL bUseThisOne = FALSE; - - iJoyNum++; - - //faB: if cv holds a string description of joystick, the value from atoi() is 0 - // else, the value was probably set by user at console to one of the previously - // enumerated joysticks - if (((consvar_t *)pvRef)->value == iJoyNum -#ifndef _UNICODE - || !lstrcmpA(((consvar_t *)pvRef)->string, lpddi->tszProductName) -#endif - ) - bUseThisOne = TRUE; - - //CONS_Printf(" cv joy is %s\n", ((consvar_t *)pvRef)->string); - - // print out device name - CONS_Printf("%c%d: %s\n", - (bUseThisOne) ? '\2' : ' ', // show name in white if this is the one we will use - iJoyNum, - //(GET_DIDEVICE_SUBTYPE(lpddi->dwDevType) == DIDEVTYPEJOYSTICK_GAMEPAD) ? "Gamepad " : "Joystick", - lpddi->tszProductName); //, lpddi->tszInstanceName); - - // use specified joystick (cv_usejoystick.value in pvRef) - if (!bUseThisOne) - return DIENUM_CONTINUE; - - ((consvar_t *)pvRef)->value = iJoyNum; - if (IDirectInput_CreateDevice (lpDI, &lpddi->guidInstance, - &pdev, NULL) != DI_OK) - { - // if it failed, then we can't use this joystick for some - // bizarre reason. (Maybe the user unplugged it while we - // were in the middle of enumerating it.) So continue enumerating - CONS_Printf("DIEnumJoysticks(): CreateDevice FAILED\n"); - return DIENUM_CONTINUE; - } - - // get the Device capabilities - // - caps.dwSize = sizeof (DIDEVCAPS_DX3); - if (FAILED(IDirectInputDevice_GetCapabilities (pdev, &caps))) - { - CONS_Printf("DIEnumJoysticks(): GetCapabilities FAILED\n"); - IDirectInputDevice_Release (pdev); - return DIENUM_CONTINUE; - } - if (!(caps.dwFlags & DIDC_ATTACHED)) // should be, since we enumerate only attached devices - return DIENUM_CONTINUE; - - Joystick.bJoyNeedPoll = ((caps.dwFlags & DIDC_POLLEDDATAFORMAT) != 0); - - if (caps.dwFlags & DIDC_FORCEFEEDBACK) - JoyInfo.ForceAxises = 0; - else - JoyInfo.ForceAxises = -1; - - Joystick.bGamepadStyle = (GET_DIDEVICE_SUBTYPE(caps.dwDevType) == DIDEVTYPEJOYSTICK_GAMEPAD); - //DEBUG CONS_Printf("Gamepad: %d\n", Joystick.bGamepadStyle); - - - CONS_Printf("Capabilities: %d axes, %d buttons, %d POVs, poll %d, Gamepad %d\n", - caps.dwAxes, caps.dwButtons, caps.dwPOVs, Joystick.bJoyNeedPoll, Joystick.bGamepadStyle); - - // Set the data format to "simple joystick" - a predefined data format - // - // A data format specifies which controls on a device we - // are interested in, and how they should be reported. - // - // This tells DirectInput that we will be passing a - // DIJOYSTATE structure to IDirectInputDevice::GetDeviceState. - if (IDirectInputDevice_SetDataFormat (pdev, &c_dfDIJoystick) != DI_OK) - { - CONS_Printf("DIEnumJoysticks(): SetDataFormat FAILED\n"); - IDirectInputDevice_Release (pdev); - return DIENUM_CONTINUE; - } - - // Set the cooperativity level to let DirectInput know how - // this device should interact with the system and with other - // DirectInput applications. - if (IDirectInputDevice_SetCooperativeLevel (pdev, hWndMain, - DISCL_EXCLUSIVE | DISCL_FOREGROUND) != DI_OK) - { - CONS_Printf("DIEnumJoysticks(): SetCooperativeLevel FAILED\n"); - IDirectInputDevice_Release (pdev); - return DIENUM_CONTINUE; - } - - // set the range of the joystick axis - diprg.diph.dwSize = sizeof (DIPROPRANGE); - diprg.diph.dwHeaderSize = sizeof (DIPROPHEADER); - diprg.diph.dwHow = DIPH_BYOFFSET; - diprg.lMin = -JOYAXISRANGE; // value for extreme left - diprg.lMax = +JOYAXISRANGE; // value for extreme right - - diprg.diph.dwObj = DIJOFS_X; // set the x-axis range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //goto SetPropFail; - JoyInfo.X = FALSE; - } - else JoyInfo.X = TRUE; - - diprg.diph.dwObj = DIJOFS_Y; // set the y-axis range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { -//SetPropFail: -// CONS_Printf("DIEnumJoysticks(): SetProperty FAILED\n"); -// IDirectInputDevice_Release (pdev); -// return DIENUM_CONTINUE; - JoyInfo.Y = FALSE; - } - else JoyInfo.Y = TRUE; - - diprg.diph.dwObj = DIJOFS_Z; // set the z-axis range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_Z not found\n"); - JoyInfo.Z = FALSE; - } - else JoyInfo.Z = TRUE; - - diprg.diph.dwObj = DIJOFS_RX; // set the x-rudder range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RX (x-rudder) not found\n"); - JoyInfo.Rx = FALSE; - } - else JoyInfo.Rx = TRUE; - - diprg.diph.dwObj = DIJOFS_RY; // set the y-rudder range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RY (y-rudder) not found\n"); - JoyInfo.Ry = FALSE; - } - else JoyInfo.Ry = TRUE; - - diprg.diph.dwObj = DIJOFS_RZ; // set the z-rudder range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RZ (z-rudder) not found\n"); - JoyInfo.Rz = FALSE; - } - else JoyInfo.Rz = TRUE; - diprg.diph.dwObj = DIJOFS_SLIDER(0); // set the x-misc range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RZ (x-misc) not found\n"); - JoyInfo.U = FALSE; - } - else JoyInfo.U = TRUE; - - diprg.diph.dwObj = DIJOFS_SLIDER(1); // set the y-misc range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RZ (y-misc) not found\n"); - JoyInfo.V = FALSE; - } - else JoyInfo.V = TRUE; - - // set X axis dead zone to 25% (to avoid accidental turning) - if (!Joystick.bGamepadStyle) - { - if (JoyInfo.X) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_X, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks(): couldn't SetProperty for X DEAD ZONE"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo.Y) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_Y, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks(): couldn't SetProperty for Y DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo.Z) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_Z, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks(): couldn't SetProperty for Z DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo.Rx) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_RX, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks(): couldn't SetProperty for RX DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo.Ry) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_RY, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks(): couldn't SetProperty for RY DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo.Rz) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_RZ, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks(): couldn't SetProperty for RZ DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo.U) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_SLIDER(0), - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks(): couldn't SetProperty for U DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo.V) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_SLIDER(1), - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks(): couldn't SetProperty for V DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - } - - // query for IDirectInputDevice2 - we need this to poll the joystick - if (bDX0300) - { - FFType i = EvilForce; - // we won't use the poll - lpDIJA = NULL; - for (i = 0; i > NumberofForces; i++) - lpDIE[i] = NULL; - } - else - { - LPDIRECTINPUTDEVICE2 *rp = &lpDIJA; - LPVOID *tp = (LPVOID *)rp; - if (FAILED(IDirectInputDevice_QueryInterface(pdev, &IID_IDirectInputDevice2, tp))) - { - CONS_Printf("DIEnumJoysticks(): QueryInterface FAILED\n"); - IDirectInputDevice_Release (pdev); - return DIENUM_CONTINUE; - } - - if (lpDIJA && JoyInfo.ForceAxises != -1) - { - // Since we will be playing force feedback effects, we should disable the - // auto-centering spring. - if (FAILED(SetDIDwordProperty(pdev, DIPROP_AUTOCENTER, 0, DIPH_DEVICE, FALSE))) - { - //NOP - } - - // Enumerate and count the axes of the joystick - if (FAILED(IDirectInputDevice_EnumObjects(pdev, EnumAxesCallback, - (VOID*)&JoyInfo.ForceAxises, DIDFT_AXIS))) - { - JoyInfo.ForceAxises = -1; - } - else - { - SetupAllForces(lpDIJA,lpDIE,JoyInfo.ForceAxises); - } - } - } - - // we successfully created an IDirectInputDevice. So stop looking - // for another one. - lpDIJ = pdev; - return DIENUM_STOP; -} - -// -------------- -// I_InitJoystick -// This is called everytime the 'use_joystick' variable changes -// It is normally called at least once at startup when the config is loaded -// -------------- -void I_InitJoystick(void) -{ - HRESULT hr; - - // cleanup - I_ShutdownJoystick(); - - //joystick detection can be skipped by setting use_joystick to 0 - if (M_CheckParm("-nojoy")) - { - CONS_Printf("Joystick disabled\n"); - return; - } - else - // don't do anything at the registration of the joystick cvar, - // until config is loaded - if (!lstrcmpA(cv_usejoystick.string, "0")) - return; - - // acquire the joystick only once - if (!lpDIJ) - { - joystick_detected = false; - - CONS_Printf("Looking for joystick devices:\n"); - iJoyNum = 0; - hr = IDirectInput_EnumDevices(lpDI, DIDEVTYPE_JOYSTICK, DIEnumJoysticks, - (void *)&cv_usejoystick, // our user parameter is joystick number - DIEDFL_ATTACHEDONLY); - if (FAILED(hr)) - { - CONS_Printf("\nI_InitJoystick(): EnumDevices FAILED\n"); - cv_usejoystick.value = 0; - return; - } - - if (!lpDIJ) - { - if (!iJoyNum) - CONS_Printf("none found\n"); - else - { - CONS_Printf("none used\n"); - if (cv_usejoystick.value > 0 && cv_usejoystick.value > iJoyNum) - { - CONS_Printf("\2Set the use_joystick variable to one of the" - " enumerated joystick numbers\n"); - } - } - cv_usejoystick.value = 0; - return; - } - - I_AddExitFunc(I_ShutdownJoystick); - - // set coop level - if (FAILED(IDirectInputDevice_SetCooperativeLevel(lpDIJ, hWndMain, - DISCL_NONEXCLUSIVE|DISCL_FOREGROUND))) - { - I_Error("I_InitJoystick: SetCooperativeLevel FAILED"); - } - } - else - CONS_Printf("Joystick already initialized\n"); - - // we don't unacquire joystick, so let's just pretend we re-acquired it - joystick_detected = true; -} -//Joystick 2 - -// --------------- -// DIEnumJoysticks2 -// There is no such thing as a 'system' joystick, contrary to mouse, -// we must enumerate and choose one joystick device to use -// --------------- -static BOOL CALLBACK DIEnumJoysticks2 (LPCDIDEVICEINSTANCE lpddi, - LPVOID pvRef) //cv_usejoystick -{ - LPDIRECTINPUTDEVICE pdev; - DIPROPRANGE diprg; - DIDEVCAPS caps; - BOOL bUseThisOne = FALSE; - - iJoy2Num++; - - //faB: if cv holds a string description of joystick, the value from atoi() is 0 - // else, the value was probably set by user at console to one of the previsouly - // enumerated joysticks - if (((consvar_t *)pvRef)->value == iJoy2Num -#ifndef _UNICODE - || !lstrcmpA(((consvar_t *)pvRef)->string, lpddi->tszProductName) -#endif - ) - bUseThisOne = TRUE; - - //CONS_Printf(" cv joy2 is %s\n", ((consvar_t *)pvRef)->string); - - // print out device name - CONS_Printf("%c%d: %s\n", - (bUseThisOne) ? '\2' : ' ', // show name in white if this is the one we will use - iJoy2Num, - //(GET_DIDEVICE_SUBTYPE(lpddi->dwDevType) == DIDEVTYPEJOYSTICK_GAMEPAD) ? "Gamepad " : "Joystick", - lpddi->tszProductName); //, lpddi->tszInstanceName); - - // use specified joystick (cv_usejoystick.value in pvRef) - if (!bUseThisOne) - return DIENUM_CONTINUE; - - ((consvar_t *)pvRef)->value = iJoy2Num; - if (IDirectInput_CreateDevice (lpDI, &lpddi->guidInstance, - &pdev, NULL) != DI_OK) - { - // if it failed, then we can't use this joystick for some - // bizarre reason. (Maybe the user unplugged it while we - // were in the middle of enumerating it.) So continue enumerating - CONS_Printf("DIEnumJoysticks2(): CreateDevice FAILED\n"); - return DIENUM_CONTINUE; - } - - - // get the Device capabilities - // - caps.dwSize = sizeof (DIDEVCAPS_DX3); - if (FAILED(IDirectInputDevice_GetCapabilities (pdev, &caps))) - { - CONS_Printf("DIEnumJoysticks2(): GetCapabilities FAILED\n"); - IDirectInputDevice_Release (pdev); - return DIENUM_CONTINUE; - } - if (!(caps.dwFlags & DIDC_ATTACHED)) // should be, since we enumerate only attached devices - return DIENUM_CONTINUE; - - Joystick2.bJoyNeedPoll = ((caps.dwFlags & DIDC_POLLEDDATAFORMAT) != 0); - - if (caps.dwFlags & DIDC_FORCEFEEDBACK) - JoyInfo2.ForceAxises = 0; - else - JoyInfo2.ForceAxises = -1; - - Joystick2.bGamepadStyle = (GET_DIDEVICE_SUBTYPE(caps.dwDevType) == DIDEVTYPEJOYSTICK_GAMEPAD); - //DEBUG CONS_Printf("Gamepad: %d\n", Joystick2.bGamepadStyle); - - - CONS_Printf("Capabilities: %d axes, %d buttons, %d POVs, poll %d, Gamepad %d\n", - caps.dwAxes, caps.dwButtons, caps.dwPOVs, Joystick2.bJoyNeedPoll, Joystick2.bGamepadStyle); - - - // Set the data format to "simple joystick" - a predefined data format - // - // A data format specifies which controls on a device we - // are interested in, and how they should be reported. - // - // This tells DirectInput that we will be passing a - // DIJOYSTATE structure to IDirectInputDevice::GetDeviceState. - if (IDirectInputDevice_SetDataFormat (pdev, &c_dfDIJoystick) != DI_OK) - { - CONS_Printf("DIEnumJoysticks2(): SetDataFormat FAILED\n"); - IDirectInputDevice_Release (pdev); - return DIENUM_CONTINUE; - } - - // Set the cooperativity level to let DirectInput know how - // this device should interact with the system and with other - // DirectInput applications. - if (IDirectInputDevice_SetCooperativeLevel (pdev, hWndMain, - DISCL_EXCLUSIVE | DISCL_FOREGROUND) != DI_OK) - { - CONS_Printf("DIEnumJoysticks2(): SetCooperativeLevel FAILED\n"); - IDirectInputDevice_Release (pdev); - return DIENUM_CONTINUE; - } - - // set the range of the joystick axis - diprg.diph.dwSize = sizeof (DIPROPRANGE); - diprg.diph.dwHeaderSize = sizeof (DIPROPHEADER); - diprg.diph.dwHow = DIPH_BYOFFSET; - diprg.lMin = -JOYAXISRANGE; // value for extreme left - diprg.lMax = +JOYAXISRANGE; // value for extreme right - - diprg.diph.dwObj = DIJOFS_X; // set the x-axis range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //goto SetPropFail; - JoyInfo2.X = FALSE; - } - else JoyInfo2.X = TRUE; - - diprg.diph.dwObj = DIJOFS_Y; // set the y-axis range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { -//SetPropFail: -// CONS_Printf("DIEnumJoysticks(): SetProperty FAILED\n"); -// IDirectInputDevice_Release (pdev); -// return DIENUM_CONTINUE; - JoyInfo2.Y = FALSE; - } - else JoyInfo2.Y = TRUE; - - diprg.diph.dwObj = DIJOFS_Z; // set the z-axis range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_Z not found\n"); - JoyInfo2.Z = FALSE; - } - else JoyInfo2.Z = TRUE; - - diprg.diph.dwObj = DIJOFS_RX; // set the x-rudder range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RX (x-rudder) not found\n"); - JoyInfo2.Rx = FALSE; - } - else JoyInfo2.Rx = TRUE; - - diprg.diph.dwObj = DIJOFS_RY; // set the y-rudder range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RY (y-rudder) not found\n"); - JoyInfo2.Ry = FALSE; - } - else JoyInfo2.Ry = TRUE; - - diprg.diph.dwObj = DIJOFS_RZ; // set the z-rudder range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RZ (z-rudder) not found\n"); - JoyInfo2.Rz = FALSE; - } - else JoyInfo2.Rz = TRUE; - diprg.diph.dwObj = DIJOFS_SLIDER(0); // set the x-misc range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RZ (x-misc) not found\n"); - JoyInfo2.U = FALSE; - } - else JoyInfo2.U = TRUE; - - diprg.diph.dwObj = DIJOFS_SLIDER(1); // set the y-misc range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RZ (y-misc) not found\n"); - JoyInfo2.V = FALSE; - } - else JoyInfo2.V = TRUE; - - // set X axis dead zone to 25% (to avoid accidental turning) - if (!Joystick2.bGamepadStyle) - { - if (JoyInfo2.X) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_X, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks2(): couldn't SetProperty for X DEAD ZONE"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo2.Y) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_Y, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks2(): couldn't SetProperty for Y DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo2.Z) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_Z, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks2(): couldn't SetProperty for Z DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo2.Rx) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_RX, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks2(): couldn't SetProperty for RX DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo2.Ry) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_RY, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks2(): couldn't SetProperty for RY DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo2.Rz) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_RZ, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks2(): couldn't SetProperty for RZ DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo2.U) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_SLIDER(0), - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks2(): couldn't SetProperty for U DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo2.V) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_SLIDER(1), - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks2(): couldn't SetProperty for V DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - } - - // query for IDirectInputDevice2 - we need this to poll the joystick - if (bDX0300) - { - FFType i = EvilForce; - // we won't use the poll - lpDIJA = NULL; - for (i = 0; i > NumberofForces; i++) - lpDIE[i] = NULL; - } - else - { - LPDIRECTINPUTDEVICE2 *rp = &lpDIJ2A; - LPVOID *tp = (LPVOID *)rp; - if (FAILED(IDirectInputDevice_QueryInterface(pdev, &IID_IDirectInputDevice2, tp))) - { - CONS_Printf("DIEnumJoysticks2(): QueryInterface FAILED\n"); - IDirectInputDevice_Release (pdev); - return DIENUM_CONTINUE; - } - - if (lpDIJ2A && JoyInfo2.ForceAxises != -1) - { - // Since we will be playing force feedback effects, we should disable the - // auto-centering spring. - if (FAILED(SetDIDwordProperty(pdev, DIPROP_AUTOCENTER, 0, DIPH_DEVICE, FALSE))) - { - //NOP - } - - // Enumerate and count the axes of the joystick - if (FAILED(IDirectInputDevice_EnumObjects(pdev, EnumAxesCallback, - (VOID*)&JoyInfo2.ForceAxises, DIDFT_AXIS))) - { - JoyInfo2.ForceAxises = -1; - } - else - { - SetupAllForces(lpDIJ2A,lpDIE2,JoyInfo2.ForceAxises); - } - } - } - - // we successfully created an IDirectInputDevice. So stop looking - // for another one. - lpDIJ2 = pdev; - return DIENUM_STOP; -} - - -// -------------- -// I_InitJoystick2 -// This is called everytime the 'use_joystick2' variable changes -// It is normally called at least once at startup when the config is loaded -// -------------- -void I_InitJoystick2 (void) -{ - HRESULT hr; - - // cleanup - I_ShutdownJoystick2 (); - - joystick2_detected = false; - - // joystick detection can be skipped by setting use_joystick to 0 - if (M_CheckParm("-nojoy")) - { - CONS_Printf("Joystick2 disabled\n"); - return; - } - else - // don't do anything at the registration of the joystick cvar, - // until config is loaded - if (!lstrcmpA(cv_usejoystick2.string, "0")) - return; - - // acquire the joystick only once - if (!lpDIJ2) - { - joystick2_detected = false; - - CONS_Printf("Looking for joystick devices:\n"); - iJoy2Num = 0; - hr = IDirectInput_EnumDevices(lpDI, DIDEVTYPE_JOYSTICK, - DIEnumJoysticks2, - (void *)&cv_usejoystick2, // our user parameter is joystick number - DIEDFL_ATTACHEDONLY); - if (FAILED(hr)) - { - CONS_Printf("\nI_InitJoystick2(): EnumDevices FAILED\n"); - cv_usejoystick2.value = 0; - return; - } - - if (!lpDIJ2) - { - if (iJoy2Num == 0) - CONS_Printf("none found\n"); - else - { - CONS_Printf("none used\n"); - if (cv_usejoystick2.value > 0 && - cv_usejoystick2.value > iJoy2Num) - { - CONS_Printf("\2Set the use_joystick2 variable to one of the" - " enumerated joysticks number\n"); - } - } - cv_usejoystick2.value = 0; - return; - } - - I_AddExitFunc (I_ShutdownJoystick2); - - // set coop level - if (FAILED(IDirectInputDevice_SetCooperativeLevel (lpDIJ2, hWndMain, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND))) - I_Error("I_InitJoystick2: SetCooperativeLevel FAILED"); - - // later - //if (FAILED(IDirectInputDevice_Acquire (lpDIJ2))) - // I_Error("Couldn't acquire Joystick2"); - - joystick2_detected = true; - } - else - CONS_Printf("Joystick2 already initialized\n"); - - //faB: we don't unacquire joystick, so let's just pretend we re-acquired it - joystick2_detected = true; -} - -/** \brief Joystick 1 buttons states -*/ -static INT64 lastjoybuttons = 0; - -/** \brief Joystick 1 hats state -*/ -static INT64 lastjoyhats = 0; - -static void I_ShutdownJoystick(void) -{ - int i; - event_t event; - - lastjoybuttons = lastjoyhats = 0; - - event.type = ev_keyup; - - // emulate the up of all joystick buttons - for (i = 0;i < JOYBUTTONS;i++) - { - event.data1 = KEY_JOY1+i; - D_PostEvent(&event); - } - - // emulate the up of all joystick hats - for (i = 0;i < JOYHATS*4;i++) - { - event.data1 = KEY_HAT1+i; - D_PostEvent(&event); - } - - // reset joystick position - event.type = ev_joystick; - for (i = 0;i < JOYAXISSET; i++) - { - event.data1 = i; - D_PostEvent(&event); - } - - if (joystick_detected) - CONS_Printf("I_ShutdownJoystick()\n"); - - for (i = 0; i > NumberofForces; i++) - { - if (lpDIE[i]) - { - IDirectInputEffect_Release(lpDIE[i]); - lpDIE[i] = NULL; - - } - } - if (lpDIJ) - { - IDirectInputDevice_Unacquire(lpDIJ); - IDirectInputDevice_Release(lpDIJ); - lpDIJ = NULL; - } - if (lpDIJA) - { - IDirectInputDevice2_Release(lpDIJA); - lpDIJA = NULL; - } - joystick_detected = false; -} - -/** \brief Joystick 2 buttons states -*/ -static INT64 lastjoy2buttons = 0; - -/** \brief Joystick 2 hats state -*/ -static INT64 lastjoy2hats = 0; - -static void I_ShutdownJoystick2(void) -{ - int i; - event_t event; - - lastjoy2buttons = lastjoy2hats = 0; - - event.type = ev_keyup; - - // emulate the up of all joystick buttons - for (i = 0;i < JOYBUTTONS;i++) - { - event.data1 = KEY_2JOY1+i; - D_PostEvent(&event); - } - - // emulate the up of all joystick hats - for (i = 0;i < JOYHATS*4;i++) - { - event.data1 = KEY_2HAT1+i; - D_PostEvent(&event); - } - - // reset joystick position - event.type = ev_joystick2; - for (i = 0;i < JOYAXISSET; i++) - { - event.data1 = i; - D_PostEvent(&event); - } - - if (joystick2_detected) - CONS_Printf("I_ShutdownJoystick2()\n"); - - for (i = 0; i > NumberofForces; i++) - { - if (lpDIE2[i]) - { - IDirectInputEffect_Release(lpDIE2[i]); - lpDIE2[i] = NULL; - } - } - if (lpDIJ2) - { - IDirectInputDevice_Unacquire(lpDIJ2); - IDirectInputDevice_Release(lpDIJ2); - lpDIJ2 = NULL; - } - if (lpDIJ2A) - { - IDirectInputDevice2_Release(lpDIJ2A); - lpDIJ2A = NULL; - } - joystick2_detected = false; -} - -// ------------------- -// I_GetJoystickEvents -// Get current joystick axis and button states -// ------------------- -void I_GetJoystickEvents(void) -{ - HRESULT hr; - DIJOYSTATE js; // DirectInput joystick state - int i; - INT64 joybuttons = 0; - INT64 joyhats = 0; - event_t event; - - if (!lpDIJ) - return; - - // if input is lost then acquire and keep trying - for (;;) - { - // poll the joystick to read the current state - // if the device doesn't require polling, this function returns almost instantly - if (lpDIJA) - { - hr = IDirectInputDevice2_Poll(lpDIJA); - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - goto acquire; - else if (FAILED(hr)) - { - CONS_Printf("I_GetJoystickEvents(): Poll FAILED\n"); - return; - } - } - - // get the input's device state, and put the state in dims - hr = IDirectInputDevice_GetDeviceState(lpDIJ, sizeof (DIJOYSTATE), &js); - - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - { - // DirectInput is telling us that the input stream has - // been interrupted. We aren't tracking any state - // between polls, so we don't have any special reset - // that needs to be done. We just re-acquire and - // try again. - goto acquire; - } - else if (FAILED(hr)) - { - CONS_Printf("I_GetJoystickEvents(): GetDeviceState FAILED\n"); - return; - } - - break; -acquire: - if (FAILED(IDirectInputDevice_Acquire(lpDIJ))) - return; - } - - // look for as many buttons as g_input code supports, we don't use the others - for (i = JOYBUTTONS_MIN - 1; i >= 0; i--) - { - joybuttons <<= 1; - if (js.rgbButtons[i]) - joybuttons |= 1; - } - - for (i = JOYHATS_MIN -1; i >=0; i--) - { - if (js.rgdwPOV[i] != 0xffff && js.rgdwPOV[i] != 0xffffffff) - { - if (js.rgdwPOV[i] > 270 * DI_DEGREES || js.rgdwPOV[i] < 90 * DI_DEGREES) - joyhats |= 1<<(0 + 4*i); // UP - else if (js.rgdwPOV[i] > 90 * DI_DEGREES && js.rgdwPOV[i] < 270 * DI_DEGREES) - joyhats |= 1<<(1 + 4*i); // DOWN - if (js.rgdwPOV[i] > 0 * DI_DEGREES && js.rgdwPOV[i] < 180 * DI_DEGREES) - joyhats |= 1<<(3 + 4*i); // LEFT - else if (js.rgdwPOV[i] > 180 * DI_DEGREES && js.rgdwPOV[i] < 360 * DI_DEGREES) - joyhats |= 1<<(2 + 4*i); // RIGHT - } - } - - if (joybuttons != lastjoybuttons) - { - INT64 j = 1; // keep only bits that changed since last time - INT64 newbuttons = joybuttons ^ lastjoybuttons; - lastjoybuttons = joybuttons; - - for (i = 0; i < JOYBUTTONS && i < JOYBUTTONS_MAX; i++, j <<= 1) - { - if (newbuttons & j) // button changed state? - { - if (joybuttons & j) - event.type = ev_keydown; - else - event.type = ev_keyup; - event.data1 = KEY_JOY1 + i; - D_PostEvent(&event); - } - } - } - - if (joyhats != lastjoyhats) - { - INT64 j = 1; // keep only bits that changed since last time - INT64 newhats = joyhats ^ lastjoyhats; - lastjoyhats = joyhats; - - for (i = 0; i < JOYHATS*4 && i < JOYHATS_MAX*4; i++, j <<= 1) - { - if (newhats & j) // button changed state? - { - if (joyhats & j) - event.type = ev_keydown; - else - event.type = ev_keyup; - event.data1 = KEY_HAT1 + i; - D_PostEvent(&event); - } - } - - } - - // send joystick axis positions - event.type = ev_joystick; - event.data1 = event.data2 = event.data3 = 0; - - if (Joystick.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (JoyInfo.X) - { - if (js.lX < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (js.lX > JOYAXISRANGE/2) - event.data2 = 1; - } - if (JoyInfo.Y) - { - if (js.lY < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (js.lY > JOYAXISRANGE/2) - event.data3 = 1; - } - } - else - { - // analog control style, just send the raw data - if (JoyInfo.X) event.data2 = js.lX; // x axis - if (JoyInfo.Y) event.data3 = js.lY; // y axis - } - - D_PostEvent(&event); -#if JOYAXISSET > 1 - event.data1 = 1; - event.data2 = event.data3 = 0; - - if (Joystick.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (JoyInfo.Z) - { - if (js.lZ < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (js.lZ > JOYAXISRANGE/2) - event.data2 = 1; - } - if (JoyInfo.Rx) - { - if (js.lRx < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (js.lRx > JOYAXISRANGE/2) - event.data3 = 1; - } - } - else - { - // analog control style, just send the raw data - if (JoyInfo.Z) event.data2 = js.lZ; // z axis - if (JoyInfo.Rx) event.data3 = js.lRx; // rx axis - } - - D_PostEvent(&event); -#endif -#if JOYAXISSET > 2 - event.data1 = 2; - event.data2 = event.data3 = 0; - - if (Joystick.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (JoyInfo.Rx) - { - if (js.lRy < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (js.lRy > JOYAXISRANGE/2) - event.data2 = 1; - } - if (JoyInfo.Rz) - { - if (js.lRz < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (js.lRz > JOYAXISRANGE/2) - event.data3 = 1; - } - } - else - { - // analog control style, just send the raw data - if (JoyInfo.Ry) event.data2 = js.lRy; // ry axis - if (JoyInfo.Rz) event.data3 = js.lRz; // rz axis - } - - D_PostEvent(&event); -#endif -#if JOYAXISSET > 3 - event.data1 = 3; - event.data2 = event.data3 = 0; - if (Joystick.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (JoyInfo.U) - { - if (js.rglSlider[0] < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (js.rglSlider[0] > JOYAXISRANGE/2) - event.data2 = 1; - } - if (JoyInfo.V) - { - if (js.rglSlider[1] < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (js.rglSlider[1] > JOYAXISRANGE/2) - event.data3 = 1; - } - } - else - { - // analog control style, just send the raw data - if (JoyInfo.U) event.data2 = js.rglSlider[0]; // U axis - if (JoyInfo.V) event.data3 = js.rglSlider[1]; // V axis - } - D_PostEvent(&event); -#endif -} - -// ------------------- -// I_GetJoystickEvents -// Get current joystick axis and button states -// ------------------- -void I_GetJoystick2Events(void) -{ - HRESULT hr; - DIJOYSTATE js; // DirectInput joystick state - int i; - INT64 joybuttons = 0; - INT64 joyhats = 0; - event_t event; - - if (!lpDIJ2) - return; - - // if input is lost then acquire and keep trying - for (;;) - { - // poll the joystick to read the current state - // if the device doesn't require polling, this function returns almost instantly - if (lpDIJ2A) - { - hr = IDirectInputDevice2_Poll(lpDIJ2A); - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - goto acquire; - else if (FAILED(hr)) - { - CONS_Printf("I_GetJoystick2Events(): Poll FAILED\n"); - return; - } - } - - // get the input's device state, and put the state in dims - hr = IDirectInputDevice_GetDeviceState(lpDIJ2, sizeof (DIJOYSTATE), &js); - - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - { - // DirectInput is telling us that the input stream has - // been interrupted. We aren't tracking any state - // between polls, so we don't have any special reset - // that needs to be done. We just re-acquire and - // try again. - goto acquire; - } - else if (FAILED(hr)) - { - CONS_Printf("I_GetJoystickEvents2(): GetDeviceState FAILED\n"); - return; - } - - break; -acquire: - if (FAILED(IDirectInputDevice_Acquire(lpDIJ2))) - return; - } - - // look for as many buttons as g_input code supports, we don't use the others - for (i = JOYBUTTONS_MIN - 1; i >= 0; i--) - { - joybuttons <<= 1; - if (js.rgbButtons[i]) - joybuttons |= 1; - } - - for (i = JOYHATS_MIN -1; i >=0; i--) - { - if (js.rgdwPOV[i] != 0xffff && js.rgdwPOV[i] != 0xffffffff) - { - if (js.rgdwPOV[i] > 270 * DI_DEGREES || js.rgdwPOV[i] < 90 * DI_DEGREES) - joyhats |= 1<<(0 + 4*i); // UP - else if (js.rgdwPOV[i] > 90 * DI_DEGREES && js.rgdwPOV[i] < 270 * DI_DEGREES) - joyhats |= 1<<(1 + 4*i); // DOWN - if (js.rgdwPOV[i] > 0 * DI_DEGREES && js.rgdwPOV[i] < 180 * DI_DEGREES) - joyhats |= 1<<(3 + 4*i); // LEFT - else if (js.rgdwPOV[i] > 180 * DI_DEGREES && js.rgdwPOV[i] < 360 * DI_DEGREES) - joyhats |= 1<<(2 + 4*i); // RIGHT - } - } - - if (joybuttons != lastjoy2buttons) - { - INT64 j = 1; // keep only bits that changed since last time - INT64 newbuttons = joybuttons ^ lastjoy2buttons; - lastjoy2buttons = joybuttons; - - for (i = 0; i < JOYBUTTONS && i < JOYBUTTONS_MAX; i++, j <<= 1) - { - if (newbuttons & j) // button changed state? - { - if (joybuttons & j) - event.type = ev_keydown; - else - event.type = ev_keyup; - event.data1 = KEY_2JOY1 + i; - D_PostEvent(&event); - } - } - } - - if (joyhats != lastjoy2hats) - { - INT64 j = 1; // keep only bits that changed since last time - INT64 newhats = joyhats ^ lastjoy2hats; - lastjoy2hats = joyhats; - - for (i = 0; i < JOYHATS*4 && i < JOYHATS_MAX*4; i++, j <<= 1) - { - if (newhats & j) // button changed state? - { - if (joyhats & j) - event.type = ev_keydown; - else - event.type = ev_keyup; - event.data1 = KEY_2HAT1 + i; - D_PostEvent(&event); - } - } - - } - - // send joystick axis positions - event.type = ev_joystick2; - event.data1 = event.data2 = event.data3 = 0; - - if (Joystick2.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (JoyInfo2.X) - { - if (js.lX < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (js.lX > JOYAXISRANGE/2) - event.data2 = 1; - } - if (JoyInfo2.Y) - { - if (js.lY < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (js.lY > JOYAXISRANGE/2) - event.data3 = 1; - } - } - else - { - // analog control style, just send the raw data - if (JoyInfo2.X) event.data2 = js.lX; // x axis - if (JoyInfo2.Y) event.data3 = js.lY; // y axis - } - - D_PostEvent(&event); -#if JOYAXISSET > 1 - event.data1 = 1; - event.data2 = event.data3 = 0; - - if (Joystick2.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (JoyInfo2.Z) - { - if (js.lZ < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (js.lZ > JOYAXISRANGE/2) - event.data2 = 1; - } - if (JoyInfo2.Rx) - { - if (js.lRx < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (js.lRx > JOYAXISRANGE/2) - event.data3 = 1; - } - } - else - { - // analog control style, just send the raw data - if (JoyInfo2.Z) event.data2 = js.lZ; // z axis - if (JoyInfo2.Rx) event.data3 = js.lRx; // rx axis - } - - D_PostEvent(&event); -#endif -#if JOYAXISSET > 2 - event.data1 = 2; - event.data2 = event.data3 = 0; - - if (Joystick2.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (JoyInfo2.Rx) - { - if (js.lRy < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (js.lRy > JOYAXISRANGE/2) - event.data2 = 1; - } - if (JoyInfo2.Rz) - { - if (js.lRz < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (js.lRz > JOYAXISRANGE/2) - event.data3 = 1; - } - } - else - { - // analog control style, just send the raw data - if (JoyInfo2.Ry) event.data2 = js.lRy; // ry axis - if (JoyInfo2.Rz) event.data3 = js.lRz; // rz axis - } - - D_PostEvent(&event); -#endif -#if JOYAXISSET > 3 - event.data1 = 3; - event.data2 = event.data3 = 0; - if (Joystick2.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (JoyInfo2.U) - { - if (js.rglSlider[0] < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (js.rglSlider[0] > JOYAXISRANGE/2) - event.data2 = 1; - } - if (JoyInfo2.V) - { - if (js.rglSlider[1] < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (js.rglSlider[1] > JOYAXISRANGE/2) - event.data3 = 1; - } - } - else - { - // analog control style, just send the raw data - if (JoyInfo2.U) event.data2 = js.rglSlider[0]; // U axis - if (JoyInfo2.V) event.data3 = js.rglSlider[1]; // V axis - } - D_PostEvent(&event); -#endif -} - -static int numofjoy = 0; -static char joyname[MAX_PATH]; -static int needjoy = -1; - -static BOOL CALLBACK DIEnumJoysticksCount (LPCDIDEVICEINSTANCE lpddi, - LPVOID pvRef) //joyname -{ - numofjoy++; - if (needjoy == numofjoy && pvRef && pvRef == (void *)joyname && lpddi - && lpddi->tszProductName) - { - sprintf(joyname,"%s",lpddi->tszProductName); - return DIENUM_STOP; - } - //else if (devparm) CONS_Printf("DIEnumJoysticksCount need help!"); - return DIENUM_CONTINUE; -} - -INT32 I_NumJoys(void) -{ - HRESULT hr; - needjoy = -1; - numofjoy = 0; - hr = IDirectInput_EnumDevices(lpDI, DIDEVTYPE_JOYSTICK, - DIEnumJoysticksCount, (void *)&numofjoy, DIEDFL_ATTACHEDONLY); - if (FAILED(hr)) - CONS_Printf("\nI_NumJoys(): EnumDevices FAILED\n"); - return numofjoy; - -} - -const char *I_GetJoyName(INT32 joyindex) -{ - HRESULT hr; - needjoy = joyindex; - numofjoy = 0; - ZeroMemory(joyname,sizeof (joyname)); - hr = IDirectInput_EnumDevices(lpDI, DIDEVTYPE_JOYSTICK, - DIEnumJoysticksCount, (void *)joyname, DIEDFL_ATTACHEDONLY); - if (FAILED(hr)) - CONS_Printf("\nI_GetJoyName(): EnumDevices FAILED\n"); - if (joyname[0] == 0) return NULL; - return joyname; -} - -// =========================================================================================== -// DIRECT INPUT KEYBOARD -// =========================================================================================== - -static UINT8 ASCIINames[256] = -{ - // 0 1 2 3 4 5 6 7 - // 8 9 A B C D E F - 0, 27, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', KEY_MINUS,KEY_EQUALS,KEY_BACKSPACE, KEY_TAB, - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', '[', ']', KEY_ENTER,KEY_CTRL,'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', - '\'', '`', KEY_SHIFT, '\\', 'z', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '/', KEY_SHIFT, '*', - KEY_ALT,KEY_SPACE,KEY_CAPSLOCK, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, - KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10,KEY_NUMLOCK,KEY_SCROLLLOCK,KEY_KEYPAD7, - KEY_KEYPAD8,KEY_KEYPAD9,KEY_MINUSPAD,KEY_KEYPAD4,KEY_KEYPAD5,KEY_KEYPAD6,KEY_PLUSPAD,KEY_KEYPAD1, - KEY_KEYPAD2,KEY_KEYPAD3,KEY_KEYPAD0,KEY_KPADDEL,0,0,0, KEY_F11, - KEY_F12,0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - // 0 1 2 3 4 5 6 7 - // 8 9 A B C D E F - - 0, 0, 0, 0, 0, 0, 0, 0, // 0x80 - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, KEY_ENTER,KEY_CTRL, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, // 0xa0 - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, KEY_KPADDEL, 0,KEY_KPADSLASH,0, 0, - KEY_ALT,0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, KEY_HOME, // 0xc0 - KEY_UPARROW,KEY_PGUP,0,KEY_LEFTARROW,0,KEY_RIGHTARROW,0,KEY_END, - KEY_DOWNARROW,KEY_PGDN, KEY_INS,KEY_DEL,0,0,0,0, - 0, 0, 0,KEY_LEFTWIN,KEY_RIGHTWIN,KEY_MENU, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, // 0xe0 - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - -// Return a key that has been pushed, or 0 (replace getchar() at game startup) -// -INT32 I_GetKey(void) -{ - event_t *ev; - - if (eventtail != eventhead) - { - ev = &events[eventtail]; - eventtail = (eventtail+1) & (MAXEVENTS-1); - if (ev->type == ev_keydown || ev->type == ev_console) - return ev->data1; - else - return 0; - } - return 0; -} - -// ----------------- -// I_StartupKeyboard -// Installs DirectInput keyboard -// ----------------- -#define DI_KEYBOARD_BUFFERSIZE 32 // number of data elements in keyboard buffer - -void I_StartupKeyboard(void) -{ - DIPROPDWORD dip; - - if (dedicated) - return; - - // make sure the app window has the focus or DirectInput acquire keyboard won't work - if (hWndMain) - { - SetFocus(hWndMain); - ShowWindow(hWndMain, SW_SHOW); - UpdateWindow(hWndMain); - } - - // detect error - if (lpDIK) - { - CONS_Printf("\2I_StartupKeyboard(): called twice\n"); - return; - } - - CreateDevice2(lpDI, &GUID_SysKeyboard, &lpDIK, NULL); - - if (lpDIK) - { - if (FAILED(IDirectInputDevice_SetDataFormat(lpDIK, &c_dfDIKeyboard))) - I_Error("Couldn't set keyboard data format"); - - // create buffer for buffered data - dip.diph.dwSize = sizeof (dip); - dip.diph.dwHeaderSize = sizeof (dip.diph); - dip.diph.dwObj = 0; - dip.diph.dwHow = DIPH_DEVICE; - dip.dwData = DI_KEYBOARD_BUFFERSIZE; - if (FAILED(IDirectInputDevice_SetProperty(lpDIK, DIPROP_BUFFERSIZE, &dip.diph))) - I_Error("Couldn't set keyboard buffer size"); - - if (FAILED(IDirectInputDevice_SetCooperativeLevel(lpDIK, hWndMain, - DISCL_NONEXCLUSIVE|DISCL_FOREGROUND))) - { - I_Error("Couldn't set keyboard coop level"); - } - } - else - I_Error("Couldn't create keyboard input"); - - I_AddExitFunc(I_ShutdownKeyboard); - hacktics = 0; // see definition - keyboard_started = true; -} - -// ------------------ -// I_ShutdownKeyboard -// Release DirectInput keyboard. -// ------------------ -static void I_ShutdownKeyboard(void) -{ - if (!keyboard_started) - return; - - CONS_Printf("I_ShutdownKeyboard()\n"); - - if (lpDIK) - { - IDirectInputDevice_Unacquire(lpDIK); - IDirectInputDevice_Release(lpDIK); - lpDIK = NULL; - } - - keyboard_started = false; -} - -// ------------------- -// I_GetKeyboardEvents -// Get buffered data from the keyboard -// ------------------- -static void I_GetKeyboardEvents(void) -{ - static boolean KeyboardLost = false; - - // simply repeat the last pushed key every xx tics, - // make more user friendly input for Console and game Menus -#define KEY_REPEAT_DELAY (TICRATE/17) // TICRATE tics, repeat every 1/3 second - static long RepeatKeyTics = 0; - static int RepeatKeyCode; - - DIDEVICEOBJECTDATA rgdod[DI_KEYBOARD_BUFFERSIZE]; - DWORD dwItems, d; - HRESULT hr; - int ch; - - event_t event; - ZeroMemory(&event,sizeof (event)); - - if (!keyboard_started) - return; - - if (!appActive && RepeatKeyCode) // Stop when lost focus - { - event.type = ev_keyup; - event.data1 = RepeatKeyCode; - D_PostEvent(&event); - RepeatKeyCode = 0; - } -getBufferedData: - dwItems = DI_KEYBOARD_BUFFERSIZE; - hr = IDirectInputDevice_GetDeviceData(lpDIK, sizeof (DIDEVICEOBJECTDATA), rgdod, &dwItems, 0); - - // If data stream was interrupted, reacquire the device and try again. - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - { - // why it succeeds to acquire just after I don't understand.. so I set the flag BEFORE - KeyboardLost = true; - - hr = IDirectInputDevice_Acquire(lpDIK); - if (SUCCEEDED(hr)) - goto getBufferedData; - return; - } - - // we lost data, get device actual state to recover lost information - if (hr == DI_BUFFEROVERFLOW) - { - /// \note either uncomment or delete block - //I_Error("DI buffer overflow (keyboard)"); - //I_RecoverKeyboardState (); - - //hr = IDirectInputDevice_GetDeviceState (lpDIM, sizeof (keys), &diMouseState); - } - - // We got buffered input, act on it - if (SUCCEEDED(hr)) - { - // if we previously lost keyboard data, recover its current state - if (KeyboardLost) - { - /// \bug hack simply clears the keys so we don't have the last pressed keys - /// still active.. to have to re-trigger it is not much trouble for the user. - ZeroMemory(gamekeydown, NUMKEYS); - KeyboardLost = false; - } - - // dwItems contains number of elements read (could be 0) - for (d = 0; d < dwItems; d++) - { - // dwOfs member is DIK_* value - // dwData member 0x80 bit set press down, clear is release - - if (rgdod[d].dwData & 0x80) - event.type = ev_keydown; - else - event.type = ev_keyup; - - ch = rgdod[d].dwOfs & UINT8_MAX; - if (ASCIINames[ch]) - event.data1 = ASCIINames[ch]; - else - event.data1 = 0x80; - - D_PostEvent(&event); - } - - // Key Repeat - if (dwItems) - { - // new key events, so stop repeating key - RepeatKeyCode = 0; - // delay is tripled for first repeating key - RepeatKeyTics = hacktics + (KEY_REPEAT_DELAY*2); - if (event.type == ev_keydown) // use the last event! - RepeatKeyCode = event.data1; - } - else - { - // no new keys, repeat last pushed key after some time - if (RepeatKeyCode && hacktics - RepeatKeyTics > KEY_REPEAT_DELAY) - { - event.type = ev_keydown; - event.data1 = RepeatKeyCode; - D_PostEvent(&event); - - RepeatKeyTics = hacktics; - } - } - } -} - -// -// Closes DirectInput -// -static void I_ShutdownDirectInput(void) -{ - if (lpDI) - IDirectInput_Release(lpDI); - lpDI = NULL; -} - -// This stuff should get rid of the exception and page faults when -// SRB2 bugs out with an error. Now it should exit cleanly. -// -INT32 I_StartupSystem(void) -{ - HRESULT hr; - - // some 'more global than globals' things to initialize here ? - graphics_started = keyboard_started = sound_started = cdaudio_started = false; - - I_DetectWin9x(); - - // check for OS type and version here? -#ifdef NDEBUG - signal(SIGABRT, signal_handler); - signal(SIGFPE, signal_handler); - signal(SIGILL, signal_handler); - signal(SIGSEGV, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGINT, signal_handler); -#endif - - // create DirectInput - so that I_StartupKeyboard/Mouse can be called later on - // from D_SRB2Main just like DOS version - hr = DirectInputCreate(myInstance, DIRECTINPUT_VERSION, &lpDI, NULL); - - if (SUCCEEDED(hr)) - bDX0300 = FALSE; - else - { - // try opening DirectX3 interface for NT compatibility - hr = DirectInputCreate(myInstance, DXVERSION_NTCOMPATIBLE, &lpDI, NULL); - - if (FAILED(hr)) - { - const char *sErr; - switch (hr) - { - case DIERR_BETADIRECTINPUTVERSION: - sErr = "DIERR_BETADIRECTINPUTVERSION"; - break; - case DIERR_INVALIDPARAM: - sErr = "DIERR_INVALIDPARAM"; - break; - case DIERR_OLDDIRECTINPUTVERSION : - sErr = "DIERR_OLDDIRECTINPUTVERSION"; - break; - case DIERR_OUTOFMEMORY: - sErr = "DIERR_OUTOFMEMORY"; - break; - default: - sErr = "UNKNOWN"; - break; - } - I_Error("Couldn't create DirectInput (reason: %s)", sErr); - } - else - CONS_Printf("\2Using DirectX3 interface\n"); - - // only use DirectInput3 compatible structures and calls - bDX0300 = TRUE; - } - I_AddExitFunc(I_ShutdownDirectInput); - return 0; -} - -// Closes down everything. This includes restoring the initial -// palette and video mode, and removing whatever mouse, keyboard, and -// timer routines have been installed. -// -/// \bug doesn't restore wave/midi device volume -// -// Shutdown user funcs are effectively called in reverse order. -// -void I_ShutdownSystem(void) -{ - int c; - - for (c = MAX_QUIT_FUNCS - 1; c >= 0; c--) - if (quit_funcs[c]) - (*quit_funcs[c])(); -} - -// --------------- -// I_SaveMemToFile -// Save as much as iLength bytes starting at pData, to -// a new file of given name. The file is overwritten if it is present. -// --------------- -BOOL I_SaveMemToFile(const void *pData, size_t iLength, const char *sFileName) -{ - HANDLE fileHandle; - DWORD bytesWritten; - - fileHandle = CreateFileA(sFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH, NULL); - if (fileHandle == (HANDLE)-1) - { - CONS_Printf("SaveMemToFile: Error opening file %s",sFileName); - return FALSE; - } - WriteFile(fileHandle, pData, (DWORD)iLength, &bytesWritten, NULL); - CloseHandle(fileHandle); - return TRUE; -} - -// my god how win32 suck -typedef BOOL (WINAPI *MyFunc)(LPCSTR RootName, PULARGE_INTEGER pulA, PULARGE_INTEGER pulB, PULARGE_INTEGER pulFreeBytes); - -void I_GetDiskFreeSpace(INT64* freespace) -{ - static MyFunc pfnGetDiskFreeSpaceEx = NULL; - static boolean testwin95 = false; - ULARGE_INTEGER usedbytes, lfrespace; - - if (!testwin95) - { - HMODULE h = GetModuleHandleA("kernel32.dll"); - - if (h) - pfnGetDiskFreeSpaceEx = (MyFunc)GetProcAddress(h, "GetDiskFreeSpaceExA"); - testwin95 = true; - } - if (pfnGetDiskFreeSpaceEx) - { - if (pfnGetDiskFreeSpaceEx(NULL, &lfreespace, &usedbytes, NULL)) - *freespace = lfreespace.QuadPart; - else - *freespace = INT32_MAX; - } - else - { - DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters; - GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector, - &NumberOfFreeClusters, &TotalNumberOfClusters); - *freespace = BytesPerSector * SectorsPerCluster * NumberOfFreeClusters; - } -} - -char *I_GetUserName(void) -{ - static char username[MAXPLAYERNAME+1]; - char *p; - DWORD i = MAXPLAYERNAME; - - if (!GetUserNameA(username, &i)) - { - p = getenv("USER"); - if (!p) - { - p = getenv("user"); - if (!p) - { - p = getenv("USERNAME"); - if (!p) - { - p = getenv("username"); - if (!p) - { - return NULL; - } - } - } - } - strncpy(username, p, MAXPLAYERNAME); - } - - if (!strlen(username)) - return NULL; - return username; -} - -INT32 I_mkdir(const char *dirname, INT32 unixright) -{ - (void)unixright; /// \todo should implement ntright under nt... - return CreateDirectoryA(dirname, NULL); -} - -char * I_GetEnv(const char *name) -{ - return getenv(name); -} - -INT32 I_PutEnv(char *variable) -{ - return putenv(variable); -} - -INT32 I_ClipboardCopy(const char *data, size_t size) -{ - (void)data; - (void)size; - return -1; -} - -char *I_ClipboardPaste(void) -{ - return NULL; -} - -typedef BOOL (WINAPI *MyFunc3) (DWORD); - -const CPUInfoFlags *I_CPUInfo(void) -{ - static CPUInfoFlags WIN_CPUInfo; - static MyFunc3 pfnCPUID = NULL; - SYSTEM_INFO SI; - HMODULE h = GetModuleHandleA("kernel32.dll"); - - if (h) - pfnCPUID = (MyFunc3)GetProcAddress(h, "IsProcessorFeaturePresent"); - ZeroMemory(&WIN_CPUInfo,sizeof (WIN_CPUInfo)); - if(pfnCPUID) - { - WIN_CPUInfo.FPPE = pfnCPUID( 0); //PF_FLOATING_POINT_PRECISION_ERRATA - WIN_CPUInfo.FPE = pfnCPUID( 1); //PF_FLOATING_POINT_EMULATED - WIN_CPUInfo.cmpxchg = pfnCPUID( 2); //PF_COMPARE_EXCHANGE_DOUBLE - WIN_CPUInfo.MMX = pfnCPUID( 3); //PF_MMX_INSTRUCTIONS_AVAILABLE - WIN_CPUInfo.PPCMM64 = pfnCPUID( 4); //PF_PPC_MOVEMEM_64BIT_OK - WIN_CPUInfo.ALPHAbyte = pfnCPUID( 5); //PF_ALPHA_BYTE_INSTRUCTIONS - WIN_CPUInfo.SSE = pfnCPUID( 6); //PF_XMMI_INSTRUCTIONS_AVAILABLE - WIN_CPUInfo.AMD3DNow = pfnCPUID( 7); //PF_3DNOW_INSTRUCTIONS_AVAILABLE - WIN_CPUInfo.RDTSC = pfnCPUID( 8); //PF_RDTSC_INSTRUCTION_AVAILABLE - WIN_CPUInfo.PAE = pfnCPUID( 9); //PF_PAE_ENABLED - WIN_CPUInfo.SSE2 = pfnCPUID(10); //PF_XMMI64_INSTRUCTIONS_AVAILABLE - //WIN_CPUInfo.blank = pfnCPUID(11); //PF_SSE_DAZ_MODE_AVAILABLE - WIN_CPUInfo.DEP = pfnCPUID(12); //PF_NX_ENABLED - WIN_CPUInfo.SSE3 = pfnCPUID(13); //PF_SSE3_INSTRUCTIONS_AVAILABLE - WIN_CPUInfo.cmpxchg16b = pfnCPUID(14); //PF_COMPARE_EXCHANGE128 - WIN_CPUInfo.cmp8xchg16 = pfnCPUID(15); //PF_COMPARE64_EXCHANGE128 - WIN_CPUInfo.PFC = pfnCPUID(15); //PF_CHANNELS_ENABLED - } - GetSystemInfo(&SI); - WIN_CPUInfo.CPUs = SI.dwNumberOfProcessors; - WIN_CPUInfo.IA64 = (SI.dwProcessorType == 2200); // PROCESSOR_INTEL_IA64 - WIN_CPUInfo.AMD64 = (SI.dwProcessorType == 8664); // PROCESSOR_AMD_X8664 - return &WIN_CPUInfo; -} - -UINT64 I_FileSize(const char *filename) -{ - HANDLE fileHandle; - DWORD dwSizeHigh, dwSizeLow; - UINT64 fileSize = (UINT64)-1; - - fileHandle = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, - 0, NULL); - if (fileHandle == (HANDLE)-1) - goto erroropening; - dwSizeLow = GetFileSize(fileHandle,&dwSizeHigh); - if (dwSizeLow == 0xFFFFFFFF && GetLastError() != NO_ERROR) - goto errorsizing; - fileSize = ((UINT64)(dwSizeHigh)<<32) + dwSizeLow; -errorsizing: - CloseHandle(fileHandle); -erroropening: - return fileSize; -} diff --git a/src/win32ce/win_vid.c b/src/win32ce/win_vid.c deleted file mode 100644 index b9c2e131f795b0ddde170367b38a4a50258c6a26..0000000000000000000000000000000000000000 --- a/src/win32ce/win_vid.c +++ /dev/null @@ -1,861 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief win32 video driver for Doom Legacy - -#include "../doomdef.h" - -#include <stdlib.h> -#include <stdarg.h> - -#include "../d_clisrv.h" -#include "../i_system.h" -#include "../m_argv.h" -#include "../v_video.h" -#include "../st_stuff.h" -#include "../i_video.h" -#include "../z_zone.h" -#include "fabdxlib.h" - -#include "win_main.h" -#include "../command.h" -#include "../screen.h" - -#ifdef HWRENDER -#include "win_dll.h" // loading the render DLL -#include "../hardware/hw_drv.h" // calling driver init & shutdown -#include "../hardware/hw_main.h" // calling HWR module init & shutdown -#endif - -// ------- -// Globals -// ------- - -// this is the CURRENT rendermode!! very important: used by w_wad, and much other code -rendermode_t rendermode = render_soft; - -// synchronize page flipping with screen refresh -consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -static consvar_t cv_stretch = {"stretch", "On", CV_SAVE|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - -boolean highcolor; - -static BOOL bDIBMode; // means we are using DIB instead of DirectDraw surfaces -static BITMAPINFO* bmiMain = NULL; -static HDC hDCMain = NULL; - -// ----------------- -// Video modes stuff -// ----------------- - -#define MAX_EXTRA_MODES 36 -static vmode_t extra_modes[MAX_EXTRA_MODES] = {{NULL, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 0}}; -static char names[MAX_EXTRA_MODES][10]; - -static int numvidmodes; // total number of DirectDraw display modes -static vmode_t *pvidmodes; // start of videomodes list. -static vmode_t *pcurrentmode; // the current active videomode. -static BOOL bWinParm; -static int WINAPI VID_SetWindowedDisplayMode(viddef_t *lvid, vmode_t *pcurrentmode); - -// this holds description of the startup video mode, -// the resolution is 320x200, windowed on the desktop -#define NUMSPECIALMODES 1 -static char winmode1[] ="320x200W"; // W to make sure it's the windowed mode -static vmode_t specialmodes[NUMSPECIALMODES] = -{ - { - NULL, - winmode1, // hehe - 320, 200, //(200.0/320.0)*(320.0/240.0), - 320, 1, // rowbytes, bytes per pixel - 1, 2, // windowed (TRUE), numpages - NULL, - VID_SetWindowedDisplayMode, 0 - } -}; - -// ------ -// Protos -// ------ -static void VID_Command_NumModes_f(void); -static void VID_Command_ModeInfo_f(void); -static void VID_Command_ModeList_f(void); -static void VID_Command_Mode_f(void); -static int WINAPI VID_SetDirectDrawMode(viddef_t *lvid, vmode_t *pcurrentmode); -static vmode_t *VID_GetModePtr(int modenum); -static void VID_Init(void); -static BOOL VID_FreeAndAllocVidbuffer(viddef_t *lvid); - -// ----------------- -// I_StartupGraphics -// Initialize video mode, setup dynamic screen size variables, -// and allocate screens. -// ----------------- -void I_StartupGraphics(void) -{ - if (graphics_started) - return; - -#ifdef HWRENDER - if (M_CheckParm("-opengl")) - rendermode = render_opengl; - else - rendermode = render_soft; -#endif - - if (dedicated) - rendermode = render_none; - else - VID_Init(); - - // register exit code for graphics - I_AddExitFunc(I_ShutdownGraphics); - if (!dedicated) graphics_started = true; -} - -// ------------------ -// I_ShutdownGraphics -// Close the screen, restore previous video mode. -// ------------------ -void I_ShutdownGraphics(void) -{ - if (!graphics_started) - return; - - CONS_Printf("I_ShutdownGraphics()\n"); - - //FreeConsole(); - - // release windowed startup stuff - if (hDCMain) - { - ReleaseDC(hWndMain, hDCMain); - hDCMain = NULL; - } - if (bmiMain) - { - GlobalFree(bmiMain); - bmiMain = NULL; - } - -#ifdef HWRENDER - if (rendermode != render_soft) - { - HWR_Shutdown(); // free stuff from the hardware renderer - HWD.pfnShutdown(); // close 3d card display - Shutdown3DDriver(); // free the driver DLL - } -#endif - - // free the last video mode screen buffers - if (vid.buffer) - { - GlobalFree(vid.buffer); - vid.buffer = NULL; - } - -#ifdef HWRENDER - if (rendermode == render_soft) -#endif - CloseDirectDraw(); - - graphics_started = false; -} - -// -------------- -// I_UpdateNoBlit -// -------------- -void I_UpdateNoBlit(void) -{ - // what is this? -} - -// -------------- -// I_FinishUpdate -// -------------- -void I_FinishUpdate(void) -{ - int i; - - if (rendermode == render_none) - return; - - // display a graph of ticrate - if (cv_ticrate.value) - SCR_DisplayTicRate(); - - // - if (bDIBMode) - { - // paranoia - if (!hDCMain || !bmiMain || !vid.buffer) - return; - // main game loop, still in a window (-win parm) - SetDIBitsToDevice(hDCMain, 0, 0, 320, 200, 0, 0, 0, 200, vid.buffer, bmiMain, - DIB_RGB_COLORS); - } - else -#ifdef HWRENDER - if (rendermode != render_soft) - HWD.pfnFinishUpdate(cv_vidwait.value); - else -#endif - { - // DIRECT DRAW - // copy virtual screen to real screen - // can fail when not active (alt-tab) - if (LockScreen()) - { - /// \todo use directX blit here!!? a blit might use hardware with access - /// to main memory on recent hardware, and software blit of directX may be - /// optimized for p2 or mmx?? - VID_BlitLinearScreen(screens[0], ScreenPtr, vid.width*vid.bpp, vid.height, - vid.width*vid.bpp, ScreenPitch); - - UnlockScreen(); - - // swap screens - ScreenFlip(cv_vidwait.value); - } - } -} - -// -// This is meant to be called only by CONS_Printf() while game startup -// -void I_LoadingScreen(LPCSTR msg) -{ - RECT rect; - - // paranoia - if (!hDCMain || !bmiMain || !vid.buffer) - return; - - GetClientRect(vid.WndParent, &rect); - - SetDIBitsToDevice(hDCMain, 0, 0, 320, 200, 0, 0, 0, 200, vid.buffer, bmiMain, DIB_RGB_COLORS); - - if (msg) - { - if (rect.bottom - rect.top > 32) - rect.top = rect.bottom - 32; // put msg on bottom of window - SetBkMode(hDCMain, TRANSPARENT); - SetTextColor(hDCMain, RGB(0x00, 0x00, 0x00)); - DrawTextA(hDCMain, msg, -1, &rect, DT_WORDBREAK|DT_CENTER); - } -} - -// ------------ -// I_ReadScreen -// ------------ -void I_ReadScreen(UINT8 *scr) -{ - // DEBUGGING - if (rendermode != render_soft) - I_Error("I_ReadScreen: called while in non-software mode"); - VID_BlitLinearScreen(screens[0], scr, vid.width*vid.bpp, vid.height, vid.width*vid.bpp, - vid.rowbytes); -} - -// ------------ -// I_SetPalette -// ------------ -void I_SetPalette(RGBA_t *palette) -{ - int i; - - if (bDIBMode) - { - // set palette in RGBQUAD format, NOT THE SAME ORDER as PALETTEENTRY, grmpf! - RGBQUAD *pColors; - pColors = (RGBQUAD *)((char *)bmiMain + bmiMain->bmiHeader.biSize); - ZeroMemory(pColors, sizeof (RGBQUAD)*256); - for (i = 0; i < 256; i++, pColors++, palette++) - { - pColors->rgbRed = palette->s.red; - pColors->rgbGreen = palette->s.green; - pColors->rgbBlue = palette->s.blue; - } - } - else -#ifdef HWRENDER - if (rendermode == render_soft) -#endif - { - PALETTEENTRY mainpal[256]; - - // this clears the 'flag' for each color in palette - ZeroMemory(mainpal, sizeof mainpal); - - // set palette in PALETTEENTRY format - for (i = 0; i < 256; i++, palette++) - { - mainpal[i].peRed = palette->s.red; - mainpal[i].peGreen = palette->s.green; - mainpal[i].peBlue = palette->s.blue; - } - SetDDPalette(mainpal); // set DirectDraw palette - } -} - -// -// return number of video modes in pvidmodes list -// -INT32 VID_NumModes(void) -{ - return numvidmodes - NUMSPECIALMODES; //faB: dont accept the windowed mode 0 -} - -// return a video mode number from the dimensions -// returns any available video mode if the mode was not found -INT32 VID_GetModeForSize(INT32 w, INT32 h) -{ - vmode_t *pv = pvidmodes; - int modenum = 0; - - // skip the special modes so that it finds only fullscreen modes - for (; pv && modenum < NUMSPECIALMODES; pv = pv->pnext, ++modenum); - for (; pv; pv = pv->pnext, ++modenum) - if (pv->width == (unsigned)w && pv->height == (unsigned)h) - return modenum; - - // if not found, return the first mode available, - // preferably a full screen mode (all modes after the 'specialmodes') - if (numvidmodes > NUMSPECIALMODES) - return NUMSPECIALMODES; // use first full screen mode - - return 0; // no fullscreen mode, use windowed mode -} - -// -// Enumerate DirectDraw modes available -// -static int nummodes = 0; -static BOOL GetExtraModesCallback(int width, int height, int bpp) -{ - CONS_Printf("mode %d x %d x %d bpp\n", width, height, bpp); - - // skip all unwanted modes - if (highcolor && bpp != 15) - goto skip; - if (!highcolor && bpp != 8) - goto skip; - - if (bpp > 16 || width > MAXVIDWIDTH || height > MAXVIDHEIGHT) - goto skip; - - // check if we have space for this mode - if (nummodes >= MAX_EXTRA_MODES) - { - CONS_Printf("mode skipped (too many)\n"); - return FALSE; - } - - // store mode info - extra_modes[nummodes].pnext = &extra_modes[nummodes+1]; - memset(names[nummodes], 0, 10); - snprintf(names[nummodes], 9, "%dx%d", width, height); - - extra_modes[nummodes].name = names[nummodes]; - extra_modes[nummodes].width = width; - extra_modes[nummodes].height = height; - - // exactly, the current FinishUdpate() gets the rowbytes itself after locking the video buffer - // so for now we put anything here - extra_modes[nummodes].rowbytes = width; - extra_modes[nummodes].windowed = false; - extra_modes[nummodes].misc = 0; // unused - extra_modes[nummodes].pextradata = NULL; - extra_modes[nummodes].setmode = VID_SetDirectDrawMode; - - extra_modes[nummodes].numpages = 2; // double-buffer (but this value is unused) - - extra_modes[nummodes].bytesperpixel = (bpp+1)>>3; - - nummodes++; -skip: - return TRUE; -} - -// -// Collect info about DirectDraw display modes we use -// -static inline void VID_GetExtraModes(void) -{ - nummodes = 0; - EnumDirectDrawDisplayModes(GetExtraModesCallback); - - // add the extra modes (not 320x200) at the start of the mode list (if there are any) - if (nummodes) - { - extra_modes[nummodes-1].pnext = NULL; - pvidmodes = &extra_modes[0]; - numvidmodes += nummodes; - } -} - -// --------------- -// WindowMode_Init -// Add windowed modes to the start of the list, -// mode 0 is used for windowed console startup (works on all computers with no DirectX) -// --------------- -static void WindowMode_Init(void) -{ - specialmodes[NUMSPECIALMODES-1].pnext = pvidmodes; - pvidmodes = &specialmodes[0]; - numvidmodes += NUMSPECIALMODES; -} - -// ************************************************************************************* -// VID_Init -// Initialize Video modes subsystem -// ************************************************************************************* -static void VID_Init(void) -{ - vmode_t *pv; - int iMode; - - // if '-win' is specified on the command line, do not add DirectDraw modes - bWinParm = M_CheckParm("-win"); - - COM_AddCommand("vid_nummodes", VID_Command_NumModes_f); - COM_AddCommand("vid_modeinfo", VID_Command_ModeInfo_f); - COM_AddCommand("vid_modelist", VID_Command_ModeList_f); - COM_AddCommand("vid_mode", VID_Command_Mode_f); - - CV_RegisterVar(&cv_vidwait); - CV_RegisterVar(&cv_stretch); - - // setup the videmodes list, - // note that mode 0 must always be VGA mode 0x13 - pvidmodes = pcurrentmode = NULL; - numvidmodes = 0; - - // store the main window handle in viddef struct - SetWindowPos(hWndMain, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOSENDCHANGING|SWP_NOSIZE|SWP_NOMOVE); - vid.WndParent = hWndMain; - vid.buffer = NULL; - - // we startup in windowed mode using DIB bitmap - // we will use DirectDraw when switching fullScreen and entering main game loop - bDIBMode = TRUE; - bAppFullScreen = FALSE; - -#ifdef HWRENDER - // initialize the appropriate display device - if (rendermode != render_soft) - { - const char *drvname = NULL; - - switch (rendermode) - { - case render_opengl: - drvname = "r_opengl.dll"; - break; - default: - I_Error("Unknown hardware render mode"); - } - - // load the DLL - if (drvname && Init3DDriver(drvname)) - { - int hwdversion = HWD.pfnGetRenderVersion(); - if (hwdversion != VERSION) - CONS_Printf("WARNING: This r_opengl version is not supported, use it at your own risk.\n"); - - // perform initialisations - HWD.pfnInit(I_Error); - // get available display modes for the device - HWD.pfnGetModeList(&pvidmodes, &numvidmodes); - } - else - { - switch (rendermode) - { - case render_opengl: - I_Error("Error initializing OpenGL"); - default: - break; - } - rendermode = render_soft; - } - } - - if (rendermode == render_soft) -#endif - if (!bWinParm) - { - if (!CreateDirectDrawInstance()) - I_Error("Error initializing DirectDraw"); - // get available display modes for the device - VID_GetExtraModes(); - } - - // the game boots in 320x200 standard VGA, but - // we need a highcolor mode to run the game in highcolor - if (highcolor && !numvidmodes) - I_Error("Cannot run in highcolor - No 15bit highcolor DirectX video mode found."); - - // add windowed mode at the start of the list, very important! - WindowMode_Init(); - - if (!numvidmodes) - I_Error("No display modes available."); - - // DEBUG - for (iMode = 0, pv = pvidmodes; pv; pv = pv->pnext, iMode++) - CONS_Printf("#%02d: %dx%dx%dbpp (desc: '%s')\n", iMode, pv->width, pv->height, - pv->bytesperpixel, pv->name); - - // set the startup screen in a window - VID_SetMode(0); -} - -// -------------------------- -// VID_SetWindowedDisplayMode -// Display the startup 320x200 console screen into a window on the desktop, -// switching to fullscreen display only when we will enter the main game loop. -// - we can display error message boxes for startup errors -// - we can set the last used resolution only once, when entering the main game loop -// -------------------------- -static int WINAPI VID_SetWindowedDisplayMode(viddef_t *lvid, vmode_t *pcurrentmode) -{ - int iScrWidth, iScrHeight, iWinWidth, iWinHeight; - - pcurrentmode = NULL; -#ifdef DEBUG - CONS_Printf("VID_SetWindowedDisplayMode()\n"); -#endif - - lvid->u.numpages = 1; // not used - lvid->direct = NULL; // DOS remains - lvid->buffer = NULL; - - // allocate screens - if (!VID_FreeAndAllocVidbuffer(lvid)) - return -1; - - // lvid->buffer should be NULL here! - - bmiMain = (void *)GlobalAlloc(GPTR, sizeof (BITMAPINFO) + (sizeof (RGBQUAD)*256)); - if (!bmiMain) - I_Error("VID_SWDM(): No mem"); - - // setup a BITMAPINFO to allow copying our video buffer to the desktop, - // with color conversion as needed - bmiMain->bmiHeader.biSize = sizeof (BITMAPINFOHEADER); - bmiMain->bmiHeader.biWidth = lvid->width; - bmiMain->bmiHeader.biHeight= -(lvid->height); - bmiMain->bmiHeader.biPlanes = 1; - bmiMain->bmiHeader.biBitCount = 8; - bmiMain->bmiHeader.biCompression = BI_RGB; - - // center window on the desktop - iScrWidth = GetSystemMetrics(SM_CXFULLSCREEN); - iScrHeight = GetSystemMetrics(SM_CYFULLSCREEN); - - iWinWidth = lvid->width; - iWinWidth += GetSystemMetrics(SM_CXFIXEDFRAME) * 2; - - iWinHeight = lvid->height; - iWinHeight += GetSystemMetrics(SM_CYCAPTION); - iWinHeight += GetSystemMetrics(SM_CYFIXEDFRAME) * 2; - - if (devparm) - MoveWindow(hWndMain, (iScrWidth - iWinWidth), (iScrHeight - iWinHeight), iWinWidth, iWinHeight, TRUE); - else - MoveWindow(hWndMain, (iScrWidth - iWinWidth)>>1, (iScrHeight - iWinHeight)>>1, iWinWidth, iWinHeight, TRUE); - - SetFocus(hWndMain); - ShowWindow(hWndMain, SW_SHOW); - - hDCMain = GetDC(hWndMain); - if (!hDCMain) - I_Error("VID_SWDM(): GetDC FAILED"); - - return 1; -} - -// ======================================================================== -// Returns a vmode_t from the video modes list, given a video mode number. -// ======================================================================== -vmode_t *VID_GetModePtr(int modenum) -{ - vmode_t *pv; - - pv = pvidmodes; - if (!pv) - I_Error("VID_error: No video mode found\n"); - - while (modenum--) - { - pv = pv->pnext; - if (!pv) - I_Error("VID_error: Mode not available\n"); - } - return pv; -} - -// -// return the name of a video mode -// -const char *VID_GetModeName(INT32 modenum) -{ - return (VID_GetModePtr(modenum))->name; -} - -// ======================================================================== -// Sets a video mode -// ======================================================================== -INT32 VID_SetMode(INT32 modenum) -{ - int stat; - vmode_t *pnewmode; - vmode_t *poldmode; - - if (dedicated) - return 0; - - CONS_Printf("VID_SetMode(%d)\n", modenum); - - // if mode 0 (windowed) we must not be fullscreen already, - // if other mode, check it is not mode 0 and existing - if (modenum >= numvidmodes) - { - if (!pcurrentmode) - modenum = 0; // revert to the default base vid mode - else - I_Error("Unknown video mode: %d\n", modenum); - } - else if (bAppFullScreen && modenum < NUMSPECIALMODES) - I_Error("Tried to switch from fullscreen back to windowed mode %d\n", modenum); - - pnewmode = VID_GetModePtr(modenum); - - // dont switch to the same display mode - if (pnewmode == pcurrentmode) - return 1; - - // initialize the new mode - poldmode = pcurrentmode; - pcurrentmode = pnewmode; - - // initialize vidbuffer size for setmode - vid.width = pcurrentmode->width; - vid.height = pcurrentmode->height; - vid.rowbytes = pcurrentmode->rowbytes; - vid.bpp = pcurrentmode->bytesperpixel; - if (modenum) // if not 320x200 windowed mode, it's actually a hack - { - if (rendermode == render_opengl) - { - // don't accept depth < 16 for OpenGL mode (too much ugly) - if (cv_scr_depth.value < 16) - CV_SetValue(&cv_scr_depth, 16); - vid.bpp = cv_scr_depth.value/8; - vid.u.windowed = (bWinParm || !cv_fullscreen.value); - pcurrentmode->bytesperpixel = vid.bpp; - pcurrentmode->windowed = vid.u.windowed; - } - } - - stat = (*pcurrentmode->setmode)(&vid, pcurrentmode); - - if (stat == -1) - I_Error("Not enough mem for VID_SetMode\n"); - else if (stat == -2) - I_Error("Couldn't set video mode because it failed the test\n"); - else if (stat == -3) - I_Error("Couldn't set video mode because it failed the change?\n"); - else if (!stat) - I_Error("Couldn't set video mode %d (%dx%d %d bits)\n", modenum, vid.width, vid.height, (vid.bpp*8));// hardware could not setup mode - else - CONS_Printf(M_GetText("Mode changed to %d (%s)\n"), modenum, pcurrentmode->name); - - vid.modenum = modenum; - - // tell game engine to recalc all tables and realloc buffers based on new values - vid.recalc = 1; - - if (modenum < NUMSPECIALMODES) - { - // we are in startup windowed mode - bAppFullScreen = FALSE; - bDIBMode = TRUE; - } - else - { - // we switch to fullscreen - bAppFullScreen = TRUE; - bDIBMode = FALSE; -#ifdef HWRENDER - if (rendermode != render_soft) - { - // purge all patch graphics stored in software format - //Z_FreeTags (PU_PURGELEVEL, PU_PURGELEVEL+100); - HWR_Startup(); - } -#endif - } - - I_RestartSysMouse(); - return 1; -} - -// ======================================================================== -// Free the video buffer of the last video mode, -// allocate a new buffer for the video mode to set. -// ======================================================================== -static BOOL VID_FreeAndAllocVidbuffer(viddef_t *lvid) -{ - const DWORD vidbuffersize = (lvid->width * lvid->height * lvid->bpp * NUMSCREENS); - - // free allocated buffer for previous video mode - if (lvid->buffer) - GlobalFree(lvid->buffer); - - // allocate & clear the new screen buffer - lvid->buffer = GlobalAlloc(GPTR, vidbuffersize); - if (!lvid->buffer) - return FALSE; - - ZeroMemory(lvid->buffer, vidbuffersize); -#ifdef DEBUG - CONS_Printf("VID_FreeAndAllocVidbuffer done, vidbuffersize: %x\n",vidbuffersize); -#endif - return TRUE; -} - -// ======================================================================== -// Set video mode routine for DirectDraw display modes -// Out: 1 ok, -// 0 hardware could not set mode, -// -1 no mem -// ======================================================================== -static int WINAPI VID_SetDirectDrawMode(viddef_t *lvid, vmode_t *pcurrentmode) -{ - pcurrentmode = NULL; -#ifdef DEBUG - CONS_Printf("VID_SetDirectDrawMode...\n"); -#endif - - // DD modes do double-buffer page flipping, but the game engine doesn't need this.. - lvid->u.numpages = 2; - - // release ddraw surfaces etc.. - ReleaseChtuff(); - - // clean up any old vid buffer lying around, alloc new if needed - if (!VID_FreeAndAllocVidbuffer(lvid)) - return -1; // no mem - - // should clear video mem here - - // note use lvid->bpp instead of 8...will this be needed? will we support other than 256color - // in software ? - if (!InitDirectDrawe(hWndMain, lvid->width, lvid->height, 8, TRUE)) // TRUE currently always full screen - return 0; // could not set mode - - // this is NOT used with DirectDraw modes, game engine should never use this directly - // but rather render to memory bitmap buffer - lvid->direct = NULL; - - if (!cv_stretch.value && (float)vid.width/vid.height != ((float)BASEVIDWIDTH/BASEVIDHEIGHT)) - vid.height = (int)(vid.width * ((float)BASEVIDHEIGHT/BASEVIDWIDTH));// Adjust the height to match - - return 1; -} - -// ======================================================================== -// VIDEO MODE CONSOLE COMMANDS -// ======================================================================== - -// vid_nummodes -// -static void VID_Command_NumModes_f(void) -{ - CONS_Printf(M_GetText("%d video mode(s) available(s)\n"), VID_NumModes()); -} - -// vid_modeinfo <modenum> -// -static void VID_Command_ModeInfo_f(void) -{ - vmode_t *pv; - int modenum; - - if (COM_Argc() != 2) - modenum = vid.modenum; // describe the current mode - else - modenum = atoi(COM_Argv(1)); // the given mode number - - if (modenum >= VID_NumModes() || modenum < NUMSPECIALMODES) // don't accept the windowed mode 0 - { - CONS_Printf(M_GetText("Video mode not present\n")); - return; - } - - pv = VID_GetModePtr(modenum); - - CONS_Printf("%s\n", VID_GetModeName(modenum)); - CONS_Printf(M_GetText("width: %d\nheight: %d\n"), - pv->width, pv->height); - if (rendermode == render_soft) - CONS_Printf(M_GetText("bytes per scanline: %d\nbytes per pixel: %d\nnumpages: %d\n"), - pv->rowbytes, pv->bytesperpixel, pv->numpages); -} - -// vid_modelist -// -static void VID_Command_ModeList_f(void) -{ - int i, nummodes; - const char *pinfo; - vmode_t *pv; - - nummodes = VID_NumModes(); - for (i = NUMSPECIALMODES; i <= nummodes; i++) - { - pv = VID_GetModePtr(i); - pinfo = VID_GetModeName(i); - - if (pv->bytesperpixel == 1) - CONS_Printf("%d: %s\n", i, pinfo); - else - CONS_Printf("%d: %s (hicolor)\n", i, pinfo); - } -} - -// vid_mode <modenum> -// -static void VID_Command_Mode_f(void) -{ - int modenum; - - if (COM_Argc() != 2) - { - CONS_Printf(M_GetText("vid_mode <modenum> : set video mode, current video mode %i\n"), vid.modenum); - return; - } - - modenum = atoi(COM_Argv(1)); - - if (modenum >= VID_NumModes() || modenum < NUMSPECIALMODES) // don't accept the windowed mode 0 - CONS_Printf(M_GetText("Video mode not present\n")); - else - setmodeneeded = modenum + 1; // request vid mode change -} diff --git a/src/win32ce/wince_stuff.c b/src/win32ce/wince_stuff.c deleted file mode 100644 index eb02e8ae281d32f98c133104b0a2db9f2e9cf74a..0000000000000000000000000000000000000000 --- a/src/win32ce/wince_stuff.c +++ /dev/null @@ -1,135 +0,0 @@ -//It's 4am and im writing replacement string functions.... - -#include <stdlib.h> -#include <Windows.h> -#include "wince_stuff.h" - -char* _strlwr( char *string ) -{ - int i; - - if(!string) - return NULL; - - for(i=0 ; i < strlen(string); i++) - { - if((*(string + i) >= 65) && (*(string + i) <= 90)) - *(string+i) = *(string+i) + 32; - } - - return string; -} - -int _strnicmp(const char *first,const char *last, size_t count ) -{ - int f, l; - - do - { - if ( ((f = (unsigned char)(*(first++))) >= 'A') && (f <= 'Z') ) - f -= 'A' - 'a'; - - if ( ((l = (unsigned char)(*(last++))) >= 'A') && (l <= 'Z') ) - l -= 'A' - 'a'; - - } while ( --count && f && (f == l) ); - - return ( f - l ); -} - - -int _stricmp( const char *dst, const char *src ) -{ - int f, l; - - do - { - if ( ((f = (unsigned char)(*(dst++))) >= 'A') && (f <= 'Z') ) - f -= 'A' - 'a'; - - if ( ((l = (unsigned char)(*(src++))) >= 'A') && (l <= 'Z') ) - l -= 'A' - 'a'; - - } while ( f && (f == l) ); - - return(f - l); -} - - -char* _strupr( char *string ) -{ - int i; - - if(!string) - return NULL; - - for(i=0 ; i < strlen(string); i++) - { - if((*(string + i) >= 97) && (*(string + i) <= 122)) - *(string + i) = *(string + i) - 32; - } - - return string; -} - - - - -int isprint( int c ) -{ - if(c <= 31) - return FALSE; - - return TRUE; -} - - - -char* _strdup (const char * string) -{ - char *memory = NULL; - - if (!string) - return(NULL); - - if (memory = malloc(strlen(string) + 1)) - return(strcpy(memory,string)); - - return(NULL); -} - - - -char* strrchr (const char * string,int ch) -{ - char *start = (char *)string; - - while (*string++) /* find end of string */ - ; - /* search towards front */ - while (--string != start && *string != (char)ch) - ; - - if (*string == (char)ch) /* char found ? */ - return( (char *)string ); - - return(NULL); -} - -char* GetMyCWD(void) -{ - TCHAR fn[MAX_PATH]; - char* my_cwd,*p; - - GetModuleFileName(NULL,fn,MAX_PATH); - - my_cwd = (char*)malloc(MAX_PATH*sizeof(char)); - - WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR | WC_SEPCHARS, fn, -1, my_cwd, MAX_PATH, NULL, NULL); - p = strrchr(my_cwd,'\\'); - - if(p) - *(p+1) = '\0'; - - return my_cwd; -} diff --git a/src/win32ce/wince_stuff.h b/src/win32ce/wince_stuff.h deleted file mode 100644 index 5eab748482c9e09ce7ce6b1e56a7314a3dd68b4e..0000000000000000000000000000000000000000 --- a/src/win32ce/wince_stuff.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef WINCE_STUFF_H -#define WINCE_STUFF_H - -/* -char* _strlwr(char *string); -int _strnicmp(const char *string1,const char *string2, size_t count ); -int _stricmp( const char *string1, const char *string2 ); -char* _strupr( char *string ); - -char *_strdup( const char *strSource ); -char *strrchr( const char *string, int c ); - -int isprint( int c ); -*/ -char* GetMyCWD(void); - -#endif \ No newline at end of file diff --git a/src/y_inter.c b/src/y_inter.c index ed4972d2e6ae9fd21d7627f9db4650be58ced0f7..99219396426e86ad8b40a3a088cabdf243f61a7d 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -70,15 +70,15 @@ typedef union UINT32 score, total; // fake score, total UINT32 tics; // time - patch_t *ttlnum; // act number being displayed + INT32 actnum; // act number being displayed patch_t *ptotal; // TOTAL UINT8 gotlife; // Number of extra lives obtained } coop; struct { - char passed1[29]; // KNUCKLES GOT / CRAWLA HONCHO - char passed2[17]; // A CHAOS EMERALD / GOT THEM ALL! + char passed1[29]; // KNUCKLES GOT / CRAWLA HONCHO + char passed2[17]; // A CHAOS EMERALD? / GOT THEM ALL! char passed3[15]; // CAN NOW BECOME char passed4[SKINNAMESIZE+7]; // SUPER CRAWLA HONCHO INT32 passedx1; @@ -147,6 +147,7 @@ static boolean useinterpic; static INT32 timer; static INT32 intertic; +static INT32 tallydonetic = -1; static INT32 endtic = -1; intertype_t intertype = int_none; @@ -160,18 +161,50 @@ static void Y_FollowIntermission(void); static void Y_UnloadData(void); // Stuff copy+pasted from st_stuff.c -static INT32 SCX(INT32 x) -{ - return FixedInt(FixedMul(x<<FRACBITS, vid.fdupx)); -} -static INT32 SCY(INT32 z) +#define ST_DrawNumFromHud(h,n) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f, n) +#define ST_DrawPadNumFromHud(h,n,q) V_DrawPaddedTallNum(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f, n, q) +#define ST_DrawPatchFromHud(h,p) V_DrawScaledPatch(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f, p) + +static void Y_IntermissionTokenDrawer(void) { - return FixedInt(FixedMul(z<<FRACBITS, vid.fdupy)); -} + INT32 y, offs, lowy, calc; + UINT32 tokencount; + INT16 temp; + UINT8 em; + + offs = 0; + lowy = BASEVIDHEIGHT - 32 - 8; + temp = SHORT(tokenicon->height)/2; + + em = 0; + while (emeralds & (1 << em)) + if (++em == 7) + return; + + if (tallydonetic != -1) + { + offs = (intertic - tallydonetic)*2; + if (offs > 10) + offs = 8; + } + + V_DrawSmallScaledPatch(32, lowy-1, 0, emeraldpics[2][em]); // coinbox + + y = (lowy + offs + 1) - (temp + (token + 1)*8); + + for (tokencount = token; tokencount; tokencount--) + { + if (y >= -temp) + V_DrawSmallScaledPatch(32, y, 0, tokenicon); + y += 8; + } + + y += (offs*(temp - 1)/8); + calc = (lowy - y)*2; -#define ST_DrawNumFromHud(h,n) V_DrawTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART, n) -#define ST_DrawPadNumFromHud(h,n,q) V_DrawPaddedTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART, n, q) -#define ST_DrawPatchFromHud(h,p) V_DrawScaledPatch(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART, p) + if (calc > 0) + V_DrawCroppedPatch(32<<FRACBITS, y<<FRACBITS, FRACUNIT/2, 0, tokenicon, 0, 0, SHORT(tokenicon->width), calc); +} // // Y_IntermissionDrawer @@ -217,31 +250,37 @@ void Y_IntermissionDrawer(void) { INT32 bonusy; - // draw score - ST_DrawPatchFromHud(HUD_SCORE, sboscore); - ST_DrawNumFromHud(HUD_SCORENUM, data.coop.score); + if (gottoken) // first to be behind everything else + Y_IntermissionTokenDrawer(); - // draw time - ST_DrawPatchFromHud(HUD_TIME, sbotime); - if (cv_timetic.value == 1) - ST_DrawNumFromHud(HUD_SECONDS, data.coop.tics); - else + if (!splitscreen) { - INT32 seconds, minutes, tictrn; + // draw score + ST_DrawPatchFromHud(HUD_SCORE, sboscore); + ST_DrawNumFromHud(HUD_SCORENUM, data.coop.score); + + // draw time + ST_DrawPatchFromHud(HUD_TIME, sbotime); + if (cv_timetic.value == 1) + ST_DrawNumFromHud(HUD_SECONDS, data.coop.tics); + else + { + INT32 seconds, minutes, tictrn; - seconds = G_TicsToSeconds(data.coop.tics); - minutes = G_TicsToMinutes(data.coop.tics, true); - tictrn = G_TicsToCentiseconds(data.coop.tics); + seconds = G_TicsToSeconds(data.coop.tics); + minutes = G_TicsToMinutes(data.coop.tics, true); + tictrn = G_TicsToCentiseconds(data.coop.tics); - ST_DrawNumFromHud(HUD_MINUTES, minutes); // Minutes - ST_DrawPatchFromHud(HUD_TIMECOLON, sbocolon); // Colon - ST_DrawPadNumFromHud(HUD_SECONDS, seconds, 2); // Seconds + ST_DrawNumFromHud(HUD_MINUTES, minutes); // Minutes + ST_DrawPatchFromHud(HUD_TIMECOLON, sbocolon); // Colon + ST_DrawPadNumFromHud(HUD_SECONDS, seconds, 2); // Seconds - // we should show centiseconds on the intermission screen too, if the conditions are right. - if (modeattacking || cv_timetic.value == 2) - { - ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod); // Period - ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2); // Tics + // we should show centiseconds on the intermission screen too, if the conditions are right. + if (modeattacking || cv_timetic.value == 2) + { + ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod); // Period + ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2); // Tics + } } } @@ -249,8 +288,8 @@ void Y_IntermissionDrawer(void) V_DrawLevelTitle(data.coop.passedx1, 49, 0, data.coop.passed1); V_DrawLevelTitle(data.coop.passedx2, 49+V_LevelNameHeight(data.coop.passed2)+2, 0, data.coop.passed2); - if (mapheaderinfo[gamemap-1]->actnum) - V_DrawScaledPatch(244, 57, 0, data.coop.ttlnum); + if (data.coop.actnum) + V_DrawLevelActNum(244, 57, 0, data.coop.actnum); bonusy = 150; // Total @@ -276,86 +315,183 @@ void Y_IntermissionDrawer(void) INT32 xoffset1 = 0; // Line 1 x offset INT32 xoffset2 = 0; // Line 2 x offset INT32 xoffset3 = 0; // Line 3 x offset + INT32 xoffset4 = 0; // Line 4 x offset + INT32 xoffset5 = 0; // Line 5 x offset + INT32 xoffset6 = 0; // Line 6 x offset UINT8 drawsection = 0; + if (gottoken) // first to be behind everything else + Y_IntermissionTokenDrawer(); + // draw the header - if (intertic <= TICRATE) + if (intertic <= 2*TICRATE) animatetic = 0; else if (!animatetic && data.spec.bonus.points == 0 && data.spec.passed3[0] != '\0') - animatetic = intertic; + animatetic = intertic + TICRATE; - if (animatetic) + if (animatetic && (tic_t)intertic >= animatetic) { + const INT32 scradjust = (vid.width/vid.dupx)>>3; // 40 for BASEVIDWIDTH INT32 animatetimer = (intertic - animatetic); - if (animatetimer <= 8) + if (animatetimer <= 14) { - xoffset1 = -(animatetimer * 40); - xoffset2 = -((animatetimer-2) * 40); + xoffset1 = -(animatetimer * scradjust); + xoffset2 = -((animatetimer-2) * scradjust); + xoffset3 = -((animatetimer-4) * scradjust); + xoffset4 = -((animatetimer-6) * scradjust); + xoffset5 = -((animatetimer-8) * scradjust); if (xoffset2 > 0) xoffset2 = 0; + if (xoffset3 > 0) xoffset3 = 0; + if (xoffset4 > 0) xoffset4 = 0; + if (xoffset5 > 0) xoffset5 = 0; } - else if (animatetimer <= 19) + else if (animatetimer < 32) { drawsection = 1; - xoffset1 = (16-animatetimer) * 40; - xoffset2 = (18-animatetimer) * 40; - xoffset3 = (20-animatetimer) * 40; + xoffset1 = (22-animatetimer) * scradjust; + xoffset2 = (24-animatetimer) * scradjust; + xoffset3 = (26-animatetimer) * scradjust; + xoffset4 = (28-animatetimer) * scradjust; + xoffset5 = (30-animatetimer) * scradjust; + xoffset6 = (32-animatetimer) * scradjust; if (xoffset1 < 0) xoffset1 = 0; if (xoffset2 < 0) xoffset2 = 0; + if (xoffset3 < 0) xoffset3 = 0; + if (xoffset4 < 0) xoffset4 = 0; + if (xoffset5 < 0) xoffset5 = 0; } else + { drawsection = 1; + if (animatetimer == 32) + S_StartSound(NULL, sfx_s3k68); + } } if (drawsection == 1) { + const char *ringtext = "\x86" "50 RINGS, NO SHIELD"; + const char *tut1text = "\x86" "PRESS " "\x82" "SPIN"; + const char *tut2text = "\x86" "MID-" "\x82" "JUMP"; ttheight = 16; V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1); ttheight += V_LevelNameHeight(data.spec.passed3) + 2; V_DrawLevelTitle(data.spec.passedx3 + xoffset2, ttheight, 0, data.spec.passed3); ttheight += V_LevelNameHeight(data.spec.passed4) + 2; V_DrawLevelTitle(data.spec.passedx4 + xoffset3, ttheight, 0, data.spec.passed4); - } - else if (data.spec.passed1[0] != '\0') - { - ttheight = 24; - V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1); - ttheight += V_LevelNameHeight(data.spec.passed2) + 2; - V_DrawLevelTitle(data.spec.passedx2 + xoffset2, ttheight, 0, data.spec.passed2); + + ttheight = 108; + V_DrawLevelTitle(BASEVIDWIDTH/2 + xoffset4 - (V_LevelNameWidth(ringtext)/2), ttheight, 0, ringtext); + ttheight += V_LevelNameHeight(ringtext) + 2; + V_DrawLevelTitle(BASEVIDWIDTH/2 + xoffset5 - (V_LevelNameWidth(tut1text)/2), ttheight, 0, tut1text); + ttheight += V_LevelNameHeight(tut1text) + 2; + V_DrawLevelTitle(BASEVIDWIDTH/2 + xoffset6 - (V_LevelNameWidth(tut2text)/2), ttheight, 0, tut2text); } else { - ttheight = 24 + (V_LevelNameHeight(data.spec.passed2)/2) + 2; - V_DrawLevelTitle(data.spec.passedx2 + xoffset1, ttheight, 0, data.spec.passed2); + if (data.spec.passed1[0] != '\0') + { + ttheight = 24; + V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1); + ttheight += V_LevelNameHeight(data.spec.passed2) + 2; + V_DrawLevelTitle(data.spec.passedx2 + xoffset2, ttheight, 0, data.spec.passed2); + } + else + { + ttheight = 24 + (V_LevelNameHeight(data.spec.passed2)/2) + 2; + V_DrawLevelTitle(data.spec.passedx2 + xoffset1, ttheight, 0, data.spec.passed2); + } + + V_DrawScaledPatch(152 + xoffset3, 108, 0, data.spec.bonuspatch); + V_DrawTallNum(BASEVIDWIDTH + xoffset3 - 68, 109, 0, data.spec.bonus.points); + V_DrawScaledPatch(152 + xoffset4, 124, 0, data.spec.pscore); + V_DrawTallNum(BASEVIDWIDTH + xoffset4 - 68, 125, 0, data.spec.score); + + // Draw continues! + if (!multiplayer /* && (data.spec.continues & 0x80) */) // Always draw outside of netplay + { + UINT8 continues = data.spec.continues & 0x7F; + + V_DrawScaledPatch(152 + xoffset5, 150, 0, data.spec.pcontinues); + for (i = 0; i < continues; ++i) + { + if ((data.spec.continues & 0x80) && i == continues-1 && (endtic < 0 || intertic%20 < 10)) + break; + V_DrawContinueIcon(246 + xoffset5 - (i*12), 162, 0, *data.spec.playerchar, *data.spec.playercolor); + } + } } // draw the emeralds - if (intertic & 1) + //if (intertic & 1) { - INT32 emeraldx = 80; - for (i = 0; i < 7; ++i) + boolean drawthistic = !(ALL7EMERALDS(emeralds) && (intertic & 1)); + INT32 emeraldx = 152 - 3*28; + INT32 em = P_GetNextEmerald(); + + if (em == 7) { - if (emeralds & (1 << i)) - V_DrawScaledPatch(emeraldx, 74, 0, emeraldpics[i]); - emeraldx += 24; + if (!stagefailed) + { + fixed_t adjust = 2*(FINESINE(FixedAngle((intertic + 1)<<(FRACBITS-4)) & FINEMASK)); + V_DrawFixedPatch(152<<FRACBITS, (74<<FRACBITS) - adjust, FRACUNIT, 0, emeraldpics[0][em], NULL); + } } - } + else if (em < 7) + { + static UINT8 emeraldbounces = 0; + static INT32 emeraldmomy = 20; + static INT32 emeraldy = -40; - V_DrawScaledPatch(152, 108, 0, data.spec.bonuspatch); - V_DrawTallNum(BASEVIDWIDTH - 68, 109, 0, data.spec.bonus.points); - V_DrawScaledPatch(152, 124, 0, data.spec.pscore); - V_DrawTallNum(BASEVIDWIDTH - 68, 125, 0, data.spec.score); + if (drawthistic) + for (i = 0; i < 7; ++i) + { + if ((i != em) && (emeralds & (1 << i))) + V_DrawScaledPatch(emeraldx, 74, 0, emeraldpics[0][i]); + emeraldx += 28; + } - // Draw continues! - if (!multiplayer /* && (data.spec.continues & 0x80) */) // Always draw outside of netplay - { - UINT8 continues = data.spec.continues & 0x7F; + emeraldx = 152 + (em-3)*28; - V_DrawScaledPatch(152, 150, 0, data.spec.pcontinues); - for (i = 0; i < continues; ++i) - { - if ((data.spec.continues & 0x80) && i == continues-1 && (endtic < 0 || intertic%20 < 10)) - break; - V_DrawContinueIcon(246 - (i*12), 162, 0, *data.spec.playerchar, *data.spec.playercolor); + if (intertic <= 1) + { + emeraldbounces = 0; + emeraldmomy = 20; + emeraldy = -40; + } + else + { + if (!stagefailed) + { + if (emeraldbounces < 3) + { + emeraldmomy += 1; + emeraldy += emeraldmomy; + if (emeraldy > 74) + { + S_StartSound(NULL, sfx_tink); // tink + emeraldbounces++; + emeraldmomy = -(emeraldmomy/2); + emeraldy = 74; + } + } + } + else + { + emeraldmomy += 1; + emeraldy += emeraldmomy; + emeraldx += intertic - 6; + if (emeraldbounces < 1 && emeraldy > 74) + { + S_StartSound(NULL, sfx_shldls); // nope + emeraldbounces++; + emeraldmomy = -(emeraldmomy/2); + emeraldy = 74; + } + } + if (drawthistic) + V_DrawScaledPatch(emeraldx, emeraldy, 0, emeraldpics[0][em]); + } } } } @@ -434,7 +570,7 @@ void Y_IntermissionDrawer(void) V_DrawRightAlignedString(x+152, y, 0, va("%i", data.match.scores[i])); else if (intertype == int_race) { - if (players[data.match.num[i]].pflags & PF_TIMEOVER) + if (players[data.match.num[i]].pflags & PF_GAMETYPEOVER) snprintf(strtime, sizeof strtime, "DNF"); else snprintf(strtime, sizeof strtime, @@ -452,7 +588,7 @@ void Y_IntermissionDrawer(void) V_DrawRightAlignedString(x+152+BASEVIDWIDTH/2, y, 0, va("%u", data.match.scores[i])); else if (intertype == int_race) { - if (players[data.match.num[i]].pflags & PF_TIMEOVER) + if (players[data.match.num[i]].pflags & PF_GAMETYPEOVER) snprintf(strtime, sizeof strtime, "DNF"); else snprintf(strtime, sizeof strtime, "%i:%02i.%02i", G_TicsToMinutes(data.match.scores[i], true), @@ -602,7 +738,7 @@ void Y_IntermissionDrawer(void) // already constrained to 8 characters V_DrawString(x+36, y, V_ALLOWLOWERCASE, data.competition.name[i]); - if (players[data.competition.num[i]].pflags & PF_TIMEOVER) + if (players[data.competition.num[i]].pflags & PF_GAMETYPEOVER) snprintf(sstrtime, sizeof sstrtime, "Time Over"); else if (players[data.competition.num[i]].lives <= 0) snprintf(sstrtime, sizeof sstrtime, "Game Over"); @@ -707,7 +843,8 @@ void Y_Ticker(void) else if (mapheaderinfo[gamemap-1]->musintername[0] && S_MusicExists(mapheaderinfo[gamemap-1]->musintername, !midi_disabled, !digital_disabled)) S_ChangeMusicInternal(mapheaderinfo[gamemap-1]->musintername, false); // don't loop it else - S_ChangeMusicInternal("lclear", false); // don't loop it + S_ChangeMusicInternal("_clear", false); // don't loop it + tallydonetic = -1; } if (intertic < TICRATE) // one second pause before tally begins @@ -732,20 +869,23 @@ void Y_Ticker(void) data.coop.total += data.coop.bonuses[i].points; data.coop.bonuses[i].points = 0; } + if (data.coop.score > MAXSCORE) + data.coop.score = MAXSCORE; if (data.coop.bonuses[i].points > 0) anybonuses = true; } if (!anybonuses) { + tallydonetic = intertic; endtic = intertic + 3*TICRATE; // 3 second pause after end of tally - S_StartSound(NULL, sfx_chchng); // cha-ching! + S_StartSound(NULL, (gottoken ? sfx_token : sfx_chchng)); // cha-ching! // Update when done with tally if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback) { if (M_UpdateUnlockablesAndExtraEmblems()) - S_StartSound(NULL, sfx_ncitem); + S_StartSound(NULL, sfx_s3k68); G_SaveGameData(); } @@ -764,8 +904,7 @@ void Y_Ticker(void) { INT32 i; UINT32 oldscore = data.spec.score; - boolean skip = false; - static INT32 tallydonetic = 0; + boolean skip = false, super = false; if (!intertic) // first time only { @@ -779,23 +918,30 @@ void Y_Ticker(void) else if (mapheaderinfo[gamemap-1]->musintername[0] && S_MusicExists(mapheaderinfo[gamemap-1]->musintername, !midi_disabled, !digital_disabled)) S_ChangeMusicInternal(mapheaderinfo[gamemap-1]->musintername, false); // don't loop it else - S_ChangeMusicInternal("lclear", false); // don't loop it - tallydonetic = 0; + S_ChangeMusicInternal("_clear", false); // don't loop it + tallydonetic = -1; } - if (intertic < TICRATE) // one second pause before tally begins + if (intertic < 2*TICRATE) // TWO second pause before tally begins, thank you mazmazz return; for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && (players[i].cmd.buttons & BT_USE)) - skip = true; + if (playeringame[i]) + { + if (players[i].cmd.buttons & BT_USE) + skip = true; + if (players[i].charflags & SF_SUPER) + super = true; + } - if (tallydonetic != 0) + if (tallydonetic != -1 && ((data.spec.continues & 0x80) || (super && ALL7EMERALDS(emeralds)))) { - if (intertic > tallydonetic) + if ((intertic - tallydonetic) > (3*TICRATE)/2) { endtic = intertic + 4*TICRATE; // 4 second pause after end of tally - S_StartSound(NULL, sfx_flgcap); // cha-ching! + if (data.spec.continues & 0x80) + S_StartSound(NULL, sfx_s3kac); // bingly-bingly-bing! + } return; } @@ -811,18 +957,17 @@ void Y_Ticker(void) if (!data.spec.bonus.points) { - if (data.spec.continues & 0x80) // don't set endtic yet! - tallydonetic = intertic + (3*TICRATE)/2; - else // okay we're good. + tallydonetic = intertic; + if (!((data.spec.continues & 0x80) || (super && ALL7EMERALDS(emeralds)))) // don't set endtic yet! endtic = intertic + 4*TICRATE; // 4 second pause after end of tally - S_StartSound(NULL, sfx_chchng); // cha-ching! + S_StartSound(NULL, (gottoken ? sfx_token : sfx_chchng)); // cha-ching! // Update when done with tally if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback) { if (M_UpdateUnlockablesAndExtraEmblems()) - S_StartSound(NULL, sfx_ncitem); + S_StartSound(NULL, sfx_s3k68); G_SaveGameData(); } @@ -840,7 +985,7 @@ void Y_Ticker(void) else if (intertype == int_match || intertype == int_ctf || intertype == int_teammatch) // match { if (!intertic) // first time only - S_ChangeMusicInternal("racent", true); // loop it + S_ChangeMusicInternal("_inter", true); // loop it // If a player has left or joined, recalculate scores. if (data.match.numplayers != D_NumPlayers()) @@ -849,7 +994,7 @@ void Y_Ticker(void) else if (intertype == int_race || intertype == int_classicrace) // race { if (!intertic) // first time only - S_ChangeMusicInternal("racent", true); // loop it + S_ChangeMusicInternal("_inter", true); // loop it // Don't bother recalcing for race. It doesn't make as much sense. } @@ -878,13 +1023,13 @@ static void Y_UpdateRecordReplays(void) if ((mainrecords[gamemap-1]->time == 0) || (players[consoleplayer].realtime < mainrecords[gamemap-1]->time)) mainrecords[gamemap-1]->time = players[consoleplayer].realtime; - if ((UINT16)(players[consoleplayer].health - 1) > mainrecords[gamemap-1]->rings) - mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].health - 1); + if ((UINT16)(players[consoleplayer].rings) > mainrecords[gamemap-1]->rings) + mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].rings); // Save demo! bestdemo[255] = '\0'; lastdemo[255] = '\0'; - G_SetDemoTime(players[consoleplayer].realtime, players[consoleplayer].score, (UINT16)(players[consoleplayer].health-1)); + G_SetDemoTime(players[consoleplayer].realtime, players[consoleplayer].score, (UINT16)(players[consoleplayer].rings)); G_CheckDemoStatus(); I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755); @@ -894,14 +1039,14 @@ static void Y_UpdateRecordReplays(void) I_Error("Out of memory for replay filepath\n"); sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap)); - snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, cv_chooseskin.string); + snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, skins[cv_chooseskin.value-1].name); if (FIL_FileExists(lastdemo)) { UINT8 *buf; size_t len = FIL_ReadFile(lastdemo, &buf); - snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, cv_chooseskin.string); + snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, skins[cv_chooseskin.value-1].name); if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1) { // Better time, save this demo. if (FIL_FileExists(bestdemo)) @@ -910,7 +1055,7 @@ static void Y_UpdateRecordReplays(void) CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW RECORD TIME!"), M_GetText("Saved replay as"), bestdemo); } - snprintf(bestdemo, 255, "%s-%s-score-best.lmp", gpath, cv_chooseskin.string); + snprintf(bestdemo, 255, "%s-%s-score-best.lmp", gpath, skins[cv_chooseskin.value-1].name); if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<1))) { // Better score, save this demo. if (FIL_FileExists(bestdemo)) @@ -919,7 +1064,7 @@ static void Y_UpdateRecordReplays(void) CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW HIGH SCORE!"), M_GetText("Saved replay as"), bestdemo); } - snprintf(bestdemo, 255, "%s-%s-rings-best.lmp", gpath, cv_chooseskin.string); + snprintf(bestdemo, 255, "%s-%s-rings-best.lmp", gpath, skins[cv_chooseskin.value-1].name); if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<2))) { // Better rings, save this demo. if (FIL_FileExists(bestdemo)) @@ -939,8 +1084,7 @@ static void Y_UpdateRecordReplays(void) CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for Record Attack records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : ""); // Update timeattack menu's replay availability. - CV_AddValue(&cv_nextmap, 1); - CV_AddValue(&cv_nextmap, -1); + Nextmap_OnChange(); } // @@ -951,6 +1095,7 @@ static void Y_UpdateRecordReplays(void) void Y_StartIntermission(void) { INT32 i; + UINT8 completionEmblems = M_CompletionEmblems(); intertic = -1; @@ -1048,6 +1193,9 @@ void Y_StartIntermission(void) if (modeattacking == ATTACKING_RECORD) Y_UpdateRecordReplays(); + + if (completionEmblems) + CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)completionEmblems, completionEmblems > 1 ? "s" : ""); } for (i = 0; i < 4; ++i) @@ -1055,11 +1203,7 @@ void Y_StartIntermission(void) data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_STATIC); // get act number - if (mapheaderinfo[prevmap]->actnum) - data.coop.ttlnum = W_CachePatchName(va("TTL%.2d", mapheaderinfo[prevmap]->actnum), - PU_STATIC); - else - data.coop.ttlnum = W_CachePatchName("TTL01", PU_STATIC); + data.coop.actnum = mapheaderinfo[gamemap-1]->actnum; // get background patches widebgpatch = W_CachePatchName("INTERSCW", PU_STATIC); @@ -1148,6 +1292,10 @@ void Y_StartIntermission(void) { if (!stagefailed) mapvisited[gamemap-1] |= MV_BEATEN; + + // all emeralds/ultimate/perfect emblems won't be possible in ss, oh well? + if (completionEmblems) + CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)completionEmblems, completionEmblems > 1 ? "s" : ""); } // give out ring bonuses @@ -1205,7 +1353,7 @@ void Y_StartIntermission(void) data.spec.passed1[sizeof data.spec.passed1 - 1] = '\0'; strcpy(data.spec.passed2, "GOT THEM ALL!"); - if (skins[players[consoleplayer].skin].flags & SF_SUPER) + if (players[consoleplayer].charflags & SF_SUPER) { strcpy(data.spec.passed3, "CAN NOW BECOME"); snprintf(data.spec.passed4, @@ -1226,6 +1374,11 @@ void Y_StartIntermission(void) else strcpy(data.spec.passed1, "YOU GOT"); strcpy(data.spec.passed2, "A CHAOS EMERALD"); + if (P_GetNextEmerald() > 6) + { + data.spec.passed2[15] = '?'; + data.spec.passed2[16] = '\0'; + } } data.spec.passedx1 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed1))/2; data.spec.passedx2 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed2))/2; @@ -1478,7 +1631,7 @@ static void Y_CalculateCompetitionWinners(void) bestat[j] = true; times[i] = players[i].realtime; - rings[i] = (UINT32)max(players[i].health-1, 0); + rings[i] = (UINT32)max(players[i].rings, 0); maxrings[i] = (UINT32)players[i].totalring; monitors[i] = (UINT32)players[i].numboxes; scores[i] = (UINT32)min(players[i].score, 99999990); @@ -1493,7 +1646,7 @@ static void Y_CalculateCompetitionWinners(void) else bestat[0] = false; - if (max(players[i].health-1, 0) >= max(players[j].health-1, 0)) + if (max(players[i].rings, 0) >= max(players[j].rings, 0)) points[i]++; else bestat[1] = false; @@ -1593,8 +1746,7 @@ static void Y_SetTimeBonus(player_t *player, y_bonus_t *bstruct) // calculate time bonus secs = player->realtime / TICRATE; - if (secs < 30) /* :30 */ bonus = 100000; - else if (secs < 45) /* :45 */ bonus = 50000; + if (secs < 30) /* :30 */ bonus = 50000; else if (secs < 60) /* 1:00 */ bonus = 10000; else if (secs < 90) /* 1:30 */ bonus = 5000; else if (secs < 120) /* 2:00 */ bonus = 4000; @@ -1617,7 +1769,27 @@ static void Y_SetRingBonus(player_t *player, y_bonus_t *bstruct) { strncpy(bstruct->patch, "YB_RING", sizeof(bstruct->patch)); bstruct->display = true; - bstruct->points = max(0, (player->health-1) * 100); + bstruct->points = max(0, (player->rings) * 100); +} + +// +// Y_SetNightsBonus +// +static void Y_SetNightsBonus(player_t *player, y_bonus_t *bstruct) +{ + strncpy(bstruct->patch, "YB_NIGHT", sizeof(bstruct->patch)); + bstruct->display = true; + bstruct->points = player->totalmarescore; +} + +// +// Y_SetLapBonus +// +static void Y_SetLapBonus(player_t *player, y_bonus_t *bstruct) +{ + strncpy(bstruct->patch, "YB_LAP", sizeof(bstruct->patch)); + bstruct->display = true; + bstruct->points = max(0, player->totalmarebonuslap * 1000); } // @@ -1665,9 +1837,9 @@ static void Y_SetPerfectBonus(player_t *player, y_bonus_t *bstruct) for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i]) continue; - sharedringtotal += players[i].health - 1; + sharedringtotal += players[i].rings; } - if (!sharedringtotal || sharedringtotal < nummaprings) + if (!sharedringtotal || nummaprings == -1 || sharedringtotal < nummaprings) data.coop.gotperfbonus = 0; else data.coop.gotperfbonus = 1; @@ -1681,7 +1853,7 @@ static void Y_SetPerfectBonus(player_t *player, y_bonus_t *bstruct) // This list can be extended in the future with SOC/Lua, perhaps. typedef void (*bonus_f)(player_t *, y_bonus_t *); -bonus_f bonuses_list[4][4] = { +bonus_f bonuses_list[6][4] = { { Y_SetNullBonus, Y_SetNullBonus, @@ -1706,6 +1878,18 @@ bonus_f bonuses_list[4][4] = { Y_SetRingBonus, Y_SetPerfectBonus, }, + { + Y_SetNullBonus, + Y_SetNightsBonus, + Y_SetLapBonus, + Y_SetNullBonus, + }, + { + Y_SetNullBonus, + Y_SetLinkBonus, + Y_SetLapBonus, + Y_SetNullBonus, + }, }; @@ -1740,15 +1924,19 @@ static void Y_AwardCoopBonuses(void) { (bonuses_list[bonusnum][j])(&players[i], &localbonuses[j]); players[i].score += localbonuses[j].points; + if (players[i].score > MAXSCORE) + players[i].score = MAXSCORE; } - ptlives = (!ultimatemode && !modeattacking) ? max((players[i].score/50000) - (oldscore/50000), 0) : 0; + ptlives = min( + (INT32)((!ultimatemode && !modeattacking && players[i].lives != INFLIVES) ? max((INT32)((players[i].score/50000) - (oldscore/50000)), (INT32)0) : 0), + (INT32)(mapheaderinfo[prevmap]->maxbonuslives < 0 ? INT32_MAX : mapheaderinfo[prevmap]->maxbonuslives)); if (ptlives) P_GivePlayerLives(&players[i], ptlives); if (i == consoleplayer) { - data.coop.gotlife = ptlives; + data.coop.gotlife = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? 0 : ptlives); M_Memcpy(&data.coop.bonuses, &localbonuses, sizeof(data.coop.bonuses)); } } @@ -1777,23 +1965,25 @@ static void Y_AwardSpecialStageBonus(void) if (!playeringame[i] || players[i].lives < 1) // not active or game over Y_SetNullBonus(&players[i], &localbonus); - else if (useNightsSS) // Link instead of Score - Y_SetLinkBonus(&players[i], &localbonus); + else if (maptol & TOL_NIGHTS) // Mare score instead of Rings + Y_SetNightsBonus(&players[i], &localbonus); else Y_SetRingBonus(&players[i], &localbonus); players[i].score += localbonus.points; + if (players[i].score > MAXSCORE) + players[i].score = MAXSCORE; // grant extra lives right away since tally is faked - ptlives = (!ultimatemode && !modeattacking) ? max((players[i].score/50000) - (oldscore/50000), 0) : 0; - if (ptlives) - P_GivePlayerLives(&players[i], ptlives); + ptlives = min( + (INT32)((!ultimatemode && !modeattacking && players[i].lives != INFLIVES) ? max((INT32)((players[i].score/50000) - (oldscore/50000)), (INT32)0) : 0), + (INT32)(mapheaderinfo[prevmap]->maxbonuslives < 0 ? INT32_MAX : mapheaderinfo[prevmap]->maxbonuslives)); + P_GivePlayerLives(&players[i], ptlives); if (i == consoleplayer) { + data.spec.gotlife = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? 0 : ptlives); M_Memcpy(&data.spec.bonus, &localbonus, sizeof(data.spec.bonus)); - data.spec.gotlife = ptlives; - // Continues related data.spec.continues = min(players[i].continues, 8); if (players[i].gotcontinue) @@ -1857,7 +2047,6 @@ static void Y_UnloadData(void) { case int_coop: // unload the coop and single player patches - UNLOAD(data.coop.ttlnum); UNLOAD(data.coop.bonuspatches[3]); UNLOAD(data.coop.bonuspatches[2]); UNLOAD(data.coop.bonuspatches[1]); diff --git a/src/z_zone.c b/src/z_zone.c index a3e13422f9bed1d569a84eb25f9419993ed66309..001c69bb3c9f3adc1a689537a2fc155d042bcb43 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -82,6 +82,59 @@ typedef struct memblock_s struct memblock_s *next, *prev; } ATTRPACK memblock_t; +// both the head and tail of the zone memory block list +static memblock_t head; + +// +// Function prototypes +// +static void Command_Memfree_f(void); +#ifdef ZDEBUG +static void Command_Memdump_f(void); +#endif + +// -------------------------- +// Zone memory initialisation +// -------------------------- + +/** Initialises zone memory. + * Used at game startup. + * + * \sa I_GetFreeMem, Command_Memfree_f, Command_Memdump_f + */ +void Z_Init(void) +{ + UINT32 total, memfree; + + memset(&head, 0x00, sizeof(head)); + + head.next = head.prev = &head; + + memfree = I_GetFreeMem(&total)>>20; + CONS_Printf("System memory: %uMB - Free: %uMB\n", total>>20, memfree); + + // Note: This allocates memory. Watch out. + COM_AddCommand("memfree", Command_Memfree_f); + +#ifdef ZDEBUG + COM_AddCommand("memdump", Command_Memdump_f); +#endif +} + + +// ---------------------- +// 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) @@ -131,32 +184,12 @@ static memblock_t *Ptr2Memblock(void *ptr, const char* func) } -static memblock_t head; - -static void Command_Memfree_f(void); -#ifdef ZDEBUG -static void Command_Memdump_f(void); -#endif - -void Z_Init(void) -{ - UINT32 total, memfree; - - memset(&head, 0x00, sizeof(head)); - - head.next = head.prev = &head; - - memfree = I_GetFreeMem(&total)>>20; - CONS_Printf("System memory: %uMB - Free: %uMB\n", total>>20, memfree); - - // Note: This allocates memory. Watch out. - COM_AddCommand("memfree", Command_Memfree_f); - -#ifdef ZDEBUG - COM_AddCommand("memdump", Command_Memdump_f); -#endif -} - +/** Frees allocated memory. + * + * \param ptr A pointer to allocated memory, + * assumed to have been allocated with Z_Malloc/Z_Calloc. + * \sa Z_FreeTags + */ #ifdef ZDEBUG void Z_Free2(void *ptr, const char *file, INT32 line) #else @@ -206,7 +239,11 @@ void Z_Free(void *ptr) #endif } -// malloc() that doesn't accept failure. +/** malloc() that doesn't accept failure. + * + * \param size Amount of memory to be allocated, in bytes. + * \return A pointer to the allocated memory. + */ static void *xm(size_t size) { const size_t padedsize = size+sizeof (size_t); @@ -220,10 +257,6 @@ static void *xm(size_t size) if (p == NULL) { -#if defined (_NDS) | defined (_PSP) - // Temporary-ish debugging measure - Command_Memfree_f(); -#endif I_Error("Out of memory allocating %s bytes", sizeu1(size)); } } @@ -231,10 +264,18 @@ static void *xm(size_t size) return p; } -// Z_Malloc -// You can pass Z_Malloc() a NULL user if the tag is less than -// PU_PURGELEVEL. - +/** The Z_MallocAlign function. + * Allocates a block of memory, adds it to a linked list so we can keep track of it. + * + * \param size Amount of memory to be allocated, in bytes. + * \param tag Purge tag. + * \param user The address of a pointer to the memory to be allocated. + * When the memory is freed by Z_Free later, + * the pointer at this address will then be automatically set to NULL. + * \param alignbits The alignment of the memory to be allocated, in bits. Can be 0. + * \note You can pass Z_Malloc() a NULL user if the tag is less than PU_PURGELEVEL. + * \sa Z_CallocAlign, Z_ReallocAlign + */ #ifdef ZDEBUG void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) @@ -311,6 +352,19 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) return given; } +/** The Z_CallocAlign function. + * Allocates a block of memory, adds it to a linked list so we can keep track of it. + * Unlike Z_MallocAlign, this also initialises the bytes to zero. + * + * \param size Amount of memory to be allocated, in bytes. + * \param tag Purge tag. + * \param user The address of a pointer to the memory to be allocated. + * When the memory is freed by Z_Free later, + * the pointer at this address will then be automatically set to NULL. + * \param alignbits The alignment of the memory to be allocated, in bits. Can be 0. + * \note You can pass Z_Calloc() a NULL user if the tag is less than PU_PURGELEVEL. + * \sa Z_MallocAlign, Z_ReallocAlign + */ #ifdef ZDEBUG void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) #else @@ -327,10 +381,26 @@ void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) #endif } +/** The Z_ReallocAlign function. + * Reallocates a block of memory with a new size. + * + * \param ptr A pointer to allocated memory, + * assumed to have been allocated with Z_Malloc/Z_Calloc. + * If NULL, this function instead acts as a wrapper for Z_CallocAlign. + * \param size New size of memory block, in bytes. + * If zero, then the memory is freed and NULL is returned. + * \param tag New purge tag. + * \param user The address of a pointer to the memory to be reallocated. + * This can be a different user to the one originally assigned to the memory block. + * \param alignbits The alignment of the memory to be allocated, in bits. Can be 0. + * \return A pointer to the reallocated memory. Can be NULL if memory was freed. + * \note You can pass Z_Realloc() a NULL user if the tag is less than PU_PURGELEVEL. + * \sa Z_MallocAlign, Z_CallocAlign + */ #ifdef ZDEBUG void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) #else -void *Z_ReallocAlign(void *ptr, size_t size,INT32 tag, void *user, INT32 alignbits) +void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits) #endif { void *rez; @@ -397,6 +467,11 @@ void *Z_ReallocAlign(void *ptr, size_t size,INT32 tag, void *user, INT32 alignb return rez; } +/** Frees all memory for a given set of tags. + * + * \param lowtag The lowest tag to consider. + * \param hightag The highest tag to consider. + */ void Z_FreeTags(INT32 lowtag, INT32 hightag) { memblock_t *block, *next; @@ -411,22 +486,25 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag) } } -// -// Z_CheckMemCleanup -// -// TODO: Currently blocks >= PU_PURGELEVEL are freed every -// CLEANUPCOUNT. It might be better to keep track of -// the total size of all purgable memory and free it when the -// size exceeds some value. -// -// This was in Z_Malloc, but was freeing data at -// unsafe times. Now it is only called when it is safe -// to cleanup memory. +// ----------------- +// Utility functions +// ----------------- +// starting value of nextcleanup #define CLEANUPCOUNT 2000 +// number of function calls left before next cleanup static INT32 nextcleanup = CLEANUPCOUNT; +/** This was in Z_Malloc, but was freeing data at + * unsafe times. Now it is only called when it is safe + * to cleanup memory. + * + * \todo Currently blocks >= PU_PURGELEVEL are freed every + * CLEANUPCOUNT. It might be better to keep track of + * the total size of all purgable memory and free it when the + * size exceeds some value. + */ void Z_CheckMemCleanup(void) { if (nextcleanup-- == 0) @@ -542,10 +620,21 @@ void Z_CheckHeap(INT32 i) } } +// ------------------------ +// Zone memory modification +// ------------------------ + +/** Changes a memory block's purge tag. + * + * \param ptr A pointer to allocated memory, + * assumed to have been allocated with Z_Malloc/Z_Calloc. + * \param tag The new tag. + * \sa Z_SetUser + */ #ifdef PARANOIA void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line) #else -void Z_ChangeTag2(void *ptr, INT32 tag) +void Z_ChangeTag(void *ptr, INT32 tag) #endif { memblock_t *block; @@ -587,12 +676,59 @@ void Z_ChangeTag2(void *ptr, INT32 tag) block->tag = tag; } +/** Changes a memory block's user. + * + * \param ptr A pointer to allocated memory, + * assumed to have been allocated with Z_Malloc/Z_Calloc. + * \param newuser The new user for the memory block. + * \sa Z_ChangeTag + */ +#ifdef PARANOIA +void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line) +#else +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 + +#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); +#endif + + if (block->tag >= PU_PURGELEVEL && newuser == NULL) + I_Error("Internal memory management error: " + "tried to make block purgable but it has no owner"); + + block->user = (void*)newuser; + *newuser = ptr; +} + +// ----------------- +// Zone memory usage +// ----------------- + /** Calculates memory usage for a given set of tags. + * * \param lowtag The lowest tag to consider. * \param hightag The highest tag to consider. * \return Number of bytes currently allocated in the heap for the * given tags. - * \sa Z_TagUsage */ size_t Z_TagsUsage(INT32 lowtag, INT32 hightag) { @@ -609,18 +745,20 @@ size_t Z_TagsUsage(INT32 lowtag, INT32 hightag) return cnt; } -size_t Z_TagUsage(INT32 tagnum) -{ - return Z_TagsUsage(tagnum, tagnum); -} +// ----------------------- +// Miscellaneous functions +// ----------------------- -void Command_Memfree_f(void) +/** The function called by the "memfree" console command. + * Prints the memory being used by each part of the game to the console. + */ +static void Command_Memfree_f(void) { UINT32 freebytes, totalbytes; Z_CheckHeap(-1); CONS_Printf("\x82%s", M_GetText("Memory Info\n")); - CONS_Printf(M_GetText("Total heap used : %7s KB\n"), sizeu1(Z_TagsUsage(0, INT32_MAX)>>10)); + CONS_Printf(M_GetText("Total heap used : %7s KB\n"), sizeu1(Z_TotalUsage()>>10)); CONS_Printf(M_GetText("Static : %7s KB\n"), sizeu1(Z_TagUsage(PU_STATIC)>>10)); CONS_Printf(M_GetText("Static (sound) : %7s KB\n"), sizeu1(Z_TagUsage(PU_SOUND)>>10)); CONS_Printf(M_GetText("Static (music) : %7s KB\n"), sizeu1(Z_TagUsage(PU_MUSIC)>>10)); @@ -648,6 +786,11 @@ void Command_Memfree_f(void) } #ifdef ZDEBUG +/** The function called by the "memdump" console command. + * Prints zone memory debugging information (i.e. tag, size, location in code allocated). + * Can be all memory allocated in game, or between a set of tags (if -min/-max args used). + * This command is available only if ZDEBUG is enabled. + */ static void Command_Memdump_f(void) { memblock_t *block; @@ -669,45 +812,12 @@ static void Command_Memdump_f(void) } #endif -// Creates a copy of a string. +/** Creates a copy of a string. + * + * \param s The string to be copied. + * \return A copy of the string, allocated in zone memory. + */ char *Z_StrDup(const char *s) { return strcpy(ZZ_Alloc(strlen(s) + 1), s); } - - -#ifdef PARANOIA -void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line) -#else -void Z_SetUser2(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 - -#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); -#endif - - if (block->tag >= PU_PURGELEVEL && newuser == NULL) - I_Error("Internal memory management error: " - "tried to make block purgable but it has no owner"); - - block->user = (void*)newuser; - *newuser = ptr; -} diff --git a/src/z_zone.h b/src/z_zone.h index 1424a3782b9263cb40891589c8495bcd34e4dcfb..8d32e74f11a87466bab95d2e507f9cf37b03b6ac 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -30,96 +30,115 @@ //#define ZDEBUG // -// ZONE MEMORY -// PU - purge tags. -// Tags < PU_LEVEL are not purged until freed explicitly. -#define PU_STATIC 1 // static entire execution time -#define PU_LUA 2 // static entire execution time -- used by lua so it doesn't get caught in loops forever - -#define PU_SOUND 11 // static while playing -#define PU_MUSIC 12 // static while playing -#define PU_HUDGFX 13 // static until WAD added - -#define PU_HWRPATCHINFO 21 // Hardware GLPatch_t struct for OpenGL texture cache -#define PU_HWRPATCHCOLMIPMAP 22 // Hardware GLMipmap_t struct colromap variation of patch - -#define PU_HWRCACHE 48 // static until unlocked -#define PU_CACHE 49 // static until unlocked - -// Tags s.t. PU_LEVEL <= tag < PU_PURGELEVEL are purged at level start -#define PU_LEVEL 50 // static until level exited -#define PU_LEVSPEC 51 // a special thinker in a level -#define PU_HWRPLANE 52 - -// Tags >= PU_PURGELEVEL are purgable whenever needed -#define PU_PURGELEVEL 100 -#define PU_CACHE_UNLOCKED 101 -#define PU_HWRCACHE_UNLOCKED 102 // 'second-level' cache for graphics - // stored in hardware format and downloaded as needed -#define PU_HWRPATCHINFO_UNLOCKED 103 +// Purge tags +// +// Now they are an enum! -- Monster Iestyn 15/02/18 +// +enum +{ + // Tags < PU_LEVEL are not purged until freed explicitly. + PU_STATIC = 1, // static entire execution time + PU_LUA = 2, // static entire execution time -- used by lua so it doesn't get caught in loops forever + + PU_SOUND = 11, // static while playing + PU_MUSIC = 12, // static while playing + PU_HUDGFX = 13, // static until WAD added + + PU_HWRPATCHINFO = 21, // Hardware GLPatch_t struct for OpenGL texture cache + PU_HWRPATCHCOLMIPMAP = 22, // Hardware GLMipmap_t struct colormap variation of patch + + PU_HWRCACHE = 48, // static until unlocked + PU_CACHE = 49, // static until unlocked + + // Tags s.t. PU_LEVEL <= tag < PU_PURGELEVEL are purged at level start + PU_LEVEL = 50, // static until level exited + PU_LEVSPEC = 51, // a special thinker in a level + PU_HWRPLANE = 52, // if ZPLANALLOC is enabled in hw_bsp.c, this is used to alloc polygons for OpenGL + + // Tags >= PU_PURGELEVEL are purgable whenever needed + PU_PURGELEVEL = 100, // Note: this is never actually used as a tag + PU_CACHE_UNLOCKED = 101, // Note: unused + PU_HWRCACHE_UNLOCKED = 102, // 'unlocked' PU_HWRCACHE memory: + // 'second-level' cache for graphics + // stored in hardware format and downloaded as needed + PU_HWRPATCHINFO_UNLOCKED = 103, // 'unlocked' PU_HWRPATCHINFO memory +}; +// +// Zone memory initialisation +// void Z_Init(void); -void Z_FreeTags(INT32 lowtag, INT32 hightag); -void Z_CheckMemCleanup(void); -void Z_CheckHeap(INT32 i); -#ifdef PARANOIA -void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line); -#else -void Z_ChangeTag2(void *ptr, INT32 tag); -#endif -#ifdef PARANOIA -void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line); -#else -void Z_SetUser2(void *ptr, void **newuser); -#endif +// +// Zone memory allocation +// +// enable ZDEBUG to get the file + line the functions were called from +// for ZZ_Alloc, see doomdef.h +// +// Z_Free and alloc with alignment #ifdef ZDEBUG -#define Z_Free(p) Z_Free2(p, __FILE__, __LINE__) +#define Z_Free(p) Z_Free2(p, __FILE__, __LINE__) +#define Z_MallocAlign(s,t,u,a) Z_Malloc2(s, t, u, a, __FILE__, __LINE__) +#define Z_CallocAlign(s,t,u,a) Z_Calloc2(s, t, u, a, __FILE__, __LINE__) +#define Z_ReallocAlign(p,s,t,u,a) Z_Realloc2(p,s, t, u, a, __FILE__, __LINE__) void Z_Free2(void *ptr, const char *file, INT32 line); -#define Z_Malloc(s,t,u) Z_Malloc2(s, t, u, 0, __FILE__, __LINE__) -#define Z_MallocAlign(s,t,u,a) Z_Malloc2(s, t, u, a, __FILE__, __LINE__) void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1); -#define Z_Calloc(s,t,u) Z_Calloc2(s, t, u, 0, __FILE__, __LINE__) -#define Z_CallocAlign(s,t,u,a) Z_Calloc2(s, t, u, a, __FILE__, __LINE__) void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1); -#define Z_Realloc(p,s,t,u) Z_Realloc2(p, s, t, u, 0, __FILE__, __LINE__) -#define Z_ReallocAlign(p,s,t,u,a) Z_Realloc2(p,s, t, u, a, __FILE__, __LINE__) void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(2); #else void Z_Free(void *ptr); void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(1); -#define Z_Malloc(s,t,u) Z_MallocAlign(s, t, u, 0) void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(1); -#define Z_Calloc(s,t,u) Z_CallocAlign(s, t, u, 0) -void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(2) ; -#define Z_Realloc(p, s,t,u) Z_ReallocAlign(p, s, t, u, 0) +void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(2); #endif -size_t Z_TagUsage(INT32 tagnum); -size_t Z_TagsUsage(INT32 lowtag, INT32 hightag); +// Alloc with no alignment +#define Z_Malloc(s,t,u) Z_MallocAlign(s, t, u, 0) +#define Z_Calloc(s,t,u) Z_CallocAlign(s, t, u, 0) +#define Z_Realloc(p,s,t,u) Z_ReallocAlign(p, s, t, u, 0) -char *Z_StrDup(const char *in); +// Free all memory by tag +// these don't give line numbers for ZDEBUG currently though +// (perhaps this should be changed in future?) +#define Z_FreeTag(tagnum) Z_FreeTags(tagnum, tagnum) +void Z_FreeTags(INT32 lowtag, INT32 hightag); + +// +// Utility functions +// +void Z_CheckMemCleanup(void); +void Z_CheckHeap(INT32 i); -// This is used to get the local FILE : LINE info from CPP -// prior to really call the function in question. +// +// Zone memory modification +// +// enable PARANOIA to get the file + line the functions were called from // #ifdef PARANOIA #define Z_ChangeTag(p,t) Z_ChangeTag2(p, t, __FILE__, __LINE__) +#define Z_SetUser(p,u) Z_SetUser2(p, u, __FILE__, __LINE__) +void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line); +void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line); #else -#define Z_ChangeTag(p,t) Z_ChangeTag2(p, t) +void Z_ChangeTag(void *ptr, INT32 tag); +void Z_SetUser(void *ptr, void **newuser); #endif -#ifdef PARANOIA -#define Z_SetUser(p,u) Z_SetUser2(p, u, __FILE__, __LINE__) -#else -#define Z_SetUser(p,u) Z_SetUser2(p, u) -#endif +// +// Zone memory usage +// +// Note: These give the memory used in bytes, +// shift down by 10 to convert to KB +// +#define Z_TagUsage(tagnum) Z_TagsUsage(tagnum, tagnum) +size_t Z_TagsUsage(INT32 lowtag, INT32 hightag); +#define Z_TotalUsage() Z_TagsUsage(0, INT32_MAX) -#ifdef _NDS ///TODO: need a lock reference system -#define Z_Unlock(p) Z_ChangeTag(p, PU_CACHE_UNLOCKED) -#else -#define Z_Unlock(p) (void)p -#endif +// +// Miscellaneous functions +// +char *Z_StrDup(const char *in); +#define Z_Unlock(p) (void)p // TODO: remove this now that NDS code has been removed #endif