diff --git a/.gitlab/ci/templates/srb2ci.yml b/.gitlab/ci/templates/srb2ci.yml index 3716d9df921407cb29081af301a5b6a3d92db459..bdf8a3ed66d8126559c25e5563da432da41932e0 100644 --- a/.gitlab/ci/templates/srb2ci.yml +++ b/.gitlab/ci/templates/srb2ci.yml @@ -61,7 +61,7 @@ - - | # apt_update echo -e "\e[0Ksection_start:`date +%s`:apt_update[collapsed=true]\r\e[0KUpdating APT listing" - - apt-get update + - timeout 2m apt-get update || timeout 2m apt-get update - | # apt_update echo -e "\e[0Ksection_end:`date +%s`:apt_update\r\e[0K" diff --git a/assets/CMakeLists.txt b/assets/CMakeLists.txt index dfb2f4180db7dbbae9a454a6f939aeda9e6f26a4..68c84819513075a90e21917ce797acf893c2a40d 100644 --- a/assets/CMakeLists.txt +++ b/assets/CMakeLists.txt @@ -27,10 +27,10 @@ list(TRANSFORM SRB2_ASSETS_DOCS PREPEND "${SRB2_ASSET_DIRECTORY_ABSOLUTE}") set(SRB2_ASSETS_GAME "srb2.pk3" - "player.dta" + "characters.pk3" "zones.pk3" "patch.pk3" - "music.dta" + "music.pk3" "models.dat" ) list(TRANSFORM SRB2_ASSETS_GAME PREPEND "/") diff --git a/assets/README.txt b/assets/README.txt index 2c522966e87099c0ea9b9d4c9688c78b698d823f..fe238dec09ec619becc718ab0fc60b7224e407e4 100644 --- a/assets/README.txt +++ b/assets/README.txt @@ -39,7 +39,7 @@ https://facebook.com/SonicRoboBlast2 COPYRIGHT AND DISCLAIMER -Design and content in Sonic Robo Blast 2 is copyright 1998-2024 by Sonic Team Jr. +Design and content in Sonic Robo Blast 2 is copyright 1998-2025 by Sonic Team Jr. All original material in this game is copyrighted by their respective owners, and no copyright infringement is intended. Sonic Team Jr. is in no way affiliated with SEGA or Sonic Team, and we do not claim ownership of any of SEGA's intellectual property used in SRB2. diff --git a/assets/debian-template/copyright b/assets/debian-template/copyright index 649e796fb1ca5a6c652d34d0a4784d9e835627f8..71d2cf583d6e6e624ad7a12638ea65df775f4223 100644 --- a/assets/debian-template/copyright +++ b/assets/debian-template/copyright @@ -12,7 +12,7 @@ Upstream Author(s): Copyright: - Copyright (C) 1998-2024 by Sonic Team Junior + Copyright (C) 1998-2025 by Sonic Team Junior License: @@ -21,7 +21,7 @@ License: The Debian packaging is: Copyright (C) 2010 Callum Dickinson <gcfreak_ag20@hotmail.com> - Copyright (C) 2010-2024 by Sonic Team Junior <stjr@srb2.org> + Copyright (C) 2010-2025 by Sonic Team Junior <stjr@srb2.org> and is licensed under the GPL version 2, see "/usr/share/common-licenses/GPL-2". diff --git a/cmake/Modules/Findlibopenmpt.cmake b/cmake/Modules/Findlibopenmpt.cmake index d7de22134831c1e0edc8b3b6e62ed42abd69287f..96cc3102677c0639bed76fe28cf60efd13e63429 100644 --- a/cmake/Modules/Findlibopenmpt.cmake +++ b/cmake/Modules/Findlibopenmpt.cmake @@ -1,14 +1,16 @@ include(LibFindMacros) -libfind_pkg_check_modules(libopenmpt_PKGCONF openmpt) +libfind_pkg_check_modules(libopenmpt_PKGCONF openmpt libopenmpt) find_path(libopenmpt_INCLUDE_DIR NAMES libopenmpt.h PATHS ${libopenmpt_PKGCONF_INCLUDE_DIRS} - "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include/libopenmpt" - "/usr/include/libopenmpt" - "/usr/local/include/libopenmpt" + "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include" + "/usr/include" + "/usr/local/include" + PATH_SUFFIXES ++ libopenmpt ) find_library(libopenmpt_LIBRARY diff --git a/debian-template/copyright b/debian-template/copyright index 649e796fb1ca5a6c652d34d0a4784d9e835627f8..71d2cf583d6e6e624ad7a12638ea65df775f4223 100644 --- a/debian-template/copyright +++ b/debian-template/copyright @@ -12,7 +12,7 @@ Upstream Author(s): Copyright: - Copyright (C) 1998-2024 by Sonic Team Junior + Copyright (C) 1998-2025 by Sonic Team Junior License: @@ -21,7 +21,7 @@ License: The Debian packaging is: Copyright (C) 2010 Callum Dickinson <gcfreak_ag20@hotmail.com> - Copyright (C) 2010-2024 by Sonic Team Junior <stjr@srb2.org> + Copyright (C) 2010-2025 by Sonic Team Junior <stjr@srb2.org> and is licensed under the GPL version 2, see "/usr/share/common-licenses/GPL-2". diff --git a/scripts/arm64-osx-1015.cmake b/scripts/arm64-osx-1015.cmake new file mode 100644 index 0000000000000000000000000000000000000000..224430bc1fe787c70db8480cf86e84f1e8bcb637 --- /dev/null +++ b/scripts/arm64-osx-1015.cmake @@ -0,0 +1,7 @@ +set(VCPKG_TARGET_ARCHITECTURE arm64) +set(VCPKG_OSX_DEPLOYMENT_TARGET 10.15) +set(VCPKG_CRT_LINKAGE dynamic) +set(VCPKG_LIBRARY_LINKAGE static) + +set(VCPKG_CMAKE_SYSTEM_NAME Darwin) +set(VCPKG_OSX_ARCHITECTURES arm64) diff --git a/scripts/make-macos-universal.sh b/scripts/make-macos-universal.sh new file mode 100755 index 0000000000000000000000000000000000000000..f1b17516c16fec2d333e5bfc9e3cc9fbfadb0499 --- /dev/null +++ b/scripts/make-macos-universal.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +# Makes a fused macOS Universal app bundle in the arm64 release preset dir +# Only works if in master branch or in source tarball + +set -e + +rm -rf "build/ninja-x64_osx_vcpkg-release" +rm -rf "build/ninja-arm64_osx_vcpkg-release" +cmake --preset ninja-x64_osx_vcpkg-release -DVCPKG_OVERLAY_TRIPLETS=scripts/ -DVCPKG_TARGET_TRIPLET=x64-osx-1015 -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 "-DSRB2_SDL2_EXE_NAME=srb2" +cmake --build --preset ninja-x64_osx_vcpkg-release +cmake --preset ninja-arm64_osx_vcpkg-release -DVCPKG_OVERLAY_TRIPLETS=scripts/ -DVCPKG_TARGET_TRIPLET=arm64-osx-1015 -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 "-DSRB2_SDL2_EXE_NAME=srb2" +cmake --build --preset ninja-arm64_osx_vcpkg-release + +mkdir -p build/dist +rm -rf "build/dist/Sonic Robo Blast 2.app" "build/dist/srb2.app" + +cp -r build/ninja-arm64_osx_vcpkg-release/bin/srb2.app build/dist/ + +lipo -create \ + -output "build/dist/srb2.app/Contents/MacOS/srb2" \ + build/ninja-x64_osx_vcpkg-release/bin/srb2.app/Contents/MacOS/srb2 \ + build/ninja-arm64_osx_vcpkg-release/bin/srb2.app/Contents/MacOS/srb2 + +mv build/dist/srb2.app "build/dist/Sonic Robo Blast 2.app" diff --git a/scripts/x64-osx-1015.cmake b/scripts/x64-osx-1015.cmake new file mode 100644 index 0000000000000000000000000000000000000000..5f0c7b66e0e4c1c9969ed6963ddcc99cef9db64c --- /dev/null +++ b/scripts/x64-osx-1015.cmake @@ -0,0 +1,7 @@ +set(VCPKG_TARGET_ARCHITECTURE x64) +set(VCPKG_OSX_DEPLOYMENT_TARGET 10.15) +set(VCPKG_CRT_LINKAGE dynamic) +set(VCPKG_LIBRARY_LINKAGE static) + +set(VCPKG_CMAKE_SYSTEM_NAME Darwin) +set(VCPKG_OSX_ARCHITECTURES x86_64) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 20caecf7bd6a65a20631318799016da319d3f13d..fbd29cddda5e3caae29aaee01bbed579375730a5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -172,6 +172,11 @@ if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") endif() endif() +if("${CMAKE_SYSTEM_NAME}" MATCHES "Haiku") + target_compile_definitions(SRB2SDL2 PRIVATE -DNOEXECINFO) + target_link_libraries(SRB2SDL2 PRIVATE network) +endif() + if("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin") target_compile_definitions(SRB2SDL2 PRIVATE -DMACOSX) endif() diff --git a/src/Makefile.d/detect.mk b/src/Makefile.d/detect.mk index 9e27369462b00c407f02cb95dbda22ef284a91d1..853ad3d6df728d7c69ea64b204cf099547f59e45 100644 --- a/src/Makefile.d/detect.mk +++ b/src/Makefile.d/detect.mk @@ -4,7 +4,6 @@ # Previously featured:\ PANDORA\ - HAIKU\ DUMMY\ DJGPPDOS\ SOLARIS\ @@ -17,6 +16,7 @@ all_systems:=\ UNIX\ LINUX\ FREEBSD\ + HAIKU\ # check for user specified system ifeq (,$(filter $(all_systems),$(.VARIABLES))) @@ -35,6 +35,8 @@ system:=$(shell uname -s) ifeq ($(system),Linux) new_system:=LINUX +else ifeq ($(system),Haiku) +new_system:=HAIKU else $(error \ diff --git a/src/Makefile.d/haiku.mk b/src/Makefile.d/haiku.mk new file mode 100644 index 0000000000000000000000000000000000000000..6742ec75b58f992a916a99752c72ca827f4dab5e --- /dev/null +++ b/src/Makefile.d/haiku.mk @@ -0,0 +1,71 @@ +# +# Makefile options for Haiku +# + +opts+=-DUNIXCOMMON -DLUA_USE_POSIX + +ifndef DEDICATED +ifndef DUMMY +SDL?=1 +DEDICATED?=0 +endif +endif + +NOEXECINFO=1 + +ifeq (${SDL},1) +EXENAME?=srb2haiku +else ifeq (${DEDICATED},1) +EXENAME?=srb2haikud +endif + +ifndef NONET +libs+=-lnetwork +endif + +define _set = +$(1)_CFLAGS?=$($(1)_opts) +$(1)_LDFLAGS?=$($(1)_libs) +endef + +lib:=../libs/gme +LIBGME_opts:=-I$(lib)/include +LIBGME_libs:=-l:libgme.so.0 +$(eval $(call _set,LIBGME)) + +lib:=../libs/libopenmpt +LIBOPENMPT_opts:=-I$(lib)/inc +LIBOPENMPT_libs:=-l:libopenmpt.so.0 +$(eval $(call _set,LIBOPENMPT)) + +ifdef SDL +lib:=../libs/SDL2_mixer +mixer_opts:=-I$(lib)/include +mixer_libs:=-l:libSDL2_mixer-2.0.so.0 + +lib:=../libs/SDL2 +SDL_opts:=-I$(lib)/include $(mixer_opts) +SDL_libs:=$(mixer_libs) -l:libSDL2-2.0.so.0 +$(eval $(call _set,SDL)) +endif + +lib:=../libs/zlib +ZLIB_opts:=-I$(lib) +ZLIB_libs:=-l:libz.so.1 +$(eval $(call _set,ZLIB)) + +ifndef PNG_CONFIG +PNG_opts:= +PNG_libs:=-l:libpng16.so.16 +$(eval $(call _set,PNG)) +endif + +lib:=../libs/curl +CURL_opts:=-I$(lib)/include +CURL_libs:=-l:libcurl.so.4 +$(eval $(call _set,CURL)) + +lib:=../libs/miniupnpc +MINIUPNPC_opts:=-I$(lib)/include +MINIUPNPC_libs:=-l:libminiupnpc.so.17 +$(eval $(call _set,MINIUPNPC)) diff --git a/src/Makefile.d/platform.mk b/src/Makefile.d/platform.mk index d9a2954f60c54b30c121c0467022c1707f720fc0..d5423a397384922689260546b71948447846f3e1 100644 --- a/src/Makefile.d/platform.mk +++ b/src/Makefile.d/platform.mk @@ -35,6 +35,10 @@ endif else ifdef FREEBSD UNIX=1 platform=freebsd +else ifdef HAIKU +# Give Haiku its own configuration, since it +# isn't actually UNIX. +include Makefile.d/haiku.mk else ifdef SOLARIS # FIXME: UNTESTED UNIX=1 platform=solaris diff --git a/src/Makefile.d/sdl.mk b/src/Makefile.d/sdl.mk index a1bfa33038bbacebada85790a7565fceb9440985..d5e83989c2d1955146a8c228c15034d9f2b9e091 100644 --- a/src/Makefile.d/sdl.mk +++ b/src/Makefile.d/sdl.mk @@ -33,11 +33,13 @@ else opts+=-DHAVE_MIXER sources+=sdl/mixer_sound.c - ifdef HAVE_MIXERX - opts+=-DHAVE_MIXERX - libs+=-lSDL2_mixer_ext - else - libs+=-lSDL2_mixer + ifndef HAIKU # Haiku has a special import path + ifdef HAVE_MIXERX + opts+=-DHAVE_MIXERX + libs+=-lSDL2_mixer_ext + else + libs+=-lSDL2_mixer + endif endif endif diff --git a/src/am_map.c b/src/am_map.c index df3a45cfff504e046ddaa6ecc03cf9f9d548e45f..36b62f2f9b0157c58a2becd8b55624302d29ae0b 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -1076,6 +1076,9 @@ static inline void AM_drawPlayers(void) if (!playeringame[i] || players[i].spectator) continue; + if (!players[i].mo) + continue; + p = &players[i]; if (p->skincolor > 0) color = R_GetTranslationColormap(TC_DEFAULT, p->skincolor, GTC_CACHE)[GREENS + 8]; diff --git a/src/command.c b/src/command.c index 399714bd0d65758489634477a8bf84b2444ff659..29f491e295d7378be64cf72a2c0115c5dd51e676 100644 --- a/src/command.c +++ b/src/command.c @@ -648,7 +648,7 @@ static void COM_ExecuteString(char *ptext) { if ((com_flags & COM_LUA) && !(cmd->flags & COM_LUA)) { - CONS_Alert(CONS_WARNING, "Command '%s' cannot be run from Lua.\n", cmd->name); + CONS_Alert(CONS_WARNING, "Command '%s' cannot be run from a script.\n", cmd->name); return; } @@ -809,49 +809,60 @@ static void COM_CEchoDuration_f(void) /** Executes a script file. */ -static void COM_Exec_f(void) +boolean COM_ExecFile(const char *scriptname, com_flags_t flags, boolean silent) { UINT8 *buf = NULL; char filename[256]; - if (COM_Argc() < 2 || COM_Argc() > 3) - { - CONS_Printf(M_GetText("exec <filename>: run a script file\n")); - return; - } - - if (!D_CheckPathAllowed(COM_Argv(1), "tried to exec")) - return; + if (!D_CheckPathAllowed(scriptname, "tried to exec")) + return false; // load file // Try with Argv passed verbatim first, for back compat - FIL_ReadFile(COM_Argv(1), &buf); + FIL_ReadFile(scriptname, &buf); if (!buf) { // Now try by searching the file path // filename is modified with the full found path - strcpy(filename, COM_Argv(1)); + strlcpy(filename, scriptname, sizeof(filename)); if (findfile(filename, NULL, true) != FS_NOTFOUND) FIL_ReadFile(filename, &buf); if (!buf) - { - if (!COM_CheckParm("-noerror")) - CONS_Printf(M_GetText("couldn't execute file %s\n"), COM_Argv(1)); - return; - } + return false; } - if (!COM_CheckParm("-silent")) - CONS_Printf(M_GetText("executing %s\n"), COM_Argv(1)); + if (!silent) + CONS_Printf(M_GetText("Executing %s\n"), scriptname); // insert text file into the command buffer - COM_BufAddTextEx((char *)buf, com_flags); - COM_BufAddTextEx("\n", com_flags); + COM_BufAddTextEx((char *)buf, flags); + COM_BufAddTextEx("\n", flags); // free buffer Z_Free(buf); + + return true; +} + +static void COM_Exec_f(void) +{ + boolean silent; + + if (COM_Argc() < 2 || COM_Argc() > 3) + { + CONS_Printf(M_GetText("exec <filename>: run a script file\n")); + return; + } + + silent = COM_CheckParm("-silent"); + + if (COM_ExecFile(COM_Argv(1), com_flags, silent)) + return; + + if (!COM_CheckParm("-noerror")) + CONS_Printf(M_GetText("Couldn't execute file %s\n"), COM_Argv(1)); } /** Delays execution of the rest of the commands until the next frame. @@ -1988,7 +1999,7 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth) if (!var->string) I_Error("CV_Set: %s no string set!\n", var->name); #endif - if (!var || !var->string || !value || !stricmp(var->string, value)) + if (!var || !var->string || !value || (var->can_change == NULL && !stricmp(var->string, value))) return; // no changes if (var->flags & CV_NETVAR) @@ -2493,7 +2504,7 @@ static boolean CV_Command(void) if (CV_Immutable(v)) { - CONS_Alert(CONS_WARNING, "Variable '%s' cannot be changed from Lua.\n", v->name); + CONS_Alert(CONS_WARNING, "Variable '%s' cannot be changed from a script.\n", v->name); return true; } diff --git a/src/command.h b/src/command.h index c1ac7d48669b11568ca6446c48386462b2cadd39..70342a78512783e6ea3bf3fc2122bee21d074099 100644 --- a/src/command.h +++ b/src/command.h @@ -66,6 +66,9 @@ void COM_ImmedExecute(const char *ptext); // Execute commands in buffer, flush them void COM_BufExecute(void); +// Executes a script from a file +boolean COM_ExecFile(const char *scriptname, com_flags_t flags, boolean silent); + // As above; and progress the wait timer. void COM_BufTicker(void); diff --git a/src/config.h.in b/src/config.h.in index 6d49a698934bf8b498f6bfb402bbaa7f8ff93191..a6dabcbafa1fbb331c89b56b0b80fed9b4f425a7 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -40,10 +40,11 @@ * Last updated 2023 / 05 / 02 - v2.2.11 - patch.pk3 & zones.pk3 * Last updated 2023 / 09 / 06 - v2.2.12 - patch.pk3 * Last updated 2023 / 09 / 09 - v2.2.13 - none + * Last updated 2025 / 01 / 16 - v2.2.14 - main assets */ -#define ASSET_HASH_SRB2_PK3 "ad911f29a28a18968ee5b2d11c2acb39" -#define ASSET_HASH_ZONES_PK3 "1c8adf8d079ecb87d00081f158acf3c7" -#define ASSET_HASH_PLAYER_DTA "2e7aaae8a6b1b77d90ffe7606ceadb6c" +#define ASSET_HASH_SRB2_PK3 "c1d9a4b3452b350d4662f41eb301dc6c" +#define ASSET_HASH_ZONES_PK3 "2ab758817fff96bc60ee9dec85e0b534" +#define ASSET_HASH_CHARACTERS_PK3 "97ce7008d16152731fe037141309aa24" #ifdef USE_PATCH_DTA #define ASSET_HASH_PATCH_PK3 "3c7b73f34af7e9a7bceb2d5260f76172" #endif diff --git a/src/d_main.c b/src/d_main.c index 2e58765805ff48a9172ce12a8f98cf905210f8fd..c1edbfbd802cc3ee9e068e95e9c45ac76581f345 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2024 by Sonic Team Junior. +// Copyright (C) 1999-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -1180,7 +1180,7 @@ static void IdentifyVersion(void) D_AddFile(&startupwadfiles, va(pandf,srb2waddir, "zones.pk3")); // Add the players - D_AddFile(&startupwadfiles, va(pandf,srb2waddir, "player.dta")); + D_AddFile(&startupwadfiles, va(pandf,srb2waddir, "characters.pk3")); #ifdef USE_PATCH_DTA // Add our crappy patches to fix our bugs @@ -1199,7 +1199,7 @@ static void IdentifyVersion(void) I_Error("File "str" has been modified with non-music/sound lumps"); \ } - MUSICTEST("music.dta") + MUSICTEST("music.pk3") //MUSICTEST("patch_music.pk3") } #endif @@ -1250,7 +1250,7 @@ void D_SRB2Main(void) // Print GPL notice for our console users (Linux) CONS_Printf( "\n\nSonic Robo Blast 2\n" - "Copyright (C) 1998-2024 by Sonic Team Junior\n\n" + "Copyright (C) 1998-2025 by Sonic Team Junior\n\n" "This program comes with ABSOLUTELY NO WARRANTY.\n\n" "This is free software, and you are welcome to redistribute it\n" "and/or modify it under the terms of the GNU General Public License\n" @@ -1432,7 +1432,7 @@ void D_SRB2Main(void) P_InitializeTables(); //P_BackupTables(); - mainwads = 3; // doesn't include music.dta + mainwads = 3; // doesn't include music.pk3 #ifdef USE_PATCH_DTA mainwads++; #endif @@ -1447,11 +1447,11 @@ void D_SRB2Main(void) // Check MD5s of autoloaded files W_VerifyFileMD5(0, ASSET_HASH_SRB2_PK3); // srb2.pk3 W_VerifyFileMD5(1, ASSET_HASH_ZONES_PK3); // zones.pk3 - W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta + W_VerifyFileMD5(2, ASSET_HASH_CHARACTERS_PK3); // characters.pk3 #ifdef USE_PATCH_DTA W_VerifyFileMD5(3, ASSET_HASH_PATCH_PK3); // patch.pk3 #endif - // don't check music.dta because people like to modify it, and it doesn't matter if they do + // don't check music.pk3 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. #endif //ifndef DEVELOP @@ -1601,7 +1601,7 @@ void D_SRB2Main(void) { if (!M_IsNextParm()) I_Error("usage: -room <room_id>\nCheck the Master Server's webpage for room ID numbers.\n"); - ms_RoomId = atoi(M_GetNextParm()); + CV_SetValue(&cv_masterserver_room_id, atoi(M_GetNextParm())); #ifdef UPDATE_ALERT GetMODVersion_Console(); diff --git a/src/d_think.h b/src/d_think.h index 58912458783a2f3b2187e50ebaf00a667a0e0a78..76c1bb5b8af11a5557bab32705897445e699ca5b 100644 --- a/src/d_think.h +++ b/src/d_think.h @@ -51,6 +51,8 @@ typedef struct thinker_s // killough 11/98: count of how many other objects reference // this one using pointers. Used for garbage collection. INT32 references; + + boolean removing; boolean cachable; #ifdef PARANOIA diff --git a/src/dedicated/i_system.c b/src/dedicated/i_system.c index 23c0149ca789bcdd34bc464590b1edc67398ddbf..ab872713a850be2a8b8ca9cf86c121594b34f16f 100644 --- a/src/dedicated/i_system.c +++ b/src/dedicated/i_system.c @@ -3,7 +3,7 @@ // // Copyright (C) 1993-1996 by id Software, Inc. // Portions Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 2014-2024 by Sonic Team Junior. +// Copyright (C) 2014-2025 by Sonic Team Junior. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -65,10 +65,11 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #pragma warning(default : 4214 4244) #endif -#if defined (__unix__) || defined(__APPLE__) || (defined (UNIXCOMMON) && !defined (__HAIKU__)) -#if defined (__linux__) -#include <sys/vfs.h> +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) +#if defined (__linux__) || defined (__HAIKU__) +#include <sys/statvfs.h> #else +#include <sys/statvfs.h> #include <sys/param.h> #include <sys/mount.h> /*For meminfo*/ @@ -81,7 +82,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #endif #endif -#if defined (__linux__) || (defined (UNIXCOMMON) && !defined (__HAIKU__)) +#if defined (__linux__) || defined (UNIXCOMMON) #ifndef NOTERMIOS #include <termios.h> #include <sys/ioctl.h> // ioctl @@ -96,8 +97,10 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #if defined (__unix__) || (defined (UNIXCOMMON) && !defined (__APPLE__)) #include <errno.h> #include <sys/wait.h> +#ifndef __HAIKU__ // haiku's crash dialog is just objectively better #define NEWSIGNALHANDLER #endif +#endif #ifndef NOMUMBLE #ifdef __linux__ // need -lrt @@ -374,15 +377,24 @@ void I_Sleep(UINT32 ms) void I_SleepDuration(precise_t duration) { -#if defined(__linux__) || defined(__FreeBSD__) +#if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__) UINT64 precision = I_GetPrecisePrecision(); - struct timespec ts = { - .tv_sec = duration / precision, - .tv_nsec = duration * 1000000000 / precision % 1000000000, - }; - int status; - do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts); - while (status == EINTR); + precise_t dest = I_GetPreciseTime() + duration; + precise_t slack = (precision / 5000); // 0.2 ms slack + if (duration > slack) + { + duration -= slack; + struct timespec ts = { + .tv_sec = duration / precision, + .tv_nsec = duration * 1000000000 / precision % 1000000000, + }; + int status; + do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts); + while (status == EINTR); + } + + // busy-wait the rest + while (((INT64)dest - (INT64)I_GetPreciseTime()) > 0); #else UINT64 precision = I_GetPrecisePrecision(); INT32 sleepvalue = cv_sleep.value; @@ -705,10 +717,9 @@ typedef struct static 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; +// lock to prevent clearing partial lines, since not everything +// printed ends on a newline. +static boolean ttycon_ateol = true; // some key codes that the terminal may be using // TTimo NOTE: I'm not sure how relevant this is static INT32 tty_erase; @@ -736,63 +747,31 @@ static inline void tty_FlushIn(void) // 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) +// Hanicef NOTE: using \b this way is unreliable because of terminal state, +// it's better to use \r to reset the cursor to the beginning of the +// line and clear from there. 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; + write(STDOUT_FILENO, "\r", 1); if (tty_con.cursor>0) { - for (i=0; i<tty_con.cursor; i++) - { - tty_Back(); - } + write(STDOUT_FILENO, tty_con.buffer, tty_con.cursor); } - + write(STDOUT_FILENO, " \b", 2); } -// 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) +static void tty_Clear(void) { size_t i; - ssize_t d; - //I_Assert(consolevent); - I_Assert(ttycon_hide>0); - ttycon_hide--; - if (ttycon_hide == 0 && tty_con.cursor) + write(STDOUT_FILENO, "\r", 1); + if (tty_con.cursor>0) { for (i=0; i<tty_con.cursor; i++) { - d = write(STDOUT_FILENO, tty_con.buffer+i, 1); + write(STDOUT_FILENO, " ", 1); } + write(STDOUT_FILENO, "\r", 1); } - (void)d; } // never exit without calling this, or your terminal will be left in a pretty bad state @@ -900,6 +879,11 @@ static void I_GetConsoleEvents(void) tty_con.cursor = 0; ev.key = KEY_ENTER; } + else if (key == 0x4) // ^D, aka EOF + { + // shut down, most unix programs behave this way + I_Quit(); + } else continue; } else if (tty_con.cursor < sizeof(tty_con.buffer)) @@ -1046,6 +1030,9 @@ void I_OutputMsg(const char *fmt, ...) va_start(argptr,fmt); len = vsnprintf(NULL, 0, fmt, argptr); va_end(argptr); + if (len == 0) + return; + txt = malloc(len+1); va_start(argptr,fmt); vsprintf(txt, fmt, argptr); @@ -1135,18 +1122,20 @@ void I_OutputMsg(const char *fmt, ...) } #else #ifdef HAVE_TERMIOS - if (consolevent) + if (consolevent && ttycon_ateol) { - tty_Hide(); + tty_Clear(); + ttycon_ateol = false; } #endif if (!framebuffer) fprintf(stderr, "%s", txt); #ifdef HAVE_TERMIOS - if (consolevent) + if (consolevent && txt[len-1] == '\n') { - tty_Show(); + write(STDOUT_FILENO, tty_con.buffer, tty_con.cursor); + ttycon_ateol = true; } #endif @@ -1226,18 +1215,13 @@ void I_ShutdownSystem(void) void I_GetDiskFreeSpace(INT64* freespace) { #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) -#if defined (SOLARIS) || defined (__HAIKU__) - *freespace = INT32_MAX; - return; -#else // Both Linux and BSD have this, apparently. - struct statfs stfs; - if (statfs(srb2home, &stfs) == -1) + struct statvfs stfs; + if (statvfs(srb2home, &stfs) == -1) { *freespace = INT32_MAX; return; } *freespace = stfs.f_bavail * stfs.f_bsize; -#endif #elif defined (_WIN32) static p_GetDiskFreeSpaceExA pfnGetDiskFreeSpaceEx = NULL; static boolean testwin95 = false; @@ -1453,8 +1437,10 @@ const char *I_LocateWad(void) { // change to the directory where we found srb2.pk3 #if defined (_WIN32) + waddir = _fullpath(NULL, waddir, MAX_PATH); SetCurrentDirectoryA(waddir); #else + waddir = realpath(waddir, NULL); if (chdir(waddir) == -1) I_OutputMsg("Couldn't change working directory\n"); #endif diff --git a/src/deh_lua.c b/src/deh_lua.c index b5037a70c31fa2a3dab3c51cde69e8736b6e6164..916d131f4799fb308aef26e9efb5585f1a364cd1 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -28,6 +28,12 @@ static inline int lib_freeslot(lua_State *L) if (!lua_lumploading) return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); + if (!deh_loaded) + { + initfreeslots(); + deh_loaded = true; + } + while (n-- > 0) { s = Z_StrDup(luaL_checkstring(L,1)); diff --git a/src/deh_soc.c b/src/deh_soc.c index 7690e045ea4e0d9dac022a9527cc262cb59626de..f46cf96a79b95ca421acdc67088d8ef3b93aaed6 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -3566,7 +3566,7 @@ void readmaincfg(MYFILE *f) if (fastcmp(word, "EXECCFG")) { if (strchr(word2, '.')) - COM_BufAddText(va("exec %s\n", word2)); + COM_ExecFile(word2, COM_LUA, false); else { lumpnum_t lumpnum; @@ -3581,7 +3581,7 @@ void readmaincfg(MYFILE *f) if (lumpnum == LUMPERROR || W_LumpLength(lumpnum) == 0) CONS_Debug(DBG_SETUP, "SOC Error: script lump %s not found/not valid.\n", newname); else - COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE)); + COM_BufInsertTextEx(W_CacheLumpNum(lumpnum, PU_CACHE), COM_LUA); } } @@ -3907,6 +3907,7 @@ void readmaincfg(MYFILE *f) value = get_number(word2); bootmap = (INT16)value; + bootmapchanged = true; //titlechanged = true; } else if (fastcmp(word, "STARTCHAR")) diff --git a/src/dehacked.c b/src/dehacked.c index 07070e7cb89ee87766a0d12da9e803999ef25ce7..a728359bb6c0da98c25427e0ea3553801896b387 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -20,6 +20,7 @@ boolean deh_loaded = false; boolean gamedataadded = false; boolean titlechanged = false; boolean introchanged = false; +boolean bootmapchanged = false; static int dbg_line; static INT32 deh_num_warning = 0; @@ -192,11 +193,14 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) INT32 i; if (!deh_loaded) + { initfreeslots(); + deh_loaded = true; + } deh_num_warning = 0; - gamedataadded = titlechanged = introchanged = false; + gamedataadded = titlechanged = introchanged = bootmapchanged = 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. @@ -587,7 +591,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) if (gamestate == GS_TITLESCREEN) { - if (introchanged) + if (bootmapchanged && bootmap) + { + menuactive = false; + D_MapChange(bootmap, gametype, ultimatemode, true, 0, false, false); + } + else if (introchanged) { menuactive = false; I_UpdateMouseGrab(); @@ -605,14 +614,10 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) if (deh_num_warning) { CONS_Printf(M_GetText("%d warning%s in the SOC lump\n"), deh_num_warning, deh_num_warning == 1 ? "" : "s"); - if (devparm) { + if (devparm) I_Error("%s%s",va(M_GetText("%d warning%s in the SOC lump\n"), deh_num_warning, deh_num_warning == 1 ? "" : "s"), M_GetText("See log.txt for details.\n")); - //while (!I_GetKey()) - //I_OsPolling(); - } } - deh_loaded = true; Z_Free(s); } diff --git a/src/dehacked.h b/src/dehacked.h index d985b14b031d648b35f991d03e6797ab72f52137..e7b9b46566411f51654f2b60270ff745b28b18c2 100644 --- a/src/dehacked.h +++ b/src/dehacked.h @@ -39,6 +39,7 @@ extern boolean deh_loaded; extern boolean gamedataadded; extern boolean titlechanged; extern boolean introchanged; +extern boolean bootmapchanged; #define MAX_ACTION_RECURSION 30 extern const char *luaactions[MAX_ACTION_RECURSION]; diff --git a/src/doomdef.h b/src/doomdef.h index c92e6dc37df8f2f12668b1ce822877ae43176618..81ab7bbfb5505507f3df07b6b5709b6d4f995e81 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -168,7 +168,7 @@ extern char logfilename[1024]; // Does this version require an added patch file? // Comment or uncomment this as necessary. -#define USE_PATCH_DTA +//#define USE_PATCH_DTA // Enforce a limit of loaded WAD files. //#define ENFORCE_WAD_LIMIT diff --git a/src/f_finale.c b/src/f_finale.c index 2b239711b78b716bf5f6ebb324c37935ad8cb13f..1587e69a85aed00eb8d907d39ab1aae24d2dde05 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1080,6 +1080,7 @@ static const char *credits[] = { "Louis-Antoine \"LJ Sonic\" de Moulins", // de Rochefort doesn't quite fit on the screen sorry lol "John \"JTE\" Muniz", "Colin \"Sonict\" Pfaff", + "\"Radicalicious\"", "James \"james\" Robert Roman", "Sean \"Sryder13\" Ryder", "Ehab \"Wolfy\" Saeed", @@ -1103,7 +1104,8 @@ static const char *credits[] = { "\"ChrispyPixels\"", "Paul \"Boinciel\" Clempson", "Sally \"TehRealSalt\" Cochenour", - "\"Dave Lite\"", + "\"DaJumpJump\"", // New Ringslinger graphics (2.2.14) + "\"DeltaSanic\"", "Desmond \"Blade\" DesJardins", "Sherman \"CoatRack\" DesJardins", "\"DirkTheHusky\"", @@ -1123,10 +1125,12 @@ static const char *credits[] = { "\"MotorRoach\"", "Phillip \"TelosTurntable\" Robinson", "\"Scizor300\"", + "\"Skydusk\"", "Wessel \"sphere\" Smit", "David \"Instant Sonic\" Spencer Jr.", "\"SSNTails\"", "Daniel \"Inazuma\" Trinh", + "Samuel \"Spectorious\" Tuttle", "\"VelocitOni\"", "Jarrett \"JEV3\" Voight", "", @@ -1135,6 +1139,7 @@ static const char *credits[] = { "Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo "Malcolm \"RedXVI\" Brown", "Dave \"DemonTomatoDave\" Bulmer", + "Dan Cidoni", // aka Krabs "Paul \"Boinciel\" Clempson", "\"Cyan Helkaraxe\"", "Claire \"clairebun\" Ellis", @@ -1153,24 +1158,32 @@ static const char *credits[] = { "Colette \"fickleheart\" Bordelon", "Hank \"FuriousFox\" Brannock", "Matthew \"Fawfulfan\" Chapman", + "Dan Cidoni", // aka Krabs "Paul \"Boinciel\" Clempson", "Sally \"TehRealSalt\" Cochenour", "Desmond \"Blade\" DesJardins", "Sherman \"CoatRack\" DesJardins", "Ben \"Mystic\" Geyer", "Nathan \"Jazz\" Giroux", + "\"GomaTheMascar\"", "Vivian \"toaster\" Grannell", "James \"SeventhSentinel\" Hall", "Kepa \"Nev3r\" Iceta", "Thomas \"Shadow Hog\" Igoe", + "Mujamel \"MK\" Khan", "\"Kaito Sinclaire\"", "Alexander \"DrTapeworm\" Moench-Ford", + "\"orbitalviolet\"", // summit showdown hehehehe (aka Evertone) + "\"Radicalicious\"", "\"Revan\"", "Anna \"QueenDelta\" Sandlin", + "\"Skydusk\"", "Wessel \"sphere\" Smit", "\"SSNTails\"", + "Aaron \"Othius\" Stojkov", "Rob Tisdell", "\"Torgo\"", + "Samuel \"Spectorious\" Tuttle", "Jarrett \"JEV3\" Voight", "Johnny \"Sonikku\" Wallbank", "Marco \"mazmazz\" Zafra", @@ -3435,7 +3448,7 @@ void F_TitleScreenTicker(boolean run) { for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -3645,7 +3658,7 @@ static void F_DrawContinueCharacter(INT32 dx, INT32 dy, UINT8 n) ( HUD_HOOK(continue), luahuddrawlist_continue[n], contPlayers[n], dx, dy, contskins[n]->highresscale, - (INT32)(&contskins[n] - skins), cont_spr2[n][0], cont_spr2[n][1], cont_spr2[n][2] + 1, contColors[n], // add 1 to rotation to convert internal angle numbers (0-7) to WAD editor angle numbers (1-8) + (INT32)(contskins[n]->skinnum), cont_spr2[n][0], cont_spr2[n][1], cont_spr2[n][2] + 1, contColors[n], // add 1 to rotation to convert internal angle numbers (0-7) to WAD editor angle numbers (1-8) imcontinuing ? continuetime : timetonext, imcontinuing ); } @@ -3711,7 +3724,7 @@ void F_ContinueDrawer(void) else if (ncontinues > 10) { if (!(continuetime & 1) || continuetime > 17) - V_DrawContinueIcon(x, 68, 0, (INT32)(&contskins[0] - skins), contColors[0]); + V_DrawContinueIcon(x, 68, 0, contskins[0]->skinnum, contColors[0]); V_DrawScaledPatch(x+12, 66, 0, stlivex); V_DrawRightAlignedString(x+38, 64, 0, va("%d",(imcontinuing ? ncontinues-1 : ncontinues))); @@ -3725,7 +3738,7 @@ void F_ContinueDrawer(void) { if (i == (ncontinues/2) && ((continuetime & 1) || continuetime > 17)) continue; - V_DrawContinueIcon(x - (i*30), 68, 0, (INT32)(&contskins[0] - skins), contColors[0]); + V_DrawContinueIcon(x - (i*30), 68, 0, contskins[0]->skinnum, contColors[0]); } x = BASEVIDWIDTH>>1; } diff --git a/src/g_demo.c b/src/g_demo.c index 857bbb7ecb46edaaaba7f0a72de22a6f04b07611..6d1d397cab687e132e9c2acfe8c876f16f141878 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -614,7 +614,7 @@ void G_ConsGhostTic(void) mobj = NULL; for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mobj = (mobj_t *)th; if (mobj->type == (mobjtype_t)type && mobj->x == x && mobj->y == y && mobj->z == z) @@ -2696,7 +2696,7 @@ void G_DoPlayMetal(void) // find metal sonic for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo = (mobj_t *)th; diff --git a/src/g_game.c b/src/g_game.c index d409bb2cf721b0132f086113932c5402da289615..8940635851adbbf56b95e296c1fa908da642b828 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1384,7 +1384,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (PLAYERINPUTDOWN(ssplayer, GC_SPIN) || (usejoystick && axis > 0)) cmd->buttons |= BT_SPIN; - if (gamestate != GS_LEVEL) // not in a level, don't build anything else + if (gamestate == GS_INTRO) // prevent crash in intro { cmd->angleturn = ticcmd_oldangleturn[forplayer]; cmd->aiming = G_ClipAimingPitch(myaiming); @@ -1722,7 +1722,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // At this point, cmd doesn't contain the final angle yet, // So we need to temporarily transform it so Lua scripters // don't need to handle it differently than in other hooks. - if (addedtogame) + if (addedtogame && gamestate == GS_LEVEL) { INT16 extra = ticcmd_oldangleturn[forplayer] - player->oldrelangleturn; INT16 origangle = cmd->angleturn; @@ -3072,7 +3072,7 @@ void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo) // scan all thinkers for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index f282ca89184b9d47fe000f47e126880c0467b602..b71bf7007e03ab2cdb7d229d84aa5a57deb8cc8c 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -1258,20 +1258,29 @@ void HWR_SetMapPalette(void) // Creates a hardware lighttable from the supplied lighttable. // Returns the id of the hw lighttable, usable in FSurfaceInfo. -UINT32 HWR_CreateLightTable(UINT8 *lighttable) +UINT32 HWR_CreateLightTable(UINT8 *lighttable, RGBA_t *hw_lighttable) { - UINT32 i, id; + UINT32 i; RGBA_t *palette = HWR_GetTexturePalette(); - RGBA_t *hw_lighttable = Z_Malloc(256 * 32 * sizeof(RGBA_t), PU_STATIC, NULL); // To make the palette index -> RGBA mapping easier for the shader, // the hardware lighttable is composed of RGBA colors instead of palette indices. for (i = 0; i < 256 * 32; i++) hw_lighttable[i] = palette[lighttable[i]]; - id = HWD.pfnCreateLightTable(hw_lighttable); - Z_Free(hw_lighttable); - return id; + return HWD.pfnCreateLightTable(hw_lighttable); +} + +// Updates a hardware lighttable of a given id from the supplied lighttable. +void HWR_UpdateLightTable(UINT32 id, UINT8 *lighttable, RGBA_t *hw_lighttable) +{ + UINT32 i; + RGBA_t *palette = HWR_GetTexturePalette(); + + for (i = 0; i < 256 * 32; i++) + hw_lighttable[i] = palette[lighttable[i]]; + + HWD.pfnUpdateLightTable(id, hw_lighttable); } // get hwr lighttable id for colormap, create it if it doesn't already exist @@ -1285,25 +1294,41 @@ UINT32 HWR_GetLightTableID(extracolormap_t *colormap) default_colormap = true; } + UINT8 *colormap_pointer; + + if (default_colormap) + colormap_pointer = colormaps; // don't actually use the data from the "default colormap" + else + colormap_pointer = colormap->colormap; + // create hw lighttable if there isn't one - if (!colormap->gl_lighttable_id) + if (colormap->gl_lighttable.data == NULL) { - UINT8 *colormap_pointer; + Z_Malloc(256 * 32 * sizeof(RGBA_t), PU_HWRLIGHTTABLEDATA, &colormap->gl_lighttable.data); + } - if (default_colormap) - colormap_pointer = colormaps; // don't actually use the data from the "default colormap" - else - colormap_pointer = colormap->colormap; - colormap->gl_lighttable_id = HWR_CreateLightTable(colormap_pointer); + // Generate the texture for this light table + if (!colormap->gl_lighttable.id) + { + colormap->gl_lighttable.id = HWR_CreateLightTable(colormap_pointer, colormap->gl_lighttable.data); + } + // Update the texture if it was directly changed by a script + else if (colormap->gl_lighttable.needs_update) + { + HWR_UpdateLightTable(colormap->gl_lighttable.id, colormap_pointer, colormap->gl_lighttable.data); } - return colormap->gl_lighttable_id; + colormap->gl_lighttable.needs_update = false; + + return colormap->gl_lighttable.id; } // Note: all hardware lighttable ids assigned before this // call become invalid and must not be used. void HWR_ClearLightTables(void) { + Z_FreeTag(PU_HWRLIGHTTABLEDATA); + if (vid.glstate == VID_GL_LIBRARY_LOADED) HWD.pfnClearLightTables(); } diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 694cc1b8c0d5a16e1d40ae9d14575c562d868058..a5fdc00a47c17e6b5cbeba5d074554a66672cde7 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -71,6 +71,7 @@ EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value); EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut); EXPORT UINT32 HWRAPI(CreateLightTable)(RGBA_t *hw_lighttable); +EXPORT void HWRAPI(UpdateLightTable)(UINT32 id, RGBA_t *hw_lighttable); EXPORT void HWRAPI(ClearLightTables)(void); EXPORT void HWRAPI(SetScreenPalette)(RGBA_t *palette); @@ -125,6 +126,7 @@ struct hwdriver_s SetPaletteLookup pfnSetPaletteLookup; CreateLightTable pfnCreateLightTable; + UpdateLightTable pfnUpdateLightTable; ClearLightTables pfnClearLightTables; SetScreenPalette pfnSetScreenPalette; }; diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 62fe8d0bda5b521f650a91f00f97e111d99e6eed..bf9f7da3b4c126154fed2faf81761f348fbeed63 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -133,7 +133,8 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch); void HWR_SetPalette(RGBA_t *palette); void HWR_SetMapPalette(void); -UINT32 HWR_CreateLightTable(UINT8 *lighttable); +UINT32 HWR_CreateLightTable(UINT8 *lighttable, RGBA_t *hw_lighttable); +void HWR_UpdateLightTable(UINT32 id, UINT8 *lighttable, RGBA_t *hw_lighttable); UINT32 HWR_GetLightTableID(extracolormap_t *colormap); void HWR_ClearLightTables(void); diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index ff02a28b6ee9382c7097b7a6bb76076b673c1710..349274665798010a1e3642a9442304b161f939d3 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -409,6 +409,8 @@ static const light_t *startt_lspr[] = &lspr[NOLIGHT], // SPR_XMS4 &lspr[NOLIGHT], // SPR_XMS5 &lspr[NOLIGHT], // SPR_XMS6 + &lspr[NOLIGHT], // SPR_SNTT + &lspr[NOLIGHT], // SPR_SSTT &lspr[NOLIGHT], // SPR_FHZI &lspr[NOLIGHT], // SPR_ROSY @@ -442,6 +444,8 @@ static const light_t *startt_lspr[] = // Misc Scenery &lspr[NOLIGHT], // SPR_STLG &lspr[NOLIGHT], // SPR_DBAL + &lspr[NOLIGHT], // SPR_GINE + &lspr[NOLIGHT], // SPR_PPAL // Powerup Indicators &lspr[NOLIGHT], // SPR_ARMA @@ -495,6 +499,15 @@ static const light_t *startt_lspr[] = &lspr[NOLIGHT], // SPR_SSWY &lspr[NOLIGHT], // SPR_SSWR &lspr[NOLIGHT], // SPR_SSWB + &lspr[NOLIGHT], // SPR_MPRY + &lspr[NOLIGHT], // SPR_MPRR + &lspr[NOLIGHT], // SPR_MPRB + &lspr[NOLIGHT], // SPR_MSWY + &lspr[NOLIGHT], // SPR_MSWR + &lspr[NOLIGHT], // SPR_MSWB + &lspr[NOLIGHT], // SPR_MDIY + &lspr[NOLIGHT], // SPR_MDIR + &lspr[NOLIGHT], // SPR_MDIB &lspr[NOLIGHT], // SPR_BSTY &lspr[NOLIGHT], // SPR_BSTR @@ -553,6 +566,7 @@ static const light_t *startt_lspr[] = &lspr[NOLIGHT], // SPR_BGOM &lspr[REDBALL_L], // SPR_FFWR &lspr[SMALLREDBALL_L], // SPR_FBLL + &lspr[NOLIGHT], // SPR_MKOP &lspr[NOLIGHT], // SPR_SHLL &lspr[REDBALL_L], // SPR_PUMA &lspr[NOLIGHT], // SPR_HAMM @@ -562,6 +576,29 @@ static const light_t *startt_lspr[] = &lspr[NOLIGHT], // SPR_MUS1 &lspr[NOLIGHT], // SPR_MUS2 &lspr[NOLIGHT], // SPR_TOAD + &lspr[NOLIGHT], // SPR_MARS + &lspr[NOLIGHT], // SPR_MRFL + &lspr[NOLIGHT], // SPR_MAUH + &lspr[NOLIGHT], // SPR_MBSA + &lspr[NOLIGHT], // SPR_MBSB + &lspr[NOLIGHT], // SPR_MBSC + &lspr[NOLIGHT], // SPR_MFRE + &lspr[NOLIGHT], // SPR_MFYE + &lspr[NOLIGHT], // SPR_MFBE + &lspr[NOLIGHT], // SPR_MFWD + &lspr[NOLIGHT], // SPR_MUS3 + + // Mario powerups + &lspr[NOLIGHT], // SPR_MSIV + &lspr[NOLIGHT], // SPR_MS1P + &lspr[NOLIGHT], // SPR_MSAT + &lspr[NOLIGHT], // SPR_MSFO + &lspr[NOLIGHT], // SPR_MSAR + &lspr[NOLIGHT], // SPR_MSWW + &lspr[NOLIGHT], // SPR_MSEL + &lspr[NOLIGHT], // SPR_MSSP + &lspr[NOLIGHT], // SPR_MEGH + &lspr[NOLIGHT], // SPR_UPPB // NiGHTS Stuff &lspr[SUPERSONIC_L], // SPR_NDRN // NiGHTS drone @@ -623,10 +660,18 @@ static const light_t *startt_lspr[] = &lspr[NOLIGHT], // SPR_BRIR &lspr[NOLIGHT], // SPR_BRIB &lspr[NOLIGHT], // SPR_BRIY + &lspr[NOLIGHT], // SPR_MBRI + &lspr[NOLIGHT], // SPR_MBRS + &lspr[NOLIGHT], // SPR_MBRB + &lspr[NOLIGHT], // SPR_MBRC + &lspr[NOLIGHT], // SPR_MTRI // Gravity Well Objects &lspr[NOLIGHT], // SPR_GWLG &lspr[NOLIGHT], // SPR_GWLR + + // LJ Knuckles + &lspr[NOLIGHT], // SPR_OLDK, }; static UINT32 t_numlspr; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 69d3344c95cf084b6ab7bb4c983c90508b6db9a6..8da91be79ac975ec395c4bd43cc3c73b179415c2 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1692,7 +1692,7 @@ static void HWR_ProcessSeg(void) { blendmode = PF_Masked; - if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) + if ((rover->fofflags & FOF_TRANSLUCENT && !((rover->fofflags & FOF_SPLAT) && rover->alpha >= 255)) || rover->blend) { blendmode = rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent; Surf.PolyColor.s.alpha = max(0, min(rover->alpha, 255)); @@ -1849,7 +1849,7 @@ static void HWR_ProcessSeg(void) { blendmode = PF_Masked; - if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) + if ((rover->fofflags & FOF_TRANSLUCENT && !((rover->fofflags & FOF_SPLAT) && rover->alpha >= 255)) || rover->blend) { blendmode = rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent; Surf.PolyColor.s.alpha = max(0, min(rover->alpha, 255)); @@ -2530,7 +2530,7 @@ static void HWR_Subsector(size_t num) alpha, rover->master->frontsector, PF_Fog|PF_NoTexture, true, false, rover->master->frontsector->extra_colormap); } - else if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) // SoM: Flags are more efficient + else if ((rover->fofflags & FOF_TRANSLUCENT && !((rover->fofflags & FOF_SPLAT) && rover->alpha >= 255)) || rover->blend) // SoM: Flags are more efficient { light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < bottomCullHeight ? true : false); @@ -2576,7 +2576,7 @@ static void HWR_Subsector(size_t num) alpha, rover->master->frontsector, PF_Fog|PF_NoTexture, true, false, rover->master->frontsector->extra_colormap); } - else if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) + else if ((rover->fofflags & FOF_TRANSLUCENT && !((rover->fofflags & FOF_SPLAT) && rover->alpha >= 255)) || rover->blend) { light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < topCullHeight ? true : false); @@ -5794,6 +5794,7 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_glskydome); CV_RegisterVar(&cv_glspritebillboarding); CV_RegisterVar(&cv_glfakecontrast); + CV_RegisterVar(&cv_glslopecontrast); CV_RegisterVar(&cv_glshearing); CV_RegisterVar(&cv_glshaders); diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 17103f20230eaed3d2ff9fae521016ba3300cc34..3aeba1e89b7739549f38f65df7a3019cf915fe9e 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1205,6 +1205,90 @@ static void adjustTextureCoords(model_t *model, patch_t *patch) model->max_t = gpatch->max_t; } +static INT32 GetAnimDuration(mobj_t *mobj) //part of p_mobj's setplayermobjstate logic, used to make sure that anim durations are actually correct when the speed gets adjusted on players +{ + player_t *player = mobj->player; + INT32 tics = mobj->state->tics; + + if (!(mobj->frame & FF_ANIMATE) && mobj->anim_duration) //set manually by something through lua + return mobj->anim_duration; + + if (!player && mobj->type == MT_TAILSOVERLAY && mobj->tracer) //so tails overlays interpolate properly + player = mobj->tracer->player; + if (player) + { + if (player->panim == PA_EDGE && (player->charflags & SF_FASTEDGE)) + tics = 2; + else if (player->powers[pw_tailsfly] && (!(player->mo->eflags & MFE_UNDERWATER) || (mobj->type == MT_PLAYER))) //tailsoverlay does not get adjusted from these rules when underwater + { + if (player->fly1 > 0) + tics = 1; + else if (!(player->mo->eflags & MFE_UNDERWATER)) + tics = 2; + else + tics = 4; + } + else if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST)) + { + 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) + tics = 4; + else if (speed < 20<<FRACBITS) + tics = 3; + else if (speed < 30<<FRACBITS) + tics = 2; + else + tics = 1; + } + 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) + tics = 1; + else if (speed > step) + tics = 2; + else + tics = 3; + } + else + { + speed = FixedDiv(player->speed, FixedMul(mobj->scale, player->mo->movefactor)); + if (player->panim == PA_ROLL || player->panim == PA_JUMP) + { + if (speed > 16<<FRACBITS) + tics = 1; + else + tics = 2; + } + 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 (player->panim == PA_WALK) + { + if (speed > 12<<FRACBITS) + tics = 2; + else if (speed > 6<<FRACBITS) + tics = 3; + else + tics = 4; + } + else if ((player->panim == PA_RUN) || (player->panim == PA_DASH)) + { + if (speed > 52<<FRACBITS) + tics = 1; + else + tics = 2; + } + } + } + } + } + return tics; +} + // // HWR_DrawModel // @@ -1278,7 +1362,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) { patch_t *gpatch, *blendgpatch; GLPatch_t *hwrPatch = NULL, *hwrBlendPatch = NULL; - float durs = (float)spr->mobj->state->tics; + float durs = GetAnimDuration(spr->mobj); float tics = (float)spr->mobj->tics; const boolean papersprite = (R_ThingIsPaperSprite(spr->mobj) && !R_ThingIsFloorSprite(spr->mobj)); const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(spr->mobj)); @@ -1299,8 +1383,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) } // Apparently people don't like jump frames like that, so back it goes - //if (tics > durs) - //durs = tics; + if (tics > durs) + durs = tics; // Make linkdraw objects use their tracer's alpha value fixed_t newalpha = spr->mobj->alpha; @@ -1619,7 +1703,6 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, md2->scale * xs, md2->scale * ys, flip, hflip, &Surf); } } - return true; } diff --git a/src/hardware/r_opengl/ogl_win.c b/src/hardware/r_opengl/ogl_win.c index c9bf601442a5531b35d0ac629730aa83978d17a6..ec8fc9bdb8b77f99f03b97af7df9cbdedea864f4 100644 --- a/src/hardware/r_opengl/ogl_win.c +++ b/src/hardware/r_opengl/ogl_win.c @@ -117,7 +117,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL module #define pwglDeleteContext wglDeleteContext; #define pwglMakeCurrent wglMakeCurrent; #else -static HMODULE OGL32, GLU32; +static HMODULE OGL32; typedef void *(WINAPI *PFNwglGetProcAddress) (const char *); static PFNwglGetProcAddress pwglGetProcAddress; typedef HGLRC (WINAPI *PFNwglCreateContext) (HDC hdc); @@ -132,13 +132,6 @@ static PFNwglMakeCurrent pwglMakeCurrent; void *GetGLFunc(const char *proc) { void *func = NULL; - if (strncmp(proc, "glu", 3) == 0) - { - if (GLU32) - func = GetProcAddress(GLU32, proc); - else - return NULL; - } if (pwglGetProcAddress) func = pwglGetProcAddress(proc); if (!func) @@ -155,8 +148,6 @@ boolean LoadGL(void) if (!OGL32) return 0; - GLU32 = LoadLibrary("GLU32.DLL"); - pwglGetProcAddress = GetGLFunc("wglGetProcAddress"); pwglCreateContext = GetGLFunc("wglCreateContext"); pwglDeleteContext = GetGLFunc("wglDeleteContext"); @@ -528,7 +519,6 @@ EXPORT void HWRAPI(Shutdown) (void) ReleaseDC(hWnd, hDC); hDC = NULL; } - FreeLibrary(GLU32); FreeLibrary(OGL32); GL_DBG_Printf ("HWRAPI Shutdown(DONE)\n"); } diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 75a92c2fb33ad542b0931786a9b4688a9f9dccbc..e11dd4f166cb8e068cc8fb99d2e2bd0661832755 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -96,6 +96,7 @@ static GLint min_filter = GL_LINEAR; static GLint mag_filter = GL_LINEAR; static GLint anisotropic_filter = 0; static boolean model_lighting = false; +boolean supportMipMap = false; const GLubyte *gl_version = NULL; const GLubyte *gl_renderer = NULL; @@ -417,9 +418,6 @@ static PFNglCopyTexImage2D pglCopyTexImage2D; typedef void (APIENTRY * PFNglCopyTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); static PFNglCopyTexSubImage2D pglCopyTexSubImage2D; #endif -/* GLU functions */ -typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data); -static PFNgluBuild2DMipmaps pgluBuild2DMipmaps; /* 1.2 functions for 3D textures */ typedef void (APIENTRY * PFNglTexImage3D) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); @@ -708,9 +706,6 @@ void SetupGLFunc4(void) pglUniform3fv = GetGLFunc("glUniform3fv"); pglGetUniformLocation = GetGLFunc("glGetUniformLocation"); #endif - - // GLU - pgluBuild2DMipmaps = GetGLFunc("gluBuild2DMipmaps"); } EXPORT boolean HWRAPI(InitShaders) (void) @@ -1617,7 +1612,8 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); if (MipMap) { - pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); + pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); if (pTexInfo->flags & TF_TRANSPARENT) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff @@ -1638,7 +1634,8 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); if (MipMap) { - pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); + pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); if (pTexInfo->flags & TF_TRANSPARENT) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff @@ -1658,7 +1655,8 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) { if (MipMap) { - pgluBuild2DMipmaps(GL_TEXTURE_2D, textureformatGL, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); + pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); // Control the mipmap level of detail pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); // the lower the number, the higer the detail if (pTexInfo->flags & TF_TRANSPARENT) @@ -2241,7 +2239,7 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) mag_filter = GL_LINEAR; min_filter = GL_NEAREST; } - if (!pgluBuild2DMipmaps) + if (!supportMipMap) { MipMap = GL_FALSE; min_filter = GL_LINEAR; @@ -3257,6 +3255,24 @@ EXPORT UINT32 HWRAPI(CreateLightTable)(RGBA_t *hw_lighttable) return item->id; } +EXPORT void HWRAPI(UpdateLightTable)(UINT32 id, RGBA_t *hw_lighttable) +{ + LTListItem *item = LightTablesHead; + while (item && item->id != id) + item = item->next; + + if (item) + { + pglBindTexture(GL_TEXTURE_2D, item->id); + + // Just update it + pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 32, GL_RGBA, GL_UNSIGNED_BYTE, hw_lighttable); + + // restore previously bound texture + pglBindTexture(GL_TEXTURE_2D, tex_downloaded); + } +} + // Delete light table textures, ids given before become invalid and must not be used. EXPORT void HWRAPI(ClearLightTables)(void) { diff --git a/src/hardware/r_opengl/r_opengl.h b/src/hardware/r_opengl/r_opengl.h index f7e33c46aa36b9c416a80dc9158c5c7321fb78d0..197f75ea8931735b3e10b80e68a6ae47a5a736f5 100644 --- a/src/hardware/r_opengl/r_opengl.h +++ b/src/hardware/r_opengl/r_opengl.h @@ -35,7 +35,6 @@ #else #include <GL/gl.h> -#include <GL/glu.h> #ifdef STATIC_OPENGL // Because of the 1.3 functions, you'll need GLext to compile it if static #define GL_GLEXT_PROTOTYPES @@ -127,6 +126,7 @@ extern GLint screen_width; extern GLint screen_height; extern GLbyte screen_depth; extern GLint maximumAnisotropy; +extern boolean supportMipMap; /** \brief OpenGL flags for video driver */ diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 087572490f119a95f0719c8634a7e3327f23a0a9..d11359faddea0b3d7f7d81ee1891f0be078f4bc6 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -590,6 +590,45 @@ static void Command_CSay_f(void) UINT8 spam_tokens[MAXPLAYERS] = { 1 }; // fill the buffer with 1 so the motd can be sent. tic_t spam_tics[MAXPLAYERS]; +static const char *GetChatColorFromSkinColor(INT32 skincolor) +{ + const char *textcolor = NULL; + UINT16 chatcolor = skincolors[skincolor].chatcolor; + if (!chatcolor || chatcolor%0x1000 || chatcolor>V_INVERTMAP) + textcolor = "\x80"; + else if (chatcolor == V_MAGENTAMAP) + textcolor = "\x81"; + else if (chatcolor == V_YELLOWMAP) + textcolor = "\x82"; + else if (chatcolor == V_GREENMAP) + textcolor = "\x83"; + else if (chatcolor == V_BLUEMAP) + textcolor = "\x84"; + else if (chatcolor == V_REDMAP) + textcolor = "\x85"; + else if (chatcolor == V_GRAYMAP) + textcolor = "\x86"; + else if (chatcolor == V_ORANGEMAP) + textcolor = "\x87"; + else if (chatcolor == V_SKYMAP) + textcolor = "\x88"; + else if (chatcolor == V_PURPLEMAP) + textcolor = "\x89"; + else if (chatcolor == V_AQUAMAP) + textcolor = "\x8a"; + else if (chatcolor == V_PERIDOTMAP) + textcolor = "\x8b"; + else if (chatcolor == V_AZUREMAP) + textcolor = "\x8c"; + else if (chatcolor == V_BROWNMAP) + textcolor = "\x8d"; + else if (chatcolor == V_ROSYMAP) + textcolor = "\x8e"; + else if (chatcolor == V_INVERTMAP) + textcolor = "\x8f"; + return textcolor; +} + /** Receives a message, processing an ::XD_SAY command. * \sa DoSayCommand * \author Graue <graue@oceanbase.org> @@ -599,6 +638,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) SINT8 target; UINT8 flags; const char *dispname; + char buf[HU_MAXMSGLEN + 1]; char *msg; boolean action = false; char *ptr; @@ -608,8 +648,8 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) target = READSINT8(*p); flags = READUINT8(*p); - msg = (char *)*p; - SKIPSTRINGL(*p, HU_MAXMSGLEN + 1); + msg = buf; + READSTRINGL(*p, msg, HU_MAXMSGLEN + 1); if ((cv_mute.value || players[playernum].muted || flags & (HU_CSAY|HU_SERVER_SAY)) && playernum != serverplayer && !(IsPlayerAdmin(playernum))) { @@ -709,51 +749,27 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) { if (players[playernum].ctfteam == 1) // red { - cstart = "\x85"; - textcolor = "\x85"; + cstart = textcolor = GetChatColorFromSkinColor(skincolor_redteam); } else // blue { - cstart = "\x84"; - textcolor = "\x84"; + cstart = textcolor = GetChatColorFromSkinColor(skincolor_blueteam); } } else { - UINT16 chatcolor = skincolors[players[playernum].skincolor].chatcolor; - - if (!chatcolor || chatcolor%0x1000 || chatcolor>V_INVERTMAP) - cstart = "\x80"; - else if (chatcolor == V_MAGENTAMAP) - cstart = "\x81"; - else if (chatcolor == V_YELLOWMAP) - cstart = "\x82"; - else if (chatcolor == V_GREENMAP) - cstart = "\x83"; - else if (chatcolor == V_BLUEMAP) - cstart = "\x84"; - else if (chatcolor == V_REDMAP) - cstart = "\x85"; - else if (chatcolor == V_GRAYMAP) - cstart = "\x86"; - else if (chatcolor == V_ORANGEMAP) - cstart = "\x87"; - else if (chatcolor == V_SKYMAP) - cstart = "\x88"; - else if (chatcolor == V_PURPLEMAP) - cstart = "\x89"; - else if (chatcolor == V_AQUAMAP) - cstart = "\x8a"; - else if (chatcolor == V_PERIDOTMAP) - cstart = "\x8b"; - else if (chatcolor == V_AZUREMAP) - cstart = "\x8c"; - else if (chatcolor == V_BROWNMAP) - cstart = "\x8d"; - else if (chatcolor == V_ROSYMAP) - cstart = "\x8e"; - else if (chatcolor == V_INVERTMAP) - cstart = "\x8f"; + cstart = GetChatColorFromSkinColor(players[playernum].skincolor); + if (G_GametypeHasTeams()) + { + if (players[playernum].ctfteam == 1) // red + { + cstart = GetChatColorFromSkinColor(skincolor_redteam); + } + else // blue + { + cstart = GetChatColorFromSkinColor(skincolor_blueteam); + } + } } prefix = cstart; diff --git a/src/info.c b/src/info.c index aa213765281a8ab81f28b0a01350ef76532d18c9..1a3c39925186c61c1cf91b64e7933c250273e12f 100644 --- a/src/info.c +++ b/src/info.c @@ -306,6 +306,8 @@ static const char sprnames[][MAXSPRITENAME + 1] = "XMS4", // Lamppost "XMS5", // Hanging Star "XMS6", // Mistletoe + "SNTT", // Silver Shiver tree + "SSTT", // Silver Shiver tree with snow "FHZI", // FHZ ice "ROSY", @@ -339,6 +341,8 @@ static const char sprnames[][MAXSPRITENAME + 1] = // Misc Scenery "STLG", // Stalagmites "DBAL", // Disco + "GINE", // Crystalline Heights tree + "PPAL", // Pristine Shores palm trees // Powerup Indicators "ARMA", // Armageddon Shield Orb @@ -392,6 +396,15 @@ static const char sprnames[][MAXSPRITENAME + 1] = "SSWY", // Yellow Side Spring "SSWR", // Red Side Spring "SSWB", // Blue Side Spring + "MPRY", // Yellow trampoline + "MPRR", // Red trampoline + "MPRB", // Blue trampoline + "MSWY", // Yellow horizontal trampoline + "MSWR", // Red horizontal trampoline + "MSWB", // Blue horizontal trampoline + "MDIY", // Yellow diagonal trampoline + "MDIR", // Red diagonal trampoline + "MDIB", // Blue diagonal trampoline "BSTY", // Yellow Booster "BSTR", // Red Booster @@ -450,6 +463,7 @@ static const char sprnames[][MAXSPRITENAME + 1] = "BGOM", "FFWR", "FBLL", + "MKOP", "SHLL", "PUMA", "HAMM", @@ -459,6 +473,29 @@ static const char sprnames[][MAXSPRITENAME + 1] = "MUS1", "MUS2", "TOAD", + "MARS", + "MRFL", + "MAUH", + "MBSA", + "MBSB", + "MBSC", + "MFRE", + "MFYE", + "MFBE", + "MFWD", + "MUS3", + + // Mario powerups + "MSIV", // invincibility + "MS1P", // 1-up + "MSAT", // attract + "MSFO", // force + "MSAR", // nuke + "MSWW", // whirlwind + "MSEL", // elemental + "MSSP", // speed shoes + "MEGH", // poison + "UPPB", // particle pickup // NiGHTS Stuff "NDRN", // NiGHTS drone @@ -520,10 +557,18 @@ static const char sprnames[][MAXSPRITENAME + 1] = "BRIR", // CEZ3 colored bricks "BRIB", // CEZ3 colored bricks "BRIY", // CEZ3 colored bricks + "MBRI", + "MBRS", + "MBRB", + "MBRC", + "MTRI", // Gravity Well Objects "GWLG", "GWLR", + + // LJ Knuckles + "OLDK", }; UINT32 numspriteinfo; @@ -2557,6 +2602,10 @@ static const state_t startstates[] = {"LAMPPOST2", 0, SPR_XMS4, 1, -1, {NULL}, 0, 0, S_NULL, 0}, {"HANGSTAR", 0, SPR_XMS5, 0, -1, {NULL}, 0, 0, S_NULL, 0}, {"MISTLETOE", 0, SPR_XMS6, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"SSZTREE", 0, SPR_SNTT, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"SSZTREE_BRANCH", 0, SPR_SNTT, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL, 0}, + {"SSZTREE2", 0, SPR_SSTT, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"SSZTREE2_BRANCH", 0, SPR_SSTT, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL, 0}, // Xmas GFZ bushes {"XMASBLUEBERRYBUSH", 0, SPR_BUS3, 1, -1, {NULL}, 0, 0, S_NULL, 0}, {"XMASBERRYBUSH", 0, SPR_BUS1, 1, -1, {NULL}, 0, 0, S_NULL, 0}, @@ -2680,6 +2729,10 @@ static const state_t startstates[] = {"EGGSTATUE2", 0, SPR_ESTA, 1, -1, {NULL}, 0, 0, S_NULL, 0}, + {"GINE", 0, SPR_GINE, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"PPAL", 0, SPR_PPAL, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"PPEL", 0, SPR_PPAL, 1, -1, {NULL}, 0, 0, S_NULL, 0}, + // Shield Orb {"ARMA1", 0, SPR_ARMA, FF_TRANS40 , 2, {NULL}, 0, 0, S_ARMA2 , 0}, {"ARMA2", 0, SPR_ARMA, FF_TRANS40| 1, 2, {NULL}, 0, 0, S_ARMA3 , 0}, @@ -3229,6 +3282,69 @@ static const state_t startstates[] = {"BHORIZ7", 0, SPR_SSWB, 2, 1, {NULL}, 0, 0, S_BHORIZ8, 0}, {"BHORIZ8", 0, SPR_SSWB, 1, 1, {NULL}, 0, 0, S_BHORIZ1, 0}, + // Yellow trampoline + {"YELLOWTRAMPOLINE", 0, SPR_MPRY, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"YELLOWTRAMPOLINE2", 0, SPR_MPRY, 4, 4, {A_Pain}, 0, 0, S_YELLOWTRAMPOLINE3, 0}, + {"YELLOWTRAMPOLINE3", 0, SPR_MPRY, 3, 1, {NULL}, 0, 0, S_YELLOWTRAMPOLINE4, 0}, + {"YELLOWTRAMPOLINE4", 0, SPR_MPRY, 2, 1, {NULL}, 0, 0, S_YELLOWTRAMPOLINE5, 0}, + {"YELLOWTRAMPOLINE5", 0, SPR_MPRY, 1, 1, {NULL}, 0, 0, S_YELLOWTRAMPOLINE, 0}, + + // Red trampoline + {"REDTRAMPOLINE", 0, SPR_MPRR, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"REDTRAMPOLINE2", 0, SPR_MPRR, 4, 4, {A_Pain}, 0, 0, S_REDTRAMPOLINE3, 0}, + {"REDTRAMPOLINE3", 0, SPR_MPRR, 3, 1, {NULL}, 0, 0, S_REDTRAMPOLINE4, 0}, + {"REDTRAMPOLINE4", 0, SPR_MPRR, 2, 1, {NULL}, 0, 0, S_REDTRAMPOLINE5, 0}, + {"REDTRAMPOLINE5", 0, SPR_MPRR, 1, 1, {NULL}, 0, 0, S_REDTRAMPOLINE, 0}, + + // Blue trampoline + {"BLUETRAMPOLINE", 0, SPR_MPRB, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"BLUETRAMPOLINE2", 0, SPR_MPRB, 4, 4, {A_Pain}, 0, 0, S_BLUETRAMPOLINE3, 0}, + {"BLUETRAMPOLINE3", 0, SPR_MPRB, 3, 1, {NULL}, 0, 0, S_BLUETRAMPOLINE4, 0}, + {"BLUETRAMPOLINE4", 0, SPR_MPRB, 2, 1, {NULL}, 0, 0, S_BLUETRAMPOLINE5, 0}, + {"BLUETRAMPOLINE5", 0, SPR_MPRB, 1, 1, {NULL}, 0, 0, S_BLUETRAMPOLINE, 0}, + + // Yellow horizontal trampoline + {"HORIZYELLOWTRAMPOLINE", 0, SPR_MSWY, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"HORIZYELLOWTRAMPOLINE2", 0, SPR_MSWY, 4, 4, {A_Pain}, 0, 0, S_HORIZYELLOWTRAMPOLINE3, 0}, + {"HORIZYELLOWTRAMPOLINE3", 0, SPR_MSWY, 3, 1, {NULL}, 0, 0, S_HORIZYELLOWTRAMPOLINE4, 0}, + {"HORIZYELLOWTRAMPOLINE4", 0, SPR_MSWY, 2, 1, {NULL}, 0, 0, S_HORIZYELLOWTRAMPOLINE5, 0}, + {"HORIZYELLOWTRAMPOLINE5", 0, SPR_MSWY, 1, 1, {NULL}, 0, 0, S_HORIZYELLOWTRAMPOLINE, 0}, + + // Red horizontal trampoline + {"HORIZREDTRAMPOLINE", 0, SPR_MSWR, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"HORIZREDTRAMPOLINE2", 0, SPR_MSWR, 4, 4, {A_Pain}, 0, 0, S_HORIZREDTRAMPOLINE3, 0}, + {"HORIZREDTRAMPOLINE3", 0, SPR_MSWR, 3, 1, {NULL}, 0, 0, S_HORIZREDTRAMPOLINE4, 0}, + {"HORIZREDTRAMPOLINE4", 0, SPR_MSWR, 2, 1, {NULL}, 0, 0, S_HORIZREDTRAMPOLINE5, 0}, + {"HORIZREDTRAMPOLINE5", 0, SPR_MSWR, 1, 1, {NULL}, 0, 0, S_HORIZREDTRAMPOLINE, 0}, + + // Blue horizontal trampoline + {"HORIZBLUETRAMPOLINE", 0, SPR_MSWB, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"HORIZBLUETRAMPOLINE2", 0, SPR_MSWB, 4, 4, {A_Pain}, 0, 0, S_HORIZBLUETRAMPOLINE3, 0}, + {"HORIZBLUETRAMPOLINE3", 0, SPR_MSWB, 3, 1, {NULL}, 0, 0, S_HORIZBLUETRAMPOLINE4, 0}, + {"HORIZBLUETRAMPOLINE4", 0, SPR_MSWB, 2, 1, {NULL}, 0, 0, S_HORIZBLUETRAMPOLINE5, 0}, + {"HORIZBLUETRAMPOLINE5", 0, SPR_MSWB, 1, 1, {NULL}, 0, 0, S_HORIZBLUETRAMPOLINE, 0}, + + // Yellow diagonal trampoline + {"DIAGYELLOWTRAMPOLINE", 0, SPR_MDIY, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"DIAGYELLOWTRAMPOLINE2", 0, SPR_MDIY, 4, 4, {A_Pain}, 0, 0, S_DIAGYELLOWTRAMPOLINE3, 0}, + {"DIAGYELLOWTRAMPOLINE3", 0, SPR_MDIY, 3, 1, {NULL}, 0, 0, S_DIAGYELLOWTRAMPOLINE4, 0}, + {"DIAGYELLOWTRAMPOLINE4", 0, SPR_MDIY, 2, 1, {NULL}, 0, 0, S_DIAGYELLOWTRAMPOLINE5, 0}, + {"DIAGYELLOWTRAMPOLINE5", 0, SPR_MDIY, 1, 1, {NULL}, 0, 0, S_DIAGYELLOWTRAMPOLINE, 0}, + + // Red diagonal trampoline + {"DIAGREDTRAMPOLINE", 0, SPR_MDIR, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"DIAGREDTRAMPOLINE2", 0, SPR_MDIR, 4, 4, {A_Pain}, 0, 0, S_DIAGREDTRAMPOLINE3, 0}, + {"DIAGREDTRAMPOLINE3", 0, SPR_MDIR, 3, 1, {NULL}, 0, 0, S_DIAGREDTRAMPOLINE4, 0}, + {"DIAGREDTRAMPOLINE4", 0, SPR_MDIR, 2, 1, {NULL}, 0, 0, S_DIAGREDTRAMPOLINE5, 0}, + {"DIAGREDTRAMPOLINE5", 0, SPR_MDIR, 1, 1, {NULL}, 0, 0, S_DIAGREDTRAMPOLINE, 0}, + + // Blue diagonal trampoline + {"DIAGBLUETRAMPOLINE", 0, SPR_MDIB, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"DIAGBLUETRAMPOLINE2", 0, SPR_MDIB, 4, 4, {A_Pain}, 0, 0, S_DIAGBLUETRAMPOLINE3, 0}, + {"DIAGBLUETRAMPOLINE3", 0, SPR_MDIB, 3, 1, {NULL}, 0, 0, S_DIAGBLUETRAMPOLINE4, 0}, + {"DIAGBLUETRAMPOLINE4", 0, SPR_MDIB, 2, 1, {NULL}, 0, 0, S_DIAGBLUETRAMPOLINE5, 0}, + {"DIAGBLUETRAMPOLINE5", 0, SPR_MDIB, 1, 1, {NULL}, 0, 0, S_DIAGBLUETRAMPOLINE, 0}, + // Boosters {"BOOSTERSOUND", 0, SPR_NULL, 0, 1, {A_Pain}, 0, 0, S_INVISIBLE, 0}, {"YELLOWBOOSTERROLLER", 0, SPR_BSTY, FF_ANIMATE, -1, {NULL}, 2, 1, S_NULL, 0}, @@ -3524,41 +3640,33 @@ static const state_t startstates[] = {"RINGEXPLODE", 0, SPR_NULL, 0, 1, {A_RingExplode}, 0, 0, S_XPLD1, 0}, // Coin - {"COIN1", 0, SPR_COIN, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_COIN2, 0}, - {"COIN2", 0, SPR_COIN, FF_FULLBRIGHT|1, 5, {NULL}, 0, 0, S_COIN3, 0}, - {"COIN3", 0, SPR_COIN, FF_FULLBRIGHT|2, 5, {NULL}, 0, 0, S_COIN1, 0}, + {"COIN", 0, SPR_COIN, FF_ANIMATE, 32, {NULL}, 15, 2, S_COIN, 0}, // Coin Sparkle - {"COINSPARKLE1", 0, SPR_CPRK, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_COINSPARKLE2, 0}, - {"COINSPARKLE2", 0, SPR_CPRK, FF_FULLBRIGHT|1, 5, {NULL}, 0, 0, S_COINSPARKLE3, 0}, - {"COINSPARKLE3", 0, SPR_CPRK, FF_FULLBRIGHT|2, 5, {NULL}, 0, 0, S_COINSPARKLE4, 0}, - {"COINSPARKLE4", 0, SPR_CPRK, FF_FULLBRIGHT|3, 5, {NULL}, 0, 0, S_NULL, 0}, + {"COINSPARKLE1", 0, SPR_CPRK, 1|FF_FULLBRIGHT|FF_TRANS30|FF_ADD, 2, {A_ForceStop}, 0, 0, S_COINSPARKLE2, 0}, + {"COINSPARKLE2", 0, SPR_CPRK, 2|FF_FULLBRIGHT|FF_ANIMATE|FF_TRANS30|FF_ADD, 20, {NULL}, 9, 2, S_NULL, 0}, // Goomba {"GOOMBA1", 0, SPR_GOOM, 0, 6, {A_Look}, 0, 0, S_GOOMBA1B, 0}, {"GOOMBA1B", 0, SPR_GOOM, 1, 6, {A_Look}, 0, 0, S_GOOMBA1, 0}, - {"GOOMBA2", 0, SPR_GOOM, 0, 3, {A_Chase}, 0, 0, S_GOOMBA3, 0}, - {"GOOMBA3", 0, SPR_GOOM, 0, 3, {A_Chase}, 0, 0, S_GOOMBA4, 0}, - {"GOOMBA4", 0, SPR_GOOM, 1, 3, {A_Chase}, 0, 0, S_GOOMBA5, 0}, - {"GOOMBA5", 0, SPR_GOOM, 1, 3, {A_Chase}, 0, 0, S_GOOMBA6, 0}, - {"GOOMBA6", 0, SPR_GOOM, 0, 3, {A_Chase}, 0, 0, S_GOOMBA7, 0}, - {"GOOMBA7", 0, SPR_GOOM, 0, 3, {A_Chase}, 0, 0, S_GOOMBA8, 0}, - {"GOOMBA8", 0, SPR_GOOM, 1, 3, {A_Chase}, 0, 0, S_GOOMBA9, 0}, - {"GOOMBA9", 0, SPR_GOOM, 1, 3, {A_Chase}, 0, 0, S_GOOMBA2, 0}, - {"GOOMBA_DEAD", 0, SPR_GOOM, 2, 16, {A_Scream}, 0, 0, S_NULL, 0}, + {"GOOMBA2", 0, SPR_GOOM, 0, 6, {A_Chase}, 0, 0, S_GOOMBA3, 0}, + {"GOOMBA3", 0, SPR_GOOM, 1, 6, {A_Chase}, 0, 0, S_GOOMBA4, 0}, + {"GOOMBA4", 0, SPR_GOOM, 2, 6, {A_Chase}, 0, 0, S_GOOMBA5, 0}, + {"GOOMBA5", 0, SPR_GOOM, 3, 6, {A_Chase}, 0, 0, S_GOOMBA2, 0}, + {"GOOMBA_DEAD", 0, SPR_GOOM, 4, 8, {A_Scream}, 0, 0, S_GOOMBA_DEAD2, 0}, + {"GOOMBA_DEAD2", 0, SPR_GOOM, 5, 4, {NULL}, 0, 0, S_GOOMBA_DEAD3, 0}, + {"GOOMBA_DEAD3", 0, SPR_GOOM, 4, 15, {NULL}, 0, 0, S_NULL, 0}, // Blue Goomba {"BLUEGOOMBA1", 0, SPR_BGOM, 0, 6, {A_Look}, 0, 0, S_BLUEGOOMBA1B, 0}, {"BLUEGOOMBA1B", 0, SPR_BGOM, 1, 6, {A_Look}, 0, 0, S_BLUEGOOMBA1, 0}, - {"BLUEGOOMBA2", 0, SPR_BGOM, 0, 3, {A_Chase}, 0, 0, S_BLUEGOOMBA3, 0}, - {"BLUEGOOMBA3", 0, SPR_BGOM, 0, 3, {A_Chase}, 0, 0, S_BLUEGOOMBA4, 0}, - {"BLUEGOOMBA4", 0, SPR_BGOM, 1, 3, {A_Chase}, 0, 0, S_BLUEGOOMBA5, 0}, - {"BLUEGOOMBA5", 0, SPR_BGOM, 1, 3, {A_Chase}, 0, 0, S_BLUEGOOMBA6, 0}, - {"BLUEGOOMBA6", 0, SPR_BGOM, 0, 3, {A_Chase}, 0, 0, S_BLUEGOOMBA7, 0}, - {"BLUEGOOMBA7", 0, SPR_BGOM, 0, 3, {A_Chase}, 0, 0, S_BLUEGOOMBA8, 0}, - {"BLUEGOOMBA8", 0, SPR_BGOM, 1, 3, {A_Chase}, 0, 0, S_BLUEGOOMBA9, 0}, - {"BLUEGOOMBA9", 0, SPR_BGOM, 1, 3, {A_Chase}, 0, 0, S_BLUEGOOMBA2, 0}, - {"BLUEGOOMBA_DEAD", 0, SPR_BGOM, 2, 16, {A_Scream}, 0, 0, S_NULL, 0}, + {"BLUEGOOMBA2", 0, SPR_BGOM, 0, 6, {A_Chase}, 0, 0, S_BLUEGOOMBA3, 0}, + {"BLUEGOOMBA3", 0, SPR_BGOM, 1, 6, {A_Chase}, 0, 0, S_BLUEGOOMBA4, 0}, + {"BLUEGOOMBA4", 0, SPR_BGOM, 2, 6, {A_Chase}, 0, 0, S_BLUEGOOMBA5, 0}, + {"BLUEGOOMBA5", 0, SPR_BGOM, 3, 6, {A_Chase}, 0, 0, S_BLUEGOOMBA2, 0}, + {"BLUEGOOMBA_DEAD", 0, SPR_BGOM, 4, 8, {A_Scream}, 0, 0, S_BLUEGOOMBA_DEAD2, 0}, + {"BLUEGOOMBA_DEAD2", 0, SPR_BGOM, 5, 4, {NULL}, 0, 0, S_BLUEGOOMBA_DEAD3, 0}, + {"BLUEGOOMBA_DEAD3", 0, SPR_BGOM, 4, 15, {NULL}, 0, 0, S_NULL, 0}, // Fire Flower {"FIREFLOWER1", 0, SPR_FFWR, 0, 3, {NULL}, 0, 0, S_FIREFLOWER2, 0}, @@ -3571,8 +3679,17 @@ static const state_t startstates[] = {"FIREBALLTRAIL1", 0, SPR_FBLL, 1|FF_FULLBRIGHT|FF_TRANS50, 1, {A_SetScale}, FRACUNIT*3/4, 0, S_FIREBALLTRAIL2, 0}, {"FIREBALLTRAIL2", 0, SPR_FBLL, 1|FF_FULLBRIGHT|FF_TRANS50, 8, {A_SetScale}, FRACUNIT/6, 1, S_NULL, 0}, - // Turtle Shell - {"SHELL", 0, SPR_SHLL, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + // Green Koopa + {"GREENKOOPASPAWN", 0, SPR_MKOP, 0, 1, {A_Look}, 0, 0, S_GREENKOOPASPAWN, 0}, // S_GREENKOOPASPAWN + {"GREENKOOPA1", 0, SPR_MKOP, 0, 5, {A_GuardChase}, 1, 0, S_GREENKOOPA2, 0}, // S_GREENKOOPA1 + {"GREENKOOPA2", 0, SPR_MKOP, 1, 5, {A_GuardChase}, 1, 0, S_GREENKOOPA3, 0}, // S_GREENKOOPA2 + {"GREENKOOPA3", 0, SPR_MKOP, 2, 5, {A_GuardChase}, 1, 0, S_GREENKOOPA4, 0}, // S_GREENKOOPA3 + {"GREENKOOPA4", 0, SPR_MKOP, 3, 5, {A_GuardChase}, 1, 0, S_GREENKOOPA1, 0}, // S_GREENKOOPA4 + {"GREENKOOPADEATH1", 0, SPR_MKOP, 3, 1, {A_Scream}, 0, 0, S_GREENKOOPADEATH2, 0}, // S_GREENKOOPADEATH1 + {"GREENKOOPADEATH2", 0, SPR_MKOP, 3, 1, {A_SpawnObjectRelative}, 0|0, 0|MT_SHELL, S_NULL, 0}, // S_GREENKOOPADEATH2 + + // Koopa Shell + {"SHELL", 0 ,SPR_SHLL, 0, -1, {NULL}, 0, 0, S_NULL, 0}, // S_SHELL // Puma (Mario fireball) {"PUMA_START1", 0, SPR_PUMA, FF_FULLBRIGHT|2, 1, {A_FishJump}, 0, MT_PUMATRAIL, S_PUMA_START2, 0}, @@ -3609,6 +3726,70 @@ static const state_t startstates[] = {"MARIOBUSH2", 0, SPR_MUS2, 0, -1, {NULL}, 0, 0, S_NULL, 0}, {"TOAD", 0, SPR_TOAD, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"PTZSHROOM", 0, SPR_MARS, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"PTZFLAG1", 0, SPR_MRFL, 0|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_PTZFLAG2, 0}, + {"PTZFLAG2", 0, SPR_MRFL, 1|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_PTZFLAG3, 0}, + {"PTZFLAG3", 0, SPR_MRFL, 2|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_PTZFLAG4, 0}, + {"PTZFLAG4", 0, SPR_MRFL, 3|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_PTZFLAG5, 0}, + {"PTZFLAG5", 0, SPR_MRFL, 4|FF_PAPERSPRITE, 4, {NULL}, 0, 0, S_PTZFLAG1, 0}, + {"MARIOBUSH", 0, SPR_MAUH, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL, 0}, + {"BSBSHROOM", 0, SPR_MBSA, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"BLBSHROOM", 0, SPR_MBSB, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"BNWSHROOM", 0, SPR_MBSC, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"REDMFLOWER", 0, SPR_MFRE, FF_ANIMATE, -1, {NULL}, 3, 4, S_NULL, 0}, + {"BLUEMFLOWER", 0, SPR_MFBE, FF_ANIMATE, -1, {NULL}, 3, 4, S_NULL, 0}, + {"YELLOWMFLOWER", 0, SPR_MFYE, FF_ANIMATE, -1, {NULL}, 3, 4, S_NULL, 0}, + {"WHITEDANDELION", 0, SPR_MFWD, FF_ANIMATE, -1, {NULL}, 3, 6, S_NULL, 0}, + {"MAR64TREE", 0, SPR_MUS3, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + + // Mario powerups + {"LIFESHROOM", 0, SPR_MS1P, 0, 1, {A_FlickyHop}, FRACUNIT/6, 5*FRACUNIT, S_LIFESHROOM2, 0}, + {"LIFESHROOM2", 0, SPR_MS1P, 0, 1, {A_FlickyAim}, ANGLE_90, 64*FRACUNIT, S_LIFESHROOM, 0}, + {"LIFESHROOMD", 0, SPR_MS1P, 0, 1, {A_ExtraLife}, 0, 0, S_PARTICLEPICKUP1, 0}, + + {"LIFESHROOM_INVISIBLE", 0, SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"LIFESHROOM_INVISIBLE_TOUCH", 0, SPR_NULL, 0, 1, {A_ExtraLife}, 0, 0, S_NULL, 0}, + + {"POISONSHROOM", 0, SPR_MEGH, 0, 1, {A_FlickyHop}, FRACUNIT/6, 5*FRACUNIT, S_POISONSHROOM2, 0}, + {"POISONSHROOM2", 0, SPR_MEGH, 0, 1, {A_FlickyAim}, ANGLE_90, 64*FRACUNIT, S_POISONSHROOM, 0}, + {"POISONSHROOMD", 0, SPR_MEGH, 0, 1, {A_EggmanBox}, 0, 0, S_PARTICLEPICKUP1, 0}, + + {"NUKESHROOM", 0, SPR_MSAR, 0, 1, {A_FlickyHop}, FRACUNIT/6, 5*FRACUNIT, S_NUKESHROOM2, 0}, + {"NUKESHROOM2", 0, SPR_MSAR, 0, 1, {A_FlickyAim}, ANGLE_90, 64*FRACUNIT, S_NUKESHROOM, 0}, + {"NUKESHROOMD", 0, SPR_MSAR, 0, 1, {A_GiveShield}, SH_ARMAGEDDON, 0, S_1000SCOREAWARD, 0}, + + {"FORCESHROOM", 0, SPR_MSFO, 0, 1, {A_FlickyHop}, FRACUNIT/6, 5*FRACUNIT, S_FORCESHROOM2, 0}, + {"FORCESHROOM2", 0, SPR_MSFO, 0, 1, {A_FlickyAim}, ANGLE_90, 64*FRACUNIT, S_FORCESHROOM, 0}, + {"FORCESHROOMD", 0, SPR_MSFO, 0, 1, {A_GiveShield}, SH_FORCE|1, 0, S_1000SCOREAWARD, 0}, + + {"ATTRACTSHROOM", 0, SPR_MSAT, 0, 1, {A_FlickyHop}, FRACUNIT/6, 5*FRACUNIT, S_ATTRACTSHROOM2, 0}, + {"ATTRACTSHROOM2", 0, SPR_MSAT, 0, 1, {A_FlickyAim}, ANGLE_90, 64*FRACUNIT, S_ATTRACTSHROOM, 0}, + {"ATTRACTSHROOMD", 0, SPR_MSAT, 0, 1, {A_GiveShield}, SH_ATTRACT, 0, S_1000SCOREAWARD, 0}, + + {"ELEMENTALSHROOM", 0, SPR_MSEL, 0, 1, {A_FlickyHop}, FRACUNIT/6, 5*FRACUNIT, S_ELEMENTALSHROOM2, 0}, + {"ELEMENTALSHROOM2", 0, SPR_MSEL, 0, 1, {A_FlickyAim}, ANGLE_90, 64*FRACUNIT, S_ELEMENTALSHROOM, 0}, + {"ELEMENTALSHROOMD", 0, SPR_MSEL, 0, 1, {A_GiveShield}, SH_ELEMENTAL, 0, S_1000SCOREAWARD, 0}, + + {"CLOUDSHROOM", 0, SPR_MSWW, 0, 1, {A_FlickyHop}, FRACUNIT/6, 5*FRACUNIT, S_CLOUDSHROOM2, 0}, + {"CLOUDSHROOM2", 0, SPR_MSWW, 0, 1, {A_FlickyAim}, ANGLE_90, 64*FRACUNIT, S_CLOUDSHROOM, 0}, + {"CLOUDSHROOMD", 0, SPR_MSWW, 0, 1, {A_GiveShield}, SH_WHIRLWIND, 0, S_1000SCOREAWARD, 0}, + + {"STARMAN", 0, SPR_MSIV, 0, 1, {A_Look}, 3, 1, S_STARMAN, 0}, + {"STARMAN1", 0, SPR_MSIV, 0, 2, {A_BunnyHop}, 7, 6, S_STARMAN2, 0}, + {"STARMAN2", 0, SPR_MSIV, 0, 1, {A_SmokeTrailer}, MT_BOXSPARKLE, 0, S_STARMAN3, 0}, + {"STARMAN3", 0, SPR_MSIV, 0, 1, {A_GhostMe}, 0, 0, S_STARMAN1, 0}, + {"STARMAND", 0, SPR_MSIV, 0, 1, {A_Invincibility}, 0, 0, S_PARTICLEPICKUP1, 0}, + + {"SPEEDWINGS", 0, SPR_MSSP, 0, -1, {NULL}, 0, 0, S_NULL, 0}, + {"SPEEDWINGSD", 0, SPR_MSSP, 0, 1, {A_SuperSneakers}, 0, 0, S_NULL, 0}, + + {"PARTICLEPICKUP1", 0, SPR_UPPB, FF_ADD, 1, {A_ForceStop}, 0, 0, S_PARTICLEPICKUP2, 0}, + {"PARTICLEPICKUP2", 0, SPR_UPPB, 1|FF_ANIMATE|FF_ADD, 19, {NULL}, 18, 1, S_NULL, 0}, + {"1000SCOREAWARD", 0, SPR_NULL, 0, 1, {A_SpawnObjectRelative}, 0, MT_POWERUPAWARD, S_PARTICLEPICKUP1, 0}, + {"POWERUPAWARD", 0, SPR_NULL, 0, 1, {NULL}, 0, 0, S_POWERUPAWARD1, 0}, + {"POWERUPAWARD1", 0, SPR_NULL, 0, 1, {A_FindTarget}, MT_PLAYER, 0, S_POWERUPAWARD2, 0}, + {"POWERUPAWARD2", 0, SPR_NULL, 0, 1, {A_AwardScore}, 0, 0, S_NULL, 0}, + // Nights Drone {"NIGHTSDRONE_MAN1", 0, SPR_NDRN, 0, -1, {NULL}, 0, 0, S_NIGHTSDRONE_MAN2, 0}, {"NIGHTSDRONE_MAN2", 0, SPR_NDRN, 0, -1, {NULL}, 0, 0, S_NIGHTSDRONE_MAN1, 0}, @@ -3915,14 +4096,24 @@ static const state_t startstates[] = {"ROCKCRUMBLEO", 0, SPR_ROIO, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL, 0}, {"ROCKCRUMBLEP", 0, SPR_ROIP, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL, 0}, - {"GFZDEBRIS", 0, SPR_GFZD, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL, 0}, - {"BRICKDEBRIS", 0, SPR_BRIC, FF_ANIMATE, -1, {A_DebrisRandom}, 7, 2, S_NULL, 0}, - {"WOODDEBRIS", 0, SPR_WDDB, FF_ANIMATE, -1, {A_DebrisRandom}, 7, 2, S_NULL, 0}, - {"REDBRICKDEBRIS", 0, SPR_BRIR, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL, 0}, - {"BLUEBRICKDEBRIS", 0, SPR_BRIB, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL, 0}, - {"YELLOWBRICKDEBRIS", 0, SPR_BRIY, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL, 0}, - - {"NAMECHECK", 0, SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL, 0}, + {"GFZDEBRIS", 0, SPR_GFZD, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL, 0}, // S_GFZDEBRIS + {"BRICKDEBRIS", 0, SPR_BRIC, FF_ANIMATE, -1, {A_DebrisRandom}, 7, 2, S_NULL, 0}, // S_BRICKDEBRIS + {"WOODDEBRIS", 0, SPR_WDDB, FF_ANIMATE, -1, {A_DebrisRandom}, 7, 2, S_NULL, 0}, // S_WOODDEBRIS + {"REDBRICKDEBRIS", 0, SPR_BRIR, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL, 0}, // S_REDBRICKDEBRIS + {"BLUEBRICKDEBRIS", 0, SPR_BRIB, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL, 0}, // S_BLUEBRICKDEBRIS + {"YELLOWBRICKDEBRIS", 0, SPR_BRIY, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL, 0}, // S_YELLOWBRICKDEBRIS + {"MARIOBRICKDEBRIS", 0, SPR_MBRI, FF_ANIMATE, 50, {NULL}, 9, 2, S_NULL, 0}, // S_MARIOBRICKDEBRIS + {"MARIOBRICKDEBRISS", 0, SPR_MBRS, FF_ANIMATE, 50, {NULL}, 9, 2, S_NULL, 0}, // S_MARIOBRICKDEBRISS + {"MARIOBRICKDEBRISB", 0, SPR_MBRB, FF_ANIMATE, 50, {NULL}, 9, 2, S_NULL, 0}, // S_MARIOBRICKDEBRISB + {"MARIOBRICKDEBRISC", 0, SPR_MBRC, FF_ANIMATE, 50, {NULL}, 9, 2, S_NULL, 0}, // S_MARIOBRICKDEBRISC + {"MARIOBRICKDEBRISM", 0, SPR_MTRI, FF_ANIMATE, 50, {NULL}, 3, 4, S_NULL, 0}, // S_MARIOBRICKDEBRISM + + {"NAMECHECK", 0, SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL, 0}, // S_NAMECHECK + + {"OLDK_STND", 0, SPR_OLDK, FF_ANIMATE, -1, {NULL}, 1, 16, S_NULL, 0}, // S_OLDK_STND + {"OLDK_DIE0", 0, SPR_OLDK, 2, 0, {A_ForceWin}, 0, 0, S_OLDK_DIE1, 0}, // S_OLDK_DIE0 + {"OLDK_DIE1", 0, SPR_OLDK, 2, 0, {A_Scream}, 0, 0, S_OLDK_DIE2, 0}, // S_OLDK_DIE1 + {"OLDK_DIE2", 0, SPR_OLDK, 2, -1, {A_ZThrust}, 14, 1|(1<<16), S_NULL, 0}, // S_OLDK_DIE2 }; state_t **states; @@ -7872,6 +8063,258 @@ static const mobjinfo_t startmobjinfo[] = S_BHORIZ2 // raisestate }, + { + "YELLOWTRAMPOLINE", + 1814, // doomednum + S_YELLOWTRAMPOLINE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_mariob, // 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 + 20*FRACUNIT, // mass + 0, // damage + sfx_None, // activesound + MF_SOLID|MF_SPRING, // flags + S_YELLOWTRAMPOLINE2 // raisestate + }, + + { + "REDTRAMPOLINE", + 1815, // doomednum + S_REDTRAMPOLINE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_mariob, // 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 + 32*FRACUNIT, // mass + 0, // damage + sfx_None, // activesound + MF_SOLID|MF_SPRING, // flags + S_REDTRAMPOLINE2 // raisestate + }, + + { + "BLUETRAMPOLINE", + 1813, // doomednum + S_BLUETRAMPOLINE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_mariob, // 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_SOLID|MF_SPRING, // flags + S_BLUETRAMPOLINE2 // raisestate + }, + + { + "HORIZYELLOWTRAMPOLINE", + 1817, // doomednum + S_HORIZYELLOWTRAMPOLINE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_mariob, // 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 + 0, // mass + 36*FRACUNIT, // damage + sfx_None, // activesound + MF_SOLID|MF_SPRING, // flags + S_HORIZYELLOWTRAMPOLINE2 // raisestate + }, + + { + "HORIZREDTRAMPOLINE", + 1818, // doomednum + S_HORIZREDTRAMPOLINE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_mariob, // 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 + 0, // mass + 72*FRACUNIT, // damage + sfx_None, // activesound + MF_SOLID|MF_SPRING, // flags + S_HORIZREDTRAMPOLINE2 // raisestate + }, + + { + "HORIZBLUETRAMPOLINE", + 1816, // doomednum + S_HORIZBLUETRAMPOLINE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_mariob, // 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 + 0, // mass + 18*FRACUNIT, // damage + sfx_None, // activesound + MF_SOLID|MF_SPRING, // flags + S_HORIZBLUETRAMPOLINE2 // raisestate + }, + + { + "DIAGYELLOWTRAMPOLINE", + 2551, // doomednum + S_DIAGYELLOWTRAMPOLINE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_mariob, // 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 + 20*FRACUNIT, // mass + 20*FRACUNIT, // damage + sfx_None, // activesound + MF_SOLID|MF_SPRING, // flags + S_DIAGYELLOWTRAMPOLINE2 // raisestate + }, + + { + "DIAGREDTRAMPOLINE", + 2552, // doomednum + S_DIAGREDTRAMPOLINE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_mariob, // 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 + 32*FRACUNIT, // mass + 32*FRACUNIT, // damage + sfx_None, // activesound + MF_SOLID|MF_SPRING, // flags + S_DIAGREDTRAMPOLINE2 // raisestate + }, + + { + "DIAGBLUETRAMPOLINE", + 2550, // doomednum + S_DIAGBLUETRAMPOLINE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_mariob, // 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 + 11*FRACUNIT, // damage + sfx_None, // activesound + MF_SOLID|MF_SPRING, // flags + S_DIAGBLUETRAMPOLINE2 // raisestate + }, + { "BOOSTERSEG", -1, // doomednum @@ -14845,9 +15288,9 @@ static const mobjinfo_t startmobjinfo[] = }, { - "XMASBLUEBERRYBUSH", - 1859, // doomednum - S_XMASBLUEBERRYBUSH, // spawnstate + "SSZTREE", + 1860, // doomednum + S_SSZTREE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -14862,20 +15305,20 @@ static const mobjinfo_t startmobjinfo[] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 20*FRACUNIT, // radius + 256*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_SCENERY, // flags S_NULL // raisestate }, { - "XMASBERRYBUSH", - 1857, // doomednum - S_XMASBERRYBUSH, // spawnstate + "SSZTREE_BRANCH", + -1, // doomednum + S_SSZTREE_BRANCH, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -14890,20 +15333,20 @@ static const mobjinfo_t startmobjinfo[] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 20*FRACUNIT, // radius + 256*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage + 1, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, { - "XMASBUSH", - 1858, // doomednum - S_XMASBUSH, // spawnstate + "SSZTREE2", + 1861, // doomednum + S_SSZTREE2, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -14918,20 +15361,20 @@ static const mobjinfo_t startmobjinfo[] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 20*FRACUNIT, // radius + 256*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_SCENERY, // flags S_NULL // raisestate }, { - "FHZICE1", - 2100, // doomednum - S_FHZICE1, // spawnstate + "SSZTREE2_BRANCH", + -1, // doomednum + S_SSZTREE2_BRANCH, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -14946,20 +15389,20 @@ static const mobjinfo_t startmobjinfo[] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8*FRACUNIT, // radius - 32*FRACUNIT, // height + 20*FRACUNIT, // radius + 256*FRACUNIT, // height 0, // display offset 100, // mass - 0, // damage + 1, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, { - "FHZICE2", - 2101, // doomednum - S_FHZICE2, // spawnstate + "XMASBLUEBERRYBUSH", + 1859, // doomednum + S_XMASBLUEBERRYBUSH, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -14974,7 +15417,7 @@ static const mobjinfo_t startmobjinfo[] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8*FRACUNIT, // radius + 16*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset 100, // mass @@ -14985,10 +15428,122 @@ static const mobjinfo_t startmobjinfo[] = }, { - "ROSY", - 2104, // doomednum - S_ROSY_IDLE1, // spawnstate - 1000, // spawnhealth + "XMASBERRYBUSH", + 1857, // doomednum + S_XMASBERRYBUSH, // 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_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { + "XMASBUSH", + 1858, // doomednum + S_XMASBUSH, // 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_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { + "FHZICE1", + 2100, // doomednum + S_FHZICE1, // 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_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { + "FHZICE2", + 2101, // doomednum + S_FHZICE2, // 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_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { + "ROSY", + 2104, // doomednum + S_ROSY_IDLE1, // spawnstate + 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime @@ -16751,6 +17306,90 @@ static const mobjinfo_t startmobjinfo[] = S_NULL // raisestate }, + { + "GINE", + 3048, // doomednum + S_GINE, // 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 + 32*FRACUNIT, // radius + 628*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_SOLID|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { + "PPAL", + 3050, // doomednum + S_PPAL, // 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 + 626*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_SOLID|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { + "PPEL", + 3051, // doomednum + S_PPEL, // 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 + 517*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_SOLID|MF_SCENERY, // flags + S_NULL // raisestate + }, + { "ELEMENTAL_ORB", -1, // doomednum @@ -19362,7 +20001,7 @@ static const mobjinfo_t startmobjinfo[] = { "COIN", 1800, // doomednum - S_COIN1, // spawnstate + S_COIN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -19390,7 +20029,7 @@ static const mobjinfo_t startmobjinfo[] = { "FLINGCOIN", -1, // doomednum - S_COIN1, // spawnstate + S_COIN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -19555,6 +20194,34 @@ static const mobjinfo_t startmobjinfo[] = S_NULL // raisestate }, + { + "GREENKOOPA", + 1832, // doomednum + S_GREENKOOPASPAWN, // spawnstate + 1, // spawnhealth + S_GREENKOOPA1, // seestate + sfx_None, // seesound + 1, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_GREENKOOPADEATH1, // deathstate + S_NULL, // xdeathstate + sfx_mario2, // deathsound + 12, // speed + 16*FRACUNIT, // radius + 48*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_mario1, // activesound + MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY, // flags + S_NULL // raisestate + }, + { "SHELL", 1804, // doomednum @@ -19835,9 +20502,9 @@ static const mobjinfo_t startmobjinfo[] = }, { - "AXIS", - 1700, // doomednum - S_INVISIBLE, // spawnstate + "PTZSHROOM", + 1811, // doomednum + S_PTZSHROOM, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -19851,21 +20518,21 @@ static const mobjinfo_t startmobjinfo[] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 10*FRACUNIT, // speed - 256*FRACUNIT, // radius - 1*FRACUNIT, // height + 0, // speed + 16*FRACUNIT, // radius + 96*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP, // flags + MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, { - "AXISTRANSFER", - 1701, // doomednum - S_INVISIBLE, // spawnstate + "PTZFLAG", + 1812, // doomednum + S_PTZFLAG1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -19879,21 +20546,21 @@ static const mobjinfo_t startmobjinfo[] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 10, // speed + 0, // speed 16*FRACUNIT, // radius - 1, // height + 96*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP, // flags + MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, { - "AXISTRANSFERLINE", - 1702, // doomednum - S_INVISIBLE, // spawnstate + "MARIOBUSH", + 1819, // doomednum + S_MARIOBUSH, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -19907,28 +20574,28 @@ static const mobjinfo_t startmobjinfo[] = S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound - 10, // speed - 32*FRACUNIT, // radius - 1, // height + 0, // speed + 16*FRACUNIT, // radius + 96*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP, // flags + MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, { - "NIGHTSDRONE", - 1703, // doomednum - S_INVISIBLE, // spawnstate - 120, // spawnhealth + "BSBSHROOM", + 1820, // doomednum + S_BSBSHROOM, // 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 @@ -19937,36 +20604,652 @@ static const mobjinfo_t startmobjinfo[] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 80*FRACUNIT, // height - 1, // display offset - 1000, // mass + 96*FRACUNIT, // height + 0, // display offset + 100, // mass 0, // damage - sfx_ideya, // activesound - MF_NOGRAVITY|MF_NOCLIP|MF_SPECIAL, // flags + sfx_None, // activesound + MF_NOCLIP|MF_SCENERY, // flags S_NULL // raisestate }, { - "NIGHTSDRONE_MAN", - -1, // doomednum - S_INVISIBLE, // spawnstate - 120, // spawnhealth + "BLBSHROOM", + 1821, // doomednum + S_BLBSHROOM, // 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_NIGHTSDRONE_MAN1, // meleestate + S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 56*FRACUNIT, // height - 1, // display offset + 96*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { + "BNWSHROOM", + 1822, // doomednum + S_BNWSHROOM, // 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 + 96*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { + "REDMFLOWER", + 1823, // doomednum + S_REDMFLOWER, // 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 + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { + "BLUEMFLOWER", + 1842, // doomednum + S_BLUEMFLOWER, // 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 + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { + "YELLOWMFLOWER", + 1824, // doomednum + S_YELLOWMFLOWER,// 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 + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { + "WHITEDANDELION", + 1840, // doomednum + S_WHITEDANDELION, // 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 + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { + "MAR64TREE", + 1847, // doomednum + S_MAR64TREE, // 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 + 150*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SOLID|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { + "LIFESHROOM", + 1826, // doomednum + S_LIFESHROOM, // 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_LIFESHROOMD, // 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 + }, + + { + "LIFESHROOM_INVISIBLE", + 1841, // doomednum + S_LIFESHROOM_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_LIFESHROOM_INVISIBLE_TOUCH, // deathstate + S_NULL, // xdeathstate + sfx_mario3, // deathsound + -3072, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { + "POISONSHROOM", + 2303, // doomednum + S_POISONSHROOM, // 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_POISONSHROOMD,// deathstate + S_NULL, // xdeathstate + sfx_mario3, // 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 + }, + + { + "NUKESHROOM", + 1829, // doomednum + S_NUKESHROOM, // 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_NUKESHROOMD, // deathstate + S_NULL, // xdeathstate + sfx_mario3, // 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 + }, + + { + "FORCESHROOM", + 1828, // doomednum + S_FORCESHROOM, // 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_FORCESHROOMD, // deathstate + S_NULL, // xdeathstate + sfx_mario3, // 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 + }, + + { + "ATTRACTSHROOM", + 1827, // doomednum + S_ATTRACTSHROOM,// 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_ATTRACTSHROOMD, // deathstate + S_NULL, // xdeathstate + sfx_mario3, // 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 + }, + + { + "ELEMENTALSHROOM", + 1831, // doomednum + S_ELEMENTALSHROOM, // 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_ELEMENTALSHROOMD, // deathstate + S_NULL, // xdeathstate + sfx_mario3, // 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 + }, + + { + "CLOUDSHROOM", + 1830, // doomednum + S_CLOUDSHROOM, // 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_CLOUDSHROOMD, // deathstate + S_NULL, // xdeathstate + sfx_mario3, // 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 + }, + + { + "STARMAN", + 1825, // doomednum + S_STARMAN, // spawnstate + 1000, // spawnhealth + S_STARMAN1, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_STARMAND, // deathstate + S_NULL, // xdeathstate + sfx_mario3, // 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 + }, + + { + "SPEEDWINGS", + 2304, // doomednum + S_SPEEDWINGS, // 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_SPEEDWINGSD, // deathstate + S_NULL, // xdeathstate + sfx_mario3, // 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 + }, + + { + "POWERUPAWARD", + -1, // doomednum + S_POWERUPAWARD, // 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_mario4, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { + "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 + }, + + { + "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 + }, + + { + "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 + }, + + { + "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 + }, + + { + "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 @@ -22132,6 +23415,146 @@ static const mobjinfo_t startmobjinfo[] = S_NULL // raisestate }, + { + "MARIOBRICKDEBRIS", + -1, // doomednum + S_MARIOBRICKDEBRIS, // 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 + 6, // speed + 16*FRACUNIT, // radius + 48*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_marioc, // activesound + MF_NOCLIPHEIGHT|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { + "MARIOBRICKDEBRISS", + -1, // doomednum + S_MARIOBRICKDEBRISS, // 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 + 6, // speed + 16*FRACUNIT, // radius + 48*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_marioc, // activesound + MF_NOCLIPHEIGHT|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { + "MARIOBRICKDEBRISB", + -1, // doomednum + S_MARIOBRICKDEBRISB, // 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 + 6, // speed + 16*FRACUNIT, // radius + 48*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_marioc, // activesound + MF_NOCLIPHEIGHT|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { + "MARIOBRICKDEBRISC", + -1, // doomednum + S_MARIOBRICKDEBRISC, // 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 + 6, // speed + 16*FRACUNIT, // radius + 48*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_marioc, // activesound + MF_NOCLIPHEIGHT|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { + "MARIOBRICKDEBRISM", + -1, // doomednum + S_MARIOBRICKDEBRISM, // 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 + 6, // speed + 16*FRACUNIT, // radius + 48*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_marioc, // activesound + MF_NOCLIPHEIGHT|MF_SCENERY, // flags + S_NULL // raisestate + }, + { "NAMECHECK", -1, // doomednum @@ -22187,6 +23610,34 @@ static const mobjinfo_t startmobjinfo[] = MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, + + { + "OLDK", + 666, // doomednum + S_OLDK_STND, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 32, // reactiontime + sfx_None, // attacksound + S_OLDK_DIE0, // painstate + 128, // painchance + sfx_s3k35, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_OLDK_DIE0, // deathstate + S_NULL, // xdeathstate + sfx_s3k35, // deathsound + 2*FRACUNIT, // speed + 32*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // display offset + 1000, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL|MF_SHOOTABLE|MF_NOGRAVITY|MF_BOSS, // flags + S_NULL // raisestate + }, }; mobjinfo_t **mobjinfo; diff --git a/src/info.h b/src/info.h index 804f74ca16082ca5cda2a04c878bd7f05c252192..61df9c6af3ad9a48f27689aa81158635d0b58102 100644 --- a/src/info.h +++ b/src/info.h @@ -856,6 +856,8 @@ typedef enum sprite SPR_XMS4, // Lamppost SPR_XMS5, // Hanging Star SPR_XMS6, // Mistletoe + SPR_SNTT, // Silver Shiver tree + SPR_SSTT, // Silver Shiver tree with snow SPR_FHZI, // FHZ Ice SPR_ROSY, @@ -889,6 +891,8 @@ typedef enum sprite // Misc Scenery SPR_STLG, // Stalagmites SPR_DBAL, // Disco + SPR_GINE, // Crystalline Heights tree + SPR_PPAL, // Pristine Shores palm trees // Powerup Indicators SPR_ARMA, // Armageddon Shield Orb @@ -942,6 +946,15 @@ typedef enum sprite SPR_SSWY, // Yellow Side Spring SPR_SSWR, // Red Side Spring SPR_SSWB, // Blue Side Spring + SPR_MPRY, // Yellow trampoline + SPR_MPRR, // Red trampoline + SPR_MPRB, // Blue trampoline + SPR_MSWY, // Yellow horizontal trampoline + SPR_MSWR, // Red horizontal trampoline + SPR_MSWB, // Blue horizontal trampoline + SPR_MDIY, // Yellow diagonal trampoline + SPR_MDIR, // Red diagonal trampoline + SPR_MDIB, // Blue diagonal trampoline SPR_BSTY, // Yellow Booster SPR_BSTR, // Red Booster @@ -1000,6 +1013,7 @@ typedef enum sprite SPR_BGOM, SPR_FFWR, SPR_FBLL, + SPR_MKOP, SPR_SHLL, SPR_PUMA, SPR_HAMM, @@ -1009,6 +1023,29 @@ typedef enum sprite SPR_MUS1, SPR_MUS2, SPR_TOAD, + SPR_MARS, + SPR_MRFL, + SPR_MAUH, + SPR_MBSA, + SPR_MBSB, + SPR_MBSC, + SPR_MFRE, + SPR_MFYE, + SPR_MFBE, + SPR_MFWD, + SPR_MUS3, + + // Mario powerups + SPR_MSIV, // invincibility + SPR_MS1P, // 1-up + SPR_MSAT, // attract + SPR_MSFO, // force + SPR_MSAR, // nuke + SPR_MSWW, // whirlwind + SPR_MSEL, // elemental + SPR_MSSP, // speed shoes + SPR_MEGH, // poison + SPR_UPPB, // particle pickup // NiGHTS Stuff SPR_NDRN, // NiGHTS drone @@ -1070,10 +1107,18 @@ typedef enum sprite SPR_BRIR, // CEZ3 colored bricks SPR_BRIB, SPR_BRIY, + SPR_MBRI, + SPR_MBRS, + SPR_MBRB, + SPR_MBRC, + SPR_MTRI, // Gravity Well Objects SPR_GWLG, SPR_GWLR, + + // LJ Knuckles + SPR_OLDK, } spritenum_t; typedef enum playersprite @@ -3080,6 +3125,10 @@ typedef enum state S_LAMPPOST2, // with snow S_HANGSTAR, S_MISTLETOE, + S_SSZTREE, + S_SSZTREE_BRANCH, + S_SSZTREE2, + S_SSZTREE2_BRANCH, // Xmas GFZ bushes S_XMASBLUEBERRYBUSH, S_XMASBERRYBUSH, @@ -3200,6 +3249,9 @@ typedef enum state S_DBALL5, S_DBALL6, S_EGGSTATUE2, + S_GINE, + S_PPAL, + S_PPEL, // Shield Orb S_ARMA1, @@ -3748,6 +3800,69 @@ typedef enum state S_BHORIZ7, S_BHORIZ8, + // Yellow Trampoline + S_YELLOWTRAMPOLINE, + S_YELLOWTRAMPOLINE2, + S_YELLOWTRAMPOLINE3, + S_YELLOWTRAMPOLINE4, + S_YELLOWTRAMPOLINE5, + + // Red Trampoline + S_REDTRAMPOLINE, + S_REDTRAMPOLINE2, + S_REDTRAMPOLINE3, + S_REDTRAMPOLINE4, + S_REDTRAMPOLINE5, + + // Blue Trampoline + S_BLUETRAMPOLINE, + S_BLUETRAMPOLINE2, + S_BLUETRAMPOLINE3, + S_BLUETRAMPOLINE4, + S_BLUETRAMPOLINE5, + + // Horizontal Yellow Trampoline + S_HORIZYELLOWTRAMPOLINE, + S_HORIZYELLOWTRAMPOLINE2, + S_HORIZYELLOWTRAMPOLINE3, + S_HORIZYELLOWTRAMPOLINE4, + S_HORIZYELLOWTRAMPOLINE5, + + // Horizontal Red Trampoline + S_HORIZREDTRAMPOLINE, + S_HORIZREDTRAMPOLINE2, + S_HORIZREDTRAMPOLINE3, + S_HORIZREDTRAMPOLINE4, + S_HORIZREDTRAMPOLINE5, + + // Horizontal Blue Trampoline + S_HORIZBLUETRAMPOLINE, + S_HORIZBLUETRAMPOLINE2, + S_HORIZBLUETRAMPOLINE3, + S_HORIZBLUETRAMPOLINE4, + S_HORIZBLUETRAMPOLINE5, + + // Diagonal Yellow Trampoline + S_DIAGYELLOWTRAMPOLINE, + S_DIAGYELLOWTRAMPOLINE2, + S_DIAGYELLOWTRAMPOLINE3, + S_DIAGYELLOWTRAMPOLINE4, + S_DIAGYELLOWTRAMPOLINE5, + + // Diagonal Red Trampoline + S_DIAGREDTRAMPOLINE, + S_DIAGREDTRAMPOLINE2, + S_DIAGREDTRAMPOLINE3, + S_DIAGREDTRAMPOLINE4, + S_DIAGREDTRAMPOLINE5, + + // Diagonal Blue Trampoline + S_DIAGBLUETRAMPOLINE, + S_DIAGBLUETRAMPOLINE2, + S_DIAGBLUETRAMPOLINE3, + S_DIAGBLUETRAMPOLINE4, + S_DIAGBLUETRAMPOLINE5, + // Booster S_BOOSTERSOUND, S_YELLOWBOOSTERROLLER, @@ -4020,37 +4135,28 @@ typedef enum state S_RINGEXPLODE, - S_COIN1, - S_COIN2, - S_COIN3, + // Mario-specific stuff + S_COIN, S_COINSPARKLE1, S_COINSPARKLE2, - S_COINSPARKLE3, - S_COINSPARKLE4, S_GOOMBA1, S_GOOMBA1B, S_GOOMBA2, S_GOOMBA3, S_GOOMBA4, S_GOOMBA5, - S_GOOMBA6, - S_GOOMBA7, - S_GOOMBA8, - S_GOOMBA9, S_GOOMBA_DEAD, + S_GOOMBA_DEAD2, + S_GOOMBA_DEAD3, S_BLUEGOOMBA1, S_BLUEGOOMBA1B, S_BLUEGOOMBA2, S_BLUEGOOMBA3, S_BLUEGOOMBA4, S_BLUEGOOMBA5, - S_BLUEGOOMBA6, - S_BLUEGOOMBA7, - S_BLUEGOOMBA8, - S_BLUEGOOMBA9, S_BLUEGOOMBA_DEAD, - - // Mario-specific stuff + S_BLUEGOOMBA_DEAD2, + S_BLUEGOOMBA_DEAD3, S_FIREFLOWER1, S_FIREFLOWER2, S_FIREFLOWER3, @@ -4058,6 +4164,13 @@ typedef enum state S_FIREBALL, S_FIREBALLTRAIL1, S_FIREBALLTRAIL2, + S_GREENKOOPASPAWN, + S_GREENKOOPA1, + S_GREENKOOPA2, + S_GREENKOOPA3, + S_GREENKOOPA4, + S_GREENKOOPADEATH1, + S_GREENKOOPADEATH2, S_SHELL, S_PUMA_START1, S_PUMA_START2, @@ -4083,6 +4196,68 @@ typedef enum state S_MARIOBUSH1, S_MARIOBUSH2, S_TOAD, + S_PTZSHROOM, + S_PTZFLAG1, + S_PTZFLAG2, + S_PTZFLAG3, + S_PTZFLAG4, + S_PTZFLAG5, + S_MARIOBUSH, + S_BSBSHROOM, + S_BLBSHROOM, + S_BNWSHROOM, + S_REDMFLOWER, + S_BLUEMFLOWER, + S_YELLOWMFLOWER, + S_WHITEDANDELION, + S_MAR64TREE, + + // Power up mushrooms + S_LIFESHROOM, + S_LIFESHROOM2, + S_LIFESHROOMD, + S_LIFESHROOM_INVISIBLE, + S_LIFESHROOM_INVISIBLE_TOUCH, + + S_POISONSHROOM, + S_POISONSHROOM2, + S_POISONSHROOMD, + + S_NUKESHROOM, + S_NUKESHROOM2, + S_NUKESHROOMD, + + S_FORCESHROOM, + S_FORCESHROOM2, + S_FORCESHROOMD, + + S_ATTRACTSHROOM, + S_ATTRACTSHROOM2, + S_ATTRACTSHROOMD, + + S_ELEMENTALSHROOM, + S_ELEMENTALSHROOM2, + S_ELEMENTALSHROOMD, + + S_CLOUDSHROOM, + S_CLOUDSHROOM2, + S_CLOUDSHROOMD, + + S_STARMAN, + S_STARMAN1, + S_STARMAN2, + S_STARMAN3, + S_STARMAND, + + S_SPEEDWINGS, + S_SPEEDWINGSD, + + S_PARTICLEPICKUP1, + S_PARTICLEPICKUP2, + S_1000SCOREAWARD, + S_POWERUPAWARD, + S_POWERUPAWARD1, + S_POWERUPAWARD2, // Nights-specific stuff S_NIGHTSDRONE_MAN1, @@ -4385,8 +4560,19 @@ typedef enum state S_REDBRICKDEBRIS, // for CEZ3 S_BLUEBRICKDEBRIS, // for CEZ3 S_YELLOWBRICKDEBRIS, // for CEZ3 + S_MARIOBRICKDEBRIS, + S_MARIOBRICKDEBRISS, + S_MARIOBRICKDEBRISB, + S_MARIOBRICKDEBRISC, + S_MARIOBRICKDEBRISM, S_NAMECHECK, + + // LJ Knuckles + S_OLDK_STND, + S_OLDK_DIE0, + S_OLDK_DIE1, + S_OLDK_DIE2, } statenum_t; typedef struct @@ -4577,6 +4763,16 @@ typedef enum mobj_type MT_REDHORIZ, MT_BLUEHORIZ, + MT_YELLOWTRAMPOLINE, + MT_REDTRAMPOLINE, + MT_BLUETRAMPOLINE, + MT_HORIZYELLOWTRAMPOLINE, + MT_HORIZREDTRAMPOLINE, + MT_HORIZBLUETRAMPOLINE, + MT_DIAGYELLOWTRAMPOLINE, + MT_DIAGREDTRAMPOLINE, + MT_DIAGBLUETRAMPOLINE, + MT_BOOSTERSEG, MT_BOOSTERROLLER, MT_YELLOWBOOSTER, @@ -4874,6 +5070,10 @@ typedef enum mobj_type MT_LAMPPOST2, // with snow MT_HANGSTAR, MT_MISTLETOE, + MT_SSZTREE, + MT_SSZTREE_BRANCH, + MT_SSZTREE2, + MT_SSZTREE2_BRANCH, // Xmas GFZ bushes MT_XMASBLUEBERRYBUSH, MT_XMASBERRYBUSH, @@ -4953,6 +5153,9 @@ typedef enum mobj_type // Misc scenery MT_DBALL, MT_EGGSTATUE2, + MT_GINE, + MT_PPAL, + MT_PPEL, // Powerup Indicators MT_ELEMENTAL_ORB, // Elemental shield mobj @@ -5070,6 +5273,7 @@ typedef enum mobj_type MT_FIREFLOWER, MT_FIREBALL, MT_FIREBALLTRAIL, + MT_GREENKOOPA, MT_SHELL, MT_PUMA, MT_PUMATRAIL, @@ -5080,6 +5284,30 @@ typedef enum mobj_type MT_MARIOBUSH1, MT_MARIOBUSH2, MT_TOAD, + MT_PTZSHROOM, + MT_PTZFLAG, + MT_BSBSHROOM, + MT_BLBSHROOM, + MT_BNWSHROOM, + MT_MARIOBUSH, + MT_REDMFLOWER, + MT_BLUEMFLOWER, + MT_YELLOWMFLOWER, + MT_WHITEDANDELION, + MT_MAR64TREE, + + // Power up mushrooms + MT_LIFESHROOM, + MT_LIFESHROOM_INVISIBLE, + MT_POISONSHROOM, + MT_NUKESHROOM, + MT_FORCESHROOM, + MT_ATTRACTSHROOM, + MT_ELEMENTALSHROOM, + MT_CLOUDSHROOM, + MT_STARMAN, + MT_SPEEDWINGS, + MT_POWERUPAWARD, // NiGHTS Stuff MT_AXIS, @@ -5177,9 +5405,16 @@ typedef enum mobj_type MT_REDBRICKDEBRIS, // for CEZ3 MT_BLUEBRICKDEBRIS, // for CEZ3 MT_YELLOWBRICKDEBRIS, // for CEZ3 + MT_MARIOBRICKDEBRIS, + MT_MARIOBRICKDEBRISS, + MT_MARIOBRICKDEBRISB, + MT_MARIOBRICKDEBRISC, + MT_MARIOBRICKDEBRISM, MT_NAMECHECK, MT_RAY, // General purpose mobj + + MT_OLDK, } mobjtype_t; typedef struct diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 475aa437dbff4ef2be9141a1bd2dc38bf809a0ea..7f8c99156db1e75c4b8010da36b9f3d1e322ee6e 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by John "JTE" Muniz. -// Copyright (C) 2012-2024 by Sonic Team Junior. +// Copyright (C) 2012-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -1730,12 +1730,11 @@ static int lib_pResetCamera(lua_State *L) static int lib_pSuperReady(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); - boolean transform = (boolean)lua_opttrueboolean(L, 2); //HUDSAFE INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); - lua_pushboolean(L, P_SuperReady(player, transform)); + lua_pushboolean(L, P_SuperReady(player)); return 1; } @@ -3181,17 +3180,25 @@ static int lib_rTextureNumForName(lua_State *L) static int lib_rCheckTextureNameForNum(lua_State *L) { + char s[9]; INT32 num = (INT32)luaL_checkinteger(L, 1); //HUDSAFE - lua_pushstring(L, R_CheckTextureNameForNum(num)); + + M_Memcpy(s, R_CheckTextureNameForNum(num), 8); + s[8] = '\0'; + lua_pushstring(L, s); return 1; } static int lib_rTextureNameForNum(lua_State *L) { + char s[9]; INT32 num = (INT32)luaL_checkinteger(L, 1); //HUDSAFE - lua_pushstring(L, R_TextureNameForNum(num)); + + M_Memcpy(s, R_TextureNameForNum(num), 8); + s[8] = '\0'; + lua_pushstring(L, s); return 1; } diff --git a/src/lua_blockmaplib.c b/src/lua_blockmaplib.c index c29eadecc625214615c2546abd2216c9b6630254..f570c229b97b138d6d10e714c4c2cdd8175b1596 100644 --- a/src/lua_blockmaplib.c +++ b/src/lua_blockmaplib.c @@ -254,11 +254,10 @@ static int lib_searchBlockmap(lua_State *L) } else // mobj and function only - search around mobj's radius by default { - fixed_t radius = mobj->radius + MAXRADIUS; - x1 = mobj->x - radius; - x2 = mobj->x + radius; - y1 = mobj->y - radius; - y2 = mobj->y + radius; + x1 = mobj->x - mobj->radius; + x2 = mobj->x + mobj->radius; + y1 = mobj->y - mobj->radius; + y2 = mobj->y + mobj->radius; } lua_settop(L, 2); // pop everything except function, mobj diff --git a/src/lua_colorlib.c b/src/lua_colorlib.c index 9e679eb402f8e6e99eb4957c93aee8dbe9915bdb..2743635edfefe88348a93dc45aa26f77d4702067 100644 --- a/src/lua_colorlib.c +++ b/src/lua_colorlib.c @@ -593,7 +593,7 @@ static int extracolormap_set(lua_State *L) || exc->fadergba != old_fade_rgba || exc->fadestart != old_fade_start || exc->fadeend != old_fade_end) - R_GenerateLightTable(exc, true); + R_UpdateLightTable(exc, true); return 0; } diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index aaa676526d1eac6adbad4ac5d8ba34e31388d2cd..b9b24307b0127b41fe0050106c4447ac5d3f7d55 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -31,11 +31,27 @@ return luaL_error(L, "HUD rendering code should not call this function!"); static consvar_t *this_cvar; +static void clear_lua_stack(void) +{ + if (gL) // check if Lua is actually turned on first, you dummmy -- Monster Iestyn 04/07/18 + lua_settop(gL, 0); // clear stack +} + void Got_Luacmd(UINT8 **cp, INT32 playernum) { UINT8 i, argc, flags; + const char *argv[256]; char buf[256]; + argc = READUINT8(*cp); + argv[0] = (const char*)*cp; + SKIPSTRINGN(*cp, 255); + for (i = 1; i < argc; i++) + { + argv[i] = (const char*)*cp; + SKIPSTRINGN(*cp, 255); + } + // don't use I_Assert here, goto the deny code below // to clean up and kick people who try nefarious exploits // like sending random junk lua commands to crash the server @@ -48,8 +64,7 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum) lua_getfield(gL, LUA_REGISTRYINDEX, "COM_Command"); // push COM_Command if (!lua_istable(gL, -1)) goto deny; - argc = READUINT8(*cp); - READSTRINGN(*cp, buf, 255); + strlcpy(buf, argv[0], 255); strlwr(buf); // must lowercase buffer lua_getfield(gL, -1, buf); // push command info table if (!lua_istable(gL, -1)) goto deny; @@ -75,10 +90,17 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum) lua_remove(gL, -2); // pop command info table + if (!lua_checkstack(gL, argc)) // player + command arguments + { + clear_lua_stack(); + CONS_Alert(CONS_WARNING, "lua command stack overflow from %s (%d, need %d more)\n", player_names[playernum], lua_gettop(gL), argc); + return; + } + LUA_PushUserdata(gL, &players[playernum], META_PLAYER); for (i = 1; i < argc; i++) { - READSTRINGN(*cp, buf, 255); + strlcpy(buf, argv[i], 255); lua_pushstring(gL, buf); } LUA_Call(gL, (int)argc, 0, 1); // argc is 1-based, so this will cover the player we passed too. @@ -86,8 +108,7 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum) deny: //must be hacked/buggy client - if (gL) // check if Lua is actually turned on first, you dummmy -- Monster Iestyn 04/07/18 - lua_settop(gL, 0); // clear stack + clear_lua_stack(); CONS_Alert(CONS_WARNING, M_GetText("Illegal lua command received from %s\n"), player_names[playernum]); if (server) @@ -173,6 +194,11 @@ void COM_Lua_f(void) I_Assert(lua_isfunction(gL, -1)); lua_remove(gL, -2); // pop command info table + if (!lua_checkstack(gL, COM_Argc() + 1)) + { + CONS_Alert(CONS_WARNING, "lua command stack overflow (%d, need %s more)\n", lua_gettop(gL), sizeu1(COM_Argc() + 1)); + return; + } LUA_PushUserdata(gL, &players[playernum], META_PLAYER); for (i = 1; i < COM_Argc(); i++) lua_pushstring(gL, COM_Argv(i)); diff --git a/src/lua_hook.h b/src/lua_hook.h index 90a11d05d66dbf89a6fabd30123b63aae965235f..ce79cd1cb70a2e81f9d531ed15094e7cf42b1e75 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -72,6 +72,7 @@ automatically. X (MusicChange),\ X (PlayerHeight),/* override player height */\ X (PlayerCanEnterSpinGaps),\ + X (AddonLoaded),\ X (KeyDown),\ X (KeyUp),\ diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index a1fe6f1b9c552ae7e19be9e85d5ba2104820d461..dea2c890a14534ab8cad19662d93bfb3fd5e3553 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -613,6 +613,10 @@ static int libd_getSprite2Patch(lua_State *L) if (super) j |= SPR2F_SUPER; + // If there is no "super" variation of this sprite, try with the normal one. + if (!P_IsValidSprite2(skins[i], j)) + j &= ~SPR2F_SUPER; + sprdef = P_GetSkinSpritedef(skins[i], j); // set frame number diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 6bb3b5493a276a50f73a2297663d9a287cf8bbc7..b1793545879b712ceb1c4510d2e3da62d9b9e64a 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -198,12 +198,12 @@ static int mobj_get(lua_State *L) enum mobj_e field = Lua_optoption(L, 2, -1, mobj_fields_ref); lua_settop(L, 2); - if (!mo || !ISINLEVEL) { + if (P_MobjWasRemoved(mo) || !ISINLEVEL) { if (field == mobj_valid) { lua_pushboolean(L, 0); return 1; } - if (!mo) { + if (P_MobjWasRemoved(mo)) { return LUA_ErrInvalid(L, "mobj_t"); } else return luaL_error(L, "Do not access an mobj_t field outside a level!"); diff --git a/src/lua_script.c b/src/lua_script.c index 3ed63781cde0e5c68348ce32cad3c2ead2d71255..dcf431282aa80207b9f0ad242ace0c602a12fd73 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -1779,7 +1779,7 @@ void LUA_Archive(save_t *save_p) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; // archive function will determine when to skip mobjs, @@ -1817,7 +1817,7 @@ void LUA_UnArchive(save_t *save_p) mobjnum = P_ReadUINT32(save_p); // read a mobjnum for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; if (((mobj_t *)th)->mobjnum != mobjnum) // find matching mobj continue; diff --git a/src/m_cheat.c b/src/m_cheat.c index e86296390098a4b51012cc0330bc81e097206e97..ea0029cf8ac0fa1c2e281eb9fd07952d9244e8c9 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -562,7 +562,7 @@ void Command_Teleport_f(void) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -1072,7 +1072,7 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo = (mobj_t *)th; diff --git a/src/m_menu.c b/src/m_menu.c index e64485f0d1f76503aa9bb333ff6c3dfc11136ed0..d9b11513b33166a1e81529a7ae9582a714613d88 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3,7 +3,7 @@ // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 2011-2016 by Matthew "Kaito Sinclaire" Walsh. -// Copyright (C) 1999-2024 by Sonic Team Junior. +// Copyright (C) 1999-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -3318,7 +3318,7 @@ boolean M_Responder(event_t *ev) if (ch == -1) return false; - else if (ch == gamecontrol[GC_SYSTEMMENU][0] || ch == gamecontrol[GC_SYSTEMMENU][1]) // allow remappable ESC key + else if (ev->type != ev_text && (ch == gamecontrol[GC_SYSTEMMENU][0] || ch == gamecontrol[GC_SYSTEMMENU][1])) // allow remappable ESC key ch = KEY_ESCAPE; // F-Keys @@ -3399,9 +3399,16 @@ boolean M_Responder(event_t *ev) // Handle menuitems which need a specific key handling if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_KEYHANDLER) { + // block text input if ctrl is held, to allow using ctrl+c ctrl+v and ctrl+x + if (ctrldown) + { + routine(ch); + return true; + } + // ignore ev_keydown events if the key maps to a character, since // the ev_text event will follow immediately after in that case. - if (ev->type == ev_keydown && ch >= 32 && ch <= 127) + if (ev->type == ev_keydown && ((ch >= 32 && ch <= 127) || (ch >= KEY_KEYPAD7 && ch <= KEY_KPADDEL))) return true; routine(ch); @@ -3429,7 +3436,7 @@ boolean M_Responder(event_t *ev) { // dirty hack: for customising controls, I want only buttons/keys, not moves if (ev->type == ev_mouse || ev->type == ev_mouse2 || ev->type == ev_joystick - || ev->type == ev_joystick2) + || ev->type == ev_joystick2 || ev->type == ev_text) return true; if (routine) { @@ -8511,6 +8518,7 @@ static void M_StartTutorial(INT32 choice) gamecomplete = 0; cursaveslot = 0; maplistoption = 0; + CV_StealthSet(&cv_skin, DEFAULTSKIN); // tutorial accounts for sonic only G_DeferedInitNew(false, G_BuildMapName(tutorialmap), 0, false, false); } @@ -11775,10 +11783,10 @@ static void M_ChooseRoom(INT32 choice) #endif if (choice == 0) - ms_RoomId = -1; + CV_SetValue(&cv_masterserver_room_id, 0); else { - ms_RoomId = roomIds[choice-1]; + CV_SetValue(&cv_masterserver_room_id, roomIds[choice-1]); menuRoomIndex = choice - 1; } @@ -12115,8 +12123,7 @@ static void M_HandleConnectIP(INT32 choice) if ( ctrldown ) { switch (choice) { - case 'v': - case 'V': // ctrl+v, pasting + case 'v': // ctrl+v, pasting { const char *paste = I_ClipboardPaste(); @@ -12129,8 +12136,7 @@ static void M_HandleConnectIP(INT32 choice) break; } case KEY_INS: - case 'c': - case 'C': // ctrl+c, ctrl+insert, copying + case 'c': // ctrl+c, ctrl+insert, copying if (l != 0) // Don't replace the clipboard without any text { I_ClipboardCopy(setupm_ip, l); @@ -12138,8 +12144,7 @@ static void M_HandleConnectIP(INT32 choice) } break; - case 'x': - case 'X': // ctrl+x, cutting + case 'x': // ctrl+x, cutting if (l != 0) // Don't replace the clipboard without any text { I_ClipboardCopy(setupm_ip, l); @@ -12195,15 +12200,6 @@ static void M_HandleConnectIP(INT32 choice) setupm_ip[l] = (char)choice; setupm_ip[l+1] = 0; } - else if (choice >= 199 && choice <= 211 && choice != 202 && choice != 206) //numpad too! - { - 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; - } - break; } @@ -14421,6 +14417,33 @@ static INT32 quitsounds[] = sfx_chchng // Tails 11-09-99 }; +const char *QuitScreenMessages[3] = { + ( + "Design and content in\n" + "SRB2 is copyright\n" + "1998-2025 by STJr. All\n" + "original material in\n" + "this game is copyrighted\n" + "by their respective\n" + "owners, and no copyright\n" + "infringement is\n" + "intended. STJr's staff\n" + "make no profit\n" + "whatsoever (in\n" + "fact, we lose\n" + "money)." + ), + + ( + "THIS GAME SHOULD NOT BE SOLD!" + ), + + ( + "STJr is in no way affiliated\n" + "with SEGA or Sonic Team." + ) +}; + void M_QuitResponse(INT32 ch) { tic_t ptime; @@ -14442,6 +14465,9 @@ void M_QuitResponse(INT32 ch) while (ptime > I_GetTime()) { V_DrawScaledPatch(0, 0, 0, W_CachePatchName("GAMEQUIT", PU_PATCH)); // Demo 3 Quit Screen Tails 06-16-2001 + V_DrawCenteredString(2+(V_StringWidth(QuitScreenMessages[0], V_ALLOWLOWERCASE)/2), 4, V_ALLOWLOWERCASE, QuitScreenMessages[0]); + V_DrawCenteredString(160, 166, V_ALLOWLOWERCASE|V_REDMAP, QuitScreenMessages[1]); + V_DrawCenteredString(160, 176, V_ALLOWLOWERCASE, QuitScreenMessages[2]); I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001 I_Sleep(cv_sleep.value); I_UpdateTime(cv_timescale.value); diff --git a/src/m_perfstats.c b/src/m_perfstats.c index b9948bdc0c3284a3473e7e6e8b95b2e3bd8fb568..33a774acfbb4ca9781ff62a177b93f9bffca28f8 100644 --- a/src/m_perfstats.c +++ b/src/m_perfstats.c @@ -453,7 +453,7 @@ static int PS_DrawPerfRows(int x, int y, int color, perfstatrow_t *rows) return draw_y; } -static void PS_UpdateMetricHistory(ps_metric_t *metric, boolean time_metric, boolean frame_metric, boolean set_user) +static void PS_UpdateMetricHistory(ps_metric_t *metric, boolean time_metric, boolean frame_metric) { int index = frame_metric ? ps_frame_index : ps_tick_index; @@ -461,7 +461,7 @@ static void PS_UpdateMetricHistory(ps_metric_t *metric, boolean time_metric, boo { // allocate history table int value_size = time_metric ? sizeof(precise_t) : sizeof(INT32); - void** memory_user = set_user ? &metric->history : NULL; + void** memory_user = &metric->history; metric->history = Z_Calloc(value_size * cv_ps_samplesize.value, PU_PERFSTATS, memory_user); @@ -491,7 +491,7 @@ static void PS_UpdateRowHistories(perfstatrow_t *rows, boolean frame_metric) for (row = rows; row->lores_label; row++) { if (PS_IsRowValid(row)) - PS_UpdateMetricHistory(row->metric, !!(row->flags & PS_TIME), frame_metric, true); + PS_UpdateMetricHistory(row->metric, !!(row->flags & PS_TIME), frame_metric); } } @@ -584,7 +584,7 @@ static void PS_CountThinkers(void) for (thinker = thlist[i].next; thinker != &thlist[i]; thinker = thinker->next) { ps_thinkercount.value.i++; - if (thinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (thinker->removing) ps_removecount.value.i++; else if (i == THINK_POLYOBJ) ps_polythcount.value.i++; @@ -649,17 +649,17 @@ void PS_UpdateTickStats(void) if (cv_perfstats.value == 3) { for (i = 0; i < thinkframe_hooks_length; i++) - PS_UpdateMetricHistory(&thinkframe_hooks[i].time_taken, true, false, false); + PS_UpdateMetricHistory(&thinkframe_hooks[i].time_taken, true, false); } else if (cv_perfstats.value == 4) { for (i = 0; i < prethinkframe_hooks_length; i++) - PS_UpdateMetricHistory(&prethinkframe_hooks[i].time_taken, true, false, false); + PS_UpdateMetricHistory(&prethinkframe_hooks[i].time_taken, true, false); } else if (cv_perfstats.value == 5) { for (i = 0; i < postthinkframe_hooks_length; i++) - PS_UpdateMetricHistory(&postthinkframe_hooks[i].time_taken, true, false, false); + PS_UpdateMetricHistory(&postthinkframe_hooks[i].time_taken, true, false); } } if (cv_perfstats.value) diff --git a/src/netcode/client_connection.c b/src/netcode/client_connection.c index 917e32b598e03d86f8540b997329069f279817fb..c740d53a6a3845539bfe0637771e78827ae8b055 100644 --- a/src/netcode/client_connection.c +++ b/src/netcode/client_connection.c @@ -546,6 +546,7 @@ static void AbortConnection(void) { Snake_Free(&snake); + CURLAbortFile(); D_QuitNetGame(); CL_Reset(); D_StartTitle(); @@ -1062,10 +1063,6 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic } } - // Rusty TODO: multithread - if (filedownload.http_running) - CURLGetFile(); - if (waitmore) break; // exit the case diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index ff2c9143c3cd204597ee7adc11e560e27947201d..1a7d8d39b068f46966bd44e953288d7fb992a334 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -113,9 +113,11 @@ consvar_t cv_blamecfail = CVAR_INIT ("blamecfail", "Off", CV_SAVE|CV_NETVAR, CV_ static CV_PossibleValue_t playbackspeed_cons_t[] = {{1, "MIN"}, {10, "MAX"}, {0, NULL}}; consvar_t cv_playbackspeed = CVAR_INIT ("playbackspeed", "1", 0, playbackspeed_cons_t, NULL); -consvar_t cv_idletime = CVAR_INIT ("idletime", "0", CV_SAVE, CV_Unsigned, NULL); -consvar_t cv_idlespectate = CVAR_INIT ("idlespectate", "On", CV_SAVE, CV_OnOff, NULL); -consvar_t cv_dedicatedidletime = CVAR_INIT ("dedicatedidletime", "10", CV_SAVE, CV_Unsigned, NULL); +consvar_t cv_dedicatedidletime = CVAR_INIT ("dedicatedidletime", "10", CV_SAVE|CV_NETVAR, CV_Unsigned, NULL); + +static CV_PossibleValue_t idleaction_cons_t[] = {{1, "Kick"}, {2, "Spectate"}, {0, NULL}}; +consvar_t cv_idleaction = CVAR_INIT ("idleaction", "Spectate", CV_SAVE|CV_NETVAR, idleaction_cons_t, NULL); +consvar_t cv_idletime = CVAR_INIT ("idletime", "3", CV_SAVE|CV_NETVAR, CV_Unsigned, NULL); consvar_t cv_httpsource = CVAR_INIT ("http_source", "", CV_SAVE, NULL, NULL); @@ -1373,7 +1375,7 @@ static void IdleUpdate(void) if (cv_idletime.value && !IsPlayerAdmin(i) && i != serverplayer && !(players[i].pflags & PF_FINISHED) && players[i].lastinputtime > (tic_t)cv_idletime.value * TICRATE * 60) { players[i].lastinputtime = 0; - if (cv_idlespectate.value && G_GametypeHasSpectators()) + if (cv_idleaction.value == 2 && G_GametypeHasSpectators()) { changeteam_union NetPacket; UINT16 usvalue; @@ -1384,7 +1386,7 @@ static void IdleUpdate(void) usvalue = SHORT(NetPacket.value.l|NetPacket.value.b); SendNetXCmd(XD_TEAMCHANGE, &usvalue, sizeof(usvalue)); } - else + else if (cv_idleaction.value == 1) { SendKick(i, KICK_MSG_IDLE | KICK_MSG_KEEP_BODY); } @@ -1814,7 +1816,7 @@ INT16 Consistancy(void) { for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo = (mobj_t *)th; diff --git a/src/netcode/d_clisrv.h b/src/netcode/d_clisrv.h index 342173dff5bf575a762433a4cb2ad753a61685a0..86af61e9e02eb9528b759ce635970a96e3a28ee4 100644 --- a/src/netcode/d_clisrv.h +++ b/src/netcode/d_clisrv.h @@ -73,7 +73,7 @@ extern UINT32 realpingtable[MAXPLAYERS]; extern UINT32 playerpingtable[MAXPLAYERS]; extern tic_t servermaxping; -extern consvar_t cv_netticbuffer, cv_resynchattempts, cv_blamecfail, cv_playbackspeed, cv_idletime, cv_idlespectate, cv_dedicatedidletime; +extern consvar_t cv_netticbuffer, cv_resynchattempts, cv_blamecfail, cv_playbackspeed, cv_idletime, cv_idleaction, cv_dedicatedidletime; extern consvar_t cv_httpsource; // Used in d_net, the only dependence diff --git a/src/netcode/d_net.c b/src/netcode/d_net.c index 99859ea4c0c9c05e3058b0bf8fcb6a9953d10c0b..4860d8688b4a8b998b59523c6cf52502c69d10ca 100644 --- a/src/netcode/d_net.c +++ b/src/netcode/d_net.c @@ -1143,7 +1143,7 @@ static void Internal_FreeNodenum(INT32 nodenum) char *I_NetSplitAddress(char *host, char **port) { - boolean v4 = (strchr(host, '.') != NULL); + boolean v4 = (host[0] != '['); host = strtok(host, v4 ? ":" : "[]"); diff --git a/src/netcode/d_netcmd.c b/src/netcode/d_netcmd.c index 206fa18b75a899d6a934e74307b655c5131d73e1..79f5140d16cffd4eb4cd108a324e4a7a22a4e41f 100644 --- a/src/netcode/d_netcmd.c +++ b/src/netcode/d_netcmd.c @@ -391,7 +391,7 @@ static CV_PossibleValue_t perfstats_cons_t[] = { consvar_t cv_perfstats = CVAR_INIT ("perfstats", "Off", CV_CALL, perfstats_cons_t, PS_PerfStats_OnChange); static CV_PossibleValue_t ps_samplesize_cons_t[] = { {1, "MIN"}, {1000, "MAX"}, {0, NULL}}; -consvar_t cv_ps_samplesize = CVAR_INIT ("ps_samplesize", "1", CV_CALL, ps_samplesize_cons_t, PS_SampleSize_OnChange); +consvar_t cv_ps_samplesize = CVAR_INIT ("ps_samplesize", "175", CV_CALL, ps_samplesize_cons_t, PS_SampleSize_OnChange); static CV_PossibleValue_t ps_descriptor_cons_t[] = { {1, "Average"}, {2, "SD"}, {3, "Minimum"}, {4, "Maximum"}, {0, NULL}}; consvar_t cv_ps_descriptor = CVAR_INIT ("ps_descriptor", "Average", 0, ps_descriptor_cons_t, NULL); @@ -620,7 +620,7 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_blamecfail); CV_RegisterVar(&cv_dedicatedidletime); CV_RegisterVar(&cv_idletime); - CV_RegisterVar(&cv_idlespectate); + CV_RegisterVar(&cv_idleaction); CV_RegisterVar(&cv_httpsource); COM_AddCommand("ping", Command_Ping_f, COM_LUA); @@ -4910,11 +4910,13 @@ static void Name2_OnChange(void) static boolean Skin_CanChange(const char *valstr) { - (void)valstr; - if (!Playing()) return true; // do whatever you want + // You already are that skin. + if (stricmp(skins[players[consoleplayer].skin]->name, valstr) == 0) + return false; + if (!(multiplayer || netgame)) // In single player. return true; @@ -4929,11 +4931,13 @@ static boolean Skin_CanChange(const char *valstr) static boolean Skin2_CanChange(const char *valstr) { - (void)valstr; - if (!Playing() || !splitscreen) return true; // do whatever you want + // You already are that skin. + if (stricmp(skins[players[secondarydisplayplayer].skin]->name, valstr) == 0) + return false; + if (CanChangeSkin(secondarydisplayplayer) && !P_PlayerMoving(secondarydisplayplayer)) return true; else diff --git a/src/netcode/d_netfil.c b/src/netcode/d_netfil.c index adec1a0e47ecd4a2996a7edcf0016eb9c4529936..bfb67838ff68e3831914e77dd029ffa19942eaac 100644 --- a/src/netcode/d_netfil.c +++ b/src/netcode/d_netfil.c @@ -95,6 +95,7 @@ static filetran_t transfer[MAXNETNODES]; INT32 fileneedednum; // Number of files needed to join the server fileneeded_t *fileneeded; // List of needed files static tic_t lasttimeackpacketsent = 0; +static I_mutex downloadmutex; char downloaddir[512] = "DOWNLOAD"; // For resuming failed downloads @@ -606,7 +607,7 @@ void AddLuaFileTransfer(const char *filename, const char *mode) prevnext = &((*prevnext)->next); // Allocate file transfer information and append it to the transfer list - filetransfer = malloc(sizeof(luafiletransfer_t)); + filetransfer = calloc(1, sizeof(luafiletransfer_t)); if (!filetransfer) I_Error("AddLuaFileTransfer: Out of memory\n"); *prevnext = filetransfer; @@ -1344,9 +1345,9 @@ void PT_FileFragment(SINT8 node, INT32 netconsole) if (!(strcmp(filename, "srb2.pk3") && strcmp(filename, "zones.pk3") - && strcmp(filename, "player.dta") + && strcmp(filename, "characters.pk3") && strcmp(filename, "patch.pk3") - && strcmp(filename, "music.dta") + && strcmp(filename, "music.pk3") )) I_Error("Tried to download \"%s\"", filename); @@ -1609,11 +1610,13 @@ boolean CURLPrepareFile(const char* url, int dfilenum) I_Error("Attempted to download files in -nodownload mode"); #endif - curl_global_init(CURL_GLOBAL_ALL); + if (!multi_handle) + { + curl_global_init(CURL_GLOBAL_ALL); + multi_handle = curl_multi_init(); + } http_handle = curl_easy_init(); - multi_handle = curl_multi_init(); - if (http_handle && multi_handle) { I_mkdir(downloaddir, 0755); @@ -1672,6 +1675,8 @@ boolean CURLPrepareFile(const char* url, int dfilenum) filedownload.current = dfilenum; filedownload.http_running = true; + I_spawn_thread("http-download", (I_thread_fn)CURLGetFile, NULL); + return true; } @@ -1680,103 +1685,119 @@ boolean CURLPrepareFile(const char* url, int dfilenum) return false; } +void CURLAbortFile(void) +{ + filedownload.http_running = false; + + // lock and unlock to wait for the download thread to exit + I_lock_mutex(&downloadmutex); + I_unlock_mutex(downloadmutex); +} + void CURLGetFile(void) { + I_lock_mutex(&downloadmutex); CURLMcode mc; /* return code used by curl_multi_wait() */ CURLcode easyres; /* Return from easy interface */ - int numfds; CURLMsg *m; /* for picking up messages with the transfer status */ CURL *e; int msgs_left; /* how many messages are left */ const char *easy_handle_error; + boolean running = true; - if (curl_runninghandles) + while (running && filedownload.http_running) { - curl_multi_perform(multi_handle, &curl_runninghandles); + if (curl_runninghandles) + { + curl_multi_perform(multi_handle, &curl_runninghandles); - /* wait for activity, timeout or "nothing" */ - mc = curl_multi_wait(multi_handle, NULL, 0, 1000, &numfds); + /* wait for activity, timeout or "nothing" */ + mc = curl_multi_wait(multi_handle, NULL, 0, 1000, NULL); - if (mc != CURLM_OK) - { - CONS_Alert(CONS_WARNING, "curl_multi_wait() failed, code %d.\n", mc); - return; + if (mc != CURLM_OK) + { + CONS_Alert(CONS_WARNING, "curl_multi_wait() failed, code %d.\n", mc); + continue; + } + curl_curfile->currentsize = curl_dlnow; + curl_curfile->totalsize = curl_dltotal; } - curl_curfile->currentsize = curl_dlnow; - curl_curfile->totalsize = curl_dltotal; - } - /* See how the transfers went */ - while ((m = curl_multi_info_read(multi_handle, &msgs_left))) - { - if (m && (m->msg == CURLMSG_DONE)) + /* See how the transfers went */ + while ((m = curl_multi_info_read(multi_handle, &msgs_left))) { - e = m->easy_handle; - easyres = m->data.result; - - char *filename = Z_StrDup(curl_realname); - nameonly(filename); - - if (easyres != CURLE_OK) + if (m && (m->msg == CURLMSG_DONE)) { - long response_code = 0; + running = false; + e = m->easy_handle; + easyres = m->data.result; - if (easyres == CURLE_HTTP_RETURNED_ERROR) - curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, &response_code); + char *filename = Z_StrDup(curl_realname); + nameonly(filename); - if (response_code == 404) - curl_curfile->failed = FDOWNLOAD_FAIL_NOTFOUND; - else - curl_curfile->failed = FDOWNLOAD_FAIL_OTHER; - - easy_handle_error = (response_code) ? va("HTTP response code %ld", response_code) : curl_easy_strerror(easyres); - curl_curfile->status = FS_FALLBACK; - curl_curfile->currentsize = curl_origfilesize; - curl_curfile->totalsize = curl_origtotalfilesize; - filedownload.http_failed = true; - fclose(curl_curfile->file); - remove(curl_curfile->filename); - CONS_Alert(CONS_ERROR, M_GetText("Failed to download addon \"%s\" (%s)\n"), filename, easy_handle_error); - } - else - { - fclose(curl_curfile->file); + if (easyres != CURLE_OK) + { + long response_code = 0; - CONS_Printf(M_GetText("Finished download of \"%s\"\n"), filename); + if (easyres == CURLE_HTTP_RETURNED_ERROR) + curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, &response_code); - if (checkfilemd5(curl_curfile->filename, curl_curfile->md5sum) == FS_MD5SUMBAD) - { - CONS_Alert(CONS_WARNING, M_GetText("File \"%s\" does not match the version used by the server\n"), filename); + if (response_code == 404) + curl_curfile->failed = FDOWNLOAD_FAIL_NOTFOUND; + else + curl_curfile->failed = FDOWNLOAD_FAIL_OTHER; + + easy_handle_error = (response_code) ? va("HTTP response code %ld", response_code) : curl_easy_strerror(easyres); curl_curfile->status = FS_FALLBACK; - curl_curfile->failed = FDOWNLOAD_FAIL_MD5SUMBAD; + curl_curfile->currentsize = curl_origfilesize; + curl_curfile->totalsize = curl_origtotalfilesize; filedownload.http_failed = true; + fclose(curl_curfile->file); + remove(curl_curfile->filename); + CONS_Alert(CONS_ERROR, M_GetText("Failed to download addon \"%s\" (%s)\n"), filename, easy_handle_error); } else { - filedownload.completednum++; - filedownload.completedsize += curl_curfile->totalsize; - curl_curfile->status = FS_FOUND; + fclose(curl_curfile->file); + + CONS_Printf(M_GetText("Finished download of \"%s\"\n"), filename); + + if (checkfilemd5(curl_curfile->filename, curl_curfile->md5sum) == FS_MD5SUMBAD) + { + CONS_Alert(CONS_WARNING, M_GetText("File \"%s\" does not match the version used by the server\n"), filename); + curl_curfile->status = FS_FALLBACK; + curl_curfile->failed = FDOWNLOAD_FAIL_MD5SUMBAD; + filedownload.http_failed = true; + } + else + { + filedownload.completednum++; + filedownload.completedsize += curl_curfile->totalsize; + curl_curfile->status = FS_FOUND; + } } - } - Z_Free(filename); + Z_Free(filename); - curl_curfile->file = NULL; - filedownload.http_running = false; - filedownload.remaining--; - curl_multi_remove_handle(multi_handle, e); - curl_easy_cleanup(e); + curl_curfile->file = NULL; + filedownload.remaining--; + curl_multi_remove_handle(multi_handle, e); + curl_easy_cleanup(e); - if (!filedownload.remaining) - break; + if (!filedownload.remaining) + break; + } } } - if (!filedownload.remaining) + if (!filedownload.remaining || !filedownload.http_running) { curl_multi_cleanup(multi_handle); curl_global_cleanup(); + multi_handle = NULL; } + filedownload.http_running = false; + I_unlock_mutex(downloadmutex); } HTTP_login * diff --git a/src/netcode/d_netfil.h b/src/netcode/d_netfil.h index 4039b5e2d5cc4b0d81fbdc04e6d7c7bef46f724a..9f29d18bb79ff39dda69fffd68e2756f8d4f0db9 100644 --- a/src/netcode/d_netfil.h +++ b/src/netcode/d_netfil.h @@ -140,6 +140,7 @@ boolean CL_SendFileRequest(void); void PT_RequestFile(SINT8 node); boolean CURLPrepareFile(const char* url, int dfilenum); +void CURLAbortFile(void); void CURLGetFile(void); HTTP_login * CURLGetLogin (const char *url, HTTP_login ***return_prev_next); diff --git a/src/netcode/i_tcp.c b/src/netcode/i_tcp.c index 4c3d58ee2d406f9c29f5659e07fc45c3de7cb515..256d9992eff6acdd614ac9bf99428e459884fe2a 100644 --- a/src/netcode/i_tcp.c +++ b/src/netcode/i_tcp.c @@ -1152,11 +1152,7 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port) // test ip address of server for (i = 0; i < mysocketses; ++i) { - /* sendto tests that there is a network to this - address */ - if (runp->ai_addr->sa_family == myfamily[i] && - sendto(mysockets[i], NULL, 0, 0, - runp->ai_addr, runp->ai_addrlen) == 0) + if (runp->ai_addr->sa_family == myfamily[i]) { memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen); break; diff --git a/src/netcode/mserv.c b/src/netcode/mserv.c index 78a395344994e2c3ba9552649e414fd7d07d839f..fba36a3babddc507dd9d3c7601682ac50baa7a45 100644 --- a/src/netcode/mserv.c +++ b/src/netcode/mserv.c @@ -55,6 +55,7 @@ static boolean ServerName_CanChange (const char*); static void Update_parameters (void); static void MasterServer_OnChange(void); +static void RoomId_OnChange(void); static CV_PossibleValue_t masterserver_update_rate_cons_t[] = { {2, "MIN"}, @@ -66,8 +67,9 @@ consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://ds.ms.srb2.org/M consvar_t cv_servername = CVAR_INIT_WITH_CALLBACKS ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Update_parameters, ServerName_CanChange); consvar_t cv_masterserver_update_rate = CVAR_INIT ("masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, Update_parameters); +consvar_t cv_masterserver_room_id = CVAR_INIT ("masterserver_room_id", "0", CV_CALL, CV_Unsigned, RoomId_OnChange); -INT16 ms_RoomId = -1; +INT16 ms_RoomId = 0; #if defined (MASTERSERVER) && defined (HAVE_THREADS) int ms_QueryId; @@ -92,6 +94,7 @@ void AddMServCommands(void) { CV_RegisterVar(&cv_masterserver); CV_RegisterVar(&cv_masterserver_update_rate); + CV_RegisterVar(&cv_masterserver_room_id); CV_RegisterVar(&cv_masterserver_timeout); CV_RegisterVar(&cv_masterserver_debug); CV_RegisterVar(&cv_masterserver_token); @@ -534,6 +537,17 @@ Update_parameters (void) #endif/*MASTERSERVER*/ } +static void RoomId_OnChange(void) +{ + if (ms_RoomId != cv_masterserver_room_id.value) + { + UnregisterServer(); + ms_RoomId = cv_masterserver_room_id.value; + if (Online()) + RegisterServer(); + } +} + static void MasterServer_OnChange(void) { #ifdef MASTERSERVER diff --git a/src/netcode/mserv.h b/src/netcode/mserv.h index 0bc8c8e6b878a415887e2a9613188d3ceac30956..419c11a89409d7491249d159f669285c344fdee5 100644 --- a/src/netcode/mserv.h +++ b/src/netcode/mserv.h @@ -66,6 +66,7 @@ typedef struct extern consvar_t cv_masterserver, cv_servername; extern consvar_t cv_masterserver_update_rate; +extern consvar_t cv_masterserver_room_id; extern consvar_t cv_masterserver_timeout; extern consvar_t cv_masterserver_debug; extern consvar_t cv_masterserver_token; diff --git a/src/p_enemy.c b/src/p_enemy.c index 7fc77dba21a9e8912fe4c9b0b61c128682783819..26ae8a0cf483c6e7c09383e0db17abca025db7e0 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3744,7 +3744,7 @@ static void P_DoBossVictory(mobj_t *mo) // scan the remaining thinkers to see if all bosses are dead for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -6449,7 +6449,7 @@ void A_RingExplode(mobj_t *actor) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -7837,13 +7837,14 @@ void A_BuzzFly(mobj_t *actor) // Function: A_GuardChase // -// Description: Modified A_Chase for Egg Guard +// Description: Modified A_Chase for Egg Guard and Koopa Troopas // -// var1 = unused +// var1 = shield (0) or no shield (1) // var2 = unused // void A_GuardChase(mobj_t *actor) { + INT32 locvar1 = var1; INT32 delta; if (LUA_CallAction(A_GUARDCHASE, actor)) @@ -7852,11 +7853,11 @@ void A_GuardChase(mobj_t *actor) if (actor->reactiontime) actor->reactiontime--; - if (actor->threshold != 42) // In formation... + if (actor->threshold != 42 || locvar1 == 1) // In formation... { fixed_t speed; - if (!actor->tracer || !actor->tracer->health) + if ((!actor->tracer || !actor->tracer->health) && locvar1 == 0) { P_SetTarget(&actor->tracer, NULL); actor->threshold = 42; @@ -7945,7 +7946,7 @@ void A_GuardChase(mobj_t *actor) // Now that we've moved, its time for our shield to move! // Otherwise it'll never act as a proper overlay. if (actor->tracer && actor->tracer->state - && actor->tracer->state->action.acp1) + && actor->tracer->state->action.acp1 && locvar1 == 0) { var1 = actor->tracer->state->var1, var2 = actor->tracer->state->var2; actor->tracer->state->action.acp1(actor->tracer); @@ -8756,7 +8757,7 @@ void A_FindTarget(mobj_t *actor) // scan the thinkers for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -8820,7 +8821,7 @@ void A_FindTracer(mobj_t *actor) // scan the thinkers for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -9498,7 +9499,7 @@ void A_RemoteAction(mobj_t *actor) // scan the thinkers for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -9761,7 +9762,7 @@ void A_SetObjectTypeState(mobj_t *actor) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -10391,7 +10392,7 @@ void A_CheckThingCount(mobj_t *actor) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -14395,7 +14396,7 @@ void A_LavafallLava(mobj_t *actor) if (LUA_CallAction(A_LAVAFALLLAVA, actor)) return; - if ((40 - actor->fuse) % (2*(actor->scale >> FRACBITS))) + if ((40 - actor->fuse) % max(2*(actor->scale >> FRACBITS), 1)) // avoid crashes if actor->scale < FRACUNIT return; // Don't spawn lava unless a player is nearby. diff --git a/src/p_inter.c b/src/p_inter.c index 81ba6e0ed20a78a932c30a074d56f96f257ca5cb..97b88531e698fee128996713c39124f0cf66aed8 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -101,7 +101,7 @@ void P_ClearStarPost(INT32 postnum) // scan the thinkers for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -130,7 +130,7 @@ void P_ResetStarposts(void) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; post = (mobj_t *)th; @@ -1003,7 +1003,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // scan the thinkers to find the corresponding anchorpoint for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -1097,7 +1097,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // scan the remaining thinkers for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -1147,7 +1147,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // in from the paraloop. Isn't this just so efficient? for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -1522,7 +1522,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // scan the remaining thinkers to find koopa for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -2020,7 +2020,7 @@ void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -2870,7 +2870,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget // scan the thinkers to make sure all the old pinch dummies are gone on death for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo = (mobj_t *)th; diff --git a/src/p_local.h b/src/p_local.h index 39856bffbcc5d7d04272afdb143974af18b95d80..de519b211b8d664ddba9305f6a6c5a2eb03ed159 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -39,11 +39,6 @@ // Convenience macro to fix issue with collision along bottom/left edges of blockmap -Red #define BMBOUNDFIX(xl, xh, yl, yh) {if (xl > xh) xl = 0; if (yl > yh) yl = 0;} -// MAXRADIUS is for precalculated sector block boxes -// the spider demon is larger, -// but we do not have any moving sectors nearby -#define MAXRADIUS (32*FRACUNIT) - // max Z move up or down without jumping // above this, a height difference is considered as a 'dropoff' #define MAXSTEPMOVE (24*FRACUNIT) @@ -203,7 +198,7 @@ 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_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius); boolean P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user -boolean P_SuperReady(player_t *player, boolean transform); +boolean P_SuperReady(player_t *player); void P_DoJump(player_t *player, boolean soundandstate, boolean allowflip); void P_DoSpinDashDust(player_t *player); #define P_AnalogMove(player) (P_ControlStyle(player) == CS_LMAOGALOG) diff --git a/src/p_map.c b/src/p_map.c index 4799635fc4d52a188d9326f473fbe08d8f254c4b..99a9873da6e6b2a5d3db958162fbb12cf90d2c29 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -36,6 +36,9 @@ #include "m_perfstats.h" // ps_checkposition_calls +// Formerly called MAXRADIUS +#define MAXTRYMOVE (32*FRACUNIT) + fixed_t tmbbox[4]; mobj_t *tmthing; static INT32 tmflags; @@ -2165,15 +2168,10 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) } } - // The bounding box is extended by MAXRADIUS - // because mobj_ts are grouped into mapblocks - // based on their origin point, and can overlap - // into adjacent blocks by up to MAXRADIUS units. - - xl = (unsigned)(tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT; - xh = (unsigned)(tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT; - yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT; - yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT; + xl = (unsigned)(tmbbox[BOXLEFT] - bmaporgx)>>MAPBLOCKSHIFT; + xh = (unsigned)(tmbbox[BOXRIGHT] - bmaporgx)>>MAPBLOCKSHIFT; + yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT; + yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT; BMBOUNDFIX(xl, xh, yl, yh); @@ -2393,11 +2391,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) } } - // The bounding box is extended by MAXRADIUS - // because mobj_ts are grouped into mapblocks - // based on their origin point, and can overlap - // into adjacent blocks by up to MAXRADIUS units. - xl = (unsigned)(tmbbox[BOXLEFT] - bmaporgx)>>MAPBLOCKSHIFT; xh = (unsigned)(tmbbox[BOXRIGHT] - bmaporgx)>>MAPBLOCKSHIFT; yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT; @@ -2528,16 +2521,16 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam) } do { - if (x-tryx > MAXRADIUS) - tryx += MAXRADIUS; - else if (x-tryx < -MAXRADIUS) - tryx -= MAXRADIUS; + if (x-tryx > MAXTRYMOVE) + tryx += MAXTRYMOVE; + else if (x-tryx < -MAXTRYMOVE) + tryx -= MAXTRYMOVE; else tryx = x; - if (y-tryy > MAXRADIUS) - tryy += MAXRADIUS; - else if (y-tryy < -MAXRADIUS) - tryy -= MAXRADIUS; + if (y-tryy > MAXTRYMOVE) + tryy += MAXTRYMOVE; + else if (y-tryy < -MAXTRYMOVE) + tryy -= MAXTRYMOVE; else tryy = y; @@ -2683,7 +2676,7 @@ increment_move floatok = false; // This makes sure that there are no freezes from computing extremely small movements. - // Originally was MAXRADIUS/2, but that can cause some bad inconsistencies for small players. + // Originally was MAXTRYMOVE/2, but that can cause some bad inconsistencies for small players. radius = max(radius, thing->scale); // And we also have to prevent Big Large (tm) movements, as those can skip too far @@ -2872,10 +2865,10 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) { INT32 xl, xh, yl, yh; - yh = (unsigned)(thing->y + MAXRADIUS - bmaporgy)>>MAPBLOCKSHIFT; - yl = (unsigned)(thing->y - MAXRADIUS - bmaporgy)>>MAPBLOCKSHIFT; - xh = (unsigned)(thing->x + MAXRADIUS - bmaporgx)>>MAPBLOCKSHIFT; - xl = (unsigned)(thing->x - MAXRADIUS - bmaporgx)>>MAPBLOCKSHIFT; + yh = (unsigned)(thing->y + thing->radius - bmaporgy)>>MAPBLOCKSHIFT; + yl = (unsigned)(thing->y - thing->radius - bmaporgy)>>MAPBLOCKSHIFT; + xh = (unsigned)(thing->x + thing->radius - bmaporgx)>>MAPBLOCKSHIFT; + xl = (unsigned)(thing->x - thing->radius - bmaporgx)>>MAPBLOCKSHIFT; BMBOUNDFIX(xl, xh, yl, yh); @@ -2947,16 +2940,16 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y) tryx = thing->x; tryy = thing->y; do { - if (x-tryx > MAXRADIUS) - tryx += MAXRADIUS; - else if (x-tryx < -MAXRADIUS) - tryx -= MAXRADIUS; + if (x-tryx > MAXTRYMOVE) + tryx += MAXTRYMOVE; + else if (x-tryx < -MAXTRYMOVE) + tryx -= MAXTRYMOVE; else tryx = x; - if (y-tryy > MAXRADIUS) - tryy += MAXRADIUS; - else if (y-tryy < -MAXRADIUS) - tryy -= MAXRADIUS; + if (y-tryy > MAXTRYMOVE) + tryy += MAXTRYMOVE; + else if (y-tryy < -MAXTRYMOVE) + tryy -= MAXTRYMOVE; else tryy = y; @@ -4215,7 +4208,8 @@ void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 dama INT32 xl, xh, yl, yh; fixed_t dist; - dist = FixedMul(damagedist, spot->scale) + MAXRADIUS; + dist = FixedMul(damagedist, spot->scale); + yh = (unsigned)(spot->y + dist - bmaporgy)>>MAPBLOCKSHIFT; yl = (unsigned)(spot->y - dist - bmaporgy)>>MAPBLOCKSHIFT; xh = (unsigned)(spot->x + dist - bmaporgx)>>MAPBLOCKSHIFT; @@ -4385,15 +4379,15 @@ static boolean P_CheckSectorPolyObjects(sector_t *sector, boolean realcrush, boo { mobj_t *mo; blocknode_t *block; + blocknode_t *next = NULL; if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) continue; - block = blocklinks[y * bmapwidth + x]; - - for (; block; block = block->mnext) + for (block = blocklinks[y * bmapwidth + x]; block != NULL; block = next) { mo = block->mobj; + next = block->mnext; // Monster Iestyn: do we need to check if a mobj has already been checked? ...probably not I suspect if (!P_MobjInsidePolyobj(po, mo)) diff --git a/src/p_maputl.c b/src/p_maputl.c index f10a396a3f2d2b74946a22f90c1f13a2c3f6bfc5..5398fd7a4c584022e8f33bb49312a176207e74b8 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -1052,35 +1052,23 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *)) // boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean (*func)(mobj_t *)) { - mobj_t *bnext = NULL; blocknode_t *block, *next = NULL; if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) return true; // Check interaction with the objects in the blockmap. - for (block = blocklinks[y*bmapwidth + x]; block; block = next) + for (block = blocklinks[y*bmapwidth + x]; block != NULL; block = next) { - next = block->mnext; - if (next) - P_SetTarget(&bnext, next->mobj); // We want to note our reference to bnext here in case it is MF_NOTHINK and gets removed! + next = block->mnext; // We want to note our reference to mnext here! if (!func(block->mobj)) - { - P_SetTarget(&bnext, NULL); return false; - } - if (P_MobjWasRemoved(tmthing) // func just popped our tmthing, cannot continue. - || (bnext && P_MobjWasRemoved(bnext))) // func just broke blockmap chain, cannot continue. - { - P_SetTarget(&bnext, NULL); + if (P_MobjWasRemoved(tmthing)) // func just popped our tmthing, cannot continue. return true; - } } - P_SetTarget(&bnext, NULL); - return true; } diff --git a/src/p_mobj.c b/src/p_mobj.c index c2fa310fdf804b4cf1d44e755d1d8385dbc7327d..ed5566c8ecd000da44478cc35c87227cadbc0a61 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -90,17 +90,21 @@ static void P_SetupStateAnimation(mobj_t *mobj, state_t *st) if (mobj->sprite == SPR_PLAY && mobj->skin) { spritedef_t *spritedef = P_GetSkinSpritedef(mobj->skin, mobj->sprite2); - animlength = (INT32)(spritedef->numframes); + animlength = (INT32)(spritedef->numframes) - 1; } else animlength = st->var1; if (!(st->frame & FF_ANIMATE)) + { + mobj->anim_duration = 0; return; + } if (animlength <= 0 || st->var2 == 0) { mobj->frame &= ~FF_ANIMATE; + mobj->anim_duration = 0; return; // Crash/stupidity prevention } @@ -174,27 +178,6 @@ static void P_CycleMobjState(mobj_t *mobj) } } -// -// P_CycleMobjState for players. -// -static void P_CyclePlayerMobjState(mobj_t *mobj) -{ - // state animations - P_CycleStateAnimation(mobj); - - // 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 && mobj->state) - if (!P_SetMobjState(mobj, mobj->state->nextstate)) - return; // freed itself - } -} - // // P_SetPlayerMobjState // Returns true if the mobj is still present. @@ -792,7 +775,7 @@ void P_EmeraldManager(void) for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { - if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (think->removing) continue; mo = (mobj_t *)think; @@ -3482,7 +3465,7 @@ void P_DestroyRobots(void) for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { - if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (think->removing) continue; mo = (mobj_t *)think; @@ -3826,7 +3809,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj) } animonly: - P_CyclePlayerMobjState(mobj); + P_CycleMobjState(mobj); } static void CalculatePrecipFloor(precipmobj_t *mobj) @@ -4281,7 +4264,7 @@ static void P_Boss3Thinker(mobj_t *mobj) // this can happen if the boss was hurt earlier than expected for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -5370,7 +5353,7 @@ static void P_Boss9Thinker(mobj_t *mobj) // Build a hoop linked list of 'em! for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -6072,7 +6055,7 @@ mobj_t *P_GetClosestAxis(mobj_t *source) // scan the thinkers to find the closest axis point for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -8088,6 +8071,10 @@ static boolean P_MobjBossThink(mobj_t *mobj) case MT_METALSONIC_BATTLE: P_Boss9Thinker(mobj); break; + case MT_OLDK: + if (mobj->health <= 0) + mobj->momz -= (2*FRACUNIT)/3; + break; default: // Generic SOC-made boss if (mobj->flags2 & MF2_SKULLFLY) P_SpawnGhostMobj(mobj); @@ -9364,10 +9351,10 @@ static void P_PointPushThink(mobj_t *mobj) radius = mobj->spawnpoint->args[0] << FRACBITS; pushmobj = mobj; - xl = (unsigned)(mobj->x - radius - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT; - xh = (unsigned)(mobj->x + radius - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT; - yl = (unsigned)(mobj->y - radius - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT; - yh = (unsigned)(mobj->y + radius - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT; + xl = (unsigned)(mobj->x - radius - bmaporgx)>>MAPBLOCKSHIFT; + xh = (unsigned)(mobj->x + radius - bmaporgx)>>MAPBLOCKSHIFT; + yl = (unsigned)(mobj->y - radius - bmaporgy)>>MAPBLOCKSHIFT; + yh = (unsigned)(mobj->y + radius - bmaporgy)>>MAPBLOCKSHIFT; P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_PushThing); } @@ -10353,10 +10340,7 @@ void P_MobjThinker(mobj_t *mobj) } // Can end up here if a player dies. - if (mobj->player) - P_CyclePlayerMobjState(mobj); - else - P_CycleMobjState(mobj); + P_CycleMobjState(mobj); if (P_MobjWasRemoved(mobj)) return; @@ -11210,17 +11194,16 @@ tic_t itemrespawntime[ITEMQUESIZE]; size_t iquehead, iquetail; #ifdef PARANOIA -#define SCRAMBLE_REMOVED // Force debug build to crash when Removed mobj is accessed +#define SCRAMBLE_REMOVED // Force debug build to crash when a removed mobj is accessed #endif void P_RemoveMobj(mobj_t *mobj) { I_Assert(mobj != NULL); - if (P_MobjWasRemoved(mobj)) - return; // something already removing this mobj. + if (P_MobjWasRemoved(mobj) || mobj->thinker.removing) + return; // Something already removed or is removing this mobj. - mobj->thinker.function.acp1 = (actionf_p1)P_RemoveThinkerDelayed; // shh. no recursing. + mobj->thinker.removing = true; // Set earlier to avoid recursion. LUA_HookMobj(mobj, MOBJ_HOOK(MobjRemoved)); - mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker; // needed for P_UnsetThingPosition, etc. to work. // Rings only, please! if (mobj->spawnpoint && @@ -12890,7 +12873,7 @@ static boolean P_MapAlreadyHasStarPost(mobj_t *mobj) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -13177,6 +13160,32 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean banner->angle = mobjangle + ANGLE_90; } break; + case MT_SSZTREE: + { // Spawn the branches + INT32 i; + mobj_t *branch; + for (i = 0; i < 5; i++) + { + branch = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_SSZTREE_BRANCH); + if (P_MobjWasRemoved(branch)) + continue; + branch->angle = mobj->angle + FixedAngle(i*72*FRACUNIT); + } + } + break; + case MT_SSZTREE2: + { // Spawn the branches + INT32 i; + mobj_t *branch; + for (i = 0; i < 5; i++) + { + branch = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_SSZTREE2_BRANCH); + if (P_MobjWasRemoved(branch)) + continue; + branch->angle = mobj->angle + FixedAngle(i*72*FRACUNIT); + } + } + break; case MT_HHZTREE_TOP: { // Spawn the branches angle_t mobjangle = FixedAngle(mthing->angle << FRACBITS) & (ANGLE_90 - 1); diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 168fca61f331ce96772f6124270b0be8ab66f2df..3d1a38d36ff9d9b8f7324df0b18029e35519870d 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -878,15 +878,15 @@ static void Polyobj_carryThings(polyobj_t *po, fixed_t dx, fixed_t dy) { mobj_t *mo; blocknode_t *block; + blocknode_t *next = NULL; if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) continue; - block = blocklinks[y * bmapwidth + x]; - - for (; block; block = block->mnext) + for (block = blocklinks[y * bmapwidth + x]; block != NULL; block = next) { mo = block->mobj; + next = block->mnext; if (mo->lastlook == pomovecount) continue; @@ -927,11 +927,11 @@ static INT32 Polyobj_clipThings(polyobj_t *po, line_t *line) if (!(po->flags & POF_SOLID)) return hitflags; - // adjust linedef bounding box to blockmap, extend by MAXRADIUS - linebox[BOXLEFT] = (unsigned)(line->bbox[BOXLEFT] - bmaporgx - MAXRADIUS) >> MAPBLOCKSHIFT; - linebox[BOXRIGHT] = (unsigned)(line->bbox[BOXRIGHT] - bmaporgx + MAXRADIUS) >> MAPBLOCKSHIFT; - linebox[BOXBOTTOM] = (unsigned)(line->bbox[BOXBOTTOM] - bmaporgy - MAXRADIUS) >> MAPBLOCKSHIFT; - linebox[BOXTOP] = (unsigned)(line->bbox[BOXTOP] - bmaporgy + MAXRADIUS) >> MAPBLOCKSHIFT; + // adjust linedef bounding box to blockmap + linebox[BOXLEFT] = (unsigned)(line->bbox[BOXLEFT] - bmaporgx) >> MAPBLOCKSHIFT; + linebox[BOXRIGHT] = (unsigned)(line->bbox[BOXRIGHT] - bmaporgx) >> MAPBLOCKSHIFT; + linebox[BOXBOTTOM] = (unsigned)(line->bbox[BOXBOTTOM] - bmaporgy) >> MAPBLOCKSHIFT; + linebox[BOXTOP] = (unsigned)(line->bbox[BOXTOP] - bmaporgy) >> MAPBLOCKSHIFT; // check all mobj blockmap cells the line contacts for (y = linebox[BOXBOTTOM]; y <= linebox[BOXTOP]; ++y) @@ -942,9 +942,11 @@ static INT32 Polyobj_clipThings(polyobj_t *po, line_t *line) { mobj_t *mo = NULL; blocknode_t *block = blocklinks[y * bmapwidth + x]; + blocknode_t *next = NULL; - for (; block; block = block->mnext) + for (; block != NULL; block = next) { + next = block->mnext; mo = block->mobj; // Don't scroll objects that aren't affected by gravity @@ -1115,15 +1117,15 @@ static void Polyobj_rotateThings(polyobj_t *po, vector2_t origin, angle_t delta, { mobj_t *mo; blocknode_t *block; + blocknode_t *next = NULL; if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) continue; - block = blocklinks[y * bmapwidth + x]; - - for (; block; block = block->mnext) + for (block = blocklinks[y * bmapwidth + x]; block != NULL; block = next) { mo = block->mobj; + next = block->mnext; if (mo->lastlook == pomovecount) continue; @@ -1316,7 +1318,7 @@ void Polyobj_InitLevel(void) // the mobj_t pointers on a queue for use below. for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo = (mobj_t *)th; diff --git a/src/p_saveg.c b/src/p_saveg.c index 83f7deb350d6e9562a25178900736db55daa38b5..dcdb5606d7e8d2f109be2936157b841a27053d23 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2972,8 +2972,7 @@ static void P_NetArchiveThinkers(save_t *save_p) // save off the current thinkers for (th = thlist[i].next; th != &thlist[i]; th = th->next) { - if (!(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed - || th->function.acp1 == (actionf_p1)P_NullPrecipThinker)) + if (!(th->removing || th->function.acp1 == (actionf_p1)P_NullPrecipThinker)) numsaved++; if (th->function.acp1 == (actionf_p1)P_MobjThinker) @@ -3186,7 +3185,7 @@ static void P_NetArchiveThinkers(save_t *save_p) } #ifdef PARANOIA else - I_Assert(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed); // wait garbage collection + I_Assert(th->removing); // wait garbage collection #endif } @@ -3207,7 +3206,7 @@ mobj_t *P_FindNewPosition(UINT32 oldposition) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mobj = (mobj_t *)th; @@ -4528,7 +4527,7 @@ static inline void P_FinishMobjs(void) for (currentthinker = thlist[THINK_MOBJ].next; currentthinker != &thlist[THINK_MOBJ]; currentthinker = currentthinker->next) { - if (currentthinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (currentthinker->removing) continue; mobj = (mobj_t *)currentthinker; @@ -4546,7 +4545,7 @@ static void P_RelinkPointers(void) for (currentthinker = thlist[THINK_MOBJ].next; currentthinker != &thlist[THINK_MOBJ]; currentthinker = currentthinker->next) { - if (currentthinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (currentthinker->removing) continue; mobj = (mobj_t *)currentthinker; @@ -5239,8 +5238,8 @@ static void P_NetArchiveSectorPortals(save_t *save_p) UINT8 type = secportals[i].type; P_WriteUINT8(save_p, type); - P_WriteFixed(save_p, secportals[i].origin.x); - P_WriteFixed(save_p, secportals[i].origin.y); + P_WriteUINT8(save_p, secportals[i].ceiling ? 1 : 0); + P_WriteUINT32(save_p, SaveSector(secportals[i].target)); switch (type) { @@ -5255,8 +5254,8 @@ static void P_NetArchiveSectorPortals(save_t *save_p) P_WriteUINT32(save_p, SaveSector(secportals[i].sector)); break; case SECPORTAL_OBJECT: - if (secportals[i].mobj && !P_MobjWasRemoved(secportals[i].mobj)) - SaveMobjnum(secportals[i].mobj); + if (!P_MobjWasRemoved(secportals[i].mobj)) + P_WriteUINT32(save_p, SaveMobjnum(secportals[i].mobj)); else P_WriteUINT32(save_p, 0); break; @@ -5283,8 +5282,8 @@ static void P_NetUnArchiveSectorPortals(save_t *save_p) sectorportal_t *secportal = &secportals[id]; secportal->type = P_ReadUINT8(save_p); - secportal->origin.x = P_ReadFixed(save_p); - secportal->origin.y = P_ReadFixed(save_p); + secportal->ceiling = (P_ReadUINT8(save_p) != 0) ? true : false; + secportal->target = LoadSector(P_ReadUINT32(save_p)); switch (secportal->type) { @@ -5376,7 +5375,7 @@ void P_SaveNetGame(save_t *save_p, boolean resending) // Assign the mobjnumber for pointer tracking for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mobj = (mobj_t *)th; diff --git a/src/p_setup.c b/src/p_setup.c index c25336b11abe5319da6deab80334a8daf947e3d1..58896426f50700e29dcfbaaf71283ceef7fe67f9 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -530,7 +530,7 @@ UINT32 P_GetScoreForGradeOverall(INT16 map, UINT8 grade) void P_AddNiGHTSTimes(INT16 i, char *gtext) { char *spos = gtext; - + for (UINT8 n = 0; n < 8; n++) { if (spos != NULL) @@ -692,7 +692,7 @@ void P_ReloadRings(void) // scan the thinkers to find rings/spheres/hoops to unset for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo = (mobj_t *)th; @@ -750,7 +750,7 @@ void P_SwitchSpheresBonusMode(boolean bonustime) // scan the thinkers to find spheres to switch for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo = (mobj_t *)th; @@ -3075,7 +3075,7 @@ static void P_LoadTextmap(void) // TODO: remove this limitation in a backwards-compatible way (UDMF versioning?) UINT8 lightalpha = (textmap_colormap.lightalpha * 102) / 10; UINT8 fadealpha = (textmap_colormap.fadealpha * 102) / 10; - + INT32 rgba = P_ColorToRGBA(textmap_colormap.lightcolor, lightalpha); INT32 fadergba = P_ColorToRGBA(textmap_colormap.fadecolor, fadealpha); sc->extra_colormap = sc->spawn_extra_colormap = R_CreateColormap(rgba, fadergba, textmap_colormap.fadestart, textmap_colormap.fadeend, textmap_colormap.flags); @@ -5866,6 +5866,10 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[0] = tag; lines[i].args[1] = !!(lines[i].flags & ML_NOCLIMB); break; + case 465: // Bounce Player (purely for backwards compatibility with new Pipe Towers) + lines[i].args[0] = (FixedHypot(lines[i].dx, lines[i].dy) / 8) >> FRACBITS; + lines[i].special = 430; + break; case 466: //Set level failure state lines[i].args[0] = !!(lines[i].flags & ML_NOCLIMB); break; @@ -7333,7 +7337,7 @@ void P_RespawnThings(void) for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { - if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (think->removing) continue; P_RemoveMobj((mobj_t *)think); } @@ -7369,11 +7373,11 @@ static void P_RunLevelScript(const char *scriptname) return; } - COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE)); + COM_BufInsertTextEx(W_CacheLumpNum(lumpnum, PU_CACHE), COM_LUA); } else { - COM_BufAddText(va("exec %s\n", scriptname)); + COM_ExecFile(scriptname, COM_LUA, false); } COM_BufExecute(); // Run it! } @@ -7645,20 +7649,20 @@ static void P_InitCamera(void) CV_SetValue(&cv_analog[1], 0); displayplayer = consoleplayer; // Start with your OWN view, please! - } - if (twodlevel) - { - CV_SetValue(&cv_analog[0], false); - CV_SetValue(&cv_analog[1], false); - } - else - { - if (cv_useranalog[0].value) - CV_SetValue(&cv_analog[0], true); + if (twodlevel) + { + CV_SetValue(&cv_analog[0], false); + CV_SetValue(&cv_analog[1], false); + } + else + { + if (cv_useranalog[0].value) + CV_SetValue(&cv_analog[0], true); - if ((splitscreen && cv_useranalog[1].value) || botingame) - CV_SetValue(&cv_analog[1], true); + if ((splitscreen && cv_useranalog[1].value) || botingame) + CV_SetValue(&cv_analog[1], true); + } } } @@ -7853,6 +7857,10 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) maptol = mapheaderinfo[gamemap-1]->typeoflevel; gametyperules = gametypedefaultrules[gametype]; + // clear the target on map change, since the object will be invalidated + P_SetTarget(&ticcmd_ztargetfocus[0], NULL); + P_SetTarget(&ticcmd_ztargetfocus[1], NULL); + CON_Drawer(); // let the user know what we are going to do I_FinishUpdate(); // page flip or blit buffer @@ -8002,6 +8010,9 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) // Free GPU textures before freeing patches. if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED)) HWR_ClearAllTextures(); + + // Delete light table textures + HWR_ClearLightTables(); #endif Patch_FreeTag(PU_PATCH_LOWPRIORITY); diff --git a/src/p_spec.c b/src/p_spec.c index 06203f58fccf5f3e9e8a7575342ecc5f048e1580..54e7a8cacec292d2c5438cd08283cab4cccd1aee 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2546,7 +2546,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) char *text = Z_Malloc(len + 1, PU_CACHE, NULL); memcpy(text, lump, len); text[len] = '\0'; - COM_BufInsertText(text); + COM_BufInsertTextEx(text, COM_LUA); Z_Free(text); } } @@ -2702,6 +2702,18 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) EV_DoCrush(line->args[0], line, crushBothOnce); break; + case 430: // Bounce Player + if (mo && mo->player) + { + P_SetObjectMomZ(mo, line->args[0]*FRACUNIT, false); + S_StartSound(NULL, sfx_s3k8a); + mo->player->pflags |= PF_JUMPED; + if (skins[mo->player->skin]->flags & SF_NOJUMPSPIN) + P_SetMobjState(mo, S_PLAY_SPRING); + else + P_SetMobjState(mo, S_PLAY_JUMP); + } + break; case 432: // Enable/Disable 2D Mode if (mo && mo->player) { @@ -3642,7 +3654,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (mo2->type != MT_EGGTRAP) continue; - if (mo2->thinker.function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (mo2->thinker.removing) continue; P_KillMobj(mo2, NULL, mo, 0); @@ -3854,7 +3866,7 @@ void P_SetupSignExit(player_t *player) // spin all signposts in the level then. for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { - if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (think->removing) continue; thing = (mobj_t *)think; @@ -3892,7 +3904,7 @@ boolean P_IsFlagAtBase(mobjtype_t flag) for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { - if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (think->removing) continue; mo = (mobj_t *)think; @@ -4395,7 +4407,7 @@ static void P_ProcessEggCapsule(player_t *player, sector_t *sector) // The chimps are my friends.. heeheeheheehehee..... - LouisJM for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; if (mo2->type != MT_EGGTRAP) @@ -6236,7 +6248,7 @@ static void P_DoPortalCopyFromLine(sector_t *dest_sector, int plane_type, int ta } } -static sectorportal_t *P_SectorGetPortalOrCreate(sector_t *sector, UINT32 *num, UINT32 *result) +static sectorportal_t *P_SectorGetPortalOrCreate(sector_t *sector, UINT32 *num, UINT32 *result, boolean ceiling) { sectorportal_t *secportal = NULL; @@ -6244,8 +6256,8 @@ static sectorportal_t *P_SectorGetPortalOrCreate(sector_t *sector, UINT32 *num, { *num = P_NewSectorPortal(); secportal = &secportals[*num]; - secportal->origin.x = sector->soundorg.x; - secportal->origin.y = sector->soundorg.y; + secportal->target = sector; + secportal->ceiling = ceiling; *result = *num; } else @@ -6259,12 +6271,12 @@ static sectorportal_t *P_SectorGetPortalOrCreate(sector_t *sector, UINT32 *num, static sectorportal_t *P_SectorGetFloorPortalOrCreate(sector_t *sector, UINT32 *result) { - return P_SectorGetPortalOrCreate(sector, §or->portal_floor, result); + return P_SectorGetPortalOrCreate(sector, §or->portal_floor, result, false); } static sectorportal_t *P_SectorGetCeilingPortalOrCreate(sector_t *sector, UINT32 *result) { - return P_SectorGetPortalOrCreate(sector, §or->portal_ceiling, result); + return P_SectorGetPortalOrCreate(sector, §or->portal_ceiling, result, true); } static void P_CopySectorPortalToLines(UINT32 portal_num, int sector_tag) diff --git a/src/p_tick.c b/src/p_tick.c index c56b2a97f5518e64ccca367412e6b8863a0d59d8..40fa8f39967476abac98cebb51ba8c52247bdf98 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -162,7 +162,7 @@ void Command_CountMobjs_f(void) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; if (((mobj_t *)th)->type == i) @@ -182,7 +182,7 @@ void Command_CountMobjs_f(void) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; if (((mobj_t *)th)->type == i) @@ -346,6 +346,7 @@ void P_RemoveThinkerDelayed(thinker_t *thinker) void P_RemoveThinker(thinker_t *thinker) { LUA_InvalidateUserdata(thinker); + thinker->removing = true; thinker->function.acp1 = (actionf_p1)P_RemoveThinkerDelayed; } diff --git a/src/p_user.c b/src/p_user.c index c2b552d996d1ccfd9357d101d0f6e0590a3918e9..16337316c055d34fda9e3116a1eaa6bb9089eced 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -435,7 +435,7 @@ UINT8 P_FindLowestMare(void) // to find the egg capsule with the lowest mare for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -488,7 +488,7 @@ boolean P_TransferToNextMare(player_t *player) // to find the closest axis point for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -539,7 +539,7 @@ static mobj_t *P_FindAxis(INT32 mare, INT32 axisnum) // to find the closest axis point for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -574,7 +574,7 @@ static mobj_t *P_FindAxisTransfer(INT32 mare, INT32 axisnum, mobjtype_t type) // to find the closest axis point for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -615,7 +615,7 @@ void P_TransferToAxis(player_t *player, INT32 axisnum) // to find the closest axis point for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -716,7 +716,7 @@ static void P_DeNightserizePlayer(player_t *player) // Check to see if the player should be killed. for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -1899,7 +1899,7 @@ void P_SpawnShieldOrb(player_t *player) // blaze through the thinkers to see if an orb already exists! for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; shieldobj = (mobj_t *)th; @@ -4438,27 +4438,21 @@ static void P_DoSuperStuff(player_t *player) // // Returns true if player is ready to transform or detransform // -boolean P_SuperReady(player_t *player, boolean transform) +boolean P_SuperReady(player_t *player) { - if (!transform && - (player->powers[pw_super] < TICRATE*3/2 - || !G_CoopGametype())) // No turning back in competitive! - return false; - else if (transform - && (player->powers[pw_super] - || !ALL7EMERALDS(emeralds) - || !(player->rings >= 50))) - return false; - if (player->mo + && (player->rings >= 50) + && ALL7EMERALDS(emeralds) + && (player->charflags & SF_SUPER) + && (player->pflags & PF_JUMPED) + && !player->powers[pw_super] + && !player->powers[pw_invulnerability] + && !(player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_tailsfly] && !player->powers[pw_carry] - && (player->charflags & SF_SUPER) && !P_PlayerInPain(player) && !player->climbing && !(player->pflags & (PF_JUMPSTASIS|PF_THOKKED|PF_STARTDASH|PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY)) - && ((player->pflags & PF_JUMPED) || (P_IsObjectOnGround(player->mo) && (player->panim == PA_IDLE || player->panim == PA_EDGE - || player->panim == PA_WALK || player->panim == PA_RUN || (player->charflags & SF_DASHMODE && player->panim == PA_DASH)))) && !(maptol & TOL_NIGHTS)) return true; @@ -5112,7 +5106,7 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -5318,8 +5312,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd, boolean spinshieldhac ; else if (cmd->buttons & BT_SPIN) { - if (spinshieldhack && !(player->pflags & PF_SPINDOWN) && P_SuperReady(player, true) - && !player->powers[pw_invulnerability] && !(player->powers[pw_shield] & SH_NOSTACK)) // These two checks are no longer in P_SuperReady + if (spinshieldhack && !(player->pflags & PF_SPINDOWN) && P_SuperReady(player)) { // If you're using two-button play, can turn Super and aren't already, // and you don't have a shield, then turn Super! @@ -6479,7 +6472,7 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad // Find next waypoint for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -6515,7 +6508,7 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad { for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -6544,7 +6537,7 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad { for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -7276,7 +7269,7 @@ static void P_NiGHTSMovement(player_t *player) // to find the closest axis point for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -8176,7 +8169,7 @@ void P_MovePlayer(player_t *player) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -8803,12 +8796,8 @@ void P_MovePlayer(player_t *player) if ((cmd->buttons & BT_SHIELD) && !(player->pflags & PF_SHIELDDOWN) && !spinshieldhack) { // Transform into super if we can! - if (P_SuperReady(player, true)) + if (P_SuperReady(player)) P_DoSuperTransformation(player, false); - - // Detransform from super if we can! - else if (P_SuperReady(player, false)) - P_DoSuperDetransformation(player); } } @@ -9161,7 +9150,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { - if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (think->removing) continue; mo = (mobj_t *)think; @@ -9259,7 +9248,7 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction, for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { - if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (think->removing) continue; mo = (mobj_t *)think; @@ -9378,7 +9367,7 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet) for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { - if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (think->removing) continue; mo = (mobj_t *)think; @@ -9524,7 +9513,7 @@ void P_FindEmerald(void) // to find all emeralds for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; @@ -10925,7 +10914,7 @@ static mobj_t *P_GetAxis(INT32 num) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mobj = (mobj_t *)th; @@ -12007,7 +11996,7 @@ void P_PlayerThink(player_t *player) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; diff --git a/src/r_data.c b/src/r_data.c index e7200ecbd600c85cc6b3ca89c5c84d511b8aface..32faa07a8fb40370008218f2c4fa9ec3a4d3737b 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -426,9 +426,6 @@ void R_ClearColormaps(void) { // Purged by PU_LEVEL, just overwrite the pointer extra_colormaps = R_CreateDefaultColormap(true); -#ifdef HWRENDER - HWR_ClearLightTables(); -#endif } // @@ -849,6 +846,15 @@ void R_GenerateLightTable(extracolormap_t *extra_colormap, boolean uselookup) } } +void R_UpdateLightTable(extracolormap_t *extra_colormap, boolean uselookup) +{ + R_GenerateLightTable(extra_colormap, uselookup); + +#ifdef HWRENDER + extra_colormap->gl_lighttable.needs_update = true; +#endif +} + extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3) { // default values diff --git a/src/r_data.h b/src/r_data.h index 7c6ee19d50c4b8b9b081691541b4d35fff5388c4..64abf6d83637ed8f54c7449f621ac52eb6aa9113 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -90,6 +90,7 @@ typedef enum } textmapcolormapflags_t; void R_GenerateLightTable(extracolormap_t *extra_colormap, boolean uselookup); +void R_UpdateLightTable(extracolormap_t *extra_colormap, boolean uselookup); lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap); extracolormap_t * R_CreateColormapFromLinedef(char *p1, char *p2, char *p3); extracolormap_t* R_CreateColormap(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags); diff --git a/src/r_defs.h b/src/r_defs.h index 332d78e3c768877a671aadf2a9b22acfa06bd437..80b697c40f10e24745ba2e0cc74e0e9ed6a21318 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -76,8 +76,11 @@ typedef struct extracolormap_s lighttable_t *colormap; #ifdef HWRENDER - // The id of the hardware lighttable. Zero means it does not exist yet. - UINT32 gl_lighttable_id; + struct { + UINT32 id; // The id of the hardware lighttable. Zero means it does not exist yet. + RGBA_t *data; // The texture data of the hardware lighttable. + boolean needs_update; // If the colormap changed recently or not. + } gl_lighttable; #endif #ifdef EXTRACOLORMAPLUMPS @@ -242,9 +245,8 @@ typedef struct sectorportal_s struct sector_s *sector; struct mobj_s *mobj; }; - struct { - fixed_t x, y; - } origin; + struct sector_s *target; + boolean ceiling; } sectorportal_t; typedef struct ffloor_s diff --git a/src/r_draw.h b/src/r_draw.h index 00032e44f51d713b42b89cd9c2dda5344e945abb..d5c5b4e25d36ba375d365a2d13f0ba5fab19e3f3 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -173,6 +173,7 @@ void R_DrawTiltedTranslucentSpan_8(void); void R_DrawSplat_8(void); void R_DrawTranslucentSplat_8(void); void R_DrawTiltedSplat_8(void); +void R_DrawTiltedTranslucentSplat_8(void); void R_DrawFloorSprite_8(void); void R_DrawTranslucentFloorSprite_8(void); @@ -194,6 +195,7 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void); void R_DrawSplat_NPO2_8(void); void R_DrawTranslucentSplat_NPO2_8(void); void R_DrawTiltedSplat_NPO2_8(void); +void R_DrawTiltedTranslucentSplat_NPO2_8(void); void R_DrawFloorSprite_NPO2_8(void); void R_DrawTranslucentFloorSprite_NPO2_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index 220878f88e4d34ac0cfd99ef7246a12aec73d4e4..c720f454e078d1f7857227eae01caa866d56d136 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -1301,6 +1301,136 @@ void R_DrawTiltedSplat_8(void) #endif } +void R_DrawTiltedTranslucentSplat_8(void) +{ + // x1, x2 = ds_x1, ds_x2 + int width = ds_x2 - ds_x1; + double iz, uz, vz; + UINT32 u, v; + int i; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + + UINT8 val; + + double startz, startu, startv; + double izstep, uzstep, vzstep; + double endz, endu, endv; + UINT32 stepu, stepv; + + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); + + R_CalcSlopeLight(); + + dest = &topleft[ds_y*vid.width + ds_x1]; + source = ds_source; + //colormap = ds_colormap; + +#if 0 // The "perfect" reference version of this routine. Pretty slow. + // Use it only to see how things are supposed to look. + i = 0; + do + { + double z = 1.f/iz; + u = (INT64)(uz*z); + v = (INT64)(vz*z); + + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + + val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + + dest++; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; + } while (--width >= 0); +#else + startz = 1.f/iz; + startu = uz*startz; + startv = vz*startz; + + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; + //x1 = 0; + width++; + + while (width >= SPANSIZE) + { + iz += izstep; + uz += uzstep; + vz += vzstep; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + stepu = (INT64)((endu - startu) * INVSPAN); + stepv = (INT64)((endv - startv) * INVSPAN); + u = (INT64)(startu); + v = (INT64)(startv); + + for (i = SPANSIZE-1; i >= 0; i--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + dest++; + u += stepu; + v += stepv; + } + startu = endu; + startv = endv; + width -= SPANSIZE; + } + if (width > 0) + { + if (width == 1) + { + u = (INT64)(startu); + v = (INT64)(startv); + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + } + else + { + double left = width; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + left = 1.f/left; + stepu = (INT64)((endu - startu) * left); + stepv = (INT64)((endv - startv) * left); + u = (INT64)(startu); + v = (INT64)(startv); + + for (; width != 0; width--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + dest++; + u += stepu; + v += stepv; + } + } + } +#endif +} + /** \brief The R_DrawSplat_8 function Just like R_DrawSpan_8, but skips transparent pixels. */ diff --git a/src/r_draw8_npo2.c b/src/r_draw8_npo2.c index 6213ecbc5f17af1cfa37b78c4d9d454f0ab09c9a..7fbb40d84956d342f1d675876f7dbcc9b2cd539b 100644 --- a/src/r_draw8_npo2.c +++ b/src/r_draw8_npo2.c @@ -666,6 +666,204 @@ void R_DrawTiltedSplat_NPO2_8(void) #endif } +void R_DrawTiltedTranslucentSplat_NPO2_8(void) +{ + // x1, x2 = ds_x1, ds_x2 + int width = ds_x2 - ds_x1; + double iz, uz, vz; + UINT32 u, v; + int i; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + + UINT8 val; + + double startz, startu, startv; + double izstep, uzstep, vzstep; + double endz, endu, endv; + UINT32 stepu, stepv; + + struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); + struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); + + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); + + R_CalcSlopeLight(); + + dest = &topleft[ds_y*vid.width + ds_x1]; + source = ds_source; + //colormap = ds_colormap; + +#if 0 // The "perfect" reference version of this routine. Pretty slow. + // Use it only to see how things are supposed to look. + i = 0; + do + { + double z = 1.f/iz; + u = (INT64)(uz*z); + v = (INT64)(vz*z); + + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + + // Lactozilla: Non-powers-of-two + { + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + if (y < 0) + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + + val = source[((y * ds_flatwidth) + x)]; + } + + if (val != TRANSPARENTPIXEL) + *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + + dest++; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; + } while (--width >= 0); +#else + startz = 1.f/iz; + startu = uz*startz; + startv = vz*startz; + + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; + //x1 = 0; + width++; + + while (width >= SPANSIZE) + { + iz += izstep; + uz += uzstep; + vz += vzstep; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + stepu = (INT64)((endu - startu) * INVSPAN); + stepv = (INT64)((endv - startv) * INVSPAN); + u = (INT64)(startu); + v = (INT64)(startv); + + for (i = SPANSIZE-1; i >= 0; i--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + // Lactozilla: Non-powers-of-two + { + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + if (y < 0) + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + + val = source[((y * ds_flatwidth) + x)]; + } + if (val != TRANSPARENTPIXEL) + *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + dest++; + u += stepu; + v += stepv; + } + startu = endu; + startv = endv; + width -= SPANSIZE; + } + if (width > 0) + { + if (width == 1) + { + u = (INT64)(startu); + v = (INT64)(startv); + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + // Lactozilla: Non-powers-of-two + { + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + if (y < 0) + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + + val = source[((y * ds_flatwidth) + x)]; + } + if (val != TRANSPARENTPIXEL) + *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + } + else + { + double left = width; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + left = 1.f/left; + stepu = (INT64)((endu - startu) * left); + stepv = (INT64)((endv - startv) * left); + u = (INT64)(startu); + v = (INT64)(startv); + + for (; width != 0; width--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + // Lactozilla: Non-powers-of-two + { + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + if (y < 0) + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + + val = source[((y * ds_flatwidth) + x)]; + } + if (val != TRANSPARENTPIXEL) + *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + dest++; + u += stepu; + v += stepv; + } + } + } +#endif +} + /** \brief The R_DrawSplat_NPO2_8 function Just like R_DrawSpan_NPO2_8, but skips transparent pixels. */ diff --git a/src/r_main.c b/src/r_main.c index 32e3138eb07fbe1abc736c382cc66de389084b64..ee05876da1395f4375515457e552b36cffcfd486 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1434,6 +1434,9 @@ static void R_PortalFrame(portal_t *portal) viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); + if (!P_MobjWasRemoved(portal->viewmobj)) + r_viewmobj = portal->viewmobj; + portalclipstart = portal->start; portalclipend = portal->end; diff --git a/src/r_plane.c b/src/r_plane.c index 380f39eabca224a402044d7be1504a3b60356044..a0de048ea8c6fe7eac8265d1cdfd3559d9bba1d6 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -83,7 +83,7 @@ static fixed_t planeheight; fixed_t yslopetab[MAXVIDHEIGHT*16]; fixed_t *yslope; -static fixed_t xoffs, yoffs; +static INT64 xoffs, yoffs; static dvector3_t slope_origin, slope_u, slope_v; static dvector3_t slope_lightu, slope_lightv; @@ -376,19 +376,25 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li visplane_t *check; unsigned hash; + float offset_xd = FixedToFloat(xoff) / FixedToFloat(xscale ? xscale : 1); + float offset_yd = FixedToFloat(yoff) / FixedToFloat(yscale ? yscale : 1); + + INT64 offset_x = offset_xd * FRACUNIT; + INT64 offset_y = offset_yd * FRACUNIT; + if (!slope) // Don't mess with this right now if a slope is involved { - xoff += FixedMul(viewx, xscale); - yoff -= FixedMul(viewy, yscale); + offset_x += viewx; + offset_y -= viewy; if (plangle != 0) { // Add the view offset, rotated by the plane angle. float ang = ANG2RAD(plangle); - float x = FixedToFloat(xoff); - float y = FixedToFloat(yoff); - xoff = FloatToFixed(x * cos(ang) + y * sin(ang)); - yoff = FloatToFixed(-x * sin(ang) + y * cos(ang)); + float x = offset_x / (float)FRACUNIT; + float y = offset_y / (float)FRACUNIT; + offset_x = (x * cos(ang) + y * sin(ang)) * FRACUNIT; + offset_y = (-x * sin(ang) + y * cos(ang)) * FRACUNIT; } } @@ -399,16 +405,19 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li float ang = ANG2RAD(polyobj->angle); float x = FixedToFloat(polyobj->centerPt.x); float y = FixedToFloat(polyobj->centerPt.y); - xoff -= FloatToFixed(x * cos(ang) + y * sin(ang)); - yoff -= FloatToFixed(x * sin(ang) - y * cos(ang)); + offset_x -= (x * cos(ang) + y * sin(ang)) * FRACUNIT; + offset_y -= (x * sin(ang) - y * cos(ang)) * FRACUNIT; } else { - xoff -= polyobj->centerPt.x; - yoff += polyobj->centerPt.y; + offset_x -= polyobj->centerPt.x; + offset_y += polyobj->centerPt.y; } } + offset_x = ((INT64)offset_x * xscale) / FRACUNIT; + offset_y = ((INT64)offset_y * yscale) / FRACUNIT; + // This appears to fix the Nimbus Ruins sky bug. if (picnum == skyflatnum && pfloor) { @@ -423,7 +432,7 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li { if (height == check->height && picnum == check->picnum && lightlevel == check->lightlevel - && xoff == check->xoffs && yoff == check->yoffs + && offset_x == check->xoffs && offset_y == check->yoffs && xscale == check->xscale && yscale == check->yscale && planecolormap == check->extra_colormap && check->viewx == viewx && check->viewy == viewy && check->viewz == viewz @@ -449,8 +458,8 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li check->lightlevel = lightlevel; check->minx = vid.width; check->maxx = -1; - check->xoffs = xoff; - check->yoffs = yoff; + check->xoffs = offset_x; + check->yoffs = offset_y; check->xscale = xscale; check->yscale = yscale; check->extra_colormap = planecolormap; @@ -658,13 +667,13 @@ static void R_DrawSkyPlane(visplane_t *pl) } // Returns the height of the sloped plane at (x, y) as a double -static double R_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y) +static double R_GetSlopeZAt(const pslope_t *slope, INT64 x, INT64 y) { // If you want to reimplement this using just the equation constants, use this instead: // (d + a*x + b*y) * -(1.0 / c) - double px = FixedToDouble(x) - slope->dorigin.x; - double py = FixedToDouble(y) - slope->dorigin.y; + double px = (x / (double)FRACUNIT) - slope->dorigin.x; + double py = (y / (double)FRACUNIT) - slope->dorigin.y; double dist = (px * slope->dnormdir.x) + (py * slope->dnormdir.y); @@ -672,10 +681,10 @@ static double R_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y) } // Sets the texture origin vector of the sloped plane. -static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, fixed_t angle) +static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, INT64 xoff, INT64 yoff, fixed_t angle) { - INT64 vx = (INT64)xpos + (INT64)xoff; - INT64 vy = (INT64)ypos - (INT64)yoff; + INT64 vx = (INT64)xpos + xoff; + INT64 vy = (INT64)ypos - yoff; float vxf = vx / (float)FRACUNIT; float vyf = vy / (float)FRACUNIT; @@ -702,7 +711,7 @@ void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, slope->moved = false; } - R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, xoff, yoff, angle); + R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, (INT64)xoff, (INT64)yoff, angle); height = R_GetSlopeZAt(slope, xpos, ypos); zeroheight = height - FixedToDouble(zpos); @@ -735,7 +744,7 @@ void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, } // This function calculates all of the vectors necessary for drawing a sloped and scaled plane. -void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle) +void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, INT64 xoff, INT64 yoff, angle_t angle, angle_t plangle) { double height, z_at_xy; float ang; @@ -836,9 +845,11 @@ static void CalcSlopePlaneVectors(visplane_t *pl, fixed_t xoff, fixed_t yoff) { if (!ds_fog && (pl->xscale != FRACUNIT || pl->yscale != FRACUNIT)) { + float offset_x = FixedToFloat(xoff) / FixedToFloat(pl->xscale ? pl->xscale : 1); + float offset_y = FixedToFloat(yoff) / FixedToFloat(pl->yscale ? pl->yscale : 1); R_SetScaledSlopePlane(pl->slope, pl->viewx, pl->viewy, pl->viewz, FixedDiv(FRACUNIT, pl->xscale), FixedDiv(FRACUNIT, pl->yscale), - FixedDiv(xoff, pl->xscale), FixedDiv(yoff, pl->yscale), pl->viewangle, pl->plangle); + (INT64)(offset_x * FRACUNIT), (INT64)(offset_y * FRACUNIT), pl->viewangle, pl->plangle); } else R_SetSlopePlane(pl->slope, pl->viewx, pl->viewy, pl->viewz, xoff, yoff, pl->viewangle, pl->plangle); @@ -1079,6 +1090,9 @@ void R_DrawSinglePlane(visplane_t *pl) case SPANDRAWFUNC_SPLAT: spanfunctype = SPANDRAWFUNC_TILTEDSPLAT; break; + case SPANDRAWFUNC_TRANSSPLAT: + spanfunctype = SPANDRAWFUNC_TILTEDTRANSSPLAT; + break; case SPANDRAWFUNC_SOLID: spanfunctype = SPANDRAWFUNC_TILTEDSOLID; break; diff --git a/src/r_plane.h b/src/r_plane.h index 69620f25e07cadefee8242f23ad3a26a57ffbc9d..cd947750119b8446e0683bd4d62ae7b88fa9c1a7 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -48,7 +48,7 @@ typedef struct visplane_s UINT16 padbottomstart, bottom[MAXVIDWIDTH], padbottomend; INT32 high, low; // R_PlaneBounds should set these. - fixed_t xoffs, yoffs; // Scrolling flats. + INT64 xoffs, yoffs; // Scrolling flats. fixed_t xscale, yscale; sector_t *sector; @@ -85,7 +85,7 @@ void R_DrawSinglePlane(visplane_t *pl); // Calculates the slope vectors needed for tilted span drawing. void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle); -void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle); +void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, INT64 xoff, INT64 yoff, angle_t angle, angle_t plangle); typedef struct planemgr_s { diff --git a/src/r_portal.c b/src/r_portal.c index 4d042cae38574bd54165d5b5850e8e18c5f31f33..957d574b2e9ebc3505a459adfee51c08270066ac 100644 --- a/src/r_portal.c +++ b/src/r_portal.c @@ -101,7 +101,7 @@ void Portal_ClipApply (const portal_t* portal) static portal_t* Portal_Add (const INT16 x1, const INT16 x2) { - portal_t *portal = Z_Malloc(sizeof(portal_t), PU_LEVEL, NULL); + portal_t *portal = Z_Calloc(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); @@ -117,7 +117,7 @@ static portal_t* Portal_Add (const INT16 x1, const INT16 x2) portal_cap->next = portal; portal_cap = portal; } - portal->next = NULL; + portal->clipline = -1; // Store clipping values so they can be restored once the portal is rendered. portal->ceilingclip = ceilingclipsave; @@ -142,11 +142,9 @@ void Portal_Remove (portal_t* portal) Z_Free(portal); } -static void Portal_GetViewpointForLine(portal_t *portal, line_t *start, line_t *dest) +static void Portal_GetViewpointForLine(portal_t *portal, line_t *start, line_t *dest, angle_t dangle) { // Offset the portal view by the linedef centers - 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; @@ -168,7 +166,6 @@ static void Portal_GetViewpointForLine(portal_t *portal, line_t *start, line_t * 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; } @@ -189,12 +186,13 @@ void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, con line_t* start = &lines[line1]; line_t* dest = &lines[line2]; - Portal_GetViewpointForLine(portal, start, dest); + angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0); + + Portal_GetViewpointForLine(portal, start, dest, dangle); + + portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight; portal->clipline = line2; - portal->is_skybox = false; - portal->is_horizon = false; - portal->horizon_sector = NULL; Portal_ClipRange(portal); @@ -317,10 +315,7 @@ static boolean Portal_AddSkybox (const visplane_t* plane) Portal_ClipVisplane(plane, portal); - portal->clipline = -1; portal->is_skybox = true; - portal->is_horizon = false; - portal->horizon_sector = NULL; Portal_GetViewpointForSkybox(portal); @@ -332,14 +327,28 @@ static void Portal_GetViewpointForSecPortal(portal_t *portal, sectorportal_t *se fixed_t x, y, z; angle_t angle; + sector_t *target = secportal->target; + + fixed_t target_x = target->soundorg.x; + fixed_t target_y = target->soundorg.y; + fixed_t target_z; + + if (secportal->ceiling) + target_z = P_GetSectorCeilingZAt(target, target_x, target_y); + else + target_z = P_GetSectorFloorZAt(target, target_x, target_y); + switch (secportal->type) { case SECPORTAL_LINE: - Portal_GetViewpointForLine(portal, secportal->line.start, secportal->line.dest); + angle = secportal->line.dest->angle - secportal->line.start->angle; + Portal_GetViewpointForLine(portal, secportal->line.start, secportal->line.dest, angle); + portal->viewz = viewz; // Apparently it just works like that. Not going to question it. return; case SECPORTAL_OBJECT: - if (!secportal->mobj || P_MobjWasRemoved(secportal->mobj)) + if (P_MobjWasRemoved(secportal->mobj)) return; + portal->viewmobj = secportal->mobj; x = secportal->mobj->x; y = secportal->mobj->y; z = secportal->mobj->z; @@ -373,8 +382,9 @@ static void Portal_GetViewpointForSecPortal(portal_t *portal, sectorportal_t *se return; } - fixed_t refx = secportal->origin.x - viewx; - fixed_t refy = secportal->origin.y - viewy; + fixed_t refx = target_x - viewx; + fixed_t refy = target_y - viewy; + fixed_t refz = target_z - viewz; // Rotate the X/Y to match the target angle if (angle != 0) @@ -387,7 +397,7 @@ static void Portal_GetViewpointForSecPortal(portal_t *portal, sectorportal_t *se portal->viewx = x - refx; portal->viewy = y - refy; - portal->viewz = z + viewz; + portal->viewz = z - refz; portal->viewangle = angle + viewangle; } @@ -413,11 +423,6 @@ static boolean Portal_AddSectorPortal (const visplane_t* plane) Portal_ClipVisplane(plane, portal); - portal->clipline = -1; - portal->is_horizon = false; - portal->is_skybox = false; - portal->horizon_sector = NULL; - Portal_GetViewpointForSecPortal(portal, secportal); return true; @@ -425,7 +430,7 @@ static boolean Portal_AddSectorPortal (const visplane_t* plane) /** Creates a transferred sector portal. */ -void Portal_AddTransferred (UINT32 secportalnum, const INT32 x1, const INT32 x2) +void Portal_AddTransferred (const UINT32 secportalnum, const INT32 x1, const INT32 x2) { if (secportalnum >= secportalcount) return; @@ -435,9 +440,6 @@ void Portal_AddTransferred (UINT32 secportalnum, const INT32 x1, const INT32 x2) return; portal_t* portal = Portal_Add(x1, x2); - portal->is_skybox = false; - portal->is_horizon = false; - portal->horizon_sector = NULL; if (secportal->type == SECPORTAL_SKYBOX) Portal_GetViewpointForSkybox(portal); diff --git a/src/r_portal.h b/src/r_portal.h index 2485e45a71afb5bc189525f140527c5bb03e2a21..5190885b7189c38b1b7b1b7b13f0519f1d455b0c 100644 --- a/src/r_portal.h +++ b/src/r_portal.h @@ -36,6 +36,8 @@ typedef struct portal_s boolean is_skybox; + mobj_t *viewmobj; + UINT8 pass; /**< Keeps track of the portal's recursion depth. */ INT32 clipline; /**< Optional clipline for line-based portals. */ @@ -58,7 +60,7 @@ 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_AddTransferred (UINT32 secportalnum, const INT32 x1, const INT32 x2); +void Portal_AddTransferred (const UINT32 secportalnum, const INT32 x1, const INT32 x2); void Portal_ClipRange (portal_t* portal); void Portal_ClipApply (const portal_t* portal); diff --git a/src/r_splats.c b/src/r_splats.c index 813c4b2430b53941c449450c9b5926e2e922ec80..ce35a35b4c3ff24d1045a170a67d421310f837af 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -381,7 +381,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr if (pSplat->slope) { - R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle); + R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, (INT64)pSplat->xscale, (INT64)pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle); } else if (!ds_solidcolor) { diff --git a/src/screen.c b/src/screen.c index 3e8ec751bd756ba2d54953e8dab78be50d919bc5..1c133d5e8f2f994c8a0131eb29fd38acbcd4ccb9 100644 --- a/src/screen.c +++ b/src/screen.c @@ -124,6 +124,7 @@ void SCR_SetDrawFuncs(void) spanfuncs[SPANDRAWFUNC_SPLAT] = R_DrawSplat_8; spanfuncs[SPANDRAWFUNC_TRANSSPLAT] = R_DrawTranslucentSplat_8; spanfuncs[SPANDRAWFUNC_TILTEDSPLAT] = R_DrawTiltedSplat_8; + spanfuncs[SPANDRAWFUNC_TILTEDTRANSSPLAT] = R_DrawTiltedTranslucentSplat_8; spanfuncs[SPANDRAWFUNC_SPRITE] = R_DrawFloorSprite_8; spanfuncs[SPANDRAWFUNC_TRANSSPRITE] = R_DrawTranslucentFloorSprite_8; spanfuncs[SPANDRAWFUNC_TILTEDSPRITE] = R_DrawTiltedFloorSprite_8; @@ -146,6 +147,7 @@ void SCR_SetDrawFuncs(void) spanfuncs_npo2[SPANDRAWFUNC_SPLAT] = R_DrawSplat_NPO2_8; spanfuncs_npo2[SPANDRAWFUNC_TRANSSPLAT] = R_DrawTranslucentSplat_NPO2_8; spanfuncs_npo2[SPANDRAWFUNC_TILTEDSPLAT] = R_DrawTiltedSplat_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_TILTEDTRANSSPLAT] = R_DrawTiltedTranslucentSplat_NPO2_8; spanfuncs_npo2[SPANDRAWFUNC_SPRITE] = R_DrawFloorSprite_NPO2_8; spanfuncs_npo2[SPANDRAWFUNC_TRANSSPRITE] = R_DrawTranslucentFloorSprite_NPO2_8; spanfuncs_npo2[SPANDRAWFUNC_TILTEDSPRITE] = R_DrawTiltedFloorSprite_NPO2_8; @@ -493,11 +495,9 @@ void SCR_ClosedCaptions(void) basey -= 42; else if (splitscreen) basey -= 8; - else if ((modeattacking == ATTACKING_NIGHTS) - || (!(maptol & TOL_NIGHTS) - && LUA_HudEnabled(hud_powerups) + else if (LUA_HudEnabled(hud_powerups) && ((cv_powerupdisplay.value == 2) // "Always" - || (cv_powerupdisplay.value == 1 && !camera.chase)))) // "First-person only" + || (cv_powerupdisplay.value == 1 && !camera.chase))) // "First-person only" basey -= 16; } diff --git a/src/screen.h b/src/screen.h index 6d45560c4582164e84c881004cbda002a7177d47..3ce593a52e8595e7412eb9c20c29c91ba9c057bb 100644 --- a/src/screen.h +++ b/src/screen.h @@ -115,6 +115,7 @@ enum SPANDRAWFUNC_SPLAT, SPANDRAWFUNC_TRANSSPLAT, SPANDRAWFUNC_TILTEDSPLAT, + SPANDRAWFUNC_TILTEDTRANSSPLAT, SPANDRAWFUNC_SPRITE, SPANDRAWFUNC_TRANSSPRITE, diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index ca87fcc7951758e9a5de7ca1a405f88b1f202204..f561266017dd9fcf20b467b3c5e9323be7f5dbe2 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -112,6 +112,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(SetPaletteLookup); GETFUNC(CreateLightTable); + GETFUNC(UpdateLightTable); GETFUNC(ClearLightTables); GETFUNC(SetScreenPalette); diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 9fe50a6a2347583f0fe705ff5c6f6a0466ea51a9..b2396e269b8d7cc456ee9f525aeda7991835cd4e 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -5,7 +5,7 @@ // // Copyright (C) 1993-1996 by id Software, Inc. // Portions Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 2014-2023 by Sonic Team Junior. +// Copyright (C) 2014-2025 by Sonic Team Junior. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -78,10 +78,11 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #include "SDL_cpuinfo.h" #define HAVE_SDLCPUINFO -#if defined (__unix__) || defined(__APPLE__) || (defined (UNIXCOMMON) && !defined (__HAIKU__)) -#if defined (__linux__) -#include <sys/vfs.h> +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) +#if defined (__linux__) || defined (__HAIKU__) +#include <sys/statvfs.h> #else +#include <sys/statvfs.h> #include <sys/param.h> #include <sys/mount.h> /*For meminfo*/ @@ -94,7 +95,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #endif #endif -#if defined (__linux__) || (defined (UNIXCOMMON) && !defined (__HAIKU__)) +#if defined (__linux__) || defined (UNIXCOMMON) #ifndef NOTERMIOS #include <termios.h> #include <sys/ioctl.h> // ioctl @@ -109,8 +110,10 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #if defined (__unix__) || (defined (UNIXCOMMON) && !defined (__APPLE__)) #include <errno.h> #include <sys/wait.h> +#ifndef __HAIKU__ // haiku's crash dialog is just objectively better #define NEWSIGNALHANDLER #endif +#endif #ifndef NOMUMBLE #ifdef __linux__ // need -lrt @@ -477,10 +480,9 @@ typedef struct 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; +// lock to prevent clearing partial lines, since not everything +// printed ends on a newline. +static boolean ttycon_ateol = true; // some key codes that the terminal may be using // TTimo NOTE: I'm not sure how relevant this is static INT32 tty_erase; @@ -508,63 +510,31 @@ static inline void tty_FlushIn(void) // 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) +// Hanicef NOTE: using \b this way is unreliable because of terminal state, +// it's better to use \r to reset the cursor to the beginning of the +// line and clear from there. 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; + write(STDOUT_FILENO, "\r", 1); 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; + write(STDOUT_FILENO, tty_con.buffer, tty_con.cursor); } - tty_Clear(); - ttycon_hide++; + write(STDOUT_FILENO, " \b", 2); } -// show the current line -// FIXME TTimo need to position the cursor if needed?? -static inline void tty_Show(void) +static void tty_Clear(void) { size_t i; - ssize_t d; - //I_Assert(consolevent); - I_Assert(ttycon_hide>0); - ttycon_hide--; - if (ttycon_hide == 0 && tty_con.cursor) + write(STDOUT_FILENO, "\r", 1); + if (tty_con.cursor>0) { for (i=0; i<tty_con.cursor; i++) { - d = write(STDOUT_FILENO, tty_con.buffer+i, 1); + write(STDOUT_FILENO, " ", 1); } + write(STDOUT_FILENO, "\r", 1); } - (void)d; } // never exit without calling this, or your terminal will be left in a pretty bad state @@ -672,6 +642,11 @@ void I_GetConsoleEvents(void) tty_con.cursor = 0; ev.key = KEY_ENTER; } + else if (key == 0x4) // ^D, aka EOF + { + // shut down, most unix programs behave this way + I_Quit(); + } else continue; } else if (tty_con.cursor < sizeof (tty_con.buffer)) @@ -879,9 +854,16 @@ static void I_RegisterChildSignals(void) void I_OutputMsg(const char *fmt, ...) { size_t len; - char txt[8192]; + char *txt; va_list argptr; + va_start(argptr,fmt); + len = vsnprintf(NULL, 0, fmt, argptr); + va_end(argptr); + if (len == 0) + return; + + txt = malloc(len+1); va_start(argptr,fmt); vsprintf(txt, fmt, argptr); va_end(argptr); @@ -915,7 +897,10 @@ void I_OutputMsg(const char *fmt, ...) DWORD bytesWritten; if (co == INVALID_HANDLE_VALUE) + { + free(txt); return; + } if (GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &bytesWritten)) { @@ -931,11 +916,16 @@ void I_OutputMsg(const char *fmt, ...) if (oldLength > 0) { LPVOID blank = malloc(oldLength); - if (!blank) return; + if (!blank) + { + free(txt); + return; + } memset(blank, ' ', oldLength); // Blank out. oldLines = malloc(oldLength*sizeof(TCHAR)); if (!oldLines) { + free(txt); free(blank); return; } @@ -970,18 +960,20 @@ void I_OutputMsg(const char *fmt, ...) } #else #ifdef HAVE_TERMIOS - if (consolevent) + if (consolevent && ttycon_ateol) { - tty_Hide(); + tty_Clear(); + ttycon_ateol = false; } #endif if (!framebuffer) fprintf(stderr, "%s", txt); #ifdef HAVE_TERMIOS - if (consolevent) + if (consolevent && txt[len-1] == '\n') { - tty_Show(); + write(STDOUT_FILENO, tty_con.buffer, tty_con.cursor); + ttycon_ateol = true; } #endif @@ -990,6 +982,7 @@ void I_OutputMsg(const char *fmt, ...) fflush(stderr); #endif + free(txt); } // @@ -2307,15 +2300,24 @@ void I_Sleep(UINT32 ms) void I_SleepDuration(precise_t duration) { -#if defined(__linux__) || defined(__FreeBSD__) +#if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__) UINT64 precision = I_GetPrecisePrecision(); - struct timespec ts = { - .tv_sec = duration / precision, - .tv_nsec = duration * 1000000000 / precision % 1000000000, - }; - int status; - do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts); - while (status == EINTR); + precise_t dest = I_GetPreciseTime() + duration; + precise_t slack = (precision / 5000); // 0.2 ms slack + if (duration > slack) + { + duration -= slack; + struct timespec ts = { + .tv_sec = duration / precision, + .tv_nsec = duration * 1000000000 / precision % 1000000000, + }; + int status; + do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts); + while (status == EINTR); + } + + // busy-wait the rest + while (((INT64)dest - (INT64)I_GetPreciseTime()) > 0); #elif defined (MIN_SLEEP_DURATION_MS) UINT64 precision = I_GetPrecisePrecision(); INT32 sleepvalue = cv_sleep.value; @@ -2754,18 +2756,13 @@ void I_ShutdownSystem(void) void I_GetDiskFreeSpace(INT64 *freespace) { #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) -#if defined (SOLARIS) || defined (__HAIKU__) - *freespace = INT32_MAX; - return; -#else // Both Linux and BSD have this, apparently. - struct statfs stfs; - if (statfs(srb2home, &stfs) == -1) + struct statvfs stfs; + if (statvfs(srb2home, &stfs) == -1) { *freespace = INT32_MAX; return; } *freespace = stfs.f_bavail * stfs.f_bsize; -#endif #elif defined (_WIN32) static p_GetDiskFreeSpaceExA pfnGetDiskFreeSpaceEx = NULL; static boolean testwin95 = false; @@ -3087,8 +3084,10 @@ const char *I_LocateWad(void) { // change to the directory where we found srb2.pk3 #if defined (_WIN32) + waddir = _fullpath(NULL, waddir, MAX_PATH); SetCurrentDirectoryA(waddir); #else + waddir = realpath(waddir, NULL); if (chdir(waddir) == -1) I_OutputMsg("Couldn't change working directory\n"); #endif diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 10c866a1e32ff6dd3c8ac248fb50df2a4e3a30f6..82583ccb4651ff8cbfc42be4a0f40ee54bd31d7d 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -87,7 +87,7 @@ #endif // maximum number of windowed modes (see windowedModes[][]) -#define MAXWINMODES (18) +#define MAXWINMODES (21) /** \brief */ @@ -157,7 +157,9 @@ static INT32 windowedModes[MAXWINMODES][2] = {1920,1080}, // 1.66 {1680,1050}, // 1.60,5.25 {1600,1200}, // 1.33 + {1600,1000}, // 1.60,5.00 {1600, 900}, // 1.66 + {1536, 864}, // 1.66,4.80 {1366, 768}, // 1.66 {1440, 900}, // 1.60,4.50 {1280,1024}, // 1.33? @@ -166,6 +168,7 @@ static INT32 windowedModes[MAXWINMODES][2] = {1280, 720}, // 1.66 {1152, 864}, // 1.33,3.60 {1024, 768}, // 1.33,3.20 + { 960, 600}, // 1.60,3.00 { 800, 600}, // 1.33,2.50 { 640, 480}, // 1.33,2.00 { 640, 400}, // 1.60,2.00 @@ -1901,6 +1904,7 @@ void VID_StartupOpenGL(void) HWD.pfnSetPaletteLookup = hwSym("SetPaletteLookup",NULL); HWD.pfnCreateLightTable = hwSym("CreateLightTable",NULL); + HWD.pfnUpdateLightTable = hwSym("UpdateLightTable",NULL); HWD.pfnClearLightTables = hwSym("ClearLightTables",NULL); HWD.pfnSetScreenPalette = hwSym("SetScreenPalette",NULL); @@ -1945,8 +1949,6 @@ void I_ShutdownGraphics(void) I_OutputMsg("shut down\n"); #ifdef HWRENDER - if (GLUhandle) - hwClose(GLUhandle); if (sdlglcontext) { SDL_GL_DeleteContext(sdlglcontext); diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index e7347547e224b43f2fcdf66e527c8adc2681e243..c78b43ec4097cafad8420ceb7497e2883220a67e 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -70,18 +70,10 @@ PFNglGetString pglGetString; /** \brief SDL video display surface */ INT32 oglflags = 0; -void *GLUhandle = NULL; SDL_GLContext sdlglcontext = 0; 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); } @@ -89,7 +81,6 @@ boolean LoadGL(void) { #ifndef STATIC_OPENGL const char *OGLLibname = NULL; - const char *GLULibname = NULL; if (M_CheckParm("-OGLlib") && M_IsNextParm()) OGLLibname = M_GetNextParm(); @@ -102,43 +93,6 @@ boolean LoadGL(void) CONS_Printf("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 - { - CONS_Alert(CONS_ERROR, "Could not load GLU Library: %s\n", GLULibname); - if (!M_CheckParm ("-GLUlib")) - CONS_Alert(CONS_ERROR, "If you know what is the GLU library's name, use -GLUlib\n"); - } - } - else - { - CONS_Alert(CONS_ERROR, "Could not load GLU Library\n"); - CONS_Alert(CONS_ERROR, "If you know what is the GLU library's name, use -GLUlib\n"); - } #endif return SetupGLfunc(); } @@ -155,6 +109,7 @@ boolean OglSdlSurface(INT32 w, INT32 h) { INT32 cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value; static boolean first_init = false; + static int majorGL = 0, minorGL = 0; oglflags = 0; @@ -189,6 +144,12 @@ boolean OglSdlSurface(INT32 w, INT32 h) else maximumAnisotropy = 1; + if (sscanf((const char*)gl_version, "%d.%d", &majorGL, &minorGL) + && (!(majorGL == 1 && minorGL <= 3))) + supportMipMap = true; + else + supportMipMap = false; + SetupGLFunc4(); glanisotropicmode_cons_t[1].value = maximumAnisotropy; diff --git a/src/sdl/ogl_sdl.h b/src/sdl/ogl_sdl.h index bd1d699ff44db27a4599bfb81d4f65e34ac7f858..87df5e5e6115334dd8705658d70f9f6e5b6706f8 100644 --- a/src/sdl/ogl_sdl.h +++ b/src/sdl/ogl_sdl.h @@ -19,8 +19,6 @@ #include "../v_video.h" -extern void *GLUhandle; - boolean OglSdlSurface(INT32 w, INT32 h); void OglSdlFinishUpdate(boolean vidwait); diff --git a/src/sounds.c b/src/sounds.c index 6b33ade2478d53b871938430523f3fb60a0f76a9..9a0e737bcc9b31a3632c473a547186dc80301001 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -284,6 +284,8 @@ static const sfxinfo_t S_startsfx[] = {"mario8", false, 48, SF_X4AWAYSOUND, -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"}, + {"mariob", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spring"}, + {"marioc", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Crumbling"}, {"thwomp", true, 127, SF_X4AWAYSOUND, -1, NULL, 0, -1, -1, LUMPERROR, "Thwomp"}, // Black Eggman diff --git a/src/sounds.h b/src/sounds.h index c8d2fd3e8781512d36b4dd236831654600165594..72ef7fb447c57e16e6348aff165bb1051135a2e1 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -329,6 +329,8 @@ typedef enum sfx_mario8, sfx_mario9, sfx_marioa, + sfx_mariob, + sfx_marioc, sfx_thwomp, // Black Eggman diff --git a/src/st_stuff.c b/src/st_stuff.c index 359ffec5f701f6f75f6e5eaa0448f279720afe7a..3dcc0b061595face958dfb81c01aaef21c2eec0a 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2068,24 +2068,25 @@ static void ST_drawNiGHTSHUD(void) if (!stplyr->exiting && !oldspecialstage && LUA_HudEnabled(hud_nightsscore)) ST_DrawNightsOverlayNum(304<<FRACBITS, 14<<FRACBITS, FRACUNIT, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTORIGHT, stplyr->marescore, nightsnum, SKINCOLOR_AZURE); - // TODO give this its own section for Lua + // TODO: give this its own section for Lua + // TODO: on multi-mare maps, show time & grade for each completed mare if (!stplyr->exiting && LUA_HudEnabled(hud_nightsscore)) { if (modeattacking == ATTACKING_NIGHTS) { INT32 maretime = max(stplyr->realtime - stplyr->marebegunat, 0); -#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); +#define VFLAGS V_SNAPTOTOP|V_SNAPTORIGHT|V_PERPLAYER|V_HUDTRANS + V_DrawScaledPatch(BASEVIDWIDTH-16, 40, VFLAGS, W_CachePatchName("NGRTIMER", PU_HUDGFX)); + V_DrawPaddedTallNum(BASEVIDWIDTH-16, 40, VFLAGS, G_TicsToCentiseconds(maretime), 2); + V_DrawScaledPatch(BASEVIDWIDTH-40, 40, VFLAGS, sboperiod); if (maretime < 60*TICRATE) - V_DrawTallNum(BASEVIDWIDTH-46, BASEVIDHEIGHT-20, VFLAGS, G_TicsToSeconds(maretime)); + V_DrawTallNum(BASEVIDWIDTH-40, 40, VFLAGS, G_TicsToSeconds(maretime)); else { - 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)); + V_DrawPaddedTallNum(BASEVIDWIDTH-40, 40, VFLAGS, G_TicsToSeconds(maretime), 2); + V_DrawScaledPatch(BASEVIDWIDTH-64, 40, VFLAGS, sbocolon); + V_DrawTallNum(BASEVIDWIDTH-64, 40, VFLAGS, G_TicsToMinutes(maretime, true)); } #undef VFLAGS } @@ -2655,7 +2656,7 @@ static boolean ST_doItemFinderIconsAndSound(void) // Scan thinkers to find emblem mobj with these ids for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + if (th->removing) continue; mo2 = (mobj_t *)th; diff --git a/src/version.h b/src/version.h index 8d8f8978e7ea3cf593247a73a9460ed139193c10..21204e01619cf9d177a56800ac81eeb6afa95a8c 100644 --- a/src/version.h +++ b/src/version.h @@ -12,4 +12,4 @@ #define MODVERSION 55 // Define this as a prerelease version suffix (pre#, RC#) -#define BETAVERSION "nightly" +//#define BETAVERSION "pre4" diff --git a/src/w_wad.c b/src/w_wad.c index 4a1d44548b75b801343cd60a81f8c80bec7bcf17..50ba622a9b32f538b18d50dcdf29fbfd457f7355 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -65,6 +65,7 @@ #include "i_video.h" // rendermode #include "md5.h" #include "lua_script.h" +#include "lua_hook.h" #ifdef SCANTHINGS #include "p_setup.h" // P_ScanThings #endif @@ -307,12 +308,10 @@ static void W_LoadDehackedLumps(UINT16 wadnum, boolean mainfile) * \param resblock resulting MD5 checksum * \return 0 if MD5 checksum was made, and is at resblock, 1 if error was found */ + +#ifndef NOMD5 static INT32 W_MakeFileMD5(const char *filename, void *resblock) { -#ifdef NOMD5 - (void)filename; - memset(resblock, 0x00, 16); -#else FILE *fhandle; if ((fhandle = fopen(filename, "rb")) != NULL) @@ -329,9 +328,9 @@ static INT32 W_MakeFileMD5(const char *filename, void *resblock) fclose(fhandle); return 0; } -#endif return 1; } +#endif // Invalidates the cache of lump numbers. Call this whenever a wad is added. static void W_InvalidateLumpnumCache(void) @@ -1011,6 +1010,10 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) break; } + lua_lumploading++; + LUA_HookVoid(HOOK(AddonLoaded)); + lua_lumploading--; + W_InvalidateLumpnumCache(); return wadfile->numlumps; } @@ -1171,6 +1174,11 @@ UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup) W_ReadFileShaders(wadfile); W_LoadTrnslateLumps(numwadfiles - 1); W_LoadDehackedLumpsPK3(numwadfiles - 1, mainfile); + + lua_lumploading++; + LUA_HookVoid(HOOK(AddonLoaded)); + lua_lumploading--; + W_InvalidateLumpnumCache(); return wadfile->numlumps; @@ -1350,17 +1358,6 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump) return i; } -// Returns 0 if the folder is not empty, 1 if it is empty, -1 if it doesn't exist -INT32 W_IsFolderEmpty(const char *name, UINT16 wad) -{ - UINT16 start = W_CheckNumForFolderStartPK3(name, wad, 0); - if (start == INT16_MAX) - return -1; - - // Unlike W_CheckNumForFolderStartPK3, W_CheckNumForFolderEndPK3 doesn't return INT16_MAX. - return W_CheckNumForFolderEndPK3(name, wad, start) <= start; -} - char *W_GetLumpFolderPathPK3(UINT16 wad, UINT16 lump) { const char *fullname = wadfiles[wad]->lumpinfo[lump].fullname; @@ -1725,10 +1722,14 @@ static UINT16 W_CheckNumForPatchNamePwad(const char *name, UINT16 wad, boolean l // TODO: cache namespace lump IDs if (W_FileHasFolders(wadfiles[wad])) { - if (!W_IsFolderEmpty("Flats/", wad)) + start = W_CheckNumForFolderStartPK3("Flats/", wad, 0); + end = W_CheckNumForFolderEndPK3("Flats/", wad, start); + + // if the start and end is the same, the folder is empty + if (end <= start) { - start = W_CheckNumForFolderStartPK3("Flats/", wad, 0); - end = W_CheckNumForFolderEndPK3("Flats/", wad, start); + start = INT16_MAX; + end = INT16_MAX; } } else diff --git a/src/w_wad.h b/src/w_wad.h index 5872ae50a98c017961cf6964ab203d71151d8f4d..84aafa3a40e2e48f662c723d5a5854138806b5b0 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -180,7 +180,6 @@ UINT16 W_CheckNumForMarkerStartPwad(const char *name, UINT16 wad, UINT16 startlu UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump); UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump); UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump); -INT32 W_IsFolderEmpty(const char *name, UINT16 wad); char *W_GetLumpFolderPathPK3(UINT16 wad, UINT16 lump); char *W_GetLumpFolderNamePK3(UINT16 wad, UINT16 lump); diff --git a/src/win32/Srb2win.rc b/src/win32/Srb2win.rc index bbe61cb17568873fa481d80e375eb1ecd8ea834f..6fba9f9a8877e65fb99c91c2e24022926857beba 100644 --- a/src/win32/Srb2win.rc +++ b/src/win32/Srb2win.rc @@ -98,7 +98,7 @@ BEGIN VALUE "FileDescription", "Sonic Robo Blast 2\0" VALUE "FileVersion", VERSIONSTRING_RC VALUE "InternalName", "srb2\0" - VALUE "LegalCopyright", "Copyright 1998-2024 by Sonic Team Junior\0" + VALUE "LegalCopyright", "Copyright 1998-2025 by Sonic Team Junior\0" VALUE "LegalTrademarks", "Sonic the Hedgehog and related characters are trademarks of Sega.\0" VALUE "OriginalFilename", "srb2win.exe\0" VALUE "PrivateBuild", "\0" diff --git a/src/y_inter.c b/src/y_inter.c index 95a08a38711330e054a00bb89dde0bf4d5bccee2..e9905f1de870d3dd49aeba817a12451ce1ffdbd3 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -109,6 +109,7 @@ typedef union UINT16 *color[MAXPLAYERS]; // Winner's color # boolean spectator[MAXPLAYERS]; // Spectator list UINT8 *character[MAXPLAYERS]; // Winner's character # + INT32 ctfteam[MAXPLAYERS]; // Winner's ctfteam # INT32 num[MAXPLAYERS]; // Winner's player # char *name[MAXPLAYERS]; // Winner's name patch_t *result; // RESULT @@ -579,9 +580,9 @@ void Y_IntermissionDrawer(void) { if (LUA_HudEnabled(hud_intermissiontitletext)) { - const char *ringtext = "\x82" "get 50 rings, then"; + const char *ringtext = "\x82" "50 rings, no shield"; const char *tut1text = "\x82" "press " "\x80" "shield"; - const char *tut2text = "\x82" "to transform"; + const char *tut2text = "\x82" "mid-" "\x80" "jump"; ttheight = 8; V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1); ttheight += V_LevelNameHeight(data.spec.passed3) + 2; @@ -849,7 +850,7 @@ void Y_IntermissionDrawer(void) { UINT8 *colormap = R_GetTranslationColormap(*data.match.character[i], *data.match.color[i], GTC_CACHE); - if (*data.match.color[i] == SKINCOLOR_RED) //red + if (data.match.ctfteam[i] == 1) //red { if (redplayers++ > 9) continue; @@ -857,7 +858,7 @@ void Y_IntermissionDrawer(void) y = (redplayers * 16) + 32; V_DrawCenteredString(x+6, y, 0, va("%d", redplayers)); } - else if (*data.match.color[i] == SKINCOLOR_BLUE) //blue + else if (data.match.ctfteam[i] == 2) //blue { if (blueplayers++ > 9) continue; @@ -1129,7 +1130,7 @@ 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("_clear", false); // don't loop it + S_ChangeMusicInternal(stagefailed ? "CHFAIL" : "CHPASS", false); // don't loop it tallydonetic = -1; } @@ -1622,6 +1623,7 @@ static void Y_CalculateMatchWinners(void) boolean completed[MAXPLAYERS]; // Initialize variables + memset(data.match.ctfteam, 0, sizeof (data.match.ctfteam)); memset(data.match.scores, 0, sizeof (data.match.scores)); memset(data.match.color, 0, sizeof (data.match.color)); memset(data.match.character, 0, sizeof (data.match.character)); @@ -1642,8 +1644,15 @@ static void Y_CalculateMatchWinners(void) if (players[i].score >= data.match.scores[data.match.numplayers] && completed[i] == false) { + data.match.ctfteam[data.match.numplayers] = players[i].ctfteam; data.match.scores[data.match.numplayers] = players[i].score; data.match.color[data.match.numplayers] = &players[i].skincolor; + if (data.match.ctfteam[data.match.numplayers] == 1) // red team + data.match.color[data.match.numplayers] = &skincolor_redteam; + + if (data.match.ctfteam[data.match.numplayers] == 2) // blue team + data.match.color[data.match.numplayers] = &skincolor_blueteam; + data.match.character[data.match.numplayers] = &players[i].skin; data.match.name[data.match.numplayers] = player_names[i]; data.match.spectator[data.match.numplayers] = players[i].spectator; diff --git a/src/z_zone.c b/src/z_zone.c index 5750f8ae016becd9c9548b690b0e7fd5b32ec7cb..0852fabaeac03f3751d33063cb14f63105678537 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -671,6 +671,7 @@ static void Command_Memfree_f(void) CONS_Printf(M_GetText("Cached textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10)); CONS_Printf(M_GetText("Texture colormaps : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10)); CONS_Printf(M_GetText("Model textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRMODELTEXTURE)>>10)); + CONS_Printf(M_GetText("Light table textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRLIGHTTABLEDATA)>>10)); CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10)); CONS_Printf(M_GetText("All GPU textures : %7d KB\n"), HWR_GetTextureUsed()>>10); } diff --git a/src/z_zone.h b/src/z_zone.h index ce7af4a159555e3a6c2be83e8d0eadcf8a7a69eb..56c540c3bb31a4a84e5f2403519455f3830583ee 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -55,6 +55,7 @@ enum PU_HWRPATCHINFO = 21, // Hardware GLPatch_t struct for OpenGL texture cache PU_HWRPATCHCOLMIPMAP = 22, // Hardware GLMipmap_t struct colormap variation of patch PU_HWRMODELTEXTURE = 23, // Hardware model texture + PU_HWRLIGHTTABLEDATA = 24, // Hardware light table data PU_HWRCACHE = 48, // static until unlocked PU_CACHE = 49, // static until unlocked