mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-18 14:02:51 +00:00
Merge master
Slopes in a few maps are really broken ... think it's anchors, I'm gonna leave that to jart :V
This commit is contained in:
commit
b5fcd74ef9
63 changed files with 3395 additions and 1163 deletions
23
cmake/Modules/FindDiscordRPC.cmake
Normal file
23
cmake/Modules/FindDiscordRPC.cmake
Normal file
|
|
@ -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)
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# SRB2Kart - Which DLLs do I need to bundle?
|
||||
|
||||
Updated 12/6/2019 (v2.2)
|
||||
Updated 8/23/2020 (v1.3)
|
||||
|
||||
Here are the required DLLs, per build. For each architecture, copy all the binaries from these folders:
|
||||
|
||||
|
|
@ -15,6 +15,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\SDL2mixerX\i686-w64-mingw32\bin\*.dll (get everything)
|
||||
|
|
@ -24,27 +25,8 @@ 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
|
||||
<<<<<<< HEAD
|
||||
* 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)
|
||||
=======
|
||||
* libs\SDL2mixerX\x86_64-w64-mingw32\bin\*.dll (get everything)
|
||||
* libs\libopenmpt\x86_64\bin\mingw\libopenmpt.dll
|
||||
>>>>>>> srb2/next
|
||||
|
|
|
|||
16
libs/discord-rpc.props
Normal file
16
libs/discord-rpc.props
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<LibraryPath Condition="'$(Platform)' == 'Win32'">$(SolutionDir)libs\discord-rpc\win32-dynamic\lib;$(LibraryPath)</LibraryPath>
|
||||
<IncludePath Condition="'$(Platform)' == 'Win32'">$(SolutionDir)libs\discord-rpc\win32-dynamic\lib;$(IncludePath)</IncludePath>
|
||||
<LibraryPath Condition="'$(Platform)' == 'x64'">$(SolutionDir)libs\discord-rpc\win64-dynamic\lib;$(LibraryPath)</LibraryPath>
|
||||
<IncludePath Condition="'$(Platform)' == 'x64'">$(SolutionDir)libs\discord-rpc\win64-dynamic\lib;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Platform)' == 'Win32' OR '$(Platform)' == 'x64'">
|
||||
<Link>
|
||||
<AdditionalDependencies>discord-rpc.dll.a;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup />
|
||||
</Project>
|
||||
26
libs/discord-rpc/win32-dynamic/include/discord_register.h
Normal file
26
libs/discord-rpc/win32-dynamic/include/discord_register.h
Normal file
|
|
@ -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
|
||||
87
libs/discord-rpc/win32-dynamic/include/discord_rpc.h
Normal file
87
libs/discord-rpc/win32-dynamic/include/discord_rpc.h
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
// 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
|
||||
BIN
libs/discord-rpc/win32-dynamic/lib/discord-rpc.lib
Normal file
BIN
libs/discord-rpc/win32-dynamic/lib/discord-rpc.lib
Normal file
Binary file not shown.
26
libs/discord-rpc/win64-dynamic/include/discord_register.h
Normal file
26
libs/discord-rpc/win64-dynamic/include/discord_register.h
Normal file
|
|
@ -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
|
||||
87
libs/discord-rpc/win64-dynamic/include/discord_rpc.h
Normal file
87
libs/discord-rpc/win64-dynamic/include/discord_rpc.h
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
// 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
|
||||
BIN
libs/discord-rpc/win64-dynamic/lib/discord-rpc.lib
Normal file
BIN
libs/discord-rpc/win64-dynamic/lib/discord-rpc.lib
Normal file
Binary file not shown.
BIN
libs/dll-binaries/i686/discord-rpc.dll
Normal file
BIN
libs/dll-binaries/i686/discord-rpc.dll
Normal file
Binary file not shown.
BIN
libs/dll-binaries/x86_64/discord-rpc.dll
Normal file
BIN
libs/dll-binaries/x86_64/discord-rpc.dll
Normal file
Binary file not shown.
39
libs/drmingw/include/exchndl.h
Normal file
39
libs/drmingw/include/exchndl.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2002-2015 Jose Fonseca
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
// Set the unhandled exception handler.
|
||||
// Must be called when exchndll.dll is statically loaded (as opposed to loaded
|
||||
// dynamically via LoadLibrary)
|
||||
EXTERN_C VOID APIENTRY
|
||||
ExcHndlInit(void);
|
||||
|
||||
|
||||
// Override the report file name.
|
||||
//
|
||||
// Default is prog_name.RPT, in the same directory as the main executable.
|
||||
//
|
||||
// You can also pass "-" for stderr.
|
||||
EXTERN_C BOOL APIENTRY
|
||||
ExcHndlSetLogFileNameA(const char *szLogFileName);
|
||||
BIN
libs/drmingw/lib/win32/libexchndl.a
Normal file
BIN
libs/drmingw/lib/win32/libexchndl.a
Normal file
Binary file not shown.
BIN
libs/drmingw/lib/win32/libmgwhelp.a
Normal file
BIN
libs/drmingw/lib/win32/libmgwhelp.a
Normal file
Binary file not shown.
|
|
@ -103,7 +103,6 @@ set(SRB2_CORE_HEADERS
|
|||
m_swap.h
|
||||
md5.h
|
||||
mserv.h
|
||||
http-mserv.h
|
||||
p5prof.h
|
||||
s_sound.h
|
||||
screen.h
|
||||
|
|
@ -253,6 +252,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_HAVE_OPENMPT ON CACHE BOOL
|
||||
|
|
@ -429,6 +430,32 @@ if(${SRB2_CONFIG_HAVE_MIXERX})
|
|||
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)
|
||||
|
|
@ -481,7 +508,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
|
||||
|
|
|
|||
84
src/Makefile
84
src/Makefile
|
|
@ -57,10 +57,10 @@
|
|||
# Compile a profile version, add 'PROFILEMODE=1'
|
||||
# Compile a debug version, add 'DEBUGMODE=1'
|
||||
# Compile for the testers group (they don't get to play unless we're watching *wink*), add 'TESTERS=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)/main.kart \
|
||||
|
|
@ -124,7 +176,6 @@ NOPNG=1
|
|||
NOZLIB=1
|
||||
NONET=1
|
||||
NOHW=1
|
||||
NOHS=1
|
||||
NOASM=1
|
||||
NOIPX=1
|
||||
EXENAME?=srb2dummy
|
||||
|
|
@ -146,7 +197,6 @@ endif
|
|||
ifdef PANDORA
|
||||
NONX86=1
|
||||
NOHW=1
|
||||
NOHS=1
|
||||
endif
|
||||
|
||||
ifndef NOOPENMPT
|
||||
|
|
@ -228,13 +278,6 @@ else
|
|||
$(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o
|
||||
endif
|
||||
|
||||
ifdef NOHS
|
||||
OPTS+=-DNOHS
|
||||
else
|
||||
OPTS+=-DHW3SOUND
|
||||
OBJS+=$(OBJDIR)/hw3sound.o
|
||||
endif
|
||||
|
||||
OPTS += -DCOMPVERSION
|
||||
|
||||
ifndef NONX86
|
||||
|
|
@ -348,6 +391,12 @@ CFLAGS+=-DHAVE_MINIUPNPC
|
|||
endif
|
||||
endif
|
||||
|
||||
ifdef HAVE_DISCORDRPC
|
||||
LIBS+=-ldiscord-rpc
|
||||
CFLAGS+=-DHAVE_DISCORDRPC
|
||||
OBJS+=$(OBJDIR)/discord.o
|
||||
endif
|
||||
|
||||
include blua/Makefile.cfg
|
||||
|
||||
ifdef NOMD5
|
||||
|
|
@ -780,19 +829,6 @@ $(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.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
|
||||
|
||||
|
|
|
|||
|
|
@ -210,10 +210,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
|
||||
|
|
|
|||
|
|
@ -322,8 +322,8 @@ static void Arith (lua_State *L, StkId ra, TValue *rb,
|
|||
case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
|
||||
case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
|
||||
case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
|
||||
case TM_DIV: if (nc == 0) { lua_pushliteral(L, "divide by zero error"); lua_error(L); } else setnvalue(ra, luai_numdiv(nb, nc)); break;
|
||||
case TM_MOD: if (nc == 0) { lua_pushliteral(L, "modulo by zero error"); lua_error(L); } else setnvalue(ra, luai_nummod(nb, nc)); break;
|
||||
case TM_DIV: if (nc == 0) { luaG_runerror(L, "divide by zero error"); } else setnvalue(ra, luai_numdiv(nb, nc)); break;
|
||||
case TM_MOD: if (nc == 0) { luaG_runerror(L, "modulo by zero error"); } else setnvalue(ra, luai_nummod(nb, nc)); break;
|
||||
case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
|
||||
case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
|
||||
case TM_AND: setnvalue(ra, luai_numand(nb, nc)); break;
|
||||
|
|
@ -492,8 +492,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||
if (ttisnumber(rb) && ttisnumber(rc)) {
|
||||
lua_Number nb = nvalue(rb), nc = nvalue(rc);
|
||||
if (nc == 0) {
|
||||
lua_pushliteral(L, "divide by zero error");
|
||||
lua_error(L);
|
||||
luaG_runerror(L, "divide by zero error");
|
||||
}
|
||||
else
|
||||
setnvalue(ra, luai_numdiv(nb, nc));
|
||||
|
|
@ -508,8 +507,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
|
|||
if (ttisnumber(rb) && ttisnumber(rc)) {
|
||||
lua_Number nb = nvalue(rb), nc = nvalue(rc);
|
||||
if (nc == 0) {
|
||||
lua_pushliteral(L, "modulo by zero error");
|
||||
lua_error(L);
|
||||
luaG_runerror(L, "modulo by zero error");
|
||||
}
|
||||
else
|
||||
setnvalue(ra, luai_nummod(nb, nc));
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
/* Manually defined asset hashes for non-CMake builds
|
||||
* 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
|
||||
*/
|
||||
|
||||
#define ASSET_HASH_MAIN_KART "00000000000000000000000000000000"
|
||||
|
|
|
|||
635
src/d_clisrv.c
635
src/d_clisrv.c
File diff suppressed because it is too large
Load diff
|
|
@ -367,6 +367,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;
|
||||
|
||||
|
|
@ -592,6 +597,10 @@ 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)
|
||||
|
|
@ -619,6 +628,8 @@ extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
|||
extern consvar_t cv_joinnextround;
|
||||
#endif
|
||||
|
||||
extern consvar_t cv_discordinvites;
|
||||
|
||||
// Used in d_net, the only dependence
|
||||
tic_t ExpandTics(INT32 low, tic_t basetic);
|
||||
void D_ClientServerInit(void);
|
||||
|
|
@ -643,7 +654,7 @@ void CL_Reset(void);
|
|||
void CL_ClearPlayer(INT32 playernum);
|
||||
void CL_RemovePlayer(INT32 playernum, kickreason_t reason);
|
||||
void CL_QueryServerList(msg_server_t *list);
|
||||
void CL_UpdateServerList(boolean internetsearch, INT32 room);
|
||||
void CL_UpdateServerList(void);
|
||||
// Is there a game running
|
||||
boolean Playing(void);
|
||||
|
||||
|
|
|
|||
73
src/d_main.c
73
src/d_main.c
|
|
@ -59,7 +59,6 @@
|
|||
#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
|
||||
|
|
@ -96,6 +95,10 @@
|
|||
int VERSION;
|
||||
int SUBVERSION;
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
#include "discord.h"
|
||||
#endif
|
||||
|
||||
// platform independant focus loss
|
||||
UINT8 window_notinfocus = false;
|
||||
|
||||
|
|
@ -901,6 +904,13 @@ void D_SRB2Loop(void)
|
|||
#endif
|
||||
|
||||
LUA_Step();
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
if (! dedicated)
|
||||
{
|
||||
Discord_RunCallbacks();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1078,9 +1088,23 @@ static void ChangeDirForUrlHandler(void)
|
|||
// Identify the SRB2 version, and IWAD file to use.
|
||||
// ==========================================================================
|
||||
|
||||
static boolean AddIWAD(void)
|
||||
{
|
||||
char * path = va(pandf,srb2path,"main.kart");
|
||||
|
||||
if (FIL_ReadFileOK(path))
|
||||
{
|
||||
D_AddFile(path, startupiwads);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void IdentifyVersion(void)
|
||||
{
|
||||
char *mainresource;
|
||||
const char *srb2waddir = NULL;
|
||||
|
||||
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
|
||||
|
|
@ -1098,36 +1122,19 @@ static void IdentifyVersion(void)
|
|||
if (getcwd(srb2path, 256) != NULL)
|
||||
srb2waddir = srb2path;
|
||||
else
|
||||
{
|
||||
srb2waddir = ".";
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (macintosh) && !defined (HAVE_SDL)
|
||||
// cwd is always "/" when app is dbl-clicked
|
||||
if (!stricmp(srb2waddir, "/"))
|
||||
srb2waddir = I_GetWadDir();
|
||||
#endif
|
||||
// Commercial.
|
||||
mainresource = malloc(strlen(srb2waddir)+1+9+1);
|
||||
if (mainresource == NULL)
|
||||
I_Error("No more free memory to look in %s", srb2waddir);
|
||||
else
|
||||
sprintf(mainresource, pandf, srb2waddir, "main.kart");
|
||||
// Load the IWAD
|
||||
if (! AddIWAD())
|
||||
{
|
||||
I_Error("MAIN.KART 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 (mainresource != NULL && FIL_ReadFileOK(mainresource))
|
||||
D_AddFile(mainresource, startupiwads);
|
||||
else
|
||||
I_Error("main.kart not found! Expected in %s, ss file: %s \n", srb2waddir, mainresource);
|
||||
|
||||
if (mainresource)
|
||||
free(mainresource);
|
||||
|
||||
// if you change the ordering of this or add/remove a file, be sure to update the md5
|
||||
// checking in D_SRB2Main
|
||||
|
||||
|
|
@ -1662,17 +1669,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 <room_id>\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()))
|
||||
{
|
||||
|
|
@ -1890,6 +1886,13 @@ void D_SRB2Main(void)
|
|||
if (!P_LoadLevel(false))
|
||||
I_Quit(); // fail so reset game stuff
|
||||
}
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
if (! dedicated)
|
||||
{
|
||||
DRPC_Init();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *D_Home(void)
|
||||
|
|
|
|||
|
|
@ -64,6 +64,10 @@
|
|||
#define CV_RESTRICT 0
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
#include "discord.h"
|
||||
#endif
|
||||
|
||||
// ------
|
||||
// protos
|
||||
// ------
|
||||
|
|
@ -89,6 +93,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);
|
||||
|
|
@ -752,6 +757,9 @@ void D_RegisterServerCommands(void)
|
|||
#endif
|
||||
|
||||
CV_RegisterVar(&cv_dummyconsvar);
|
||||
|
||||
CV_RegisterVar(&cv_discordinvites);
|
||||
RegisterNetXCmd(XD_DISCORD, Got_DiscordInfo);
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
|
|
@ -1038,6 +1046,12 @@ void D_RegisterClientCommands(void)
|
|||
#ifdef 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.
|
||||
|
|
@ -1255,6 +1269,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;
|
||||
}
|
||||
|
|
@ -1455,7 +1471,12 @@ static void SendNameAndColor(UINT8 n)
|
|||
snacpending[n]++;
|
||||
|
||||
// Don't change name if muted
|
||||
if (cv_mute.value && !(server || IsPlayerAdmin(playernum)))
|
||||
if (player_name_changes[playernum] >= MAXNAMECHANGES)
|
||||
{
|
||||
CV_StealthSet(&cv_playername[n], player_names[playernum]);
|
||||
HU_AddChatText("\x85*You must wait to change your name again", false);
|
||||
}
|
||||
else if (cv_mute.value && !(server || IsPlayerAdmin(playernum)))
|
||||
CV_StealthSet(&cv_playername[n], player_names[playernum]);
|
||||
else // Cleanup name if changing it
|
||||
CleanupPlayerName(playernum, cv_playername[n].zstring);
|
||||
|
|
@ -1491,6 +1512,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
|||
UINT16 color, followercolor;
|
||||
UINT8 skin;
|
||||
SINT8 follower;
|
||||
SINT8 localplayer = -1;
|
||||
UINT8 i;
|
||||
|
||||
#ifdef PARANOIA
|
||||
|
|
@ -1509,7 +1531,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
|||
I_Error("snacpending[%d] negative!", i);
|
||||
#endif
|
||||
|
||||
// i is now player screen id
|
||||
localplayer = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1590,8 +1612,8 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
|||
const INT32 forcedskin = cv_forceskin.value;
|
||||
SetPlayerSkinByNum(playernum, forcedskin);
|
||||
|
||||
if (playernum == g_localplayers[i])
|
||||
CV_StealthSet(&cv_skin[i], skins[forcedskin].name);
|
||||
if (localplayer != -1)
|
||||
CV_StealthSet(&cv_skin[localplayer], skins[forcedskin].name);
|
||||
}
|
||||
else
|
||||
SetPlayerSkinByNum(playernum, skin);
|
||||
|
|
@ -1602,6 +1624,11 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
|||
|
||||
// set follower
|
||||
SetFollower(playernum, follower);
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
if (playernum == consoleplayer)
|
||||
DRPC_UpdatePresence();
|
||||
#endif
|
||||
}
|
||||
|
||||
void SendWeaponPref(UINT8 n)
|
||||
|
|
@ -2865,6 +2892,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)
|
||||
|
|
@ -3799,7 +3830,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))
|
||||
{
|
||||
|
|
@ -3937,7 +3968,7 @@ static void Command_Addfile(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;
|
||||
|
|
@ -3996,7 +4027,7 @@ static void Got_RequestAddfilecmd(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);
|
||||
|
|
@ -4289,6 +4320,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.
|
||||
|
|
@ -5603,3 +5638,26 @@ static void KartEliminateLast_OnChange(void)
|
|||
|
||||
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)
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,6 +161,7 @@ typedef enum
|
|||
XD_CANCELPARTYINVITE, // 31
|
||||
XD_GIVEITEM, // 32
|
||||
XD_ADDBOT, // 33
|
||||
XD_DISCORD, // 34
|
||||
|
||||
MAXNETXCMD
|
||||
} netxcmd_t;
|
||||
|
|
|
|||
|
|
@ -118,6 +118,10 @@ static pauseddownload_t *pauseddownload = NULL;
|
|||
#ifndef NONET
|
||||
// for cl loading screen
|
||||
INT32 lastfilenum = -1;
|
||||
INT32 downloadcompletednum = 0;
|
||||
UINT32 downloadcompletedsize = 0;
|
||||
INT32 totalfilesrequestednum = 0;
|
||||
UINT32 totalfilesrequestedsize = 0;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
|
|
@ -156,7 +160,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)
|
||||
|
|
@ -222,7 +226,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
|
||||
fileneeded[i].justdownloaded = false;
|
||||
filestatus = READUINT8(p); // The first byte is the file status
|
||||
fileneeded[i].willsend = (UINT8)(filestatus >> 4);
|
||||
|
|
@ -416,15 +420,17 @@ boolean PT_RequestFile(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;
|
||||
|
|
@ -441,7 +447,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)
|
||||
{
|
||||
|
|
@ -470,10 +476,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) &&
|
||||
|
|
@ -481,36 +496,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
|
||||
|
|
@ -519,6 +533,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);
|
||||
|
|
@ -544,6 +559,7 @@ void CL_LoadServerFiles(void)
|
|||
fileneeded[i].status, s);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddLuaFileTransfer(const char *filename, const char *mode)
|
||||
|
|
@ -1374,6 +1390,11 @@ void PT_FileFragment(void)
|
|||
netbuffer->packettype = PT_HASLUAFILE;
|
||||
HSendPacket(servernode, true, 0, 0);
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
downloadcompletednum++;
|
||||
downloadcompletedsize += file->totalsize;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else // Already received
|
||||
|
|
@ -1732,6 +1753,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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ typedef enum
|
|||
|
||||
typedef enum
|
||||
{
|
||||
FS_NOTCHECKED,
|
||||
FS_NOTFOUND,
|
||||
FS_FOUND,
|
||||
FS_REQUESTED,
|
||||
|
|
@ -61,6 +62,10 @@ extern char downloaddir[512];
|
|||
|
||||
#ifndef NONET
|
||||
extern INT32 lastfilenum;
|
||||
extern INT32 downloadcompletednum;
|
||||
extern UINT32 downloadcompletedsize;
|
||||
extern INT32 totalfilesrequestednum;
|
||||
extern UINT32 totalfilesrequestedsize;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
|
|
@ -74,7 +79,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 AddRamToSendQueue(INT32 node, void *data, size_t size, freemethod_t freemethod,
|
||||
UINT8 fileid);
|
||||
|
||||
|
|
|
|||
|
|
@ -10362,7 +10362,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",
|
||||
|
|
@ -10373,6 +10372,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",
|
||||
|
||||
|
|
@ -12689,8 +12689,6 @@ static inline int lib_getenum(lua_State *L)
|
|||
if (mathlib) return luaL_error(L, "constant '%s' could not be parsed.\n", word);
|
||||
|
||||
// DYNAMIC variables too!!
|
||||
// Try not to add anything that would break netgames or timeattack replays here.
|
||||
// You know, like consoleplayer, displayplayer, secondarydisplayplayer, or gametime.
|
||||
return LUA_PushGlobals(L, word);
|
||||
}
|
||||
|
||||
|
|
|
|||
712
src/discord.c
Normal file
712
src/discord.c
Normal file
|
|
@ -0,0 +1,712 @@
|
|||
// 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 <curl/curl.h>
|
||||
#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 (dedicated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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 = ((gametype == GT_BATTLE) ? "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
|
||||
80
src/discord.h
Normal file
80
src/discord.h
Normal file
|
|
@ -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__
|
||||
|
|
@ -220,4 +220,11 @@ typedef struct
|
|||
|
||||
#define NUMMAPS 1035
|
||||
|
||||
/* slope thing types */
|
||||
enum
|
||||
{
|
||||
FLOOR_SLOPE_THING = 777,
|
||||
CEILING_SLOPE_THING = 778,
|
||||
};
|
||||
|
||||
#endif // __DOOMDATA__
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
// Use Mixer interface?
|
||||
#ifdef HAVE_MIXER
|
||||
#define SOUND SOUND_MIXER
|
||||
#define NOHS // No HW3SOUND
|
||||
#ifdef HW3SOUND
|
||||
#undef HW3SOUND
|
||||
#endif
|
||||
|
|
@ -45,7 +44,6 @@
|
|||
// Use FMOD?
|
||||
#ifdef HAVE_FMOD
|
||||
#define SOUND SOUND_FMOD
|
||||
#define NOHS // No HW3SOUND
|
||||
#ifdef HW3SOUND
|
||||
#undef HW3SOUND
|
||||
#endif
|
||||
|
|
@ -62,10 +60,6 @@
|
|||
#if !defined (HWRENDER) && !defined (NOHW)
|
||||
#define HWRENDER
|
||||
#endif
|
||||
// judgecutor: 3D sound support
|
||||
#if !defined(HW3SOUND) && !defined (NOHS)
|
||||
#define HW3SOUND
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
|
@ -165,32 +159,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.
|
||||
|
|
@ -683,4 +658,10 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
|||
/// MIDI support is really shitty -- we don't use it anyway, so lets throw it behind a define
|
||||
#define NO_MIDI
|
||||
|
||||
#if defined (HAVE_CURL) && ! defined (NONET)
|
||||
#define MASTERSERVER
|
||||
#else
|
||||
#undef UPDATE_ALERT
|
||||
#endif
|
||||
|
||||
#endif // __DOOMDEF__
|
||||
|
|
|
|||
13
src/g_game.c
13
src/g_game.c
|
|
@ -58,6 +58,10 @@
|
|||
#include "k_grandprix.h"
|
||||
#include "doomstat.h"
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
#include "discord.h"
|
||||
#endif
|
||||
|
||||
gameaction_t gameaction;
|
||||
gamestate_t gamestate = GS_NULL;
|
||||
UINT8 ultimatemode = false;
|
||||
|
|
@ -471,6 +475,7 @@ player_t *seenplayer; // player we're aiming at right now
|
|||
// now automatically allocated in D_RegisterClientCommands
|
||||
// so that it doesn't have to be updated depending on the value of MAXPLAYERS
|
||||
char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
|
||||
INT32 player_name_changes[MAXPLAYERS];
|
||||
|
||||
// Allocation for time and nights data
|
||||
void G_AllocMainRecordData(INT16 i)
|
||||
|
|
@ -1957,6 +1962,11 @@ void G_Ticker(boolean run)
|
|||
if (camtoggledelay[i])
|
||||
camtoggledelay[i]--;
|
||||
}
|
||||
|
||||
if (gametic % NAMECHANGERATE == 0)
|
||||
{
|
||||
memset(player_name_changes, 0, sizeof player_name_changes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4744,6 +4754,9 @@ INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep)
|
|||
void G_SetGamestate(gamestate_t newstate)
|
||||
{
|
||||
gamestate = newstate;
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
DRPC_UpdatePresence();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* These functions handle the exitgame flag. Before, when the user
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ extern char customversionstring[32];
|
|||
extern player_t *seenplayer;
|
||||
#endif
|
||||
extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
|
||||
extern INT32 player_name_changes[MAXPLAYERS];
|
||||
|
||||
extern player_t players[MAXPLAYERS];
|
||||
extern boolean playeringame[MAXPLAYERS];
|
||||
|
|
|
|||
233
src/http-mserv.c
233
src/http-mserv.c
|
|
@ -11,10 +11,12 @@
|
|||
/*
|
||||
Documentation available here.
|
||||
|
||||
<http://mb.srb2.org/MS/tools/api/v1/>
|
||||
<https://ms.kartkrew.org/tools/api/2/>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
#include <curl/curl.h>
|
||||
#endif
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "d_clisrv.h"
|
||||
|
|
@ -49,6 +51,8 @@ consvar_t cv_masterserver_token = {
|
|||
NULL, 0, NULL, NULL, 0, 0, NULL/* C90 moment */
|
||||
};
|
||||
|
||||
#ifdef MASTERSERVER
|
||||
|
||||
static int hms_started;
|
||||
|
||||
static char *hms_api;
|
||||
|
|
@ -137,7 +141,7 @@ HMS_connect (const char *format, ...)
|
|||
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);
|
||||
token_length = ( sizeof "&token="-1 )+ strlen(quack_token);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -152,7 +156,9 @@ HMS_connect (const char *format, ...)
|
|||
seek = strlen(hms_api) + 1;/* + '/' */
|
||||
|
||||
va_start (ap, format);
|
||||
url = malloc(seek + vsnprintf(0, 0, format, ap) + token_length + 1);
|
||||
url = malloc(seek + vsnprintf(0, 0, format, ap) +
|
||||
sizeof "?v=2" - 1 +
|
||||
token_length + 1);
|
||||
va_end (ap);
|
||||
|
||||
sprintf(url, "%s/", hms_api);
|
||||
|
|
@ -165,8 +171,11 @@ HMS_connect (const char *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);
|
||||
sprintf(&url[seek], "&token=%s", quack_token);
|
||||
|
||||
CONS_Printf("HMS: connecting '%s'...\n", url);
|
||||
|
||||
|
|
@ -254,117 +263,6 @@ HMS_end (struct HMS_buffer *buffer)
|
|||
free(buffer);
|
||||
}
|
||||
|
||||
int
|
||||
HMS_fetch_rooms (int joining, int query_id)
|
||||
{
|
||||
struct HMS_buffer *hms;
|
||||
int ok;
|
||||
|
||||
int doing_shit;
|
||||
|
||||
char *id;
|
||||
char *title;
|
||||
char *room_motd;
|
||||
|
||||
int id_no;
|
||||
|
||||
char *p;
|
||||
char *end;
|
||||
|
||||
int i;
|
||||
|
||||
(void)query_id;
|
||||
|
||||
hms = HMS_connect("rooms");
|
||||
|
||||
if (! hms)
|
||||
return 0;
|
||||
|
||||
if (HMS_do(hms))
|
||||
{
|
||||
doing_shit = 1;
|
||||
|
||||
p = hms->buffer;
|
||||
|
||||
for (i = 0; i < NUM_LIST_ROOMS && ( end = strstr(p, "\n\n\n") );)
|
||||
{
|
||||
*end = '\0';
|
||||
|
||||
id = strtok(p, "\n");
|
||||
title = strtok(0, "\n");
|
||||
room_motd = strtok(0, "");
|
||||
|
||||
if (id && title && room_motd)
|
||||
{
|
||||
id_no = atoi(id);
|
||||
|
||||
/*
|
||||
Don't show the 'All' room if hosting. And it's a hack like this
|
||||
because I'm way too lazy to add another feature to the MS.
|
||||
*/
|
||||
if (joining || id_no != 0)
|
||||
{
|
||||
#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
|
||||
|
||||
room_list[i].header.buffer[0] = 1;
|
||||
|
||||
room_list[i].id = id_no;
|
||||
strlcpy(room_list[i].name, title, sizeof room_list[i].name);
|
||||
strlcpy(room_list[i].motd, room_motd, sizeof room_list[i].motd);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
p = ( end + 3 );/* skip the three linefeeds */
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (doing_shit)
|
||||
room_list[i].header.buffer[0] = 0;
|
||||
|
||||
ok = 1;
|
||||
|
||||
if (doing_shit)
|
||||
{
|
||||
#ifdef HAVE_THREADS
|
||||
I_lock_mutex(&m_menu_mutex);
|
||||
#endif
|
||||
{
|
||||
for (i = 0; room_list[i].header.buffer[0]; i++)
|
||||
{
|
||||
if(*room_list[i].name != '\0')
|
||||
{
|
||||
MP_RoomMenu[i+1].text = room_list[i].name;
|
||||
roomIds[i] = room_list[i].id;
|
||||
MP_RoomMenu[i+1].status = IT_STRING|IT_CALL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_THREADS
|
||||
I_unlock_mutex(m_menu_mutex);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
ok = 0;
|
||||
|
||||
HMS_end(hms);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
int
|
||||
HMS_register (void)
|
||||
{
|
||||
|
|
@ -373,28 +271,26 @@ HMS_register (void)
|
|||
|
||||
char post[256];
|
||||
|
||||
char *title;
|
||||
char *contact;
|
||||
|
||||
hms = HMS_connect("rooms/%d/register", ms_RoomId);
|
||||
hms = HMS_connect(
|
||||
"games/%s/%d/servers/register", SRB2APPLICATION, MODVERSION);
|
||||
|
||||
if (! hms)
|
||||
return 0;
|
||||
|
||||
title = curl_easy_escape(hms->curl, cv_servername.string, 0);
|
||||
contact = curl_easy_escape(hms->curl, cv_server_contact.string, 0);
|
||||
|
||||
snprintf(post, sizeof post,
|
||||
"port=%d&"
|
||||
"title=%s&"
|
||||
"version=%s",
|
||||
"contact=%s",
|
||||
|
||||
current_port,
|
||||
|
||||
title,
|
||||
|
||||
SRB2VERSION
|
||||
contact
|
||||
);
|
||||
|
||||
curl_free(title);
|
||||
curl_free(contact);
|
||||
|
||||
curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post);
|
||||
|
||||
|
|
@ -468,19 +364,13 @@ HMS_list_servers (void)
|
|||
{
|
||||
struct HMS_buffer *hms;
|
||||
|
||||
char *p;
|
||||
|
||||
hms = HMS_connect("servers");
|
||||
hms = HMS_connect("games/%s/%d/servers", SRB2APPLICATION, MODVERSION);
|
||||
|
||||
if (! hms)
|
||||
return;
|
||||
|
||||
if (HMS_do(hms))
|
||||
{
|
||||
p = &hms->buffer[strlen(hms->buffer)];
|
||||
while (*--p == '\n')
|
||||
;
|
||||
|
||||
CONS_Printf("%s\n", hms->buffer);
|
||||
}
|
||||
|
||||
|
|
@ -488,35 +378,24 @@ HMS_list_servers (void)
|
|||
}
|
||||
|
||||
msg_server_t *
|
||||
HMS_fetch_servers (msg_server_t *list, int room_number, int query_id)
|
||||
HMS_fetch_servers (msg_server_t *list, int query_id)
|
||||
{
|
||||
struct HMS_buffer *hms;
|
||||
|
||||
int doing_shit;
|
||||
|
||||
char local_version[9];
|
||||
|
||||
char *room;
|
||||
|
||||
char *address;
|
||||
char *port;
|
||||
char *title;
|
||||
char *version;
|
||||
char *contact;
|
||||
|
||||
char *end;
|
||||
char *section_end;
|
||||
char *p;
|
||||
|
||||
int i;
|
||||
|
||||
(void)query_id;
|
||||
|
||||
if (room_number > 0)
|
||||
{
|
||||
hms = HMS_connect("rooms/%d/servers", room_number);
|
||||
}
|
||||
else
|
||||
hms = HMS_connect("servers");
|
||||
hms = HMS_connect("games/%s/%d/servers", SRB2APPLICATION, MODVERSION);
|
||||
|
||||
if (! hms)
|
||||
return NULL;
|
||||
|
|
@ -525,35 +404,18 @@ HMS_fetch_servers (msg_server_t *list, int room_number, int query_id)
|
|||
{
|
||||
doing_shit = 1;
|
||||
|
||||
snprintf(local_version, sizeof local_version,
|
||||
"%s",
|
||||
SRB2VERSION
|
||||
);
|
||||
|
||||
p = hms->buffer;
|
||||
i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
section_end = strstr(p, "\n\n");
|
||||
|
||||
room = strtok(p, "\n");
|
||||
|
||||
p = strtok(0, "");
|
||||
|
||||
if (! p)
|
||||
break;
|
||||
|
||||
while (i < MAXSERVERLIST && ( end = strchr(p, '\n') ))
|
||||
{
|
||||
*end = '\0';
|
||||
|
||||
address = strtok(p, " ");
|
||||
port = strtok(0, " ");
|
||||
title = strtok(0, " ");
|
||||
version = strtok(0, "");
|
||||
contact = strtok(0, "");
|
||||
|
||||
if (address && port && title && version)
|
||||
if (address && port)
|
||||
{
|
||||
#ifdef HAVE_THREADS
|
||||
I_lock_mutex(&ms_QueryId_mutex);
|
||||
|
|
@ -567,39 +429,27 @@ HMS_fetch_servers (msg_server_t *list, int room_number, int query_id)
|
|||
break;
|
||||
#endif
|
||||
|
||||
if (strcmp(version, local_version) == 0)
|
||||
{
|
||||
strlcpy(list[i].ip, address, sizeof list[i].ip);
|
||||
strlcpy(list[i].port, port, sizeof list[i].port);
|
||||
strlcpy(list[i].name, title, sizeof list[i].name);
|
||||
strlcpy(list[i].version, version, sizeof list[i].version);
|
||||
|
||||
list[i].room = atoi(room);
|
||||
if (contact)
|
||||
{
|
||||
strlcpy(list[i].contact, contact, sizeof list[i].contact);
|
||||
}
|
||||
|
||||
list[i].header.buffer[0] = 1;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if (end == section_end)/* end of list for this room */
|
||||
break;
|
||||
else
|
||||
p = ( end + 1 );/* skip server delimiter */
|
||||
}
|
||||
else
|
||||
{
|
||||
section_end = 0;/* malformed so quit the parsing */
|
||||
/* malformed so quit the parsing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! doing_shit)
|
||||
break;
|
||||
|
||||
p = ( section_end + 2 );
|
||||
}
|
||||
while (section_end) ;
|
||||
|
||||
if (doing_shit)
|
||||
list[i].header.buffer[0] = 0;
|
||||
}
|
||||
|
|
@ -620,7 +470,7 @@ HMS_compare_mod_version (char *buffer, size_t buffer_size)
|
|||
char *version;
|
||||
char *version_name;
|
||||
|
||||
hms = HMS_connect("versions/%d", MODID);
|
||||
hms = HMS_connect("games/%s/version", SRB2APPLICATION);
|
||||
|
||||
if (! hms)
|
||||
return 0;
|
||||
|
|
@ -649,6 +499,19 @@ HMS_compare_mod_version (char *buffer, size_t buffer_size)
|
|||
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)
|
||||
{
|
||||
|
|
@ -657,17 +520,21 @@ HMS_set_api (char *api)
|
|||
#endif
|
||||
{
|
||||
free(hms_api);
|
||||
hms_api = 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
|
||||
}
|
||||
|
|
|
|||
269
src/k_kart.c
269
src/k_kart.c
|
|
@ -306,35 +306,35 @@ static INT32 K_KartItemOddsRace[NUMKARTRESULTS-1][8] =
|
|||
/*Jawz x2*/ { 0, 0, 1, 2, 0, 0, 0, 0 } // Jawz x2
|
||||
};
|
||||
|
||||
static INT32 K_KartItemOddsBattle[NUMKARTRESULTS-1][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
|
||||
/*Bubble Shield*/ { 0, 0, 0, 0, 0, 0 }, // Bubble Shield
|
||||
/*Flame Shield*/ { 0, 0, 0, 0, 0, 0 }, // Flame Shield
|
||||
/*Hyudoro*/ { 1, 1, 0, 0, 0, 0 }, // Hyudoro
|
||||
/*Pogo Spring*/ { 1, 1, 0, 0, 0, 0 }, // Pogo Spring
|
||||
/*Super Ring*/ { 0, 0, 0, 0, 0, 0 }, // Super Ring
|
||||
/*Kitchen Sink*/ { 0, 0, 0, 0, 0, 0 }, // Kitchen Sink
|
||||
/*Sneaker x2*/ { 0, 0, 0, 0, 0, 0 }, // Sneaker x2
|
||||
/*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
|
||||
/*Bubble Shield*/ { 0, 0 }, // Bubble Shield
|
||||
/*Flame Shield*/ { 0, 0 }, // Flame Shield
|
||||
/*Hyudoro*/ { 2, 0 }, // Hyudoro
|
||||
/*Pogo Spring*/ { 2, 0 }, // Pogo Spring
|
||||
/*Super Ring*/ { 0, 0 }, // Super Ring
|
||||
/*Kitchen Sink*/ { 0, 0 }, // Kitchen Sink
|
||||
/*Sneaker x2*/ { 0, 0 }, // Sneaker x2
|
||||
/*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
|
||||
};
|
||||
|
||||
#define DISTVAR (2048) // Magic number distance for use with item roulette tiers
|
||||
|
|
@ -620,19 +620,20 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush,
|
|||
UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbumper, boolean spbrush)
|
||||
{
|
||||
UINT8 i;
|
||||
UINT8 n = 0;
|
||||
UINT8 useodds = 0;
|
||||
UINT8 disttable[14];
|
||||
UINT8 totallen = 0;
|
||||
UINT8 distlen = 0;
|
||||
boolean oddsvalid[8];
|
||||
|
||||
// Unused now, oops :V
|
||||
(void)bestbumper;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
UINT8 j;
|
||||
boolean available = false;
|
||||
|
||||
if (gametype == GT_BATTLE && i > 5)
|
||||
if (gametype == GT_BATTLE && i > 1)
|
||||
{
|
||||
oddsvalid[i] = false;
|
||||
break;
|
||||
|
|
@ -653,30 +654,24 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum
|
|||
#define SETUPDISTTABLE(odds, num) \
|
||||
if (oddsvalid[odds]) \
|
||||
for (i = num; i; --i) \
|
||||
disttable[distlen++] = odds; \
|
||||
totallen += num;
|
||||
disttable[distlen++] = odds;
|
||||
|
||||
if (gametype == GT_BATTLE) // Battle Mode
|
||||
{
|
||||
SETUPDISTTABLE(0,1);
|
||||
SETUPDISTTABLE(1,1);
|
||||
SETUPDISTTABLE(2,1);
|
||||
SETUPDISTTABLE(3,1);
|
||||
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;
|
||||
n = (wantedpos * distlen) / totallen;
|
||||
useodds = disttable[n];
|
||||
useodds = 0;
|
||||
|
||||
if (oddsvalid[0] == false && oddsvalid[1] == true)
|
||||
{
|
||||
// try to use karma odds as a fallback
|
||||
useodds = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1240,7 +1235,7 @@ 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
|
||||
|
||||
|
|
@ -1248,18 +1243,64 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
|
|||
*/
|
||||
static UINT8 K_CheckOffroadCollide(mobj_t *mo)
|
||||
{
|
||||
UINT8 i;
|
||||
// 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));
|
||||
|
||||
for (i = 2; i < 5; i++)
|
||||
for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
if (P_MobjTouchingSectorSpecial(mo, 1, i, true))
|
||||
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
|
||||
|
|
@ -4944,14 +4985,22 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source)
|
|||
static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
const INT32 numsnds = 13;
|
||||
|
||||
const fixed_t closedist = 160*FRACUNIT;
|
||||
const fixed_t fardist = 1536*FRACUNIT;
|
||||
|
||||
const UINT8 dampenval = 48; // 255 * 48 = close enough to FRACUNIT/6
|
||||
|
||||
INT32 class, s, w; // engine class number
|
||||
|
||||
UINT8 volume = 255;
|
||||
fixed_t volumedampen = 0;
|
||||
fixed_t volumedampen = FRACUNIT;
|
||||
|
||||
INT32 targetsnd = 0;
|
||||
INT32 i;
|
||||
|
||||
s = (player->kartspeed-1)/3;
|
||||
w = (player->kartweight-1)/3;
|
||||
s = (player->kartspeed - 1) / 3;
|
||||
w = (player->kartweight - 1) / 3;
|
||||
|
||||
#define LOCKSTAT(stat) \
|
||||
if (stat < 0) { stat = 0; } \
|
||||
|
|
@ -4960,83 +5009,119 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd)
|
|||
LOCKSTAT(w);
|
||||
#undef LOCKSTAT
|
||||
|
||||
class = s+(3*w);
|
||||
class = s + (3*w);
|
||||
|
||||
// Silence the engines
|
||||
if (leveltime < 8 || player->spectator)
|
||||
{
|
||||
player->karthud[khud_enginesnd] = 0; // Reset sound number
|
||||
// Silence the engines, and reset sound number while we're at it.
|
||||
player->karthud[khud_enginesnd] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ((leveltime % 8) != ((player-players) % 8)) // Per-player offset, to make engines sound distinct!
|
||||
#else
|
||||
if (leveltime % 8) // .25 seconds of wait time between engine sounds
|
||||
if (leveltime % 8)
|
||||
#endif
|
||||
{
|
||||
// .25 seconds of wait time between each engine sound playback
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->respawn.state == RESPAWNST_DROP) // Dropdashing
|
||||
{
|
||||
// Dropdashing
|
||||
targetsnd = ((cmd->buttons & BT_ACCELERATE) ? 12 : 0);
|
||||
else if (K_PlayerEBrake(player) == true) // Spindashing
|
||||
}
|
||||
else if (K_PlayerEBrake(player) == true)
|
||||
{
|
||||
// Spindashing
|
||||
targetsnd = ((cmd->buttons & BT_DRIFT) ? 12 : 0);
|
||||
}
|
||||
else
|
||||
targetsnd = (((6*K_GetForwardMove(player))/25) + ((player->speed / mapobjectscale)/5))/2;
|
||||
{
|
||||
// Average out the value of forwardmove and the speed that you're moving at.
|
||||
targetsnd = (((6 * cmd->forwardmove) / 25) + ((player->speed / mapobjectscale) / 5)) / 2;
|
||||
}
|
||||
|
||||
if (targetsnd < 0)
|
||||
targetsnd = 0;
|
||||
if (targetsnd > 12)
|
||||
targetsnd = 12;
|
||||
if (targetsnd < 0) { targetsnd = 0; }
|
||||
if (targetsnd > 12) { targetsnd = 12; }
|
||||
|
||||
if (player->karthud[khud_enginesnd] < targetsnd)
|
||||
player->karthud[khud_enginesnd]++;
|
||||
if (player->karthud[khud_enginesnd] > targetsnd)
|
||||
player->karthud[khud_enginesnd]--;
|
||||
if (player->karthud[khud_enginesnd] < targetsnd) { player->karthud[khud_enginesnd]++; }
|
||||
if (player->karthud[khud_enginesnd] > targetsnd) { player->karthud[khud_enginesnd]--; }
|
||||
|
||||
if (player->karthud[khud_enginesnd] < 0)
|
||||
player->karthud[khud_enginesnd] = 0;
|
||||
if (player->karthud[khud_enginesnd] > 12)
|
||||
player->karthud[khud_enginesnd] = 12;
|
||||
if (player->karthud[khud_enginesnd] < 0) { player->karthud[khud_enginesnd] = 0; }
|
||||
if (player->karthud[khud_enginesnd] > 12) { player->karthud[khud_enginesnd] = 12; }
|
||||
|
||||
// This code calculates how many players (and thus, how many engine sounds) are within ear shot,
|
||||
// and rebalances the volume of your engine sound based on how far away they are.
|
||||
|
||||
// This results in multiple things:
|
||||
// - When on your own, you will hear your own engine sound extremely clearly.
|
||||
// - When you were alone but someone is gaining on you, yours will go quiet, and you can hear theirs more clearly.
|
||||
// - When around tons of people, engine sounds will try to rebalance to not be as obnoxious.
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
UINT8 thisvol = 0;
|
||||
fixed_t dist;
|
||||
|
||||
if (!playeringame[i] || !players[i].mo || players[i].spectator || players[i].exiting)
|
||||
if (!playeringame[i] || !players[i].mo)
|
||||
{
|
||||
// This player doesn't exist.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (players[i].spectator)
|
||||
{
|
||||
// This player isn't playing an engine sound.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (P_IsDisplayPlayer(&players[i]))
|
||||
{
|
||||
volumedampen += FRACUNIT; // We already know what this is gonna be, let's not waste our time.
|
||||
// Don't dampen yourself!
|
||||
continue;
|
||||
}
|
||||
|
||||
dist = P_AproxDistance(P_AproxDistance(player->mo->x-players[i].mo->x,
|
||||
player->mo->y-players[i].mo->y), player->mo->z-players[i].mo->z) / 2;
|
||||
dist = P_AproxDistance(
|
||||
P_AproxDistance(
|
||||
player->mo->x - players[i].mo->x,
|
||||
player->mo->y - players[i].mo->y),
|
||||
player->mo->z - players[i].mo->z) / 2;
|
||||
|
||||
dist = FixedDiv(dist, mapobjectscale);
|
||||
|
||||
if (dist > 1536<<FRACBITS)
|
||||
if (dist > fardist)
|
||||
{
|
||||
// ENEMY OUT OF RANGE !
|
||||
continue;
|
||||
else if (dist < 160<<FRACBITS) // engine sounds' approx. range
|
||||
}
|
||||
else if (dist < closedist)
|
||||
{
|
||||
// engine sounds' approx. range
|
||||
thisvol = 255;
|
||||
}
|
||||
else
|
||||
thisvol = (15 * (((160<<FRACBITS) - dist)>>FRACBITS)) / (((1536<<FRACBITS)-(160<<FRACBITS))>>(FRACBITS+4));
|
||||
{
|
||||
thisvol = (15 * ((closedist - dist) / FRACUNIT)) / ((fardist - closedist) >> (FRACBITS+4));
|
||||
}
|
||||
|
||||
if (thisvol == 0)
|
||||
continue;
|
||||
|
||||
volumedampen += (thisvol * 257); // 255 * 257 = FRACUNIT
|
||||
volumedampen += (thisvol * dampenval);
|
||||
}
|
||||
|
||||
if (volumedampen > FRACUNIT)
|
||||
volume = FixedDiv(volume<<FRACBITS, volumedampen)>>FRACBITS;
|
||||
{
|
||||
volume = FixedDiv(volume * FRACUNIT, volumedampen) / FRACUNIT;
|
||||
}
|
||||
|
||||
if (volume <= 0) // Might as well
|
||||
if (volume <= 0)
|
||||
{
|
||||
// Don't need to play the sound at all.
|
||||
return;
|
||||
}
|
||||
|
||||
S_StartSoundAtVolume(player->mo, (sfx_krta00 + player->karthud[khud_enginesnd]) + (class*numsnds), volume);
|
||||
S_StartSoundAtVolume(player->mo, (sfx_krta00 + player->karthud[khud_enginesnd]) + (class * numsnds), volume);
|
||||
}
|
||||
|
||||
static void K_UpdateInvincibilitySounds(player_t *player)
|
||||
|
|
|
|||
|
|
@ -3624,41 +3624,6 @@ static int lib_kGetItemPatch(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// sets the remaining time before players blow up
|
||||
static int lib_kSetRaceCountdown(lua_State *L)
|
||||
{
|
||||
tic_t c = (tic_t)luaL_checkinteger(L, 1);
|
||||
racecountdown = c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// sets the remaining time before the race ends after everyone finishes
|
||||
static int lib_kSetExitCountdown(lua_State *L)
|
||||
{
|
||||
tic_t c = (tic_t)luaL_checkinteger(L, 1);
|
||||
NOHUD
|
||||
exitcountdown = c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Sets the item cooldown before another shrink / SPB can be rolled
|
||||
static int lib_kSetIndirectItemCountdown(lua_State *L)
|
||||
{
|
||||
tic_t c = (tic_t)luaL_checkinteger(L, 1);
|
||||
NOHUD
|
||||
indirectitemcooldown = c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Sets the item cooldown before another shrink / SPB can be rolled
|
||||
static int lib_kSetHyuCountdown(lua_State *L)
|
||||
{
|
||||
tic_t c = (tic_t)luaL_checkinteger(L, 1);
|
||||
NOHUD
|
||||
hyubgone = c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static luaL_Reg lib[] = {
|
||||
{"print", lib_print},
|
||||
{"chatprint", lib_chatprint},
|
||||
|
|
@ -3920,10 +3885,6 @@ static luaL_Reg lib[] = {
|
|||
{"K_GetKartAccel",lib_kGetKartAccel},
|
||||
{"K_GetKartFlashing",lib_kGetKartFlashing},
|
||||
{"K_GetItemPatch",lib_kGetItemPatch},
|
||||
{"K_SetRaceCountdown",lib_kSetRaceCountdown},
|
||||
{"K_SetExitCountdown",lib_kSetExitCountdown},
|
||||
{"K_SetIndirectItemCooldown",lib_kSetIndirectItemCountdown},
|
||||
{"K_SetHyudoroCooldown",lib_kSetHyuCountdown},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -370,7 +370,11 @@ int LUA_PushGlobals(lua_State *L, const char *word)
|
|||
} 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;
|
||||
}
|
||||
|
||||
|
|
@ -381,6 +385,15 @@ int LUA_WriteGlobals(lua_State *L, const char *word)
|
|||
redscore = (UINT32)luaL_checkinteger(L, 2);
|
||||
else if (fastcmp(word, "bluescore"))
|
||||
bluescore = (UINT32)luaL_checkinteger(L, 2);
|
||||
// SRB2Kart
|
||||
else if (fastcmp(word,"racecountdown"))
|
||||
racecountdown = (tic_t)luaL_checkinteger(L, 2);
|
||||
else if (fastcmp(word,"exitcountdown"))
|
||||
exitcountdown = (tic_t)luaL_checkinteger(L, 2);
|
||||
else if (fastcmp(word,"indirectitemcooldown"))
|
||||
indirectitemcooldown = (tic_t)luaL_checkinteger(L, 2);
|
||||
else if (fastcmp(word,"hyubgone"))
|
||||
hyubgone = (tic_t)luaL_checkinteger(L, 2);
|
||||
else
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
795
src/m_menu.c
795
src/m_menu.c
File diff suppressed because it is too large
Load diff
|
|
@ -239,7 +239,6 @@ typedef enum
|
|||
M_NOT_WAITING,
|
||||
|
||||
M_WAITING_VERSION,
|
||||
M_WAITING_ROOMS,
|
||||
M_WAITING_SERVERS,
|
||||
}
|
||||
M_waiting_mode_t;
|
||||
|
|
@ -336,12 +335,6 @@ typedef struct menuitem_s
|
|||
UINT8 alphaKey;
|
||||
} menuitem_t;
|
||||
|
||||
extern menuitem_t MP_RoomMenu[];
|
||||
extern UINT32 roomIds[NUM_LIST_ROOMS];
|
||||
|
||||
extern menuitem_t MP_RoomMenu[];
|
||||
extern UINT32 roomIds[NUM_LIST_ROOMS];
|
||||
|
||||
typedef struct menu_s
|
||||
{
|
||||
UINT32 menuid; // ID to encode menu type and hierarchy
|
||||
|
|
@ -478,6 +471,8 @@ void Addons_option_Onchange(void);
|
|||
void M_ReplayHut(INT32 choice);
|
||||
void M_SetPlaybackMenuPointer(void);
|
||||
|
||||
void M_RefreshPauseMenu(void);
|
||||
|
||||
INT32 HU_GetHighlightColor(void);
|
||||
|
||||
// Moviemode menu updating
|
||||
|
|
|
|||
153
src/mserv.c
153
src/mserv.c
|
|
@ -23,6 +23,12 @@
|
|||
#include "m_menu.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
#include "discord.h"
|
||||
#endif
|
||||
|
||||
#ifdef MASTERSERVER
|
||||
|
||||
static int MSId;
|
||||
static int MSRegisteredId = -1;
|
||||
|
||||
|
|
@ -43,27 +49,33 @@ static I_cond MSCond;
|
|||
# define Unlock_state()
|
||||
#endif/*HAVE_THREADS*/
|
||||
|
||||
static void Update_parameters (void);
|
||||
|
||||
#ifndef NONET
|
||||
static void Command_Listserv_f(void);
|
||||
#endif
|
||||
|
||||
#endif/*MASTERSERVER*/
|
||||
|
||||
static void Update_parameters (void);
|
||||
|
||||
static void MasterServer_OnChange(void);
|
||||
|
||||
static void Advertise_OnChange(void);
|
||||
|
||||
static CV_PossibleValue_t masterserver_update_rate_cons_t[] = {
|
||||
{2, "MIN"},
|
||||
{60, "MAX"},
|
||||
{0}
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
consvar_t cv_masterserver = {"masterserver", "https://mb.srb2.org/MS/0", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
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};
|
||||
|
||||
consvar_t cv_masterserver_update_rate = {"masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, Update_parameters, 0, NULL, NULL, 0, 0, NULL};
|
||||
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};
|
||||
|
||||
INT16 ms_RoomId = -1;
|
||||
consvar_t cv_advertise = {"advertise", "No", CV_NETVAR|CV_CALL|CV_NOINIT, CV_YesNo, Advertise_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
#if defined (MASTERSERVER) && defined (HAVE_THREADS)
|
||||
int ms_QueryId;
|
||||
I_mutex ms_QueryId_mutex;
|
||||
|
||||
|
|
@ -73,10 +85,6 @@ I_mutex ms_ServerList_mutex;
|
|||
|
||||
UINT16 current_port = 0;
|
||||
|
||||
// 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
|
||||
|
||||
/** Adds variables and commands relating to the master server.
|
||||
*
|
||||
* \sa cv_masterserver, cv_servername,
|
||||
|
|
@ -90,11 +98,17 @@ void AddMServCommands(void)
|
|||
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
|
||||
}
|
||||
|
||||
#ifdef MASTERSERVER
|
||||
|
||||
static void WarnGUI (void)
|
||||
{
|
||||
#ifdef HAVE_THREADS
|
||||
|
|
@ -107,14 +121,14 @@ static void WarnGUI (void)
|
|||
}
|
||||
|
||||
#define NUM_LIST_SERVER MAXSERVERLIST
|
||||
msg_server_t *GetShortServersList(INT32 room, int id)
|
||||
msg_server_t *GetShortServersList(int id)
|
||||
{
|
||||
msg_server_t *server_list;
|
||||
|
||||
// +1 for easy test
|
||||
server_list = malloc(( NUM_LIST_SERVER + 1 ) * sizeof *server_list);
|
||||
|
||||
if (HMS_fetch_servers(server_list, room, id))
|
||||
if (HMS_fetch_servers(server_list, id))
|
||||
return server_list;
|
||||
else
|
||||
{
|
||||
|
|
@ -124,17 +138,6 @@ msg_server_t *GetShortServersList(INT32 room, int id)
|
|||
}
|
||||
}
|
||||
|
||||
INT32 GetRoomsList(boolean hosting, int id)
|
||||
{
|
||||
if (HMS_fetch_rooms( ! hosting, id))
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
WarnGUI();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UPDATE_ALERT
|
||||
char *GetMODVersion(int id)
|
||||
{
|
||||
|
|
@ -168,15 +171,6 @@ char *GetMODVersion(int id)
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Console only version of the above (used before game init)
|
||||
void GetMODVersion_Console(void)
|
||||
{
|
||||
char buffer[16];
|
||||
|
||||
if (HMS_compare_mod_version(buffer, sizeof buffer) > 0)
|
||||
I_Error(UPDATE_ALERT_STRING_CONSOLE, VERSIONSTRING, buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NONET
|
||||
|
|
@ -267,6 +261,9 @@ Finish_unlist (void)
|
|||
Lock_state();
|
||||
{
|
||||
registered = MSRegistered;
|
||||
|
||||
if (MSId == MSRegisteredId)
|
||||
MSId++;
|
||||
}
|
||||
Unlock_state();
|
||||
|
||||
|
|
@ -287,13 +284,6 @@ Finish_unlist (void)
|
|||
I_wake_all_cond(&MSCond);
|
||||
#endif
|
||||
}
|
||||
|
||||
Lock_state();
|
||||
{
|
||||
if (MSId == MSRegisteredId)
|
||||
MSId++;
|
||||
}
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
|
|
@ -395,6 +385,7 @@ Change_masterserver_thread (char *api)
|
|||
|
||||
void RegisterServer(void)
|
||||
{
|
||||
#ifdef MASTERSERVER
|
||||
#ifdef HAVE_THREADS
|
||||
I_spawn_thread(
|
||||
"register-server",
|
||||
|
|
@ -404,6 +395,7 @@ void RegisterServer(void)
|
|||
#else
|
||||
Finish_registration();
|
||||
#endif
|
||||
#endif/*MASTERSERVER*/
|
||||
}
|
||||
|
||||
static void UpdateServer(void)
|
||||
|
|
@ -421,6 +413,7 @@ static void UpdateServer(void)
|
|||
|
||||
void UnregisterServer(void)
|
||||
{
|
||||
#ifdef MASTERSERVER
|
||||
#ifdef HAVE_THREADS
|
||||
I_spawn_thread(
|
||||
"unlist-server",
|
||||
|
|
@ -430,12 +423,13 @@ void UnregisterServer(void)
|
|||
#else
|
||||
Finish_unlist();
|
||||
#endif
|
||||
#endif/*MASTERSERVER*/
|
||||
}
|
||||
|
||||
static boolean
|
||||
Online (void)
|
||||
{
|
||||
return ( serverrunning && ms_RoomId > 0 );
|
||||
return ( serverrunning && cv_advertise.value );
|
||||
}
|
||||
|
||||
static inline void SendPingToMasterServer(void)
|
||||
|
|
@ -465,9 +459,33 @@ static inline void SendPingToMasterServer(void)
|
|||
}
|
||||
}
|
||||
|
||||
void MasterClient_Ticker(void)
|
||||
{
|
||||
#ifdef MASTERSERVER
|
||||
SendPingToMasterServer();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
Set_api (const char *api)
|
||||
{
|
||||
#ifdef HAVE_THREADS
|
||||
I_spawn_thread(
|
||||
"change-masterserver",
|
||||
(I_thread_fn)Change_masterserver_thread,
|
||||
strdup(api)
|
||||
);
|
||||
#else
|
||||
HMS_set_api(strdup(api));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif/*MASTERSERVER*/
|
||||
|
||||
static void
|
||||
Update_parameters (void)
|
||||
{
|
||||
#ifdef MASTERSERVER
|
||||
int registered;
|
||||
int delayed;
|
||||
|
||||
|
|
@ -487,29 +505,12 @@ Update_parameters (void)
|
|||
if (! delayed && registered)
|
||||
UpdateServer();
|
||||
}
|
||||
}
|
||||
|
||||
void MasterClient_Ticker(void)
|
||||
{
|
||||
SendPingToMasterServer();
|
||||
}
|
||||
|
||||
static void
|
||||
Set_api (const char *api)
|
||||
{
|
||||
#ifdef HAVE_THREADS
|
||||
I_spawn_thread(
|
||||
"change-masterserver",
|
||||
(I_thread_fn)Change_masterserver_thread,
|
||||
strdup(api)
|
||||
);
|
||||
#else
|
||||
HMS_set_api(strdup(api));
|
||||
#endif
|
||||
#endif/*MASTERSERVER*/
|
||||
}
|
||||
|
||||
static void MasterServer_OnChange(void)
|
||||
{
|
||||
#ifdef MASTERSERVER
|
||||
UnregisterServer();
|
||||
|
||||
/*
|
||||
|
|
@ -527,4 +528,36 @@ static void MasterServer_OnChange(void)
|
|||
|
||||
if (Online())
|
||||
RegisterServer();
|
||||
#endif/*MASTERSERVER*/
|
||||
}
|
||||
|
||||
static void
|
||||
Advertise_OnChange(void)
|
||||
{
|
||||
int different;
|
||||
|
||||
if (cv_advertise.value)
|
||||
{
|
||||
if (serverrunning)
|
||||
{
|
||||
Lock_state();
|
||||
{
|
||||
different = ( MSId != MSRegisteredId );
|
||||
}
|
||||
Unlock_state();
|
||||
|
||||
if (different)
|
||||
{
|
||||
RegisterServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UnregisterServer();
|
||||
}
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
DRPC_UpdatePresence();
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
28
src/mserv.h
28
src/mserv.h
|
|
@ -16,9 +16,6 @@
|
|||
|
||||
#include "i_threads.h"
|
||||
|
||||
// lowered from 32 due to menu changes
|
||||
#define NUM_LIST_ROOMS 16
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
|
@ -35,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;
|
||||
|
|
@ -65,15 +53,13 @@ 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;
|
||||
extern consvar_t cv_advertise;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
extern int ms_QueryId;
|
||||
|
|
@ -88,24 +74,20 @@ void UnregisterServer(void);
|
|||
|
||||
void MasterClient_Ticker(void);
|
||||
|
||||
msg_server_t *GetShortServersList(INT32 room, int id);
|
||||
INT32 GetRoomsList(boolean hosting, int id);
|
||||
msg_server_t *GetShortServersList(int id);
|
||||
#ifdef UPDATE_ALERT
|
||||
char *GetMODVersion(int id);
|
||||
void GetMODVersion_Console(void);
|
||||
#endif
|
||||
extern msg_rooms_t room_list[NUM_LIST_ROOMS+1];
|
||||
|
||||
void AddMServCommands(void);
|
||||
|
||||
/* HTTP */
|
||||
void HMS_set_api (char *api);
|
||||
int HMS_fetch_rooms (int joining, int id);
|
||||
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 room, int id);
|
||||
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
|
||||
|
|
|
|||
|
|
@ -432,8 +432,17 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
return;
|
||||
}
|
||||
|
||||
// Treat polyobjects kind of like 3D Floors
|
||||
if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT))
|
||||
{
|
||||
front = linedef->frontsector;
|
||||
back = linedef->frontsector;
|
||||
}
|
||||
else
|
||||
{
|
||||
front = linedef->frontsector;
|
||||
back = linedef->backsector;
|
||||
}
|
||||
|
||||
I_Assert(front != NULL);
|
||||
I_Assert(back != NULL);
|
||||
|
|
|
|||
|
|
@ -10464,6 +10464,7 @@ static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing)
|
|||
return true;
|
||||
}
|
||||
else if (mthing->type == 750 // Slope vertex point (formerly chaos spawn)
|
||||
|| (mthing->type == 777 || mthing->type == 778) // Slope anchors
|
||||
|| (mthing->type >= 600 && mthing->type <= 609) // Special placement patterns
|
||||
|| mthing->type == 1705 || mthing->type == 1713) // Hoops
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3980,8 +3980,16 @@ boolean P_LoadLevel(boolean fromnetsave)
|
|||
// init anything that P_SpawnSlopes/P_LoadThings needs to know
|
||||
P_InitSpecials();
|
||||
|
||||
// set up world state
|
||||
// jart: needs to be done here so anchored slopes know the attached list
|
||||
P_SpawnSpecials(fromnetsave);
|
||||
|
||||
P_SpawnSlopes(fromnetsave);
|
||||
|
||||
P_RaiseThings();
|
||||
|
||||
P_SpawnSpecialsThatRequireObjects();
|
||||
|
||||
P_SpawnMapThings(!fromnetsave);
|
||||
skyboxmo[0] = skyboxviewpnts[0];
|
||||
skyboxmo[1] = skyboxcenterpnts[0];
|
||||
|
|
@ -3990,8 +3998,6 @@ boolean P_LoadLevel(boolean fromnetsave)
|
|||
if (!playerstarts[numcoopstarts])
|
||||
break;
|
||||
|
||||
// set up world state
|
||||
P_SpawnSpecials(fromnetsave);
|
||||
K_AdjustWaypointsParameters();
|
||||
|
||||
if (!fromnetsave) // ugly hack for P_NetUnArchiveMisc (and P_LoadNetGame)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@
|
|||
pslope_t *slopelist = NULL;
|
||||
UINT16 slopecount = 0;
|
||||
|
||||
static void P_BuildSlopeAnchorList (void);
|
||||
static void P_SetupAnchoredSlopes (void);
|
||||
|
||||
// Calculate line normal
|
||||
void P_CalculateSlopeNormal(pslope_t *slope) {
|
||||
slope->normal.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT);
|
||||
|
|
@ -72,7 +75,7 @@ static void P_CalculateLineSlopeHighLow(pslope_t *slope, line_t *line, boolean c
|
|||
}
|
||||
|
||||
/// Setup slope via 3 vertexes.
|
||||
static void ReconfigureViaVertexes (pslope_t *slope, const vector3_t v1, const vector3_t v2, const vector3_t v3)
|
||||
void P_ReconfigureViaVertexes (pslope_t *slope, const vector3_t v1, const vector3_t v2, const vector3_t v3)
|
||||
{
|
||||
vector3_t vec1, vec2;
|
||||
|
||||
|
|
@ -185,7 +188,7 @@ void T_DynamicSlopeVert (dynplanethink_t* th)
|
|||
th->vex[i].z = 0;
|
||||
}
|
||||
|
||||
ReconfigureViaVertexes(slope, th->vex[0], th->vex[1], th->vex[2]);
|
||||
P_ReconfigureViaVertexes(slope, th->vex[0], th->vex[1], th->vex[2]);
|
||||
}
|
||||
|
||||
static inline void P_AddDynSlopeThinker (pslope_t* slope, dynplanetype_t type, line_t* sourceline, fixed_t extent, const INT16 tags[3], const vector3_t vx[3])
|
||||
|
|
@ -492,7 +495,7 @@ static pslope_t *MakeViaMapthings(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flag
|
|||
vx[i].z += R_PointInSubsector(vx[i].x, vx[i].y)->sector->floorheight;
|
||||
}
|
||||
|
||||
ReconfigureViaVertexes(ret, vx[0], vx[1], vx[2]);
|
||||
P_ReconfigureViaVertexes(ret, vx[0], vx[1], vx[2]);
|
||||
|
||||
if (spawnthinker && (flags & SL_DYNAMIC))
|
||||
P_AddDynSlopeThinker(ret, DP_VERTEX, NULL, 0, tags, vx);
|
||||
|
|
@ -574,7 +577,7 @@ static void SpawnVertexSlopes(void)
|
|||
pslope_t *slop = Slope_Add(0);
|
||||
sc->f_slope = slop;
|
||||
sc->hasslope = true;
|
||||
ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]);
|
||||
P_ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]);
|
||||
}
|
||||
|
||||
if (v1->ceilingzset || v2->ceilingzset || v3->ceilingzset)
|
||||
|
|
@ -586,7 +589,7 @@ static void SpawnVertexSlopes(void)
|
|||
pslope_t *slop = Slope_Add(0);
|
||||
sc->c_slope = slop;
|
||||
sc->hasslope = true;
|
||||
ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]);
|
||||
P_ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -709,6 +712,14 @@ void P_SpawnSlopes(const boolean fromsave) {
|
|||
}
|
||||
}
|
||||
|
||||
// jart
|
||||
|
||||
/// Build list of slope anchors--faster searching.
|
||||
P_BuildSlopeAnchorList();
|
||||
|
||||
/// Setup anchor based slopes.
|
||||
P_SetupAnchoredSlopes();
|
||||
|
||||
/// Copies slopes from tagged sectors via line specials.
|
||||
/// \note Doesn't actually copy, but instead they share the same pointers.
|
||||
for (i = 0; i < numlines; i++)
|
||||
|
|
@ -966,3 +977,6 @@ void P_ButteredSlope(mobj_t *mo)
|
|||
|
||||
P_Thrust(mo, mo->standingslope->xydirection, thrust);
|
||||
}
|
||||
|
||||
// jart
|
||||
#include "slope_anchors.c"
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ typedef enum
|
|||
void P_LinkSlopeThinkers (void);
|
||||
|
||||
void P_CalculateSlopeNormal(pslope_t *slope);
|
||||
void P_ReconfigureViaVertexes(pslope_t *slope, const vector3_t v1, const vector3_t v2, const vector3_t v3);
|
||||
void P_SpawnSlopes(const boolean fromsave);
|
||||
|
||||
//
|
||||
|
|
|
|||
45
src/p_spec.c
45
src/p_spec.c
|
|
@ -1081,7 +1081,6 @@ INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Parses arguments for parameterized polyobject door types
|
||||
static boolean PolyDoor(line_t *line)
|
||||
{
|
||||
|
|
@ -1355,7 +1354,6 @@ static boolean PolyDisplace(line_t *line)
|
|||
return EV_DoPolyObjDisplace(&pdd);
|
||||
}
|
||||
|
||||
|
||||
// Parses arguments for parameterized polyobject rotate-by-sector-heights specials
|
||||
static boolean PolyRotDisplace(line_t *line)
|
||||
{
|
||||
|
|
@ -5547,6 +5545,26 @@ P_RaiseTaggedThingsToFakeFloor (
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
P_RaiseThings (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < numlines; ++i)
|
||||
{
|
||||
switch (lines[i].special)
|
||||
{
|
||||
case 80: // Raise tagged things by type to this FOF
|
||||
P_RaiseTaggedThingsToFakeFloor(
|
||||
( sides[lines[i].sidenum[0]].textureoffset >> FRACBITS ),
|
||||
lines[i].tag,
|
||||
lines[i].frontsector
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// SPECIAL SPAWNING
|
||||
//
|
||||
|
|
@ -6931,28 +6949,19 @@ void P_SpawnSpecials(boolean fromnetsave)
|
|||
}
|
||||
}
|
||||
|
||||
/* some things have to be done after FOF spawn */
|
||||
|
||||
for (i = 0; i < numlines; ++i)
|
||||
{
|
||||
switch (lines[i].special)
|
||||
{
|
||||
case 80: // Raise tagged things by type to this FOF
|
||||
P_RaiseTaggedThingsToFakeFloor(
|
||||
( sides[lines[i].sidenum[0]].textureoffset >> FRACBITS ),
|
||||
lines[i].tag,
|
||||
lines[i].frontsector
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate each list
|
||||
for (i = 0; i < numsectors; i++)
|
||||
if(secthinkers[i].thinkers)
|
||||
Z_Free(secthinkers[i].thinkers);
|
||||
|
||||
Z_Free(secthinkers);
|
||||
}
|
||||
|
||||
/** Fuck polyobjects
|
||||
*/
|
||||
void P_SpawnSpecialsThatRequireObjects(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
// haleyjd 02/20/06: spawn polyobjects
|
||||
Polyobj_InitLevel();
|
||||
|
|
|
|||
10
src/p_spec.h
10
src/p_spec.h
|
|
@ -43,6 +43,8 @@ void P_SetupLevelFlatAnims(void);
|
|||
// at map load
|
||||
void P_InitSpecials(void);
|
||||
void P_SpawnSpecials(boolean fromnetsave);
|
||||
void P_RaiseThings(void);
|
||||
void P_SpawnSpecialsThatRequireObjects(void);
|
||||
|
||||
// every tic
|
||||
void P_UpdateSpecials(void);
|
||||
|
|
@ -648,4 +650,12 @@ void P_CalcHeight(player_t *player);
|
|||
|
||||
sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo);
|
||||
|
||||
/* line specials */
|
||||
enum
|
||||
{
|
||||
LT_SLOPE_ANCHORS_FLOOR = 777,
|
||||
LT_SLOPE_ANCHORS_CEILING = 778,
|
||||
LT_SLOPE_ANCHORS = 779,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -536,6 +536,7 @@ void S_StartCaption(sfxenum_t sfx_id, INT32 cnum, UINT16 lifespan)
|
|||
|
||||
void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
||||
{
|
||||
const INT32 initial_volume = volume;
|
||||
INT32 sep, pitch, priority, cnum;
|
||||
const sfxenum_t actual_id = sfx_id;
|
||||
sfxinfo_t *sfx;
|
||||
|
|
@ -900,6 +901,7 @@ dontplay4:
|
|||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
|
@ -1110,7 +1112,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;
|
||||
|
||||
|
|
@ -1444,15 +1446,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 (r_splitscreen)
|
||||
|
|
|
|||
|
|
@ -88,6 +88,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;
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,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}
|
||||
|
|
@ -91,10 +93,12 @@ 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}
|
||||
${SRB2_HWRENDER_SOURCES}
|
||||
|
|
@ -166,6 +170,7 @@ if(${SDL2_FOUND})
|
|||
${ZLIB_LIBRARIES}
|
||||
${OPENGL_LIBRARIES}
|
||||
${CURL_LIBRARIES}
|
||||
${DISCORDRPC_LIBRARIES}
|
||||
)
|
||||
set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}")
|
||||
else()
|
||||
|
|
@ -179,6 +184,7 @@ if(${SDL2_FOUND})
|
|||
${ZLIB_LIBRARIES}
|
||||
${OPENGL_LIBRARIES}
|
||||
${CURL_LIBRARIES}
|
||||
${DISCORDRPC_LIBRARIES}
|
||||
)
|
||||
|
||||
if(${CMAKE_SYSTEM} MATCHES Linux)
|
||||
|
|
@ -261,6 +267,7 @@ if(${SDL2_FOUND})
|
|||
${ZLIB_INCLUDE_DIRS}
|
||||
${OPENGL_INCLUDE_DIRS}
|
||||
${CURL_INCLUDE_DIRS}
|
||||
${DISCORDRPC_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
if((${SRB2_HAVE_MIXER}) OR (${SRB2_HAVE_MIXERX}))
|
||||
|
|
@ -375,6 +382,10 @@ if(${SDL2_FOUND})
|
|||
getwinlib(libstdc++-6 "libstdc++-6.dll")
|
||||
endif()
|
||||
|
||||
if(${SRB2_CONFIG_HAVE_DISCORDRPC})
|
||||
getwinlib(discord-rpc "discord-rpc.dll")
|
||||
endif()
|
||||
|
||||
install(PROGRAMS
|
||||
${win_extra_dll_list}
|
||||
DESTINATION .
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -65,6 +65,10 @@ char logfilename[1024];
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (_WIN32)
|
||||
#include "exchndl.h"
|
||||
#endif
|
||||
|
||||
#if defined (_WIN32)
|
||||
#include "../win32/win_dbg.h"
|
||||
typedef BOOL (WINAPI *p_IsDebuggerPresent)(VOID);
|
||||
|
|
@ -191,6 +195,20 @@ static void InitLogging(void)
|
|||
#endif
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
static void
|
||||
ChDirToExe (void)
|
||||
{
|
||||
CHAR path[MAX_PATH];
|
||||
if (GetModuleFileNameA(NULL, path, MAX_PATH) > 0)
|
||||
{
|
||||
strrchr(path, '\\')[0] = '\0';
|
||||
SetCurrentDirectoryA(path);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief The main function
|
||||
|
||||
\param argc number of arg
|
||||
|
|
@ -219,6 +237,10 @@ int main(int argc, char **argv)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
ChDirToExe();
|
||||
#endif
|
||||
|
||||
#ifdef LOGMESSAGES
|
||||
if (!M_CheckParm("-nolog"))
|
||||
InitLogging();
|
||||
|
|
@ -237,7 +259,7 @@ int main(int argc, char **argv)
|
|||
)
|
||||
#endif
|
||||
{
|
||||
LoadLibraryA("exchndl.dll");
|
||||
ExcHndlInit();
|
||||
}
|
||||
}
|
||||
#ifndef __MINGW32__
|
||||
|
|
|
|||
|
|
@ -152,11 +152,6 @@ int TimeFunction(int requested_frequency);
|
|||
#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
|
||||
|
|
@ -2341,6 +2336,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);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
/// \brief SRB2 graphics stuff for SDL
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
|
|
@ -85,6 +86,10 @@
|
|||
#include "ogl_sdl.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
#include "../discord.h"
|
||||
#endif
|
||||
|
||||
// maximum number of windowed modes (see windowedModes[][])
|
||||
#define MAXWINMODES (18)
|
||||
|
||||
|
|
@ -1324,6 +1329,11 @@ void I_FinishUpdate(void)
|
|||
if (cv_closedcaptioning.value)
|
||||
SCR_ClosedCaptions();
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
if (discordRequestList != NULL)
|
||||
ST_AskToJoinEnvelope();
|
||||
#endif
|
||||
|
||||
if (rendermode == render_soft && screens[0])
|
||||
{
|
||||
SDL_Rect rect;
|
||||
|
|
|
|||
492
src/slope_anchors.c
Normal file
492
src/slope_anchors.c
Normal file
|
|
@ -0,0 +1,492 @@
|
|||
// 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 Charyb's vertex slope anchors.
|
||||
/// This file is self contained to avoid a Big Large merge conflict.
|
||||
|
||||
/*
|
||||
FIXME
|
||||
FIXME
|
||||
FIXME
|
||||
FIXME WHEN 2.2 MERGE IS OVER, REFACTOR A LOT OF THE CODE IN P_SLOPES.C AND
|
||||
FIXME MAKE THIS NOT REDUNDANT.
|
||||
FIXME
|
||||
FIXME
|
||||
FIXME
|
||||
*/
|
||||
|
||||
struct anchor_list
|
||||
{
|
||||
mapthing_t ** anchors;
|
||||
const vertex_t ** points;
|
||||
fixed_t * closeness;
|
||||
size_t count;
|
||||
};
|
||||
|
||||
struct anchor_list floor_anchors;
|
||||
struct anchor_list ceiling_anchors;
|
||||
|
||||
static void * new_list (size_t n) {
|
||||
return Z_Malloc(n, PU_LEVEL, NULL);
|
||||
}
|
||||
|
||||
static void make_new_anchor_list (struct anchor_list * list) {
|
||||
list->anchors = new_list(list->count * sizeof *list->anchors);
|
||||
list->points = new_list(list->count * sizeof *list->points);
|
||||
list->closeness = new_list(list->count * sizeof *list->closeness);
|
||||
}
|
||||
|
||||
static void allocate_anchors (void) {
|
||||
size_t i;
|
||||
|
||||
floor_anchors.count = 0;
|
||||
ceiling_anchors.count = 0;
|
||||
|
||||
for (i = 0; i < nummapthings; ++i)
|
||||
{
|
||||
switch (mapthings[i].type)
|
||||
{
|
||||
case FLOOR_SLOPE_THING:
|
||||
floor_anchors.count++;
|
||||
break;
|
||||
|
||||
case CEILING_SLOPE_THING:
|
||||
ceiling_anchors.count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
make_new_anchor_list(&floor_anchors);
|
||||
make_new_anchor_list(&ceiling_anchors);
|
||||
}
|
||||
|
||||
static void
|
||||
compare_vertex_distance
|
||||
(
|
||||
const vertex_t ** nearest,
|
||||
fixed_t * nearest_distance,
|
||||
const fixed_t origin_x,
|
||||
const fixed_t origin_y,
|
||||
const vertex_t * v
|
||||
){
|
||||
const fixed_t distance = abs(P_AproxDistance
|
||||
(
|
||||
origin_x - v->x,
|
||||
origin_y - v->y
|
||||
));
|
||||
|
||||
if (distance < (*nearest_distance))
|
||||
{
|
||||
(*nearest) = v;
|
||||
(*nearest_distance) = distance;
|
||||
}
|
||||
}
|
||||
|
||||
static const vertex_t *
|
||||
nearest_point
|
||||
(
|
||||
fixed_t * closeness,
|
||||
mapthing_t * a,
|
||||
const sector_t * sector
|
||||
){
|
||||
const fixed_t x = a->x << FRACBITS;
|
||||
const fixed_t y = a->y << FRACBITS;
|
||||
|
||||
const vertex_t * v = NULL;/* shut compiler up, should never be NULL */
|
||||
|
||||
size_t i;
|
||||
|
||||
(*closeness) = INT32_MAX;
|
||||
|
||||
for (i = 0; i < sector->linecount; ++i)
|
||||
{
|
||||
compare_vertex_distance(&v, closeness, x, y, sector->lines[i]->v1);
|
||||
compare_vertex_distance(&v, closeness, x, y, sector->lines[i]->v2);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static INT16
|
||||
anchor_height
|
||||
(
|
||||
const mapthing_t * a,
|
||||
const sector_t * s
|
||||
){
|
||||
{
|
||||
INT16 z = ( a->options >> ZSHIFT );
|
||||
|
||||
if (a->options & MTF_OBJECTFLIP)
|
||||
{
|
||||
return ( s->ceilingheight >> FRACBITS ) - z;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ( s->floorheight >> FRACBITS ) + z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_anchor
|
||||
(
|
||||
struct anchor_list * list,
|
||||
mapthing_t * a
|
||||
){
|
||||
const subsector_t * sub = R_PointInSubsector
|
||||
(
|
||||
a->x << FRACBITS,
|
||||
a->y << FRACBITS
|
||||
);
|
||||
|
||||
const vertex_t * v;
|
||||
|
||||
fixed_t closeness;
|
||||
|
||||
a->z = anchor_height(a, sub->sector);
|
||||
|
||||
v = nearest_point(&closeness, a, sub->sector);
|
||||
|
||||
a->x = ( v->x >> FRACBITS );
|
||||
a->y = ( v->y >> FRACBITS );
|
||||
|
||||
list->anchors [list->count] = a;
|
||||
list->points [list->count] = v;
|
||||
list->closeness[list->count] = closeness;
|
||||
|
||||
list->count++;
|
||||
}
|
||||
|
||||
static void build_anchors (void) {
|
||||
size_t i;
|
||||
|
||||
floor_anchors.count = 0;
|
||||
ceiling_anchors.count = 0;
|
||||
|
||||
for (i = 0; i < nummapthings; ++i)
|
||||
{
|
||||
switch (mapthings[i].type)
|
||||
{
|
||||
case FLOOR_SLOPE_THING:
|
||||
set_anchor(&floor_anchors, &mapthings[i]);
|
||||
break;
|
||||
|
||||
case CEILING_SLOPE_THING:
|
||||
set_anchor(&ceiling_anchors, &mapthings[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_anchor
|
||||
(
|
||||
mapthing_t ** anchors,
|
||||
fixed_t distances[3],
|
||||
const struct anchor_list * list,
|
||||
const INT16 tag,
|
||||
const vertex_t * v
|
||||
){
|
||||
size_t i;
|
||||
|
||||
int k;
|
||||
|
||||
for (i = 0; i < list->count; ++i)
|
||||
{
|
||||
if (list->points[i] == v && list->anchors[i]->extrainfo == tag)
|
||||
{
|
||||
for (k = 0; k < 3; ++k)
|
||||
{
|
||||
if (list->closeness[i] < distances[k])
|
||||
{
|
||||
if (k == 0)
|
||||
{
|
||||
distances[2] = distances[1];
|
||||
distances[1] = distances[0];
|
||||
|
||||
anchors [2] = anchors [1];
|
||||
anchors [1] = anchors [0];
|
||||
}
|
||||
else if (k == 1)
|
||||
{
|
||||
distances[2] = distances[1];
|
||||
anchors [2] = anchors [1];
|
||||
}
|
||||
|
||||
distances[k] = list->closeness[i];
|
||||
|
||||
anchors[k] = list->anchors[i];
|
||||
|
||||
break;
|
||||
}
|
||||
else if (list->anchors[i] == anchors[k])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_sector_anchors
|
||||
(
|
||||
mapthing_t ** anchors,
|
||||
fixed_t distances[3],
|
||||
const struct anchor_list * list,
|
||||
const INT16 tag,
|
||||
const sector_t * sector
|
||||
){
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sector->linecount; ++i)
|
||||
{
|
||||
get_anchor(anchors, distances, list, tag, sector->lines[i]->v1);
|
||||
get_anchor(anchors, distances, list, tag, sector->lines[i]->v2);
|
||||
}
|
||||
}
|
||||
|
||||
static mapthing_t **
|
||||
find_closest_anchors
|
||||
(
|
||||
const sector_t * sector,
|
||||
const struct anchor_list * list,
|
||||
const INT16 tag
|
||||
){
|
||||
fixed_t distances[3] = { INT32_MAX, INT32_MAX, INT32_MAX };
|
||||
|
||||
mapthing_t ** anchors;
|
||||
|
||||
int last = 0;
|
||||
|
||||
size_t i;
|
||||
|
||||
if (list->count < 3)
|
||||
{
|
||||
I_Error("At least three slope anchors are required to make a slope.");
|
||||
}
|
||||
|
||||
anchors = Z_Malloc(3 * sizeof *anchors, PU_LEVEL, NULL);
|
||||
|
||||
if (sector->numattached > 0)
|
||||
{
|
||||
for (i = 0; i < sector->numattached; ++i)
|
||||
{
|
||||
get_sector_anchors
|
||||
(anchors, distances, list, tag, §ors[sector->attached[i]]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
get_sector_anchors(anchors, distances, list, tag, sector);
|
||||
}
|
||||
|
||||
if (distances[2] < INT32_MAX)
|
||||
{
|
||||
return anchors;
|
||||
}
|
||||
|
||||
if (distances[1] < INT32_MAX)
|
||||
last = 2;
|
||||
else if (distances[0] < INT32_MAX)
|
||||
last = 1;
|
||||
else
|
||||
last = 0;
|
||||
|
||||
if (sector->numattached > 0)
|
||||
{
|
||||
CONS_Printf("\nSearched for anchors in sectors...\n\n");
|
||||
|
||||
for (i = 0; i < sector->numattached; ++i)
|
||||
{
|
||||
CONS_Printf("#%s\n", sizeu1 (sector->attached[i]));
|
||||
}
|
||||
|
||||
I_Error(
|
||||
"(Control Sector #%s)"
|
||||
" Slope requires anchors (with Parameter %d)"
|
||||
" near 3 of its target sectors' vertices (%d found)"
|
||||
|
||||
"\n\nCheck the log to see which sectors were searched.",
|
||||
|
||||
sizeu1 (sector - sectors),
|
||||
tag,
|
||||
last
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
I_Error(
|
||||
"(Sector #%s)"
|
||||
" Slope requires anchors (with Parameter %d)"
|
||||
" near 3 of its vertices (%d found)",
|
||||
|
||||
sizeu1 (sector - sectors),
|
||||
tag,
|
||||
last
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static pslope_t *
|
||||
new_vertex_slope
|
||||
(
|
||||
mapthing_t ** anchors,
|
||||
const INT16 flags
|
||||
){
|
||||
pslope_t * slope = Z_Calloc(sizeof (pslope_t), PU_LEVEL, NULL);
|
||||
const vector3_t anchorVertices[3] = {
|
||||
{anchors[0]->x << FRACBITS, anchors[0]->y << FRACBITS, anchors[0]->z << FRACBITS},
|
||||
{anchors[1]->x << FRACBITS, anchors[1]->y << FRACBITS, anchors[1]->z << FRACBITS},
|
||||
{anchors[2]->x << FRACBITS, anchors[2]->y << FRACBITS, anchors[2]->z << FRACBITS}
|
||||
};
|
||||
|
||||
if (flags & ML_NETONLY)
|
||||
{
|
||||
slope->flags |= SL_NOPHYSICS;
|
||||
}
|
||||
|
||||
if (flags & ML_NONET)
|
||||
{
|
||||
slope->flags |= SL_DYNAMIC;
|
||||
}
|
||||
|
||||
P_ReconfigureViaVertexes(slope, anchorVertices[0], anchorVertices[1], anchorVertices[2]);
|
||||
//slope->refpos = 5;
|
||||
|
||||
// Add to the slope list
|
||||
slope->next = slopelist;
|
||||
slopelist = slope;
|
||||
|
||||
slopecount++;
|
||||
slope->id = slopecount;
|
||||
|
||||
return slope;
|
||||
}
|
||||
|
||||
static mapthing_t **
|
||||
flip_slope
|
||||
(
|
||||
mapthing_t ** origin,
|
||||
const sector_t * sector
|
||||
){
|
||||
mapthing_t * copy = Z_Malloc(3 * sizeof (mapthing_t), PU_LEVEL, NULL);
|
||||
mapthing_t ** anchors = Z_Malloc(3 * sizeof (mapthing_t *), PU_LEVEL, NULL);
|
||||
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
memcpy(©[i], origin[i], sizeof copy[i]);
|
||||
|
||||
copy[i].options ^= MTF_OBJECTFLIP;
|
||||
copy[i].z = anchor_height(©[i], sector);
|
||||
|
||||
anchors[i] = ©[i];
|
||||
}
|
||||
|
||||
return anchors;
|
||||
}
|
||||
|
||||
static void
|
||||
slope_sector
|
||||
(
|
||||
pslope_t ** slope,
|
||||
pslope_t ** alt,
|
||||
sector_t * sector,
|
||||
const INT16 flags,
|
||||
const struct anchor_list * list,
|
||||
const INT16 tag
|
||||
){
|
||||
mapthing_t ** anchors = find_closest_anchors(sector, list, tag);
|
||||
|
||||
if (anchors != NULL)
|
||||
{
|
||||
(*slope) = new_vertex_slope(anchors, flags);
|
||||
|
||||
/* Effect 6 - invert slope to opposite side */
|
||||
if (flags & ML_EFFECT6)
|
||||
{
|
||||
(*alt) = new_vertex_slope(flip_slope(anchors, sector), flags);
|
||||
}
|
||||
|
||||
sector->hasslope = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
make_anchored_slope
|
||||
(
|
||||
const line_t * line,
|
||||
const int plane
|
||||
){
|
||||
enum
|
||||
{
|
||||
FLOOR = 0x1,
|
||||
CEILING = 0x2,
|
||||
};
|
||||
|
||||
INT16 flags = line->flags;
|
||||
|
||||
const int side = ( flags & ML_NOCLIMB ) != 0;
|
||||
|
||||
sector_t * s;
|
||||
|
||||
if (side == 0 || flags & ML_TWOSIDED)
|
||||
{
|
||||
s = sides[line->sidenum[side]].sector;
|
||||
|
||||
if (plane == (FLOOR|CEILING))
|
||||
{
|
||||
flags &= ~ML_EFFECT6;
|
||||
}
|
||||
|
||||
if (plane & FLOOR)
|
||||
{
|
||||
slope_sector
|
||||
(&s->f_slope, &s->c_slope, s, flags, &floor_anchors, line->tag);
|
||||
}
|
||||
|
||||
if (plane & CEILING)
|
||||
{
|
||||
slope_sector
|
||||
(&s->c_slope, &s->f_slope, s, flags, &ceiling_anchors, line->tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void P_BuildSlopeAnchorList (void) {
|
||||
allocate_anchors();
|
||||
build_anchors();
|
||||
}
|
||||
|
||||
static void P_SetupAnchoredSlopes (void) {
|
||||
enum
|
||||
{
|
||||
FLOOR = 0x1,
|
||||
CEILING = 0x2,
|
||||
};
|
||||
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < numlines; ++i)
|
||||
{
|
||||
if (lines[i].special == LT_SLOPE_ANCHORS_FLOOR)
|
||||
{
|
||||
make_anchored_slope(&lines[i], FLOOR);
|
||||
}
|
||||
else if (lines[i].special == LT_SLOPE_ANCHORS_CEILING)
|
||||
{
|
||||
make_anchored_slope(&lines[i], CEILING);
|
||||
}
|
||||
else if (lines[i].special == LT_SLOPE_ANCHORS)
|
||||
{
|
||||
make_anchored_slope(&lines[i], FLOOR|CEILING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -888,6 +888,10 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"bhurry", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // v1.0.2 Battle overtime
|
||||
{"bsnipe", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Banana sniping
|
||||
{"sploss", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Down to yellow sparks
|
||||
{"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
|
||||
{"cock", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Hammer cocks, bang bang
|
||||
|
|
|
|||
|
|
@ -952,6 +952,10 @@ typedef enum
|
|||
sfx_bhurry,
|
||||
sfx_bsnipe,
|
||||
sfx_sploss,
|
||||
sfx_join,
|
||||
sfx_leave,
|
||||
sfx_requst,
|
||||
sfx_syfail,
|
||||
sfx_itfree,
|
||||
sfx_dbgsal,
|
||||
sfx_cock,
|
||||
|
|
|
|||
|
|
@ -136,6 +136,11 @@ static patch_t *fnshico;
|
|||
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] =
|
||||
|
|
@ -363,6 +368,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
|
||||
|
|
@ -1009,6 +1019,22 @@ static void ST_MayonakaStatic(void)
|
|||
V_DrawFixedPatch(320<<FRACBITS, 142<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_FLIP|flag, hud_tv2, NULL);
|
||||
}
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
void ST_AskToJoinEnvelope(void)
|
||||
{
|
||||
const tic_t freq = TICRATE/2;
|
||||
|
||||
if (menuactive)
|
||||
return;
|
||||
|
||||
if ((leveltime % freq) < freq/2)
|
||||
return;
|
||||
|
||||
V_DrawFixedPatch(296*FRACUNIT, 2*FRACUNIT, FRACUNIT, V_SNAPTOTOP|V_SNAPTORIGHT, envelope, NULL);
|
||||
// maybe draw number of requests with V_DrawPingNum ?
|
||||
}
|
||||
#endif
|
||||
|
||||
void ST_Drawer(void)
|
||||
{
|
||||
boolean stagetitle = false; // Decide whether to draw the stage title or not
|
||||
|
|
|
|||
|
|
@ -32,6 +32,11 @@ void ST_Ticker(boolean run);
|
|||
// Called when naming a replay.
|
||||
void ST_DrawDemoTitleEntry(void);
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
// Called when you have Discord asks
|
||||
void ST_AskToJoinEnvelope(void);
|
||||
#endif
|
||||
|
||||
// Called by main loop.
|
||||
void ST_Drawer(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,10 @@ ifndef MINGW64 #miniupnc is broken with MINGW64
|
|||
endif
|
||||
endif
|
||||
|
||||
ifndef NO_DISCORDRPC
|
||||
HAVE_DISCORDRPC=1
|
||||
endif
|
||||
|
||||
OPTS=-DSTDC_HEADERS
|
||||
|
||||
ifndef GCC44
|
||||
|
|
@ -76,6 +80,12 @@ else
|
|||
endif
|
||||
endif
|
||||
|
||||
ifndef MINGW64
|
||||
CPPFLAGS+=-I../libs/drmingw/include
|
||||
LDFLAGS+=-L../libs/drmingw/lib/win32
|
||||
LIBS+=-lmgwhelp -lexchndl
|
||||
endif
|
||||
|
||||
# name of the exefile
|
||||
ifdef SDL
|
||||
EXENAME?=srb2kart.exe
|
||||
|
|
@ -163,3 +173,14 @@ else
|
|||
CURL_LDFLAGS+=-L../libs/curl/lib32 -lcurl
|
||||
endif #MINGW64
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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".
|
||||
Loading…
Add table
Reference in a new issue