diff --git a/CMakeLists.txt b/CMakeLists.txt index 51f98707d..1e80b549e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) # DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string. # Version change is fine. project(SRB2 - VERSION 1.2 + VERSION 1.3 LANGUAGES C) if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) diff --git a/appveyor.yml b/appveyor.yml index 4ad24ee05..7e87c271c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 1.2.{branch}-{build} +version: 1.3.{branch}-{build} os: MinGW environment: @@ -29,7 +29,7 @@ environment: ############################## DPL_ENABLED: 0 DPL_TAG_ENABLED: 0 - DPL_INSTALLER_NAME: srb2kart-v12 + DPL_INSTALLER_NAME: srb2kart-v13 # Asset handling is barebones vs. Travis Deployer. We operate on 7z only. # Include the README files and the OpenGL batch in the main and patch archives. # The x86/x64 archives contain the DLL binaries. diff --git a/cmake/Modules/FindDiscordRPC.cmake b/cmake/Modules/FindDiscordRPC.cmake new file mode 100644 index 000000000..e71762767 --- /dev/null +++ b/cmake/Modules/FindDiscordRPC.cmake @@ -0,0 +1,23 @@ +include(LibFindMacros) + +libfind_pkg_check_modules(DISCORDRPC_PKGCONF DISCORDRPC) + +find_path(DISCORDRPC_INCLUDE_DIR + NAMES discord_rpc.h + PATHS + ${DISCORDRPC_PKGCONF_INCLUDE_DIRS} + "/usr/include" + "/usr/local/include" +) + +find_library(DISCORDRPC_LIBRARY + NAMES discord-rpc + PATHS + ${DISCORDRPC_PKGCONF_LIBRARY_DIRS} + "/usr/lib" + "/usr/local/lib" +) + +set(DISCORDRPC_PROCESS_INCLUDES DISCORDRPC_INCLUDE_DIR) +set(DISCORDRPC_PROCESS_LIBS DISCORDRPC_LIBRARY) +libfind_process(DISCORDRPC) diff --git a/debian-template/source/options b/debian-template/source/options index 7829e2976..9532ff202 100644 --- a/debian-template/source/options +++ b/debian-template/source/options @@ -2,10 +2,7 @@ tar-ignore = "assets/*.srb" tar-ignore = "assets/*.pk3" tar-ignore = "assets/*.dta" tar-ignore = "assets/*.wad" -<<<<<<< HEAD:debian-template/source/options tar-ignore = "assets/*.kart" -======= ->>>>>>> e251f9c230beda984cdcdea7e903d765f1c68f6f:debian-template/source/options tar-ignore = "assets/debian/${PACKAGE_NAME}-data/*" tar-ignore = "assets/debian/tmp/*" tar-ignore = "*.obj" diff --git a/libs/DLL-README.txt b/libs/DLL-README.txt index 06fae1278..bbb6d3cd4 100644 --- a/libs/DLL-README.txt +++ b/libs/DLL-README.txt @@ -1,6 +1,6 @@ # SRB2Kart - Which DLLs do I need to bundle? -Updated 12/4/2018 (v2.1.21) +Updated 8/23/2020 (v1.3) Here are the required DLLs, per build. For each architecture, copy all the binaries from these folders: @@ -14,6 +14,7 @@ and don't forget to build r_opengl.dll for srb2dd. * libs\dll-binaries\i686\exchndl.dll * libs\dll-binaries\i686\libgme.dll +* libs\dll-binaries\i686\discord-rpc.dll * libs\dll-binaries\i686\mgwhelp.dll (depend for exchndl.dll) * libs\SDL2\i686-w64-mingw32\bin\SDL2.dll * libs\SDL2_mixer\i686-w64-mingw32\bin\*.dll (get everything) @@ -22,22 +23,7 @@ and don't forget to build r_opengl.dll for srb2dd. * libs\dll-binaries\x86_64\exchndl.dll * libs\dll-binaries\x86_64\libgme.dll +* libs\dll-binaries\x86_64\discord-rpc.dll * libs\dll-binaries\x86_64\mgwhelp.dll (depend for exchndl.dll) * libs\SDL2\x86_64-w64-mingw32\bin\SDL2.dll * libs\SDL2_mixer\x86_64-w64-mingw32\bin\*.dll (get everything) - -## srb2kartdd, 32-bit - -* libs\dll-binaries\i686\exchndl.dll -* libs\dll-binaries\i686\fmodex.dll -* libs\dll-binaries\i686\libgme.dll -* libs\dll-binaries\i686\mgwhelp.dll (depend for exchndl.dll) -* r_opengl.dll (build this from make) - -## srb2kartdd, 64-bit - -* libs\dll-binaries\x86_64\exchndl.dll -* libs\dll-binaries\x86_64\fmodex.dll -* libs\dll-binaries\x86_64\libgme.dll -* libs\dll-binaries\x86_64\mgwhelp.dll (depend for exchndl.dll) -* r_opengl.dll (build this from make) diff --git a/libs/discord-rpc.props b/libs/discord-rpc.props new file mode 100644 index 000000000..83c7a03f3 --- /dev/null +++ b/libs/discord-rpc.props @@ -0,0 +1,16 @@ + + + + + $(SolutionDir)libs\discord-rpc\win32-dynamic\lib;$(LibraryPath) + $(SolutionDir)libs\discord-rpc\win32-dynamic\lib;$(IncludePath) + $(SolutionDir)libs\discord-rpc\win64-dynamic\lib;$(LibraryPath) + $(SolutionDir)libs\discord-rpc\win64-dynamic\lib;$(IncludePath) + + + + discord-rpc.dll.a;%(AdditionalDependencies) + + + + \ No newline at end of file diff --git a/libs/discord-rpc/win32-dynamic/include/discord_register.h b/libs/discord-rpc/win32-dynamic/include/discord_register.h new file mode 100644 index 000000000..16fb42f32 --- /dev/null +++ b/libs/discord-rpc/win32-dynamic/include/discord_register.h @@ -0,0 +1,26 @@ +#pragma once + +#if defined(DISCORD_DYNAMIC_LIB) +#if defined(_WIN32) +#if defined(DISCORD_BUILDING_SDK) +#define DISCORD_EXPORT __declspec(dllexport) +#else +#define DISCORD_EXPORT __declspec(dllimport) +#endif +#else +#define DISCORD_EXPORT __attribute__((visibility("default"))) +#endif +#else +#define DISCORD_EXPORT +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command); +DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, const char* steamId); + +#ifdef __cplusplus +} +#endif diff --git a/libs/discord-rpc/win32-dynamic/include/discord_rpc.h b/libs/discord-rpc/win32-dynamic/include/discord_rpc.h new file mode 100644 index 000000000..3e1441e05 --- /dev/null +++ b/libs/discord-rpc/win32-dynamic/include/discord_rpc.h @@ -0,0 +1,87 @@ +#pragma once +#include + +// clang-format off + +#if defined(DISCORD_DYNAMIC_LIB) +# if defined(_WIN32) +# if defined(DISCORD_BUILDING_SDK) +# define DISCORD_EXPORT __declspec(dllexport) +# else +# define DISCORD_EXPORT __declspec(dllimport) +# endif +# else +# define DISCORD_EXPORT __attribute__((visibility("default"))) +# endif +#else +# define DISCORD_EXPORT +#endif + +// clang-format on + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DiscordRichPresence { + const char* state; /* max 128 bytes */ + const char* details; /* max 128 bytes */ + int64_t startTimestamp; + int64_t endTimestamp; + const char* largeImageKey; /* max 32 bytes */ + const char* largeImageText; /* max 128 bytes */ + const char* smallImageKey; /* max 32 bytes */ + const char* smallImageText; /* max 128 bytes */ + const char* partyId; /* max 128 bytes */ + int partySize; + int partyMax; + const char* matchSecret; /* max 128 bytes */ + const char* joinSecret; /* max 128 bytes */ + const char* spectateSecret; /* max 128 bytes */ + int8_t instance; +} DiscordRichPresence; + +typedef struct DiscordUser { + const char* userId; + const char* username; + const char* discriminator; + const char* avatar; +} DiscordUser; + +typedef struct DiscordEventHandlers { + void (*ready)(const DiscordUser* request); + void (*disconnected)(int errorCode, const char* message); + void (*errored)(int errorCode, const char* message); + void (*joinGame)(const char* joinSecret); + void (*spectateGame)(const char* spectateSecret); + void (*joinRequest)(const DiscordUser* request); +} DiscordEventHandlers; + +#define DISCORD_REPLY_NO 0 +#define DISCORD_REPLY_YES 1 +#define DISCORD_REPLY_IGNORE 2 + +DISCORD_EXPORT void Discord_Initialize(const char* applicationId, + DiscordEventHandlers* handlers, + int autoRegister, + const char* optionalSteamId); +DISCORD_EXPORT void Discord_Shutdown(void); + +/* checks for incoming messages, dispatches callbacks */ +DISCORD_EXPORT void Discord_RunCallbacks(void); + +/* If you disable the lib starting its own io thread, you'll need to call this from your own */ +#ifdef DISCORD_DISABLE_IO_THREAD +DISCORD_EXPORT void Discord_UpdateConnection(void); +#endif + +DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence); +DISCORD_EXPORT void Discord_ClearPresence(void); + +DISCORD_EXPORT void Discord_Respond(const char* userid, /* DISCORD_REPLY_ */ int reply); + +DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* handlers); + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/libs/discord-rpc/win32-dynamic/lib/discord-rpc.lib b/libs/discord-rpc/win32-dynamic/lib/discord-rpc.lib new file mode 100644 index 000000000..d8b6689f3 Binary files /dev/null and b/libs/discord-rpc/win32-dynamic/lib/discord-rpc.lib differ diff --git a/libs/discord-rpc/win64-dynamic/include/discord_register.h b/libs/discord-rpc/win64-dynamic/include/discord_register.h new file mode 100644 index 000000000..16fb42f32 --- /dev/null +++ b/libs/discord-rpc/win64-dynamic/include/discord_register.h @@ -0,0 +1,26 @@ +#pragma once + +#if defined(DISCORD_DYNAMIC_LIB) +#if defined(_WIN32) +#if defined(DISCORD_BUILDING_SDK) +#define DISCORD_EXPORT __declspec(dllexport) +#else +#define DISCORD_EXPORT __declspec(dllimport) +#endif +#else +#define DISCORD_EXPORT __attribute__((visibility("default"))) +#endif +#else +#define DISCORD_EXPORT +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command); +DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, const char* steamId); + +#ifdef __cplusplus +} +#endif diff --git a/libs/discord-rpc/win64-dynamic/include/discord_rpc.h b/libs/discord-rpc/win64-dynamic/include/discord_rpc.h new file mode 100644 index 000000000..3e1441e05 --- /dev/null +++ b/libs/discord-rpc/win64-dynamic/include/discord_rpc.h @@ -0,0 +1,87 @@ +#pragma once +#include + +// clang-format off + +#if defined(DISCORD_DYNAMIC_LIB) +# if defined(_WIN32) +# if defined(DISCORD_BUILDING_SDK) +# define DISCORD_EXPORT __declspec(dllexport) +# else +# define DISCORD_EXPORT __declspec(dllimport) +# endif +# else +# define DISCORD_EXPORT __attribute__((visibility("default"))) +# endif +#else +# define DISCORD_EXPORT +#endif + +// clang-format on + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DiscordRichPresence { + const char* state; /* max 128 bytes */ + const char* details; /* max 128 bytes */ + int64_t startTimestamp; + int64_t endTimestamp; + const char* largeImageKey; /* max 32 bytes */ + const char* largeImageText; /* max 128 bytes */ + const char* smallImageKey; /* max 32 bytes */ + const char* smallImageText; /* max 128 bytes */ + const char* partyId; /* max 128 bytes */ + int partySize; + int partyMax; + const char* matchSecret; /* max 128 bytes */ + const char* joinSecret; /* max 128 bytes */ + const char* spectateSecret; /* max 128 bytes */ + int8_t instance; +} DiscordRichPresence; + +typedef struct DiscordUser { + const char* userId; + const char* username; + const char* discriminator; + const char* avatar; +} DiscordUser; + +typedef struct DiscordEventHandlers { + void (*ready)(const DiscordUser* request); + void (*disconnected)(int errorCode, const char* message); + void (*errored)(int errorCode, const char* message); + void (*joinGame)(const char* joinSecret); + void (*spectateGame)(const char* spectateSecret); + void (*joinRequest)(const DiscordUser* request); +} DiscordEventHandlers; + +#define DISCORD_REPLY_NO 0 +#define DISCORD_REPLY_YES 1 +#define DISCORD_REPLY_IGNORE 2 + +DISCORD_EXPORT void Discord_Initialize(const char* applicationId, + DiscordEventHandlers* handlers, + int autoRegister, + const char* optionalSteamId); +DISCORD_EXPORT void Discord_Shutdown(void); + +/* checks for incoming messages, dispatches callbacks */ +DISCORD_EXPORT void Discord_RunCallbacks(void); + +/* If you disable the lib starting its own io thread, you'll need to call this from your own */ +#ifdef DISCORD_DISABLE_IO_THREAD +DISCORD_EXPORT void Discord_UpdateConnection(void); +#endif + +DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence); +DISCORD_EXPORT void Discord_ClearPresence(void); + +DISCORD_EXPORT void Discord_Respond(const char* userid, /* DISCORD_REPLY_ */ int reply); + +DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* handlers); + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/libs/discord-rpc/win64-dynamic/lib/discord-rpc.lib b/libs/discord-rpc/win64-dynamic/lib/discord-rpc.lib new file mode 100644 index 000000000..fcd009d82 Binary files /dev/null and b/libs/discord-rpc/win64-dynamic/lib/discord-rpc.lib differ diff --git a/libs/dll-binaries/i686/discord-rpc.dll b/libs/dll-binaries/i686/discord-rpc.dll new file mode 100644 index 000000000..88c7d0cef Binary files /dev/null and b/libs/dll-binaries/i686/discord-rpc.dll differ diff --git a/libs/dll-binaries/x86_64/discord-rpc.dll b/libs/dll-binaries/x86_64/discord-rpc.dll new file mode 100644 index 000000000..8493c5490 Binary files /dev/null and b/libs/dll-binaries/x86_64/discord-rpc.dll differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c0d673a6f..c43464b78 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -35,6 +35,7 @@ set(SRB2_CORE_SOURCES m_random.c md5.c mserv.c + http-mserv.c s_sound.c screen.c sounds.c @@ -220,6 +221,8 @@ set(SRB2_CONFIG_HAVE_ZLIB ON CACHE BOOL "Enable zlib support.") set(SRB2_CONFIG_HAVE_GME ON CACHE BOOL "Enable GME support.") +set(SRB2_CONFIG_HAVE_DISCORDRPC OFF CACHE BOOL + "Enable Discord rich presence support.") set(SRB2_CONFIG_HAVE_CURL ON CACHE BOOL "Enable curl support, used for downloading files via HTTP.") set(SRB2_CONFIG_HWRENDER ON CACHE BOOL @@ -234,7 +237,7 @@ set(SRB2_CONFIG_STATIC_OPENGL OFF CACHE BOOL ### use internal libraries? if(${CMAKE_SYSTEM} MATCHES "Windows") ###set on Windows only set(SRB2_CONFIG_USE_INTERNAL_LIBRARIES OFF CACHE BOOL - "Use SRB2's internal copies of required dependencies (SDL2, PNG, zlib, GME).") + "Use SRB2Kart's internal copies of required dependencies (SDL2, PNG, zlib, GME).") endif() if(${SRB2_CONFIG_HAVE_BLUA}) @@ -277,6 +280,7 @@ if(${SRB2_CONFIG_HAVE_BLUA}) blua/lfunc.c blua/lgc.c blua/linit.c + blua/liolib.c blua/llex.c blua/lmem.c blua/lobject.c @@ -328,7 +332,7 @@ if(${SRB2_CONFIG_HAVE_GME}) if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES}) set(GME_FOUND ON) set(GME_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/gme/include) - if(${SRB2_SYSTEM_BITS} EQUAL 64) + if(${SRB2_SYSTEM_BITS} EQUAL 64) set(GME_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/gme/win64 -lgme") else() # 32-bit set(GME_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/gme/win32 -lgme") @@ -344,6 +348,32 @@ if(${SRB2_CONFIG_HAVE_GME}) endif() endif() +if(${SRB2_CONFIG_HAVE_DISCORDRPC}) + if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES}) + set(DISCORDRPC_FOUND ON) + if(${SRB2_SYSTEM_BITS} EQUAL 64) + set(DISCORDRPC_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/discord-rpc/win64-dynamic/include) + set(DISCORDRPC_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/discord-rpc/win64-dynamic/lib -ldiscord-rpc") + else() # 32-bit + set(DISCORDRPC_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/discord-rpc/win32-dynamic/include) + set(DISCORDRPC_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/discord-rpc/win32-dynamic/lib -ldiscord-rpc") + endif() + else() + find_package(DiscordRPC) + endif() + if(${DISCORDRPC_FOUND}) + set(SRB2_HAVE_DISCORDRPC ON) + add_definitions(-DHAVE_DISCORDRPC) + set(SRB2_DISCORDRPC_SOURCES discord.c) + set(SRB2_DISCORDRPC_HEADERS discord.h) + prepend_sources(SRB2_DISCORDRPC_SOURCES) + prepend_sources(SRB2_DISCORDRPC_HEADERS) + source_group("Discord Rich Presence" FILES ${SRB2_DISCORDRPC_SOURCES} ${SRB2_DISCORDRPC_HEADERS}) + else() + message(WARNING "You have specified that Discord Rich Presence is available but it was not found.") + endif() +endif() + if(${SRB2_CONFIG_HAVE_ZLIB}) if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES}) set(ZLIB_FOUND ON) @@ -396,7 +426,7 @@ endif() if(${SRB2_CONFIG_HAVE_CURL}) if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES}) set(CURL_FOUND ON) - set(CURL_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/curl) + set(CURL_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/curl/include) if(${SRB2_SYSTEM_BITS} EQUAL 64) set(CURL_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/curl/lib64 -lcurl") else() # 32-bit diff --git a/src/Makefile b/src/Makefile index 8eda8c400..fb859a339 100644 --- a/src/Makefile +++ b/src/Makefile @@ -60,10 +60,10 @@ # Compile with GCC 4.6x version, add 'GCC46=1' # Compile a profile version, add 'PROFILEMODE=1' # Compile a debug version, add 'DEBUGMODE=1' -# Compile with extra warnings, add 'WARNINGMODE=1' +# Compile with less warnings, add 'RELAXWARNINGS=1' +# Generate compiler errors for most compiler warnings, add 'ERRORMODE=1' # Compile without NASM's tmap.nas, add 'NOASM=1' # Compile without 3D hardware support, add 'NOHW=1' -# Compile without 3D sound support, add 'NOHS=1' # Compile with GDBstubs, add 'RDB=1' # Compile without PNG, add 'NOPNG=1' # Compile without zlib, add 'NOZLIB=1' @@ -81,6 +81,58 @@ # ############################################################################# +ALL_SYSTEMS=\ + PANDORA\ + LINUX64\ + MINGW64\ + HAIKU\ + DUMMY\ + DJGPPDOS\ + MINGW\ + UNIX\ + LINUX\ + SOLARIS\ + FREEBSD\ + MACOSX\ + SDL\ + +# check for user specified system +ifeq (,$(filter $(ALL_SYSTEMS),$(.VARIABLES))) +ifeq ($(OS),Windows_NT) # all windows are Windows_NT... + + $(info Detected a Windows system, compiling for 32-bit MinGW SDL2...) + + # go for a 32-bit sdl mingw exe by default + MINGW=1 + SDL=1 + WINDOWSHELL=1 + +else # if you on the *nix + + system:=$(shell uname -s) + + ifeq ($(system),Linux) + new_system=LINUX + else + + $(error \ + Could not automatically detect your system,\ + try specifying a system manually) + + endif + + ifeq ($(shell getconf LONG_BIT),64) + system+=64-bit + new_system:=$(new_system)64 + endif + + $(info Detected $(system) ($(new_system))...) + $(new_system)=1 + +endif +endif + + # SRB2 data files D_DIR?=../bin/Resources D_FILES=$(D_DIR)/srb2.srb \ @@ -136,7 +188,6 @@ NOPNG=1 NOZLIB=1 NONET=1 NOHW=1 -NOHS=1 NOASM=1 NOIPX=1 EXENAME?=srb2dummy @@ -167,7 +218,6 @@ endif ifdef PANDORA NONX86=1 NOHW=1 -NOHS=1 endif ifdef WII @@ -217,7 +267,6 @@ NOPNG=1 NOZLIB=1 NONET=1 #NOHW=1 -NOHS=1 NOASM=1 NOIPX=1 NONX86=1 @@ -287,13 +336,6 @@ endif $(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o endif -ifdef NOHS - OPTS+=-DNOHS -else - OPTS+=-DHW3SOUND - OBJS+=$(OBJDIR)/hw3sound.o -endif - OPTS += -DCOMPVERSION ifndef NONX86 @@ -396,6 +438,12 @@ CFLAGS+=-DHAVE_MINIUPNPC endif endif +ifdef HAVE_DISCORDRPC +LIBS+=-ldiscord-rpc +CFLAGS+=-DHAVE_DISCORDRPC +OBJS+=$(OBJDIR)/discord.o +endif + ifndef NO_LUA include blua/Makefile.cfg endif @@ -548,6 +596,7 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/w_wad.o \ $(OBJDIR)/filesrch.o \ $(OBJDIR)/mserv.o \ + $(OBJDIR)/http-mserv.o\ $(OBJDIR)/i_tcp.o \ $(OBJDIR)/lzf.o \ $(OBJDIR)/vid_copy.o \ @@ -941,19 +990,6 @@ $(OBJDIR)/r_minigl.o: hardware/r_minigl/r_minigl.c hardware/r_opengl/r_opengl.h $(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@ endif -ifndef NOHS -$(OBJDIR)/s_ds3d.o: hardware/s_ds3d/s_ds3d.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_ds3d.o $(WFLAGS) -D_WINDOWS -mwindows -c hardware/s_ds3d/s_ds3d.c - -$(OBJDIR)/s_fmod.o: hardware/s_openal/s_openal.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_fmod.o $(WFLAGS) -D_WINDOWS -mwindows -c hardware/s_fmod/s_fmod.c - -$(OBJDIR)/s_openal.o: hardware/s_openal/s_openal.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_openal.o $(WFLAGS) -D_WINDOWS -mwindows -c hardware/s_openal/s_openal.c -endif endif endif diff --git a/src/Makefile.cfg b/src/Makefile.cfg index a3baeedda..e45265cab 100644 --- a/src/Makefile.cfg +++ b/src/Makefile.cfg @@ -1,3 +1,4 @@ +# vim: ft=make # # Makefile.cfg for SRB2 # @@ -7,7 +8,90 @@ # and other things # +# See the following variable don't start with 'GCC'. This is +# to avoid a false positive with the version detection... + +SUPPORTED_GCC_VERSIONS:=\ + 101 102\ + 91 92 93\ + 81 82 83 84\ + 71 72 73 74 75\ + 61 62 63 64\ + 51 52 53 54 55\ + 40 41 42 43 44 45 46 47 48 49 + +LATEST_GCC_VERSION=10.2 + +# gcc or g++ +ifdef PREFIX + CC=$(PREFIX)-gcc + CXX=$(PREFIX)-g++ + OBJCOPY=$(PREFIX)-objcopy + OBJDUMP=$(PREFIX)-objdump + STRIP=$(PREFIX)-strip + WINDRES=$(PREFIX)-windres +else + OBJCOPY=objcopy + OBJDUMP=objdump + STRIP=strip + WINDRES=windres +endif + +# because Apple screws with us on this +# need to get bintools from homebrew +ifdef MACOSX + CC=clang + CXX=clang + OBJCOPY=gobjcopy + OBJDUMP=gobjdump +endif + +# Automatically set version flag, but not if one was manually set +ifeq (,$(filter GCC%,$(.VARIABLES))) + version:=$(shell $(CC) --version) + # check if this is in fact GCC + ifneq (,$(or $(findstring gcc,$(version)),$(findstring GCC,$(version)))) + version:=$(shell $(CC) -dumpversion) + + # Turn version into words of major, minor + v:=$(subst ., ,$(version)) + # concat. major minor + v:=$(word 1,$(v))$(word 2,$(v)) + + # If this version is not in the list, default to the latest supported + ifeq (,$(filter $(v),$(SUPPORTED_GCC_VERSIONS))) + $(info\ + Your compiler version, GCC $(version), is not supported by the Makefile.\ + The Makefile will assume GCC $(LATEST_GCC_VERSION).) + GCC$(subst .,,$(LATEST_GCC_VERSION))=1 + else + $(info Detected GCC $(version) (GCC$(v))) + GCC$(v)=1 + endif + endif +endif + +ifdef GCC102 +GCC101=1 +endif + +ifdef GCC101 +GCC93=1 +endif + +ifdef GCC93 +GCC92=1 +endif + +ifdef GCC92 +GCC91=1 +endif + ifdef GCC91 +GCC84=1 +endif + +ifdef GCC84 GCC83=1 endif @@ -20,6 +104,18 @@ GCC81=1 endif ifdef GCC81 +GCC75=1 +endif + +ifdef GCC75 +GCC74=1 +endif + +ifdef GCC74 +GCC73=1 +endif + +ifdef GCC73 GCC72=1 endif @@ -44,6 +140,10 @@ GCC61=1 endif ifdef GCC61 +GCC55=1 +endif + +ifdef GCC55 GCC54=1 endif @@ -114,10 +214,7 @@ WFLAGS=-Wall ifndef GCC295 #WFLAGS+=-Wno-packed endif -ifdef ERRORMODE -WARNINGMODE=1 -endif -ifdef WARNINGMODE +ifndef RELAXWARNINGS WFLAGS+=-W #WFLAGS+=-Wno-sign-compare ifndef GCC295 @@ -463,30 +560,6 @@ ifdef ARCHNAME BIN:=$(BIN)/$(ARCHNAME) endif -# gcc or g++ -ifdef PREFIX - CC=$(PREFIX)-gcc - CXX=$(PREFIX)-g++ - OBJCOPY=$(PREFIX)-objcopy - OBJDUMP=$(PREFIX)-objdump - STRIP=$(PREFIX)-strip - WINDRES=$(PREFIX)-windres -else - OBJCOPY=objcopy - OBJDUMP=objdump - STRIP=strip - WINDRES=windres -endif - -# because Apple screws with us on this -# need to get bintools from homebrew -ifdef MACOSX - CC=clang - CXX=clang - OBJCOPY=gobjcopy - OBJDUMP=gobjdump -endif - OBJDUMP_OPTS?=--wide --source --line-numbers LD=$(CC) diff --git a/src/am_map.c b/src/am_map.c index 5e73d2ec4..91c68233c 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -862,10 +862,8 @@ static inline void AM_drawWalls(void) { size_t i; static mline_t l; -#ifdef ESLOPE fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends fixed_t backf1 = 0, backf2 = 0, backc1 = 0, backc2 = 0; // back floor ceiling ends -#endif for (i = 0; i < numlines; i++) { @@ -873,7 +871,6 @@ static inline void AM_drawWalls(void) l.a.y = lines[i].v1->y >> FRACTOMAPBITS; l.b.x = lines[i].v2->x >> FRACTOMAPBITS; l.b.y = lines[i].v2->y >> FRACTOMAPBITS; -#ifdef ESLOPE #define SLOPEPARAMS(slope, end1, end2, normalheight) \ if (slope) { \ end1 = P_GetZAt(slope, lines[i].v1->x, lines[i].v1->y); \ @@ -888,7 +885,6 @@ static inline void AM_drawWalls(void) SLOPEPARAMS(lines[i].backsector->c_slope, backc1, backc2, lines[i].backsector->ceilingheight) } #undef SLOPEPARAMS -#endif if (!lines[i].backsector) // 1-sided { @@ -897,19 +893,11 @@ static inline void AM_drawWalls(void) else AM_drawMline(&l, WALLCOLORS); } -#ifdef ESLOPE else if ((backf1 == backc1 && backf2 == backc2) // Back is thok barrier || (frontf1 == frontc1 && frontf2 == frontc2)) // Front is thok barrier { if (backf1 == backc1 && backf2 == backc2 && frontf1 == frontc1 && frontf2 == frontc2) // BOTH are thok barriers -#else - else if (lines[i].backsector->floorheight == lines[i].backsector->ceilingheight // Back is thok barrier - || lines[i].frontsector->floorheight == lines[i].frontsector->ceilingheight) // Front is thok barrier - { - if (lines[i].backsector->floorheight == lines[i].backsector->ceilingheight - && lines[i].frontsector->floorheight == lines[i].frontsector->ceilingheight) // BOTH are thok barriers -#endif { if (lines[i].flags & ML_NOCLIMB) AM_drawMline(&l, NOCLIMBTSWALLCOLORS); @@ -927,20 +915,10 @@ static inline void AM_drawWalls(void) else { if (lines[i].flags & ML_NOCLIMB) { -#ifdef ESLOPE if (backf1 != frontf1 || backf2 != frontf2) { -#else - if (lines[i].backsector->floorheight - != lines[i].frontsector->floorheight) { -#endif AM_drawMline(&l, NOCLIMBFDWALLCOLORS); // floor level change } -#ifdef ESLOPE else if (backc1 != frontc1 || backc2 != frontc2) { -#else - else if (lines[i].backsector->ceilingheight - != lines[i].frontsector->ceilingheight) { -#endif AM_drawMline(&l, NOCLIMBCDWALLCOLORS); // ceiling level change } else @@ -948,20 +926,10 @@ static inline void AM_drawWalls(void) } else { -#ifdef ESLOPE if (backf1 != frontf1 || backf2 != frontf2) { -#else - if (lines[i].backsector->floorheight - != lines[i].frontsector->floorheight) { -#endif AM_drawMline(&l, FDWALLCOLORS); // floor level change } -#ifdef ESLOPE else if (backc1 != frontc1 || backc2 != frontc2) { -#else - else if (lines[i].backsector->ceilingheight - != lines[i].frontsector->ceilingheight) { -#endif AM_drawMline(&l, CDWALLCOLORS); // ceiling level change } else diff --git a/src/blua/Makefile.cfg b/src/blua/Makefile.cfg index b1131eaca..2ed5a5355 100644 --- a/src/blua/Makefile.cfg +++ b/src/blua/Makefile.cfg @@ -18,6 +18,7 @@ OBJS:=$(OBJS) \ $(OBJDIR)/ldo.o \ $(OBJDIR)/lfunc.o \ $(OBJDIR)/linit.o \ + $(OBJDIR)/liolib.o \ $(OBJDIR)/llex.o \ $(OBJDIR)/lmem.o \ $(OBJDIR)/lobject.o \ diff --git a/src/blua/linit.c b/src/blua/linit.c index 52b02dbe7..d17390b20 100644 --- a/src/blua/linit.c +++ b/src/blua/linit.c @@ -17,6 +17,7 @@ static const luaL_Reg lualibs[] = { {"", luaopen_base}, {LUA_TABLIBNAME, luaopen_table}, + {LUA_IOLIBNAME, luaopen_io}, {LUA_STRLIBNAME, luaopen_string}, {NULL, NULL} }; diff --git a/src/blua/liolib.c b/src/blua/liolib.c new file mode 100644 index 000000000..a9e71f74a --- /dev/null +++ b/src/blua/liolib.c @@ -0,0 +1,589 @@ +/* +** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $ +** Standard I/O (and system) library +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include + +#define liolib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" +#include "../i_system.h" +#include "../doomdef.h" +#include "../m_misc.h" + + + +#define IO_INPUT 1 +#define IO_OUTPUT 2 + +#define FILELIMIT 1024*1024 // Size limit for reading/writing files + + +static const char *const fnames[] = {"input", "output"}; +static const char *whitelist[] = { // Allow scripters to write files of these types to SRB2's folder + ".txt", + ".sav2", + ".cfg", + ".png", + ".bmp" +}; + + +static int pushresult (lua_State *L, int i, const char *filename) { + int en = errno; /* calls to Lua API may change this value */ + if (i) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushnil(L); + if (filename) + lua_pushfstring(L, "%s: %s", filename, strerror(en)); + else + lua_pushfstring(L, "%s", strerror(en)); + lua_pushinteger(L, en); + return 3; + } +} + + +static void fileerror (lua_State *L, int arg, const char *filename) { + lua_pushfstring(L, "%s: %s", filename, strerror(errno)); + luaL_argerror(L, arg, lua_tostring(L, -1)); +} + + +#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE)) + + +static int io_type (lua_State *L) { + void *ud; + luaL_checkany(L, 1); + ud = lua_touserdata(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); + if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1)) + lua_pushnil(L); /* not a file */ + else if (*((FILE **)ud) == NULL) + lua_pushliteral(L, "closed file"); + else + lua_pushliteral(L, "file"); + return 1; +} + + +static FILE *tofile (lua_State *L) { + FILE **f = tofilep(L); + if (*f == NULL) + luaL_error(L, "attempt to use a closed file"); + return *f; +} + + + +/* +** When creating file handles, always creates a `closed' file handle +** before opening the actual file; so, if there is a memory error, the +** file is not left opened. +*/ +static FILE **newfile (lua_State *L) { + FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); + *pf = NULL; /* file handle is currently `closed' */ + luaL_getmetatable(L, LUA_FILEHANDLE); + lua_setmetatable(L, -2); + return pf; +} + + +/* +** function to (not) close the standard files stdin, stdout, and stderr +*/ +static int io_noclose (lua_State *L) { + lua_pushnil(L); + lua_pushliteral(L, "cannot close standard file"); + return 2; +} + + +/* +** function to close regular files +*/ +static int io_fclose (lua_State *L) { + FILE **p = tofilep(L); + int ok = (fclose(*p) == 0); + *p = NULL; + return pushresult(L, ok, NULL); +} + + +static int aux_close (lua_State *L) { + lua_getfenv(L, 1); + lua_getfield(L, -1, "__close"); + return (lua_tocfunction(L, -1))(L); +} + + +static int io_close (lua_State *L) { + if (lua_isnone(L, 1)) + lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT); + tofile(L); /* make sure argument is a file */ + return aux_close(L); +} + + +static int io_gc (lua_State *L) { + FILE *f = *tofilep(L); + /* ignore closed files */ + if (f != NULL) + aux_close(L); + return 0; +} + + +static int io_tostring (lua_State *L) { + FILE *f = *tofilep(L); + if (f == NULL) + lua_pushliteral(L, "file (closed)"); + else + lua_pushfstring(L, "file (%p)", f); + return 1; +} + +static int StartsWith(const char *a, const char *b) // this is wolfs being lazy yet again +{ + if(strncmp(a, b, strlen(b)) == 0) return 1; + return 0; +} + + +static int io_open (lua_State *L) { + FILE **pf; + const char *filename = luaL_checkstring(L, 1); + int pass = 0; + size_t i; + int length = strlen(filename); + char *splitter, *forward, *backward; + char *destFilename; + const char *mode = luaL_optstring(L, 2, "r"); + + for (i = 0; i < (sizeof (whitelist) / sizeof(const char *)); i++) + { + if (!stricmp(&filename[length - strlen(whitelist[i])], whitelist[i])) + { + pass = 1; + break; + } + } + if (strstr(filename, "..") || strchr(filename, ':') || StartsWith(filename, "\\") + || StartsWith(filename, "/") || !pass) + { + luaL_error(L,"access denied to %s", filename); + return pushresult(L,0,filename); + } + + destFilename = va("luafiles"PATHSEP"%s", filename); + + // Make directories as needed + splitter = destFilename; + + forward = strchr(splitter, '/'); + backward = strchr(splitter, '\\'); + while ((splitter = (forward && backward) ? min(forward, backward) : (forward ?: backward))) + { + *splitter = 0; + I_mkdir(destFilename, 0755); + *splitter = '/'; + splitter++; + + forward = strchr(splitter, '/'); + backward = strchr(splitter, '\\'); + } + + pf = newfile(L); + *pf = fopen(destFilename, mode); + return (*pf == NULL) ? pushresult(L, 0, filename) : 1; +} + + +static int io_tmpfile (lua_State *L) { + FILE **pf = newfile(L); + *pf = tmpfile(); + return (*pf == NULL) ? pushresult(L, 0, NULL) : 1; +} + + +static FILE *getiofile (lua_State *L, int findex) { + FILE *f; + lua_rawgeti(L, LUA_ENVIRONINDEX, findex); + f = *(FILE **)lua_touserdata(L, -1); + if (f == NULL) + luaL_error(L, "standard %s file is closed", fnames[findex - 1]); + return f; +} + + +static int g_iofile (lua_State *L, int f, const char *mode) { + if (!lua_isnoneornil(L, 1)) { + const char *filename = lua_tostring(L, 1); + if (filename) { + FILE **pf = newfile(L); + *pf = fopen(filename, mode); + if (*pf == NULL) + fileerror(L, 1, filename); + } + else { + tofile(L); /* check that it's a valid file handle */ + lua_pushvalue(L, 1); + } + lua_rawseti(L, LUA_ENVIRONINDEX, f); + } + /* return current value */ + lua_rawgeti(L, LUA_ENVIRONINDEX, f); + return 1; +} + + +static int io_input (lua_State *L) { + return g_iofile(L, IO_INPUT, "r"); +} + + +static int io_output (lua_State *L) { + return g_iofile(L, IO_OUTPUT, "w"); +} + + +static int io_readline (lua_State *L); + + +static void aux_lines (lua_State *L, int idx, int toclose) { + lua_pushvalue(L, idx); + lua_pushboolean(L, toclose); /* close/not close file when finished */ + lua_pushcclosure(L, io_readline, 2); +} + + +static int f_lines (lua_State *L) { + tofile(L); /* check that it's a valid file handle */ + aux_lines(L, 1, 0); + return 1; +} + + +static int io_lines (lua_State *L) { + if (lua_isnoneornil(L, 1)) { /* no arguments? */ + /* will iterate over default input */ + lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); + return f_lines(L); + } + else { + const char *filename = luaL_checkstring(L, 1); + FILE **pf = newfile(L); + *pf = fopen(filename, "r"); + if (*pf == NULL) + fileerror(L, 1, filename); + aux_lines(L, lua_gettop(L), 1); + return 1; + } +} + + +/* +** {====================================================== +** READ +** ======================================================= +*/ + + +static int read_number (lua_State *L, FILE *f) { + lua_Number d; + if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { + lua_pushnumber(L, d); + return 1; + } + else return 0; /* read fails */ +} + + +static int test_eof (lua_State *L, FILE *f) { + int c = getc(f); + ungetc(c, f); + lua_pushlstring(L, NULL, 0); + return (c != EOF); +} + + +static int read_line (lua_State *L, FILE *f) { + luaL_Buffer b; + luaL_buffinit(L, &b); + for (;;) { + size_t l; + char *p = luaL_prepbuffer(&b); + if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ + luaL_pushresult(&b); /* close buffer */ + return (lua_objlen(L, -1) > 0); /* check whether read something */ + } + l = strlen(p); + if (l == 0 || p[l-1] != '\n') + luaL_addsize(&b, l); + else { + luaL_addsize(&b, l - 1); /* do not include `eol' */ + luaL_pushresult(&b); /* close buffer */ + return 1; /* read at least an `eol' */ + } + } +} + + +static int read_chars (lua_State *L, FILE *f, size_t n) { + size_t rlen; /* how much to read */ + size_t nr; /* number of chars actually read */ + luaL_Buffer b; + luaL_buffinit(L, &b); + rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ + do { + char *p = luaL_prepbuffer(&b); + if (rlen > n) rlen = n; /* cannot read more than asked */ + nr = fread(p, sizeof(char), rlen, f); + luaL_addsize(&b, nr); + n -= nr; /* still have to read `n' chars */ + } while (n > 0 && nr == rlen); /* until end of count or eof */ + luaL_pushresult(&b); /* close buffer */ + return (n == 0 || lua_objlen(L, -1) > 0); +} + + +static int g_read (lua_State *L, FILE *f, int first) { + int nargs = lua_gettop(L) - 1; + int success; + int n; + clearerr(f); + if (nargs == 0) { /* no arguments? */ + success = read_line(L, f); + n = first+1; /* to return 1 result */ + } + else { /* ensure stack space for all results and for auxlib's buffer */ + luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); + success = 1; + for (n = first; nargs-- && success; n++) { + if (lua_type(L, n) == LUA_TNUMBER) { + size_t l = (size_t)lua_tointeger(L, n); + success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); + } + else { + const char *p = lua_tostring(L, n); + luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); + switch (p[1]) { + case 'n': /* number */ + success = read_number(L, f); + break; + case 'l': /* line */ + success = read_line(L, f); + break; + case 'a': /* file */ + read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ + success = 1; /* always success */ + break; + default: + return luaL_argerror(L, n, "invalid format"); + } + } + } + } + if (ferror(f)) + return pushresult(L, 0, NULL); + if (!success) { + lua_pop(L, 1); /* remove last result */ + lua_pushnil(L); /* push nil instead */ + } + return n - first; +} + + +static int io_read (lua_State *L) { + return g_read(L, getiofile(L, IO_INPUT), 1); +} + + +static int f_read (lua_State *L) { + return g_read(L, tofile(L), 2); +} + + +static int io_readline (lua_State *L) { + FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1)); + int sucess; + if (f == NULL) /* file is already closed? */ + luaL_error(L, "file is already closed"); + sucess = read_line(L, f); + if (ferror(f)) + return luaL_error(L, "%s", strerror(errno)); + if (sucess) return 1; + else { /* EOF */ + if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ + lua_settop(L, 0); + lua_pushvalue(L, lua_upvalueindex(1)); + aux_close(L); /* close it */ + } + return 0; + } +} + +/* }====================================================== */ + + +static int g_write (lua_State *L, FILE *f, int arg) { + int nargs = lua_gettop(L) - 1; + int status = 1; + size_t count; + for (; nargs--; arg++) { + if (lua_type(L, arg) == LUA_TNUMBER) { + /* optimization: could be done exactly as for strings */ + status = status && + fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; + } + else { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + count += l; + if (ftell(f) + l > FILELIMIT) + { + luaL_error(L,"write limit bypassed in file. Changes have been discarded."); + break; + } + status = status && (fwrite(s, sizeof(char), l, f) == l); + } + } + return pushresult(L, status, NULL); +} + + +static int io_write (lua_State *L) { + return g_write(L, getiofile(L, IO_OUTPUT), 1); +} + + +static int f_write (lua_State *L) { + return g_write(L, tofile(L), 2); +} + + +static int f_seek (lua_State *L) { + static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; + static const char *const modenames[] = {"set", "cur", "end", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, "cur", modenames); + long offset = luaL_optlong(L, 3, 0); + op = fseek(f, offset, mode[op]); + if (op) + return pushresult(L, 0, NULL); /* error */ + else { + lua_pushinteger(L, ftell(f)); + return 1; + } +} + + +static int f_setvbuf (lua_State *L) { + static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; + static const char *const modenames[] = {"no", "full", "line", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, NULL, modenames); + lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); + int res = setvbuf(f, NULL, mode[op], sz); + return pushresult(L, res == 0, NULL); +} + + + +static int io_flush (lua_State *L) { + return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); +} + + +static int f_flush (lua_State *L) { + return pushresult(L, fflush(tofile(L)) == 0, NULL); +} + + +static const luaL_Reg iolib[] = { + {"close", io_close}, + {"flush", io_flush}, + {"input", io_input}, + {"lines", io_lines}, + {"open", io_open}, + {"output", io_output}, + {"read", io_read}, + {"tmpfile", io_tmpfile}, + {"type", io_type}, + {"write", io_write}, + {NULL, NULL} +}; + + +static const luaL_Reg flib[] = { + {"close", io_close}, + {"flush", f_flush}, + {"lines", f_lines}, + {"read", f_read}, + {"seek", f_seek}, + {"setvbuf", f_setvbuf}, + {"write", f_write}, + {"__gc", io_gc}, + {"__tostring", io_tostring}, + {NULL, NULL} +}; + + +static void createmeta (lua_State *L) { + luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ + lua_pushvalue(L, -1); /* push metatable */ + lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ + luaL_register(L, NULL, flib); /* file methods */ +} + + +static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { + *newfile(L) = f; + if (k > 0) { + lua_pushvalue(L, -1); + lua_rawseti(L, LUA_ENVIRONINDEX, k); + } + lua_pushvalue(L, -2); /* copy environment */ + lua_setfenv(L, -2); /* set it */ + lua_setfield(L, -3, fname); +} + + +static void newfenv (lua_State *L, lua_CFunction cls) { + lua_createtable(L, 0, 1); + lua_pushcfunction(L, cls); + lua_setfield(L, -2, "__close"); +} + + +LUALIB_API int luaopen_io (lua_State *L) { + createmeta(L); + /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ + newfenv(L, io_fclose); + lua_replace(L, LUA_ENVIRONINDEX); + /* open library */ + luaL_register(L, LUA_IOLIBNAME, iolib); + /* create (and set) default files */ + newfenv(L, io_noclose); /* close function for default files */ + createstdfile(L, stdin, IO_INPUT, "stdin"); + createstdfile(L, stdout, IO_OUTPUT, "stdout"); + createstdfile(L, stderr, 0, "stderr"); + lua_pop(L, 1); /* pop environment for default files */ + return 1; +} + diff --git a/src/blua/lualib.h b/src/blua/lualib.h index 6ebe27287..4ea97edf3 100644 --- a/src/blua/lualib.h +++ b/src/blua/lualib.h @@ -21,6 +21,9 @@ LUALIB_API int (luaopen_base) (lua_State *L); #define LUA_TABLIBNAME "table" LUALIB_API int (luaopen_table) (lua_State *L); +#define LUA_IOLIBNAME "io" +LUALIB_API int (luaopen_io) (lua_State *L); + #define LUA_STRLIBNAME "string" LUALIB_API int (luaopen_string) (lua_State *L); diff --git a/src/config.h.in b/src/config.h.in index a7a0be53b..b529121e1 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -37,7 +37,7 @@ * Last updated 2015 / 05 / 03 - SRB2 v2.1.15 - srb2.srb * Last updated 2018 / 12 / 23 - SRB2 v2.1.22 - patch.dta * Last updated 2019 / 01 / 18 - Kart v1.0.2 - Main assets - * Last updated 2020 / 05 / 09 - Kart v1.2 - patch.kart + * Last updated 2020 / 08 / 30 - Kart v1.3 - patch.kart */ // Base SRB2 hashes @@ -52,7 +52,7 @@ #define ASSET_HASH_CHARS_KART "e2c428347dde52858a3dacd29fc5b964" #define ASSET_HASH_MAPS_KART "1335cd064656aedca359cfbb5233ac4a" #ifdef USE_PATCH_KART -#define ASSET_HASH_PATCH_KART "2a556446ab428492110e7544841e1f42" +#define ASSET_HASH_PATCH_KART "f7b68076f8abc54e1a78963d97f69ab2" #endif #endif diff --git a/src/console.c b/src/console.c index 5c4a2fc8a..0449ced69 100644 --- a/src/console.c +++ b/src/console.c @@ -31,6 +31,7 @@ #include "i_video.h" #include "z_zone.h" #include "i_system.h" +#include "i_threads.h" #include "d_main.h" #include "m_menu.h" #include "filesrch.h" @@ -45,6 +46,16 @@ #define MAXHUDLINES 20 +#ifdef HAVE_THREADS +I_mutex con_mutex; + +# define Lock_state() I_lock_mutex(&con_mutex) +# define Unlock_state() I_unlock_mutex(con_mutex) +#else/*HAVE_THREADS*/ +# define Lock_state() +# define Unlock_state() +#endif/*HAVE_THREADS*/ + static boolean con_started = false; // console has been initialised boolean con_startup = false; // true at game startup, screen need refreshing static boolean con_forcepic = true; // at startup toggle console translucency when first off @@ -170,6 +181,8 @@ static void CONS_hudlines_Change(void) { INT32 i; + Lock_state(); + // Clear the currently displayed lines for (i = 0; i < con_hudlines; i++) con_hudtime[i] = 0; @@ -181,6 +194,8 @@ static void CONS_hudlines_Change(void) con_hudlines = cons_hudlines.value; + Unlock_state(); + CONS_Printf(M_GetText("Number of console HUD lines is now %d\n"), con_hudlines); } @@ -188,12 +203,16 @@ static void CONS_hudlines_Change(void) // static void CONS_Clear_f(void) { + Lock_state(); + memset(con_buffer, 0, CON_BUFFERSIZE); con_cx = 0; con_cy = con_totallines-1; con_line = &con_buffer[con_cy*con_width]; con_scrollup = 0; + + Unlock_state(); } // Choose english keymap @@ -369,20 +388,29 @@ void CON_Init(void) for (i = 0; i < NUMINPUTS; i++) bindtable[i] = NULL; + Lock_state(); + // clear all lines memset(con_buffer, 0, CON_BUFFERSIZE); // make sure it is ready for the loading screen con_width = 0; + + Unlock_state(); + CON_RecalcSize(); CON_SetupColormaps(); + Lock_state(); + //note: CON_Ticker should always execute at least once before D_Display() con_clipviewtop = -1; // -1 does not clip con_hudlines = atoi(cons_hudlines.defaultvalue); + Unlock_state(); + // setup console input filtering CON_InputInit(); @@ -391,15 +419,23 @@ void CON_Init(void) COM_AddCommand("cls", CONS_Clear_f); //COM_AddCommand("english", CONS_English_f); // set console full screen for game startup MAKE SURE VID_Init() done !!! + Lock_state(); + con_destlines = vid.height; con_curlines = vid.height; + Unlock_state(); if (!dedicated) { + Lock_state(); + con_started = true; con_startup = true; // need explicit screen refresh until we are in Doom loop consoletoggle = false; + + Unlock_state(); + CV_RegisterVar(&cons_msgtimeout); CV_RegisterVar(&cons_hudlines); CV_RegisterVar(&cons_speed); @@ -411,19 +447,27 @@ void CON_Init(void) } else { + Lock_state(); + con_started = true; con_startup = false; // need explicit screen refresh until we are in Doom loop consoletoggle = true; + + Unlock_state(); } } // Console input initialization // static void CON_InputInit(void) { + Lock_state(); + // prepare the first prompt line memset(inputlines, 0, sizeof (inputlines)); inputline = 0; input_cur = input_sel = input_len = 0; + + Unlock_state(); } //====================================================================== @@ -439,6 +483,8 @@ static void CON_RecalcSize(void) char *tmp_buffer; char *string; + Lock_state(); + switch (cv_constextsize.value) { case V_NOSCALEPATCH: @@ -476,11 +522,18 @@ static void CON_RecalcSize(void) // check for change of video width if (conw == con_width) + { + Unlock_state(); return; // didn't change + } + + Unlock_state(); tmp_buffer = Z_Malloc(CON_BUFFERSIZE, PU_STATIC, NULL); string = Z_Malloc(CON_BUFFERSIZE, PU_STATIC, NULL); // BP: it is a line but who know + Lock_state(); + oldcon_width = con_width; oldnumlines = con_totallines; oldcon_cy = con_cy; @@ -501,6 +554,8 @@ static void CON_RecalcSize(void) con_line = &con_buffer[con_cy*con_width]; con_scrollup = 0; + Unlock_state(); + // re-arrange console text buffer to keep text if (oldcon_width) // not the first time { @@ -525,7 +580,11 @@ static void CON_RecalcSize(void) static void CON_ChangeHeight(void) { - INT32 minheight = 20 * con_scalefactor; // 20 = 8+8+4 + INT32 minheight; + + Lock_state(); + + minheight = 20 * con_scalefactor; // 20 = 8+8+4 // toggle console in con_destlines = (cons_height.value*vid.height)/100; @@ -535,13 +594,19 @@ static void CON_ChangeHeight(void) con_destlines = vid.height; con_destlines &= ~0x3; // multiple of text row height + + Unlock_state(); } // Handles Console moves in/out of screen (per frame) // static void CON_MoveConsole(void) { - const fixed_t conspeed = FixedDiv(cons_speed.value*vid.fdupy, FRACUNIT); + fixed_t conspeed; + + Lock_state(); + + conspeed = FixedDiv(cons_speed.value*vid.fdupy, FRACUNIT); // instant if (!cons_speed.value) @@ -563,6 +628,8 @@ static void CON_MoveConsole(void) if (con_curlines < con_destlines) con_curlines = con_destlines; } + + Unlock_state(); } INT32 CON_ShiftChar(INT32 ch) @@ -608,27 +675,44 @@ void CON_ClearHUD(void) { INT32 i; + Lock_state(); + for (i = 0; i < con_hudlines; i++) con_hudtime[i] = 0; + + Unlock_state(); } // Force console to move out immediately // note: con_ticker will set consoleready false void CON_ToggleOff(void) { + Lock_state(); + if (!con_destlines) + { + Unlock_state(); return; + } con_destlines = 0; con_curlines = 0; CON_ClearHUD(); con_forcepic = 0; con_clipviewtop = -1; // remove console clipping of view + + Unlock_state(); } boolean CON_Ready(void) { - return consoleready; + boolean ready; + Lock_state(); + { + ready = consoleready; + } + Unlock_state(); + return ready; } // Console ticker: handles console move in/out, cursor blinking @@ -636,7 +720,11 @@ boolean CON_Ready(void) void CON_Ticker(void) { INT32 i; - INT32 minheight = 20 * con_scalefactor; // 20 = 8+8+4 + INT32 minheight; + + Lock_state(); + + minheight = 20 * con_scalefactor; // 20 = 8+8+4 // cursor blinking con_tick++; @@ -694,6 +782,8 @@ void CON_Ticker(void) if (con_hudtime[i] < 0) con_hudtime[i] = 0; } + + Unlock_state(); } // @@ -705,32 +795,51 @@ void CON_Ticker(void) static void CON_InputClear(void) { + Lock_state(); + memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); input_cur = input_sel = input_len = 0; + + Unlock_state(); } static void CON_InputSetString(const char *c) { + Lock_state(); + memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); strcpy(inputlines[inputline], c); input_cur = input_sel = input_len = strlen(c); + + Unlock_state(); } static void CON_InputAddString(const char *c) { size_t csize = strlen(c); + + Lock_state(); + if (input_len + csize > CON_MAXPROMPTCHARS-1) + { + Unlock_state(); return; + } if (input_cur != input_len) memmove(&inputlines[inputline][input_cur+csize], &inputlines[inputline][input_cur], input_len-input_cur); memcpy(&inputlines[inputline][input_cur], c, csize); input_len += csize; input_sel = (input_cur += csize); + + Unlock_state(); } static void CON_InputDelSelection(void) { size_t start, end, len; + + Lock_state(); + if (input_cur > input_sel) { start = input_sel; @@ -749,27 +858,39 @@ static void CON_InputDelSelection(void) input_len -= len; input_sel = input_cur = start; + + Unlock_state(); } static void CON_InputAddChar(char c) { if (input_len >= CON_MAXPROMPTCHARS-1) return; + + Lock_state(); + if (input_cur != input_len) memmove(&inputlines[inputline][input_cur+1], &inputlines[inputline][input_cur], input_len-input_cur); inputlines[inputline][input_cur++] = c; inputlines[inputline][++input_len] = 0; input_sel = input_cur; + + Unlock_state(); } static void CON_InputDelChar(void) { if (!input_cur) return; + + Lock_state(); + if (input_cur != input_len) memmove(&inputlines[inputline][input_cur-1], &inputlines[inputline][input_cur], input_len-input_cur); inputlines[inputline][--input_len] = 0; input_sel = --input_cur; + + Unlock_state(); } // @@ -1208,6 +1329,8 @@ static void CON_Print(char *msg) S_StartSound(NULL, sfx_radio); } + Lock_state(); + if (!(*msg & 0x80)) { con_line[con_cx++] = '\x80'; @@ -1268,7 +1391,10 @@ static void CON_Print(char *msg) } if (*msg == '\0') + { + Unlock_state(); return; + } // printable character for (l = 0; l < (con_width-11) && msg[l] > ' '; l++) @@ -1286,6 +1412,8 @@ static void CON_Print(char *msg) for (; l > 0; l--) con_line[con_cx++] = *(msg++); } + + Unlock_state(); } void CON_LogMessage(const char *msg) @@ -1317,6 +1445,7 @@ void CONS_Printf(const char *fmt, ...) { va_list argptr; static char *txt = NULL; + boolean startup; if (txt == NULL) txt = malloc(8192); @@ -1349,11 +1478,16 @@ void CONS_Printf(const char *fmt, ...) CON_LogMessage(txt); #endif + Lock_state(); + // make sure new text is visible con_scrollup = 0; + startup = con_startup; + + Unlock_state(); // if not in display loop, force screen update - if (con_startup) + if (startup) { #if (defined (_WINDOWS)) || (defined (__OS2__) && !defined (HAVE_SDL)) patch_t *con_backpic = W_CachePatchName("KARTKREW", PU_CACHE); @@ -1667,8 +1801,13 @@ static void CON_DrawConsole(void) // void CON_Drawer(void) { + Lock_state(); + if (!con_started || !graphics_started) + { + Unlock_state(); return; + } if (con_recalc) CON_RecalcSize(); @@ -1678,4 +1817,6 @@ void CON_Drawer(void) else if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE || gamestate == GS_CREDITS || gamestate == GS_VOTING || gamestate == GS_EVALUATION || gamestate == GS_WAITINGPLAYERS) CON_DrawHudlines(); + + Unlock_state(); } diff --git a/src/console.h b/src/console.h index 53d1787f6..46bc57017 100644 --- a/src/console.h +++ b/src/console.h @@ -12,6 +12,7 @@ #include "d_event.h" #include "command.h" +#include "i_threads.h" #ifdef _WII void CON_InitWii(void); @@ -21,6 +22,10 @@ void CON_Init(void); boolean CON_Responder(event_t *ev); +#ifdef HAVE_THREADS +extern I_mutex con_mutex; +#endif + // set true when screen size has changed, to adapt console extern boolean con_recalc; diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 652ffbcb8..88fdb35a8 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -46,6 +46,7 @@ #include "lua_script.h" #include "lua_hook.h" #include "k_kart.h" +#include "s_sound.h" // sfx_syfail #ifdef CLIENT_LOADINGSCREEN // cl loading screen @@ -57,6 +58,10 @@ #include "sdl12/SRB2XBOX/xboxhelp.h" #endif +#ifdef HAVE_DISCORDRPC +#include "discord.h" +#endif + // // NETWORKING // @@ -76,7 +81,7 @@ boolean server = true; // true or false but !server == client #define client (!server) boolean nodownload = false; -static boolean serverrunning = false; +boolean serverrunning = false; INT32 serverplayer = 0; char motd[254], server_context[8]; // Message of the Day, Unique Context (even without Mumble support) @@ -141,6 +146,9 @@ char connectedservername[MAXSERVERNAME]; /// \todo WORK! boolean acceptnewnode = true; +boolean serverisfull = false; //lets us be aware if the server was full after we check files, but before downloading, so we can ask if the user still wants to download or not +tic_t firstconnectattempttime = 0; + // engine // Must be a power of two @@ -1093,8 +1101,10 @@ static INT16 Consistancy(void); typedef enum { CL_SEARCHING, + CL_CHECKFILES, CL_DOWNLOADFILES, CL_ASKJOIN, + CL_LOADFILES, CL_WAITJOINRESPONSE, #ifdef JOININGAME CL_DOWNLOADSAVEGAME, @@ -1102,6 +1112,7 @@ typedef enum CL_CONNECTED, CL_ABORTED, CL_ASKFULLFILELIST, + CL_CONFIRMCONNECT, #ifdef HAVE_CURL CL_PREPAREHTTPFILES, CL_DOWNLOADHTTPFILES, @@ -1166,11 +1177,7 @@ static inline void CL_DrawConnectionStatus(void) // Draw background fade V_DrawFadeScreen(0xFF00, 16); - // Draw the bottom box. - M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-24-8, 32, 1); - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-24, V_YELLOWMAP, "Press ESC to abort"); - - if (cl_mode != CL_DOWNLOADFILES + if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_LOADFILES #ifdef HAVE_CURL && cl_mode != CL_DOWNLOADHTTPFILES #endif @@ -1181,6 +1188,10 @@ static inline void CL_DrawConnectionStatus(void) // 15 pal entries total. const char *cltext; + //Draw bottom box + M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-24-8, 32, 1); + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-24, V_YELLOWMAP, "Press ESC to abort"); + for (i = 0; i < 16; ++i) V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-24, 16, 8, palstart + ((animtime - i) & 15)); @@ -1202,11 +1213,22 @@ static inline void CL_DrawConnectionStatus(void) break; #endif case CL_ASKFULLFILELIST: - cltext = M_GetText("This server has a LOT of files!"); + case CL_CHECKFILES: + cltext = M_GetText("Checking server addon list ..."); + break; + case CL_CONFIRMCONNECT: + cltext = ""; + break; + case CL_LOADFILES: + cltext = M_GetText("Loading server addons..."); break; case CL_ASKJOIN: case CL_WAITJOINRESPONSE: - cltext = M_GetText("Requesting to join..."); + if (serverisfull) + cltext = M_GetText("Server full, waiting for a slot..."); + else + cltext = M_GetText("Requesting to join..."); + break; #ifdef HAVE_CURL case CL_PREPAREHTTPFILES: @@ -1221,19 +1243,47 @@ static inline void CL_DrawConnectionStatus(void) } else { - if (lastfilenum != -1) + if (cl_mode == CL_LOADFILES) + { + INT32 totalfileslength; + INT32 loadcompletednum = 0; + INT32 i; + + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-24, V_YELLOWMAP, "Press ESC to abort"); + + //ima just count files here + for (i = 0; i < fileneedednum; i++) + if (fileneeded[i].status == FS_OPEN) + loadcompletednum++; + + // Loading progress + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-32, V_YELLOWMAP, "Loading server addons..."); + totalfileslength = (INT32)((loadcompletednum/(double)(fileneedednum)) * 256); + M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-24-8, 32, 1); + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 175); + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, totalfileslength, 8, 160); + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE, + va(" %2u/%2u Files",loadcompletednum,fileneedednum)); + } + else if (lastfilenum != -1) { INT32 dldlength; + INT32 totalfileslength; + UINT32 totaldldsize; static char tempname[28]; fileneeded_t *file = &fileneeded[lastfilenum]; char *filename = file->filename; + // Draw the bottom box. + M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-58-8, 32, 1); + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-58-14, V_YELLOWMAP, "Press ESC to abort"); + Net_GetNetStat(); dldlength = (INT32)((file->currentsize/(double)file->totalsize) * 256); if (dldlength > 256) dldlength = 256; - V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 175); - V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, dldlength, 8, 160); + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-58, 256, 8, 175); + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-58, dldlength, 8, 160); memset(tempname, 0, sizeof(tempname)); // offset filename to just the name only part @@ -1251,16 +1301,52 @@ static inline void CL_DrawConnectionStatus(void) strncpy(tempname, filename, sizeof(tempname)-1); } - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-32, V_YELLOWMAP, + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-58-22, V_YELLOWMAP, va(M_GetText("Downloading \"%s\""), tempname)); - V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE, + V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-58, V_20TRANS|V_MONOSPACE, va(" %4uK/%4uK",fileneeded[lastfilenum].currentsize>>10,file->totalsize>>10)); - V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE, + V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-58, V_20TRANS|V_MONOSPACE, va("%3.1fK/s ", ((double)getbps)/1024)); + + // Download progress + + if (fileneeded[lastfilenum].currentsize != fileneeded[lastfilenum].totalsize) + totaldldsize = downloadcompletedsize+fileneeded[lastfilenum].currentsize; //Add in single file progress download if applicable + else + totaldldsize = downloadcompletedsize; + + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-14, V_YELLOWMAP, "Overall Download Progress"); + totalfileslength = (INT32)((totaldldsize/(double)totalfilesrequestedsize) * 256); + M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-24-8, 32, 1); + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 175); + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, totalfileslength, 8, 160); + + if (totalfilesrequestedsize>>20 >= 100) //display in MB if over 100MB + V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE, + va(" %4uM/%4uM",totaldldsize>>20,totalfilesrequestedsize>>20)); + else + V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE, + va(" %4uK/%4uK",totaldldsize>>10,totalfilesrequestedsize>>10)); + + V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE, + va("%2u/%2u Files ",downloadcompletednum,totalfilesrequestednum)); } else + { + INT32 i, animtime = ((ccstime / 4) & 15) + 16; + UINT8 palstart = (cl_mode == CL_SEARCHING) ? 128 : 160; + // 15 pal entries total. + + //Draw bottom box + M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-24-8, 32, 1); + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-24, V_YELLOWMAP, "Press ESC to abort"); + + for (i = 0; i < 16; ++i) + V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-24, 16, 8, palstart + ((animtime - i) & 15)); + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-32, V_YELLOWMAP, M_GetText("Waiting to download files...")); + } } } #endif @@ -1270,7 +1356,7 @@ static boolean CL_AskFileList(INT32 firstfile) netbuffer->packettype = PT_TELLFILESNEEDED; netbuffer->u.filesneedednum = firstfile; - return HSendPacket(servernode, true, 0, sizeof (INT32)); + return HSendPacket(servernode, false, 0, sizeof (INT32)); } /** Sends a special packet to declare how many players in local @@ -1306,13 +1392,75 @@ static boolean CL_SendJoin(void) return HSendPacket(servernode, false, 0, sizeof (clientconfig_pak)); } +static void +CopyCaretColors (char *p, const char *s, int n) +{ + char *t; + int m; + int c; + if (!n) + return; + while (( t = strchr(s, '^') )) + { + m = ( t - s ); + + if (m >= n) + { + memcpy(p, s, n); + return; + } + else + memcpy(p, s, m); + + p += m; + n -= m; + s += m; + + if (!n) + return; + + if (s[1]) + { + c = toupper(s[1]); + if (isdigit(c)) + c = 0x80 + ( c - '0' ); + else if (c >= 'A' && c <= 'F') + c = 0x80 + ( c - 'A' ); + else + c = 0; + + if (c) + { + *p++ = c; + n--; + + if (!n) + return; + } + else + { + if (n < 2) + break; + + memcpy(p, s, 2); + + p += 2; + n -= 2; + } + + s += 2; + } + else + break; + } + strncpy(p, s, n); +} + static void SV_SendServerInfo(INT32 node, tic_t servertime) { UINT8 *p; -#ifdef HAVE_CURL size_t mirror_length; const char *httpurl = cv_httpsource.string; -#endif netbuffer->packettype = PT_SERVERINFO; netbuffer->u.serverinfo._255 = 255; @@ -1336,8 +1484,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) (dedicated ? SV_DEDICATED : 0) ); - - strncpy(netbuffer->u.serverinfo.servername, cv_servername.string, + CopyCaretColors(netbuffer->u.serverinfo.servername, cv_servername.string, MAXSERVERNAME); strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7); @@ -1378,7 +1525,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl, mapheaderinfo[gamemap-1]->actnum) < 0) { // If there's an encoding error, send UNKNOWN, we accept that the above may be truncated - strncpy(netbuffer->u.serverinfo.maptitle, "UNKNOWN", 33); + strncpy(netbuffer->u.serverinfo.maptitle, "Unknown", 33); } } else @@ -1389,19 +1536,18 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl) < 0) { // If there's an encoding error, send UNKNOWN, we accept that the above may be truncated - strncpy(netbuffer->u.serverinfo.maptitle, "UNKNOWN", 33); + strncpy(netbuffer->u.serverinfo.maptitle, "Unknown", 33); } } } } else - strncpy(netbuffer->u.serverinfo.maptitle, "UNKNOWN", 33); + strncpy(netbuffer->u.serverinfo.maptitle, "Unknown", 33); netbuffer->u.serverinfo.maptitle[32] = '\0'; netbuffer->u.serverinfo.actnum = 0; //mapheaderinfo[gamemap-1]->actnum -#ifdef HAVE_CURL mirror_length = strlen(httpurl); if (mirror_length > MAX_MIRROR_LENGTH) mirror_length = MAX_MIRROR_LENGTH; @@ -1411,7 +1557,6 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) strncpy(netbuffer->u.serverinfo.httpsource, "", mirror_length); netbuffer->u.serverinfo.httpsource[MAX_MIRROR_LENGTH-1] = '\0'; -#endif p = PutFileNeeded(0); @@ -1524,6 +1669,10 @@ static boolean SV_SendServerConfig(INT32 node) netbuffer->u.servercfg.playercolor[i] = (UINT8)players[i].skincolor; } + netbuffer->u.servercfg.maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value)); + netbuffer->u.servercfg.allownewplayer = cv_allownewplayer.value; + netbuffer->u.servercfg.discordinvites = (boolean)cv_discordinvites.value; + memcpy(netbuffer->u.servercfg.server_context, server_context, 8); op = p = netbuffer->u.servercfg.varlengthinputs; @@ -1721,7 +1870,7 @@ static void CL_LoadReceivedSavegame(void) if (strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) CON_LogMessage(va(" %s", mapheaderinfo[gamemap-1]->zonttl)); else if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) - CON_LogMessage(M_GetText(" ZONE")); + CON_LogMessage(M_GetText(" Zone")); if (strlen(mapheaderinfo[gamemap-1]->actnum) > 0) CON_LogMessage(va(" %s", mapheaderinfo[gamemap-1]->actnum)); } @@ -1748,7 +1897,7 @@ static void CL_LoadReceivedSavegame(void) #endif #ifndef NONET -static void SendAskInfo(INT32 node, boolean viams) +static void SendAskInfo(INT32 node) { const tic_t asktime = I_GetTime(); netbuffer->packettype = PT_ASKINFO; @@ -1759,10 +1908,6 @@ static void SendAskInfo(INT32 node, boolean viams) // now allowed traffic from the host to us in, so once the MS relays // our address to the host, it'll be able to speak to us. HSendPacket(node, false, 0, sizeof (askinfo_pak)); - - // Also speak to the MS. - if (viams && node != 0 && node != BROADCASTADDR) - SendAskInfoViaMS(node, asktime); } serverelem_t serverlist[MAXSERVERLIST]; @@ -1828,13 +1973,12 @@ static void SL_InsertServer(serverinfo_pak* info, SINT8 node) M_SortServerList(); } -void CL_UpdateServerList(boolean internetsearch, INT32 room) +void CL_UpdateServerList (void) { SL_ClearServerList(0); if (!netgame && I_NetOpenSocket) { - MSCloseUDPSocket(); // Tidy up before wiping the slate. if (I_NetOpenSocket()) { netgame = true; @@ -1844,67 +1988,95 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room) // search for local servers if (netgame) - SendAskInfo(BROADCASTADDR, false); + SendAskInfo(BROADCASTADDR); +} - if (internetsearch) +void CL_QueryServerList (msg_server_t *server_list) +{ + INT32 i; + + CL_UpdateServerList(); + + for (i = 0; server_list[i].header.buffer[0]; i++) { - const msg_server_t *server_list; - INT32 i = -1; - server_list = GetShortServersList(room); - if (server_list) + // Make sure MS version matches our own, to + // thwart nefarious servers who lie to the MS. + + /* lol bruh, that version COMES from the servers */ + //if (strcmp(version, server_list[i].version) == 0) { - char version[8] = ""; -#if VERSION > 0 || SUBVERSION > 0 - snprintf(version, sizeof (version), "%d.%d", VERSION, SUBVERSION); -#else - strcpy(version, GetRevisionString()); -#endif - version[sizeof (version) - 1] = '\0'; + INT32 node = I_NetMakeNodewPort(server_list[i].ip, server_list[i].port); + if (node == -1) + break; // no more node free + SendAskInfo(node); + // Force close the connection so that servers can't eat + // up nodes forever if we never get a reply back from them + // (usually when they've not forwarded their ports). + // + // Don't worry, we'll get in contact with the working + // servers again when they send SERVERINFO to us later! + // + // (Note: as a side effect this probably means every + // server in the list will probably be using the same node (e.g. node 1), + // not that it matters which nodes they use when + // the connections are closed afterwards anyway) + // -- Monster Iestyn 12/11/18 + Net_CloseConnection(node|FORCECLOSE); + } + } +} +#endif // ifndef NONET - for (i = 0; server_list[i].header.buffer[0]; i++) +static void M_ConfirmConnect(event_t *ev) +{ +#ifndef NONET + if (ev->type == ev_keydown) + { + if (ev->data1 == ' ' || ev->data1 == 'y' || ev->data1 == KEY_ENTER || ev->data1 == gamecontrol[gc_accelerate][0] || ev->data1 == gamecontrol[gc_accelerate][1]) + { + if (totalfilesrequestednum > 0) { - // Make sure MS version matches our own, to - // thwart nefarious servers who lie to the MS. - - if (strcmp(version, server_list[i].version) == 0) +#ifdef HAVE_CURL + if (http_source[0] == '\0' || curl_failedwebdownload) +#endif { - INT32 node = I_NetMakeNodewPort(server_list[i].ip, server_list[i].port); - if (node == -1) - break; // no more node free - SendAskInfo(node, true); - // Force close the connection so that servers can't eat - // up nodes forever if we never get a reply back from them - // (usually when they've not forwarded their ports). - // - // Don't worry, we'll get in contact with the working - // servers again when they send SERVERINFO to us later! - // - // (Note: as a side effect this probably means every - // server in the list will probably be using the same node (e.g. node 1), - // not that it matters which nodes they use when - // the connections are closed afterwards anyway) - // -- Monster Iestyn 12/11/18 - Net_CloseConnection(node|FORCECLOSE); + if (CL_SendRequestFile()) + { + cl_mode = CL_DOWNLOADFILES; + } } +#ifdef HAVE_CURL + else + cl_mode = CL_PREPAREHTTPFILES; +#endif } + else + cl_mode = CL_LOADFILES; + + M_ClearMenus(true); } - - //no server list?(-1) or no servers?(0) - if (!i) + else if (ev->data1 == 'n' || ev->data1 == KEY_ESCAPE|| ev->data1 == gamecontrol[gc_brake][0] || ev->data1 == gamecontrol[gc_brake][1]) { - ; /// TODO: display error or warning? + cl_mode = CL_ABORTED; + M_ClearMenus(true); } } +#else + (void)ev; +#endif } -#endif // ifndef NONET - static boolean CL_FinishedFileList(void) { INT32 i; - CONS_Printf(M_GetText("Checking files...\n")); + char *downloadsize = NULL; + //CONS_Printf(M_GetText("Checking files...\n")); i = CL_CheckFiles(); - if (i == 3) // too many files + if (i == 4) // still checking ... + { + return true; + } + else if (i == 3) // too many files { D_QuitNetGame(); CL_Reset(); @@ -1923,17 +2095,31 @@ static boolean CL_FinishedFileList(void) CL_Reset(); D_StartTitle(); M_StartMessage(M_GetText( - "You have WAD files loaded or have\n" - "modified the game in some way, and\n" - "your file list does not match\n" - "the server's file list.\n" - "Please restart SRB2Kart before connecting.\n\n" + "You have the wrong addons loaded.\n\n" + "To play on this server, restart\n" + "the game and don't load any addons.\n" + "SRB2Kart will automatically add\n" + "everything you need when you join.\n\n" "Press ESC\n" ), NULL, MM_NOTHING); return false; } else if (i == 1) - cl_mode = CL_ASKJOIN; + { + if (serverisfull) + { + M_StartMessage(M_GetText( + "This server is full!\n" + "\n" + "You may load server addons (if any), and wait for a slot.\n" + "\n" + "Press ACCEL to continue or BRAKE to cancel.\n\n" + ), M_ConfirmConnect, MM_EVENTHANDLER); + cl_mode = CL_CONFIRMCONNECT; + } + else + cl_mode = CL_LOADFILES; + } else { // must download something @@ -1948,23 +2134,71 @@ static boolean CL_FinishedFileList(void) CL_Reset(); D_StartTitle(); M_StartMessage(M_GetText( - "You cannot connect to this server\n" - "because you cannot download the files\n" - "that you are missing from the server.\n\n" - "See the console or log file for\n" - "more details.\n\n" + "An error occured when trying to\n" + "download missing addons.\n" + "(This is almost always a problem\n" + "with the server, not your game.)\n\n" + "See the console or log file\n" + "for additional details.\n\n" "Press ESC\n" ), NULL, MM_NOTHING); return false; } + } - if (CL_SendRequestFile()) - cl_mode = CL_DOWNLOADFILES; +#ifdef HAVE_CURL + if (!curl_failedwebdownload) +#endif + { +#ifndef NONET + downloadcompletednum = 0; + downloadcompletedsize = 0; + totalfilesrequestednum = 0; + totalfilesrequestedsize = 0; +#endif + + for (i = 0; i < fileneedednum; i++) + if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD) + { +#ifndef NONET + totalfilesrequestednum++; + totalfilesrequestedsize += fileneeded[i].totalsize; +#endif + } + +#ifndef NONET + if (totalfilesrequestedsize>>20 >= 100) + downloadsize = Z_StrDup(va("%uM",totalfilesrequestedsize>>20)); + else + downloadsize = Z_StrDup(va("%uK",totalfilesrequestedsize>>10)); +#endif + + if (serverisfull) + M_StartMessage(va(M_GetText( + "This server is full!\n" + "Download of %s additional content is required to join.\n" + "\n" + "You may download, load server addons, and wait for a slot.\n" + "\n" + "Press ACCEL to continue or BRAKE to cancel.\n\n" + ), downloadsize), M_ConfirmConnect, MM_EVENTHANDLER); + else + M_StartMessage(va(M_GetText( + "Download of %s additional content is required to join.\n" + "\n" + "Press ACCEL to continue or BRAKE to cancel.\n\n" + ), downloadsize), M_ConfirmConnect, MM_EVENTHANDLER); + + Z_Free(downloadsize); + cl_mode = CL_CONFIRMCONNECT; } #ifdef HAVE_CURL else { - cl_mode = CL_PREPAREHTTPFILES; + if (CL_SendRequestFile()) + { + cl_mode = CL_DOWNLOADFILES; + } } #endif } @@ -1973,14 +2207,13 @@ static boolean CL_FinishedFileList(void) /** Called by CL_ServerConnectionTicker * - * \param viams ??? * \param asksent The last time we asked the server to join. We re-ask every second in case our request got lost in transmit. * \return False if the connection was aborted * \sa CL_ServerConnectionTicker * \sa CL_ConnectToServer * */ -static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent) +static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) { #ifndef NONET INT32 i; @@ -2005,11 +2238,7 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent) // Quit here rather than downloading files and being refused later. if (serverlist[i].info.numberofplayer >= serverlist[i].info.maxplayer) { - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - M_StartMessage(va(M_GetText("Maximum players reached: %d\n\nPress ESC\n"), serverlist[i].info.maxplayer), NULL, MM_NOTHING); - return false; + serverisfull = true; } if (client) @@ -2023,7 +2252,6 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent) if (serverlist[i].info.httpsource[0]) CONS_Printf("We received a http url from the server, however it will not be used as this build lacks curl support (%s)\n", serverlist[i].info.httpsource); #endif - D_ParseFileneeded(serverlist[i].info.fileneedednum, serverlist[i].info.fileneeded, 0); if (serverlist[i].info.kartvars & SV_LOTSOFADDONS) { @@ -2032,8 +2260,7 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent) return true; } - if (!CL_FinishedFileList()) - return false; + cl_mode = CL_CHECKFILES; } else cl_mode = CL_ASKJOIN; // files need not be checked for the server. @@ -2042,13 +2269,12 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent) } // Ask the info to the server (askinfo packet) - if (*asksent + NEWTICRATE < I_GetTime()) + if (I_GetTime() >= *asksent) { - SendAskInfo(servernode, viams); - *asksent = I_GetTime(); + SendAskInfo(servernode); + *asksent = I_GetTime() + NEWTICRATE; } #else - (void)viams; (void)asksent; // No netgames, so we skip this state. cl_mode = CL_ASKJOIN; @@ -2059,7 +2285,6 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent) /** Called by CL_ConnectToServer * - * \param viams ??? * \param tmpsave The name of the gamestate file??? * \param oldtic Used for knowing when to poll events and redraw * \param asksent The last time we asked the server to join. We re-ask every second in case our request got lost in transmit. @@ -2068,11 +2293,11 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent) * \sa CL_ConnectToServer * */ -static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic_t *oldtic, tic_t *asksent) +static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic_t *asksent) { boolean waitmore; INT32 i; - + #ifdef NONET (void)tmpsave; #endif @@ -2080,34 +2305,36 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic switch (cl_mode) { case CL_SEARCHING: - if (!CL_ServerConnectionSearchTicker(viams, asksent)) + if (!CL_ServerConnectionSearchTicker(asksent)) return false; break; case CL_ASKFULLFILELIST: if (cl_lastcheckedfilecount == UINT16_MAX) // All files retrieved - { - if (!CL_FinishedFileList()) - return false; - } - else if (fileneedednum != cl_lastcheckedfilecount || *asksent + NEWTICRATE < I_GetTime()) + cl_mode = CL_CHECKFILES; + else if (fileneedednum != cl_lastcheckedfilecount || I_GetTime() >= *asksent) { if (CL_AskFileList(fileneedednum)) { cl_lastcheckedfilecount = fileneedednum; - *asksent = I_GetTime(); + *asksent = I_GetTime() + NEWTICRATE; } } break; - + case CL_CHECKFILES: + if (!CL_FinishedFileList()) + return false; + break; #ifdef HAVE_CURL case CL_PREPAREHTTPFILES: if (http_source[0]) { for (i = 0; i < fileneedednum; i++) if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD) + { curl_transfers++; - + } + cl_mode = CL_DOWNLOADHTTPFILES; } break; @@ -2131,19 +2358,13 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic if (curl_failedwebdownload && !curl_transfers) { - if (!CL_FinishedFileList()) - break; - CONS_Printf("One or more files failed to download, falling back to internal downloader\n"); - if (CL_SendRequestFile()) - { - cl_mode = CL_DOWNLOADFILES; - break; - } + cl_mode = CL_CHECKFILES; + break; } if (!curl_transfers) - cl_mode = CL_ASKJOIN; // don't break case continue to cljoin request now + cl_mode = CL_LOADFILES; break; #endif @@ -2159,21 +2380,50 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic if (waitmore) break; // exit the case - cl_mode = CL_ASKJOIN; // don't break case continue to cljoin request now - /* FALLTHRU */ - + cl_mode = CL_LOADFILES; + break; + case CL_LOADFILES: + if (CL_LoadServerFiles()) + { + *asksent = 0; //This ensure the first join ask is right away + firstconnectattempttime = I_GetTime(); + cl_mode = CL_ASKJOIN; + } + break; case CL_ASKJOIN: - CL_LoadServerFiles(); + if (firstconnectattempttime + NEWTICRATE*300 < I_GetTime() && !server) + { + CONS_Printf(M_GetText("5 minute wait time exceeded.\n")); + CONS_Printf(M_GetText("Network game synchronization aborted.\n")); + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + M_StartMessage(M_GetText( + "5 minute wait time exceeded.\n" + "You may retry connection.\n" + "\n" + "Press ESC\n" + ), NULL, MM_NOTHING); + return false; + } #ifdef JOININGAME // prepare structures to save the file // WARNING: this can be useless in case of server not in GS_LEVEL // but since the network layer doesn't provide ordered packets... CL_PrepareDownloadSaveGame(tmpsave); #endif - if (CL_SendJoin()) + if (I_GetTime() >= *asksent && CL_SendJoin()) + { + *asksent = I_GetTime() + NEWTICRATE*3; cl_mode = CL_WAITJOINRESPONSE; + } + break; + case CL_WAITJOINRESPONSE: + if (I_GetTime() >= *asksent) + { + cl_mode = CL_ASKJOIN; + } break; - #ifdef JOININGAME case CL_DOWNLOADSAVEGAME: // At this state, the first (and only) needed file is the gamestate @@ -2182,13 +2432,13 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic // Gamestate is now handled within CL_LoadReceivedSavegame() CL_LoadReceivedSavegame(); cl_mode = CL_CONNECTED; + break; } // don't break case continue to CL_CONNECTED else break; #endif - - case CL_WAITJOINRESPONSE: case CL_CONNECTED: + case CL_CONFIRMCONNECT: //logic is handled by M_ConfirmConnect default: break; @@ -2209,9 +2459,13 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic INT32 key; I_OsPolling(); + + if (cl_mode == CL_CONFIRMCONNECT) + D_ProcessEvents(); //needed for menu system to receive inputs + key = I_GetKey(); // Only ESC and non-keyboard keys abort connection - if (key == KEY_ESCAPE || key >= KEY_MOUSE1) + if (key == KEY_ESCAPE || key >= KEY_MOUSE1 || cl_mode == CL_ABORTED) { CONS_Printf(M_GetText("Network game synchronization aborted.\n")); D_QuitNetGame(); @@ -2228,6 +2482,13 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic F_TitleScreenTicker(true); F_TitleScreenDrawer(); CL_DrawConnectionStatus(); +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif + M_Drawer(); //Needed for drawing messageboxes on the connection screen +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); +#endif I_UpdateNoVsync(); // page flip or blit buffer if (moviemode) M_SaveFrame(); @@ -2245,11 +2506,10 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic /** Use adaptive send using net_bandwidth and stat.sendbytes * - * \param viams ??? * \todo Better description... * */ -static void CL_ConnectToServer(boolean viams) +static void CL_ConnectToServer(void) { INT32 pnumnodes, nodewaited = doomcom->numnodes, i; tic_t oldtic; @@ -2293,9 +2553,10 @@ static void CL_ConnectToServer(boolean viams) ClearAdminPlayers(); pnumnodes = 1; - oldtic = I_GetTime() - 1; + oldtic = 0; #ifndef NONET - asksent = (tic_t) - TICRATE; + asksent = 0; + firstconnectattempttime = I_GetTime(); i = SL_SearchServer(servernode); @@ -2321,9 +2582,9 @@ static void CL_ConnectToServer(boolean viams) { // If the connection was aborted for some reason, leave #ifndef NONET - if (!CL_ServerConnectionTicker(viams, tmpsave, &oldtic, &asksent)) + if (!CL_ServerConnectionTicker(tmpsave, &oldtic, &asksent)) #else - if (!CL_ServerConnectionTicker(viams, (char*)NULL, &oldtic, (tic_t *)NULL)) + if (!CL_ServerConnectionTicker((char*)NULL, &oldtic, (tic_t *)NULL)) #endif return; @@ -2504,9 +2765,6 @@ static void Command_ReloadBan(void) //recheck ban.txt static void Command_connect(void) { - // Assume we connect directly. - boolean viams = false; - if (COM_Argc() < 2 || *COM_Argv(1) == 0) { CONS_Printf(M_GetText( @@ -2540,9 +2798,6 @@ static void Command_connect(void) if (netgame && !stricmp(COM_Argv(1), "node")) { servernode = (SINT8)atoi(COM_Argv(2)); - - // Use MS to traverse NAT firewalls. - viams = true; } else if (netgame) { @@ -2551,7 +2806,6 @@ static void Command_connect(void) } else if (I_NetOpenSocket) { - MSCloseUDPSocket(); // Tidy up before wiping the slate. I_NetOpenSocket(); netgame = true; multiplayer = true; @@ -2580,7 +2834,7 @@ static void Command_connect(void) } botingame = false; botskin = 0; - CL_ConnectToServer(viams); + CL_ConnectToServer(); } #endif @@ -2687,6 +2941,8 @@ void CL_RemovePlayer(INT32 playernum, INT32 reason) // Reset the name sprintf(player_names[playernum], "Player %d", playernum+1); + player_name_changes[playernum] = 0; + if (IsPlayerAdmin(playernum)) { RemoveAdminPlayer(playernum); // don't stay admin after you're gone @@ -2737,6 +2993,14 @@ void CL_Reset(void) fileneedednum = 0; memset(fileneeded, 0, sizeof(fileneeded)); +#ifndef NONET + totalfilesrequestednum = 0; + totalfilesrequestedsize = 0; +#endif + firstconnectattempttime = 0; + serverisfull = false; + connectiontimeout = (tic_t)cv_nettimeout.value; //reset this temporary hack + #ifdef HAVE_CURL curl_failedwebdownload = false; curl_transfers = 0; @@ -3076,6 +3340,11 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) #endif } + if (msg == KICK_MSG_PLAYER_QUIT) + S_StartSound(NULL, sfx_leave); // intended leave + else + S_StartSound(NULL, sfx_syfail); // he he he + switch (msg) { case KICK_MSG_GO_AWAY: @@ -3203,12 +3472,21 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) static CV_PossibleValue_t netticbuffer_cons_t[] = {{0, "MIN"}, {3, "MAX"}, {0, NULL}}; consvar_t cv_netticbuffer = {"netticbuffer", "1", CV_SAVE, netticbuffer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_allownewplayer = {"allowjoin", "On", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL }; +static void Joinable_OnChange(void); + +consvar_t cv_allownewplayer = {"allowjoin", "On", CV_SAVE|CV_CALL, CV_OnOff, Joinable_OnChange, 0, NULL, NULL, 0, 0, NULL}; + #ifdef VANILLAJOINNEXTROUND consvar_t cv_joinnextround = {"joinnextround", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done #endif + static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {MAXPLAYERS, "MAX"}, {0, NULL}}; -consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE|CV_CALL, maxplayers_cons_t, Joinable_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +// Here for dedicated servers +static CV_PossibleValue_t discordinvites_cons_t[] = {{0, "Admins Only"}, {1, "Everyone"}, {0, NULL}}; +consvar_t cv_discordinvites = {"discordinvites", "Everyone", CV_SAVE|CV_CALL, discordinvites_cons_t, Joinable_OnChange, 0, NULL, NULL, 0, 0, NULL}; + static CV_PossibleValue_t resynchattempts_cons_t[] = {{0, "MIN"}, {20, "MAX"}, {0, NULL}}; consvar_t cv_resynchattempts = {"resynchattempts", "5", CV_SAVE, resynchattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL }; consvar_t cv_blamecfail = {"blamecfail", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL }; @@ -3225,6 +3503,24 @@ consvar_t cv_downloadspeed = {"downloadspeed", "16", CV_SAVE, downloadspeed_cons static void Got_AddPlayer(UINT8 **p, INT32 playernum); static void Got_RemovePlayer(UINT8 **p, INT32 playernum); +static void Joinable_OnChange(void) +{ + UINT8 buf[3]; + UINT8 *p = buf; + UINT8 maxplayer; + + if (!server) + return; + + maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value)); + + WRITEUINT8(p, maxplayer); + WRITEUINT8(p, cv_allownewplayer.value); + WRITEUINT8(p, cv_discordinvites.value); + + SendNetXCmd(XD_DISCORD, &buf, 3); +} + // called one time at init void D_ClientServerInit(void) { @@ -3315,6 +3611,8 @@ void SV_ResetServer(void) adminplayers[i] = -1; // Populate the entire adminplayers array with -1. } + memset(player_name_changes, 0, sizeof player_name_changes); + mynode = 0; cl_packetmissed = false; @@ -3377,8 +3675,10 @@ void D_QuitNetGame(void) for (i = 0; i < MAXNETNODES; i++) if (nodeingame[i]) HSendPacket(i, true, 0, 0); - if (serverrunning && ms_RoomId > 0) +#ifdef MASTERSERVER + if (serverrunning && cv_advertise.value) UnregisterServer(); +#endif } else if (servernode > 0 && servernode < MAXNETNODES && nodeingame[(UINT8)servernode]) { @@ -3474,6 +3774,9 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) if (netgame) { + if (node != mynode) + S_StartSound(NULL, sfx_join); + if (server && cv_showjoinaddress.value) { const char *address; @@ -3490,6 +3793,10 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) #ifdef HAVE_BLUA LUAh_PlayerJoin(newplayernum); #endif + +#ifdef HAVE_DISCORDRPC + DRPC_UpdatePresence(); +#endif } // Xcmd XD_REMOVEPLAYER @@ -3516,6 +3823,10 @@ static void Got_RemovePlayer(UINT8 **p, INT32 playernum) reason = READUINT8(*p); CL_RemovePlayer(pnum, reason); + +#ifdef HAVE_DISCORDRPC + DRPC_UpdatePresence(); +#endif } static boolean SV_AddWaitingPlayers(void) @@ -3625,15 +3936,16 @@ boolean SV_SpawnServer(void) SV_GenContext(); if (netgame && I_NetOpenSocket) { - MSCloseUDPSocket(); // Tidy up before wiping the slate. I_NetOpenSocket(); - if (ms_RoomId > 0) +#ifdef MASTERSERVER + if (cv_advertise.value) RegisterServer(); +#endif } // non dedicated server just connect to itself if (!dedicated) - CL_ConnectToServer(false); + CL_ConnectToServer(); else doomcom->numslots = 1; } @@ -3659,7 +3971,7 @@ void SV_StopServer(void) D_Clearticcmd(i); consoleplayer = 0; - cl_mode = CL_SEARCHING; + cl_mode = CL_ABORTED; maketic = gametic+1; neededtic = maketic; serverrunning = false; @@ -3685,7 +3997,7 @@ static void SV_SendRefuse(INT32 node, const char *reason) strcpy(netbuffer->u.serverrefuse.reason, reason); netbuffer->packettype = PT_SERVERREFUSE; - HSendPacket(node, true, 0, strlen(netbuffer->u.serverrefuse.reason) + 1); + HSendPacket(node, false, 0, strlen(netbuffer->u.serverrefuse.reason) + 1); Net_CloseConnection(node); } @@ -3836,6 +4148,7 @@ static void HandleTimeout(SINT8 node) */ static void HandleServerInfo(SINT8 node) { + char servername[MAXSERVERNAME]; // compute ping in ms const tic_t ticnow = I_GetTime(); const tic_t ticthen = (tic_t)LONG(netbuffer->u.serverinfo.time); @@ -3844,6 +4157,8 @@ static void HandleServerInfo(SINT8 node) netbuffer->u.serverinfo.servername[MAXSERVERNAME-1] = 0; netbuffer->u.serverinfo.application [sizeof netbuffer->u.serverinfo.application - 1] = '\0'; + memcpy(servername, netbuffer->u.serverinfo.servername, MAXSERVERNAME); + CopyCaretColors(netbuffer->u.serverinfo.servername, servername, MAXSERVERNAME); netbuffer->u.serverinfo.gametype = (UINT8)((netbuffer->u.serverinfo.gametype == VANILLA_GT_MATCH) ? GT_MATCH : GT_RACE); SL_InsertServer(&netbuffer->u.serverinfo, node); @@ -3957,13 +4272,24 @@ static void HandlePacketFromAwayNode(SINT8 node) if (!reason) I_Error("Out of memory!\n"); - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); + if (strstr(reason, "Maximum players reached")) + { + serverisfull = true; + //Special timeout for when refusing due to player cap. The client will wait 3 seconds between join requests when waiting for a slot, so we need this to be much longer + //We set it back to the value of cv_nettimeout.value in CL_Reset + connectiontimeout = NEWTICRATE*7; + cl_mode = CL_ASKJOIN; + free(reason); + break; + } M_StartMessage(va(M_GetText("Server refuses connection\n\nReason:\n%s"), reason), NULL, MM_NOTHING); + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + free(reason); // Will be reset by caller. Signals refusal. @@ -3983,7 +4309,7 @@ static void HandlePacketFromAwayNode(SINT8 node) } SERVERONLY /// \note how would this happen? and is it doing the right thing if it does? - if (cl_mode != CL_WAITJOINRESPONSE) + if (!(cl_mode == CL_WAITJOINRESPONSE || cl_mode == CL_ASKJOIN)) break; if (client) @@ -3997,6 +4323,12 @@ static void HandlePacketFromAwayNode(SINT8 node) memcpy(server_context, netbuffer->u.servercfg.server_context, 8); } +#ifdef HAVE_DISCORDRPC + discordInfo.maxPlayers = netbuffer->u.servercfg.maxplayer; + discordInfo.joinsAllowed = netbuffer->u.servercfg.allownewplayer; + discordInfo.everyoneCanInvite = netbuffer->u.servercfg.discordinvites; +#endif + nodeingame[(UINT8)servernode] = true; serverplayer = netbuffer->u.servercfg.serverplayer; doomcom->numslots = SHORT(netbuffer->u.servercfg.totalslotnum); @@ -5346,7 +5678,9 @@ FILESTAMP GetPackets(); FILESTAMP +#ifdef MASTERSERVER MasterClient_Ticker(); +#endif if (client) { @@ -5403,7 +5737,9 @@ FILESTAMP // client send the command after a receive of the server // the server send before because in single player is beter +#ifdef MASTERSERVER MasterClient_Ticker(); // Acking the Master Server +#endif if (client) { @@ -5459,7 +5795,13 @@ FILESTAMP if (nowtime > resptime) { resptime = nowtime; +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif M_Ticker(); +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); +#endif CON_Ticker(); } SV_FileSendTicker(); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index e9b180dfe..e94fd7e83 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -18,6 +18,7 @@ #include "d_netcmd.h" #include "tables.h" #include "d_player.h" +#include "mserv.h" /* The 'packet version' is used to distinguish packet formats. @@ -333,6 +334,11 @@ typedef struct char server_context[8]; // Unique context id, generated at server startup. + // Discord info (always defined for net compatibility) + UINT8 maxplayer; + boolean allownewplayer; + boolean discordinvites; + UINT8 varlengthinputs[0]; // Playernames and netvars } ATTRPACK serverconfig_pak; @@ -530,7 +536,12 @@ typedef enum } kickreason_t; +/* the max number of name changes in some time period */ +#define MAXNAMECHANGES (5) +#define NAMECHANGERATE (60*TICRATE) + extern boolean server; +extern boolean serverrunning; #define client (!server) extern boolean dedicated; // For dedicated server extern UINT16 software_MAXPACKETLENGTH; @@ -552,6 +563,8 @@ extern consvar_t #endif cv_netticbuffer, cv_allownewplayer, cv_maxplayers, cv_resynchattempts, cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed; +extern consvar_t cv_discordinvites; + // Used in d_net, the only dependence tic_t ExpandTics(INT32 low, tic_t basetic); void D_ClientServerInit(void); @@ -577,7 +590,8 @@ void CL_RemoveSplitscreenPlayer(UINT8 p); void CL_Reset(void); void CL_ClearPlayer(INT32 playernum); void CL_RemovePlayer(INT32 playernum, INT32 reason); -void CL_UpdateServerList(boolean internetsearch, INT32 room); +void CL_QueryServerList(msg_server_t *list); +void CL_UpdateServerList(void); // Is there a game running boolean Playing(void); diff --git a/src/d_main.c b/src/d_main.c index 85b363e0e..0404dc446 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -50,6 +50,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #include "hu_stuff.h" #include "i_sound.h" #include "i_system.h" +#include "i_threads.h" #include "i_video.h" #include "m_argv.h" #include "m_menu.h" @@ -68,7 +69,6 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #include "m_cheat.h" #include "y_inter.h" #include "p_local.h" // chasecam -#include "mserv.h" // ms_RoomId #include "m_misc.h" // screenshot functionality #include "dehacked.h" // Dehacked list test #include "m_cond.h" // condition initialization @@ -102,6 +102,10 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #include "lua_script.h" #endif +#ifdef HAVE_DISCORDRPC +#include "discord.h" +#endif + // platform independant focus loss UINT8 window_notinfocus = false; @@ -196,6 +200,8 @@ void D_ProcessEvents(void) { event_t *ev; + boolean eaten; + for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1)) { ev = &events[eventtail]; @@ -217,7 +223,17 @@ void D_ProcessEvents(void) } // Menu input - if (M_Responder(ev)) +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif + { + eaten = M_Responder(ev); + } +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); +#endif + + if (eaten) continue; // menu ate the event // Demo input: @@ -226,7 +242,17 @@ void D_ProcessEvents(void) continue; // demo ate the event // console input - if (CON_Responder(ev)) +#ifdef HAVE_THREADS + I_lock_mutex(&con_mutex); +#endif + { + eaten = CON_Responder(ev); + } +#ifdef HAVE_THREADS + I_unlock_mutex(con_mutex); +#endif + + if (eaten) continue; // ate the event G_Responder(ev); @@ -522,7 +548,13 @@ static void D_Display(void) if (gamestate != GS_TIMEATTACK) CON_Drawer(); +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif M_Drawer(); // menu is drawn even on top of everything +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); +#endif // focus lost moved to M_Drawer // @@ -698,6 +730,10 @@ void D_SRB2Loop(void) #ifdef HAVE_BLUA LUA_Step(); #endif + +#ifdef HAVE_DISCORDRPC + Discord_RunCallbacks(); +#endif } } @@ -812,9 +848,23 @@ static inline void D_CleanFile(char **filearray) // Identify the SRB2 version, and IWAD file to use. // ========================================================================== +static boolean AddIWAD(void) +{ + char * path = va(pandf,srb2path,"srb2.srb"); + + if (FIL_ReadFileOK(path)) + { + D_AddFile(path, startupwadfiles); + return true; + } + else + { + return false; + } +} + static void IdentifyVersion(void) { - char *srb2wad1, *srb2wad2; const char *srb2waddir = NULL; #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) @@ -838,43 +888,21 @@ static void IdentifyVersion(void) #ifdef _arch_dreamcast srb2waddir = "/cd"; #else - srb2waddir = "."; + srb2waddir = srb2path; #endif } } -#if defined (macintosh) && !defined (HAVE_SDL) - // cwd is always "/" when app is dbl-clicked - if (!stricmp(srb2waddir, "/")) - srb2waddir = I_GetWadDir(); -#endif - // Commercial. - srb2wad1 = malloc(strlen(srb2waddir)+1+8+1); - srb2wad2 = malloc(strlen(srb2waddir)+1+8+1); - if (srb2wad1 == NULL && srb2wad2 == NULL) - I_Error("No more free memory to look in %s", srb2waddir); - if (srb2wad1 != NULL) - sprintf(srb2wad1, pandf, srb2waddir, "srb2.srb"); - if (srb2wad2 != NULL) - sprintf(srb2wad2, pandf, srb2waddir, "srb2.wad"); + // Load the IWAD + if (! AddIWAD()) + { + I_Error("SRB2.SRB not found! Expected in %s\n", srb2waddir); + } // will be overwritten in case of -cdrom or unix/win home snprintf(configfile, sizeof configfile, "%s" PATHSEP CONFIGFILENAME, srb2waddir); configfile[sizeof configfile - 1] = '\0'; - // Load the IWAD - if (srb2wad2 != NULL && FIL_ReadFileOK(srb2wad2)) - D_AddFile(srb2wad2, startupwadfiles); - else if (srb2wad1 != NULL && FIL_ReadFileOK(srb2wad1)) - D_AddFile(srb2wad1, startupwadfiles); - else - I_Error("SRB2.SRB/SRB2.WAD not found! Expected in %s, ss files: %s or %s\n", srb2waddir, srb2wad1, srb2wad2); - - if (srb2wad1) - free(srb2wad1); - if (srb2wad2) - free(srb2wad2); - // if you change the ordering of this or add/remove a file, be sure to update the md5 // checking in D_SRB2Main @@ -1395,17 +1423,6 @@ void D_SRB2Main(void) CONS_Printf("ST_Init(): Init status bar.\n"); ST_Init(); - if (M_CheckParm("-room")) - { - if (!M_IsNextParm()) - I_Error("usage: -room \nCheck the Master Server's webpage for room ID numbers.\n"); - ms_RoomId = atoi(M_GetNextParm()); - -#ifdef UPDATE_ALERT - GetMODVersion_Console(); -#endif - } - // Set up splitscreen players before joining! if (!dedicated && (M_CheckParm("-splitscreen") && M_IsNextParm())) { @@ -1581,6 +1598,10 @@ void D_SRB2Main(void) if (!P_SetupLevel(false)) I_Quit(); // fail so reset game stuff } + +#ifdef HAVE_DISCORDRPC + DRPC_Init(); +#endif } const char *D_Home(void) diff --git a/src/d_net.h b/src/d_net.h index 30de29916..607f3e901 100644 --- a/src/d_net.h +++ b/src/d_net.h @@ -19,7 +19,9 @@ #define __D_NET__ // Max computers in a game -#define MAXNETNODES 64 +// 127 is probably as high as this can go, because +// SINT8 is used for nodes sometimes >:( +#define MAXNETNODES 127 #define BROADCASTADDR MAXNETNODES #define NETSPLITSCREEN // Kart's splitscreen netgame feature @@ -41,6 +43,8 @@ extern SINT8 nodetoplayer4[MAXNETNODES]; // Say the numplayer for this node if a extern UINT8 playerpernode[MAXNETNODES]; // Used specially for splitscreen extern boolean nodeingame[MAXNETNODES]; // Set false as nodes leave game +extern boolean serverrunning; + INT32 Net_GetFreeAcks(boolean urgent); void Net_AckTicker(void); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 7d94d2ed2..4a90de333 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -55,6 +55,10 @@ #define CV_RESTRICT 0 #endif +#ifdef HAVE_DISCORDRPC +#include "discord.h" +#endif + // ------ // protos // ------ @@ -77,6 +81,7 @@ static void Got_RandomSeed(UINT8 **cp, INT32 playernum); static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum); static void Got_Teamchange(UINT8 **cp, INT32 playernum); static void Got_Clearscores(UINT8 **cp, INT32 playernum); +static void Got_DiscordInfo(UINT8 **cp, INT32 playernum); static void PointLimit_OnChange(void); static void TimeLimit_OnChange(void); @@ -704,10 +709,13 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_showping); #ifdef SEENAMES - CV_RegisterVar(&cv_allowseenames); + CV_RegisterVar(&cv_allowseenames); #endif CV_RegisterVar(&cv_dummyconsvar); + + CV_RegisterVar(&cv_discordinvites); + RegisterNetXCmd(XD_DISCORD, Got_DiscordInfo); } // ========================================================================= @@ -1000,6 +1008,12 @@ void D_RegisterClientCommands(void) #if defined(HAVE_BLUA) && defined(LUA_ALLOW_BYTECODE) COM_AddCommand("dumplua", Command_Dumplua_f); #endif + +#ifdef HAVE_DISCORDRPC + CV_RegisterVar(&cv_discordrp); + CV_RegisterVar(&cv_discordstreamer); + CV_RegisterVar(&cv_discordasks); +#endif } /** Checks if a name (as received from another player) is okay. @@ -1204,6 +1218,8 @@ static void SetPlayerName(INT32 playernum, char *newname) if (netgame) HU_AddChatText(va("\x82*%s renamed to %s", player_names[playernum], newname), false); + player_name_changes[playernum]++; + strcpy(player_names[playernum], newname); demo_extradata[playernum] |= DXD_NAME; } @@ -1385,7 +1401,12 @@ static void SendNameAndColor(void) snacpending++; // Don't change name if muted - if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) + if (player_name_changes[consoleplayer] >= MAXNAMECHANGES) + { + CV_StealthSet(&cv_playername, player_names[consoleplayer]); + HU_AddChatText("\x85*You must wait to change your name again", false); + } + else if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) CV_StealthSet(&cv_playername, player_names[consoleplayer]); else // Cleanup name if changing it CleanupPlayerName(consoleplayer, cv_playername.zstring); @@ -1509,7 +1530,12 @@ static void SendNameAndColor2(void) snac2pending++; // Don't change name if muted - if (cv_mute.value && !(server || IsPlayerAdmin(displayplayers[1]))) + if (player_name_changes[displayplayers[1]] >= MAXNAMECHANGES) + { + CV_StealthSet(&cv_playername2, player_names[displayplayers[1]]); + HU_AddChatText("\x85*You must wait to change your name again", false); + } + else if (cv_mute.value && !(server || IsPlayerAdmin(displayplayers[1]))) CV_StealthSet(&cv_playername2, player_names[displayplayers[1]]); else // Cleanup name if changing it CleanupPlayerName(displayplayers[1], cv_playername2.zstring); @@ -1624,7 +1650,12 @@ static void SendNameAndColor3(void) snac3pending++; // Don't change name if muted - if (cv_mute.value && !(server || IsPlayerAdmin(displayplayers[2]))) + if (player_name_changes[displayplayers[2]] >= MAXNAMECHANGES) + { + CV_StealthSet(&cv_playername3, player_names[displayplayers[2]]); + HU_AddChatText("\x85*You must wait to change your name again", false); + } + else if (cv_mute.value && !(server || IsPlayerAdmin(displayplayers[2]))) CV_StealthSet(&cv_playername3, player_names[displayplayers[2]]); else // Cleanup name if changing it CleanupPlayerName(displayplayers[2], cv_playername3.zstring); @@ -1747,7 +1778,12 @@ static void SendNameAndColor4(void) snac4pending++; // Don't change name if muted - if (cv_mute.value && !(server || IsPlayerAdmin(displayplayers[3]))) + if (player_name_changes[displayplayers[3]] >= MAXNAMECHANGES) + { + CV_StealthSet(&cv_playername4, player_names[displayplayers[3]]); + HU_AddChatText("\x85*You must wait to change your name again", false); + } + else if (cv_mute.value && !(server || IsPlayerAdmin(displayplayers[3]))) CV_StealthSet(&cv_playername4, player_names[displayplayers[3]]); else // Cleanup name if changing it CleanupPlayerName(displayplayers[3], cv_playername4.zstring); @@ -1802,8 +1838,11 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) skin = READUINT8(*cp); // set name - if (strcasecmp(player_names[playernum], name) != 0) - SetPlayerName(playernum, name); + if (player_name_changes[playernum] < MAXNAMECHANGES) + { + if (strcasecmp(player_names[playernum], name) != 0) + SetPlayerName(playernum, name); + } // set color p->skincolor = color % MAXSKINCOLORS; @@ -1859,6 +1898,11 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) } else SetPlayerSkinByNum(playernum, skin); + +#ifdef HAVE_DISCORDRPC + if (playernum == consoleplayer) + DRPC_UpdatePresence(); +#endif } void SendWeaponPref(void) @@ -2670,6 +2714,10 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) if (demo.recording) // Okay, level loaded, character spawned and skinned, G_BeginRecording(); // I AM NOW READY TO RECORD. demo.deferstart = true; + +#ifdef HAVE_DISCORDRPC + DRPC_UpdatePresence(); +#endif } static void Command_Pause(void) @@ -4088,7 +4136,7 @@ static void Command_RunSOC(void) static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum) { char filename[256]; - filestatus_t ncs = FS_NOTFOUND; + filestatus_t ncs = FS_NOTCHECKED; if (playernum != serverplayer && !IsPlayerAdmin(playernum)) { @@ -4260,7 +4308,7 @@ static void Command_Delfile(void) static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum) { char filename[241]; - filestatus_t ncs = FS_NOTFOUND; + filestatus_t ncs = FS_NOTCHECKED; UINT8 md5sum[16]; boolean kick = false; boolean toomany = false; @@ -4355,7 +4403,7 @@ static void Got_Delfilecmd(UINT8 **cp, INT32 playernum) static void Got_Addfilecmd(UINT8 **cp, INT32 playernum) { char filename[241]; - filestatus_t ncs = FS_NOTFOUND; + filestatus_t ncs = FS_NOTCHECKED; UINT8 md5sum[16]; READSTRINGN(*cp, filename, 240); @@ -4643,6 +4691,10 @@ static void TimeLimit_OnChange(void) } else if (netgame || multiplayer) CONS_Printf(M_GetText("Time limit disabled\n")); + +#ifdef HAVE_DISCORDRPC + DRPC_UpdatePresence(); +#endif } /** Adjusts certain settings to match a changed gametype. @@ -5668,3 +5720,32 @@ static void KartEliminateLast_OnChange(void) if (G_RaceGametype() && cv_karteliminatelast.value) P_CheckRacers(); } + +void Got_DiscordInfo(UINT8 **p, INT32 playernum) +{ + if (playernum != serverplayer /*&& !IsPlayerAdmin(playernum)*/) + { + // protect against hacked/buggy client + CONS_Alert(CONS_WARNING, M_GetText("Illegal Discord info command received from %s\n"), player_names[playernum]); + if (server) + { + XBOXSTATIC UINT8 buf[2]; + + buf[0] = (UINT8)playernum; + buf[1] = KICK_MSG_CON_FAIL; + SendNetXCmd(XD_KICK, &buf, 2); + } + return; + } + + // Don't do anything with the information if we don't have Discord RP support +#ifdef HAVE_DISCORDRPC + discordInfo.maxPlayers = READUINT8(*p); + discordInfo.joinsAllowed = (boolean)READUINT8(*p); + discordInfo.everyoneCanInvite = (boolean)READUINT8(*p); + + DRPC_UpdatePresence(); +#else + (*p) += 3; +#endif +} diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 2d8e5705a..1e1588083 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -178,9 +178,10 @@ typedef enum XD_MODIFYVOTE, // 23 XD_PICKVOTE, // 24 XD_REMOVEPLAYER,// 25 + XD_DISCORD, // 26 #ifdef HAVE_BLUA - XD_LUACMD, // 26 - XD_LUAVAR, // 27 + XD_LUACMD, // 27 + XD_LUAVAR, // 28 #endif MAXNETXCMD } netxcmd_t; diff --git a/src/d_netfil.c b/src/d_netfil.c index 3dc9da68c..c9bfb4ea7 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -108,6 +108,10 @@ char downloaddir[512] = "DOWNLOAD"; #ifdef CLIENT_LOADINGSCREEN // for cl loading screen INT32 lastfilenum = -1; +INT32 downloadcompletednum = 0; +UINT32 downloadcompletedsize = 0; +INT32 totalfilesrequestednum = 0; +UINT32 totalfilesrequestedsize = 0; #endif #ifdef HAVE_CURL @@ -141,7 +145,7 @@ UINT8 *PutFileNeeded(UINT16 firstfile) char wadfilename[MAX_WADPATH] = ""; UINT8 filestatus; - for (i = mainwads; i < numwadfiles; i++) + for (i = mainwads+1; i < numwadfiles; i++) //mainwads+1, otherwise we start on the first mainwad { // If it has only music/sound lumps, don't put it in the list if (!wadfiles[i]->important) @@ -207,7 +211,7 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi p = (UINT8 *)fileneededstr; for (i = firstfile; i < fileneedednum; i++) { - fileneeded[i].status = FS_NOTFOUND; // We haven't even started looking for the file yet + fileneeded[i].status = FS_NOTCHECKED; // We haven't even started looking for the file yet filestatus = READUINT8(p); // The first byte is the file status fileneeded[i].willsend = (UINT8)(filestatus >> 4); fileneeded[i].totalsize = READUINT32(p); // The four next bytes are the file size @@ -370,15 +374,17 @@ boolean Got_RequestFilePak(INT32 node) * \return 0 if some files are missing * 1 if all files exist * 2 if some already loaded files are not requested or are in a different order + * 3 too many files, over WADLIMIT + * 4 still checking, continuing next tic * */ INT32 CL_CheckFiles(void) { INT32 i, j; char wadfilename[MAX_WADPATH]; - INT32 ret = 1; size_t packetsize = 0; - size_t filestoget = 0; + size_t filestoload = 0; + boolean downloadrequired = false; // if (M_CheckParm("-nofiles")) // return 1; @@ -395,7 +401,7 @@ INT32 CL_CheckFiles(void) if (modifiedgame) { CONS_Debug(DBG_NETPLAY, "game is modified; only doing basic checks\n"); - for (i = 0, j = mainwads; i < fileneedednum || j < numwadfiles;) + for (i = 0, j = mainwads+1; i < fileneedednum || j < numwadfiles;) { if (j < numwadfiles && !wadfiles[j]->important) { @@ -424,10 +430,19 @@ INT32 CL_CheckFiles(void) for (i = 0; i < fileneedednum; i++) { + if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_FALLBACK) + downloadrequired = true; + + if (fileneeded[i].status == FS_FOUND || fileneeded[i].status == FS_NOTFOUND) + filestoload++; + + if (fileneeded[i].status != FS_NOTCHECKED) //since we're running this over multiple tics now, its possible for us to come across files checked in previous tics + continue; + CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename); // Check in already loaded files - for (j = mainwads; wadfiles[j]; j++) + for (j = mainwads+1; wadfiles[j]; j++) { nameonly(strcpy(wadfilename, wadfiles[j]->filename)); if (!stricmp(wadfilename, fileneeded[i].filename) && @@ -435,36 +450,35 @@ INT32 CL_CheckFiles(void) { CONS_Debug(DBG_NETPLAY, "already loaded\n"); fileneeded[i].status = FS_OPEN; - break; + return 4; } } - if (fileneeded[i].status != FS_NOTFOUND) - continue; packetsize += nameonlylength(fileneeded[i].filename) + 22; - if (mainwads+filestoget >= MAX_WADFILES) - return 3; - - filestoget++; - fileneeded[i].status = findfile(fileneeded[i].filename, fileneeded[i].md5sum, true); CONS_Debug(DBG_NETPLAY, "found %d\n", fileneeded[i].status); - if (fileneeded[i].status != FS_FOUND) - ret = 0; + return 4; } - return ret; + + //now making it here means we've checked the entire list and no FS_NOTCHECKED files remain + if (numwadfiles+filestoload > MAX_WADFILES) + return 3; + else if (downloadrequired) + return 0; //some stuff is FS_NOTFOUND, needs download + else + return 1; //everything is FS_OPEN or FS_FOUND, proceed to loading } // Load it now -void CL_LoadServerFiles(void) +boolean CL_LoadServerFiles(void) { INT32 i; // if (M_CheckParm("-nofiles")) // return; - for (i = 1; i < fileneedednum; i++) + for (i = 0; i < fileneedednum; i++) { if (fileneeded[i].status == FS_OPEN) continue; // Already loaded @@ -473,6 +487,7 @@ void CL_LoadServerFiles(void) P_AddWadFile(fileneeded[i].filename); G_SetGameModified(true, false); fileneeded[i].status = FS_OPEN; + return false; } else if (fileneeded[i].status == FS_MD5SUMBAD) I_Error("Wrong version of file %s", fileneeded[i].filename); @@ -498,6 +513,7 @@ void CL_LoadServerFiles(void) fileneeded[i].status, s); } } + return true; } // Number of files to send @@ -858,6 +874,10 @@ void Got_Filetxpak(void) file->status = FS_FOUND; CONS_Printf(M_GetText("Downloading %s...(done)\n"), filename); +#ifndef NONET + downloadcompletednum++; + downloadcompletedsize += file->totalsize; +#endif } } else @@ -1088,7 +1108,7 @@ void CURLPrepareFile(const char* url, int dfilenum) // Only allow HTTP and HTTPS curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS); - curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("SRB2Kart/v%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents. + curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("SRB2Kart/v%d.%d", VERSION, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents. // Follow a redirect request, if sent by the server. curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1L); @@ -1169,6 +1189,8 @@ void CURLGetFile(void) { nameonly(curl_realname); CONS_Printf(M_GetText("Finished downloading %s\n"), curl_realname); + downloadcompletednum++; + downloadcompletedsize += curl_curfile->totalsize; curl_curfile->status = FS_FOUND; fclose(curl_curfile->file); } diff --git a/src/d_netfil.h b/src/d_netfil.h index f37df371f..905364e30 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -25,6 +25,7 @@ typedef enum typedef enum { + FS_NOTCHECKED, FS_NOTFOUND, FS_FOUND, FS_REQUESTED, @@ -52,6 +53,10 @@ extern char downloaddir[512]; #ifdef CLIENT_LOADINGSCREEN extern INT32 lastfilenum; +extern INT32 downloadcompletednum; +extern UINT32 downloadcompletedsize; +extern INT32 totalfilesrequestednum; +extern UINT32 totalfilesrequestedsize; #endif #ifdef HAVE_CURL @@ -65,7 +70,7 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi void CL_PrepareDownloadSaveGame(const char *tmpsave); INT32 CL_CheckFiles(void); -void CL_LoadServerFiles(void); +boolean CL_LoadServerFiles(void); void SV_SendRam(INT32 node, void *data, size_t size, freemethod_t freemethod, UINT8 fileid); diff --git a/src/dehacked.c b/src/dehacked.c index 96d82fff4..00f4fa96d 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -925,6 +925,18 @@ static void readlevelheader(MYFILE *f, INT32 num) sizeof(mapheaderinfo[num-1]->subttl), va("Level header %d: subtitle", num)); continue; } + else if (fastcmp(word, "LEVELNAME")) + { + deh_strlcpy(mapheaderinfo[num-1]->lvlttl, word2, + sizeof(mapheaderinfo[num-1]->lvlttl), va("Level header %d: levelname", num)); + continue; + } + else if (fastcmp(word, "ZONETITLE")) + { + deh_strlcpy(mapheaderinfo[num-1]->zonttl, word2, + sizeof(mapheaderinfo[num-1]->zonttl), va("Level header %d: zonetitle", num)); + continue; + } // Lua custom options also go above, contents may be case sensitive. if (fastncmp(word, "LUA.", 4)) @@ -987,16 +999,6 @@ static void readlevelheader(MYFILE *f, INT32 num) } // Strings that can be truncated - else if (fastcmp(word, "LEVELNAME")) - { - deh_strlcpy(mapheaderinfo[num-1]->lvlttl, word2, - sizeof(mapheaderinfo[num-1]->lvlttl), va("Level header %d: levelname", num)); - } - else if (fastcmp(word, "ZONETITLE")) - { - deh_strlcpy(mapheaderinfo[num-1]->zonttl, word2, - sizeof(mapheaderinfo[num-1]->zonttl), va("Level header %d: zonetitle", num)); - } else if (fastcmp(word, "SCRIPTNAME")) { deh_strlcpy(mapheaderinfo[num-1]->scriptname, word2, @@ -7764,7 +7766,6 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_TWINKLECARTAMBIENCE", "MT_EXPLODINGBARREL", "MT_MERRYHORSE", - "MT_ARIDTOAD", "MT_BLUEFRUIT", "MT_ORANGEFRUIT", "MT_REDFRUIT", @@ -7775,6 +7776,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_BOOSTPROMPT", "MT_BOOSTOFF", "MT_BOOSTON", + "MT_ARIDTOAD", "MT_LIZARDMAN", "MT_LIONMAN", @@ -8622,13 +8624,11 @@ struct { {"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel {"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop. -#ifdef ESLOPE // Slope flags {"SL_NOPHYSICS",SL_NOPHYSICS}, // Don't do momentum adjustment with this slope {"SL_NODYNAMIC",SL_NODYNAMIC}, // Slope will never need to move during the level, so don't fuss with recalculating it {"SL_ANCHORVERTEX",SL_ANCHORVERTEX},// Slope is using a Slope Vertex Thing to anchor its position {"SL_VERTEXSLOPE",SL_VERTEXSLOPE}, // Slope is built from three Slope Vertex Things -#endif // Angles {"ANG1",ANG1}, @@ -9764,6 +9764,9 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"exitcountdown")) { lua_pushinteger(L, exitcountdown); // This name is pretty dumb. Hence why we'll prefer more descriptive names at least in Lua... return 1; + } else if (fastcmp(word,"replayplayback")) { + lua_pushboolean(L, demo.playback); + return 1; } return 0; } diff --git a/src/discord.c b/src/discord.c new file mode 100644 index 000000000..99cc0a3bd --- /dev/null +++ b/src/discord.c @@ -0,0 +1,707 @@ +// SONIC ROBO BLAST 2 KART +//----------------------------------------------------------------------------- +// Copyright (C) 2018-2020 by Sally "TehRealSalt" Cochenour. +// Copyright (C) 2018-2020 by Kart Krew. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file discord.h +/// \brief Discord Rich Presence handling + +#ifdef HAVE_DISCORDRPC + +#ifdef HAVE_CURL +#include +#endif // HAVE_CURL + +#include "i_system.h" +#include "d_clisrv.h" +#include "d_netcmd.h" +#include "i_net.h" +#include "g_game.h" +#include "p_tick.h" +#include "m_menu.h" // gametype_cons_t +#include "r_things.h" // skins +#include "mserv.h" // cv_advertise +#include "z_zone.h" +#include "byteptr.h" + +#include "discord.h" +#include "doomdef.h" + +// Feel free to provide your own, if you care enough to create another Discord app for this :P +#define DISCORD_APPID "503531144395096085" + +// length of IP strings +#define IP_SIZE 21 + +consvar_t cv_discordrp = {"discordrp", "On", CV_SAVE|CV_CALL, CV_OnOff, DRPC_UpdatePresence, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_discordstreamer = {"discordstreamer", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_discordasks = {"discordasks", "Yes", CV_SAVE|CV_CALL, CV_YesNo, DRPC_UpdatePresence, 0, NULL, NULL, 0, 0, NULL}; + +struct discordInfo_s discordInfo; + +discordRequest_t *discordRequestList = NULL; + +#ifdef HAVE_CURL +struct SelfIPbuffer +{ + CURL *curl; + char *pointer; + size_t length; +}; + +static char self_ip[IP_SIZE]; +#endif // HAVE_CURL + +/*-------------------------------------------------- + static char *DRPC_XORIPString(const char *input) + + Simple XOR encryption/decryption. Not complex or + very secretive because we aren't sending anything + that isn't easily accessible via our Master Server anyway. +--------------------------------------------------*/ +static char *DRPC_XORIPString(const char *input) +{ + const UINT8 xor[IP_SIZE] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}; + char *output = malloc(sizeof(char) * (IP_SIZE+1)); + UINT8 i; + + for (i = 0; i < IP_SIZE; i++) + { + char xorinput; + + if (!input[i]) + break; + + xorinput = input[i] ^ xor[i]; + + if (xorinput < 32 || xorinput > 126) + { + xorinput = input[i]; + } + + output[i] = xorinput; + } + + output[i] = '\0'; + + return output; +} + +/*-------------------------------------------------- + static void DRPC_HandleReady(const DiscordUser *user) + + Callback function, ran when the game connects to Discord. + + Input Arguments:- + user - Struct containing Discord user info. + + Return:- + None +--------------------------------------------------*/ +static void DRPC_HandleReady(const DiscordUser *user) +{ + if (cv_discordstreamer.value) + { + CONS_Printf("Discord: connected to %s\n", user->username); + } + else + { + CONS_Printf("Discord: connected to %s#%s (%s)\n", user->username, user->discriminator, user->userId); + } +} + +/*-------------------------------------------------- + static void DRPC_HandleDisconnect(int err, const char *msg) + + Callback function, ran when disconnecting from Discord. + + Input Arguments:- + err - Error type + msg - Error message + + Return:- + None +--------------------------------------------------*/ +static void DRPC_HandleDisconnect(int err, const char *msg) +{ + CONS_Printf("Discord: disconnected (%d: %s)\n", err, msg); +} + +/*-------------------------------------------------- + static void DRPC_HandleError(int err, const char *msg) + + Callback function, ran when Discord outputs an error. + + Input Arguments:- + err - Error type + msg - Error message + + Return:- + None +--------------------------------------------------*/ +static void DRPC_HandleError(int err, const char *msg) +{ + CONS_Alert(CONS_WARNING, "Discord error (%d: %s)\n", err, msg); +} + +/*-------------------------------------------------- + static void DRPC_HandleJoin(const char *secret) + + Callback function, ran when Discord wants to + connect a player to the game via a channel invite + or a join request. + + Input Arguments:- + secret - Value that links you to the server. + + Return:- + None +--------------------------------------------------*/ +static void DRPC_HandleJoin(const char *secret) +{ + char *ip = DRPC_XORIPString(secret); + CONS_Printf("Connecting to %s via Discord\n", ip); + COM_BufAddText(va("connect \"%s\"\n", ip)); + free(ip); +} + +/*-------------------------------------------------- + static boolean DRPC_InvitesAreAllowed(void) + + Determines whenever or not invites or + ask to join requests are allowed. + + Input Arguments:- + None + + Return:- + true if invites are allowed, false otherwise. +--------------------------------------------------*/ +static boolean DRPC_InvitesAreAllowed(void) +{ + if (!Playing()) + { + // We're not playing, so we should not be getting invites. + return false; + } + + if (cv_discordasks.value == 0) + { + // Client has the CVar set to off, so never allow invites from this client. + return false; + } + + if (discordInfo.joinsAllowed == true) + { + if (discordInfo.everyoneCanInvite == true) + { + // Everyone's allowed! + return true; + } + else if (consoleplayer == serverplayer || IsPlayerAdmin(consoleplayer)) + { + // Only admins are allowed! + return true; + } + } + + // Did not pass any of the checks + return false; +} + +/*-------------------------------------------------- + static void DRPC_HandleJoinRequest(const DiscordUser *requestUser) + + Callback function, ran when Discord wants to + ask the player if another Discord user can join + or not. + + Input Arguments:- + requestUser - DiscordUser struct for the user trying to connect. + + Return:- + None +--------------------------------------------------*/ +static void DRPC_HandleJoinRequest(const DiscordUser *requestUser) +{ + discordRequest_t *append = discordRequestList; + discordRequest_t *newRequest; + + if (DRPC_InvitesAreAllowed() == false) + { + // Something weird happened if this occurred... + Discord_Respond(requestUser->userId, DISCORD_REPLY_IGNORE); + return; + } + + newRequest = Z_Calloc(sizeof(discordRequest_t), PU_STATIC, NULL); + + newRequest->username = Z_Calloc(344, PU_STATIC, NULL); + snprintf(newRequest->username, 344, "%s", requestUser->username); + + newRequest->discriminator = Z_Calloc(8, PU_STATIC, NULL); + snprintf(newRequest->discriminator, 8, "%s", requestUser->discriminator); + + newRequest->userID = Z_Calloc(32, PU_STATIC, NULL); + snprintf(newRequest->userID, 32, "%s", requestUser->userId); + + if (append != NULL) + { + discordRequest_t *prev = NULL; + + while (append != NULL) + { + // CHECK FOR DUPES!! Ignore any that already exist from the same user. + if (!strcmp(newRequest->userID, append->userID)) + { + Discord_Respond(newRequest->userID, DISCORD_REPLY_IGNORE); + DRPC_RemoveRequest(newRequest); + return; + } + + prev = append; + append = append->next; + } + + newRequest->prev = prev; + prev->next = newRequest; + } + else + { + discordRequestList = newRequest; + M_RefreshPauseMenu(); + } + + // Made it to the end, request was valid, so play the request sound :) + S_StartSound(NULL, sfx_requst); +} + +/*-------------------------------------------------- + void DRPC_RemoveRequest(discordRequest_t *removeRequest) + + See header file for description. +--------------------------------------------------*/ +void DRPC_RemoveRequest(discordRequest_t *removeRequest) +{ + if (removeRequest->prev != NULL) + { + removeRequest->prev->next = removeRequest->next; + } + + if (removeRequest->next != NULL) + { + removeRequest->next->prev = removeRequest->prev; + + if (removeRequest == discordRequestList) + { + discordRequestList = removeRequest->next; + } + } + else + { + if (removeRequest == discordRequestList) + { + discordRequestList = NULL; + } + } + + Z_Free(removeRequest->username); + Z_Free(removeRequest->userID); + Z_Free(removeRequest); +} + +/*-------------------------------------------------- + void DRPC_Init(void) + + See header file for description. +--------------------------------------------------*/ +void DRPC_Init(void) +{ + DiscordEventHandlers handlers; + memset(&handlers, 0, sizeof(handlers)); + + handlers.ready = DRPC_HandleReady; + handlers.disconnected = DRPC_HandleDisconnect; + handlers.errored = DRPC_HandleError; + handlers.joinGame = DRPC_HandleJoin; + handlers.joinRequest = DRPC_HandleJoinRequest; + + Discord_Initialize(DISCORD_APPID, &handlers, 1, NULL); + I_AddExitFunc(Discord_Shutdown); + DRPC_UpdatePresence(); +} + +#ifdef HAVE_CURL +/*-------------------------------------------------- + static size_t DRPC_WriteServerIP(char *s, size_t size, size_t n, void *userdata) + + Writing function for use with curl. Only intended to be used with simple text. + + Input Arguments:- + s - Data to write + size - Always 1. + n - Length of data + userdata - Passed in from CURLOPT_WRITEDATA, intended to be SelfIPbuffer + + Return:- + Number of bytes wrote in this pass. +--------------------------------------------------*/ +static size_t DRPC_WriteServerIP(char *s, size_t size, size_t n, void *userdata) +{ + struct SelfIPbuffer *buffer; + size_t newlength; + + buffer = userdata; + + newlength = buffer->length + size*n; + buffer->pointer = realloc(buffer->pointer, newlength+1); + + memcpy(buffer->pointer + buffer->length, s, size*n); + + buffer->pointer[newlength] = '\0'; + buffer->length = newlength; + + return size*n; +} +#endif // HAVE_CURL + +/*-------------------------------------------------- + static const char *DRPC_GetServerIP(void) + + Retrieves the IP address of the server that you're + connected to. Will attempt to use curl for getting your + own IP address, if it's not yours. +--------------------------------------------------*/ +static const char *DRPC_GetServerIP(void) +{ + const char *address; + + // If you're connected + if (I_GetNodeAddress && (address = I_GetNodeAddress(servernode)) != NULL) + { + if (strcmp(address, "self")) + { + // We're not the server, so we could successfully get the IP! + // No need to do anything else :) + return address; + } + } + +#ifdef HAVE_CURL + // This is a little bit goofy, but + // there's practically no good way to get your own public IP address, + // so we've gotta break out curl for this :V + if (!self_ip[0]) + { + CURL *curl; + + curl_global_init(CURL_GLOBAL_ALL); + curl = curl_easy_init(); + + if (curl) + { + // The API to get your public IP address from. + // Picked because it's stupid simple and it's been up for a long time. + const char *api = "http://ip4only.me/api/"; + + struct SelfIPbuffer buffer; + CURLcode success; + + buffer.length = 0; + buffer.pointer = malloc(buffer.length+1); + buffer.pointer[0] = '\0'; + + curl_easy_setopt(curl, CURLOPT_URL, api); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, DRPC_WriteServerIP); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer); + + success = curl_easy_perform(curl); + + if (success == CURLE_OK) + { + char *tmp; + tmp = strtok(buffer.pointer, ","); + + if (!strcmp(tmp, "IPv4")) // ensure correct type of IP + { + tmp = strtok(NULL, ","); + strncpy(self_ip, tmp, IP_SIZE); // Yay, we have the IP :) + } + } + + free(buffer.pointer); + curl_easy_cleanup(curl); + } + + curl_global_cleanup(); + } + + if (self_ip[0]) + return self_ip; + else +#endif // HAVE_CURL + return NULL; // Could not get your IP for whatever reason, so we cannot do Discord invites +} + +/*-------------------------------------------------- + void DRPC_EmptyRequests(void) + + Empties the request list. Any existing requests + will get an ignore reply. +--------------------------------------------------*/ +static void DRPC_EmptyRequests(void) +{ + while (discordRequestList != NULL) + { + Discord_Respond(discordRequestList->userID, DISCORD_REPLY_IGNORE); + DRPC_RemoveRequest(discordRequestList); + } +} + +/*-------------------------------------------------- + void DRPC_UpdatePresence(void) + + See header file for description. +--------------------------------------------------*/ +void DRPC_UpdatePresence(void) +{ + char detailstr[48+1]; + + char mapimg[8+1]; + char mapname[5+21+21+2+1]; + + char charimg[4+SKINNAMESIZE+1]; + char charname[11+SKINNAMESIZE+1]; + + boolean joinSecretSet = false; + + DiscordRichPresence discordPresence; + memset(&discordPresence, 0, sizeof(discordPresence)); + + if (!cv_discordrp.value) + { + // User doesn't want to show their game information, so update with empty presence. + // This just shows that they're playing SRB2Kart. (If that's too much, then they should disable game activity :V) + DRPC_EmptyRequests(); + Discord_UpdatePresence(&discordPresence); + return; + } + +#ifdef DEVELOP + // This way, we can use the invite feature in-dev, but not have snoopers seeing any potential secrets! :P + discordPresence.largeImageKey = "miscdevelop"; + discordPresence.largeImageText = "No peeking!"; + discordPresence.state = "Testing the game"; + + DRPC_EmptyRequests(); + Discord_UpdatePresence(&discordPresence); + return; +#endif // DEVELOP + + // Server info + if (netgame) + { + if (cv_advertise.value) + { + discordPresence.state = "Public"; + } + else + { + discordPresence.state = "Private"; + } + + discordPresence.partyId = server_context; // Thanks, whoever gave us Mumble support, for implementing the EXACT thing Discord wanted for this field! + discordPresence.partySize = D_NumPlayers(); // Players in server + discordPresence.partyMax = discordInfo.maxPlayers; // Max players + + if (DRPC_InvitesAreAllowed() == true) + { + const char *join; + + // Grab the host's IP for joining. + if ((join = DRPC_GetServerIP()) != NULL) + { + char *xorjoin = DRPC_XORIPString(join); + discordPresence.joinSecret = xorjoin; + free(xorjoin); + + joinSecretSet = true; + } + } + } + else + { + // Reset discord info if you're not in a place that uses it! + // Important for if you join a server that compiled without HAVE_DISCORDRPC, + // so that you don't ever end up using bad information from another server. + memset(&discordInfo, 0, sizeof(discordInfo)); + + // Offline info + if (Playing()) + discordPresence.state = "Offline"; + else if (demo.playback && !demo.title) + discordPresence.state = "Watching Replay"; + else + discordPresence.state = "Menu"; + } + + // Gametype info + if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING) && Playing()) + { + if (modeattacking) + discordPresence.details = "Time Attack"; + else + { + snprintf(detailstr, 48, "%s%s%s", + gametype_cons_t[gametype].strvalue, + (gametype == GT_RACE) ? va(" | %s", kartspeed_cons_t[gamespeed].strvalue) : "", + (encoremode == true) ? " | Encore" : "" + ); + discordPresence.details = detailstr; + } + } + + if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) // Map info + && !(demo.playback && demo.title)) + { + if ((gamemap >= 1 && gamemap <= 60) // supported race maps + || (gamemap >= 136 && gamemap <= 164)) // supported battle maps + { + snprintf(mapimg, 8, "%s", G_BuildMapName(gamemap)); + strlwr(mapimg); + discordPresence.largeImageKey = mapimg; // Map image + } + else if (mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU) + { + // Hell map, use the method that got you here :P + discordPresence.largeImageKey = "miscdice"; + } + else + { + // This is probably a custom map! + discordPresence.largeImageKey = "mapcustom"; + } + + if (mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU) + { + // Hell map, hide the name + discordPresence.largeImageText = "Map: ???"; + } + else + { + // Map name on tool tip + snprintf(mapname, 48, "Map: %s", G_BuildMapTitle(gamemap)); + discordPresence.largeImageText = mapname; + } + + if (gamestate == GS_LEVEL && Playing()) + { + const time_t currentTime = time(NULL); + const time_t mapTimeStart = currentTime - ((leveltime + (modeattacking ? starttime : 0)) / TICRATE); + + discordPresence.startTimestamp = mapTimeStart; + + if (timelimitintics > 0) + { + const time_t mapTimeEnd = mapTimeStart + ((timelimitintics + starttime + 1) / TICRATE); + discordPresence.endTimestamp = mapTimeEnd; + } + } + } + else if (gamestate == GS_VOTING) + { + discordPresence.largeImageKey = (G_BattleGametype() ? "miscredplanet" : "miscblueplanet"); + discordPresence.largeImageText = "Voting"; + } + else + { + discordPresence.largeImageKey = "misctitle"; + discordPresence.largeImageText = "Title Screen"; + } + + // Character info + if (Playing() && playeringame[consoleplayer] && !players[consoleplayer].spectator) + { + // Supported skin names + static const char *supportedSkins[] = { + // base game + "sonic", + "tails", + "knuckles", + "eggman", + "metalsonic", + // bonus chars + "flicky", + "motobug", + "amy", + "mighty", + "ray", + "espio", + "vector", + "chao", + "gamma", + "chaos", + "shadow", + "rouge", + "herochao", + "darkchao", + "cream", + "omega", + "blaze", + "silver", + "wonderboy", + "arle", + "nights", + "sakura", + "ulala", + "beat", + "vyse", + "aiai", + "kiryu", + "aigis", + "miku", + "doom", + NULL + }; + + boolean customChar = true; + UINT8 checkSkin = 0; + + // Character image + while (supportedSkins[checkSkin] != NULL) + { + if (!strcmp(skins[players[consoleplayer].skin].name, supportedSkins[checkSkin])) + { + snprintf(charimg, 21, "char%s", supportedSkins[checkSkin]); + discordPresence.smallImageKey = charimg; + customChar = false; + break; + } + + checkSkin++; + } + + if (customChar == true) + { + // Use the custom character icon! + discordPresence.smallImageKey = "charcustom"; + } + + snprintf(charname, 28, "Character: %s", skins[players[consoleplayer].skin].realname); + discordPresence.smallImageText = charname; // Character name + } + + if (joinSecretSet == false) + { + // Not able to join? Flush the request list, if it exists. + DRPC_EmptyRequests(); + } + + Discord_UpdatePresence(&discordPresence); +} + +#endif // HAVE_DISCORDRPC diff --git a/src/discord.h b/src/discord.h new file mode 100644 index 000000000..a6bb1134a --- /dev/null +++ b/src/discord.h @@ -0,0 +1,80 @@ +// SONIC ROBO BLAST 2 KART +//----------------------------------------------------------------------------- +// Copyright (C) 2018-2020 by Sally "TehRealSalt" Cochenour. +// Copyright (C) 2018-2020 by Kart Krew. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file discord.h +/// \brief Discord Rich Presence handling + +#ifndef __DISCORD__ +#define __DISCORD__ + +#ifdef HAVE_DISCORDRPC + +#include "discord_rpc.h" + +extern consvar_t cv_discordrp; +extern consvar_t cv_discordstreamer; +extern consvar_t cv_discordasks; + +extern struct discordInfo_s { + UINT8 maxPlayers; + boolean joinsAllowed; + boolean everyoneCanInvite; +} discordInfo; + +typedef struct discordRequest_s { + char *username; // Discord user name. + char *discriminator; // Discord discriminator (The little hashtag thing after the username). Separated for a "hide discriminators" cvar. + char *userID; // The ID of the Discord user, gets used with Discord_Respond() + + // HAHAHA, no. + // *Maybe* if it was only PNG I would boot up curl just to get AND convert this to Doom GFX, + // but it can *also* be a JEPG, WebP, or GIF :) + // Hey, wanna add ImageMagick as a dependency? :dying: + //patch_t *avatar; + + struct discordRequest_s *next; // Next request in the list. + struct discordRequest_s *prev; // Previous request in the list. Not used normally, but just in case something funky happens, this should repair the list. +} discordRequest_t; + +extern discordRequest_t *discordRequestList; + + +/*-------------------------------------------------- + void DRPC_RemoveRequest(void); + + Removes an invite from the list. +--------------------------------------------------*/ + +void DRPC_RemoveRequest(discordRequest_t *removeRequest); + + +/*-------------------------------------------------- + void DRPC_Init(void); + + Initalizes Discord Rich Presence by linking the Application ID + and setting the callback functions. +--------------------------------------------------*/ + +void DRPC_Init(void); + + +/*-------------------------------------------------- + void DRPC_UpdatePresence(void); + + Updates what is displayed by Rich Presence on the user's profile. + Should be called whenever something that is displayed is + changed in-game. +--------------------------------------------------*/ + +void DRPC_UpdatePresence(void); + + +#endif // HAVE_DISCORDRPC + +#endif // __DISCORD__ diff --git a/src/doomdef.h b/src/doomdef.h index 392ba7605..79ab2e13a 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -30,7 +30,6 @@ #ifdef HAVE_MIXER //#if !defined(DC) && !defined(_WIN32_WCE) && !defined(_XBOX) && !defined(GP2X) #define SOUND SOUND_MIXER - #define NOHS // No HW3SOUND #ifdef HW3SOUND #undef HW3SOUND #endif @@ -47,7 +46,6 @@ // Use FMOD? #ifdef HAVE_FMOD #define SOUND SOUND_FMOD - #define NOHS // No HW3SOUND #ifdef HW3SOUND #undef HW3SOUND #endif @@ -64,10 +62,6 @@ #if !defined (HWRENDER) && !defined (NOHW) #define HWRENDER #endif -// judgecutor: 3D sound support -#if !defined(HW3SOUND) && !defined (NOHS) -#define HW3SOUND -#endif #endif #if defined (_WIN32) || defined (_WIN32_WCE) @@ -154,9 +148,9 @@ extern char logfilename[1024]; // we use comprevision and compbranch instead. #else #define VERSION 1 // Game version -#define SUBVERSION 2 // more precise version number -#define VERSIONSTRING "v1.2" -#define VERSIONSTRINGW L"v1.2" +#define SUBVERSION 3 // more precise version number +#define VERSIONSTRING "v1.3" +#define VERSIONSTRINGW L"v1.3" // Hey! If you change this, add 1 to the MODVERSION below! Otherwise we can't force updates! // And change CMakeLists.txt, for CMake users! // AND appveyor.yml, for the build bots! @@ -187,32 +181,13 @@ extern char logfilename[1024]; // Please change to apply to your modification (we don't want everyone asking where your mod is on SRB2.org!). #define UPDATE_ALERT_STRING \ "A new update is available for SRB2Kart.\n"\ -"Please visit mb.srb2.org to download it.\n"\ +"Please visit kartkrew.org to download it.\n"\ "\n"\ "You are using version: %s\n"\ "The newest version is: %s\n"\ "\n"\ -"This update is required for online\n"\ -"play using the Master Server.\n"\ -"You will not be able to connect to\n"\ -"the Master Server until you update to\n"\ -"the newest version of the game.\n"\ -"\n"\ "(Press a key)\n" -// The string used in the I_Error alert upon trying to host through command line parameters. -// Generally less filled with newlines, since Windows gives you lots more room to work with. -#define UPDATE_ALERT_STRING_CONSOLE \ -"A new update is available for SRB2Kart.\n"\ -"Please visit mb.srb2.org to download it.\n"\ -"\n"\ -"You are using version: %s\n"\ -"The newest version is: %s\n"\ -"\n"\ -"This update is required for online play using the Master Server.\n"\ -"You will not be able to connect to the Master Server\n"\ -"until you update to the newest version of the game.\n" - // For future use, the codebase is the version of SRB2 that the modification is based on, // and should not be changed unless you have merged changes between versions of SRB2 // (such as 2.0.4 to 2.0.5, etc) into your working copy. @@ -229,7 +204,7 @@ extern char logfilename[1024]; // it's only for detection of the version the player is using so the MS can alert them of an update. // Only set it higher, not lower, obviously. // Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1". -#define MODVERSION 6 +#define MODVERSION 7 // Filter consvars by version // To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically. @@ -606,11 +581,9 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Kalaron/Eternity Engine slope code (SRB2CB ported) #define ESLOPE -#ifdef ESLOPE /// Backwards compatibility with SRB2CB's slope linedef types. /// \note A simple shim that prints a warning. #define ESLOPE_TYPESHIM -#endif /// Delete file while the game is running. /// \note EXTREMELY buggy, tends to crash game. @@ -681,4 +654,10 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Hardware renderer: OpenGL #define GL_SHADERS +#if defined (HAVE_CURL) && ! defined (NONET) +#define MASTERSERVER +#else +#undef UPDATE_ALERT +#endif + #endif // __DOOMDEF__ diff --git a/src/f_finale.c b/src/f_finale.c index 909ca2611..ade26bbe0 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -24,6 +24,7 @@ #include "w_wad.h" #include "z_zone.h" #include "i_system.h" +#include "i_threads.h" #include "m_menu.h" #include "dehacked.h" #include "g_input.h" @@ -317,7 +318,13 @@ void F_IntroDrawer(void) { I_OsPolling(); I_UpdateNoBlit(); +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif M_Drawer(); // menu is drawn even on top of wipes +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); +#endif I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001 } } diff --git a/src/f_wipe.c b/src/f_wipe.c index bb1397bcf..8bcb12782 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -22,6 +22,7 @@ #include "z_zone.h" #include "i_system.h" +#include "i_threads.h" #include "m_menu.h" #include "console.h" #include "d_main.h" @@ -379,7 +380,15 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu) I_UpdateNoBlit(); if (drawMenu) + { +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif M_Drawer(); // menu is drawn even on top of wipes +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); +#endif + } I_FinishUpdate(); // page flip or blit buffer diff --git a/src/g_game.c b/src/g_game.c index dd0d8460b..065ce7a33 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -51,6 +51,10 @@ #include "md5.h" // demo checksums #include "k_kart.h" // SRB2kart +#ifdef HAVE_DISCORDRPC +#include "discord.h" +#endif + gameaction_t gameaction; gamestate_t gamestate = GS_NULL; UINT8 ultimatemode = false; @@ -544,6 +548,8 @@ char player_names[MAXPLAYERS][MAXPLAYERNAME+1] = "Player 16" }; // SRB2kart - removed Players 17 through 32 +INT32 player_name_changes[MAXPLAYERS]; + INT16 rw_maximums[NUM_WEAPONS] = { 800, // MAX_INFINITY @@ -2498,6 +2504,11 @@ void G_Ticker(boolean run) spectatedelay3--; if (spectatedelay4) spectatedelay4--; + + if (gametic % NAMECHANGERATE == 0) + { + memset(player_name_changes, 0, sizeof player_name_changes); + } } } @@ -3647,7 +3658,7 @@ INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer, UINT8 maph void G_AddMapToBuffer(INT16 map) { - INT16 bufx, refreshnum = (TOLMaps(G_TOLFlag(gametype)) / 2) + 1; + INT16 bufx, refreshnum = max(0, TOLMaps(G_TOLFlag(gametype))-3); // Add the map to the buffer. for (bufx = NUMMAPS-1; bufx > 0; bufx--) @@ -4717,7 +4728,7 @@ char *G_BuildMapTitle(INT32 mapnum) } else if (!(mapheaderinfo[mapnum-1]->levelflags & LF_NOZONE)) { - zonetext = M_GetText("ZONE"); + zonetext = M_GetText("Zone"); len += strlen(zonetext) + 1; // ' ' + zonetext } if (strlen(mapheaderinfo[mapnum-1]->actnum) > 0) @@ -6326,8 +6337,8 @@ void G_RecordDemo(const char *name) maxsize = 1024*1024*2; if (M_CheckParm("-maxdemo") && M_IsNextParm()) maxsize = atoi(M_GetNextParm()) * 1024; -// if (demobuffer) -// free(demobuffer); + if (demobuffer) + free(demobuffer); demo_p = NULL; demobuffer = malloc(maxsize); demoend = demobuffer + maxsize; @@ -6368,7 +6379,9 @@ void G_BeginRecording(void) demoflags |= DF_ENCORE; #ifdef HAVE_BLUA - demoflags |= DF_LUAVARS; + if (!modeattacking) // Ghosts don't read luavars, and you shouldn't ever need to save Lua in replays, you doof! + // SERIOUSLY THOUGH WHY WOULD YOU LOAD HOSTMOD AND RECORD A GHOST WITH IT !???? + demoflags |= DF_LUAVARS; #endif // Setup header. @@ -6379,7 +6392,7 @@ void G_BeginRecording(void) // Full replay title demo_p += 64; - snprintf(demo.titlename, 64, "%s - %s", G_BuildMapTitle(gamemap), modeattacking ? "Record Attack" : connectedservername); + snprintf(demo.titlename, 64, "%s - %s", G_BuildMapTitle(gamemap), modeattacking ? "Time Attack" : connectedservername); // demo checksum demo_p += 16; @@ -6474,8 +6487,9 @@ void G_BeginRecording(void) WRITEUINT8(demo_p, 0xFF); // Denote the end of the player listing #ifdef HAVE_BLUA - // player lua vars, always saved even if empty - LUA_ArchiveDemo(); + // player lua vars, always saved even if empty... Unless it's record attack. + if (!modeattacking) + LUA_ArchiveDemo(); #endif memset(&oldcmd,0,sizeof(oldcmd)); @@ -7153,6 +7167,7 @@ void G_DoPlayDemo(char *defdemoname) M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); Z_Free(demobuffer); + demobuffer = NULL; demo.playback = false; demo.title = false; return; @@ -7181,6 +7196,7 @@ void G_DoPlayDemo(char *defdemoname) M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); Z_Free(demobuffer); + demobuffer = NULL; demo.playback = false; demo.title = false; return; @@ -7193,6 +7209,7 @@ void G_DoPlayDemo(char *defdemoname) M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); Z_Free(demobuffer); + demobuffer = NULL; demo.playback = false; demo.title = false; return; @@ -7212,6 +7229,7 @@ void G_DoPlayDemo(char *defdemoname) M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); Z_Free(demobuffer); + demobuffer = NULL; demo.playback = false; demo.title = false; return; @@ -7272,6 +7290,7 @@ void G_DoPlayDemo(char *defdemoname) M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); Z_Free(demobuffer); + demobuffer = NULL; demo.playback = false; demo.title = false; return; @@ -7342,6 +7361,7 @@ void G_DoPlayDemo(char *defdemoname) M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); Z_Free(demobuffer); + demobuffer = NULL; demo.playback = false; demo.title = false; return; @@ -7355,6 +7375,7 @@ void G_DoPlayDemo(char *defdemoname) M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); Z_Free(demobuffer); + demobuffer = NULL; demo.playback = false; demo.title = false; return; @@ -7379,6 +7400,7 @@ void G_DoPlayDemo(char *defdemoname) M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); Z_Free(demobuffer); + demobuffer = NULL; demo.playback = false; demo.title = false; return; @@ -7422,6 +7444,7 @@ void G_DoPlayDemo(char *defdemoname) M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); Z_Free(demobuffer); + demobuffer = NULL; demo.playback = false; demo.title = false; return; @@ -7477,6 +7500,7 @@ void G_DoPlayDemo(char *defdemoname) M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); Z_Free(demobuffer); + demobuffer = NULL; demo.playback = false; demo.title = false; return; @@ -7491,6 +7515,7 @@ void G_DoPlayDemo(char *defdemoname) M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); Z_Free(demobuffer); + demobuffer = NULL; demo.playback = false; demo.title = false; return; @@ -7543,6 +7568,7 @@ void G_DoPlayDemo(char *defdemoname) if (!gL) // No Lua state! ...I guess we'll just start one... LUA_ClearState(); + // No modeattacking check, DF_LUAVARS won't be present here. LUA_UnArchiveDemo(); } #endif @@ -8140,6 +8166,7 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void) saved = FIL_WriteFile(va("%sMS.LMP", G_BuildMapName(gamemap)), demobuffer, demo_p - demobuffer); // finally output the file. } free(demobuffer); + demobuffer = NULL; metalrecording = false; if (saved) I_Error("Saved to %sMS.LMP", G_BuildMapName(gamemap)); @@ -8320,6 +8347,7 @@ void G_SaveDemo(void) if (FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer)) // finally output the file. demo.savemode = DSM_SAVED; free(demobuffer); + demobuffer = NULL; demo.recording = false; if (modeattacking != ATTACKING_RECORD) @@ -8389,6 +8417,9 @@ boolean G_DemoTitleResponder(event_t *ev) void G_SetGamestate(gamestate_t newstate) { gamestate = newstate; +#ifdef HAVE_DISCORDRPC + DRPC_UpdatePresence(); +#endif } /* These functions handle the exitgame flag. Before, when the user diff --git a/src/g_game.h b/src/g_game.h index 0edc13c74..493be5d49 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -26,7 +26,8 @@ extern char customversionstring[32]; #ifdef SEENAMES extern player_t *seenplayer; #endif -extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1]; +extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1]; +extern INT32 player_name_changes[MAXPLAYERS]; extern player_t players[MAXPLAYERS]; extern boolean playeringame[MAXPLAYERS]; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c7ff5a4af..9b7b31e49 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4733,6 +4733,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) } R_SetupFrame(player, false); // This can stay false because it is only used to set viewsky in r_main.c, which isn't used here + framecount++; // for timedemo HWR_RenderFrame(viewnumber, player, false); } diff --git a/src/http-mserv.c b/src/http-mserv.c new file mode 100644 index 000000000..c149eb9b2 --- /dev/null +++ b/src/http-mserv.c @@ -0,0 +1,540 @@ +// SONIC ROBO BLAST 2 KART +//----------------------------------------------------------------------------- +// Copyright (C) 2020 by James R. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +// \brief HTTP based master server + +/* +Documentation available here. + + +*/ + +#ifdef HAVE_CURL +#include +#endif + +#include "doomdef.h" +#include "d_clisrv.h" +#include "command.h" +#include "m_argv.h" +#include "m_menu.h" +#include "mserv.h" +#include "i_tcp.h"/* for current_port */ +#include "i_threads.h" + +/* reasonable default I guess?? */ +#define DEFAULT_BUFFER_SIZE (4096) + +/* I just stop myself from making macros anymore. */ +#define Blame( ... ) \ + CONS_Printf("\x85" __VA_ARGS__) + +static void MasterServer_Debug_OnChange (void); + +consvar_t cv_masterserver_timeout = { + "masterserver_timeout", "5", CV_SAVE, CV_Unsigned, + NULL, 0, NULL, NULL, 0, 0, NULL/* C90 moment */ +}; + +consvar_t cv_masterserver_debug = { + "masterserver_debug", "Off", CV_SAVE|CV_CALL, CV_OnOff, + MasterServer_Debug_OnChange, 0, NULL, NULL, 0, 0, NULL/* C90 moment */ +}; + +consvar_t cv_masterserver_token = { + "masterserver_token", "", CV_SAVE, NULL, + NULL, 0, NULL, NULL, 0, 0, NULL/* C90 moment */ +}; + +#ifdef MASTERSERVER + +static int hms_started; + +static char *hms_api; +#ifdef HAVE_THREADS +static I_mutex hms_api_mutex; +#endif + +static char *hms_server_token; + +struct HMS_buffer +{ + CURL *curl; + char *buffer; + int needle; + int end; +}; + +static void +Contact_error (void) +{ + CONS_Alert(CONS_ERROR, + "There was a problem contacting the master server...\n" + ); +} + +static size_t +HMS_on_read (char *s, size_t _1, size_t n, void *userdata) +{ + struct HMS_buffer *buffer; + size_t blocks; + + (void)_1; + + buffer = userdata; + + if (n >= (size_t)( buffer->end - buffer->needle )) + { + /* resize to next multiple of buffer size */ + blocks = ( n / DEFAULT_BUFFER_SIZE + 1 ); + buffer->end += ( blocks * DEFAULT_BUFFER_SIZE ); + + buffer->buffer = realloc(buffer->buffer, buffer->end); + } + + memcpy(&buffer->buffer[buffer->needle], s, n); + buffer->needle += n; + + return n; +} + +static struct HMS_buffer * +HMS_connect (const char *format, ...) +{ + va_list ap; + CURL *curl; + char *url; + char *quack_token; + size_t seek; + size_t token_length; + struct HMS_buffer *buffer; + + if (! hms_started) + { + if (curl_global_init(CURL_GLOBAL_ALL) != 0) + { + Contact_error(); + Blame("From curl_global_init.\n"); + return NULL; + } + else + { + atexit(curl_global_cleanup); + hms_started = 1; + } + } + + curl = curl_easy_init(); + + if (! curl) + { + Contact_error(); + Blame("From curl_easy_init.\n"); + return NULL; + } + + if (cv_masterserver_token.string[0]) + { + quack_token = curl_easy_escape(curl, cv_masterserver_token.string, 0); + token_length = ( sizeof "&token="-1 )+ strlen(quack_token); + } + else + { + quack_token = NULL; + token_length = 0; + } + +#ifdef HAVE_THREADS + I_lock_mutex(&hms_api_mutex); +#endif + + seek = strlen(hms_api) + 1;/* + '/' */ + + va_start (ap, format); + url = malloc(seek + vsnprintf(0, 0, format, ap) + + sizeof "?v=2" - 1 + + token_length + 1); + va_end (ap); + + sprintf(url, "%s/", hms_api); + +#ifdef HAVE_THREADS + I_unlock_mutex(hms_api_mutex); +#endif + + va_start (ap, format); + seek += vsprintf(&url[seek], format, ap); + va_end (ap); + + strcpy(&url[seek], "?v=2"); + seek += sizeof "?v=2" - 1; + + if (quack_token) + sprintf(&url[seek], "&token=%s", quack_token); + + CONS_Printf("HMS: connecting '%s'...\n", url); + + buffer = malloc(sizeof *buffer); + buffer->curl = curl; + buffer->end = DEFAULT_BUFFER_SIZE; + buffer->buffer = malloc(buffer->end); + buffer->needle = 0; + + if (cv_masterserver_debug.value) + { + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(curl, CURLOPT_STDERR, logstream); + } + + if (M_CheckParm("-bindaddr") && M_IsNextParm()) + { + curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm()); + } + + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + + curl_easy_setopt(curl, CURLOPT_TIMEOUT, cv_masterserver_timeout.value); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer); + + curl_free(quack_token); + free(url); + + return buffer; +} + +static int +HMS_do (struct HMS_buffer *buffer) +{ + CURLcode cc; + long status; + + char *p; + + cc = curl_easy_perform(buffer->curl); + + if (cc != CURLE_OK) + { + Contact_error(); + Blame( + "From curl_easy_perform: %s\n", + curl_easy_strerror(cc) + ); + return 0; + } + + buffer->buffer[buffer->needle] = '\0'; + + curl_easy_getinfo(buffer->curl, CURLINFO_RESPONSE_CODE, &status); + + if (status != 200) + { + p = strchr(buffer->buffer, '\n'); + + if (p) + *p = '\0'; + + Contact_error(); + Blame( + "Master server error %ld: %s%s\n", + status, + buffer->buffer, + ( (p) ? "" : " (malformed)" ) + ); + + return 0; + } + else + return 1; +} + +static void +HMS_end (struct HMS_buffer *buffer) +{ + curl_easy_cleanup(buffer->curl); + free(buffer->buffer); + free(buffer); +} + +int +HMS_register (void) +{ + struct HMS_buffer *hms; + int ok; + + char post[256]; + + char *contact; + + hms = HMS_connect( + "games/%s/%d/servers/register", SRB2APPLICATION, MODVERSION); + + if (! hms) + return 0; + + contact = curl_easy_escape(hms->curl, cv_server_contact.string, 0); + + snprintf(post, sizeof post, + "port=%d&" + "contact=%s", + + current_port, + + contact + ); + + curl_free(contact); + + curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post); + + ok = HMS_do(hms); + + if (ok) + { + hms_server_token = strdup(strtok(hms->buffer, "\n")); + } + + HMS_end(hms); + + return ok; +} + +int +HMS_unlist (void) +{ + struct HMS_buffer *hms; + int ok; + + hms = HMS_connect("servers/%s/unlist", hms_server_token); + + if (! hms) + return 0; + + curl_easy_setopt(hms->curl, CURLOPT_CUSTOMREQUEST, "POST"); + + ok = HMS_do(hms); + HMS_end(hms); + + free(hms_server_token); + + return ok; +} + +int +HMS_update (void) +{ + struct HMS_buffer *hms; + int ok; + + char post[256]; + + char *title; + + hms = HMS_connect("servers/%s/update", hms_server_token); + + if (! hms) + return 0; + + title = curl_easy_escape(hms->curl, cv_servername.string, 0); + + snprintf(post, sizeof post, + "title=%s", + title + ); + + curl_free(title); + + curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post); + + ok = HMS_do(hms); + HMS_end(hms); + + return ok; +} + +void +HMS_list_servers (void) +{ + struct HMS_buffer *hms; + + hms = HMS_connect("games/%s/%d/servers", SRB2APPLICATION, MODVERSION); + + if (! hms) + return; + + if (HMS_do(hms)) + { + CONS_Printf("%s\n", hms->buffer); + } + + HMS_end(hms); +} + +msg_server_t * +HMS_fetch_servers (msg_server_t *list, int query_id) +{ + struct HMS_buffer *hms; + + int doing_shit; + + char *address; + char *port; + char *contact; + + char *end; + char *p; + + int i; + + (void)query_id; + + hms = HMS_connect("games/%s/%d/servers", SRB2APPLICATION, MODVERSION); + + if (! hms) + return NULL; + + if (HMS_do(hms)) + { + doing_shit = 1; + + p = hms->buffer; + i = 0; + + while (i < MAXSERVERLIST && ( end = strchr(p, '\n') )) + { + *end = '\0'; + + address = strtok(p, " "); + port = strtok(0, " "); + contact = strtok(0, ""); + + if (address && port) + { +#ifdef HAVE_THREADS + I_lock_mutex(&ms_QueryId_mutex); + { + if (query_id != ms_QueryId) + doing_shit = 0; + } + I_unlock_mutex(ms_QueryId_mutex); + + if (! doing_shit) + break; +#endif + + strlcpy(list[i].ip, address, sizeof list[i].ip); + strlcpy(list[i].port, port, sizeof list[i].port); + + if (contact) + { + strlcpy(list[i].contact, contact, sizeof list[i].contact); + } + + list[i].header.buffer[0] = 1; + + i++; + + p = ( end + 1 );/* skip server delimiter */ + } + else + { + /* malformed so quit the parsing */ + break; + } + } + + if (doing_shit) + list[i].header.buffer[0] = 0; + } + else + list = NULL; + + HMS_end(hms); + + return list; +} + +int +HMS_compare_mod_version (char *buffer, size_t buffer_size) +{ + struct HMS_buffer *hms; + int ok; + + char *version; + char *version_name; + + hms = HMS_connect("games/%s/version", SRB2APPLICATION); + + if (! hms) + return 0; + + ok = 0; + + if (HMS_do(hms)) + { + version = strtok(hms->buffer, " "); + version_name = strtok(0, "\n"); + + if (version && version_name) + { + if (atoi(version) != MODVERSION) + { + strlcpy(buffer, version_name, buffer_size); + ok = 1; + } + else + ok = -1; + } + } + + HMS_end(hms); + + return ok; +} + +static char * +Strip_trailing_slashes (char *api) +{ + char * p = &api[strlen(api)]; + + while (*--p == '/') + ; + + p[1] = '\0'; + + return api; +} + +void +HMS_set_api (char *api) +{ +#ifdef HAVE_THREADS + I_lock_mutex(&hms_api_mutex); +#endif + { + free(hms_api); + hms_api = Strip_trailing_slashes(api); + } +#ifdef HAVE_THREADS + I_unlock_mutex(hms_api_mutex); +#endif +} + +#endif/*MASTERSERVER*/ + +static void +MasterServer_Debug_OnChange (void) +{ +#ifdef MASTERSERVER + /* TODO: change to 'latest-log.txt' for log files revision. */ + if (cv_masterserver_debug.value) + CONS_Printf("Master server debug messages will appear in log.txt\n"); +#endif +} diff --git a/src/i_tcp.c b/src/i_tcp.c index f58aa22bc..1f1cf4f22 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -246,7 +246,8 @@ static size_t numbans = 0; static boolean SOCK_bannednode[MAXNETNODES+1]; /// \note do we really need the +1? static boolean init_tcp_driver = false; -static char port_name[8] = DEFAULTPORT; +static const char *serverport_name = DEFAULTPORT; +static const char *clientport_name;/* any port */ #ifndef NONET @@ -924,6 +925,7 @@ static boolean UDP_Socket(void) #ifdef HAVE_IPV6 const INT32 b_ipv6 = M_CheckParm("-ipv6"); #endif + const char *serv; for (s = 0; s < mysocketses; s++) @@ -939,11 +941,16 @@ static boolean UDP_Socket(void) hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; + if (serverrunning) + serv = serverport_name; + else + serv = clientport_name; + if (M_CheckParm("-bindaddr")) { while (M_IsNextParm()) { - gaie = I_getaddrinfo(M_GetNextParm(), port_name, &hints, &ai); + gaie = I_getaddrinfo(M_GetNextParm(), serv, &hints, &ai); if (gaie == 0) { runp = ai; @@ -964,7 +971,7 @@ static boolean UDP_Socket(void) } else { - gaie = I_getaddrinfo("0.0.0.0", port_name, &hints, &ai); + gaie = I_getaddrinfo("0.0.0.0", serv, &hints, &ai); if (gaie == 0) { runp = ai; @@ -979,8 +986,8 @@ static boolean UDP_Socket(void) #ifdef HAVE_MINIUPNPC if (UPNP_support) { - I_UPnP_rem(port_name, "UDP"); - I_UPnP_add(NULL, port_name, "UDP"); + I_UPnP_rem(serverport_name, "UDP"); + I_UPnP_add(NULL, serverport_name, "UDP"); } #endif } @@ -997,7 +1004,7 @@ static boolean UDP_Socket(void) { while (M_IsNextParm()) { - gaie = I_getaddrinfo(M_GetNextParm(), port_name, &hints, &ai); + gaie = I_getaddrinfo(M_GetNextParm(), serv, &hints, &ai); if (gaie == 0) { runp = ai; @@ -1018,7 +1025,7 @@ static boolean UDP_Socket(void) } else { - gaie = I_getaddrinfo("::", port_name, &hints, &ai); + gaie = I_getaddrinfo("::", serv, &hints, &ai); if (gaie == 0) { runp = ai; @@ -1475,15 +1482,19 @@ boolean I_InitTcpNetwork(void) if (!I_InitTcpDriver()) return false; - if (M_CheckParm("-port")) + if (M_CheckParm("-port") || M_CheckParm("-serverport")) // Combined -udpport and -clientport into -port // As it was really redundant having two seperate parms that does the same thing + /* Sorry Steel, I'm adding these back. But -udpport is a stupid name. */ { - if (M_IsNextParm()) - strcpy(port_name, M_GetNextParm()); - else - strcpy(port_name, "0"); + /* + If it's NULL, that's okay! Because then + we'll get a random port from getaddrinfo. + */ + serverport_name = M_GetNextParm(); } + if (M_CheckParm("-clientport")) + clientport_name = M_GetNextParm(); // parse network game options, if (M_CheckParm("-server") || dedicated) diff --git a/src/i_threads.h b/src/i_threads.h new file mode 100644 index 000000000..45a3dcc3e --- /dev/null +++ b/src/i_threads.h @@ -0,0 +1,39 @@ +// SONIC ROBO BLAST 2 KART +//----------------------------------------------------------------------------- +// Copyright (C) 2020 by James R. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file i_threads.h +/// \brief Multithreading abstraction + +#ifdef HAVE_THREADS + +#ifndef I_THREADS_H +#define I_THREADS_H + +typedef void (*I_thread_fn)(void *userdata); + +typedef void * I_mutex; +typedef void * I_cond; + +void I_start_threads (void); +void I_stop_threads (void); + +void I_spawn_thread (const char *name, I_thread_fn, void *userdata); + +/* check in your thread whether to return early */ +int I_thread_is_stopped (void); + +void I_lock_mutex (I_mutex *); +void I_unlock_mutex (I_mutex); + +void I_hold_cond (I_cond *, I_mutex); + +void I_wake_one_cond (I_cond *); +void I_wake_all_cond (I_cond *); + +#endif/*I_THREADS_H*/ +#endif/*HAVE_THREADS*/ diff --git a/src/k_kart.c b/src/k_kart.c index 2e8ca1773..e6afebc78 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -666,31 +666,31 @@ static INT32 K_KartItemOddsRace[NUMKARTRESULTS][10] = /*Jawz x2*/ { 0, 0, 0, 1, 2, 0, 0, 0, 0, 0 } // Jawz x2 }; -static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][6] = +static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][2] = { - //P-Odds 0 1 2 3 4 5 - /*Sneaker*/ { 3, 2, 2, 2, 0, 2 }, // Sneaker - /*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 0 }, // Rocket Sneaker - /*Invincibility*/ { 0, 1, 2, 3, 4, 2 }, // Invincibility - /*Banana*/ { 2, 1, 0, 0, 0, 0 }, // Banana - /*Eggman Monitor*/ { 1, 1, 0, 0, 0, 0 }, // Eggman Monitor - /*Orbinaut*/ { 6, 2, 1, 0, 0, 0 }, // Orbinaut - /*Jawz*/ { 3, 3, 3, 2, 0, 2 }, // Jawz - /*Mine*/ { 2, 3, 3, 1, 0, 2 }, // Mine - /*Ballhog*/ { 0, 1, 2, 1, 0, 2 }, // Ballhog - /*Self-Propelled Bomb*/ { 0, 0, 0, 0, 0, 0 }, // Self-Propelled Bomb - /*Grow*/ { 0, 0, 1, 2, 4, 2 }, // Grow - /*Shrink*/ { 0, 0, 0, 0, 0, 0 }, // Shrink - /*Thunder Shield*/ { 0, 0, 0, 0, 0, 0 }, // Thunder Shield - /*Hyudoro*/ { 1, 1, 0, 0, 0, 0 }, // Hyudoro - /*Pogo Spring*/ { 1, 1, 0, 0, 0, 0 }, // Pogo Spring - /*Kitchen Sink*/ { 0, 0, 0, 0, 0, 0 }, // Kitchen Sink - /*Sneaker x3*/ { 0, 0, 0, 2, 4, 2 }, // Sneaker x3 - /*Banana x3*/ { 1, 2, 1, 0, 0, 0 }, // Banana x3 - /*Banana x10*/ { 0, 0, 1, 1, 0, 2 }, // Banana x10 - /*Orbinaut x3*/ { 0, 1, 2, 1, 0, 0 }, // Orbinaut x3 - /*Orbinaut x4*/ { 0, 0, 1, 3, 4, 2 }, // Orbinaut x4 - /*Jawz x2*/ { 0, 0, 1, 2, 4, 2 } // Jawz x2 + //P-Odds 0 1 + /*Sneaker*/ { 2, 1 }, // Sneaker + /*Rocket Sneaker*/ { 0, 0 }, // Rocket Sneaker + /*Invincibility*/ { 2, 1 }, // Invincibility + /*Banana*/ { 1, 0 }, // Banana + /*Eggman Monitor*/ { 1, 0 }, // Eggman Monitor + /*Orbinaut*/ { 8, 0 }, // Orbinaut + /*Jawz*/ { 8, 1 }, // Jawz + /*Mine*/ { 4, 1 }, // Mine + /*Ballhog*/ { 2, 1 }, // Ballhog + /*Self-Propelled Bomb*/ { 0, 0 }, // Self-Propelled Bomb + /*Grow*/ { 2, 1 }, // Grow + /*Shrink*/ { 0, 0 }, // Shrink + /*Thunder Shield*/ { 0, 0 }, // Thunder Shield + /*Hyudoro*/ { 2, 0 }, // Hyudoro + /*Pogo Spring*/ { 2, 0 }, // Pogo Spring + /*Kitchen Sink*/ { 0, 0 }, // Kitchen Sink + /*Sneaker x3*/ { 0, 1 }, // Sneaker x3 + /*Banana x3*/ { 1, 0 }, // Banana x3 + /*Banana x10*/ { 0, 1 }, // Banana x10 + /*Orbinaut x3*/ { 2, 0 }, // Orbinaut x3 + /*Orbinaut x4*/ { 1, 1 }, // Orbinaut x4 + /*Jawz x2*/ { 2, 1 } // Jawz x2 }; /** \brief Item Roulette for Kart @@ -898,6 +898,7 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean sp newodds = 0; else POWERITEMODDS(newodds); + break; case KITEM_HYUDORO: if ((hyubgone > 0) || COOLDOWNONSTART) newodds = 0; @@ -922,12 +923,15 @@ static INT32 K_FindUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT3 UINT8 distlen = 0; boolean oddsvalid[10]; + // Unused now, oops :V + (void)bestbumper; + for (i = 0; i < 10; i++) { INT32 j; boolean available = false; - if (G_BattleGametype() && i > 5) + if (G_BattleGametype() && i > 1) { oddsvalid[i] = false; break; @@ -961,24 +965,20 @@ static INT32 K_FindUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT3 if (G_BattleGametype()) // Battle Mode { - if (oddsvalid[0]) SETUPDISTTABLE(0,1); - if (oddsvalid[1]) SETUPDISTTABLE(1,1); - if (oddsvalid[2]) SETUPDISTTABLE(2,1); - if (oddsvalid[3]) SETUPDISTTABLE(3,1); - if (oddsvalid[4]) SETUPDISTTABLE(4,1); - - if (player->kartstuff[k_roulettetype] == 1 && oddsvalid[5]) // 5 is the extreme odds of player-controlled "Karma" items - useodds = 5; + if (player->kartstuff[k_roulettetype] == 1 && oddsvalid[1] == true) + { + // 1 is the extreme odds of player-controlled "Karma" items + useodds = 1; + } else { - SINT8 wantedpos = (bestbumper-player->kartstuff[k_bumper]); // 0 is the best player's bumper count, 1 is a bumper below best, 2 is two bumpers below, etc - if (K_IsPlayerWanted(player)) - wantedpos++; - if (wantedpos > 4) // Don't run off into karma items - wantedpos = 4; - if (wantedpos < 0) // Don't go below somehow - wantedpos = 0; - useodds = disttable[(wantedpos * distlen) / 5]; + useodds = 0; + + if (oddsvalid[0] == false && oddsvalid[1] == true) + { + // try to use karma odds as a fallback + useodds = 1; + } } } else @@ -1061,6 +1061,10 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) bestbumper = players[i].kartstuff[k_bumper]; } + // No forced SPB in 1v1s, it has to be randomly rolled + if (pingame <= 2) + dontforcespb = true; + // This makes the roulette produce the random noises. if ((player->kartstuff[k_itemroulette] % 3) == 1 && P_IsDisplayPlayer(player) && !demo.freecam) { @@ -1372,30 +1376,72 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) } } -/** \brief Checks that the player is on an offroad subsector for realsies +/** \brief Checks that the player is on an offroad subsector for realsies. Also accounts for line riding to prevent cheese. \param mo player mobj object \return boolean */ -static UINT8 K_CheckOffroadCollide(mobj_t *mo, sector_t *sec) +static UINT8 K_CheckOffroadCollide(mobj_t *mo) { - UINT8 i; - sector_t *sec2; + // Check for sectors in touching_sectorlist + UINT8 i; // special type iter + msecnode_t *node; // touching_sectorlist iter + sector_t *s; // main sector shortcut + sector_t *s2; // FOF sector shortcut + ffloor_t *rover; // FOF + + fixed_t flr; + fixed_t cel; // floor & ceiling for height checks to make sure we're touching the offroad sector. I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); - sec2 = P_ThingOnSpecial3DFloor(mo); - - for (i = 2; i < 5; i++) + for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) { - if ((sec2 && GETSECSPECIAL(sec2->special, 1) == i) - || (P_IsObjectOnRealGround(mo, sec) && GETSECSPECIAL(sec->special, 1) == i)) - return i-1; - } + if (!node->m_sector) + break; // shouldn't happen. - return 0; + s = node->m_sector; + // 1: Check for the main sector, make sure we're on the floor of that sector and see if we can apply offroad. + // Make arbitrary Z checks because we want to check for 1 sector in particular, we don't want to affect the player if the offroad sector is way below them and they're lineriding a normal sector above. + + flr = P_MobjFloorZ(mo, s, s, mo->x, mo->y, NULL, false, true); + cel = P_MobjCeilingZ(mo, s, s, mo->x, mo->y, NULL, true, true); // get Z coords of both floors and ceilings for this sector (this accounts for slopes properly.) + // NOTE: we don't use P_GetZAt with our x/y directly because the mobj won't have the same height because of its hitbox on the slope. Complex garbage but tldr it doesn't work. + + if ( ((s->flags & SF_FLIPSPECIAL_FLOOR) && mo->z == flr) // floor check + || ((mo->eflags & MFE_VERTICALFLIP && (s->flags & SF_FLIPSPECIAL_CEILING) && (mo->z + mo->height) == cel)) ) // ceiling check. + + for (i = 2; i < 5; i++) // check for sector special + + if (GETSECSPECIAL(s->special, 1) == i) + return i-1; // return offroad type + + // 2: If we're here, we haven't found anything. So let's try looking for FOFs in the sectors using the same logic. + for (rover = s->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS)) // This FOF doesn't exist anymore. + continue; + + s2 = §ors[rover->secnum]; // makes things easier for us + + flr = P_GetFOFBottomZ(mo, s, rover, mo->x, mo->y, NULL); + cel = P_GetFOFTopZ(mo, s, rover, mo->x, mo->y, NULL); // Z coords for fof top/bottom. + + // we will do essentially the same checks as above instead of bothering with top/bottom height of the FOF. + // Reminder that an FOF's floor is its bottom, silly! + if ( ((s2->flags & SF_FLIPSPECIAL_FLOOR) && mo->z == cel) // "floor" check + || ((s2->flags & SF_FLIPSPECIAL_CEILING) && (mo->z + mo->height) == flr) ) // "ceiling" check. + + for (i = 2; i < 5; i++) // check for sector special + + if (GETSECSPECIAL(s2->special, 1) == i) + return i-1; // return offroad type + + } + } + return 0; // couldn't find any offroad } /** \brief Updates the Player's offroad value once per frame @@ -1407,14 +1453,12 @@ static UINT8 K_CheckOffroadCollide(mobj_t *mo, sector_t *sec) static void K_UpdateOffroad(player_t *player) { fixed_t offroad; - sector_t *nextsector = R_PointInSubsector( - player->mo->x + player->mo->momx*2, player->mo->y + player->mo->momy*2)->sector; - UINT8 offroadstrength = K_CheckOffroadCollide(player->mo, nextsector); + UINT8 offroadstrength = K_CheckOffroadCollide(player->mo); // If you are in offroad, a timer starts. if (offroadstrength) { - if (K_CheckOffroadCollide(player->mo, player->mo->subsector->sector) && player->kartstuff[k_offroad] == 0) + if (/*K_CheckOffroadCollide(player->mo) &&*/ player->kartstuff[k_offroad] == 0) // With the way offroad is detected now that first check is no longer necessary. -Lat' player->kartstuff[k_offroad] = (TICRATE/2); if (player->kartstuff[k_offroad] > 0) @@ -2893,14 +2937,12 @@ void K_SpawnBoostTrail(player_t *player) { newx = player->mo->x + P_ReturnThrustX(player->mo, travelangle + ((i&1) ? -1 : 1)*ANGLE_135, FixedMul(24*FRACUNIT, player->mo->scale)); newy = player->mo->y + P_ReturnThrustY(player->mo, travelangle + ((i&1) ? -1 : 1)*ANGLE_135, FixedMul(24*FRACUNIT, player->mo->scale)); -#ifdef ESLOPE if (player->mo->standingslope) { ground = P_GetZAt(player->mo->standingslope, newx, newy); if (player->mo->eflags & MFE_VERTICALFLIP) ground -= FixedMul(mobjinfo[MT_SNEAKERTRAIL].height, player->mo->scale); } -#endif flame = P_SpawnMobj(newx, newy, ground, MT_SNEAKERTRAIL); P_SetTarget(&flame->target, player->mo); @@ -3312,7 +3354,8 @@ void K_PuntMine(mobj_t *thismine, mobj_t *punter) if (!thismine || P_MobjWasRemoved(thismine)) return; - if (thismine->type == MT_SSMINE_SHIELD) // Create a new mine + //This guarantees you hit a mine being dragged + if (thismine->type == MT_SSMINE_SHIELD) // Create a new mine, and clean up the old one { mine = P_SpawnMobj(thismine->x, thismine->y, thismine->z, MT_SSMINE); P_SetTarget(&mine->target, thismine->target); @@ -3320,7 +3363,19 @@ void K_PuntMine(mobj_t *thismine, mobj_t *punter) mine->flags2 = thismine->flags2; mine->floorz = thismine->floorz; mine->ceilingz = thismine->ceilingz; + + //Since we aren't using P_KillMobj, we need to clean up the hnext reference + { + P_SetTarget(&thismine->target->hnext, NULL); //target is the player who owns the mine + thismine->target->player->kartstuff[k_bananadrag] = 0; + thismine->target->player->kartstuff[k_itemheld] = 0; + + if (--thismine->target->player->kartstuff[k_itemamount] <= 0) + thismine->target->player->kartstuff[k_itemtype] = KITEM_NONE; + } + P_RemoveMobj(thismine); + } else mine = thismine; @@ -3604,9 +3659,7 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) if (mo->eflags & MFE_SPRUNG) return; -#ifdef ESLOPE mo->standingslope = NULL; -#endif mo->eflags |= MFE_SPRUNG; @@ -3870,6 +3923,62 @@ void K_DropItems(player_t *player) K_StripItems(player); } +void K_DropRocketSneaker(player_t *player) +{ + mobj_t *shoe = player->mo; + fixed_t flingangle; + boolean leftshoe = true; //left shoe is first + + if (!(player->mo && !P_MobjWasRemoved(player->mo) && player->mo->hnext && !P_MobjWasRemoved(player->mo->hnext))) + return; + + while ((shoe = shoe->hnext) && !P_MobjWasRemoved(shoe)) + { + if (shoe->type != MT_ROCKETSNEAKER) + return; //woah, not a rocketsneaker, bail! safeguard in case this gets used when you're holding non-rocketsneakers + + shoe->flags2 &= ~MF2_DONTDRAW; + shoe->flags &= ~MF_NOGRAVITY; + shoe->angle += ANGLE_45; + + if (shoe->eflags & MFE_VERTICALFLIP) + shoe->z -= shoe->height; + else + shoe->z += shoe->height; + + //left shoe goes off tot eh left, right shoe off to the right + if (leftshoe) + flingangle = -(ANG60); + else + flingangle = ANG60; + + S_StartSound(shoe, shoe->info->deathsound); + P_SetObjectMomZ(shoe, 8*FRACUNIT, false); + P_InstaThrust(shoe, R_PointToAngle2(shoe->target->x, shoe->target->y, shoe->x, shoe->y)+flingangle, 16*FRACUNIT); + shoe->momx += shoe->target->momx; + shoe->momy += shoe->target->momy; + shoe->momz += shoe->target->momz; + shoe->extravalue2 = 1; + + leftshoe = false; + } + P_SetTarget(&player->mo->hnext, NULL); + player->kartstuff[k_rocketsneakertimer] = 0; +} + +void K_DropKitchenSink(player_t *player) +{ + if (!(player->mo && !P_MobjWasRemoved(player->mo) && player->mo->hnext && !P_MobjWasRemoved(player->mo->hnext))) + return; + + if (player->mo->hnext->type != MT_SINK_SHIELD) + return; //so we can just call this function regardless of what is being held + + P_KillMobj(player->mo->hnext, NULL, NULL); + + P_SetTarget(&player->mo->hnext, NULL); +} + // When an item in the hnext chain dies. void K_RepairOrbitChain(mobj_t *orbit) { @@ -4490,6 +4599,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) fast->momx = 3*player->mo->momx/4; fast->momy = 3*player->mo->momy/4; fast->momz = 3*player->mo->momz/4; + P_SetTarget(&fast->target, player->mo); // easier lua access K_MatchGenericExtraFlags(fast, player->mo); } @@ -5195,12 +5305,12 @@ void K_KartUpdatePosition(player_t *player) // void K_StripItems(player_t *player) { + K_DropRocketSneaker(player); + K_DropKitchenSink(player); player->kartstuff[k_itemtype] = KITEM_NONE; player->kartstuff[k_itemamount] = 0; player->kartstuff[k_itemheld] = 0; - player->kartstuff[k_rocketsneakertimer] = 0; - if (!player->kartstuff[k_itemroulette] || player->kartstuff[k_roulettetype] != 2) { player->kartstuff[k_itemroulette] = 0; diff --git a/src/k_kart.h b/src/k_kart.h index 86ae0fcc5..796065404 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -55,6 +55,8 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue); INT32 K_GetKartDriftSparkValue(player_t *player); void K_KartUpdatePosition(player_t *player); void K_DropItems(player_t *player); +void K_DropRocketSneaker(player_t *player); +void K_DropKitchenSink(player_t *player); void K_StripItems(player_t *player); void K_StripOther(player_t *player); void K_MomentumToFacing(player_t *player); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index d7292cd60..56b1a5a54 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -14,9 +14,7 @@ #ifdef HAVE_BLUA #include "p_local.h" #include "p_setup.h" // So we can have P_SetupLevelSky -#ifdef ESLOPE #include "p_slopes.h" // P_GetZAt -#endif #include "z_zone.h" #include "r_main.h" #include "r_things.h" @@ -1575,7 +1573,6 @@ static int lib_evCrumbleChain(lua_State *L) return 0; } -#ifdef ESLOPE // P_SLOPES //////////// @@ -1591,7 +1588,6 @@ static int lib_pGetZAt(lua_State *L) lua_pushfixed(L, P_GetZAt(slope, x, y)); return 1; } -#endif // R_DEFS //////////// @@ -3083,10 +3079,8 @@ static luaL_Reg lib[] = { {"P_StartQuake",lib_pStartQuake}, {"EV_CrumbleChain",lib_evCrumbleChain}, -#ifdef ESLOPE // p_slopes {"P_GetZAt",lib_pGetZAt}, -#endif // r_defs {"R_PointToAngle",lib_rPointToAngle}, diff --git a/src/lua_blockmaplib.c b/src/lua_blockmaplib.c index dabbdd9f6..0e705e2ea 100644 --- a/src/lua_blockmaplib.c +++ b/src/lua_blockmaplib.c @@ -79,9 +79,7 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th { INT32 offset; const INT32 *list; // Big blockmap -#ifdef POLYOBJECTS polymaplink_t *plink; // haleyjd 02/22/06 -#endif line_t *ld; if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) @@ -89,7 +87,6 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th offset = y*bmapwidth + x; -#ifdef POLYOBJECTS // haleyjd 02/22/06: consider polyobject lines plink = polyblocklinks[offset]; @@ -132,7 +129,6 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th } plink = (polymaplink_t *)(plink->link.next); } -#endif offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x]; diff --git a/src/lua_libs.h b/src/lua_libs.h index cb1cb49c7..00dd9c858 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -40,11 +40,9 @@ extern lua_State *gL; #define META_SUBSECTOR "SUBSECTOR_T*" #define META_SECTOR "SECTOR_T*" #define META_FFLOOR "FFLOOR_T*" -#ifdef ESLOPE #define META_SLOPE "PSLOPE_T*" #define META_VECTOR2 "VECTOR2_T" #define META_VECTOR3 "VECTOR3_T" -#endif #define META_MAPHEADER "MAPHEADER_T*" #define META_CVAR "CONSVAR_T*" diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 19292b3d6..41875ea98 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -16,9 +16,7 @@ #include "p_local.h" #include "p_setup.h" #include "z_zone.h" -#ifdef ESLOPE #include "p_slopes.h" -#endif #include "r_main.h" #include "lua_script.h" @@ -43,13 +41,9 @@ enum sector_e { sector_heightsec, sector_camsec, sector_lines, -#ifdef ESLOPE sector_ffloors, sector_fslope, sector_cslope -#else - sector_ffloors -#endif }; static const char *const sector_opt[] = { @@ -66,10 +60,8 @@ static const char *const sector_opt[] = { "camsec", "lines", "ffloors", -#ifdef ESLOPE "f_slope", "c_slope", -#endif NULL}; enum subsector_e { @@ -175,10 +167,8 @@ enum ffloor_e { ffloor_toplightlevel, ffloor_bottomheight, ffloor_bottompic, -#ifdef ESLOPE ffloor_tslope, ffloor_bslope, -#endif ffloor_sector, ffloor_flags, ffloor_master, @@ -195,10 +185,8 @@ static const char *const ffloor_opt[] = { "toplightlevel", "bottomheight", "bottompic", -#ifdef ESLOPE "t_slope", "b_slope", -#endif "sector", // secnum pushed as control sector userdata "flags", "master", // control linedef @@ -208,7 +196,6 @@ static const char *const ffloor_opt[] = { "alpha", NULL}; -#ifdef ESLOPE enum slope_e { slope_valid = 0, slope_o, @@ -247,7 +234,6 @@ static const char *const vector_opt[] = { "y", "z", NULL}; -#endif static const char *const array_opt[] ={"iterate",NULL}; static const char *const valid_opt[] ={"valid",NULL}; @@ -463,14 +449,12 @@ static int sector_get(lua_State *L) LUA_PushUserdata(L, sector->ffloors, META_FFLOOR); lua_pushcclosure(L, sector_iterate, 2); // push lib_iterateFFloors and sector->ffloors as upvalues for the function return 1; -#ifdef ESLOPE case sector_fslope: // f_slope LUA_PushUserdata(L, sector->f_slope, META_SLOPE); return 1; case sector_cslope: // c_slope LUA_PushUserdata(L, sector->c_slope, META_SLOPE); return 1; -#endif } return 0; } @@ -495,10 +479,8 @@ static int sector_set(lua_State *L) case sector_heightsec: // heightsec case sector_camsec: // camsec case sector_ffloors: // ffloors -#ifdef ESLOPE case sector_fslope: // f_slope case sector_cslope: // c_slope -#endif default: return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]); case sector_floorheight: { // floorheight @@ -1134,14 +1116,12 @@ static int ffloor_get(lua_State *L) lua_pushlstring(L, levelflat->name, i); return 1; } -#ifdef ESLOPE case ffloor_tslope: LUA_PushUserdata(L, *ffloor->t_slope, META_SLOPE); return 1; case ffloor_bslope: LUA_PushUserdata(L, *ffloor->b_slope, META_SLOPE); return 1; -#endif case ffloor_sector: LUA_PushUserdata(L, §ors[ffloor->secnum], META_SECTOR); return 1; @@ -1183,10 +1163,8 @@ static int ffloor_set(lua_State *L) switch(field) { case ffloor_valid: // valid -#ifdef ESLOPE case ffloor_tslope: // t_slope case ffloor_bslope: // b_slope -#endif case ffloor_sector: // sector case ffloor_master: // master case ffloor_target: // target @@ -1247,7 +1225,6 @@ static int ffloor_set(lua_State *L) return 0; } -#ifdef ESLOPE static int slope_get(lua_State *L) { pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); @@ -1422,7 +1399,6 @@ static int vector3_get(lua_State *L) return 0; } -#endif static int lib_getMapheaderinfo(lua_State *L) { @@ -1614,7 +1590,6 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L, 1); -#ifdef ESLOPE luaL_newmetatable(L, META_SLOPE); lua_pushcfunction(L, slope_get); lua_setfield(L, -2, "__index"); @@ -1632,7 +1607,6 @@ int LUA_MapLib(lua_State *L) lua_pushcfunction(L, vector3_get); lua_setfield(L, -2, "__index"); lua_pop(L, 1); -#endif luaL_newmetatable(L, META_MAPHEADER); lua_pushcfunction(L, mapheaderinfo_get); diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index dfb344e34..1361f8231 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -82,9 +82,7 @@ enum mobj_e { mobj_extravalue2, mobj_cusval, mobj_cvmem, -#ifdef ESLOPE mobj_standingslope, -#endif mobj_colorized }; @@ -145,9 +143,7 @@ static const char *const mobj_opt[] = { "extravalue2", "cusval", "cvmem", -#ifdef ESLOPE "standingslope", -#endif "colorized", NULL}; @@ -352,11 +348,9 @@ static int mobj_get(lua_State *L) case mobj_cvmem: lua_pushinteger(L, mo->cvmem); break; -#ifdef ESLOPE case mobj_standingslope: LUA_PushUserdata(L, mo->standingslope, META_SLOPE); break; -#endif case mobj_colorized: lua_pushboolean(L, mo->colorized); break; @@ -670,10 +664,8 @@ static int mobj_set(lua_State *L) case mobj_cvmem: mo->cvmem = luaL_checkinteger(L, 3); break; -#ifdef ESLOPE case mobj_standingslope: return NOSET; -#endif case mobj_colorized: mo->colorized = luaL_checkboolean(L, 3); break; diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index d9766513b..3aeeed734 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -17,6 +17,7 @@ #include "d_player.h" #include "g_game.h" #include "p_local.h" +#include "d_clisrv.h" #include "lua_script.h" #include "lua_libs.h" @@ -118,7 +119,7 @@ static int lib_iterateDisplayplayers(lua_State *L) for (i++; i < MAXSPLITSCREENPLAYERS; i++) { - if (!playeringame[displayplayers[i]] || i > splitscreen) + if (i > splitscreen || !playeringame[displayplayers[i]]) return 0; // Stop! There are no more players for us to go through. There will never be a player gap in displayplayers. if (!players[displayplayers[i]].mo) @@ -139,6 +140,8 @@ static int lib_getDisplayplayers(lua_State *L) lua_Integer i = luaL_checkinteger(L, 2); if (i < 0 || i >= MAXSPLITSCREENPLAYERS) return luaL_error(L, "displayplayers[] index %d out of range (0 - %d)", i, MAXSPLITSCREENPLAYERS-1); + if (i > splitscreen) + return 0; if (!playeringame[displayplayers[i]]) return 0; if (!players[displayplayers[i]].mo) @@ -385,6 +388,8 @@ static int player_get(lua_State *L) else if (fastcmp(field,"fovadd")) lua_pushfixed(L, plr->fovadd); #endif + else if (fastcmp(field,"ping")) + lua_pushinteger(L, playerpingtable[( plr - players )]); else { lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); diff --git a/src/lua_script.c b/src/lua_script.c index 6961f2e97..7c951efb3 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -22,9 +22,7 @@ #include "byteptr.h" #include "p_saveg.h" #include "p_local.h" -#ifdef ESLOPE #include "p_slopes.h" // for P_SlopeById -#endif #ifdef LUA_ALLOW_BYTECODE #include "d_netfil.h" // for LUA_DumpFile #endif @@ -472,9 +470,7 @@ enum ARCH_SIDE, ARCH_SUBSECTOR, ARCH_SECTOR, -#ifdef ESLOPE ARCH_SLOPE, -#endif ARCH_MAPHEADER, ARCH_TEND=0xFF, @@ -494,9 +490,7 @@ static const struct { {META_SIDE, ARCH_SIDE}, {META_SUBSECTOR,ARCH_SUBSECTOR}, {META_SECTOR, ARCH_SECTOR}, -#ifdef ESLOPE {META_SLOPE, ARCH_SLOPE}, -#endif {META_MAPHEADER, ARCH_MAPHEADER}, {NULL, ARCH_NULL} }; @@ -701,7 +695,6 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) } break; } -#ifdef ESLOPE case ARCH_SLOPE: { pslope_t *slope = *((pslope_t **)lua_touserdata(gL, myindex)); @@ -713,7 +706,6 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) } break; } -#endif case ARCH_MAPHEADER: { mapheader_t *header = *((mapheader_t **)lua_touserdata(gL, myindex)); @@ -915,7 +907,6 @@ static UINT8 ArchiveValueDemo(int TABLESINDEX, int myindex) } break; } -#ifdef ESLOPE case ARCH_SLOPE: { pslope_t *slope = *((pslope_t **)lua_touserdata(gL, myindex)); @@ -927,7 +918,6 @@ static UINT8 ArchiveValueDemo(int TABLESINDEX, int myindex) } break; } -#endif case ARCH_MAPHEADER: { mapheader_t *header = *((mapheader_t **)lua_touserdata(gL, myindex)); @@ -1233,11 +1223,9 @@ static UINT8 UnArchiveValue(int TABLESINDEX) case ARCH_SECTOR: LUA_PushUserdata(gL, §ors[READUINT16(save_p)], META_SECTOR); break; -#ifdef ESLOPE case ARCH_SLOPE: LUA_PushUserdata(gL, P_SlopeById(READUINT16(save_p)), META_SLOPE); break; -#endif case ARCH_MAPHEADER: LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER); break; @@ -1336,11 +1324,9 @@ static UINT8 UnArchiveValueDemo(int TABLESINDEX, char field[1024]) case ARCH_SECTOR: LUA_PushUserdata(gL, §ors[READUINT16(demo_p)], META_SECTOR); break; -#ifdef ESLOPE case ARCH_SLOPE: LUA_PushUserdata(gL, P_SlopeById(READUINT16(demo_p)), META_SLOPE); break; -#endif case ARCH_MAPHEADER: LUA_PushUserdata(gL, mapheaderinfo[READUINT16(demo_p)], META_MAPHEADER); break; diff --git a/src/m_cheat.c b/src/m_cheat.c index e7e877ada..a884ff7e4 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -862,13 +862,9 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling) if (ceiling) { -#ifdef ESLOPE // Truncate position to match where mapthing would be when spawned // (this applies to every further P_GetZAt call as well) fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->ceilingheight; -#else - fixed_t cheight = sec->ceilingheight; -#endif if (((cheight - player->mo->z - player->mo->height)>>FRACBITS) >= (1 << (16-ZSHIFT))) { @@ -879,11 +875,7 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling) } else { -#ifdef ESLOPE fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight; -#else - fixed_t fheight = sec->floorheight; -#endif if (((player->mo->z - fheight)>>FRACBITS) >= (1 << (16-ZSHIFT))) { CONS_Printf(M_GetText("Sorry, you're too %s to place this object (max: %d %s).\n"), M_GetText("high"), @@ -931,20 +923,12 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c mt->y = (INT16)(player->mo->y>>FRACBITS); if (ceiling) { -#ifdef ESLOPE fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, mt->x << FRACBITS, mt->y << FRACBITS) : sec->ceilingheight; -#else - fixed_t cheight = sec->ceilingheight; -#endif mt->options = (UINT16)((cheight - player->mo->z - player->mo->height)>>FRACBITS); } else { -#ifdef ESLOPE fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, mt->x << FRACBITS, mt->y << FRACBITS) : sec->floorheight; -#else - fixed_t fheight = sec->floorheight; -#endif mt->options = (UINT16)((player->mo->z - fheight)>>FRACBITS); } mt->options <<= ZSHIFT; @@ -1001,11 +985,7 @@ void OP_NightsObjectplace(player_t *player) UINT16 angle = (UINT16)(player->anotherflyangle % 360); INT16 temp = (INT16)FixedInt(AngleFixed(player->mo->angle)); // Traditional 2D Angle sector_t *sec = player->mo->subsector->sector; -#ifdef ESLOPE fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight; -#else - fixed_t fheight = sec->floorheight; -#endif player->pflags |= PF_ATTACKDOWN; @@ -1162,20 +1142,12 @@ void OP_ObjectplaceMovement(player_t *player) if (!!(mobjinfo[op_currentthing].flags & MF_SPAWNCEILING) ^ !!(cv_opflags.value & MTF_OBJECTFLIP)) { -#ifdef ESLOPE fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->ceilingheight; -#else - fixed_t cheight = sec->ceilingheight; -#endif op_displayflags = (UINT16)((cheight - player->mo->z - mobjinfo[op_currentthing].height)>>FRACBITS); } else { -#ifdef ESLOPE fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight; -#else - fixed_t fheight = sec->floorheight; -#endif op_displayflags = (UINT16)((player->mo->z - fheight)>>FRACBITS); } op_displayflags <<= ZSHIFT; diff --git a/src/m_menu.c b/src/m_menu.c index f04cf77f9..dc2363392 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -32,6 +32,7 @@ #include "sounds.h" #include "s_sound.h" #include "i_system.h" +#include "i_threads.h" // Addfile #include "filesrch.h" @@ -80,6 +81,11 @@ int snprintf(char *str, size_t n, const char *fmt, ...); //int vsnprintf(char *str, size_t n, const char *fmt, va_list ap); #endif +#ifdef HAVE_DISCORDRPC +//#include "discord_rpc.h" +#include "discord.h" +#endif + #define SKULLXOFF -32 #define LINEHEIGHT 16 #define STRINGHEIGHT 8 @@ -118,6 +124,12 @@ typedef enum NUM_QUITMESSAGES } text_enum; +#ifdef HAVE_THREADS +I_mutex m_menu_mutex; +#endif + +M_waiting_mode_t m_waiting_mode = M_NOT_WAITING; + const char *quitmsg[NUM_QUITMESSAGES]; // Stuff for customizing the player select screen Tails 09-22-2003 @@ -170,7 +182,6 @@ static void M_StopMessage(INT32 choice); #ifndef NONET static void M_HandleServerPage(INT32 choice); -static void M_RoomMenu(INT32 choice); #endif // Prototyping is fun, innit? @@ -178,9 +189,18 @@ static void M_RoomMenu(INT32 choice); // NEEDED FUNCTION PROTOTYPES GO HERE // ========================================================================== +void M_SetWaitingMode(int mode); +int M_GetWaitingMode(void); + // the haxor message menu menu_t MessageDef; +#ifdef HAVE_DISCORDRPC +menu_t MISC_DiscordRequestsDef; +static void M_HandleDiscordRequests(INT32 choice); +static void M_DrawDiscordRequests(void); +#endif + menu_t SPauseDef; #define lsheadingheight 16 @@ -245,7 +265,6 @@ static void M_ConnectMenu(INT32 choice); static void M_ConnectMenuModChecks(INT32 choice); static void M_Refresh(INT32 choice); static void M_Connect(INT32 choice); -static void M_ChooseRoom(INT32 choice); #endif static void M_StartOfflineServerMenu(INT32 choice); static void M_StartServer(INT32 choice); @@ -286,6 +305,9 @@ menu_t OP_SoundOptionsDef; //Misc menu_t OP_DataOptionsDef, OP_ScreenshotOptionsDef, OP_EraseDataDef; +#ifdef HAVE_DISCORDRPC +menu_t OP_DiscordOptionsDef; +#endif menu_t OP_HUDOptionsDef, OP_ChatOptionsDef; menu_t OP_GameOptionsDef, OP_ServerOptionsDef; #ifndef NONET @@ -351,7 +373,6 @@ static void M_OGL_DrawColorMenu(void); static void M_DrawMPMainMenu(void); #ifndef NONET static void M_DrawConnectMenu(void); -static void M_DrawRoomMenu(void); #endif static void M_DrawJoystick(void); static void M_DrawSetupMultiPlayerMenu(void); @@ -578,6 +599,10 @@ static menuitem_t MPauseMenu[] = {IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16}, {IT_STRING | IT_CALL, NULL, "Switch Map..." , M_MapChange, 24}, +#ifdef HAVE_DISCORDRPC + {IT_STRING | IT_SUBMENU, NULL, "Ask To Join Requests...", &MISC_DiscordRequestsDef, 24}, +#endif + {IT_CALL | IT_STRING, NULL, "Continue", M_SelectableClearMenus, 40}, {IT_CALL | IT_STRING, NULL, "P1 Setup...", M_SetupMultiPlayer, 48}, // splitscreen {IT_CALL | IT_STRING, NULL, "P2 Setup...", M_SetupMultiPlayer2, 56}, // splitscreen @@ -601,6 +626,9 @@ typedef enum mpause_addons = 0, mpause_scramble, mpause_switchmap, +#ifdef HAVE_DISCORDRPC + mpause_discordrequests, +#endif mpause_continue, mpause_psetupsplit, @@ -651,6 +679,13 @@ typedef enum spause_quit } spause_e; +#ifdef HAVE_DISCORDRPC +static menuitem_t MISC_DiscordRequestsMenu[] = +{ + {IT_KEYHANDLER|IT_NOTHING, NULL, "", M_HandleDiscordRequests, 0}, +}; +#endif + // ----------------- // Misc menu options // ----------------- @@ -982,7 +1017,7 @@ static menuitem_t MP_MainMenu[] = static menuitem_t MP_ServerMenu[] = { {IT_STRING|IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 10}, - {IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 20}, + {IT_STRING|IT_CVAR, NULL, "Advertise", &cv_advertise, 20}, {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 30}, {IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 68}, @@ -1012,54 +1047,30 @@ static menuitem_t MP_PlayerSetupMenu[] = #ifndef NONET static menuitem_t MP_ConnectMenu[] = { - {IT_STRING | IT_CALL, NULL, "Room...", M_RoomMenu, 4}, - {IT_STRING | IT_CVAR, NULL, "Sort By", &cv_serversort, 12}, - {IT_STRING | IT_KEYHANDLER, NULL, "Page", M_HandleServerPage, 20}, - {IT_STRING | IT_CALL, NULL, "Refresh", M_Refresh, 28}, - - {IT_STRING | IT_SPACE, NULL, "", M_Connect, 48-4}, - {IT_STRING | IT_SPACE, NULL, "", M_Connect, 60-4}, - {IT_STRING | IT_SPACE, NULL, "", M_Connect, 72-4}, - {IT_STRING | IT_SPACE, NULL, "", M_Connect, 84-4}, - {IT_STRING | IT_SPACE, NULL, "", M_Connect, 96-4}, - {IT_STRING | IT_SPACE, NULL, "", M_Connect, 108-4}, - {IT_STRING | IT_SPACE, NULL, "", M_Connect, 120-4}, - {IT_STRING | IT_SPACE, NULL, "", M_Connect, 132-4}, - {IT_STRING | IT_SPACE, NULL, "", M_Connect, 144-4}, - {IT_STRING | IT_SPACE, NULL, "", M_Connect, 156-4}, - {IT_STRING | IT_SPACE, NULL, "", M_Connect, 168-4}, + {IT_STRING | IT_CVAR, NULL, "Sort By", &cv_serversort, 4}, + {IT_STRING | IT_KEYHANDLER, NULL, "Page", M_HandleServerPage, 12}, + {IT_STRING | IT_CALL, NULL, "Refresh", M_Refresh, 20}, + + {IT_STRING | IT_SPACE, NULL, "", M_Connect, 36}, + {IT_STRING | IT_SPACE, NULL, "", M_Connect, 48}, + {IT_STRING | IT_SPACE, NULL, "", M_Connect, 60}, + {IT_STRING | IT_SPACE, NULL, "", M_Connect, 72}, + {IT_STRING | IT_SPACE, NULL, "", M_Connect, 84}, + {IT_STRING | IT_SPACE, NULL, "", M_Connect, 96}, + {IT_STRING | IT_SPACE, NULL, "", M_Connect, 108}, + {IT_STRING | IT_SPACE, NULL, "", M_Connect, 120}, + {IT_STRING | IT_SPACE, NULL, "", M_Connect, 132}, + {IT_STRING | IT_SPACE, NULL, "", M_Connect, 144}, + {IT_STRING | IT_SPACE, NULL, "", M_Connect, 156}, }; enum { - mp_connect_room, mp_connect_sort, mp_connect_page, mp_connect_refresh, FIRSTSERVERLINE }; - -static menuitem_t MP_RoomMenu[] = -{ - {IT_STRING | IT_CALL, NULL, "", M_ChooseRoom, 9}, - {IT_DISABLED, NULL, "", M_ChooseRoom, 18}, - {IT_DISABLED, NULL, "", M_ChooseRoom, 27}, - {IT_DISABLED, NULL, "", M_ChooseRoom, 36}, - {IT_DISABLED, NULL, "", M_ChooseRoom, 45}, - {IT_DISABLED, NULL, "", M_ChooseRoom, 54}, - {IT_DISABLED, NULL, "", M_ChooseRoom, 63}, - {IT_DISABLED, NULL, "", M_ChooseRoom, 72}, - {IT_DISABLED, NULL, "", M_ChooseRoom, 81}, - {IT_DISABLED, NULL, "", M_ChooseRoom, 90}, - {IT_DISABLED, NULL, "", M_ChooseRoom, 99}, - {IT_DISABLED, NULL, "", M_ChooseRoom, 108}, - {IT_DISABLED, NULL, "", M_ChooseRoom, 117}, - {IT_DISABLED, NULL, "", M_ChooseRoom, 126}, - {IT_DISABLED, NULL, "", M_ChooseRoom, 135}, - {IT_DISABLED, NULL, "", M_ChooseRoom, 144}, - {IT_DISABLED, NULL, "", M_ChooseRoom, 153}, - {IT_DISABLED, NULL, "", M_ChooseRoom, 162}, -}; #endif // ------------------------------------ @@ -1336,11 +1347,17 @@ static menuitem_t OP_SoundOptionsMenu[] = static menuitem_t OP_DataOptionsMenu[] = { + {IT_STRING | IT_CALL, NULL, "Screenshot Options...", M_ScreenshotOptions, 10}, {IT_STRING | IT_CALL, NULL, "Addon Options...", M_AddonsOptions, 20}, {IT_STRING | IT_SUBMENU, NULL, "Replay Options...", &MISC_ReplayOptionsDef, 30}, +#ifdef HAVE_DISCORDRPC + {IT_STRING | IT_SUBMENU, NULL, "Discord Options...", &OP_DiscordOptionsDef, 40}, + {IT_STRING | IT_SUBMENU, NULL, "Erase Data...", &OP_EraseDataDef, 60}, +#else {IT_STRING | IT_SUBMENU, NULL, "Erase Data...", &OP_EraseDataDef, 50}, +#endif }; static menuitem_t OP_ScreenshotOptionsMenu[] = @@ -1389,7 +1406,7 @@ static menuitem_t OP_AddonsOptionsMenu[] = {IT_HEADER, NULL, "Menu", NULL, 0}, {IT_STRING|IT_CVAR, NULL, "Location", &cv_addons_option, 10}, {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_addons_folder, 20}, - {IT_STRING|IT_CVAR, NULL, "Identify addons via", &cv_addons_md5, 48}, + {IT_STRING|IT_CVAR, NULL, "Identify addons via", &cv_addons_md5, 48}, {IT_STRING|IT_CVAR, NULL, "Show unsupported file types", &cv_addons_showall, 58}, {IT_HEADER, NULL, "Search", NULL, 76}, @@ -1402,6 +1419,19 @@ enum op_addons_folder = 2, }; +#ifdef HAVE_DISCORDRPC +static menuitem_t OP_DiscordOptionsMenu[] = +{ + {IT_STRING | IT_CVAR, NULL, "Rich Presence", &cv_discordrp, 10}, + + {IT_HEADER, NULL, "Rich Presence Settings", NULL, 30}, + {IT_STRING | IT_CVAR, NULL, "Streamer Mode", &cv_discordstreamer, 40}, + + {IT_STRING | IT_CVAR, NULL, "Allow Ask To Join", &cv_discordasks, 60}, + {IT_STRING | IT_CVAR, NULL, "Allow Invites", &cv_discordinvites, 70}, +}; +#endif + static menuitem_t OP_HUDOptionsMenu[] = { {IT_STRING | IT_CVAR, NULL, "Show HUD (F3)", &cv_showhud, 10}, @@ -1642,6 +1672,19 @@ menu_t MAPauseDef = PAUSEMENUSTYLE(MAPauseMenu, 40, 72); menu_t SPauseDef = PAUSEMENUSTYLE(SPauseMenu, 40, 72); menu_t MPauseDef = PAUSEMENUSTYLE(MPauseMenu, 40, 72); +#ifdef HAVE_DISCORDRPC +menu_t MISC_DiscordRequestsDef = { + NULL, + sizeof (MISC_DiscordRequestsMenu)/sizeof (menuitem_t), + &MPauseDef, + MISC_DiscordRequestsMenu, + M_DrawDiscordRequests, + 0, 0, + 0, + NULL +}; +#endif + // Misc Main Menu menu_t MISC_ScrambleTeamDef = DEFAULTMENUSTYLE(NULL, MISC_ScrambleTeamMenu, &MPauseDef, 27, 40); menu_t MISC_ChangeTeamDef = DEFAULTMENUSTYLE(NULL, MISC_ChangeTeamMenu, &MPauseDef, 27, 40); @@ -1925,17 +1968,6 @@ menu_t MP_ConnectDef = 0, M_CancelConnect }; -menu_t MP_RoomDef = -{ - "M_MULTI", - sizeof (MP_RoomMenu)/sizeof (menuitem_t), - &MP_ConnectDef, - MP_RoomMenu, - M_DrawRoomMenu, - 27, 32, - 0, - NULL -}; #endif menu_t MP_PlayerSetupDef = { @@ -2068,6 +2100,9 @@ menu_t OP_OpenGLColorDef = menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30); menu_t OP_ScreenshotOptionsDef = DEFAULTMENUSTYLE("M_SCSHOT", OP_ScreenshotOptionsMenu, &OP_DataOptionsDef, 30, 30); menu_t OP_AddonsOptionsDef = DEFAULTMENUSTYLE("M_ADDONS", OP_AddonsOptionsMenu, &OP_DataOptionsDef, 30, 30); +#ifdef HAVE_DISCORDRPC +menu_t OP_DiscordOptionsDef = DEFAULTMENUSTYLE(NULL, OP_DiscordOptionsMenu, &OP_DataOptionsDef, 30, 30); +#endif menu_t OP_EraseDataDef = DEFAULTMENUSTYLE("M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 30, 30); // ========================================================================== @@ -2929,7 +2964,6 @@ boolean M_Responder(event_t *ev) //make sure the game doesn't still think we're in a netgame. if (!Playing() && netgame && multiplayer) { - MSCloseUDPSocket(); // Clean up so we can re-open the connection later. netgame = false; multiplayer = false; } @@ -3221,12 +3255,18 @@ void M_StartControlPanel(void) MPauseMenu[mpause_psetup].status = IT_DISABLED; MISC_ChangeTeamMenu[0].status = IT_DISABLED; MISC_ChangeSpectateMenu[0].status = IT_DISABLED; + // Reset these in case splitscreen messes things up + MPauseMenu[mpause_addons].alphaKey = 8; + MPauseMenu[mpause_scramble].alphaKey = 8; + MPauseMenu[mpause_switchmap].alphaKey = 24; + MPauseMenu[mpause_switchteam].alphaKey = 48; MPauseMenu[mpause_switchspectate].alphaKey = 48; MPauseMenu[mpause_options].alphaKey = 64; MPauseMenu[mpause_title].alphaKey = 80; MPauseMenu[mpause_quit].alphaKey = 88; + Dummymenuplayer_OnChange(); if ((server || IsPlayerAdmin(consoleplayer))) @@ -3298,6 +3338,19 @@ void M_StartControlPanel(void) MPauseMenu[mpause_spectate].status = IT_GRAYEDOUT; } +#ifdef HAVE_DISCORDRPC + { + UINT8 i; + + for (i = 0; i < mpause_discordrequests; i++) + MPauseMenu[i].alphaKey -= 8; + + MPauseMenu[mpause_discordrequests].alphaKey = MPauseMenu[i].alphaKey; + + M_RefreshPauseMenu(); + } +#endif + currentMenu = &MPauseDef; itemOn = mpause_continue; } @@ -3394,6 +3447,19 @@ void M_Ticker(void) if (--vidm_testingmode == 0) setmodeneeded = vidm_previousmode + 1; } + +#if defined (MASTERSERVER) && defined (HAVE_THREADS) + I_lock_mutex(&ms_ServerList_mutex); + { + if (ms_ServerList) + { + CL_QueryServerList(ms_ServerList); + free(ms_ServerList); + ms_ServerList = NULL; + } + } + I_unlock_mutex(ms_ServerList_mutex); +#endif } // @@ -4088,6 +4154,25 @@ static void M_DrawPauseMenu(void) } #endif +#ifdef HAVE_DISCORDRPC + // kind of hackily baked in here + if (currentMenu == &MPauseDef && discordRequestList != NULL) + { + const tic_t freq = TICRATE/2; + + if ((leveltime % freq) >= freq/2) + { + V_DrawFixedPatch(204 * FRACUNIT, + (currentMenu->y + MPauseMenu[mpause_discordrequests].alphaKey - 1) * FRACUNIT, + FRACUNIT, + 0, + W_CachePatchName("K_REQUE2", PU_CACHE), + NULL + ); + } + } +#endif + M_DrawGenericMenu(); } @@ -4866,7 +4951,7 @@ static boolean M_AddonsRefresh(void) else if (majormods && !prevmajormods) { S_StartSound(NULL, sfx_s221); - message = va("%c%s\x80\nGameplay has now been modified.\nIf you wish to play Record Attack mode, restart the game to clear existing addons.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); + message = va("%c%s\x80\nYou've loaded a gameplay-modifying addon.\n\nRecord Attack has been disabled, but you\ncan still play alone in local Multiplayer.\n\nIf you wish to play Record Attack mode, restart the game to disable loaded addons.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); prevmajormods = majormods; } @@ -6222,7 +6307,12 @@ static void M_Options(INT32 choice) OP_MainMenu[4].status = OP_MainMenu[5].status = (Playing() && !(server || IsPlayerAdmin(consoleplayer))) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); OP_MainMenu[8].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL); // Play credits + +#ifdef HAVE_DISCORDRPC + OP_DataOptionsMenu[4].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); // Erase data +#else OP_DataOptionsMenu[3].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); // Erase data +#endif OP_GameOptionsMenu[3].status = (M_SecretUnlocked(SECRET_ENCORE)) ? (IT_CVAR|IT_STRING) : IT_SECRET; // cv_kartencore @@ -6263,6 +6353,20 @@ static void M_SelectableClearMenus(INT32 choice) M_ClearMenus(true); } +void M_RefreshPauseMenu(void) +{ +#ifdef HAVE_DISCORDRPC + if (discordRequestList != NULL) + { + MPauseMenu[mpause_discordrequests].status = IT_STRING | IT_SUBMENU; + } + else + { + MPauseMenu[mpause_discordrequests].status = IT_GRAYEDOUT; + } +#endif +} + // ====== // CHEATS // ====== @@ -7461,7 +7565,7 @@ static void M_DrawStatsMaps(int location) else V_DrawString(20, y, 0, va("%s %s %s", mapheaderinfo[mnum]->lvlttl, - (mapheaderinfo[mnum]->zonttl[0] ? mapheaderinfo[mnum]->zonttl : "ZONE"), + (mapheaderinfo[mnum]->zonttl[0] ? mapheaderinfo[mnum]->zonttl : "Zone"), mapheaderinfo[mnum]->actnum)); y += 8; @@ -8287,7 +8391,118 @@ static void M_EndGame(INT32 choice) // Connect Menu //=========================================================================== -#define SERVERHEADERHEIGHT 44 +void +M_SetWaitingMode (int mode) +{ +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif + { + m_waiting_mode = mode; + } +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); +#endif +} + +int +M_GetWaitingMode (void) +{ + int mode; + +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif + { + mode = m_waiting_mode; + } +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); +#endif + + return mode; +} + +#ifdef MASTERSERVER +#ifdef HAVE_THREADS +static void +Spawn_masterserver_thread (const char *name, void (*thread)(int*)) +{ + int *id = malloc(sizeof *id); + + I_lock_mutex(&ms_QueryId_mutex); + { + *id = ms_QueryId; + } + I_unlock_mutex(ms_QueryId_mutex); + + I_spawn_thread(name, (I_thread_fn)thread, id); +} + +static int +Same_instance (int id) +{ + int okay; + + I_lock_mutex(&ms_QueryId_mutex); + { + okay = ( id == ms_QueryId ); + } + I_unlock_mutex(ms_QueryId_mutex); + + return okay; +} +#endif/*HAVE_THREADS*/ + +static void +Fetch_servers_thread (int *id) +{ + msg_server_t * server_list; + + (void)id; + + M_SetWaitingMode(M_WAITING_SERVERS); + +#ifdef HAVE_THREADS + server_list = GetShortServersList(*id); +#else + server_list = GetShortServersList(0); +#endif + + if (server_list) + { +#ifdef HAVE_THREADS + if (Same_instance(*id)) +#endif + { + M_SetWaitingMode(M_NOT_WAITING); + +#ifdef HAVE_THREADS + I_lock_mutex(&ms_ServerList_mutex); + { + ms_ServerList = server_list; + } + I_unlock_mutex(ms_ServerList_mutex); +#else + CL_QueryServerList(server_list); + free(server_list); +#endif + } +#ifdef HAVE_THREADS + else + { + free(server_list); + } +#endif + } + +#ifdef HAVE_THREADS + free(id); +#endif +} +#endif/*MASTERSERVER*/ + +#define SERVERHEADERHEIGHT 36 #define SERVERLINEHEIGHT 12 #define S_LINEY(n) currentMenu->y + SERVERHEADERHEIGHT + (n * SERVERLINEHEIGHT) @@ -8359,34 +8574,18 @@ static void M_Refresh(INT32 choice) if (rendermode == render_soft) I_FinishUpdate(); // page flip or blit buffer - // note: this is the one case where 0 is a valid room number - // because it corresponds to "All" - CL_UpdateServerList(!(ms_RoomId < 0), ms_RoomId); - // first page of servers serverlistpage = 0; -} - -static INT32 menuRoomIndex = 0; -static void M_DrawRoomMenu(void) -{ - const char *rmotd; - - // use generic drawer for cursor, items and title - M_DrawGenericMenu(); - - V_DrawString(currentMenu->x - 16, currentMenu->y, highlightflags, M_GetText("Select a room")); - - M_DrawTextBox(144, 24, 20, 20); - - if (itemOn == 0) - rmotd = M_GetText("Don't connect to the Master Server."); - else - rmotd = room_list[itemOn-1].motd; - - rmotd = V_WordWrap(0, 20*8, 0, rmotd); - V_DrawString(144+8, 32, V_ALLOWLOWERCASE|V_RETURN8, rmotd); +#ifdef MASTERSERVER +#ifdef HAVE_THREADS + Spawn_masterserver_thread("fetch-servers", Fetch_servers_thread); +#else/*HAVE_THREADS*/ + Fetch_servers_thread(NULL); +#endif/*HAVE_THREADS*/ +#else/*MASTERSERVER*/ + CL_UpdateServerList(); +#endif/*MASTERSERVER*/ } static void M_DrawConnectMenu(void) @@ -8395,6 +8594,7 @@ static void M_DrawConnectMenu(void) const char *gt = "Unknown"; const char *spd = ""; INT32 numPages = (serverlistcount+(SERVERS_PER_PAGE-1))/SERVERS_PER_PAGE; + int waiting; for (i = FIRSTSERVERLINE; i < min(localservercount, SERVERS_PER_PAGE)+FIRSTSERVERLINE; i++) MP_ConnectMenu[i].status = IT_STRING | IT_SPACE; @@ -8402,20 +8602,12 @@ static void M_DrawConnectMenu(void) if (!numPages) numPages = 1; - // Room name - if (ms_RoomId < 0) - V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ConnectMenu[mp_connect_room].alphaKey, - highlightflags, (itemOn == mp_connect_room) ? "" : ""); - else - V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey, - highlightflags, room_list[menuRoomIndex].name); -#undef mp_server_room - } -#endif } static void M_MapChange(INT32 choice) @@ -8914,7 +9085,6 @@ static void M_StartServerMenu(INT32 choice) (void)choice; levellistmode = LLM_CREATESERVER; M_PrepareLevelSelect(); - ms_RoomId = -1; M_SetupNextMenu(&MP_ServerDef); } @@ -11133,3 +11303,161 @@ static void M_OGL_DrawColorMenu(void) highlightflags, "Gamma correction"); } #endif + +#ifdef HAVE_DISCORDRPC +static const tic_t confirmLength = 3*TICRATE/4; +static tic_t confirmDelay = 0; +static boolean confirmAccept = false; + +static void M_HandleDiscordRequests(INT32 choice) +{ + if (confirmDelay > 0) + return; + + switch (choice) + { + case KEY_ENTER: + Discord_Respond(discordRequestList->userID, DISCORD_REPLY_YES); + confirmAccept = true; + confirmDelay = confirmLength; + S_StartSound(NULL, sfx_s3k63); + break; + + case KEY_ESCAPE: + Discord_Respond(discordRequestList->userID, DISCORD_REPLY_NO); + confirmAccept = false; + confirmDelay = confirmLength; + S_StartSound(NULL, sfx_s3kb2); + break; + } +} + +static const char *M_GetDiscordName(discordRequest_t *r) +{ + if (r == NULL) + return ""; + + if (cv_discordstreamer.value) + return r->username; + + return va("%s#%s", r->username, r->discriminator); +} + +// (this goes in k_hud.c when merged into v2) +static void M_DrawSticker(INT32 x, INT32 y, INT32 width, INT32 flags, boolean small) +{ + patch_t *stickerEnd; + INT32 height; + + if (small == true) + { + stickerEnd = W_CachePatchName("K_STIKE2", PU_CACHE); + height = 6; + } + else + { + stickerEnd = W_CachePatchName("K_STIKEN", PU_CACHE); + height = 11; + } + + V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT, flags, stickerEnd, NULL); + V_DrawFill(x, y, width, height, 24|flags); + V_DrawFixedPatch((x + width)*FRACUNIT, y*FRACUNIT, FRACUNIT, flags|V_FLIP, stickerEnd, NULL); +} + +static void M_DrawDiscordRequests(void) +{ + discordRequest_t *curRequest = discordRequestList; + UINT8 *colormap; + patch_t *hand = NULL; + boolean removeRequest = false; + + const char *wantText = "...would like to join!"; + const char *controlText = "\x82" "ENTER" "\x80" " - Accept " "\x82" "ESC" "\x80" " - Decline"; + + INT32 x = 100; + INT32 y = 133; + + INT32 slide = 0; + INT32 maxYSlide = 18; + + if (confirmDelay > 0) + { + if (confirmAccept == true) + { + colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_GREEN, GTC_MENUCACHE); + hand = W_CachePatchName("K_LAPH02", PU_CACHE); + } + else + { + colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_RED, GTC_MENUCACHE); + hand = W_CachePatchName("K_LAPH03", PU_CACHE); + } + + slide = confirmLength - confirmDelay; + + confirmDelay--; + + if (confirmDelay == 0) + removeRequest = true; + } + else + { + colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_GREY, GTC_MENUCACHE); + } + + V_DrawFixedPatch(56*FRACUNIT, 150*FRACUNIT, FRACUNIT, 0, W_CachePatchName("K_LAPE01", PU_CACHE), colormap); + + if (hand != NULL) + { + fixed_t handoffset = (4 - abs((signed)(skullAnimCounter - 4))) * FRACUNIT; + V_DrawFixedPatch(56*FRACUNIT, 150*FRACUNIT + handoffset, FRACUNIT, 0, hand, NULL); + } + + M_DrawSticker(x + (slide * 32), y - 1, V_ThinStringWidth(M_GetDiscordName(curRequest), V_ALLOWLOWERCASE|V_6WIDTHSPACE), 0, false); + V_DrawThinString(x + (slide * 32), y, V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_YELLOWMAP, M_GetDiscordName(curRequest)); + + M_DrawSticker(x, y + 12, V_ThinStringWidth(wantText, V_ALLOWLOWERCASE|V_6WIDTHSPACE), 0, true); + V_DrawThinString(x, y + 10, V_ALLOWLOWERCASE|V_6WIDTHSPACE, wantText); + + M_DrawSticker(x, y + 26, V_ThinStringWidth(controlText, V_ALLOWLOWERCASE|V_6WIDTHSPACE), 0, true); + V_DrawThinString(x, y + 24, V_ALLOWLOWERCASE|V_6WIDTHSPACE, controlText); + + y -= 18; + + while (curRequest->next != NULL) + { + INT32 ySlide = min(slide * 4, maxYSlide); + + curRequest = curRequest->next; + + M_DrawSticker(x, y - 1 + ySlide, V_ThinStringWidth(M_GetDiscordName(curRequest), V_ALLOWLOWERCASE|V_6WIDTHSPACE), 0, false); + V_DrawThinString(x, y + ySlide, V_ALLOWLOWERCASE|V_6WIDTHSPACE, M_GetDiscordName(curRequest)); + + y -= 12; + maxYSlide = 12; + } + + if (removeRequest == true) + { + DRPC_RemoveRequest(discordRequestList); + + if (discordRequestList == NULL) + { + // No other requests + MPauseMenu[mpause_discordrequests].status = IT_GRAYEDOUT; + + if (currentMenu->prevMenu) + { + M_SetupNextMenu(currentMenu->prevMenu); + if (currentMenu == &MPauseDef) + itemOn = mpause_continue; + } + else + M_ClearMenus(true); + + return; + } + } +} +#endif diff --git a/src/m_menu.h b/src/m_menu.h index 86a840894..28fdd44e6 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -17,6 +17,8 @@ #include "d_event.h" #include "command.h" +#include "i_threads.h" +#include "mserv.h" #include "r_things.h" // for SKINNAMESIZE // @@ -72,6 +74,17 @@ typedef enum } menumessagetype_t; void M_StartMessage(const char *string, void *routine, menumessagetype_t itemtype); +typedef enum +{ + M_NOT_WAITING, + + M_WAITING_VERSION, + M_WAITING_SERVERS, +} +M_waiting_mode_t; + +extern M_waiting_mode_t m_waiting_mode; + // Called by linux_x/i_video_xshm.c void M_QuitResponse(INT32 ch); @@ -176,6 +189,10 @@ typedef struct menu_s void M_SetupNextMenu(menu_t *menudef); void M_ClearMenus(boolean callexitmenufunc); +#ifdef HAVE_THREADS +extern I_mutex m_menu_mutex; +#endif + extern menu_t *currentMenu; extern menu_t MainDef; @@ -246,6 +263,8 @@ void Addons_option_Onchange(void); void M_ReplayHut(INT32 choice); void M_SetPlaybackMenuPointer(void); +void M_RefreshPauseMenu(void); + INT32 HU_GetHighlightColor(void); // These defines make it a little easier to make menus diff --git a/src/mserv.c b/src/mserv.c index 12469928d..7adec7fff 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -2,245 +2,88 @@ //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1999-2018 by Sonic Team Junior. +// Copyright (C) 2020 by James R. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. // See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- /// \file mserv.c -/// \brief Commands used for communicate with the master server - -#ifdef __GNUC__ -#include -#include -#include -#endif +/// \brief Commands used to communicate with the master server #if !defined (UNDER_CE) #include #endif -#if (defined (NOMD5) || defined (NOMSERV)) && !defined (NONET) -#define NONET -#endif - -#ifndef NONET - -#ifndef NO_IPV6 -#define HAVE_IPV6 -#endif - -#if (defined (_WIN32) || defined (_WIN32_WCE)) && !defined (_XBOX) -#define RPC_NO_WINDOWS_H -#ifdef HAVE_IPV6 -#include -#else -#include // socket(),... -#endif //!HAVE_IPV6 -#else -#ifdef __OS2__ -#include -#endif // __OS2__ - -#ifdef HAVE_LWIP -#include -#include -#include -#define ioctl lwip_ioctl -#else -#include -#ifdef __APPLE_CC__ -#ifndef _BSD_SOCKLEN_T_ -#define _BSD_SOCKLEN_T_ -#endif -#endif -#include // socket(),... -#include // sockaddr_in -#ifdef _PS3 -#include -#elif !defined(_arch_dreamcast) -#include // getaddrinfo(),... -#include -#endif -#endif - -#ifdef _arch_dreamcast -#include "sdl12/SRB2DC/dchelp.h" -#endif - -#include // timeval,... (TIMEOUT) -#include -#endif // _WIN32/_WIN32_WCE - -#ifdef __OS2__ -#include -#endif // __OS2__ -#endif // !NONET - #include "doomstat.h" #include "doomdef.h" #include "command.h" -#include "i_net.h" -#include "console.h" +#include "i_threads.h" #include "mserv.h" -#include "d_net.h" -#include "i_tcp.h" -#include "i_system.h" -#include "byteptr.h" #include "m_menu.h" -#include "m_argv.h" // Alam is going to kill me <3 -#include "m_misc.h" // GetRevisionString() +#include "z_zone.h" -#ifdef _WIN32_WCE -#include "sdl12/SRB2CE/cehelp.h" +#ifdef HAVE_DISCORDRPC +#include "discord.h" #endif -#include "i_addrinfo.h" - -// ================================ DEFINITIONS =============================== - -#define PACKET_SIZE 1024 - - -#define MS_NO_ERROR 0 -#define MS_SOCKET_ERROR -201 -#define MS_CONNECT_ERROR -203 -#define MS_WRITE_ERROR -210 -#define MS_READ_ERROR -211 -#define MS_CLOSE_ERROR -212 -#define MS_GETHOSTBYNAME_ERROR -220 -#define MS_GETHOSTNAME_ERROR -221 -#define MS_TIMEOUT_ERROR -231 - -// see master server code for the values -#define ADD_SERVER_MSG 101 -#define REMOVE_SERVER_MSG 103 -#define ADD_SERVERv2_MSG 104 -#define GET_SERVER_MSG 200 -#define GET_SHORT_SERVER_MSG 205 -#define ASK_SERVER_MSG 206 -#define ANSWER_ASK_SERVER_MSG 207 -#define ASK_SERVER_MSG 206 -#define ANSWER_ASK_SERVER_MSG 207 -#define GET_MOTD_MSG 208 -#define SEND_MOTD_MSG 209 -#define GET_ROOMS_MSG 210 -#define SEND_ROOMS_MSG 211 -#define GET_ROOMS_HOST_MSG 212 -#define GET_VERSION_MSG 213 -#define SEND_VERSION_MSG 214 -#define GET_BANNED_MSG 215 // Someone's been baaaaaad! -#define PING_SERVER_MSG 216 - -#define HEADER_SIZE (sizeof (INT32)*4) - -#define HEADER_MSG_POS 0 -#define IP_MSG_POS 16 -#define PORT_MSG_POS 32 -#define HOSTNAME_MSG_POS 40 - - -#if defined(_MSC_VER) -#pragma pack(1) -#endif +#ifdef MASTERSERVER -/** A message to be exchanged with the master server. - */ -typedef struct -{ - INT32 id; ///< Unused? - INT32 type; ///< Type of message. - INT32 room; ///< Because everyone needs a roomie. - UINT32 length; ///< Length of the message. - char buffer[PACKET_SIZE]; ///< Actual contents of the message. -} ATTRPACK msg_t; - -#if defined(_MSC_VER) -#pragma pack() -#endif +static int MSId; +static int MSRegisteredId = -1; -typedef struct Copy_CVarMS_t -{ - char ip[64]; - char port[8]; - char name[64]; -} Copy_CVarMS_s; -static Copy_CVarMS_s registered_server; -static time_t MSLastPing; - -#if defined(_MSC_VER) -#pragma pack(1) -#endif -typedef struct -{ - char ip[16]; // Big enough to hold a full address. - UINT16 port; - UINT8 padding1[2]; - tic_t time; -} ATTRPACK ms_holepunch_packet_t; -#if defined(_MSC_VER) -#pragma pack() -#endif +static boolean MSRegistered; +static boolean MSInProgress; +static boolean MSUpdateAgain; -// win32 or djgpp -#if defined (_WIN32) || defined (_WIN32_WCE) || defined (__DJGPP__) -#define ioctl ioctlsocket -#define close closesocket -#ifdef WATTCP -#define strerror strerror_s -#endif -#if defined (_WIN32) || defined (_WIN32_WCE) -#undef errno -#define errno h_errno // some very strange things happen when not using h_error -#endif -#ifndef AI_ADDRCONFIG -#define AI_ADDRCONFIG 0x00000400 -#endif -#endif +static time_t MSLastPing; + +#ifdef HAVE_THREADS +static I_mutex MSMutex; +static I_cond MSCond; + +# define Lock_state() I_lock_mutex (&MSMutex) +# define Unlock_state() I_unlock_mutex (MSMutex) +#else/*HAVE_THREADS*/ +# define Lock_state() +# define Unlock_state() +#endif/*HAVE_THREADS*/ #ifndef NONET static void Command_Listserv_f(void); #endif + +#endif/*MASTERSERVER*/ + +static void Update_parameters (void); + static void MasterServer_OnChange(void); -static void ServerName_OnChange(void); -#define DEF_PORT "28900" -consvar_t cv_masterserver = {"masterserver", "ms.srb2.org:"DEF_PORT, CV_SAVE, NULL, MasterServer_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_servername = {"servername", "SRB2Kart server", CV_SAVE|CV_CALL|CV_NOINIT, NULL, ServerName_OnChange, 0, NULL, NULL, 0, 0, NULL}; +static void Advertise_OnChange(void); -INT16 ms_RoomId = -1; +static CV_PossibleValue_t masterserver_update_rate_cons_t[] = { + {2, "MIN"}, + {60, "MAX"}, + {0, NULL} +}; -static enum { MSCS_NONE, MSCS_WAITING, MSCS_REGISTERED, MSCS_FAILED } con_state = MSCS_NONE; +consvar_t cv_masterserver = {"masterserver", "https://ms.kartkrew.org/ms/api", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_servername = {"servername", "SRB2Kart server", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Update_parameters, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_server_contact = {"server_contact", "", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Update_parameters, 0, NULL, NULL, 0, 0, NULL}; -static INT32 msnode = -1; -UINT16 current_port = 0; +consvar_t cv_masterserver_update_rate = {"masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, MasterClient_Ticker, 0, NULL, NULL, 0, 0, NULL}; -#if (defined (_WIN32) || defined (_WIN32_WCE) || defined (_WIN32)) && !defined (NONET) -typedef SOCKET SOCKET_TYPE; -#define ERRSOCKET (SOCKET_ERROR) -#else -#if (defined (__unix__) && !defined (MSDOS)) || defined (__APPLE__) || defined (__HAIKU__) || defined (_PS3) -typedef int SOCKET_TYPE; -#else -typedef unsigned long SOCKET_TYPE; -#endif -#define ERRSOCKET (-1) -#endif +consvar_t cv_advertise = {"advertise", "No", CV_NETVAR|CV_CALL|CV_NOINIT, CV_YesNo, Advertise_OnChange, 0, NULL, NULL, 0, 0, NULL}; -#if (defined (WATTCP) && !defined (__libsocket_socklen_t)) || defined (_WIN32) -typedef int socklen_t; -#endif +#if defined (MASTERSERVER) && defined (HAVE_THREADS) +int ms_QueryId; +I_mutex ms_QueryId_mutex; -#ifndef NONET -static SOCKET_TYPE socket_fd = ERRSOCKET; // WINSOCK socket -static struct timeval select_timeout; -static fd_set wset; -static size_t recvfull(SOCKET_TYPE s, char *buf, size_t len, int flags); +msg_server_t *ms_ServerList; +I_mutex ms_ServerList_mutex; #endif -// Room list is an external variable now. -// Avoiding having to get info ten thousand times... -msg_rooms_t room_list[NUM_LIST_ROOMS+1]; // +1 for easy test +UINT16 current_port = 0; /** Adds variables and commands relating to the master server. * @@ -251,774 +94,474 @@ void AddMServCommands(void) { #ifndef NONET CV_RegisterVar(&cv_masterserver); + CV_RegisterVar(&cv_masterserver_update_rate); + CV_RegisterVar(&cv_masterserver_timeout); + CV_RegisterVar(&cv_masterserver_debug); + CV_RegisterVar(&cv_masterserver_token); + CV_RegisterVar(&cv_advertise); CV_RegisterVar(&cv_servername); + CV_RegisterVar(&cv_server_contact); +#ifdef MASTERSERVER COM_AddCommand("listserv", Command_Listserv_f); #endif +#endif } -/** Closes the connection to the master server. - * - * \todo Fix for Windows? - */ -static void CloseConnection(void) +#ifdef MASTERSERVER + +static void WarnGUI (void) { -#ifndef NONET - if (socket_fd != (SOCKET_TYPE)ERRSOCKET) - close(socket_fd); - socket_fd = ERRSOCKET; +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif + M_StartMessage(M_GetText("There was a problem connecting to\nthe Master Server\n\nCheck the console for details.\n"), NULL, MM_NOTHING); +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); #endif } -// -// MS_Write(): -// -static INT32 MS_Write(msg_t *msg) +#define NUM_LIST_SERVER MAXSERVERLIST +msg_server_t *GetShortServersList(int id) { -#ifdef NONET - (void)msg; - return MS_WRITE_ERROR; -#else - size_t len; - - if (msg->length == 0) - msg->length = (INT32)strlen(msg->buffer); - len = msg->length + HEADER_SIZE; + msg_server_t *server_list; - msg->type = htonl(msg->type); - msg->length = htonl(msg->length); - msg->room = htonl(msg->room); + // +1 for easy test + server_list = malloc(( NUM_LIST_SERVER + 1 ) * sizeof *server_list); - if ((size_t)send(socket_fd, (char *)msg, (int)len, 0) != len) - return MS_WRITE_ERROR; - return 0; -#endif + if (HMS_fetch_servers(server_list, id)) + return server_list; + else + { + free(server_list); + WarnGUI(); + return NULL; + } } -// -// MS_Read(): -// -static INT32 MS_Read(msg_t *msg) +#ifdef UPDATE_ALERT +char *GetMODVersion(int id) { -#ifdef NONET - (void)msg; - return MS_READ_ERROR; -#else - if (recvfull(socket_fd, (char *)msg, HEADER_SIZE, 0) != HEADER_SIZE) - return MS_READ_ERROR; + char *buffer; + int c; - msg->type = ntohl(msg->type); - msg->length = ntohl(msg->length); - msg->room = ntohl(msg->room); + (void)id; - if (!msg->length) // fix a bug in Windows 2000 - return 0; + buffer = malloc(16); - if (recvfull(socket_fd, (char *)msg->buffer, msg->length, 0) != msg->length) - return MS_READ_ERROR; - return 0; + c = HMS_compare_mod_version(buffer, 16); + +#ifdef HAVE_THREADS + I_lock_mutex(&ms_QueryId_mutex); + { + if (id != ms_QueryId) + c = -1; + } + I_unlock_mutex(ms_QueryId_mutex); #endif + + if (c > 0) + return buffer; + else + { + free(buffer); + + if (! c) + WarnGUI(); + + return NULL; + } } +#endif #ifndef NONET -/** Gets a list of game servers from the master server. +/** Gets a list of game servers. Called from console. */ -static INT32 GetServersList(void) +static void Command_Listserv_f(void) { - msg_t msg; - INT32 count = 0; - - msg.type = GET_SERVER_MSG; - msg.length = 0; - msg.room = 0; - if (MS_Write(&msg) < 0) - return MS_WRITE_ERROR; + CONS_Printf(M_GetText("Retrieving server list...\n")); - while (MS_Read(&msg) >= 0) { - if (!msg.length) - { - if (!count) - CONS_Alert(CONS_NOTICE, M_GetText("No servers currently running.\n")); - return MS_NO_ERROR; - } - count++; - CONS_Printf("%s",msg.buffer); + HMS_list_servers(); } - - return MS_READ_ERROR; } #endif -// -// MS_Connect() -// -static INT32 MS_Connect(const char *ip_addr, const char *str_port, INT32 async) +static void +Finish_registration (void) { -#ifdef NONET - (void)ip_addr; - (void)str_port; - (void)async; -#else - struct my_addrinfo *ai, *runp, hints; - int gaie; + int registered; - memset (&hints, 0x00, sizeof(hints)); -#ifdef AI_ADDRCONFIG - hints.ai_flags = AI_ADDRCONFIG; -#endif - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; + CONS_Printf("Registering this server on the master server...\n"); - //I_InitTcpNetwork(); this is already done on startup in D_SRB2Main() - if (!I_InitTcpDriver()) // this is done only if not already done - return MS_SOCKET_ERROR; + registered = HMS_register(); - gaie = I_getaddrinfo(ip_addr, str_port, &hints, &ai); - if (gaie != 0) - return MS_GETHOSTBYNAME_ERROR; - else - runp = ai; - - while (runp != NULL) + Lock_state(); { - socket_fd = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol); - if (socket_fd != (SOCKET_TYPE)ERRSOCKET) - { - if (async) // do asynchronous connection - { -#ifdef FIONBIO -#ifdef WATTCP - char res = 1; -#else - unsigned long res = 1; -#endif - - ioctl(socket_fd, FIONBIO, &res); -#endif + MSRegistered = registered; + MSRegisteredId = MSId; - if (connect(socket_fd, runp->ai_addr, (socklen_t)runp->ai_addrlen) == ERRSOCKET) - { -#ifdef _WIN32 // humm, on win32/win64 it doesn't work with EINPROGRESS (stupid windows) - if (WSAGetLastError() != WSAEWOULDBLOCK) -#else - if (errno != EINPROGRESS) -#endif - { - con_state = MSCS_FAILED; - CloseConnection(); - I_freeaddrinfo(ai); - return MS_CONNECT_ERROR; - } - } - con_state = MSCS_WAITING; - FD_ZERO(&wset); - FD_SET(socket_fd, &wset); - select_timeout.tv_sec = 0, select_timeout.tv_usec = 0; - I_freeaddrinfo(ai); - return 0; - } - else if (connect(socket_fd, runp->ai_addr, (socklen_t)runp->ai_addrlen) != ERRSOCKET) - { - I_freeaddrinfo(ai); - return 0; - } - } - runp = runp->ai_next; + time(&MSLastPing); } - I_freeaddrinfo(ai); -#endif - return MS_CONNECT_ERROR; + Unlock_state(); + + if (registered) + CONS_Printf("Master server registration successful.\n"); } -#define NUM_LIST_SERVER MAXSERVERLIST -const msg_server_t *GetShortServersList(INT32 room) +static void +Finish_update (void) { - static msg_server_t server_list[NUM_LIST_SERVER+1]; // +1 for easy test - msg_t msg; - INT32 i; + int registered; + int done; - // we must be connected to the master server before writing to it - if (MS_Connect(GetMasterServerIP(), GetMasterServerPort(), 0)) + Lock_state(); { - CONS_Alert(CONS_ERROR, M_GetText("Cannot connect to the Master Server\n")); - M_StartMessage(M_GetText("There was a problem connecting to\nthe Master Server\n"), NULL, MM_NOTHING); - return NULL; + registered = MSRegistered; + MSUpdateAgain = false;/* this will happen anyway */ } + Unlock_state(); - msg.type = GET_SHORT_SERVER_MSG; - msg.length = 0; - msg.room = room; - if (MS_Write(&msg) < 0) - return NULL; - - for (i = 0; i < NUM_LIST_SERVER && MS_Read(&msg) >= 0; i++) + if (registered) { - if (!msg.length) + if (HMS_update()) { - server_list[i].header.buffer[0] = 0; - CloseConnection(); - return server_list; + Lock_state(); + { + time(&MSLastPing); + MSRegistered = true; + } + Unlock_state(); + + CONS_Printf("Updated master server listing.\n"); } - M_Memcpy(&server_list[i], msg.buffer, sizeof (msg_server_t)); - server_list[i].header.buffer[0] = 1; - } - CloseConnection(); - if (i == NUM_LIST_SERVER) - { - server_list[i].header.buffer[0] = 0; - return server_list; + else + Finish_registration(); } else - return NULL; -} - -INT32 GetRoomsList(boolean hosting) -{ - static msg_ban_t banned_info[1]; - msg_t msg; - INT32 i; + Finish_registration(); - // we must be connected to the master server before writing to it - if (MS_Connect(GetMasterServerIP(), GetMasterServerPort(), 0)) + Lock_state(); { - CONS_Alert(CONS_ERROR, M_GetText("Cannot connect to the Master Server\n")); - M_StartMessage(M_GetText("There was a problem connecting to\nthe Master Server\n"), NULL, MM_NOTHING); - return -1; - } + done = ! MSUpdateAgain; - if (hosting) - msg.type = GET_ROOMS_HOST_MSG; - else - msg.type = GET_ROOMS_MSG; - msg.length = 0; - msg.room = 0; - if (MS_Write(&msg) < 0) - { - room_list[0].id = 1; - strcpy(room_list[0].motd,"Master Server Offline."); - strcpy(room_list[0].name,"Offline"); - return -1; + if (done) + MSInProgress = false; } + Unlock_state(); - for (i = 0; i < NUM_LIST_ROOMS && MS_Read(&msg) >= 0; i++) - { - if(msg.type == GET_BANNED_MSG) - { - char banmsg[1000]; - M_Memcpy(&banned_info[0], msg.buffer, sizeof (msg_ban_t)); - if (hosting) - sprintf(banmsg, M_GetText("You have been banned from\nhosting netgames.\n\nUnder the following IP Range:\n%s - %s\n\nFor the following reason:\n%s\n\nYour ban will expire on:\n%s"),banned_info[0].ipstart,banned_info[0].ipend,banned_info[0].reason,banned_info[0].endstamp); - else - sprintf(banmsg, M_GetText("You have been banned from\njoining netgames.\n\nUnder the following IP Range:\n%s - %s\n\nFor the following reason:\n%s\n\nYour ban will expire on:\n%s"),banned_info[0].ipstart,banned_info[0].ipend,banned_info[0].reason,banned_info[0].endstamp); - M_StartMessage(banmsg, NULL, MM_NOTHING); - ms_RoomId = -1; - return -2; - } - if (!msg.length) - { - room_list[i].header.buffer[0] = 0; - CloseConnection(); - return 1; - } - M_Memcpy(&room_list[i], msg.buffer, sizeof (msg_rooms_t)); - room_list[i].header.buffer[0] = 1; - } - CloseConnection(); - if (i == NUM_LIST_ROOMS) - { - room_list[i].header.buffer[0] = 0; - return 1; - } + if (! done) + Finish_update(); +#ifdef HAVE_DISCORDRPC else - { - room_list[0].id = 1; - strcpy(room_list[0].motd,M_GetText("Master Server Offline.")); - strcpy(room_list[0].name,M_GetText("Offline")); - return -1; - } + DRPC_UpdatePresence(); +#endif } -#ifdef UPDATE_ALERT -const char *GetMODVersion(void) +static void +Finish_unlist (void) { - static msg_t msg; - - // we must be connected to the master server before writing to it - if (MS_Connect(GetMasterServerIP(), GetMasterServerPort(), 0)) - { - CONS_Alert(CONS_ERROR, M_GetText("Cannot connect to the Master Server\n")); - M_StartMessage(M_GetText("There was a problem connecting to\nthe Master Server\n"), NULL, MM_NOTHING); - return NULL; - } + int registered; - msg.type = GET_VERSION_MSG; - msg.length = sizeof MODVERSION; - msg.room = MODID; // Might as well use it for something. - sprintf(msg.buffer,"%d",MODVERSION); - if (MS_Write(&msg) < 0) + Lock_state(); { - CONS_Alert(CONS_ERROR, M_GetText("Could not send to the Master Server\n")); - M_StartMessage(M_GetText("Could not send to the Master Server\n"), NULL, MM_NOTHING); - CloseConnection(); - return NULL; - } + registered = MSRegistered; - if (MS_Read(&msg) < 0) - { - CONS_Alert(CONS_ERROR, M_GetText("No reply from the Master Server\n")); - M_StartMessage(M_GetText("No reply from the Master Server\n"), NULL, MM_NOTHING); - CloseConnection(); - return NULL; + if (MSId == MSRegisteredId) + MSId++; } + Unlock_state(); - CloseConnection(); - - if(strcmp(msg.buffer,"NULL") != 0) + if (registered) { - return msg.buffer; - } - else - return NULL; -} - -// Console only version of the above (used before game init) -void GetMODVersion_Console(void) -{ - static msg_t msg; + CONS_Printf("Removing this server from the master server...\n"); - // we must be connected to the master server before writing to it - if (MS_Connect(GetMasterServerIP(), GetMasterServerPort(), 0)) - { - CONS_Alert(CONS_ERROR, M_GetText("Cannot connect to the Master Server\n")); - return; - } + if (HMS_unlist()) + CONS_Printf("Server deregistration request successfully sent.\n"); - msg.type = GET_VERSION_MSG; - msg.length = sizeof MODVERSION; - msg.room = MODID; // Might as well use it for something. - sprintf(msg.buffer,"%d",MODVERSION); - if (MS_Write(&msg) < 0) - { - CONS_Alert(CONS_ERROR, M_GetText("Could not send to the Master Server\n")); - CloseConnection(); - return; - } + Lock_state(); + { + MSRegistered = false; + } + Unlock_state(); - if (MS_Read(&msg) < 0) - { - CONS_Alert(CONS_ERROR, M_GetText("No reply from the Master Server\n")); - CloseConnection(); - return; +#ifdef HAVE_THREADS + I_wake_all_cond(&MSCond); +#endif } - CloseConnection(); - - if(strcmp(msg.buffer,"NULL") != 0) - I_Error(UPDATE_ALERT_STRING_CONSOLE, VERSIONSTRING, msg.buffer); -} +#ifdef HAVE_DISCORDRPC + DRPC_UpdatePresence(); #endif +} -#ifndef NONET -/** Gets a list of game servers. Called from console. - */ -static void Command_Listserv_f(void) +#ifdef HAVE_THREADS +static int * +Server_id (void) { - if (con_state == MSCS_WAITING) + int *id; + id = malloc(sizeof *id); + Lock_state(); { - CONS_Alert(CONS_NOTICE, M_GetText("Not yet connected to the Master Server.\n")); - return; + *id = MSId; } - - CONS_Printf(M_GetText("Retrieving server list...\n")); - - if (MS_Connect(GetMasterServerIP(), GetMasterServerPort(), 0)) - { - CONS_Alert(CONS_ERROR, M_GetText("Cannot connect to the Master Server\n")); - return; - } - - if (GetServersList()) - CONS_Alert(CONS_ERROR, M_GetText("Cannot get server list\n")); - - CloseConnection(); + Unlock_state(); + return id; } -#endif -FUNCMATH static const char *int2str(INT32 n) +static int * +New_server_id (void) { - INT32 i; - static char res[16]; - - res[15] = '\0'; - res[14] = (char)((char)(n%10)+'0'); - for (i = 13; (n /= 10); i--) - res[i] = (char)((char)(n%10)+'0'); - - return &res[i+1]; + int *id; + id = malloc(sizeof *id); + Lock_state(); + { + *id = ++MSId; + I_wake_all_cond(&MSCond); + } + Unlock_state(); + return id; } -#ifndef NONET -static INT32 ConnectionFailed(void) +static void +Register_server_thread (int *id) { - con_state = MSCS_FAILED; - CONS_Alert(CONS_ERROR, M_GetText("Connection to Master Server failed\n")); - CloseConnection(); - return MS_CONNECT_ERROR; -} -#endif + int same; -/** Tries to register the local game server on the master server. - */ -static INT32 AddToMasterServer(boolean firstadd) -{ -#ifdef NONET - (void)firstadd; -#else - static INT32 retry = 0; - int i, res; - socklen_t j; - msg_t msg; - msg_server_t *info = (msg_server_t *)msg.buffer; - INT32 room = -1; - fd_set tset; - time_t timestamp = time(NULL); - UINT32 signature, tmp; - const char *insname; - - M_Memcpy(&tset, &wset, sizeof (tset)); - res = select(255, NULL, &tset, NULL, &select_timeout); - if (res != ERRSOCKET && !res) - { - if (retry++ > 30) // an about 30 second timeout - { - retry = 0; - CONS_Alert(CONS_ERROR, M_GetText("Master Server timed out\n")); - MSLastPing = timestamp; - return ConnectionFailed(); - } - return MS_CONNECT_ERROR; - } - retry = 0; - /* - Somehow we can still select our old socket despite it being closed(?). - Atleast, that's what I THINK is happening. Anyway, we have to check that we - haven't open a socket, and actually open it! - */ - /*if (res == ERRSOCKET)*//* wtf? no! */ - if (socket_fd == (SOCKET_TYPE)ERRSOCKET) + Lock_state(); { - if (MS_Connect(GetMasterServerIP(), GetMasterServerPort(), 0)) - { - CONS_Alert(CONS_ERROR, M_GetText("Master Server socket error #%u: %s\n"), errno, strerror(errno)); - MSLastPing = timestamp; - return ConnectionFailed(); - } - } + /* wait for previous unlist to finish */ + while (*id == MSId && MSRegistered) + I_hold_cond(&MSCond, MSMutex); - // so, the socket is writable, but what does that mean, that the connection is - // ok, or bad... let see that! - j = (socklen_t)sizeof (i); - getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, (char *)&i, &j); - /* - This is also wrong. If getsockopt fails, i doesn't have to be set. Plus, if - it is set (which it appearantly is on linux), we check errno anyway. And in - the case that i is returned as normal, we don't even report the correct - value! So we accomplish NOTHING, except returning due to dumb luck. - If you care, fix this--I don't. -James (R.) - */ - if (i) // it was bad - { - CONS_Alert(CONS_ERROR, M_GetText("Master Server socket error #%u: %s\n"), errno, strerror(errno)); - MSLastPing = timestamp; - return ConnectionFailed(); + same = ( *id == MSId );/* it could have been a while */ } + Unlock_state(); -#ifdef PARANOIA - if (ms_RoomId <= 0) - I_Error("Attmepted to host in room \"All\"!\n"); -#endif - room = ms_RoomId; - - for(signature = 0, insname = cv_servername.string; *insname; signature += *insname++); - tmp = (UINT32)(signature * (size_t)&MSLastPing); - signature *= tmp; - signature &= 0xAAAAAAAA; - M_Memcpy(&info->header.signature, &signature, sizeof (UINT32)); - - strcpy(info->ip, ""); - strcpy(info->port, int2str(current_port)); - strcpy(info->name, cv_servername.string); - M_Memcpy(&info->room, & room, sizeof (INT32)); -#if VERSION > 0 || SUBVERSION > 0 - sprintf(info->version, "%d.%d", VERSION, SUBVERSION); -#else // Trunk build, send revision info - strcpy(info->version, GetRevisionString()); -#endif - strcpy(registered_server.name, cv_servername.string); + if (same)/* it could have been a while */ + Finish_registration(); - if(firstadd) - msg.type = ADD_SERVER_MSG; - else - msg.type = PING_SERVER_MSG; + free(id); +} + +static void +Update_server_thread (int *id) +{ + int same; - msg.length = (UINT32)sizeof (msg_server_t); - msg.room = 0; - if (MS_Write(&msg) < 0) + Lock_state(); { - MSLastPing = timestamp; - return ConnectionFailed(); + same = ( *id == MSRegisteredId ); } + Unlock_state(); - if(con_state != MSCS_REGISTERED) - CONS_Printf(M_GetText("Master Server update successful.\n")); + if (same) + Finish_update(); - MSLastPing = timestamp; - con_state = MSCS_REGISTERED; - CloseConnection(); -#endif - return MS_NO_ERROR; + free(id); } -static INT32 RemoveFromMasterSever(void) +static void +Unlist_server_thread (int *id) { - msg_t msg; - msg_server_t *info = (msg_server_t *)msg.buffer; - - strcpy(info->header.buffer, ""); - strcpy(info->ip, ""); - strcpy(info->port, int2str(current_port)); - strcpy(info->name, registered_server.name); - sprintf(info->version, "%d.%d", VERSION, SUBVERSION); - - msg.type = REMOVE_SERVER_MSG; - msg.length = (UINT32)sizeof (msg_server_t); - msg.room = 0; - if (MS_Write(&msg) < 0) - return MS_WRITE_ERROR; - - return MS_NO_ERROR; -} + int same; -const char *GetMasterServerPort(void) -{ - const char *t = cv_masterserver.string; + Lock_state(); + { + same = ( *id == MSRegisteredId ); + } + Unlock_state(); - while ((*t != ':') && (*t != '\0')) - t++; + if (same) + Finish_unlist(); - if (*t) - return ++t; - else - return DEF_PORT; + free(id); } -/** Gets the IP address of the master server. Actually, it seems to just - * return the hostname, instead; the lookup is done elsewhere. - * - * \return Hostname of the master server, without port number on the end. - * \todo Rename function? - */ -const char *GetMasterServerIP(void) +static void +Change_masterserver_thread (char *api) { - static char str_ip[64]; - char *t = str_ip; - - if (strstr(cv_masterserver.string, "srb2.ssntails.org:28910") - || strstr(cv_masterserver.string, "srb2.servegame.org:28910") - || strstr(cv_masterserver.string, "srb2.servegame.org:28900") - ) + Lock_state(); { - // replace it with the current default one - CV_Set(&cv_masterserver, cv_masterserver.defaultvalue); + while (MSRegistered) + I_hold_cond(&MSCond, MSMutex); } + Unlock_state(); - strcpy(t, cv_masterserver.string); - - while ((*t != ':') && (*t != '\0')) - t++; - *t = '\0'; - - return str_ip; + HMS_set_api(api); } +#endif/*HAVE_THREADS*/ -void MSOpenUDPSocket(void) +void RegisterServer(void) { -#ifndef NONET - if (I_NetMakeNodewPort) - { - // If it's already open, there's nothing to do. - if (msnode < 0) - msnode = I_NetMakeNodewPort(GetMasterServerIP(), GetMasterServerPort()); - } - else +#ifdef MASTERSERVER +#ifdef HAVE_THREADS + I_spawn_thread( + "register-server", + (I_thread_fn)Register_server_thread, + New_server_id() + ); +#else + Finish_registration(); #endif - msnode = -1; +#endif/*MASTERSERVER*/ } -void MSCloseUDPSocket(void) +static void UpdateServer(void) { - if (msnode != INT16_MAX) I_NetFreeNodenum(msnode); - msnode = -1; +#ifdef HAVE_THREADS + I_spawn_thread( + "update-server", + (I_thread_fn)Update_server_thread, + Server_id() + ); +#else + Finish_update(); +#endif } -void RegisterServer(void) +void UnregisterServer(void) { - if (con_state == MSCS_REGISTERED || con_state == MSCS_WAITING) - return; - - CONS_Printf(M_GetText("Registering this server on the Master Server...\n")); - - strcpy(registered_server.ip, GetMasterServerIP()); - strcpy(registered_server.port, GetMasterServerPort()); - - if (MS_Connect(registered_server.ip, registered_server.port, 1)) - { - CONS_Alert(CONS_ERROR, M_GetText("Cannot connect to the Master Server\n")); - return; - } - MSOpenUDPSocket(); +#ifdef MASTERSERVER +#ifdef HAVE_THREADS + I_spawn_thread( + "unlist-server", + (I_thread_fn)Unlist_server_thread, + Server_id() + ); +#else + Finish_unlist(); +#endif +#endif/*MASTERSERVER*/ +} - // keep the TCP connection open until AddToMasterServer() is completed; +static boolean +Online (void) +{ + return ( serverrunning && cv_advertise.value ); } static inline void SendPingToMasterServer(void) { -/* static tic_t next_time = 0; - tic_t cur_time; - char *inbuffer = (char*)netbuffer; + int ready; + time_t now; - cur_time = I_GetTime(); - if (!netgame) - UnregisterServer(); - else if (cur_time > next_time) // ping every 2 second if possible + if (Online()) { - next_time = cur_time+2*TICRATE; - - if (con_state == MSCS_WAITING) - AddToMasterServer(); + time(&now); - if (con_state != MSCS_REGISTERED) - return; + Lock_state(); + { + ready = ( + MSRegisteredId == MSId && + ! MSInProgress && + now >= ( MSLastPing + 60 * cv_masterserver_update_rate.value ) + ); + + if (ready) + MSInProgress = true; + } + Unlock_state(); - // cur_time is just a dummy data to send - WRITEUINT32(inbuffer, cur_time); - doomcom->datalength = sizeof (cur_time); - doomcom->remotenode = (INT16)msnode; - I_NetSend(); - } -*/ - -// Here, have a simpler MS Ping... - Cue - if(time(NULL) > (MSLastPing+(60*2)) && con_state != MSCS_NONE) - { - //CONS_Debug(DBG_NETPLAY, "%ld (current time) is greater than %d (Last Ping Time)\n", time(NULL), MSLastPing); - if(MSLastPing < 1) - AddToMasterServer(true); - else - AddToMasterServer(false); + if (ready) + UpdateServer(); } } -void SendAskInfoViaMS(INT32 node, tic_t asktime) +void MasterClient_Ticker(void) { - const char *address; - UINT16 port; - char *inip; - ms_holepunch_packet_t mshpp; - - MSOpenUDPSocket(); - - // This must be called after calling MSOpenUDPSocket, due to the - // static buffer. - address = I_GetNodeAddress(node); - - // no address? - if (!address) - return; - - // Copy the IP address into the buffer. - inip = mshpp.ip; - while(*address && *address != ':') *inip++ = *address++; - *inip = '\0'; - - // Get the port. - port = (UINT16)(*address++ ? atoi(address) : 0); - mshpp.port = SHORT(port); - - // Set the time for ping calculation. - mshpp.time = LONG(asktime); - - // Send to the MS. - M_Memcpy(netbuffer, &mshpp, sizeof(mshpp)); - doomcom->datalength = sizeof(ms_holepunch_packet_t); - doomcom->remotenode = (INT16)msnode; - I_NetSend(); +#ifdef MASTERSERVER + SendPingToMasterServer(); +#endif } -void UnregisterServer(void) +static void +Set_api (const char *api) { - if (con_state != MSCS_REGISTERED) - { - con_state = MSCS_NONE; - CloseConnection(); - return; - } +#ifdef HAVE_THREADS + I_spawn_thread( + "change-masterserver", + (I_thread_fn)Change_masterserver_thread, + strdup(api) + ); +#else + HMS_set_api(strdup(api)); +#endif +} - con_state = MSCS_NONE; +#endif/*MASTERSERVER*/ - CONS_Printf(M_GetText("Removing this server from the Master Server...\n")); +static void +Update_parameters (void) +{ +#ifdef MASTERSERVER + int registered; + int delayed; - if (MS_Connect(registered_server.ip, registered_server.port, 0)) + if (Online()) { - CONS_Alert(CONS_ERROR, M_GetText("Cannot connect to the Master Server\n")); - return; - } - - if (RemoveFromMasterSever() < 0) - CONS_Alert(CONS_ERROR, M_GetText("Cannot remove this server from the Master Server\n")); - - CloseConnection(); - MSCloseUDPSocket(); - MSLastPing = 0; -} + Lock_state(); + { + delayed = MSInProgress; -void MasterClient_Ticker(void) -{ - if (server && ms_RoomId > 0) - SendPingToMasterServer(); -} + if (delayed)/* do another update after the current one */ + MSUpdateAgain = true; + else + registered = MSRegistered; + } + Unlock_state(); -static void ServerName_OnChange(void) -{ - if (con_state == MSCS_REGISTERED) - AddToMasterServer(false); + if (! delayed && registered) + UpdateServer(); + } +#endif/*MASTERSERVER*/ } static void MasterServer_OnChange(void) { +#ifdef MASTERSERVER UnregisterServer(); - RegisterServer(); + + /* + TODO: remove this for v2, it's just a hack + for those coming in with an old config. + */ + if ( + ! cv_masterserver.changed && + strcmp(cv_masterserver.string, "ms.srb2.org:28900") == 0 + ){ + CV_StealthSet(&cv_masterserver, cv_masterserver.defaultvalue); + } + + Set_api(cv_masterserver.string); + + if (Online()) + RegisterServer(); +#endif/*MASTERSERVER*/ } -#ifndef NONET -// Like recv, but waits until we've got enough data to fill the buffer. -static size_t recvfull(SOCKET_TYPE s, char *buf, size_t len, int flags) +static void +Advertise_OnChange(void) { - /* Total received. */ - size_t totallen = 0; + int different; - while(totallen < len) + if (cv_advertise.value) { - ssize_t ret = (ssize_t)recv(s, buf + totallen, (int)(len - totallen), flags); - - /* Error. */ - if(ret == -1) - return (size_t)-1; + if (serverrunning) + { + Lock_state(); + { + different = ( MSId != MSRegisteredId ); + } + Unlock_state(); - totallen += ret; + if (different) + { + RegisterServer(); + } + } + } + else + { + UnregisterServer(); } - - return totallen; } -#endif diff --git a/src/mserv.h b/src/mserv.h index 8f8152a7c..02aaf3675 100644 --- a/src/mserv.h +++ b/src/mserv.h @@ -2,6 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1999-2018 by Sonic Team Junior. +// Copyright (C) 2020 by James R. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -13,10 +14,7 @@ #ifndef _MSERV_H_ #define _MSERV_H_ -#define MASTERSERVERS21 // MasterServer v2.1 - -// lowered from 32 due to menu changes -#define NUM_LIST_ROOMS 16 +#include "i_threads.h" #if defined(_MSC_VER) #pragma pack(1) @@ -34,19 +32,10 @@ typedef struct msg_header_t header; char ip[16]; char port[8]; - char name[32]; - INT32 room; + char contact[32]; char version[8]; // format is: x.yy.z (like 1.30.2 or 1.31) } ATTRPACK msg_server_t; -typedef struct -{ - msg_header_t header; - INT32 id; - char name[32]; - char motd[255]; -} ATTRPACK msg_rooms_t; - typedef struct { msg_header_t header; @@ -64,33 +53,41 @@ typedef struct // ================================ GLOBALS =============================== extern consvar_t cv_masterserver, cv_servername; +extern consvar_t cv_server_contact; +extern consvar_t cv_masterserver_update_rate; +extern consvar_t cv_masterserver_timeout; +extern consvar_t cv_masterserver_debug; +extern consvar_t cv_masterserver_token; -// < 0 to not connect (usually -1) (offline mode) -// == 0 to show all rooms, not a valid hosting room -// anything else is whatever room the MS assigns to that number (online mode) -extern INT16 ms_RoomId; - -const char *GetMasterServerPort(void); -const char *GetMasterServerIP(void); +extern consvar_t cv_advertise; -void MSOpenUDPSocket(void); -void MSCloseUDPSocket(void); +#ifdef HAVE_THREADS +extern int ms_QueryId; +extern I_mutex ms_QueryId_mutex; -void SendAskInfoViaMS(INT32 node, tic_t asktime); +extern msg_server_t *ms_ServerList; +extern I_mutex ms_ServerList_mutex; +#endif void RegisterServer(void); void UnregisterServer(void); void MasterClient_Ticker(void); -const msg_server_t *GetShortServersList(INT32 room); -INT32 GetRoomsList(boolean hosting); +msg_server_t *GetShortServersList(int id); #ifdef UPDATE_ALERT -const char *GetMODVersion(void); -void GetMODVersion_Console(void); +char *GetMODVersion(int id); #endif -extern msg_rooms_t room_list[NUM_LIST_ROOMS+1]; void AddMServCommands(void); +/* HTTP */ +void HMS_set_api (char *api); +int HMS_register (void); +int HMS_unlist (void); +int HMS_update (void); +void HMS_list_servers (void); +msg_server_t * HMS_fetch_servers (msg_server_t *list, int id); +int HMS_compare_mod_version (char *buffer, size_t size_of_buffer); + #endif diff --git a/src/p_enemy.c b/src/p_enemy.c index a3bf5491b..d41c4ffb6 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5795,13 +5795,8 @@ void A_MixUp(mobj_t *actor) P_SetThingPosition(players[i].mo); -#ifdef ESLOPE players[i].mo->floorz = P_GetFloorZ(players[i].mo, players[i].mo->subsector->sector, players[i].mo->x, players[i].mo->y, NULL); players[i].mo->ceilingz = P_GetCeilingZ(players[i].mo, players[i].mo->subsector->sector, players[i].mo->x, players[i].mo->y, NULL); -#else - players[i].mo->floorz = players[i].mo->subsector->sector->floorheight; - players[i].mo->ceilingz = players[i].mo->subsector->sector->ceilingheight; -#endif P_CheckPosition(players[i].mo, players[i].mo->x, players[i].mo->y); } @@ -8517,6 +8512,7 @@ void A_SPBChase(mobj_t *actor) //fast->momz = (3*actor->momz)/4; fast->color = SKINCOLOR_RED; fast->colorized = true; + P_SetTarget(&fast->target, actor); // easier lua access K_MatchGenericExtraFlags(fast, actor); } diff --git a/src/p_local.h b/src/p_local.h index 7216326d0..26035817d 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -328,9 +328,7 @@ extern mobj_t *tmfloorthing, *tmhitthing, *tmthing; extern camera_t *mapcampointer; extern fixed_t tmx; extern fixed_t tmy; -#ifdef ESLOPE extern pslope_t *tmfloorslope, *tmceilingslope; -#endif /* cphipps 2004/08/30 */ extern void P_MapStart(void); diff --git a/src/p_map.c b/src/p_map.c index 4664703d4..5d8a45afe 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -31,9 +31,7 @@ #include "r_splats.h" -#ifdef ESLOPE #include "p_slopes.h" -#endif #include "z_zone.h" @@ -56,9 +54,7 @@ fixed_t tmfloorz, tmceilingz; static fixed_t tmdropoffz, tmdrpoffceilz; // drop-off floor/ceiling heights mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz is from a sector mobj_t *tmhitthing; // the solid thing you bumped into (for collisions) -#ifdef ESLOPE pslope_t *tmfloorslope, *tmceilingslope; -#endif // keep track of the line that lowers the ceiling, // so missiles don't explode against sky hack walls @@ -135,9 +131,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) return false; } -#ifdef ESLOPE object->standingslope = NULL; // Okay, now we can't return - no launching off at silly angles for you. -#endif object->eflags |= MFE_SPRUNG; // apply this flag asap! spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify @@ -275,9 +269,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) zdist = object->z - spring->z; } -#ifdef ESLOPE object->standingslope = NULL; // No launching off at silly angles for you. -#endif switch (spring->type) { @@ -1758,9 +1750,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->z + thing->height > tmfloorz) { tmfloorz = thing->z + thing->height; -#ifdef ESLOPE tmfloorslope = NULL; -#endif } return true; } @@ -1777,17 +1767,13 @@ static boolean PIT_CheckThing(mobj_t *thing) && tmthing->z + tmthing->height < tmthing->ceilingz) { tmfloorz = tmceilingz = topz; // block while in air -#ifdef ESLOPE tmceilingslope = NULL; -#endif tmfloorthing = thing; // needed for side collision } else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height) { tmceilingz = topz; -#ifdef ESLOPE tmceilingslope = NULL; -#endif tmfloorthing = thing; // thing we may stand on } } @@ -1801,9 +1787,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->z < tmceilingz) { tmceilingz = thing->z; -#ifdef ESLOPE tmceilingslope = NULL; -#endif } return true; } @@ -1820,17 +1804,13 @@ static boolean PIT_CheckThing(mobj_t *thing) && tmthing->z > tmthing->floorz) { tmfloorz = tmceilingz = topz; // block while in air -#ifdef ESLOPE tmfloorslope = NULL; -#endif tmfloorthing = thing; // needed for side collision } else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z) { tmfloorz = topz; -#ifdef ESLOPE tmfloorslope = NULL; -#endif tmfloorthing = thing; // thing we may stand on } } @@ -1964,17 +1944,13 @@ if (tmthing->flags & MF_PAPERCOLLISION) // Caution! Turning whilst up against a { tmceilingz = opentop; ceilingline = ld; -#ifdef ESLOPE tmceilingslope = opentopslope; -#endif } if (openbottom > tmfloorz) { tmfloorz = openbottom; -#ifdef ESLOPE tmfloorslope = openbottomslope; -#endif } if (highceiling > tmdrpoffceilz) @@ -2053,10 +2029,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) // will adjust them. tmfloorz = tmdropoffz = P_GetFloorZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->floorheight; tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->ceilingheight; -#ifdef ESLOPE tmfloorslope = newsubsec->sector->f_slope; tmceilingslope = newsubsec->sector->c_slope; -#endif // Check list of fake floors and see if tmfloorz/tmceilingz need to be altered. if (newsubsec->sector->ffloors) @@ -2096,18 +2070,14 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) { if (tmfloorz < topheight - sinklevel) { tmfloorz = topheight - sinklevel; -#ifdef ESLOPE tmfloorslope = *rover->t_slope; -#endif } } else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= bottomheight + sinklevel && thing->momz >= 0) { if (tmceilingz > bottomheight + sinklevel) { tmceilingz = bottomheight + sinklevel; -#ifdef ESLOPE tmceilingslope = *rover->b_slope; -#endif } } } @@ -2129,9 +2099,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) { if (tmfloorz < thing->z) { tmfloorz = thing->z; -#ifdef ESLOPE tmfloorslope = NULL; -#endif } } // Quicksand blocks never change heights otherwise. @@ -2147,18 +2115,14 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) && !(rover->flags & FF_REVERSEPLATFORM)) { tmfloorz = tmdropoffz = topheight; -#ifdef ESLOPE tmfloorslope = *rover->t_slope; -#endif } if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2) && !(rover->flags & FF_PLATFORM) && !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))) { tmceilingz = tmdrpoffceilz = bottomheight; -#ifdef ESLOPE tmceilingslope = *rover->b_slope; -#endif } } } @@ -2175,7 +2139,6 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) BMBOUNDFIX(xl, xh, yl, yh); -#ifdef POLYOBJECTS // Check polyobjects and see if tmfloorz/tmceilingz need to be altered { validcount++; @@ -2233,23 +2196,18 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) if (polytop > tmfloorz && abs(delta1) < abs(delta2)) { tmfloorz = tmdropoffz = polytop; -#ifdef ESLOPE tmfloorslope = NULL; -#endif } if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) { tmceilingz = tmdrpoffceilz = polybottom; -#ifdef ESLOPE tmceilingslope = NULL; -#endif } } plink = (polymaplink_t *)(plink->link.next); } } } -#endif // tmfloorthing is set when tmfloorz comes from a thing's top tmfloorthing = NULL; @@ -2407,7 +2365,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) BMBOUNDFIX(xl, xh, yl, yh); -#ifdef POLYOBJECTS // Check polyobjects and see if tmfloorz/tmceilingz need to be altered { validcount++; @@ -2478,7 +2435,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) } } } -#endif // check lines for (bx = xl; bx <= xh; bx++) @@ -2657,10 +2613,8 @@ boolean PIT_PushableMoved(mobj_t *thing) mobj_t *oldthing = tmthing; line_t *oldceilline = ceilingline; line_t *oldblockline = blockingline; -#ifdef ESLOPE pslope_t *oldfslope = tmfloorslope; pslope_t *oldcslope = tmceilingslope; -#endif // Move the player P_TryMove(thing, thing->x+stand->momx, thing->y+stand->momy, true); @@ -2673,10 +2627,8 @@ boolean PIT_PushableMoved(mobj_t *thing) P_SetTarget(&tmthing, oldthing); ceilingline = oldceilline; blockingline = oldblockline; -#ifdef ESLOPE tmfloorslope = oldfslope; tmceilingslope = oldcslope; -#endif thing->momz = stand->momz; } else @@ -2698,9 +2650,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) fixed_t tryy = thing->y; fixed_t radius = thing->radius; fixed_t thingtop = thing->z + thing->height; -#ifdef ESLOPE fixed_t startingonground = P_IsObjectOnGround(thing); -#endif floatok = false; if (radius < MAXRADIUS/2) @@ -2791,26 +2741,22 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } -#ifdef ESLOPE else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep) { thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } -#endif } else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep) { thing->z = thing->floorz = tmfloorz; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } -#ifdef ESLOPE else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep) { thing->z = thing->floorz = tmfloorz; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } -#endif } if (thing->eflags & MFE_VERTICALFLIP) @@ -2872,7 +2818,6 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) thing->floorz = tmfloorz; thing->ceilingz = tmceilingz; -#ifdef ESLOPE if (!(thing->flags & MF_NOCLIPHEIGHT)) { // Assign thing's standingslope if needed @@ -2893,7 +2838,6 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) } else // don't set standingslope if you're not going to clip against it thing->standingslope = NULL; -#endif thing->x = x; thing->y = y; @@ -4674,10 +4618,8 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) sector_t *sec = R_PointInSubsector(x, y)->sector; fixed_t floorz = sec->floorheight; -#ifdef ESLOPE if (sec->f_slope) floorz = P_GetZAt(sec->f_slope, x, y); -#endif // Intercept the stupid 'fall through 3dfloors' bug Tails 03-17-2002 if (sec->ffloors) @@ -4697,12 +4639,10 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) topheight = *rover->topheight; bottomheight = *rover->bottomheight; -#ifdef ESLOPE if (*rover->t_slope) topheight = P_GetZAt(*rover->t_slope, x, y); if (*rover->b_slope) bottomheight = P_GetZAt(*rover->b_slope, x, y); -#endif if (rover->flags & FF_QUICKSAND) { diff --git a/src/p_maputl.c b/src/p_maputl.c index 355c58db8..260eb3ec6 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -308,9 +308,7 @@ fixed_t P_InterceptVector(divline_t *v2, divline_t *v1) // OPTIMIZE: keep this precalculated // fixed_t opentop, openbottom, openrange, lowfloor, highceiling; -#ifdef ESLOPE pslope_t *opentopslope, *openbottomslope; -#endif // P_CameraLineOpening // P_LineOpening, but for camera @@ -337,24 +335,20 @@ void P_CameraLineOpening(line_t *linedef) { frontfloor = sectors[front->camsec].floorheight; frontceiling = sectors[front->camsec].ceilingheight; -#ifdef ESLOPE if (sectors[front->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) frontfloor = P_GetZAt(sectors[front->camsec].f_slope, camera[0].x, camera[0].y); if (sectors[front->camsec].c_slope) frontceiling = P_GetZAt(sectors[front->camsec].c_slope, camera[0].x, camera[0].y); -#endif } else if (front->heightsec >= 0) { frontfloor = sectors[front->heightsec].floorheight; frontceiling = sectors[front->heightsec].ceilingheight; -#ifdef ESLOPE if (sectors[front->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) frontfloor = P_GetZAt(sectors[front->heightsec].f_slope, camera[0].x, camera[0].y); if (sectors[front->heightsec].c_slope) frontceiling = P_GetZAt(sectors[front->heightsec].c_slope, camera[0].x, camera[0].y); -#endif } else { @@ -365,23 +359,19 @@ void P_CameraLineOpening(line_t *linedef) { backfloor = sectors[back->camsec].floorheight; backceiling = sectors[back->camsec].ceilingheight; -#ifdef ESLOPE if (sectors[back->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) frontfloor = P_GetZAt(sectors[back->camsec].f_slope, camera[0].x, camera[0].y); if (sectors[back->camsec].c_slope) frontceiling = P_GetZAt(sectors[back->camsec].c_slope, camera[0].x, camera[0].y); -#endif } else if (back->heightsec >= 0) { backfloor = sectors[back->heightsec].floorheight; backceiling = sectors[back->heightsec].ceilingheight; -#ifdef ESLOPE if (sectors[back->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) frontfloor = P_GetZAt(sectors[back->heightsec].f_slope, camera[0].x, camera[0].y); if (sectors[back->heightsec].c_slope) frontceiling = P_GetZAt(sectors[back->heightsec].c_slope, camera[0].x, camera[0].y); -#endif } else { @@ -501,14 +491,12 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) } // Treat polyobjects kind of like 3D Floors -#ifdef POLYOBJECTS if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) { front = linedef->frontsector; back = linedef->frontsector; } else -#endif { front = linedef->frontsector; back = linedef->backsector; @@ -527,17 +515,13 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) { opentop = frontheight; highceiling = backheight; -#ifdef ESLOPE opentopslope = front->c_slope; -#endif } else { opentop = backheight; highceiling = frontheight; -#ifdef ESLOPE opentopslope = back->c_slope; -#endif } frontheight = P_GetFloorZ(mobj, front, tmx, tmy, linedef); @@ -547,17 +531,13 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) { openbottom = frontheight; lowfloor = backheight; -#ifdef ESLOPE openbottomslope = front->f_slope; -#endif } else { openbottom = backheight; lowfloor = frontheight; -#ifdef ESLOPE openbottomslope = back->f_slope; -#endif } } @@ -625,9 +605,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) // Check for fake floors in the sector. if (front->ffloors || back->ffloors -#ifdef POLYOBJECTS || linedef->polyobj -#endif ) { ffloor_t *rover; @@ -637,10 +615,8 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) fixed_t highestfloor = openbottom; fixed_t lowestfloor = lowfloor; fixed_t delta1, delta2; -#ifdef ESLOPE pslope_t *ceilingslope = opentopslope; pslope_t *floorslope = openbottomslope; -#endif // Check for frontsector's fake floors for (rover = front->ffloors; rover; rover = rover->next) @@ -665,9 +641,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) { if (bottomheight < lowestceiling) { lowestceiling = bottomheight; -#ifdef ESLOPE ceilingslope = *rover->b_slope; -#endif } else if (bottomheight < highestceiling) highestceiling = bottomheight; @@ -677,9 +651,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) { if (topheight > highestfloor) { highestfloor = topheight; -#ifdef ESLOPE floorslope = *rover->t_slope; -#endif } else if (topheight > lowestfloor) lowestfloor = topheight; @@ -709,9 +681,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) { if (bottomheight < lowestceiling) { lowestceiling = bottomheight; -#ifdef ESLOPE ceilingslope = *rover->b_slope; -#endif } else if (bottomheight < highestceiling) highestceiling = bottomheight; @@ -721,16 +691,13 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) { if (topheight > highestfloor) { highestfloor = topheight; -#ifdef ESLOPE floorslope = *rover->t_slope; -#endif } else if (topheight > lowestfloor) lowestfloor = topheight; } } -#ifdef POLYOBJECTS // Treat polyobj's backsector like a 3D Floor if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) { @@ -740,38 +707,29 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) delta2 = abs(thingtop - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2))); if (polysec->floorheight < lowestceiling && delta1 >= delta2) { lowestceiling = polysec->floorheight; -#ifdef ESLOPE ceilingslope = NULL; -#endif } else if (polysec->floorheight < highestceiling && delta1 >= delta2) highestceiling = polysec->floorheight; if (polysec->ceilingheight > highestfloor && delta1 < delta2) { highestfloor = polysec->ceilingheight; -#ifdef ESLOPE floorslope = NULL; -#endif } else if (polysec->ceilingheight > lowestfloor && delta1 < delta2) lowestfloor = polysec->ceilingheight; } -#endif if (highestceiling < highceiling) highceiling = highestceiling; if (highestfloor > openbottom) { openbottom = highestfloor; -#ifdef ESLOPE openbottomslope = floorslope; -#endif } if (lowestceiling < opentop) { opentop = lowestceiling; -#ifdef ESLOPE opentopslope = ceilingslope; -#endif } if (lowestfloor > lowfloor) @@ -1023,9 +981,7 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *)) { INT32 offset; const INT32 *list; // Big blockmap -#ifdef POLYOBJECTS polymaplink_t *plink; // haleyjd 02/22/06 -#endif line_t *ld; if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) @@ -1033,7 +989,6 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *)) offset = y*bmapwidth + x; -#ifdef POLYOBJECTS // haleyjd 02/22/06: consider polyobject lines plink = polyblocklinks[offset]; @@ -1057,7 +1012,6 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *)) } plink = (polymaplink_t *)(plink->link.next); } -#endif offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x]; diff --git a/src/p_maputl.h b/src/p_maputl.h index 1fcb68d4c..be69e0265 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -55,9 +55,7 @@ void P_CreatePrecipSecNodeList(precipmobj_t *thing, fixed_t x,fixed_t y); boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y); extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling; -#ifdef ESLOPE extern pslope_t *opentopslope, *openbottomslope; -#endif void P_LineOpening(line_t *plinedef, mobj_t *mobj); diff --git a/src/p_mobj.c b/src/p_mobj.c index f7f2afe34..506d7807b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -31,9 +31,7 @@ #include "i_video.h" #include "lua_hook.h" #include "b_bot.h" -#ifdef ESLOPE #include "p_slopes.h" -#endif #include "k_kart.h" @@ -646,12 +644,10 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover) topheight = *rover->topheight; bottomheight = *rover->bottomheight; -#ifdef ESLOPE if (*rover->t_slope) topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); if (*rover->b_slope) bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); -#endif if (mobj->z > topheight) return false; @@ -662,7 +658,6 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover) return true; } -#ifdef ESLOPE // P_GetFloorZ (and its ceiling counterpart) // Gets the floor height (or ceiling height) of the mobj's contact point in sector, assuming object's center if moved to [x, y] // If line is supplied, it's a divider line on the sector. Set it to NULL if you're not checking for collision with a line @@ -766,15 +761,11 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, P_GetZAt(slope, v2.x, v2.y) ); } -#endif fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) { -#ifdef ESLOPE I_Assert(mobj != NULL); -#endif I_Assert(sector != NULL); -#ifdef ESLOPE if (sector->f_slope) { fixed_t testx, testy; pslope_t *slope = sector->f_slope; @@ -844,25 +835,13 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the floor height -#else - (void)mobj; - (void)boundsec; - (void)x; - (void)y; - (void)line; - (void)lowest; - (void)perfect; -#endif return sector->floorheight; } fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) { -#ifdef ESLOPE I_Assert(mobj != NULL); -#endif I_Assert(sector != NULL); -#ifdef ESLOPE if (sector->c_slope) { fixed_t testx, testy; pslope_t *slope = sector->c_slope; @@ -932,26 +911,14 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the ceiling height -#else - (void)mobj; - (void)boundsec; - (void)x; - (void)y; - (void)line; - (void)lowest; - (void)perfect; -#endif return sector->ceilingheight; } // Now do the same as all above, but for cameras because apparently cameras are special? fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) { -#ifdef ESLOPE I_Assert(mobj != NULL); -#endif I_Assert(sector != NULL); -#ifdef ESLOPE if (sector->f_slope) { fixed_t testx, testy; pslope_t *slope = sector->f_slope; @@ -1021,25 +988,13 @@ fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fix return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the floor height -#else - (void)mobj; - (void)boundsec; - (void)x; - (void)y; - (void)line; - (void)lowest; - (void)perfect; -#endif return sector->floorheight; } fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) { -#ifdef ESLOPE I_Assert(mobj != NULL); -#endif I_Assert(sector != NULL); -#ifdef ESLOPE if (sector->c_slope) { fixed_t testx, testy; pslope_t *slope = sector->c_slope; @@ -1109,15 +1064,6 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the ceiling height -#else - (void)mobj; - (void)boundsec; - (void)x; - (void)y; - (void)line; - (void)lowest; - (void)perfect; -#endif return sector->ceilingheight; } static void P_PlayerFlip(mobj_t *mo) @@ -1406,9 +1352,7 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy) else if (abs(player->rmomx) < FixedMul(STOPSPEED, mo->scale) && abs(player->rmomy) < FixedMul(STOPSPEED, mo->scale) && (!(player->cmd.forwardmove && !(twodlevel || mo->flags2 & MF2_TWOD)) && !player->cmd.sidemove && !(player->pflags & PF_SPINNING)) -#ifdef ESLOPE && !(player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && (abs(player->mo->standingslope->zdelta) >= FRACUNIT/2)) -#endif ) { // if in a walking frame, stop moving @@ -1556,11 +1500,9 @@ void P_XYMovement(mobj_t *mo) fixed_t xmove, ymove; fixed_t oldx, oldy; // reducing bobbing/momentum on ice when up against walls boolean moved; -#ifdef ESLOPE pslope_t *oldslope = NULL; vector3_t slopemom; fixed_t predictedz = 0; -#endif I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); @@ -1590,7 +1532,6 @@ void P_XYMovement(mobj_t *mo) oldx = mo->x; oldy = mo->y; -#ifdef ESLOPE // adjust various things based on slope if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) { if (!P_IsObjectOnGround(mo)) { // We fell off at some point? Do the twisty thing! @@ -1612,7 +1553,6 @@ void P_XYMovement(mobj_t *mo) } } else if (P_IsObjectOnGround(mo) && !mo->momz) predictedz = mo->z; -#endif // Pushables can break some blocks if (CheckForBustableBlocks && mo->flags & MF_PUSHABLE) @@ -1799,7 +1739,6 @@ void P_XYMovement(mobj_t *mo) if (P_MobjWasRemoved(mo)) // MF_SPECIAL touched a player! O_o;; return; -#ifdef ESLOPE if (moved && oldslope) { // Check to see if we ran off if (oldslope != mo->standingslope) { // First, compare different slopes @@ -1847,7 +1786,6 @@ void P_XYMovement(mobj_t *mo) //CONS_Printf("Launched off of flat surface running into downward slope\n"); } } -#endif // Check the gravity status. P_CheckGravity(mo, false); @@ -1898,11 +1836,9 @@ void P_XYMovement(mobj_t *mo) if (player && player->pflags & PF_NIGHTSMODE) return; // no friction for NiGHTS players -#ifdef ESLOPE if ((mo->type == MT_BIGTUMBLEWEED || mo->type == MT_LITTLETUMBLEWEED) && (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8)) // Special exception for tumbleweeds on slopes return; -#endif //{ SRB2kart stuff if (mo->type == MT_ORBINAUT || mo->type == MT_JAWZ_DUD || mo->type == MT_JAWZ || mo->type == MT_BALLHOG) //(mo->type == MT_JAWZ && !mo->tracer)) @@ -2140,9 +2076,7 @@ boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover) { fixed_t topheight = - #ifdef ESLOPE *rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) : - #endif *rover->topheight; if (rover->flags & FF_SWIMMABLE && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3 @@ -2179,7 +2113,6 @@ static boolean P_ZMovement(mobj_t *mo) } mo->z += mo->momz; -#ifdef ESLOPE if (mo->standingslope) { if (mo->flags & MF_NOCLIPHEIGHT) @@ -2187,7 +2120,6 @@ static boolean P_ZMovement(mobj_t *mo) else if (!P_IsObjectOnGround(mo)) P_SlopeLaunch(mo); } -#endif switch (mo->type) { @@ -2378,7 +2310,6 @@ static boolean P_ZMovement(mobj_t *mo) else mo->z = mo->floorz; -#ifdef ESLOPE if (!(mo->flags & MF_MISSILE) && mo->standingslope) // You're still on the ground; why are we here? { mo->momz = 0; @@ -2391,7 +2322,6 @@ static boolean P_ZMovement(mobj_t *mo) mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope; P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope); } -#endif // hit the floor if (mo->type == MT_FIREBALL) // special case for the fireball @@ -2491,13 +2421,11 @@ static boolean P_ZMovement(mobj_t *mo) else mom.y -= FixedMul(6*FRACUNIT, mo->scale); } -#ifdef ESLOPE else if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) { // Pop the object up a bit to encourage bounciness //mom.z = P_MobjFlip(mo)*mo->scale; } -#endif else { mom.x = mom.y = mom.z = 0; @@ -2543,11 +2471,9 @@ static boolean P_ZMovement(mobj_t *mo) || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER)) mom.z = tmfloorthing->momz; -#ifdef ESLOPE if (mo->standingslope) { // MT_STEAM will never have a standingslope, see above. P_QuantizeMomentumToSlope(&mom, mo->standingslope); } -#endif mo->momx = mom.x; mo->momy = mom.y; @@ -2665,7 +2591,6 @@ static void P_PlayerZMovement(mobj_t *mo) || mo->player->playerstate == PST_REBORN) return; -#ifdef ESLOPE if (mo->standingslope) { if (mo->flags & MF_NOCLIPHEIGHT) @@ -2673,7 +2598,6 @@ static void P_PlayerZMovement(mobj_t *mo) else if (!P_IsObjectOnGround(mo)) P_SlopeLaunch(mo); } -#endif // clip movement if (P_IsObjectOnGround(mo) && !(mo->flags & MF_NOCLIPHEIGHT)) @@ -2702,19 +2626,15 @@ static void P_PlayerZMovement(mobj_t *mo) && mo->player->kartstuff[k_spinouttimer] == 0 && mo->player->kartstuff[k_squishedtimer] == 0) // SRB2kart P_SetPlayerMobjState(mo, S_KART_STND1); -#ifdef ESLOPE if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) { // Handle landing on slope during Z movement P_HandleSlopeLanding(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)); } -#endif -#ifdef ESLOPE if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) { // Handle landing on slope during Z movement P_HandleSlopeLanding(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)); } -#endif if (P_MobjFlip(mo)*mo->momz < 0) // falling { @@ -2732,7 +2652,6 @@ static void P_PlayerZMovement(mobj_t *mo) if (mo->eflags & MFE_JUSTHITFLOOR) { -#ifdef POLYOBJECTS // Check if we're on a polyobject // that triggers a linedef executor. msecnode_t *node; @@ -2792,7 +2711,6 @@ static void P_PlayerZMovement(mobj_t *mo) } if (!stopmovecut) -#endif // Cut momentum in half when you hit the ground and // aren't pressing any controls. @@ -2961,7 +2879,6 @@ static boolean P_SceneryZMovement(mobj_t *mo) // set standingslope P_TryMove(mo, mo->x, mo->y, true); mo->momz = -mo->momz; -#ifdef ESLOPE if (mo->standingslope) { if (mo->flags & MF_NOCLIPHEIGHT) @@ -2969,7 +2886,6 @@ static boolean P_SceneryZMovement(mobj_t *mo) else if (!P_IsObjectOnGround(mo)) P_SlopeLaunch(mo); } -#endif S_StartSound(mo, mo->info->activesound); } break; @@ -3138,13 +3054,11 @@ void P_MobjCheckWater(mobj_t *mobj) topheight = *rover->topheight; bottomheight = *rover->bottomheight; -#ifdef ESLOPE if (*rover->t_slope) topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); if (*rover->b_slope) bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); -#endif if (mobj->eflags & MFE_VERTICALFLIP) { @@ -3387,13 +3301,11 @@ static void P_SceneryCheckWater(mobj_t *mobj) topheight = *rover->topheight; bottomheight = *rover->bottomheight; -#ifdef ESLOPE if (*rover->t_slope) topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); if (*rover->b_slope) bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); -#endif if (topheight <= mobj->z || bottomheight > (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale))) @@ -3439,13 +3351,9 @@ static boolean P_CameraCheckHeat(camera_t *thiscam) continue; if (halfheight >= ( -#ifdef ESLOPE *rover->t_slope ? P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) : -#endif *rover->topheight) || halfheight <= ( -#ifdef ESLOPE *rover->b_slope ? P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) : -#endif *rover->bottomheight)) continue; @@ -3475,13 +3383,9 @@ static boolean P_CameraCheckWater(camera_t *thiscam) continue; if (halfheight >= ( -#ifdef ESLOPE *rover->t_slope ? P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) : -#endif *rover->topheight) || halfheight <= ( -#ifdef ESLOPE *rover->b_slope ? P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) : -#endif *rover->bottomheight)) continue; @@ -3681,9 +3585,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj) P_MobjCheckWater(mobj); -#ifdef ESLOPE P_ButteredSlope(mobj); -#endif // momentum movement mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN; @@ -3840,9 +3742,7 @@ static void CalculatePrecipFloor(precipmobj_t *mobj) else return; mobj->floorz = -#ifdef ESLOPE mobjsecsubsec->f_slope ? P_GetZAt(mobjsecsubsec->f_slope, mobj->x, mobj->y) : -#endif mobjsecsubsec->floorheight; if (mobjsecsubsec->ffloors) { @@ -3858,11 +3758,9 @@ static void CalculatePrecipFloor(precipmobj_t *mobj) if (!(rover->flags & FF_BLOCKOTHERS) && !(rover->flags & FF_SWIMMABLE)) continue; -#ifdef ESLOPE if (*rover->t_slope) topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); else -#endif topheight = *rover->topheight; if (topheight > mobj->floorz) @@ -8312,18 +8210,7 @@ void P_MobjThinker(mobj_t *mobj) if (!mobj->extravalue2) { - if (mobj->eflags & MFE_VERTICALFLIP) - mobj->z -= mobj->height; - else - mobj->z += mobj->height; - - S_StartSound(mobj, mobj->info->deathsound); - P_SetObjectMomZ(mobj, 8*FRACUNIT, false); - P_InstaThrust(mobj, R_PointToAngle2(mobj->target->x, mobj->target->y, mobj->x, mobj->y)+ANGLE_90, 16*FRACUNIT); - mobj->momx += mobj->target->momx; - mobj->momy += mobj->target->momy; - mobj->momz += mobj->target->momz; - mobj->extravalue2 = 1; + K_DropRocketSneaker(mobj->target->player); } else if (P_IsObjectOnGround(mobj)) { @@ -9343,7 +9230,6 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s mobj->eflags &= ~MFE_JUSTHITFLOOR; } -#ifdef ESLOPE // Sliding physics for slidey mobjs! if (mobj->type == MT_FLINGRING || mobj->type == MT_FLINGCOIN || P_WeaponOrPanel(mobj->type) @@ -9356,7 +9242,6 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s //if (mobj->standingslope) CONS_Printf("slope physics on mobj\n"); P_ButteredSlope(mobj); } -#endif if (mobj->flags & (MF_ENEMY|MF_BOSS) && mobj->health && P_CheckDeathPitCollide(mobj)) // extra pit check in case these didn't have momz @@ -9660,14 +9545,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) P_SetScale(mobj, mobj->destscale); mobj->floorz = -#ifdef ESLOPE mobj->subsector->sector->f_slope ? P_GetZAt(mobj->subsector->sector->f_slope, x, y) : -#endif mobj->subsector->sector->floorheight; mobj->ceilingz = -#ifdef ESLOPE mobj->subsector->sector->c_slope ? P_GetZAt(mobj->subsector->sector->c_slope, x, y) : -#endif mobj->subsector->sector->ceilingheight; // Tells MobjCheckWater that the water height was not set. @@ -10184,14 +10065,10 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype P_SetPrecipitationThingPosition(mobj); mobj->floorz = starting_floorz = -#ifdef ESLOPE mobj->subsector->sector->f_slope ? P_GetZAt(mobj->subsector->sector->f_slope, x, y) : -#endif mobj->subsector->sector->floorheight; mobj->ceilingz = -#ifdef ESLOPE mobj->subsector->sector->c_slope ? P_GetZAt(mobj->subsector->sector->c_slope, x, y) : -#endif mobj->subsector->sector->ceilingheight; mobj->z = z; @@ -10710,9 +10587,7 @@ void P_RespawnSpecials(void) if (mthing->options & MTF_OBJECTFLIP) { z = ( -#ifdef ESLOPE ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : -#endif ss->sector->ceilingheight) - (mthing->options >> ZSHIFT) * FRACUNIT; if (mthing->options & MTF_AMBUSH && (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i))) @@ -10722,9 +10597,7 @@ void P_RespawnSpecials(void) else { z = ( -#ifdef ESLOPE ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : -#endif ss->sector->floorheight) + (mthing->options >> ZSHIFT) * FRACUNIT; if (mthing->options & MTF_AMBUSH && (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i))) @@ -10981,14 +10854,10 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) sector = R_PointInSubsector(x, y)->sector; floor = -#ifdef ESLOPE sector->f_slope ? P_GetZAt(sector->f_slope, x, y) : -#endif sector->floorheight; ceiling = -#ifdef ESLOPE sector->c_slope ? P_GetZAt(sector->c_slope, x, y) : -#endif sector->ceilingheight; if (mthing) @@ -11060,14 +10929,10 @@ void P_MovePlayerToStarpost(INT32 playernum) sector = R_PointInSubsector(mobj->x, mobj->y)->sector; floor = -#ifdef ESLOPE sector->f_slope ? P_GetZAt(sector->f_slope, mobj->x, mobj->y) : -#endif sector->floorheight; ceiling = -#ifdef ESLOPE sector->c_slope ? P_GetZAt(sector->c_slope, mobj->x, mobj->y) : -#endif sector->ceilingheight; if (mobj->player->kartstuff[k_starpostflip]) @@ -11242,9 +11107,7 @@ void P_SpawnMapThing(mapthing_t *mthing) ss = R_PointInSubsector(mthing->x << FRACBITS, mthing->y << FRACBITS); mthing->z = (INT16)((( -#ifdef ESLOPE ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, mthing->x << FRACBITS, mthing->y << FRACBITS) : -#endif ss->sector->floorheight)>>FRACBITS) + (mthing->options >> ZSHIFT)); if (numhuntemeralds < MAXHUNTEMERALDS) @@ -11360,9 +11223,7 @@ void P_SpawnMapThing(mapthing_t *mthing) if (i == MT_NIGHTSBUMPER) z = ( -#ifdef ESLOPE ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : -#endif ss->sector->floorheight) + ((mthing->options >> ZSHIFT) << FRACBITS); else if (i == MT_AXIS || i == MT_AXISTRANSFER || i == MT_AXISTRANSFERLINE) z = ONFLOORZ; @@ -11371,9 +11232,7 @@ void P_SpawnMapThing(mapthing_t *mthing) if (mthing->options & MTF_OBJECTFLIP) { z = ( -#ifdef ESLOPE ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : -#endif ss->sector->ceilingheight); if (mthing->options & MTF_AMBUSH) // Special flag for rings @@ -11386,9 +11245,7 @@ void P_SpawnMapThing(mapthing_t *mthing) else { z = ( -#ifdef ESLOPE ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : -#endif ss->sector->floorheight); if (mthing->options & MTF_AMBUSH) // Special flag for rings @@ -11410,15 +11267,11 @@ void P_SpawnMapThing(mapthing_t *mthing) // base positions if (flip) z = ( -#ifdef ESLOPE ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : -#endif ss->sector->ceilingheight) - mobjinfo[i].height; else z = ( -#ifdef ESLOPE ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : -#endif ss->sector->floorheight); // offsetting @@ -11985,9 +11838,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) //hoopcenter->flags |= MF_NOTHINK; z += -#ifdef ESLOPE sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif sec->floorheight; hoopcenter->z = z - hoopcenter->height/2; @@ -12128,9 +11979,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) hoopcenter->spawnpoint = mthing; z += -#ifdef ESLOPE sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif sec->floorheight; hoopcenter->z = z - hoopcenter->height/2; @@ -12250,9 +12099,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) else if (mthing->type == mobjinfo[MT_NIGHTSWING].doomednum) { z = -#ifdef ESLOPE sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif sec->floorheight; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); @@ -12304,9 +12151,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) if (mthing->options & MTF_OBJECTFLIP) { z = ( -#ifdef ESLOPE sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : -#endif sec->ceilingheight) - mobjinfo[ringthing].height; if (mthing->options >> ZSHIFT) z -= ((mthing->options >> ZSHIFT) << FRACBITS); @@ -12314,9 +12159,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) else { z = -#ifdef ESLOPE sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif sec->floorheight; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); @@ -12370,9 +12213,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) if (mthing->options & MTF_OBJECTFLIP) { z = ( -#ifdef ESLOPE sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : -#endif sec->ceilingheight) - mobjinfo[ringthing].height - dist*r; if (mthing->options >> ZSHIFT) z -= ((mthing->options >> ZSHIFT) << FRACBITS); @@ -12380,9 +12221,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) else { z = ( -#ifdef ESLOPE sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif sec->floorheight) + dist*r; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); @@ -12428,9 +12267,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) if (mthing->options & MTF_OBJECTFLIP) { z = ( -#ifdef ESLOPE sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : -#endif sec->ceilingheight) - mobjinfo[ringthing].height - 64*FRACUNIT*r; if (mthing->options >> ZSHIFT) z -= ((mthing->options >> ZSHIFT) << FRACBITS); @@ -12438,9 +12275,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) else { z = ( -#ifdef ESLOPE sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif sec->floorheight) + 64*FRACUNIT*r; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); @@ -12473,9 +12308,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) } z = -#ifdef ESLOPE sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif sec->floorheight; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); diff --git a/src/p_mobj.h b/src/p_mobj.h index dfc8fc738..99ab0f0cd 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -368,9 +368,7 @@ typedef struct mobj_s INT32 cusval; INT32 cvmem; -#ifdef ESLOPE struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) -#endif boolean colorized; // Whether the mobj uses the rainbow colormap diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 03fb10d0f..60c653b16 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -28,7 +28,6 @@ #include "r_state.h" #include "r_defs.h" -#ifdef POLYOBJECTS /* Theory behind Polyobjects: @@ -2864,6 +2863,5 @@ INT32 EV_DoPolyObjFlag(line_t *pfdata) return 1; } -#endif // ifdef POLYOBJECTS // EOF diff --git a/src/p_polyobj.h b/src/p_polyobj.h index 60e996cae..9a47cd150 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -19,7 +19,6 @@ #include "r_defs.h" // haleyjd: temporary define -#ifdef POLYOBJECTS // // Defines // @@ -303,7 +302,6 @@ extern polyobj_t *PolyObjects; extern INT32 numPolyObjects; extern polymaplink_t **polyblocklinks; // polyobject blockmap -#endif // ifdef POLYOBJECTS #endif diff --git a/src/p_saveg.c b/src/p_saveg.c index 5bbba1f28..f587c6e69 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -30,9 +30,7 @@ #include "r_sky.h" #include "p_polyobj.h" #include "lua_script.h" -#ifdef ESLOPE #include "p_slopes.h" -#endif savedata_t savedata; UINT8 *save_p; @@ -949,9 +947,7 @@ typedef enum MD2_HPREV = 1<<8, MD2_COLORIZED = 1<<9, MD2_WAYPOINTCAP = 1<<10 -#ifdef ESLOPE , MD2_SLOPE = 1<<11 -#endif } mobj_diff2_t; typedef enum @@ -985,7 +981,6 @@ typedef enum tc_noenemies, tc_eachtime, tc_disappear, -#ifdef POLYOBJECTS tc_polyrotate, // haleyjd 03/26/06: polyobjects tc_polymove, tc_polywaypoint, @@ -993,7 +988,6 @@ typedef enum tc_polyswingdoor, tc_polyflag, tc_polydisplace, -#endif tc_end } specials_e; @@ -1142,10 +1136,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_HNEXT; if (mobj->hprev) diff2 |= MD2_HPREV; -#ifdef ESLOPE if (mobj->standingslope) diff2 |= MD2_SLOPE; -#endif if (mobj->colorized) diff2 |= MD2_COLORIZED; if (mobj == waypointcap) @@ -1265,10 +1257,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, mobj->hnext->mobjnum); if (diff2 & MD2_HPREV) WRITEUINT32(save_p, mobj->hprev->mobjnum); -#ifdef ESLOPE if (diff2 & MD2_SLOPE) WRITEUINT16(save_p, mobj->standingslope->id); -#endif if (diff2 & MD2_COLORIZED) WRITEUINT8(save_p, mobj->colorized); @@ -1552,7 +1542,6 @@ static void SaveDisappearThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->exists); } -#ifdef POLYOBJECTS // // SavePolyrotateThinker @@ -1662,7 +1651,6 @@ static void SavePolydisplaceThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->oldHeights); } -#endif /* // // SaveWhatThinker @@ -1842,7 +1830,6 @@ static void P_NetArchiveThinkers(void) SaveDisappearThinker(th, tc_disappear); continue; } -#ifdef POLYOBJECTS else if (th->function.acp1 == (actionf_p1)T_PolyObjRotate) { SavePolyrotatetThinker(th, tc_polyrotate); @@ -1878,7 +1865,6 @@ static void P_NetArchiveThinkers(void) SavePolydisplaceThinker(th, tc_polydisplace); continue; } -#endif #ifdef PARANOIA else if (th->function.acv != P_RemoveThinkerDelayed) // wait garbage collection I_Error("unknown thinker type %p", th->function.acp1); @@ -2142,10 +2128,8 @@ static void LoadMobjThinker(actionf_p1 thinker) mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p); if (diff2 & MD2_HPREV) mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p); -#ifdef ESLOPE if (diff2 & MD2_SLOPE) mobj->standingslope = P_SlopeById(READUINT16(save_p)); -#endif if (diff2 & MD2_COLORIZED) mobj->colorized = READUINT8(save_p); @@ -2517,7 +2501,6 @@ static inline void LoadDisappearThinker(actionf_p1 thinker) P_AddThinker(&ht->thinker); } -#ifdef POLYOBJECTS // // LoadPolyrotateThinker @@ -2637,7 +2620,6 @@ static inline void LoadPolydisplaceThinker(actionf_p1 thinker) ht->oldHeights = READFIXED(save_p); P_AddThinker(&ht->thinker); } -#endif /* // @@ -2806,7 +2788,6 @@ static void P_NetUnArchiveThinkers(void) case tc_disappear: LoadDisappearThinker((actionf_p1)T_Disappear); break; -#ifdef POLYOBJECTS case tc_polyrotate: LoadPolyrotatetThinker((actionf_p1)T_PolyObjRotate); break; @@ -2834,7 +2815,6 @@ static void P_NetUnArchiveThinkers(void) case tc_polydisplace: LoadPolydisplaceThinker((actionf_p1)T_PolyObjDisplace); break; -#endif case tc_scroll: LoadScrollThinker((actionf_p1)T_Scroll); break; @@ -2875,7 +2855,6 @@ static void P_NetUnArchiveThinkers(void) // // haleyjd 03/26/06: PolyObject saving code // -#ifdef POLYOBJECTS #define PD_FLAGS 0x01 #define PD_TRANS 0x02 @@ -2964,7 +2943,6 @@ static inline void P_UnArchivePolyObjects(void) for (i = 0; i < numSavedPolys; ++i) P_UnArchivePolyObj(&PolyObjects[i]); } -#endif // // P_FinishMobjs // @@ -3445,9 +3423,7 @@ void P_SaveNetGame(void) if (gamestate == GS_LEVEL) { P_NetArchiveWorld(); -#ifdef POLYOBJECTS P_ArchivePolyObjects(); -#endif P_NetArchiveThinkers(); P_NetArchiveSpecials(); } @@ -3489,9 +3465,7 @@ boolean P_LoadNetGame(void) if (gamestate == GS_LEVEL) { P_NetUnArchiveWorld(); -#ifdef POLYOBJECTS P_UnArchivePolyObjects(); -#endif P_NetUnArchiveThinkers(); P_NetUnArchiveSpecials(); P_RelinkPointers(); diff --git a/src/p_setup.c b/src/p_setup.c index 37bd77b5f..5956a5f93 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -78,9 +78,7 @@ #include "hardware/hw_light.h" #endif -#ifdef ESLOPE #include "p_slopes.h" -#endif // SRB2Kart #include "k_kart.h" @@ -1004,9 +1002,7 @@ static void P_LoadThings(void) // Z for objects mt->z = (INT16)( -#ifdef ESLOPE mtsector->f_slope ? P_GetZAt(mtsector->f_slope, mt->x << FRACBITS, mt->y << FRACBITS) : -#endif mtsector->floorheight)>>FRACBITS; if (mt->type == 1700 // MT_AXIS @@ -1277,9 +1273,7 @@ static void P_LoadRawLineDefs(UINT8 *data, size_t i) if (ld->sidenum[1] != 0xffff && ld->special) sides[ld->sidenum[1]].special = ld->special; -#ifdef POLYOBJECTS ld->polyobj = NULL; -#endif } } @@ -1407,8 +1401,6 @@ static void P_LoadRawSideDefs2(void *data) { UINT16 i; INT32 num; - size_t j; - RGBA_t color; for (i = 0; i < numsides; i++) { @@ -1475,6 +1467,8 @@ static void P_LoadRawSideDefs2(void *data) || (msd->bottomtexture[0] == '#' && msd->bottomtexture[1] && msd->bottomtexture[2] && msd->bottomtexture[3] && msd->bottomtexture[4] && msd->bottomtexture[5] && msd->bottomtexture[6])) { char *col; + RGBA_t color; + size_t j; sec->midmap = R_CreateColormap(msd->toptexture, msd->midtexture, msd->bottomtexture); @@ -1494,17 +1488,16 @@ static void P_LoadRawSideDefs2(void *data) color.s.red = (HEX2INT(col[1]) << 4) + HEX2INT(col[2]); color.s.green = (HEX2INT(col[3]) << 4) + HEX2INT(col[4]); color.s.blue = (HEX2INT(col[5]) << 4) + HEX2INT(col[6]); - color.s.alpha = 0; #ifdef GLENCORE if (encoremap) { j = encoremap[NearestColor(color.s.red, color.s.green, color.s.blue)]; //CONS_Printf("R_CreateColormap: encoremap[%d] = %d\n", j, encoremap[j]); -- moved encoremap upwards for optimisation - color = pLocalPalette[j]; + color = pLocalPalette[j]; // note: this sets alpha to 255, we will reset it below } #endif - + color.s.alpha = 0; // reset/init the alpha, so the addition below will work correctly sec->extra_colormap->rgba = color.rgba; // alpha @@ -1536,17 +1529,16 @@ static void P_LoadRawSideDefs2(void *data) color.s.red = (HEX2INT(col[1]) << 4) + HEX2INT(col[2]); color.s.green = (HEX2INT(col[3]) << 4) + HEX2INT(col[4]); color.s.blue = (HEX2INT(col[5]) << 4) + HEX2INT(col[6]); - color.s.alpha = 0; #ifdef GLENCORE if (encoremap) { j = encoremap[NearestColor(color.s.red, color.s.green, color.s.blue)]; //CONS_Printf("R_CreateColormap: encoremap[%d] = %d\n", j, encoremap[j]); -- moved encoremap upwards for optimisation - color = pLocalPalette[j]; + color = pLocalPalette[j]; // note: this sets alpha to 255, we will reset it below } #endif - + color.s.alpha = 0; // reset/init the alpha, so the addition below will work correctly sec->extra_colormap->fadergba = color.rgba; // alpha @@ -1951,11 +1943,9 @@ static void P_CreateBlockMap(void) blocklinks = Z_Calloc(count, PU_LEVEL, NULL); blockmap = blockmaplump + 4; -#ifdef POLYOBJECTS // haleyjd 2/22/06: setup polyobject blockmap count = sizeof(*polyblocklinks) * bmapwidth * bmapheight; polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL); -#endif } } @@ -2028,11 +2018,9 @@ static boolean P_LoadBlockMap(lumpnum_t lumpnum) blocklinks = Z_Calloc(count, PU_LEVEL, NULL); blockmap = blockmaplump+4; -#ifdef POLYOBJECTS // haleyjd 2/22/06: setup polyobject blockmap count = sizeof(*polyblocklinks) * bmapwidth * bmapheight; polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL); -#endif return true; /* Original blockmaplump = W_CacheLumpNum(lump, PU_LEVEL); @@ -2094,11 +2082,9 @@ static boolean P_LoadRawBlockMap(UINT8 *data, size_t count, const char *lumpname blocklinks = Z_Calloc(count, PU_LEVEL, NULL); blockmap = blockmaplump+4; -#ifdef POLYOBJECTS // haleyjd 2/22/06: setup polyobject blockmap count = sizeof(*polyblocklinks) * bmapwidth * bmapheight; polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL); -#endif return true; #endif } @@ -2976,7 +2962,7 @@ boolean P_SetupLevel(boolean skipprecip) snprintf(tx, 63, "%s%s%s", mapheaderinfo[gamemap-1]->lvlttl, (strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) ? va(" %s",mapheaderinfo[gamemap-1]->zonttl) : // SRB2kart - ((mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE"), + ((mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " Zone"), (strlen(mapheaderinfo[gamemap-1]->actnum) > 0) ? va(", Act %s",mapheaderinfo[gamemap-1]->actnum) : ""); V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx); I_UpdateNoVsync(); @@ -3118,9 +3104,7 @@ boolean P_SetupLevel(boolean skipprecip) P_PrepareThings(lastloadedmaplumpnum + ML_THINGS); } -#ifdef ESLOPE P_ResetDynamicSlopes(); -#endif P_LoadThings(); diff --git a/src/p_sight.c b/src/p_sight.c index 626f8bbef..87c52f162 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -99,7 +99,6 @@ static fixed_t P_InterceptVector2(divline_t *v2, divline_t *v1) return frac; } -#ifdef POLYOBJECTS static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los) { size_t i; @@ -145,7 +144,6 @@ static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los) return true; } -#endif // // P_CrossSubsector @@ -156,9 +154,7 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) { seg_t *seg; INT32 count; -#ifdef POLYOBJECTS polyobj_t *po; // haleyjd 02/23/06 -#endif #ifdef RANGECHECK if (num >= numsubsectors) @@ -168,7 +164,6 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) // haleyjd 02/23/06: this assignment should be after the above check seg = segs + subsectors[num].firstline; -#ifdef POLYOBJECTS // haleyjd 02/23/06: check polyobject lines if ((po = subsectors[num].polyList)) { @@ -183,7 +178,6 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) po = (polyobj_t *)(po->link.next); } } -#endif for (count = subsectors[num].numlines; --count >= 0; seg++) // check lines { @@ -334,15 +328,10 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) // killough 11/98: shortcut for melee situations // same subsector? obviously visible -#ifndef POLYOBJECTS - if (t1->subsector == t2->subsector) - return true; -#else // haleyjd 02/23/06: can't do this if there are polyobjects in the subsec if (!t1->subsector->polyList && t1->subsector == t2->subsector) return true; -#endif // An unobstructed LOS is possible. // Now look from eyes of t1 to any part of t2. diff --git a/src/p_slopes.c b/src/p_slopes.c index 76af7bfde..60c852f53 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -23,7 +23,6 @@ #include "p_maputl.h" #include "w_wad.h" -#ifdef ESLOPE static pslope_t *slopelist = NULL; static UINT16 slopecount = 0; @@ -620,7 +619,6 @@ void P_ResetDynamicSlopes(void) { size_t i; #ifdef ESLOPE_TYPESHIM // Rewrite old specials to new ones, and give a console warning boolean warned = false; -#endif slopelist = NULL; slopecount = 0; diff --git a/src/p_slopes.h b/src/p_slopes.h index 708a9107d..3dad65a48 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -13,7 +13,6 @@ #ifndef P_SLOPES_H__ #define P_SLOPES_H__ -#ifdef ESLOPE void P_CalculateSlopeNormal(pslope_t *slope); void P_ResetDynamicSlopes(void); void P_RunDynamicSlopes(void); @@ -41,7 +40,6 @@ void P_SlopeLaunch(mobj_t *mo); void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope); void P_ButteredSlope(mobj_t *mo); -#endif // EOF #endif // #ifdef ESLOPE diff --git a/src/p_spec.c b/src/p_spec.c index 165a2eba8..04d69c9b9 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1242,7 +1242,6 @@ INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start) } // haleyjd: temporary define -#ifdef POLYOBJECTS // // PolyDoor @@ -1451,7 +1450,6 @@ static boolean PolyDisplace(line_t *line) return EV_DoPolyObjDisplace(&pdd); } -#endif // ifdef POLYOBJECTS /** Changes a sector's tag. * Used by the linedef executor tag changer and by crumblers. @@ -3200,7 +3198,6 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; } -#ifdef POLYOBJECTS case 480: // Polyobj_DoorSlide case 481: // Polyobj_DoorSwing PolyDoor(line); @@ -3227,7 +3224,6 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 491: PolyTranslucency(line); break; -#endif default: break; @@ -4984,10 +4980,8 @@ void P_UpdateSpecials(void) // POINT LIMIT P_CheckPointLimit(); -#ifdef ESLOPE // Dynamic slopeness P_RunDynamicSlopes(); -#endif // ANIMATE TEXTURES for (anim = anims; anim < lastanim; anim++) @@ -5132,11 +5126,9 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f ffloor->topyoffs = &sec2->ceiling_yoffs; ffloor->topangle = &sec2->ceilingpic_angle; -#ifdef ESLOPE // Add slopes ffloor->t_slope = &sec2->c_slope; ffloor->b_slope = &sec2->f_slope; -#endif if ((flags & FF_SOLID) && (master->flags & ML_EFFECT1)) // Block player only flags &= ~FF_BLOCKOTHERS; @@ -5583,15 +5575,11 @@ void T_LaserFlash(laserthink_t *flash) sourcesec = ffloor->master->frontsector; // Less to type! -#ifdef ESLOPE top = (*ffloor->t_slope) ? P_GetZAt(*ffloor->t_slope, sector->soundorg.x, sector->soundorg.y) : *ffloor->topheight; bottom = (*ffloor->b_slope) ? P_GetZAt(*ffloor->b_slope, sector->soundorg.x, sector->soundorg.y) : *ffloor->bottomheight; sector->soundorg.z = (top + bottom)/2; -#else - sector->soundorg.z = (*ffloor->topheight + *ffloor->bottomheight)/2; -#endif S_StartSound(§or->soundorg, sfx_laser); // Seek out objects to DESTROY! MUAHAHHAHAHAA!!!*cough* @@ -6688,13 +6676,11 @@ void P_SpawnSpecials(INT32 fromnetsave) sectors[s].midmap = lines[i].frontsector->midmap; break; -#ifdef ESLOPE // Slope copy specials. Handled here for sanity. case 720: case 721: case 722: P_CopySectorSlope(&lines[i]); break; -#endif default: break; @@ -6708,7 +6694,6 @@ void P_SpawnSpecials(INT32 fromnetsave) Z_Free(secthinkers); -#ifdef POLYOBJECTS // haleyjd 02/20/06: spawn polyobjects Polyobj_InitLevel(); @@ -6725,7 +6710,6 @@ void P_SpawnSpecials(INT32 fromnetsave) break; } } -#endif P_RunLevelLoadExecutors(); } @@ -7246,11 +7230,9 @@ void T_Disappear(disappear_t *d) if (!(lines[d->sourceline].flags & ML_NOCLIMB)) { -#ifdef ESLOPE if (*rover->t_slope) sectors[s].soundorg.z = P_GetZAt(*rover->t_slope, sectors[s].soundorg.x, sectors[s].soundorg.y); else -#endif sectors[s].soundorg.z = *rover->topheight; S_StartSound(§ors[s].soundorg, sfx_appear); } diff --git a/src/p_tick.c b/src/p_tick.c index eaa8b4628..4cc6c9ba4 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -726,9 +726,9 @@ void P_Ticker(boolean run) if (exitcountdown > 1) exitcountdown--; - if (indirectitemcooldown > 1) + if (indirectitemcooldown > 0) indirectitemcooldown--; - if (hyubgone > 1) + if (hyubgone > 0) hyubgone--; if (G_BattleGametype()) diff --git a/src/p_user.c b/src/p_user.c index 03f8f0fbe..cb6b7bd62 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1781,13 +1781,8 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space if (GETSECSPECIAL(rover->master->frontsector->special, 1) != SPACESPECIAL) continue; -#ifdef ESLOPE topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) : *rover->topheight; bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) : *rover->bottomheight; -#else - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; -#endif if (mo->z + (mo->height/2) > topheight) continue; @@ -1821,13 +1816,8 @@ boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand if (!(rover->flags & FF_QUICKSAND)) continue; -#ifdef ESLOPE topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) : *rover->topheight; bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) : *rover->bottomheight; -#else - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; -#endif if (mo->z + flipoffset > topheight) continue; @@ -1966,9 +1956,7 @@ static void P_CheckBouncySectors(player_t *player) fixed_t oldx; fixed_t oldy; fixed_t oldz; -#ifdef ESLOPE vector3_t momentum; -#endif oldx = player->mo->x; oldy = player->mo->y; @@ -2023,7 +2011,6 @@ static void P_CheckBouncySectors(player_t *player) { fixed_t newmom; -#ifdef ESLOPE pslope_t *slope; if (abs(oldz - topheight) < abs(oldz + player->mo->height - bottomheight)) { // Hit top slope = *rover->t_slope; @@ -2039,9 +2026,6 @@ static void P_CheckBouncySectors(player_t *player) P_ReverseQuantizeMomentumToSlope(&momentum, slope); newmom = momentum.z = -FixedMul(momentum.z,linedist)/2; -#else - newmom = -FixedMul(player->mo->momz,linedist); -#endif if (abs(newmom) < (linedist*2)) { @@ -2064,7 +2048,6 @@ static void P_CheckBouncySectors(player_t *player) else if (newmom < -P_GetPlayerHeight(player)/2) newmom = -P_GetPlayerHeight(player)/2; -#ifdef ESLOPE momentum.z = newmom*2; if (slope) @@ -2073,9 +2056,6 @@ static void P_CheckBouncySectors(player_t *player) player->mo->momx = momentum.x; player->mo->momy = momentum.y; player->mo->momz = momentum.z/2; -#else - player->mo->momz = newmom; -#endif if (player->pflags & PF_SPINNING) { @@ -2132,13 +2112,8 @@ static void P_CheckQuicksand(player_t *player) if (!(rover->flags & FF_QUICKSAND)) continue; -#ifdef ESLOPE topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; -#else - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; -#endif if (topheight >= player->mo->z && bottomheight < player->mo->z + player->mo->height) { @@ -2506,15 +2481,10 @@ static void P_DoClimbing(player_t *player) // SRB2kart - unused floorclimb = true; else { -#ifdef ESLOPE floorheight = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight; ceilingheight = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight; -#else - floorheight = glidesector->sector->floorheight; - ceilingheight = glidesector->sector->ceilingheight; -#endif if (glidesector->sector->ffloors) { @@ -2528,13 +2498,8 @@ static void P_DoClimbing(player_t *player) // SRB2kart - unused floorclimb = true; -#ifdef ESLOPE topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; -#else - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; -#endif // Only supports rovers that are moving like an 'elevator', not just the top or bottom. if (rover->master->frontsector->floorspeed && rover->master->frontsector->ceilspeed == 42) @@ -2575,11 +2540,7 @@ static void P_DoClimbing(player_t *player) // SRB2kart - unused if (roverbelow == rover) continue; -#ifdef ESLOPE bottomheight2 = *roverbelow->b_slope ? P_GetZAt(*roverbelow->b_slope, player->mo->x, player->mo->y) : *roverbelow->bottomheight; -#else - bottomheight2 = *roverbelow->bottomheight; -#endif if (bottomheight2 < topheight + FixedMul(16*FRACUNIT, player->mo->scale)) foundfof = true; @@ -2625,11 +2586,7 @@ static void P_DoClimbing(player_t *player) // SRB2kart - unused if (roverbelow == rover) continue; -#ifdef ESLOPE topheight2 = *roverbelow->t_slope ? P_GetZAt(*roverbelow->t_slope, player->mo->x, player->mo->y) : *roverbelow->topheight; -#else - topheight2 = *roverbelow->topheight; -#endif if (topheight2 > bottomheight - FixedMul(16*FRACUNIT, player->mo->scale)) foundfof = true; @@ -2684,11 +2641,7 @@ static void P_DoClimbing(player_t *player) // SRB2kart - unused if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) continue; -#ifdef ESLOPE bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; -#else - bottomheight = *rover->bottomheight; -#endif if (bottomheight < floorheight + FixedMul(16*FRACUNIT, player->mo->scale)) { @@ -2729,11 +2682,7 @@ static void P_DoClimbing(player_t *player) // SRB2kart - unused if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) continue; -#ifdef ESLOPE topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; -#else - topheight = *rover->topheight; -#endif if (topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) { @@ -3102,12 +3051,10 @@ static void P_DoTeeter(player_t *player) // SRB2kart - unused. ceilingheight = sec->ceilingheight; floorheight = sec->floorheight; -#ifdef ESLOPE if (sec->c_slope) ceilingheight = P_GetZAt(sec->c_slope, checkx, checky); if (sec->f_slope) floorheight = P_GetZAt(sec->f_slope, checkx, checky); -#endif highestceilingheight = (ceilingheight > highestceilingheight) ? ceilingheight : highestceilingheight; lowestfloorheight = (floorheight < lowestfloorheight) ? floorheight : lowestfloorheight; @@ -3118,13 +3065,8 @@ static void P_DoTeeter(player_t *player) // SRB2kart - unused. { if (!(rover->flags & FF_EXISTS)) continue; -#ifdef ESLOPE topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; -#else - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; -#endif if (P_CheckSolidLava(player->mo, rover)) ; @@ -3196,7 +3138,6 @@ static void P_DoTeeter(player_t *player) // SRB2kart - unused. BMBOUNDFIX(xl, xh, yl, yh); // Polyobjects -#ifdef POLYOBJECTS validcount++; for (by = yl; by <= yh; by++) @@ -3290,7 +3231,6 @@ static void P_DoTeeter(player_t *player) // SRB2kart - unused. plink = (polymaplink_t *)(plink->link.next); } } -#endif if (teeter) // only bother with objects as a last resort if you were already teetering { mobj_t *oldtmthing = tmthing; @@ -3583,9 +3523,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) // SRB2kart - unused. && !P_PlayerInPain(player)) // subsequent revs { if ((cmd->buttons & BT_BRAKE) && player->speed < FixedMul(5<mo->scale) && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING) -#ifdef ESLOPE && (!player->mo->standingslope || (player->mo->standingslope->flags & SL_NOPHYSICS) || abs(player->mo->standingslope->zdelta) < FRACUNIT/2) -#endif ) { player->mo->momx = player->cmomx; @@ -3616,9 +3554,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) // SRB2kart - unused. // AKA Just go into a spin on the ground, you idiot. ;) else if ((cmd->buttons & BT_BRAKE || ((twodlevel || (player->mo->flags2 & MF2_TWOD)) && cmd->forwardmove < -20)) && !player->climbing && !player->mo->momz && onground && (player->speed > FixedMul(5<mo->scale) -#ifdef ESLOPE || (player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2) -#endif ) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)) { player->pflags |= PF_SPINNING; @@ -3632,9 +3568,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) // SRB2kart - unused. // Rolling normally if (onground && player->pflags & PF_SPINNING && !(player->pflags & PF_STARTDASH) && player->speed < FixedMul(5*FRACUNIT,player->mo->scale) -#ifdef ESLOPE && (!player->mo->standingslope || (player->mo->standingslope->flags & SL_NOPHYSICS) || abs(player->mo->standingslope->zdelta) < FRACUNIT/2) -#endif ) { if (GETSECSPECIAL(player->mo->subsector->sector->special, 4) == 7 || (player->mo->ceilingz - player->mo->floorz < P_GetPlayerHeight(player))) @@ -3873,9 +3807,7 @@ static void P_2dMovement(player_t *player) else if (player->onconveyor == 4 && !P_IsObjectOnGround(player->mo)) // Actual conveyor belt player->cmomx = player->cmomy = 0; else if (player->onconveyor != 2 && player->onconveyor != 4 -#ifdef POLYOBJECTS && player->onconveyor != 1 -#endif ) player->cmomx = player->cmomy = 0; @@ -4023,12 +3955,10 @@ static void P_3dMovement(player_t *player) //fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale); boolean analogmove = false; fixed_t oldMagnitude, newMagnitude; -#ifdef ESLOPE vector3_t totalthrust; totalthrust.x = totalthrust.y = 0; // I forget if this is needed totalthrust.z = FRACUNIT*P_MobjFlip(player->mo)/3; // A bit of extra push-back on slopes -#endif // ESLOPE // Get the old momentum; this will be needed at the end of the function! -SH oldMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0); @@ -4072,9 +4002,7 @@ static void P_3dMovement(player_t *player) else if (player->onconveyor == 4 && !P_IsObjectOnGround(player->mo)) // Actual conveyor belt player->cmomx = player->cmomy = 0; else if (player->onconveyor != 2 && player->onconveyor != 4 -#ifdef POLYOBJECTS && player->onconveyor != 1 -#endif ) player->cmomx = player->cmomy = 0; @@ -4152,12 +4080,8 @@ static void P_3dMovement(player_t *player) movepushforward = 0; } -#ifdef ESLOPE totalthrust.x += P_ReturnThrustX(player->mo, movepushangle, movepushforward); totalthrust.y += P_ReturnThrustY(player->mo, movepushangle, movepushforward); -#else - P_Thrust(player->mo, movepushangle, movepushforward); -#endif } else if (!(player->kartstuff[k_spinouttimer])) { @@ -4172,15 +4096,10 @@ static void P_3dMovement(player_t *player) else movepushside = (cmd->sidemove * FRACUNIT/128) - FixedDiv(player->speed, K_GetKartSpeed(player, true)); -#ifdef ESLOPE totalthrust.x += P_ReturnThrustX(player->mo, movepushsideangle, movepushside); totalthrust.y += P_ReturnThrustY(player->mo, movepushsideangle, movepushside); -#else - P_Thrust(player->mo, movepushsideangle, movepushside); -#endif } -#ifdef ESLOPE if ((totalthrust.x || totalthrust.y) && player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) { // Factor thrust to slope, but only for the part pushing up it! @@ -4200,7 +4119,6 @@ static void P_3dMovement(player_t *player) player->mo->momx += totalthrust.x; player->mo->momy += totalthrust.y; -#endif // Time to ask three questions: // 1) Are we over topspeed? @@ -5601,14 +5519,12 @@ void P_ElementalFireTrail(player_t *player) { newx = player->mo->x + P_ReturnThrustX(player->mo, travelangle + ((i&1) ? -1 : 1)*ANGLE_135, FixedMul(24*FRACUNIT, player->mo->scale)); newy = player->mo->y + P_ReturnThrustY(player->mo, travelangle + ((i&1) ? -1 : 1)*ANGLE_135, FixedMul(24*FRACUNIT, player->mo->scale)); -#ifdef ESLOPE if (player->mo->standingslope) { ground = P_GetZAt(player->mo->standingslope, newx, newy); if (player->mo->eflags & MFE_VERTICALFLIP) ground -= FixedMul(mobjinfo[MT_SPINFIRE].height, player->mo->scale); } -#endif flame = P_SpawnMobj(newx, newy, ground, MT_SPINFIRE); P_SetTarget(&flame->target, player->mo); flame->angle = travelangle; @@ -7487,13 +7403,14 @@ void P_ResetCamera(player_t *player, camera_t *thiscam) boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled) { - static UINT8 lookbackdelay[4] = {0,0,0,0}; + static boolean lookbackactive[MAXSPLITSCREENPLAYERS]; + static UINT8 lookbackdelay[MAXSPLITSCREENPLAYERS]; UINT8 num; angle_t angle = 0, focusangle = 0, focusaiming = 0; - fixed_t x, y, z, dist, height, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight; + fixed_t x, y, z, dist, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight; fixed_t pan, xpan, ypan; INT32 camrotate; - boolean camstill, lookback; + boolean camstill, lookback, lookbackdown; UINT8 timeover; mobj_t *mo; fixed_t f1, f2; @@ -7684,15 +7601,19 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall camstill = true; else if (lookback || lookbackdelay[num]) // SRB2kart - Camera flipper { +#define MAXLOOKBACKDELAY 2 camspeed = FRACUNIT; if (lookback) { camrotate += 180; - lookbackdelay[num] = 2; + lookbackdelay[num] = MAXLOOKBACKDELAY; } else lookbackdelay[num]--; } + lookbackdown = (lookbackdelay[num] == MAXLOOKBACKDELAY) != lookbackactive[num]; + lookbackactive[num] = (lookbackdelay[num] == MAXLOOKBACKDELAY); +#undef MAXLOOKBACKDELAY if (mo->eflags & MFE_VERTICALFLIP) camheight += thiscam->height; @@ -7735,8 +7656,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall thiscam->angle = angle; } - height = camheight; - // sets ideal cam pos dist = camdist; @@ -7745,10 +7664,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall dist += abs(thiscam->momz)/4; if (player->kartstuff[k_boostcam]) - { dist -= FixedMul(11*dist/16, player->kartstuff[k_boostcam]); - height -= FixedMul(height, player->kartstuff[k_boostcam]); - } x = mo->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist); y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist); @@ -7845,7 +7761,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } } -#ifdef POLYOBJECTS // Check polyobjects and see if floorz/ceilingz need to be altered { INT32 xl, xh, yl, yh, bx, by; @@ -7924,7 +7839,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } } } -#endif // crushed camera if (myceilingz <= myfloorz + thiscam->height && !resetcalled && !cameranoclip) @@ -8070,6 +7984,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall thiscam->aiming = ANGLE_22h; } + if (lookbackdown) + P_MoveChaseCamera(player, thiscam, false); + return (x == thiscam->x && y == thiscam->y && z == thiscam->z && angle == thiscam->aiming); } @@ -8201,13 +8118,8 @@ static void P_CalcPostImg(player_t *player) if (!(rover->flags & FF_EXISTS)) continue; -#ifdef ESLOPE topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; -#else - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; -#endif if (pviewheight >= topheight || pviewheight <= bottomheight) continue; @@ -8229,13 +8141,8 @@ static void P_CalcPostImg(player_t *player) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKPLAYER) continue; -#ifdef ESLOPE topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; -#else - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; -#endif if (pviewheight >= topheight || pviewheight <= bottomheight) continue; @@ -8510,9 +8417,7 @@ void P_PlayerThink(player_t *player) P_MobjCheckWater(player->mo); #ifndef SECTORSPECIALSAFTERTHINK -#ifdef POLYOBJECTS if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo)) -#endif player->onconveyor = 0; // check special sectors : damage & secrets @@ -8670,10 +8575,8 @@ void P_PlayerThink(player_t *player) // it lasts for one tic. player->pflags &= ~PF_FULLSTASIS; -#ifdef POLYOBJECTS if (player->onconveyor == 1) player->cmomy = player->cmomx = 0; -#endif //P_DoSuperStuff(player); //P_CheckSneakerAndLivesTimer(player); @@ -8921,9 +8824,7 @@ void P_PlayerAfterThink(player_t *player) cmd = &player->cmd; #ifdef SECTORSPECIALSAFTERTHINK -#ifdef POLYOBJECTS if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo)) -#endif player->onconveyor = 0; // check special sectors : damage & secrets diff --git a/src/r_bsp.c b/src/r_bsp.c index 43cb6432f..6e35fddc9 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -371,15 +371,11 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back) { return ( -#ifdef POLYOBJECTS !line->polyseg && -#endif back->ceilingpic == front->ceilingpic && back->floorpic == front->floorpic -#ifdef ESLOPE && back->f_slope == front->f_slope && back->c_slope == front->c_slope -#endif && back->lightlevel == front->lightlevel && !line->sidedef->midtexture // Check offsets too! @@ -494,7 +490,6 @@ static void R_AddLine(seg_t *line) doorclosed = 0; // Closed door. -#ifdef ESLOPE if (frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope) { fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends @@ -537,7 +532,6 @@ static void R_AddLine(seg_t *line) } } else -#endif { if (viewsector != backsector && viewsector != frontsector) { @@ -654,7 +648,6 @@ static boolean R_CheckBBox(const fixed_t *bspcoord) return true; } -#ifdef POLYOBJECTS size_t numpolys; // number of polyobjects in current subsector size_t num_po_ptrs; // number of polyobject pointers allocated @@ -819,7 +812,6 @@ static void R_AddPolyObjects(subsector_t *sub) R_AddLine(po_ptrs[i]->segs[j]); } } -#endif // // R_Subsector @@ -860,15 +852,11 @@ static void R_Subsector(size_t num) floorcolormap = ceilingcolormap = frontsector->extra_colormap; floorcenterz = -#ifdef ESLOPE frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) : -#endif frontsector->floorheight; ceilingcenterz = -#ifdef ESLOPE frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) : -#endif frontsector->ceilingheight; // Check and prep all 3D floors. Set the sector floor/ceiling light levels and colormaps. @@ -896,29 +884,21 @@ static void R_Subsector(size_t num) sub->sector->extra_colormap = frontsector->extra_colormap; if ((( -#ifdef ESLOPE frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : -#endif frontsector->floorheight) < viewz || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum))) { floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL -#ifdef POLYOBJECTS_PLANES , NULL -#endif -#ifdef ESLOPE , frontsector->f_slope -#endif , R_NoEncore(frontsector, false)); } else floorplane = NULL; if ((( -#ifdef ESLOPE frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : -#endif frontsector->ceilingheight) > viewz || frontsector->ceilingpic == skyflatnum || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum))) @@ -926,21 +906,15 @@ static void R_Subsector(size_t num) ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, ceilingcolormap, NULL -#ifdef POLYOBJECTS_PLANES , NULL -#endif -#ifdef ESLOPE , frontsector->c_slope -#endif , R_NoEncore(frontsector, true)); } else ceilingplane = NULL; numffloors = 0; -#ifdef ESLOPE ffloor[numffloors].slope = NULL; -#endif ffloor[numffloors].plane = NULL; ffloor[numffloors].polyobj = NULL; if (frontsector->ffloors) @@ -966,15 +940,11 @@ static void R_Subsector(size_t num) ffloor[numffloors].polyobj = NULL; heightcheck = -#ifdef ESLOPE *rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : -#endif *rover->bottomheight; planecenterz = -#ifdef ESLOPE *rover->b_slope ? P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) : -#endif *rover->bottomheight; if (planecenterz <= ceilingcenterz && planecenterz >= floorcenterz @@ -987,21 +957,15 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover -#ifdef POLYOBJECTS_PLANES , NULL -#endif -#ifdef ESLOPE , *rover->b_slope -#endif , R_NoEncore(rover->master->frontsector, true)); -#ifdef ESLOPE ffloor[numffloors].slope = *rover->b_slope; // Tell the renderer this sector has slopes in it. if (ffloor[numffloors].slope) frontsector->hasslope = true; -#endif ffloor[numffloors].height = heightcheck; ffloor[numffloors].ffloor = rover; @@ -1013,15 +977,11 @@ static void R_Subsector(size_t num) ffloor[numffloors].polyobj = NULL; heightcheck = -#ifdef ESLOPE *rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : -#endif *rover->topheight; planecenterz = -#ifdef ESLOPE *rover->t_slope ? P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) : -#endif *rover->topheight; if (planecenterz >= floorcenterz && planecenterz <= ceilingcenterz @@ -1033,21 +993,15 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, frontsector->lightlist[light].extra_colormap, rover -#ifdef POLYOBJECTS_PLANES , NULL -#endif -#ifdef ESLOPE , *rover->t_slope -#endif , R_NoEncore(rover->master->frontsector, false)); -#ifdef ESLOPE ffloor[numffloors].slope = *rover->t_slope; // Tell the renderer this sector has slopes in it. if (ffloor[numffloors].slope) frontsector->hasslope = true; -#endif ffloor[numffloors].height = heightcheck; ffloor[numffloors].ffloor = rover; @@ -1056,7 +1010,6 @@ static void R_Subsector(size_t num) } } -#ifdef POLYOBJECTS_PLANES // Polyobjects have planes, too! if (sub->polyList) { @@ -1086,16 +1039,12 @@ static void R_Subsector(size_t num) polysec->lightlevel, polysec->floor_xoffs, polysec->floor_yoffs, polysec->floorpic_angle-po->angle, NULL, NULL, po -#ifdef ESLOPE , NULL // will ffloors be slopable eventually? -#endif , R_NoEncore(polysec, false)); ffloor[numffloors].height = polysec->floorheight; ffloor[numffloors].polyobj = po; -#ifdef ESLOPE ffloor[numffloors].slope = NULL; -#endif // ffloor[numffloors].ffloor = rover; po->visplane = ffloor[numffloors].plane; numffloors++; @@ -1115,16 +1064,12 @@ static void R_Subsector(size_t num) polysec->lightlevel, polysec->ceiling_xoffs, polysec->ceiling_yoffs, polysec->ceilingpic_angle-po->angle, NULL, NULL, po -#ifdef ESLOPE , NULL // will ffloors be slopable eventually? -#endif , R_NoEncore(polysec, true)); ffloor[numffloors].polyobj = po; ffloor[numffloors].height = polysec->ceilingheight; -#ifdef ESLOPE ffloor[numffloors].slope = NULL; -#endif // ffloor[numffloors].ffloor = rover; po->visplane = ffloor[numffloors].plane; numffloors++; @@ -1133,7 +1078,6 @@ static void R_Subsector(size_t num) po = (polyobj_t *)(po->link.next); } } -#endif #ifdef FLOORSPLATS if (sub->splats) @@ -1156,18 +1100,14 @@ static void R_Subsector(size_t num) firstseg = NULL; -#ifdef POLYOBJECTS // haleyjd 02/19/06: draw polyobjects before static lines if (sub->polyList) R_AddPolyObjects(sub); -#endif while (count--) { // CONS_Debug(DBG_GAMELOGIC, "Adding normal line %d...(%d)\n", line->linedef-lines, leveltime); -#ifdef POLYOBJECTS if (!line->polyseg) // ignore segs that belong to polyobjects -#endif R_AddLine(line); line++; curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */ @@ -1186,11 +1126,9 @@ void R_Prep3DFloors(sector_t *sector) fixed_t bestheight, maxheight; INT32 count, i, mapnum; sector_t *sec; -#ifdef ESLOPE pslope_t *bestslope = NULL; fixed_t heighttest; // I think it's better to check the Z height at the sector's center // than assume unsloped heights are accurate indicators of order in sloped sectors. -Red -#endif count = 1; for (rover = sector->ffloors; rover; rover = rover->next) @@ -1213,14 +1151,10 @@ void R_Prep3DFloors(sector_t *sector) else memset(sector->lightlist, 0, sizeof (lightlist_t) * count); -#ifdef ESLOPE heighttest = sector->c_slope ? P_GetZAt(sector->c_slope, sector->soundorg.x, sector->soundorg.y) : sector->ceilingheight; sector->lightlist[0].height = heighttest + 1; sector->lightlist[0].slope = sector->c_slope; -#else - sector->lightlist[0].height = sector->ceilingheight + 1; -#endif sector->lightlist[0].lightlevel = §or->lightlevel; sector->lightlist[0].caster = NULL; sector->lightlist[0].extra_colormap = sector->extra_colormap; @@ -1238,7 +1172,6 @@ void R_Prep3DFloors(sector_t *sector) && !(rover->flags & FF_CUTLEVEL) && !(rover->flags & FF_CUTSPRITES))) continue; -#ifdef ESLOPE heighttest = *rover->t_slope ? P_GetZAt(*rover->t_slope, sector->soundorg.x, sector->soundorg.y) : *rover->topheight; if (heighttest > bestheight && heighttest < maxheight) @@ -1260,21 +1193,6 @@ void R_Prep3DFloors(sector_t *sector) continue; } } -#else - if (*rover->topheight > bestheight && *rover->topheight < maxheight) - { - best = rover; - bestheight = *rover->topheight; - continue; - } - if (rover->flags & FF_DOUBLESHADOW && *rover->bottomheight > bestheight - && *rover->bottomheight < maxheight) - { - best = rover; - bestheight = *rover->bottomheight; - continue; - } -#endif } if (!best) { @@ -1285,9 +1203,7 @@ void R_Prep3DFloors(sector_t *sector) sector->lightlist[i].height = maxheight = bestheight; sector->lightlist[i].caster = best; sector->lightlist[i].flags = best->flags; -#ifdef ESLOPE sector->lightlist[i].slope = bestslope; -#endif sec = §ors[best->secnum]; mapnum = sec->midmap; if (mapnum >= 0 && (size_t)mapnum < num_extra_colormaps) @@ -1313,12 +1229,8 @@ void R_Prep3DFloors(sector_t *sector) if (best->flags & FF_DOUBLESHADOW) { -#ifdef ESLOPE heighttest = *best->b_slope ? P_GetZAt(*best->b_slope, sector->soundorg.x, sector->soundorg.y) : *best->bottomheight; if (bestheight == heighttest) ///TODO: do this in a more efficient way -Red -#else - if (bestheight == *best->bottomheight) -#endif { sector->lightlist[i].lightlevel = sector->lightlist[best->lastlight].lightlevel; sector->lightlist[i].extra_colormap = diff --git a/src/r_bsp.h b/src/r_bsp.h index 1e4ca68fc..f0db9066f 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -44,13 +44,11 @@ void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2); // no longer a static since this is used for encore in hw_main.c as well now: boolean R_NoEncore(sector_t *sector, boolean ceiling); -#ifdef POLYOBJECTS void R_SortPolyObjects(subsector_t *sub); extern size_t numpolys; // number of polyobjects in current subsector extern size_t num_po_ptrs; // number of polyobject pointers allocated extern polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers -#endif sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, INT32 *ceilinglightlevel, boolean back); diff --git a/src/r_defs.h b/src/r_defs.h index 00036e9e9..6635e2afc 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -91,9 +91,7 @@ typedef struct fixed_t z; ///< Z coordinate. } degenmobj_t; -#ifdef POLYOBJECTS #include "p_polyobj.h" -#endif // Store fake planes in a resizable array insted of just by // heightsec. Allows for multiple fake planes. @@ -155,11 +153,9 @@ typedef struct ffloor_s fixed_t *bottomyoffs; angle_t *bottomangle; -#ifdef ESLOPE // Pointers to pointers. Yup. struct pslope_s **t_slope; struct pslope_s **b_slope; -#endif size_t secnum; ffloortype_e flags; @@ -190,9 +186,7 @@ typedef struct lightlist_s extracolormap_t *extra_colormap; INT32 flags; ffloor_t *caster; -#ifdef ESLOPE struct pslope_s *slope; // FF_DOUBLESHADOW makes me have to store this pointer here. Bluh bluh. -#endif } lightlist_t; @@ -226,7 +220,6 @@ typedef struct linechain_s // Slopes -#ifdef ESLOPE typedef enum { SL_NOPHYSICS = 1, // Don't do momentum adjustment with this slope SL_NODYNAMIC = 1<<1, // Slope will never need to move during the level, so don't fuss with recalculating it @@ -269,7 +262,6 @@ typedef struct pslope_s struct pslope_s *next; // Make a linked list of dynamic slopes, for easy reference later } pslope_t; -#endif typedef enum { @@ -376,12 +368,10 @@ typedef struct sector_s precipmobj_t *preciplist; struct mprecipsecnode_s *touching_preciplist; -#ifdef ESLOPE // Eternity engine slope pslope_t *f_slope; // floor slope pslope_t *c_slope; // ceiling slope boolean hasslope; // The sector, or one of its visible FOFs, contains a slope -#endif // these are saved for netgames, so do not let Lua touch these! INT32 spawn_nexttag, spawn_firsttag; // the actual nexttag/firsttag values may differ if the sector's tag was changed @@ -437,9 +427,7 @@ typedef struct line_s void *splats; // wallsplat_t list #endif INT32 firsttag, nexttag; // improves searches for tags. -#ifdef POLYOBJECTS polyobj_t *polyobj; // Belongs to a polyobject? -#endif char *text; // a concatination of all front and back texture names, for linedef specials that require a string. INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0 @@ -481,9 +469,7 @@ typedef struct subsector_s sector_t *sector; INT16 numlines; UINT16 firstline; -#ifdef POLYOBJECTS struct polyobj_s *polyList; // haleyjd 02/19/06: list of polyobjects -#endif #if 1//#ifdef FLOORSPLATS void *splats; // floorsplat_t list #endif @@ -559,10 +545,8 @@ typedef struct seg_s // Why slow things down by calculating lightlists for every thick side? size_t numlights; r_lightlist_t *rlights; -#ifdef POLYOBJECTS polyobj_t *polyseg; boolean dontrenderme; -#endif } seg_t; // @@ -639,11 +623,9 @@ typedef struct drawseg_s UINT8 portalpass; // if > 0 and <= portalrender, do not affect sprite clipping -#ifdef ESLOPE fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes -#endif } drawseg_t; typedef enum diff --git a/src/r_draw.c b/src/r_draw.c index 02a912155..a29c26a3c 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -112,11 +112,9 @@ fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; UINT8 *ds_source; // start of a 64*64 tile image UINT8 *ds_transmap; // one of the translucency tables -#ifdef ESLOPE pslope_t *ds_slope; // Current slope being used floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? float focallengthf, zeroheight; -#endif /** \brief Variable flat sizes */ diff --git a/src/r_draw.h b/src/r_draw.h index 900802cea..a9921028c 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -62,7 +62,6 @@ extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; extern UINT8 *ds_source; // start of a 64*64 tile image extern UINT8 *ds_transmap; -#ifdef ESLOPE typedef struct { float x, y, z; } floatv3_t; @@ -70,7 +69,6 @@ typedef struct { extern pslope_t *ds_slope; // Current slope being used extern floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? extern float focallengthf, zeroheight; -#endif // Variable flat sizes extern UINT32 nflatxshift; @@ -157,12 +155,10 @@ void ASMCALL R_DrawSpan_8_MMX(void); void R_DrawTranslatedColumn_8(void); void R_DrawTranslatedTranslucentColumn_8(void); void R_DrawSpan_8(void); -#ifdef ESLOPE void R_CalcTiltedLighting(fixed_t start, fixed_t end); void R_DrawTiltedSpan_8(void); void R_DrawTiltedTranslucentSpan_8(void); void R_DrawTiltedSplat_8(void); -#endif void R_DrawSplat_8(void); void R_DrawTranslucentSplat_8(void); void R_DrawTranslucentSpan_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index 634ae7075..37d93d162 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -620,7 +620,6 @@ void R_DrawSpan_8 (void) } } -#ifdef ESLOPE // R_CalcTiltedLighting // Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly. static INT32 tiltlighting[MAXVIDWIDTH]; @@ -1058,7 +1057,6 @@ void R_DrawTiltedSplat_8(void) } #endif } -#endif // ESLOPE /** \brief The R_DrawSplat_8 function Just like R_DrawSpan_8, but skips transparent pixels. diff --git a/src/r_main.c b/src/r_main.c index 6f2319b6c..5f3639ded 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -536,9 +536,7 @@ static void R_InitTextureMapping(void) focallength = FixedDiv(projection, FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2)); -#ifdef ESLOPE focallengthf = FIXED_TO_FLOAT(focallength); -#endif for (i = 0; i < FINEANGLES/2; i++) { diff --git a/src/r_plane.c b/src/r_plane.c index 659481ec8..d00274262 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -322,11 +322,9 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2) if (pindex >= MAXLIGHTZ) pindex = MAXLIGHTZ - 1; -#ifdef ESLOPE if (currentplane->slope) ds_colormap = colormaps; else -#endif ds_colormap = planezlight[pindex]; if (encoremap && !currentplane->noencore) ds_colormap += (256*32); @@ -424,20 +422,14 @@ static visplane_t *new_visplane(unsigned hash) visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, ffloor_t *pfloor -#ifdef POLYOBJECTS_PLANES , polyobj_t *polyobj -#endif -#ifdef ESLOPE , pslope_t *slope -#endif , boolean noencore) { visplane_t *check; unsigned hash; -#ifdef ESLOPE if (slope); else // Don't mess with this right now if a slope is involved -#endif { xoff += viewx; yoff -= viewy; @@ -452,7 +444,6 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, } } -#ifdef POLYOBJECTS_PLANES if (polyobj) { if (polyobj->angle != 0) @@ -467,7 +458,6 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, yoff += polyobj->centerPt.y; } } -#endif // This appears to fix the Nimbus Ruins sky bug. if (picnum == skyflatnum && pfloor) @@ -481,12 +471,10 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, for (check = visplanes[hash]; check; check = check->next) { -#ifdef POLYOBJECTS_PLANES if (check->polyobj && pfloor) continue; if (polyobj != check->polyobj) continue; -#endif if (height == check->height && picnum == check->picnum && lightlevel == check->lightlevel && xoff == check->xoffs && yoff == check->yoffs @@ -495,9 +483,7 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, && check->viewx == viewx && check->viewy == viewy && check->viewz == viewz && check->viewangle == viewangle && check->plangle == plangle -#ifdef ESLOPE && check->slope == slope -#endif && check->noencore == noencore) { return check; @@ -520,12 +506,8 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, check->viewz = viewz; check->viewangle = viewangle; check->plangle = plangle; -#ifdef POLYOBJECTS_PLANES check->polyobj = polyobj; -#endif -#ifdef ESLOPE check->slope = slope; -#endif check->noencore = noencore; memset(check->top, 0xff, sizeof (check->top)); @@ -593,12 +575,8 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop) new_pl->viewz = pl->viewz; new_pl->viewangle = pl->viewangle; new_pl->plangle = pl->plangle; -#ifdef POLYOBJECTS_PLANES new_pl->polyobj = pl->polyobj; -#endif -#ifdef ESLOPE new_pl->slope = pl->slope; -#endif new_pl->noencore = pl->noencore; pl = new_pl; pl->minx = start; @@ -623,11 +601,9 @@ void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop) INT32 unionl, unionh; // INT32 x; -#ifdef POLYOBJECTS_PLANES // Don't expand polyobject planes here - we do that on our own. if (pl->polyobj) return; -#endif if (start < pl->minx) { @@ -742,9 +718,7 @@ void R_DrawPlanes(void) } if (pl->ffloor != NULL -#ifdef POLYOBJECTS_PLANES || pl->polyobj != NULL -#endif ) continue; @@ -773,7 +747,6 @@ void R_DrawSinglePlane(visplane_t *pl) #endif spanfunc = basespanfunc; -#ifdef POLYOBJECTS_PLANES if (pl->polyobj && pl->polyobj->translucency != 0) { spanfunc = R_DrawTranslucentSpan_8; @@ -795,7 +768,6 @@ void R_DrawSinglePlane(visplane_t *pl) light = LIGHTLEVELS-1; } else -#endif if (pl->ffloor) { // Don't draw planes that shouldn't be drawn. @@ -861,9 +833,7 @@ void R_DrawSinglePlane(visplane_t *pl) #ifndef NOWATER if (pl->ffloor->flags & FF_RIPPLE -#ifdef ESLOPE && !pl->slope -#endif ) { INT32 top, bottom; @@ -902,9 +872,7 @@ void R_DrawSinglePlane(visplane_t *pl) } else light = (pl->lightlevel >> LIGHTSEGSHIFT); -#ifdef ESLOPE if (!pl->slope) // Don't mess with angle on slopes! We'll handle this ourselves later -#endif if (viewangle != pl->viewangle+pl->plangle) { memset(cachedheight, 0, sizeof (cachedheight)); @@ -978,7 +946,6 @@ void R_DrawSinglePlane(visplane_t *pl) if (light < 0) light = 0; -#ifdef ESLOPE if (pl->slope) { // Potentially override other stuff for now cus we're mean. :< But draw a slope plane! // I copied ZDoom's code and adapted it to SRB2... -fickle @@ -1118,7 +1085,6 @@ void R_DrawSinglePlane(visplane_t *pl) planezlight = scalelight[light]; } else -#endif // ESLOPE planezlight = zlight[light]; diff --git a/src/r_plane.h b/src/r_plane.h index 8f5a6073d..7a069d401 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -45,12 +45,8 @@ typedef struct visplane_s fixed_t xoffs, yoffs; // Scrolling flats. struct ffloor_s *ffloor; -#ifdef POLYOBJECTS_PLANES polyobj_t *polyobj; -#endif -#ifdef ESLOPE pslope_t *slope; -#endif boolean noencore; } visplane_t; @@ -83,12 +79,8 @@ void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2); void R_DrawPlanes(void); visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, ffloor_t *ffloor -#ifdef POLYOBJECTS_PLANES , polyobj_t *polyobj -#endif -#ifdef ESLOPE , pslope_t *slope -#endif , boolean noencore); visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop); void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop); @@ -108,18 +100,14 @@ typedef struct planemgr_s INT16 f_clip[MAXVIDWIDTH]; INT16 c_clip[MAXVIDWIDTH]; -#ifdef ESLOPE // For slope rendering; the height at the other end fixed_t f_pos_slope; fixed_t b_pos_slope; struct pslope_s *slope; -#endif struct ffloor_s *ffloor; -#ifdef POLYOBJECTS_PLANES polyobj_t *polyobj; -#endif } visffloor_t; extern visffloor_t ffloor[MAXFFLOORS]; diff --git a/src/r_segs.c b/src/r_segs.c index 399f514bc..c531be52d 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -51,20 +51,16 @@ static fixed_t rw_offset2; // for splats static fixed_t rw_scale, rw_scalestep; static fixed_t rw_midtexturemid, rw_toptexturemid, rw_bottomtexturemid; static INT32 worldtop, worldbottom, worldhigh, worldlow; -#ifdef ESLOPE static INT32 worldtopslope, worldbottomslope, worldhighslope, worldlowslope; // worldtop/bottom at end of slope static fixed_t rw_toptextureslide, rw_midtextureslide, rw_bottomtextureslide; // Defines how to adjust Y offsets along the wall for slopes static fixed_t rw_midtextureback, rw_midtexturebackslide; // Values for masked midtexture height calculation -#endif static fixed_t pixhigh, pixlow, pixhighstep, pixlowstep; static fixed_t topfrac, topstep; static fixed_t bottomfrac, bottomstep; static lighttable_t **walllights; static INT16 *maskedtexturecol; -#ifdef ESLOPE static fixed_t *maskedtextureheight = NULL; -#endif // ========================================================================== // R_Splats Wall Splats Drawer @@ -293,9 +289,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) sector_t *front, *back; INT32 times, repeats; INT64 overflow_test; -#ifdef ESLOPE INT32 range; -#endif // Calculate light table. // Use different light tables @@ -342,9 +336,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) colfunc = fuzzcolfunc; } -#ifdef ESLOPE range = max(ds->x2-ds->x1, 1); -#endif rw_scalestep = ds->scalestep; spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; @@ -374,12 +366,9 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) for (i = 0; i < dc_numlights; i++) { -#ifdef ESLOPE fixed_t leftheight, rightheight; -#endif light = &frontsector->lightlist[i]; rlight = &dc_lightlist[i]; -#ifdef ESLOPE if (light->slope) { leftheight = P_GetZAt(light->slope, ds->leftpos.x, ds->leftpos.y); rightheight = P_GetZAt(light->slope, ds->rightpos.x, ds->rightpos.y); @@ -394,10 +383,6 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) rlight->heightstep = (rlight->heightstep-rlight->height)/(range); //if (x1 > ds->x1) //rlight->height -= (x1 - ds->x1)*rlight->heightstep; -#else - rlight->height = (centeryfrac) - FixedMul((light->height - viewz), spryscale); - rlight->heightstep = -FixedMul(rw_scalestep, (light->height - viewz)); -#endif rlight->startheight = rlight->height; // keep starting value here to reset for each repeat rlight->lightlevel = *light->lightlevel; rlight->extra_colormap = light->extra_colormap; @@ -502,40 +487,18 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) } } -#ifndef ESLOPE - if (curline->linedef->flags & ML_DONTPEGBOTTOM) - { - dc_texturemid = front->floorheight > back->floorheight - ? front->floorheight : back->floorheight; - dc_texturemid = dc_texturemid + textureheight[texnum] - viewz; - } - else - { - dc_texturemid = front->ceilingheight < back->ceilingheight - ? front->ceilingheight : back->ceilingheight; - dc_texturemid = dc_texturemid - viewz; - } - dc_texturemid += curline->sidedef->rowoffset; - - if (curline->linedef->flags & ML_DONTPEGBOTTOM) - dc_texturemid += (textureheight[texnum])*times; - else - dc_texturemid -= (textureheight[texnum])*times; -#endif dc_texheight = textureheight[texnum]>>FRACBITS; // draw the columns for (dc_x = x1; dc_x <= x2; dc_x++) { -#ifdef ESLOPE dc_texturemid = ds->maskedtextureheight[dc_x]; if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3)) dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; else dc_texturemid -= (textureheight[texnum])*times; -#endif // calculate lighting if (maskedtexturecol[dc_x] != INT16_MAX) { @@ -742,14 +705,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) fixed_t offsetvalue = 0; lightlist_t *light; r_lightlist_t *rlight; -#ifdef ESLOPE INT32 range; -#endif -#ifndef ESLOPE - fixed_t lheight; -#endif line_t *newline = NULL; -#ifdef ESLOPE // Render FOF sides kinda like normal sides, with the frac and step and everything // NOTE: INT64 instead of fixed_t because overflow concerns INT64 top_frac, top_step, bottom_frac, bottom_step; @@ -759,7 +716,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) INT32 oldx = -1; fixed_t left_top, left_bottom; // needed here for slope skewing pslope_t *skewslope = NULL; -#endif void (*colfunc_2s) (column_t *); @@ -816,9 +772,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) else if (pfloor->flags & FF_FOG) colfunc = R_DrawFogColumn_8; -#ifdef ESLOPE range = max(ds->x2-ds->x1, 1); -#endif //SoM: Moved these up here so they are available for my lightlist calculations rw_scalestep = ds->scalestep; spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; @@ -835,14 +789,11 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) for (i = p = 0; i < dc_numlights; i++) { -#ifdef ESLOPE fixed_t leftheight, rightheight; fixed_t pfloorleft, pfloorright; INT64 overflow_test; -#endif light = &frontsector->lightlist[i]; rlight = &dc_lightlist[p]; -#ifdef ESLOPE #define SLOPEPARAMS(slope, end1, end2, normalheight) \ if (slope) { \ @@ -883,21 +834,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) else if (overflow_test > (INT64)CLAMPMIN) rlight->heightstep = (fixed_t)overflow_test; else rlight->heightstep = CLAMPMIN; rlight->heightstep = (rlight->heightstep-rlight->height)/(range); -#else - if (light->height < *pfloor->bottomheight) - continue; - - if (light->height > *pfloor->topheight && i+1 < dc_numlights && frontsector->lightlist[i+1].height > *pfloor->topheight) - continue; - - lheight = light->height;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : light->height; - rlight->heightstep = -FixedMul (rw_scalestep, (lheight - viewz)); - rlight->height = (centeryfrac) - FixedMul((lheight - viewz), spryscale); -#endif rlight->flags = light->flags; if (light->flags & FF_CUTLEVEL) { -#ifdef ESLOPE SLOPEPARAMS(*light->caster->b_slope, leftheight, rightheight, *light->caster->bottomheight) #undef SLOPEPARAMS leftheight -= viewz; @@ -914,11 +853,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) else if (overflow_test > (INT64)CLAMPMIN) rlight->botheightstep = (fixed_t)overflow_test; else rlight->botheightstep = CLAMPMIN; rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range); -#else - lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight; - rlight->botheightstep = -FixedMul (rw_scalestep, (lheight - viewz)); - rlight->botheight = (centeryfrac) - FixedMul((lheight - viewz), spryscale); -#endif } rlight->lightlevel = *light->lightlevel; @@ -975,7 +909,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) mceilingclip = ds->sprtopclip; dc_texheight = textureheight[texnum]>>FRACBITS; -#ifdef ESLOPE // calculate both left ends if (*pfloor->t_slope) left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; @@ -998,7 +931,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (slopeskew) dc_texturemid = left_top; else -#endif dc_texturemid = *pfloor->topheight - viewz; if (newline) @@ -1006,12 +938,10 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) offsetvalue = sides[newline->sidenum[0]].rowoffset; if (newline->flags & ML_DONTPEGBOTTOM) { -#ifdef ESLOPE skewslope = *pfloor->b_slope; // skew using bottom slope if (slopeskew) dc_texturemid = left_bottom; else -#endif offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; } } @@ -1020,17 +950,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset; if (curline->linedef->flags & ML_DONTPEGBOTTOM) { -#ifdef ESLOPE skewslope = *pfloor->b_slope; // skew using bottom slope if (slopeskew) dc_texturemid = left_bottom; else -#endif offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; } } -#ifdef ESLOPE if (slopeskew) { angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); @@ -1038,7 +965,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (skewslope) ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); } -#endif dc_texturemid += offsetvalue; @@ -1055,7 +981,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) column2s_length = textures[texnum]->height; } -#ifdef ESLOPE // Set heights according to plane, or slope, whichever { fixed_t right_top, right_bottom; @@ -1083,24 +1008,20 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) top_frac += top_step * (x1 - ds->x1); bottom_frac += bottom_step * (x1 - ds->x1); } -#endif // draw the columns for (dc_x = x1; dc_x <= x2; dc_x++) { if (maskedtexturecol[dc_x] != INT16_MAX) { -#ifdef ESLOPE if (ffloortextureslide) { // skew FOF walls if (oldx != -1) dc_texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])< (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac; else sprtopscreen = windowtop = CLAMPMIN; @@ -1110,10 +1031,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) top_frac += top_step; bottom_frac += bottom_step; -#else - sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale)); - sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen; -#endif // SoM: If column is out of range, why bother with it?? if (windowbottom < topbounds || windowtop > bottombounds) @@ -1323,9 +1240,7 @@ static void R_RenderSegLoop (void) INT32 mid; fixed_t texturecolumn = 0; -#ifdef ESLOPE fixed_t oldtexturecolumn = -1; -#endif INT32 top; INT32 bottom; INT32 i; @@ -1382,7 +1297,6 @@ static void R_RenderSegLoop (void) for (i = 0; i < numffloors; i++) { -#ifdef POLYOBJECTS_PLANES if (ffloor[i].polyobj && (!curline->polyseg || ffloor[i].polyobj != curline->polyseg)) continue; @@ -1393,7 +1307,6 @@ static void R_RenderSegLoop (void) else if (ffloor[i].plane->maxx < rw_x) ffloor[i].plane->maxx = rw_x; } -#endif if (ffloor[i].height < viewz) { @@ -1406,12 +1319,10 @@ static void R_RenderSegLoop (void) if (bottom_w > bottom) bottom_w = bottom; -#ifdef POLYOBJECTS_PLANES // Polyobject-specific hack to fix plane leaking -Red if (curline->polyseg && ffloor[i].polyobj && ffloor[i].polyobj == curline->polyseg && top_w >= bottom_w) { ffloor[i].plane->top[rw_x] = ffloor[i].plane->bottom[rw_x] = 0xFFFF; } else -#endif if (top_w <= bottom_w) { @@ -1430,12 +1341,10 @@ static void R_RenderSegLoop (void) if (bottom_w > bottom) bottom_w = bottom; -#ifdef POLYOBJECTS_PLANES // Polyobject-specific hack to fix plane leaking -Red if (curline->polyseg && ffloor[i].polyobj && ffloor[i].polyobj == curline->polyseg && top_w >= bottom_w) { ffloor[i].plane->top[rw_x] = ffloor[i].plane->bottom[rw_x] = 0xFFFF; } else -#endif if (top_w <= bottom_w) { @@ -1451,7 +1360,6 @@ static void R_RenderSegLoop (void) angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT; texturecolumn = rw_offset-FixedMul(FINETANGENT(angle),rw_distance); -#ifdef ESLOPE if (oldtexturecolumn != -1) { rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn-texturecolumn); rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn); @@ -1459,7 +1367,6 @@ static void R_RenderSegLoop (void) rw_midtextureback += FixedMul(rw_midtexturebackslide, oldtexturecolumn-texturecolumn); } oldtexturecolumn = texturecolumn; -#endif texturecolumn >>= FRACBITS; @@ -1637,13 +1544,11 @@ static void R_RenderSegLoop (void) // for backdrawing of masked mid texture maskedtexturecol[rw_x] = (INT16)texturecolumn; -#ifdef ESLOPE if (maskedtextureheight != NULL) { maskedtextureheight[rw_x] = (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3) ? max(rw_midtexturemid, rw_midtextureback) : min(rw_midtexturemid, rw_midtextureback)); } -#endif } if (dc_numlights) @@ -1699,26 +1604,19 @@ void R_StoreWallRange(INT32 start, INT32 stop) fixed_t sineval; angle_t distangle, offsetangle; boolean longboi; -#ifndef ESLOPE - fixed_t vtop; -#endif INT32 lightnum; INT32 i, p; lightlist_t *light; r_lightlist_t *rlight; INT32 range; -#ifdef ESLOPE vertex_t segleft, segright; fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; -#endif static size_t maxdrawsegs = 0; -#ifdef ESLOPE maskedtextureheight = NULL; //initialize segleft and segright memset(&segleft, 0x00, sizeof(segleft)); memset(&segright, 0x00, sizeof(segright)); -#endif if (ds_p == drawsegs+maxdrawsegs) { @@ -1824,7 +1722,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) // calculate texture boundaries // and decide if floor / ceiling marks are needed -#ifdef ESLOPE // Figure out map coordinates of where start and end are mapping to on seg, so we can clip right for slope bullshit if (frontsector->hasslope || (backsector && backsector->hasslope)) // Commenting this out for FOFslop. -Red { @@ -1880,22 +1777,15 @@ void R_StoreWallRange(INT32 start, INT32 stop) worldtopslope = P_GetZAt(frontsector->c_slope, segright.x, segright.y) - viewz; } else { worldtopslope = -#else - { -#endif worldtop = frontsector->ceilingheight - viewz; } -#ifdef ESLOPE if (frontsector->f_slope) { worldbottom = P_GetZAt(frontsector->f_slope, segleft.x, segleft.y) - viewz; worldbottomslope = P_GetZAt(frontsector->f_slope, segright.x, segright.y) - viewz; } else { worldbottomslope = -#else - { -#endif worldbottom = frontsector->floorheight - viewz; } @@ -1914,23 +1804,18 @@ void R_StoreWallRange(INT32 start, INT32 stop) { for (i = 0; i < numffloors; i++) { -#ifdef POLYOBJECTS_PLANES if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg)) continue; -#endif -#ifdef ESLOPE if (ffloor[i].slope) { ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) - viewz; ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y) - viewz; } else ffloor[i].f_pos_slope = -#endif ffloor[i].f_pos = ffloor[i].height - viewz; } } -#ifdef ESLOPE // Set up texture Y offset slides for sloped walls rw_toptextureslide = rw_midtextureslide = rw_bottomtextureslide = 0; ceilingfrontslide = floorfrontslide = ceilingbackslide = floorbackslide = 0; @@ -1950,7 +1835,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (backsector && backsector->c_slope) ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); } -#endif if (!backsector) { @@ -1960,7 +1844,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) texheight = textureheight[midtexture]; // a single sided line is terminal, so it must mark ends markfloor = markceiling = true; -#ifdef ESLOPE if (linedef->flags & ML_EFFECT2) { if (linedef->flags & ML_DONTPEGBOTTOM) rw_midtexturemid = frontsector->floorheight + texheight - viewz; @@ -1968,25 +1851,16 @@ void R_StoreWallRange(INT32 start, INT32 stop) rw_midtexturemid = frontsector->ceilingheight - viewz; } else -#endif if (linedef->flags & ML_DONTPEGBOTTOM) { -#ifdef ESLOPE rw_midtexturemid = worldbottom + texheight; rw_midtextureslide = floorfrontslide; -#else - vtop = frontsector->floorheight + texheight; - // bottom of texture at bottom - rw_midtexturemid = vtop - viewz; -#endif } else { // top of texture at top rw_midtexturemid = worldtop; -#ifdef ESLOPE rw_midtextureslide = ceilingfrontslide; -#endif } rw_midtexturemid += sidedef->rowoffset; @@ -2000,28 +1874,20 @@ void R_StoreWallRange(INT32 start, INT32 stop) { // two sided line -#ifdef ESLOPE if (backsector->c_slope) { worldhigh = P_GetZAt(backsector->c_slope, segleft.x, segleft.y) - viewz; worldhighslope = P_GetZAt(backsector->c_slope, segright.x, segright.y) - viewz; } else { worldhighslope = -#else - { -#endif worldhigh = backsector->ceilingheight - viewz; } -#ifdef ESLOPE if (backsector->f_slope) { worldlow = P_GetZAt(backsector->f_slope, segleft.x, segleft.y) - viewz; worldlowslope = P_GetZAt(backsector->f_slope, segright.x, segright.y) - viewz; } else { worldlowslope = -#else - { -#endif worldlow = backsector->floorheight - viewz; } @@ -2030,9 +1896,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (frontsector->ceilingpic == skyflatnum && backsector->ceilingpic == skyflatnum) { -#ifdef ESLOPE worldtopslope = worldhighslope = -#endif worldtop = worldhigh; } @@ -2040,26 +1904,16 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->silhouette = 0; if ( -#ifdef ESLOPE worldbottomslope > worldlowslope || -#endif worldbottom > worldlow) { ds_p->silhouette = SIL_BOTTOM; -#ifdef ESLOPE if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) ds_p->bsilheight = INT32_MAX; else ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight); -#else - ds_p->bsilheight = frontsector->floorheight; -#endif } -#ifdef ESLOPE else if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) -#else - else if (backsector->floorheight > viewz) -#endif { ds_p->silhouette = SIL_BOTTOM; ds_p->bsilheight = INT32_MAX; @@ -2067,26 +1921,16 @@ void R_StoreWallRange(INT32 start, INT32 stop) } if ( -#ifdef ESLOPE worldtopslope < worldhighslope || -#endif worldtop < worldhigh) { ds_p->silhouette |= SIL_TOP; -#ifdef ESLOPE if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) ds_p->tsilheight = INT32_MIN; else ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight); -#else - ds_p->tsilheight = frontsector->ceilingheight; -#endif } -#ifdef ESLOPE else if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) -#else - else if (backsector->ceilingheight < viewz) -#endif { ds_p->silhouette |= SIL_TOP; ds_p->tsilheight = INT32_MIN; @@ -2095,22 +1939,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (viewsector != frontsector && viewsector != backsector) { -#ifdef ESLOPE if (worldhigh <= worldbottom && worldhighslope <= worldbottomslope) -#else - if (worldhigh <= worldbottom) -#endif { ds_p->sprbottomclip = negonearray; ds_p->bsilheight = INT32_MAX; ds_p->silhouette |= SIL_BOTTOM; } -#ifdef ESLOPE if (worldlow >= worldtop && worldlowslope >= worldtopslope) -#else - if (worldlow >= worldtop) -#endif { ds_p->sprtopclip = screenheightarray; ds_p->tsilheight = INT32_MIN; @@ -2121,21 +1957,13 @@ void R_StoreWallRange(INT32 start, INT32 stop) // frontsector->ceiling and backsector->floor to see if a door was closed. // Without the following code, sprites get displayed behind closed doors. { -#ifdef ESLOPE if (doorclosed || (worldhigh <= worldbottom && worldhighslope <= worldbottomslope)) -#else - if (doorclosed || backsector->ceilingheight <= frontsector->floorheight) -#endif { ds_p->sprbottomclip = negonearray; ds_p->bsilheight = INT32_MAX; ds_p->silhouette |= SIL_BOTTOM; } -#ifdef ESLOPE if (doorclosed || (worldlow >= worldtop && worldlowslope >= worldtopslope)) -#else - if (doorclosed || backsector->floorheight >= frontsector->ceilingheight) -#endif { // killough 1/17/98, 2/8/98 ds_p->sprtopclip = screenheightarray; ds_p->tsilheight = INT32_MIN; @@ -2145,10 +1973,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) } if (worldlow != worldbottom -#ifdef ESLOPE || worldlowslope != worldbottomslope || backsector->f_slope != frontsector->f_slope -#endif || backsector->floorpic != frontsector->floorpic || backsector->lightlevel != frontsector->lightlevel //SoM: 3/22/2000: Check floor x and y offsets. @@ -2171,10 +1997,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) } if (worldhigh != worldtop -#ifdef ESLOPE || worldhighslope != worldtopslope || backsector->c_slope != frontsector->c_slope -#endif || backsector->ceilingpic != frontsector->ceilingpic || backsector->lightlevel != frontsector->lightlevel //SoM: 3/22/2000: Check floor x and y offsets. @@ -2205,9 +2029,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) // check TOP TEXTURE if (worldhigh < worldtop -#ifdef ESLOPE || worldhighslope < worldtopslope -#endif ) { fixed_t texheight; @@ -2228,66 +2050,48 @@ void R_StoreWallRange(INT32 start, INT32 stop) toptexture = R_GetTextureNum(sidedef->toptexture); texheight = textureheight[toptexture]; } -#ifdef ESLOPE if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked if (linedef->flags & ML_DONTPEGTOP) rw_toptexturemid = frontsector->ceilingheight - viewz; else rw_toptexturemid = backsector->ceilingheight - viewz; } else -#endif if (linedef->flags & ML_DONTPEGTOP) { // top of texture at top rw_toptexturemid = worldtop; -#ifdef ESLOPE rw_toptextureslide = ceilingfrontslide; -#endif } else { -#ifdef ESLOPE rw_toptexturemid = worldhigh + texheight; rw_toptextureslide = ceilingbackslide; -#else - vtop = backsector->ceilingheight + texheight; - // bottom of texture - rw_toptexturemid = vtop - viewz; -#endif } } // check BOTTOM TEXTURE if (worldlow > worldbottom -#ifdef ESLOPE || worldlowslope > worldbottomslope -#endif ) //seulement si VISIBLE!!! { // bottom texture bottomtexture = R_GetTextureNum(sidedef->bottomtexture); -#ifdef ESLOPE if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked if (linedef->flags & ML_DONTPEGBOTTOM) rw_bottomtexturemid = frontsector->floorheight - viewz; else rw_bottomtexturemid = backsector->floorheight - viewz; } else -#endif if (linedef->flags & ML_DONTPEGBOTTOM) { // bottom of texture at bottom // top of texture at top rw_bottomtexturemid = worldbottom; -#ifdef ESLOPE rw_bottomtextureslide = floorfrontslide; -#endif } else { // top of texture at top rw_bottomtexturemid = worldlow; -#ifdef ESLOPE rw_bottomtextureslide = floorbackslide; -#endif } } @@ -2300,12 +2104,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor_t *rover; ffloor_t *r2; fixed_t lowcut, highcut; -#ifdef ESLOPE fixed_t lowcutslope, highcutslope; // Used for height comparisons and etc across FOFs and slopes fixed_t high1, highslope1, low1, lowslope1, high2, highslope2, low2, lowslope2; -#endif //markceiling = markfloor = true; maskedtexture = true; @@ -2315,10 +2117,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) lowcut = max(worldbottom, worldlow) + viewz; highcut = min(worldtop, worldhigh) + viewz; -#ifdef ESLOPE lowcutslope = max(worldbottomslope, worldlowslope) + viewz; highcutslope = min(worldtopslope, worldhighslope) + viewz; -#endif if (frontsector->ffloors && backsector->ffloors) { @@ -2333,7 +2133,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (rover->norender == leveltime) continue; -#ifdef ESLOPE if (*rover->t_slope) { high1 = P_GetZAt(*rover->t_slope, segleft.x, segleft.y); highslope1 = P_GetZAt(*rover->t_slope, segright.x, segright.y); @@ -2347,10 +2146,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) continue; -#else - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) - continue; -#endif for (r2 = frontsector->ffloors; r2; r2 = r2->next) { @@ -2374,7 +2169,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; } -#ifdef ESLOPE if (*r2->t_slope) { high2 = P_GetZAt(*r2->t_slope, segleft.x, segleft.y); highslope2 = P_GetZAt(*r2->t_slope, segright.x, segright.y); @@ -2390,12 +2184,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) continue; -#else - if (*r2->topheight < lowcut || *r2->bottomheight > highcut) - continue; - if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) - continue; -#endif break; } @@ -2416,7 +2204,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (rover->norender == leveltime) continue; -#ifdef ESLOPE if (*rover->t_slope) { high1 = P_GetZAt(*rover->t_slope, segleft.x, segleft.y); highslope1 = P_GetZAt(*rover->t_slope, segright.x, segright.y); @@ -2430,10 +2217,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) continue; -#else - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) - continue; -#endif for (r2 = backsector->ffloors; r2; r2 = r2->next) { @@ -2457,7 +2240,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; } -#ifdef ESLOPE if (*r2->t_slope) { high2 = P_GetZAt(*r2->t_slope, segleft.x, segleft.y); highslope2 = P_GetZAt(*r2->t_slope, segright.x, segright.y); @@ -2473,12 +2255,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) continue; -#else - if (*r2->topheight < lowcut || *r2->bottomheight > highcut) - continue; - if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) - continue; -#endif break; } @@ -2498,17 +2274,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (rover->norender == leveltime) continue; -#ifdef ESLOPE // Oy vey. if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) continue; -#else - if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) - continue; -#endif ds_p->thicksides[i] = rover; i++; @@ -2522,7 +2293,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; if (rover->norender == leveltime) continue; -#ifdef ESLOPE // Oy vey. if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) @@ -2535,12 +2305,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldhigh+viewz && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldhighslope+viewz)) continue; -#else - if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) - continue; - if (*rover->topheight <= backsector->floorheight || *rover->bottomheight >= backsector->ceilingheight) - continue; -#endif ds_p->thicksides[i] = rover; i++; @@ -2560,10 +2324,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) else ds_p->maskedtexturecol = ds_p->thicksidecol; -#ifdef ESLOPE maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) -#ifdef POLYOBJECTS if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up rw_midtextureslide = rw_midtexturebackslide = 0; if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) @@ -2571,7 +2333,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) else rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz; } else -#endif // Set midtexture starting height if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing rw_midtextureslide = rw_midtexturebackslide = 0; @@ -2593,7 +2354,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) } rw_midtexturemid += sidedef->rowoffset; rw_midtextureback += sidedef->rowoffset; -#endif maskedtexture = true; } @@ -2658,9 +2418,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (frontsector->heightsec == -1) { if (( -#ifdef ESLOPE frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : -#endif frontsector->floorheight) >= viewz) { // above view plane @@ -2668,9 +2426,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) } if (( -#ifdef ESLOPE frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : -#endif frontsector->ceilingheight) <= viewz && frontsector->ceilingpic != skyflatnum) { @@ -2682,10 +2438,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) // calculate incremental stepping values for texture edges worldtop >>= 4; worldbottom >>= 4; -#ifdef ESLOPE worldtopslope >>= 4; worldbottomslope >>= 4; -#endif if (linedef->special == 41) { // HORIZON LINES topstep = bottomstep = 0; @@ -2698,7 +2452,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) bottomstep = -FixedMul (rw_scalestep,worldbottom); bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale); -#ifdef ESLOPE if (frontsector->c_slope) { fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldtopslope, ds_p->scale2); topstep = (topfracend-topfrac)/(range); @@ -2707,7 +2460,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldbottomslope, ds_p->scale2); bottomstep = (bottomfracend-bottomfrac)/(range); } -#endif } dc_numlights = 0; @@ -2723,14 +2475,11 @@ void R_StoreWallRange(INT32 start, INT32 stop) for (i = p = 0; i < dc_numlights; i++) { -#ifdef ESLOPE fixed_t leftheight, rightheight; -#endif light = &frontsector->lightlist[i]; rlight = &dc_lightlist[p]; -#ifdef ESLOPE if (light->slope) { leftheight = P_GetZAt(light->slope, segleft.x, segleft.y); rightheight = P_GetZAt(light->slope, segright.x, segright.y); @@ -2745,38 +2494,23 @@ void R_StoreWallRange(INT32 start, INT32 stop) leftheight >>= 4; rightheight >>= 4; -#endif if (i != 0) { -#ifdef ESLOPE if (leftheight < worldbottom && rightheight < worldbottomslope) continue; if (leftheight > worldtop && rightheight > worldtopslope && i+1 < dc_numlights && frontsector->lightlist[i+1].height > frontsector->ceilingheight) continue; -#else - if (light->height < frontsector->floorheight) - continue; - - if (light->height > frontsector->ceilingheight && i+1 < dc_numlights && frontsector->lightlist[i+1].height > frontsector->ceilingheight) - continue; -#endif } -#ifdef ESLOPE rlight->height = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); rlight->heightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); rlight->heightstep = (rlight->heightstep-rlight->height)/(range); -#else - rlight->height = (centeryfrac>>4) - FixedMul((light->height - viewz) >> 4, rw_scale); - rlight->heightstep = -FixedMul (rw_scalestep, (light->height - viewz) >> 4); -#endif rlight->flags = light->flags; if (light->caster && light->caster->flags & FF_CUTSOLIDS) { -#ifdef ESLOPE if (*light->caster->b_slope) { leftheight = P_GetZAt(*light->caster->b_slope, segleft.x, segleft.y); rightheight = P_GetZAt(*light->caster->b_slope, segright.x, segright.y); @@ -2796,10 +2530,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) rlight->botheightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range); -#else - rlight->botheight = (centeryfrac >> 4) - FixedMul((*light->caster->bottomheight - viewz) >> 4, rw_scale); - rlight->botheightstep = -FixedMul (rw_scalestep, (*light->caster->bottomheight - viewz) >> 4); -#endif } rlight->lightlevel = *light->lightlevel; @@ -2815,14 +2545,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) for (i = 0; i < numffloors; i++) { ffloor[i].f_pos >>= 4; -#ifdef ESLOPE ffloor[i].f_pos_slope >>= 4; ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(range); -#else - ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos); - ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); -#endif } } @@ -2830,42 +2555,34 @@ void R_StoreWallRange(INT32 start, INT32 stop) { worldhigh >>= 4; worldlow >>= 4; -#ifdef ESLOPE worldhighslope >>= 4; worldlowslope >>= 4; -#endif if (toptexture) { pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); pixhighstep = -FixedMul (rw_scalestep,worldhigh); -#ifdef ESLOPE if (backsector->c_slope) { fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); pixhighstep = (topfracend-pixhigh)/(range); } -#endif } if (bottomtexture) { pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); pixlowstep = -FixedMul (rw_scalestep,worldlow); -#ifdef ESLOPE if (backsector->f_slope) { fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); pixlowstep = (bottomfracend-pixlow)/(range); } -#endif } { ffloor_t * rover; -#ifdef ESLOPE fixed_t roverleft, roverright; fixed_t planevistest; -#endif i = 0; if (backsector->ffloors) @@ -2877,7 +2594,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (rover->norender == leveltime) continue; -#ifdef ESLOPE // Let the renderer know this sector is sloped. if (*rover->b_slope || *rover->t_slope) backsector->hasslope = true; @@ -2924,34 +2640,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); i++; } -#else - if (*rover->bottomheight <= backsector->ceilingheight && - *rover->bottomheight >= backsector->floorheight && - ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->bottomheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - i++; - } - - if (i >= MAXFFLOORS) - break; - - if (*rover->topheight >= backsector->floorheight && - *rover->topheight <= backsector->ceilingheight && - ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->topheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - i++; - } -#endif } } else if (frontsector && frontsector->ffloors) @@ -2964,7 +2652,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; -#ifdef ESLOPE // Let the renderer know this sector is sloped. if (*rover->b_slope || *rover->t_slope) frontsector->hasslope = true; @@ -3011,35 +2698,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); i++; } -#else - if (*rover->bottomheight <= frontsector->ceilingheight && - *rover->bottomheight >= frontsector->floorheight && - ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->bottomheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - i++; - } - if (i >= MAXFFLOORS) - break; - if (*rover->topheight >= frontsector->floorheight && - *rover->topheight <= frontsector->ceilingheight && - ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->topheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - i++; - } -#endif } } -#ifdef POLYOBJECTS_PLANES if (curline->polyseg && frontsector && (curline->polyseg->flags & POF_RENDERPLANES)) { while (i < numffloors && ffloor[i].polyobj != curline->polyseg) i++; @@ -3053,9 +2713,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (ffloor[i].plane->maxx < ds_p->x2) ffloor[i].plane->maxx = ds_p->x2; -#ifdef ESLOPE ffloor[i].slope = NULL; -#endif ffloor[i].b_pos = backsector->floorheight; ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); @@ -3072,9 +2730,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (ffloor[i].plane->maxx < ds_p->x2) ffloor[i].plane->maxx = ds_p->x2; -#ifdef ESLOPE ffloor[i].slope = NULL; -#endif ffloor[i].b_pos = backsector->ceilingheight; ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); @@ -3082,7 +2738,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) i++; } } -#endif numbackffloors = i; } diff --git a/src/r_things.c b/src/r_things.c index 59e148837..9cb35e191 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1052,10 +1052,8 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) if (!(sector->lightlist[i].caster->flags & FF_CUTSPRITES)) continue; -#ifdef ESLOPE if (sector->lightlist[i].slope) testheight = P_GetZAt(sector->lightlist[i].slope, sprite->gx, sprite->gy); -#endif if (testheight >= sprite->gzt) continue; @@ -1373,7 +1371,6 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->subsector->sector->numlights) { INT32 lightnum; -#ifdef ESLOPE // R_GetPlaneLight won't work on sloped lights! light = thing->subsector->sector->numlights - 1; for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) { @@ -1384,9 +1381,6 @@ static void R_ProjectSprite(mobj_t *thing) break; } } -#else - light = R_GetPlaneLight(thing->subsector->sector, gzt, false); -#endif lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT); if (lightnum < 0) @@ -1947,7 +1941,6 @@ static void R_CreateDrawNodes(void) entry->ffloor = ds->thicksides[i]; } } -#ifdef POLYOBJECTS_PLANES // Check for a polyobject plane, but only if this is a front line if (ds->curline->polyseg && ds->curline->polyseg->visplane && !ds->curline->side) { plane = ds->curline->polyseg->visplane; @@ -1963,7 +1956,6 @@ static void R_CreateDrawNodes(void) } ds->curline->polyseg->visplane = NULL; } -#endif if (ds->maskedtexturecol) { entry = R_CreateDrawNode(&nodehead); @@ -2008,7 +2000,6 @@ static void R_CreateDrawNodes(void) } } -#ifdef POLYOBJECTS_PLANES // find all the remaining polyobject planes and add them on the end of the list // probably this is a terrible idea if we wanted them to be sorted properly // but it works getting them in for now @@ -2029,7 +2020,6 @@ static void R_CreateDrawNodes(void) // note: no seg is set, for what should be obvious reasons PolyObjects[i].visplane = NULL; } -#endif if (visspritecount == 0) return; @@ -2052,13 +2042,11 @@ static void R_CreateDrawNodes(void) if (rover->szt > r2->plane->low || rover->sz < r2->plane->high) continue; -#ifdef ESLOPE // Effective height may be different for each comparison in the case of slopes if (r2->plane->slope) { planeobjectz = P_GetZAt(r2->plane->slope, rover->gx, rover->gy); planecameraz = P_GetZAt(r2->plane->slope, viewx, viewy); } else -#endif planeobjectz = planecameraz = r2->plane->height; if (rover->mobjflags & MF_NOCLIPHEIGHT) @@ -2117,20 +2105,16 @@ static void R_CreateDrawNodes(void) if (scale <= rover->sortscale) continue; -#ifdef ESLOPE if (*r2->ffloor->t_slope) { topplaneobjectz = P_GetZAt(*r2->ffloor->t_slope, rover->gx, rover->gy); topplanecameraz = P_GetZAt(*r2->ffloor->t_slope, viewx, viewy); } else -#endif topplaneobjectz = topplanecameraz = *r2->ffloor->topheight; -#ifdef ESLOPE if (*r2->ffloor->b_slope) { botplaneobjectz = P_GetZAt(*r2->ffloor->b_slope, rover->gx, rover->gy); botplanecameraz = P_GetZAt(*r2->ffloor->b_slope, viewx, viewy); } else -#endif botplaneobjectz = botplanecameraz = *r2->ffloor->bottomheight; if ((topplanecameraz > viewz && botplanecameraz < viewz) || @@ -2762,7 +2746,7 @@ void R_AddSkins(UINT16 wadnum) if (numskins >= MAXSKINS) { - CONS_Debug(DBG_RENDER, "ignored skin (%d skins maximum)\n", MAXSKINS); + CONS_Alert(CONS_WARNING, M_GetText("Unable to add skin, too many characters are loaded (%d maximum)\n"), MAXSKINS); continue; // so we know how many skins couldn't be added } buf = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE); diff --git a/src/s_sound.c b/src/s_sound.c index 2c96d389d..225863211 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -162,6 +162,9 @@ typedef struct // origin of sound const void *origin; + // initial volume of sound, which is applied after distance and direction + INT32 volume; + // handle of the sound being played INT32 handle; @@ -432,6 +435,7 @@ void S_StopSoundByNum(sfxenum_t sfxnum) void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) { + const INT32 initial_volume = volume; INT32 sep, pitch, priority, cnum; sfxinfo_t *sfx; const boolean reverse = (stereoreverse.value ^ encoremode); @@ -789,6 +793,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) // Assigns the handle to one of the channels in the // mix/output buffer. + channels[cnum].volume = initial_volume; channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum); } @@ -1054,7 +1059,7 @@ void S_UpdateSounds(void) if (I_SoundIsPlaying(c->handle)) { // initialize parameters - volume = 255; // 8 bits internal volume precision + volume = c->volume; // 8 bits internal volume precision pitch = NORM_PITCH; sep = NORM_SEP; @@ -1361,15 +1366,12 @@ INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *v } // volume calculation - if (approx_dist < S_CLOSE_DIST) - { - // SfxVolume is now hardware volume - *vol = 255; // not snd_SfxVolume - } - else + /* not sure if it should be > (no =), but this matches the old behavior */ + if (approx_dist >= S_CLOSE_DIST) { // distance effect - *vol = (15 * ((S_CLIPPING_DIST - approx_dist)>>FRACBITS)) / S_ATTENUATOR; + INT32 n = (15 * ((S_CLIPPING_DIST - approx_dist)>>FRACBITS)); + *vol = FixedMul(*vol * FRACUNIT / 255, n) / S_ATTENUATOR; } if (splitscreen) diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt index 33c83b8b3..04670bdc8 100644 --- a/src/sdl/CMakeLists.txt +++ b/src/sdl/CMakeLists.txt @@ -70,6 +70,8 @@ if(${SDL2_FOUND}) set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS} + ${SRB2_DISCORDRPC_SOURCES} + ${SRB2_DISCORDRPC_HEADERS} ${SRB2_PNG_SOURCES} ${SRB2_PNG_HEADERS} ${SRB2_CORE_RENDER_SOURCES} @@ -86,9 +88,11 @@ if(${SDL2_FOUND}) ${SRB2_PNG_SOURCES} ${SRB2_PNG_HEADERS}) source_group("Renderer" FILES ${SRB2_CORE_RENDER_SOURCES}) source_group("Game" FILES ${SRB2_CORE_GAME_SOURCES}) + source_group("Discord Rich Presence" FILES ${SRB2_DISCORDRPC_SOURCES} ${SRB2_DISCORDRPC_HEADERS}) source_group("Assembly" FILES ${SRB2_ASM_SOURCES} ${SRB2_NASM_SOURCES}) source_group("LUA" FILES ${SRB2_LUA_SOURCES} ${SRB2_LUA_HEADERS}) source_group("LUA\\Interpreter" FILES ${SRB2_BLUA_SOURCES} ${SRB2_BLUA_HEADERS}) + if(${SRB2_CONFIG_HWRENDER}) set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES} @@ -153,6 +157,7 @@ if(${SDL2_FOUND}) ${ZLIB_LIBRARIES} ${OPENGL_LIBRARIES} ${CURL_LIBRARIES} + ${DISCORDRPC_LIBRARIES} ) set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}") else() @@ -164,6 +169,7 @@ if(${SDL2_FOUND}) ${ZLIB_LIBRARIES} ${OPENGL_LIBRARIES} ${CURL_LIBRARIES} + ${DISCORDRPC_LIBRARIES} ) if(${CMAKE_SYSTEM} MATCHES Linux) @@ -244,6 +250,7 @@ if(${SDL2_FOUND}) ${ZLIB_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} + ${DISCORDRPC_INCLUDE_DIRS} ) if(${SRB2_HAVE_MIXER}) @@ -328,6 +335,10 @@ if(${SDL2_FOUND}) getwinlib(libgme "libgme.dll") endif() + if(${SRB2_CONFIG_HAVE_DISCORDRPC}) + getwinlib(discord-rpc "discord-rpc.dll") + endif() + install(PROGRAMS ${win_extra_dll_list} DESTINATION . diff --git a/src/sdl/Makefile.cfg b/src/sdl/Makefile.cfg index 58c4d0861..1744d6917 100644 --- a/src/sdl/Makefile.cfg +++ b/src/sdl/Makefile.cfg @@ -53,28 +53,6 @@ ifndef NOHW OBJS+=$(OBJDIR)/r_opengl.o $(OBJDIR)/ogl_sdl.o endif -ifndef NOHS -ifdef OPENAL - OBJS+=$(OBJDIR)/s_openal.o - OPTS+=-DSTATIC3DS - STATICHS=1 -else -ifdef FMOD - OBJS+=$(OBJDIR)/s_fmod.o - OPTS+=-DSTATIC3DS - STATICHS=1 -else -ifdef MINGW -ifdef DS3D - OBJS+=$(OBJDIR)/s_ds3d.o - OPTS+=-DSTATIC3DS - STATICHS=1 -endif -endif -endif -endif -endif - ifdef NOMIXER i_sound_o=$(OBJDIR)/sdl_sound.o else @@ -83,6 +61,11 @@ else SDL_LDFLAGS+=-lSDL2_mixer endif +ifndef NOTHREADS + OPTS+=-DHAVE_THREADS + OBJS+=$(OBJDIR)/i_threads.o +endif + ifdef SDL_TTF OPTS+=-DHAVE_TTF SDL_LDFLAGS+=-lSDL2_ttf -lfreetype -lz diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj index 69b3465ac..813e31a98 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj +++ b/src/sdl/Srb2SDL-vc10.vcxproj @@ -249,6 +249,7 @@ + @@ -399,6 +400,7 @@ + diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters index 9e5b98375..f197a394b 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj.filters +++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters @@ -291,6 +291,9 @@ I_Interface + + I_Interface + LUA @@ -663,6 +666,9 @@ I_Interface + + I_Interface + LUA diff --git a/src/sdl/Srb2SDL-vc9.vcproj b/src/sdl/Srb2SDL-vc9.vcproj index b21eedb87..115e17a30 100644 --- a/src/sdl/Srb2SDL-vc9.vcproj +++ b/src/sdl/Srb2SDL-vc9.vcproj @@ -2782,6 +2782,50 @@ RelativePath="..\mserv.h" > + + + + + + + + + + + + + + + + 0) + { + strrchr(path, '\\')[0] = '\0'; + SetCurrentDirectoryA(path); + } +} +#endif + + /** \brief The main function \param argc number of arg @@ -126,6 +140,10 @@ int main(int argc, char **argv) #endif #endif +#ifdef _WIN32 + ChDirToExe(); +#endif + logdir = D_Home(); #ifdef LOGMESSAGES diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index b66a4e0ab..51f708d0f 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -146,11 +146,6 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #define DEFAULTSEARCHPATH1 "/usr/local/games" #define DEFAULTSEARCHPATH2 "/usr/games" #define DEFAULTSEARCHPATH3 "/usr/local" -#elif defined (_WIN32) -#define DEFAULTWADLOCATION1 "c:\\games\\srb2kart" -#define DEFAULTWADLOCATION2 "\\games\\srb2kart" -#define DEFAULTSEARCHPATH1 "c:\\games" -#define DEFAULTSEARCHPATH2 "\\games" #endif /** \brief WAD file to look for @@ -168,6 +163,7 @@ static char returnWadPath[256]; #include "../i_video.h" #include "../i_sound.h" #include "../i_system.h" +#include "../i_threads.h" #include "../screen.h" //vid.WndParent #include "../d_net.h" #include "../g_game.h" @@ -3134,6 +3130,10 @@ INT32 I_StartupSystem(void) SDL_version SDLlinked; SDL_VERSION(&SDLcompiled) SDL_GetVersion(&SDLlinked); +#ifdef HAVE_THREADS + I_start_threads(); + I_AddExitFunc(I_stop_threads); +#endif I_StartupConsole(); #ifdef NEWSIGNALHANDLER I_Fork(); @@ -3655,6 +3655,18 @@ static const char *locateWad(void) #endif +#ifdef DEFAULTDIR + I_OutputMsg(",HOME/" DEFAULTDIR); + // examine user jart directory + if ((envstr = I_GetEnv("HOME")) != NULL) + { + sprintf(returnWadPath, "%s" PATHSEP DEFAULTDIR, envstr); + if (isWadPathOk(returnWadPath)) + return returnWadPath; + } +#endif + + #ifdef CMAKECONFIG #ifndef NDEBUG I_OutputMsg(","CMAKE_ASSETS_DIR); diff --git a/src/sdl/i_threads.c b/src/sdl/i_threads.c new file mode 100644 index 000000000..078f4e0f4 --- /dev/null +++ b/src/sdl/i_threads.c @@ -0,0 +1,356 @@ +// SONIC ROBO BLAST 2 KART +//----------------------------------------------------------------------------- +// Copyright (C) 2020 by James R. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file i_threads.c +/// \brief Multithreading abstraction + +#include "../doomdef.h" +#include "../i_threads.h" + +#include + +typedef void * (*Create_fn)(void); + +struct Link; +struct Thread; + +typedef struct Link * Link; +typedef struct Thread * Thread; + +struct Link +{ + void * data; + Link next; + Link prev; +}; + +struct Thread +{ + I_thread_fn entry; + void * userdata; + + SDL_Thread * thread; +}; + +static Link i_thread_pool; +static Link i_mutex_pool; +static Link i_cond_pool; + +static I_mutex i_thread_pool_mutex; +static I_mutex i_mutex_pool_mutex; +static I_mutex i_cond_pool_mutex; + +static SDL_atomic_t i_threads_running = {1}; + +static Link +Insert_link ( + Link * head, + Link link +){ + link->prev = NULL; + link->next = (*head); + if ((*head)) + (*head)->prev = link; + (*head) = link; + return link; +} + +static void +Free_link ( + Link * head, + Link link +){ + if (link->prev) + link->prev->next = link->next; + else + (*head) = link->next; + + if (link->next) + link->next->prev = link->prev; + + free(link->data); + free(link); +} + +static Link +New_link (void *data) +{ + Link link; + + link = malloc(sizeof *link); + + if (! link) + abort(); + + link->data = data; + + return link; +} + +static void * +Identity ( + Link * pool_anchor, + I_mutex pool_mutex, + + void ** anchor, + + Create_fn create_fn +){ + void * id; + + id = SDL_AtomicGetPtr(anchor); + + if (! id) + { + I_lock_mutex(&pool_mutex); + { + id = SDL_AtomicGetPtr(anchor); + + if (! id) + { + id = (*create_fn)(); + + if (! id) + abort(); + + Insert_link(pool_anchor, New_link(id)); + + SDL_AtomicSetPtr(anchor, id); + } + } + I_unlock_mutex(pool_mutex); + } + + return id; +} + +static int +Worker ( + Link link +){ + Thread th; + + th = link->data; + + (*th->entry)(th->userdata); + + if (SDL_AtomicGet(&i_threads_running)) + { + I_lock_mutex(&i_thread_pool_mutex); + { + if (SDL_AtomicGet(&i_threads_running)) + { + SDL_DetachThread(th->thread); + Free_link(&i_thread_pool, link); + } + } + I_unlock_mutex(i_thread_pool_mutex); + } + + return 0; +} + +void +I_spawn_thread ( + const char * name, + I_thread_fn entry, + void * userdata +){ + Link link; + Thread th; + + th = malloc(sizeof *th); + + if (! th) + abort();/* this is pretty GNU of me */ + + th->entry = entry; + th->userdata = userdata; + + I_lock_mutex(&i_thread_pool_mutex); + { + link = Insert_link(&i_thread_pool, New_link(th)); + + if (SDL_AtomicGet(&i_threads_running)) + { + th->thread = SDL_CreateThread( + (SDL_ThreadFunction)Worker, + name, + link + ); + + if (! th->thread) + abort(); + } + } + I_unlock_mutex(i_thread_pool_mutex); +} + +int +I_thread_is_stopped (void) +{ + return ( ! SDL_AtomicGet(&i_threads_running) ); +} + +void +I_start_threads (void) +{ + i_thread_pool_mutex = SDL_CreateMutex(); + i_mutex_pool_mutex = SDL_CreateMutex(); + i_cond_pool_mutex = SDL_CreateMutex(); + + if (!( + i_thread_pool_mutex && + i_mutex_pool_mutex && + i_cond_pool_mutex + )){ + abort(); + } +} + +void +I_stop_threads (void) +{ + Link link; + Link next; + + Thread th; + SDL_mutex * mutex; + SDL_cond * cond; + + if (i_threads_running.value) + { + /* rely on the good will of thread-san */ + SDL_AtomicSet(&i_threads_running, 0); + + I_lock_mutex(&i_thread_pool_mutex); + { + for ( + link = i_thread_pool; + link; + link = next + ){ + next = link->next; + th = link->data; + + SDL_WaitThread(th->thread, NULL); + + free(th); + free(link); + } + } + I_unlock_mutex(i_thread_pool_mutex); + + for ( + link = i_mutex_pool; + link; + link = next + ){ + next = link->next; + mutex = link->data; + + SDL_DestroyMutex(mutex); + + free(link); + } + + for ( + link = i_cond_pool; + link; + link = next + ){ + next = link->next; + cond = link->data; + + SDL_DestroyCond(cond); + + free(link); + } + + SDL_DestroyMutex(i_thread_pool_mutex); + SDL_DestroyMutex(i_mutex_pool_mutex); + SDL_DestroyMutex(i_cond_pool_mutex); + } +} + +void +I_lock_mutex ( + I_mutex * anchor +){ + SDL_mutex * mutex; + + mutex = Identity( + &i_mutex_pool, + i_mutex_pool_mutex, + anchor, + (Create_fn)SDL_CreateMutex + ); + + if (SDL_LockMutex(mutex) == -1) + abort(); +} + +void +I_unlock_mutex ( + I_mutex id +){ + if (SDL_UnlockMutex(id) == -1) + abort(); +} + +void +I_hold_cond ( + I_cond * cond_anchor, + I_mutex mutex_id +){ + SDL_cond * cond; + + cond = Identity( + &i_cond_pool, + i_cond_pool_mutex, + cond_anchor, + (Create_fn)SDL_CreateCond + ); + + if (SDL_CondWait(cond, mutex_id) == -1) + abort(); +} + +void +I_wake_one_cond ( + I_cond * anchor +){ + SDL_cond * cond; + + cond = Identity( + &i_cond_pool, + i_cond_pool_mutex, + anchor, + (Create_fn)SDL_CreateCond + ); + + if (SDL_CondSignal(cond) == -1) + abort(); +} + +void +I_wake_all_cond ( + I_cond * anchor +){ + SDL_cond * cond; + + cond = Identity( + &i_cond_pool, + i_cond_pool_mutex, + anchor, + (Create_fn)SDL_CreateCond + ); + + if (SDL_CondBroadcast(cond) == -1) + abort(); +} diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index e5ac04592..1e19e0b8a 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -20,6 +20,7 @@ /// \brief SRB2 graphics stuff for SDL #include +#include #include @@ -81,6 +82,10 @@ #include "ogl_sdl.h" #endif +#ifdef HAVE_DISCORDRPC +#include "../discord.h" +#endif + // maximum number of windowed modes (see windowedModes[][]) #define MAXWINMODES (18) @@ -92,7 +97,7 @@ static INT32 numVidModes = -1; */ static char vidModeName[33][32]; // allow 33 different modes -rendermode_t rendermode=render_soft; +rendermode_t rendermode = render_none; boolean highcolor = false; @@ -1463,6 +1468,11 @@ void I_FinishUpdate(void) if (cv_showping.value && netgame && consoleplayer != serverplayer) SCR_DisplayLocalPing(); +#ifdef HAVE_DISCORDRPC + if (discordRequestList != NULL) + ST_AskToJoinEnvelope(); +#endif + if (rendermode == render_soft && screens[0]) { SDL_Rect rect; @@ -1866,6 +1876,13 @@ static void Impl_VideoSetupBuffer(void) } } +static FILE * +OpenRendererFile (const char * mode) +{ + char * path = va(pandf,srb2home,"renderer.txt"); + return fopen(path, mode); +} + void I_StartupGraphics(void) { if (dedicated) @@ -1913,6 +1930,62 @@ void I_StartupGraphics(void) rendermode = render_opengl; #endif + if (rendermode == render_none) + { +#ifdef HWRENDER + char line[16]; + char * word; + FILE * file = OpenRendererFile("r"); + if (file != NULL) + { + if (fgets(line, sizeof line, file) != NULL) + { + word = strtok(line, "\n"); + + if (strcasecmp(word, "software") == 0) + { + rendermode = render_soft; + } + else if (strcasecmp(word, "opengl") == 0) + { + rendermode = render_opengl; + } + + if (rendermode != render_none) + { + CONS_Printf("Using last known renderer: %s\n", line); + } + } + fclose(file); + } +#endif + if (rendermode == render_none) + { + rendermode = render_soft; + CONS_Printf("Using default software renderer.\n"); + } + } + else + { + FILE * file = OpenRendererFile("w"); + if (file != NULL) + { + if (rendermode == render_soft) + { + fputs("software\n", file); + } + else if (rendermode == render_opengl) + { + fputs("opengl\n", file); + } + fclose(file); + } + else + { + CONS_Printf("Could not save renderer to file: %s\n", strerror(errno)); + } + } + usesdl2soft = M_CheckParm("-softblit"); borderlesswindow = M_CheckParm("-borderless"); diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 1617da2a3..c5650192d 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -110,6 +110,29 @@ static void var_cleanup(void) internal_volume = 100; } +#if defined (HAVE_LIBGME) && defined (HAVE_ZLIB) +static const char* get_zlib_error(int zErr) +{ + switch (zErr) + { + case Z_ERRNO: + return "Z_ERRNO"; + case Z_STREAM_ERROR: + return "Z_STREAM_ERROR"; + case Z_DATA_ERROR: + return "Z_DATA_ERROR"; + case Z_MEM_ERROR: + return "Z_MEM_ERROR"; + case Z_BUF_ERROR: + return "Z_BUF_ERROR"; + case Z_VERSION_ERROR: + return "Z_VERSION_ERROR"; + default: + return "unknown error"; + } +} +#endif + /// ------------------------ /// Audio System /// ------------------------ @@ -371,51 +394,11 @@ void *I_GetSfx(sfxinfo_t *sfx) } } else - { - const char *errorType; - switch (zErr) - { - case Z_ERRNO: - errorType = "Z_ERRNO"; break; - case Z_STREAM_ERROR: - errorType = "Z_STREAM_ERROR"; break; - case Z_DATA_ERROR: - errorType = "Z_DATA_ERROR"; break; - case Z_MEM_ERROR: - errorType = "Z_MEM_ERROR"; break; - case Z_BUF_ERROR: - errorType = "Z_BUF_ERROR"; break; - case Z_VERSION_ERROR: - errorType = "Z_VERSION_ERROR"; break; - default: - errorType = "unknown error"; - } - CONS_Alert(CONS_ERROR,"Encountered %s when running inflate: %s\n", errorType, stream.msg); - } + CONS_Alert(CONS_ERROR,"Encountered %s when running inflate: %s\n", get_zlib_error(zErr), stream.msg); (void)inflateEnd(&stream); } else // Hold up, zlib's got a problem - { - const char *errorType; - switch (zErr) - { - case Z_ERRNO: - errorType = "Z_ERRNO"; break; - case Z_STREAM_ERROR: - errorType = "Z_STREAM_ERROR"; break; - case Z_DATA_ERROR: - errorType = "Z_DATA_ERROR"; break; - case Z_MEM_ERROR: - errorType = "Z_MEM_ERROR"; break; - case Z_BUF_ERROR: - errorType = "Z_BUF_ERROR"; break; - case Z_VERSION_ERROR: - errorType = "Z_VERSION_ERROR"; break; - default: - errorType = "unknown error"; - } - CONS_Alert(CONS_ERROR,"Encountered %s when running inflateInit: %s\n", errorType, stream.msg); - } + CONS_Alert(CONS_ERROR,"Encountered %s when running inflateInit: %s\n", get_zlib_error(zErr), stream.msg); Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up #else return NULL; // No zlib support @@ -945,73 +928,25 @@ boolean I_LoadSong(char *data, size_t len) // Run GME on new data if (!gme_open_data(inflatedData, inflatedLen, &gme, 44100)) { - gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; - gme_start_track(gme, 0); - current_track = 0; - gme_set_equalizer(gme, &eq); - Mix_HookMusic(mix_gme, gme); Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around return true; } } else - { - const char *errorType; - switch (zErr) - { - case Z_ERRNO: - errorType = "Z_ERRNO"; break; - case Z_STREAM_ERROR: - errorType = "Z_STREAM_ERROR"; break; - case Z_DATA_ERROR: - errorType = "Z_DATA_ERROR"; break; - case Z_MEM_ERROR: - errorType = "Z_MEM_ERROR"; break; - case Z_BUF_ERROR: - errorType = "Z_BUF_ERROR"; break; - case Z_VERSION_ERROR: - errorType = "Z_VERSION_ERROR"; break; - default: - errorType = "unknown error"; - } - CONS_Alert(CONS_ERROR,"Encountered %s when running inflate: %s\n", errorType, stream.msg); - } + CONS_Alert(CONS_ERROR, "Encountered %s when running inflate: %s\n", get_zlib_error(zErr), stream.msg); (void)inflateEnd(&stream); } else // Hold up, zlib's got a problem - { - const char *errorType; - switch (zErr) - { - case Z_ERRNO: - errorType = "Z_ERRNO"; break; - case Z_STREAM_ERROR: - errorType = "Z_STREAM_ERROR"; break; - case Z_DATA_ERROR: - errorType = "Z_DATA_ERROR"; break; - case Z_MEM_ERROR: - errorType = "Z_MEM_ERROR"; break; - case Z_BUF_ERROR: - errorType = "Z_BUF_ERROR"; break; - case Z_VERSION_ERROR: - errorType = "Z_VERSION_ERROR"; break; - default: - errorType = "unknown error"; - } - CONS_Alert(CONS_ERROR,"Encountered %s when running inflateInit: %s\n", errorType, stream.msg); - } + CONS_Alert(CONS_ERROR, "Encountered %s when running inflateInit: %s\n", get_zlib_error(zErr), stream.msg); Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up + return false; #else CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n"); - return true; + return false; #endif } else if (!gme_open_data(data, len, &gme, 44100)) - { - gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; - gme_set_equalizer(gme, &eq); return true; - } #endif rw = SDL_RWFromMem(data, len); @@ -1082,6 +1017,8 @@ boolean I_PlaySong(boolean looping) #ifdef HAVE_LIBGME if (gme) { + gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; + gme_set_equalizer(gme, &eq); gme_start_track(gme, 0); current_track = 0; Mix_HookMusic(mix_gme, gme); diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index 4bb1b5676..929ac79f5 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -1434,6 +1434,8 @@ static void I_ResumeGME(void) boolean I_LoadSong(char *data, size_t len) { + (void)data; + (void)len; return false; } @@ -1495,6 +1497,7 @@ boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms (void)target_volume; (void)source_volume; (void)ms; + (void)callback; return false; } @@ -1502,6 +1505,7 @@ boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void)) { (void)target_volume; (void)ms; + (void)callback; return false; } diff --git a/src/sounds.c b/src/sounds.c index 61fddb76f..9285a2a87 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -816,6 +816,10 @@ sfxinfo_t S_sfx[NUMSFX] = {"mkuma", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Trigger Happy Havoc Monokuma {"toada", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Arid Sands Toad scream {"bsnipe", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Banana sniping + {"join", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Player joined server + {"leave", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Player left server + {"requst", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Got a Discord join request + {"syfail", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Funny sync failure {"itfree", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // :shitsfree: {"dbgsal", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Debug notification diff --git a/src/sounds.h b/src/sounds.h index dfd0bbdcd..4091081b5 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -891,6 +891,10 @@ typedef enum sfx_mkuma, sfx_toada, sfx_bsnipe, + sfx_join, + sfx_leave, + sfx_requst, + sfx_syfail, sfx_itfree, sfx_dbgsal, diff --git a/src/st_stuff.c b/src/st_stuff.c index 008a14614..9d7269982 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -129,6 +129,11 @@ static patch_t *gotbflag; static patch_t *hud_tv1; static patch_t *hud_tv2; +#ifdef HAVE_DISCORDRPC +// Discord Rich Presence +static patch_t *envelope; +#endif + // SRB2kart hudinfo_t hudinfo[NUMHUDITEMS] = @@ -349,6 +354,11 @@ void ST_LoadGraphics(void) // Midnight Channel: hud_tv1 = W_CachePatchName("HUD_TV1", PU_HUDGFX); hud_tv2 = W_CachePatchName("HUD_TV2", PU_HUDGFX); + +#ifdef HAVE_DISCORDRPC + // Discord Rich Presence + envelope = W_CachePatchName("K_REQUES", PU_HUDGFX); +#endif } // made separate so that skins code can reload custom face graphics @@ -776,7 +786,7 @@ static void ST_drawLevelTitle(void) if (zonttl[0]) zonexpos -= V_LevelNameWidth(zonttl); // SRB2kart else - zonexpos -= V_LevelNameWidth(M_GetText("ZONE")); + zonexpos -= V_LevelNameWidth(M_GetText("Zone")); } if (lvlttlxpos < 0) @@ -813,7 +823,7 @@ static void ST_drawLevelTitle(void) if (strlen(zonttl) > 0) V_DrawLevelTitle(zonexpos, bary+6, 0, zonttl); else if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) - V_DrawLevelTitle(zonexpos, bary+6, 0, M_GetText("ZONE")); + V_DrawLevelTitle(zonexpos, bary+6, 0, M_GetText("Zone")); if (actnum[0]) V_DrawLevelTitle(ttlnumxpos+12, bary+6, 0, actnum); @@ -1797,10 +1807,12 @@ static void ST_doItemFinderIconsAndSound(void) // SRB2kart - unused. // static void ST_overlayDrawer(void) { - /* SRB2kart doesn't need this stuff //hu_showscores = auto hide score/time/rings when tab rankings are shown if (!(hu_showscores && (netgame || multiplayer))) { + K_drawKartHUD(); + + /* SRB2kart doesn't need this stuff if (maptol & TOL_NIGHTS) ST_drawNiGHTSHUD(); else @@ -1824,8 +1836,8 @@ static void ST_overlayDrawer(void) ) ST_drawLives(); } - } */ + } // GAME OVER pic /*if (G_GametypeUsesLives() && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer))) @@ -1845,8 +1857,6 @@ static void ST_overlayDrawer(void) // Countdown timer for Race Mode // ...moved to k_kart.c so we can take advantage of the LAPS_Y value - K_drawKartHUD(); - /* SRB2kart doesn't need this stuff, I think // If you are in overtime, put a big honkin' flashin' message on the screen. if (G_BattleGametype() && cv_overtime.value @@ -2080,6 +2090,22 @@ static void ST_MayonakaStatic(void) V_DrawFixedPatch(320< #endif @@ -66,24 +84,6 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #define O_BINARY 0 #endif -#ifdef HAVE_ZLIB -#ifndef _MSC_VER -#ifndef _LARGEFILE64_SOURCE -#define _LARGEFILE64_SOURCE -#endif -#endif - -#ifndef _LFS64_LARGEFILE -#define _LFS64_LARGEFILE -#endif - -#ifndef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 0 -#endif - -#include "zlib.h" -#endif - typedef struct { @@ -150,7 +150,10 @@ FILE *W_OpenWadFile(const char **filename, boolean useerrors) { FILE *handle; - strncpy(filenamebuf, *filename, MAX_WADPATH); + if (filenamebuf != *filename) { + // avoid overlap + strncpy(filenamebuf, *filename, MAX_WADPATH); + } filenamebuf[MAX_WADPATH - 1] = '\0'; *filename = filenamebuf; @@ -1319,8 +1322,8 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si { size = 0; zerr(zErr); - (void)inflateEnd(&strm); } + (void)inflateEnd(&strm); } else { diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg index 583a3c79a..935b27222 100644 --- a/src/win32/Makefile.cfg +++ b/src/win32/Makefile.cfg @@ -30,6 +30,10 @@ ifndef MINGW64 #miniupnc is broken with MINGW64 endif endif +ifndef NO_DISCORDRPC + HAVE_DISCORDRPC=1 +endif + OPTS=-DSTDC_HEADERS ifndef GCC44 @@ -142,4 +146,15 @@ ifdef MINGW64 else CURL_LDFLAGS+=-L../libs/curl/lib32 -lcurl endif #MINGW64 -endif \ No newline at end of file +endif + +ifdef HAVE_DISCORDRPC +ifdef MINGW64 + CPPFLAGS+=-I../libs/discord-rpc/win64-dynamic/include + LDFLAGS+=-L../libs/discord-rpc/win64-dynamic/lib +else + CPPFLAGS+=-I../libs/discord-rpc/win32-dynamic/include + LDFLAGS+=-L../libs/discord-rpc/win32-dynamic/lib +endif + LIBS+=-ldiscord-rpc +endif diff --git a/src/y_inter.c b/src/y_inter.c index 29b681f78..c01c611ee 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -233,7 +233,7 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) } else { - const char *zonttl = (mapheaderinfo[prevmap]->zonttl[0] ? mapheaderinfo[prevmap]->zonttl : "ZONE"); + const char *zonttl = (mapheaderinfo[prevmap]->zonttl[0] ? mapheaderinfo[prevmap]->zonttl : "Zone"); if (mapheaderinfo[prevmap]->actnum[0]) snprintf(data.match.levelstring, sizeof data.match.levelstring, diff --git a/windows-installer/staging/! SRB2KART INSTALL INSTRUCTIONS !.txt b/windows-installer/staging/! SRB2KART INSTALL INSTRUCTIONS !.txt deleted file mode 100644 index 91d055be6..000000000 --- a/windows-installer/staging/! SRB2KART INSTALL INSTRUCTIONS !.txt +++ /dev/null @@ -1,11 +0,0 @@ -SRB2Kart Install Instructions - -1. Move every file from the "new-install" folder to this main install folder. - -2. DELETE "staging.bat" and "staging.txt"! These can mess up your installation if run by accident! - -3. Optionally, create a folder in your user profile named "SRB2Kart". This is where your game data and addons may live. For example, - - C:\Users\[User]\SRB2Kart - -4. Run the game! Double-click srb2kart.exe -- or see if you have Start Menu icons under "SRB2Kart". \ No newline at end of file