mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 09:11:48 +00:00
Merge branch SRB2:next into rendercvars
This commit is contained in:
commit
0c2665f3d7
108 changed files with 7483 additions and 7512 deletions
|
@ -345,7 +345,7 @@ Debian stable:arm64:
|
|||
- - |
|
||||
# make
|
||||
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
|
||||
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 ERRORMODE=1 NONX86=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 NONX86=1
|
||||
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 ERRORMODE=1 NONX86=1C || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 NONX86=1 ARM64=1
|
||||
- |
|
||||
# make
|
||||
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
|
||||
|
@ -419,6 +419,43 @@ Debian stable Clang:
|
|||
# make
|
||||
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
|
||||
|
||||
Debian stable musl:
|
||||
stage: build
|
||||
|
||||
allow_failure: true
|
||||
|
||||
artifacts:
|
||||
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-musl"
|
||||
|
||||
variables:
|
||||
CC: musl-gcc
|
||||
LDD: musl-ldd
|
||||
|
||||
script:
|
||||
- - |
|
||||
# apt_toolchain
|
||||
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
|
||||
- apt-get install gcc
|
||||
- |
|
||||
# apt_toolchain
|
||||
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
|
||||
|
||||
- - |
|
||||
# apt_development
|
||||
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
|
||||
- apt-get install musl-tools
|
||||
- |
|
||||
# apt_development
|
||||
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
|
||||
|
||||
- - |
|
||||
# make
|
||||
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
|
||||
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 SDL=0 NOHW=1 NOZLIB=1 NOCURL=1 NOGME=1 NOOPENMPT=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 SDL=0 NOHW=1 NOZLIB=1 NOCURL=1 NOGME=1 NOOPENMPT=1
|
||||
- |
|
||||
# make
|
||||
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
|
||||
|
||||
Debian testing Clang:
|
||||
extends: Debian stable Clang
|
||||
|
||||
|
@ -432,3 +469,16 @@ Debian testing Clang:
|
|||
WFLAGS: -Wno-cast-align -Wno-deprecated-non-prototype
|
||||
CFLAGS: -Wno-cast-align -Wno-deprecated-non-prototype
|
||||
LDFLAGS: -Wl,-fuse-ld=gold
|
||||
|
||||
Debian testing musl:
|
||||
extends: Debian stable musl
|
||||
|
||||
image: debian:testing-slim
|
||||
|
||||
artifacts:
|
||||
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-musl"
|
||||
|
||||
variables:
|
||||
CC: musl-gcc
|
||||
LDD: musl-ldd
|
||||
LDFLAGS: -Wl,-fuse-ld=gold
|
||||
|
|
|
@ -8,11 +8,7 @@ LOCAL_SRC_FILES := am_map.c \
|
|||
command.c \
|
||||
comptime.c \
|
||||
console.c \
|
||||
d_clisrv.c \
|
||||
d_main.c \
|
||||
d_net.c \
|
||||
d_netcmd.c \
|
||||
d_netfil.c \
|
||||
dehacked.c \
|
||||
f_finale.c \
|
||||
f_wipe.c \
|
||||
|
@ -20,7 +16,6 @@ LOCAL_SRC_FILES := am_map.c \
|
|||
g_game.c \
|
||||
g_input.c \
|
||||
hu_stuff.c \
|
||||
i_tcp.c \
|
||||
info.c \
|
||||
lzf.c \
|
||||
m_argv.c \
|
||||
|
@ -32,7 +27,6 @@ LOCAL_SRC_FILES := am_map.c \
|
|||
m_queue.c \
|
||||
m_random.c \
|
||||
md5.c \
|
||||
mserv.c \
|
||||
p_ceilng.c \
|
||||
p_enemy.c \
|
||||
p_fab.c \
|
||||
|
@ -61,6 +55,7 @@ LOCAL_SRC_FILES := am_map.c \
|
|||
r_things.c \
|
||||
s_sound.c \
|
||||
screen.c \
|
||||
snake.c \
|
||||
sounds.c \
|
||||
st_stuff.c \
|
||||
string.c \
|
||||
|
|
|
@ -6,10 +6,6 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
|
|||
config.h.in
|
||||
string.c
|
||||
d_main.c
|
||||
d_clisrv.c
|
||||
d_net.c
|
||||
d_netfil.c
|
||||
d_netcmd.c
|
||||
dehacked.c
|
||||
deh_soc.c
|
||||
deh_lua.c
|
||||
|
@ -83,12 +79,10 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
|
|||
sounds.c
|
||||
w_wad.c
|
||||
filesrch.c
|
||||
mserv.c
|
||||
http-mserv.c
|
||||
i_tcp.c
|
||||
lzf.c
|
||||
b_bot.c
|
||||
u_list.c
|
||||
snake.c
|
||||
lua_script.c
|
||||
lua_baselib.c
|
||||
lua_mathlib.c
|
||||
|
@ -149,6 +143,7 @@ set(SRB2_CONFIG_DEV_BUILD OFF CACHE BOOL
|
|||
"Compile a development build of SRB2.")
|
||||
|
||||
add_subdirectory(blua)
|
||||
add_subdirectory(netcode)
|
||||
|
||||
# OS macros
|
||||
if (UNIX)
|
||||
|
|
|
@ -62,7 +62,6 @@
|
|||
#
|
||||
# Netplay incompatible
|
||||
# --------------------
|
||||
# NONET=1 - Disable online capability.
|
||||
# NOMD5=1 - Disable MD5 checksum (validation tool).
|
||||
# NOPOSTPROCESSING=1 - ?
|
||||
# MOBJCONSISTANCY=1 - ??
|
||||
|
@ -187,6 +186,7 @@ objdir:=$(makedir)/objs
|
|||
sources+=\
|
||||
$(call List,Sourcefile)\
|
||||
$(call List,blua/Sourcefile)\
|
||||
$(call List,netcode/Sourcefile)\
|
||||
|
||||
depends:=$(basename $(filter %.c %.s,$(sources)))
|
||||
objects:=$(basename $(filter %.c %.s %.nas,$(sources)))
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
|
||||
passthru_opts+=\
|
||||
NONET NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\
|
||||
NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\
|
||||
MOBJCONSISTANCY PACKETDROP ZDEBUG\
|
||||
HAVE_MINIUPNPC\
|
||||
|
||||
|
@ -18,10 +18,6 @@ opts+=-DHWRENDER
|
|||
sources+=$(call List,hardware/Sourcefile)
|
||||
endif
|
||||
|
||||
ifdef NONET
|
||||
NOCURL=1
|
||||
endif
|
||||
|
||||
ifndef NOMD5
|
||||
sources+=md5.c
|
||||
endif
|
||||
|
@ -43,13 +39,11 @@ sources+=apng.c
|
|||
endif
|
||||
endif
|
||||
|
||||
ifndef NONET
|
||||
ifndef NOCURL
|
||||
CURLCONFIG?=curl-config
|
||||
$(eval $(call Configure,CURL,$(CURLCONFIG)))
|
||||
opts+=-DHAVE_CURL
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef HAVE_MINIUPNPC
|
||||
libs+=-lminiupnpc
|
||||
|
|
|
@ -33,12 +33,10 @@ libs+=-lws2_32
|
|||
endif
|
||||
endif
|
||||
|
||||
ifndef NONET
|
||||
ifndef MINGW64 # miniupnc is broken with MINGW64
|
||||
opts+=-I../libs -DSTATIC_MINIUPNPC
|
||||
libs+=-L../libs/miniupnpc/mingw$(32) -lws2_32 -liphlpapi
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef MINGW64
|
||||
32=32
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
string.c
|
||||
d_main.c
|
||||
d_clisrv.c
|
||||
d_net.c
|
||||
d_netfil.c
|
||||
d_netcmd.c
|
||||
dehacked.c
|
||||
deh_soc.c
|
||||
deh_lua.c
|
||||
|
@ -77,12 +73,10 @@ s_sound.c
|
|||
sounds.c
|
||||
w_wad.c
|
||||
filesrch.c
|
||||
mserv.c
|
||||
http-mserv.c
|
||||
i_tcp.c
|
||||
lzf.c
|
||||
b_bot.c
|
||||
u_list.c
|
||||
snake.c
|
||||
lua_script.c
|
||||
lua_baselib.c
|
||||
lua_mathlib.c
|
||||
|
|
|
@ -1071,7 +1071,6 @@ static inline void AM_drawPlayers(void)
|
|||
return;
|
||||
}
|
||||
|
||||
// multiplayer (how??)
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "../i_net.h"
|
||||
#include "../netcode/i_net.h"
|
||||
|
||||
boolean I_InitNetwork(void)
|
||||
{
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
#include "lualib.h"
|
||||
#include "../i_system.h"
|
||||
#include "../g_game.h"
|
||||
#include "../d_netfil.h"
|
||||
#include "../netcode/d_netfil.h"
|
||||
#include "../netcode/net_command.h"
|
||||
#include "../lua_libs.h"
|
||||
#include "../byteptr.h"
|
||||
#include "../lua_script.h"
|
||||
|
|
|
@ -28,11 +28,12 @@
|
|||
#include "byteptr.h"
|
||||
#include "p_saveg.h"
|
||||
#include "g_game.h" // for player_names
|
||||
#include "d_netcmd.h"
|
||||
#include "netcode/d_netcmd.h"
|
||||
#include "netcode/net_command.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "p_setup.h"
|
||||
#include "lua_script.h"
|
||||
#include "d_netfil.h" // findfile
|
||||
#include "netcode/d_netfil.h" // findfile
|
||||
#include "r_data.h" // Color_cons_t
|
||||
#include "d_main.h" // D_IsPathAllowed
|
||||
|
||||
|
|
|
@ -543,13 +543,13 @@ static void CON_RecalcSize(void)
|
|||
con_scalefactor = 1;
|
||||
break;
|
||||
case V_SMALLSCALEPATCH:
|
||||
con_scalefactor = vid.smalldupx;
|
||||
con_scalefactor = vid.smalldup;
|
||||
break;
|
||||
case V_MEDSCALEPATCH:
|
||||
con_scalefactor = vid.meddupx;
|
||||
con_scalefactor = vid.meddup;
|
||||
break;
|
||||
default: // Full scaling
|
||||
con_scalefactor = vid.dupx;
|
||||
con_scalefactor = vid.dup;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -667,7 +667,7 @@ static void CON_MoveConsole(void)
|
|||
}
|
||||
|
||||
// Not instant - Increment fracmovement fractionally
|
||||
fracmovement += FixedMul(cons_speed.value*vid.fdupy, renderdeltatics);
|
||||
fracmovement += FixedMul(cons_speed.value*vid.fdup, renderdeltatics);
|
||||
|
||||
if (con_curlines < con_destlines) // Move the console downwards
|
||||
{
|
||||
|
@ -1764,9 +1764,9 @@ static void CON_DrawBackpic(void)
|
|||
con_backpic = W_CachePatchNum(piclump, PU_PATCH);
|
||||
|
||||
// Center the backpic, and draw a vertically cropped patch.
|
||||
w = (con_backpic->width * vid.dupx);
|
||||
w = con_backpic->width * vid.dup;
|
||||
x = (vid.width / 2) - (w / 2);
|
||||
h = con_curlines/vid.dupy;
|
||||
h = con_curlines/vid.dup;
|
||||
|
||||
// If the patch doesn't fill the entire screen,
|
||||
// then fill the sides with a solid color.
|
||||
|
|
5840
src/d_clisrv.c
5840
src/d_clisrv.c
File diff suppressed because it is too large
Load diff
|
@ -34,7 +34,7 @@
|
|||
#include "doomdef.h"
|
||||
#include "am_map.h"
|
||||
#include "console.h"
|
||||
#include "d_net.h"
|
||||
#include "netcode/d_net.h"
|
||||
#include "f_finale.h"
|
||||
#include "g_game.h"
|
||||
#include "hu_stuff.h"
|
||||
|
@ -56,11 +56,11 @@
|
|||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
#include "d_main.h"
|
||||
#include "d_netfil.h"
|
||||
#include "netcode/d_netfil.h"
|
||||
#include "m_cheat.h"
|
||||
#include "y_inter.h"
|
||||
#include "p_local.h" // chasecam
|
||||
#include "mserv.h" // ms_RoomId
|
||||
#include "netcode/mserv.h" // ms_RoomId
|
||||
#include "m_misc.h" // screenshot functionality
|
||||
#include "deh_tables.h" // Dehacked list test
|
||||
#include "m_cond.h" // condition initialization
|
||||
|
@ -981,6 +981,7 @@ void D_StartTitle(void)
|
|||
emeralds = 0;
|
||||
memset(&luabanks, 0, sizeof(luabanks));
|
||||
lastmaploaded = 0;
|
||||
pickedchar = R_SkinAvailable(cv_defaultskin.string);
|
||||
|
||||
// In case someone exits out at the same time they start a time attack run,
|
||||
// reset modeattacking
|
||||
|
@ -1626,6 +1627,8 @@ void D_SRB2Main(void)
|
|||
autostart = true;
|
||||
}
|
||||
|
||||
pickedchar = R_SkinAvailable(cv_defaultskin.string);
|
||||
|
||||
// user settings come before "+" parameters.
|
||||
if (dedicated)
|
||||
COM_ImmedExecute(va("exec \"%s"PATHSEP"adedserv.cfg\"\n", srb2home));
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "r_sky.h"
|
||||
#include "fastcmp.h"
|
||||
#include "lua_script.h" // Reluctantly included for LUA_EvalMath
|
||||
#include "d_clisrv.h"
|
||||
#include "netcode/d_clisrv.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_light.h"
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "r_sky.h"
|
||||
#include "fastcmp.h"
|
||||
#include "lua_script.h" // Reluctantly included for LUA_EvalMath
|
||||
#include "d_clisrv.h"
|
||||
#include "netcode/d_clisrv.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_light.h"
|
||||
|
|
|
@ -1933,6 +1933,13 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
|||
"S_SMALLGRABCHAIN",
|
||||
"S_BIGGRABCHAIN",
|
||||
|
||||
// Blue spring on a ball
|
||||
"S_BLUESPRINGBALL",
|
||||
"S_BLUESPRINGBALL2",
|
||||
"S_BLUESPRINGBALL3",
|
||||
"S_BLUESPRINGBALL4",
|
||||
"S_BLUESPRINGBALL5",
|
||||
|
||||
// Yellow spring on a ball
|
||||
"S_YELLOWSPRINGBALL",
|
||||
"S_YELLOWSPRINGBALL2",
|
||||
|
@ -3891,6 +3898,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
|||
"MT_BIGMACE", // Big Mace
|
||||
"MT_SMALLGRABCHAIN", // Small Grab Chain
|
||||
"MT_BIGGRABCHAIN", // Big Grab Chain
|
||||
"MT_BLUESPRINGBALL", // Blue spring on a ball
|
||||
"MT_YELLOWSPRINGBALL", // Yellow spring on a ball
|
||||
"MT_REDSPRINGBALL", // Red spring on a ball
|
||||
"MT_SMALLFIREBAR", // Small Firebar
|
||||
|
@ -4883,7 +4891,7 @@ const char *const MENUTYPES_LIST[] = {
|
|||
"MP_SERVER",
|
||||
"MP_CONNECT",
|
||||
"MP_ROOM",
|
||||
"MP_PLAYERSETUP", // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET
|
||||
"MP_PLAYERSETUP",
|
||||
"MP_SERVER_OPTIONS",
|
||||
|
||||
// Options
|
||||
|
|
|
@ -56,7 +56,6 @@
|
|||
#endif
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#define NONET
|
||||
#if !defined (HWRENDER) && !defined (NOHW)
|
||||
#define HWRENDER
|
||||
#endif
|
||||
|
@ -724,7 +723,7 @@ extern int
|
|||
/// Maintain compatibility with older 2.2 demos
|
||||
#define OLD22DEMOCOMPAT
|
||||
|
||||
#if defined (HAVE_CURL) && ! defined (NONET)
|
||||
#ifdef HAVE_CURL
|
||||
#define MASTERSERVER
|
||||
#else
|
||||
#undef UPDATE_ALERT
|
||||
|
|
|
@ -634,7 +634,7 @@ extern boolean singletics;
|
|||
// Netgame stuff
|
||||
// =============
|
||||
|
||||
#include "d_clisrv.h"
|
||||
#include "netcode/d_clisrv.h"
|
||||
|
||||
extern consvar_t cv_timetic; // display high resolution timer
|
||||
extern consvar_t cv_powerupdisplay; // display powerups
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "../i_net.h"
|
||||
#include "../netcode/i_net.h"
|
||||
|
||||
boolean I_InitNetwork(void)
|
||||
{
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "d_main.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "netcode/d_netcmd.h"
|
||||
#include "f_finale.h"
|
||||
#include "g_game.h"
|
||||
#include "hu_stuff.h"
|
||||
|
@ -1327,7 +1327,7 @@ void F_CreditDrawer(void)
|
|||
y += 12<<FRACBITS;
|
||||
break;
|
||||
}
|
||||
if (FixedMul(y,vid.dupy) > vid.height)
|
||||
if (FixedMul(y,vid.dup) > vid.height)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1362,7 +1362,7 @@ void F_CreditTicker(void)
|
|||
case 1: y += 30<<FRACBITS; break;
|
||||
default: y += 12<<FRACBITS; break;
|
||||
}
|
||||
if (FixedMul(y,vid.dupy) > vid.height)
|
||||
if (FixedMul(y,vid.dup) > vid.height)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2082,7 +2082,7 @@ void F_EndingDrawer(void)
|
|||
if (goodending && finalecount >= TICRATE && finalecount < INFLECTIONPOINT)
|
||||
{
|
||||
INT32 workingtime = finalecount - TICRATE;
|
||||
fixed_t radius = ((vid.width/vid.dupx)*(INFLECTIONPOINT - TICRATE - workingtime))/(INFLECTIONPOINT - TICRATE);
|
||||
fixed_t radius = ((vid.width/vid.dup)*(INFLECTIONPOINT - TICRATE - workingtime))/(INFLECTIONPOINT - TICRATE);
|
||||
angle_t fa;
|
||||
INT32 eemeralds_cur[4];
|
||||
char patchname[7] = "CEMGx0";
|
||||
|
@ -2287,7 +2287,6 @@ void F_InitMenuPresValues(void)
|
|||
void F_SkyScroll(const char *patchname)
|
||||
{
|
||||
INT32 x, basey = 0;
|
||||
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
|
||||
patch_t *pat;
|
||||
|
||||
if (rendermode == render_none)
|
||||
|
@ -2315,17 +2314,17 @@ void F_SkyScroll(const char *patchname)
|
|||
curbgy %= pat->height * 16;
|
||||
|
||||
// Ooh, fancy frame interpolation
|
||||
x = ((curbgx*dupz) + FixedInt((rendertimefrac-FRACUNIT) * curbgxspeed*dupz)) / 16;
|
||||
basey = ((curbgy*dupz) + FixedInt((rendertimefrac-FRACUNIT) * curbgyspeed*dupz)) / 16;
|
||||
x = ((curbgx*vid.dup) + FixedInt((rendertimefrac-FRACUNIT) * curbgxspeed*vid.dup)) / 16;
|
||||
basey = ((curbgy*vid.dup) + FixedInt((rendertimefrac-FRACUNIT) * curbgyspeed*vid.dup)) / 16;
|
||||
|
||||
if (x > 0) // Make sure that we don't leave the left or top sides empty
|
||||
x -= pat->width * dupz;
|
||||
x -= pat->width * vid.dup;
|
||||
if (basey > 0)
|
||||
basey -= pat->height * dupz;
|
||||
basey -= pat->height * vid.dup;
|
||||
|
||||
for (; x < vid.width; x += pat->width * dupz)
|
||||
for (; x < vid.width; x += pat->width * vid.dup)
|
||||
{
|
||||
for (INT32 y = basey; y < vid.height; y += pat->height * dupz)
|
||||
for (INT32 y = basey; y < vid.height; y += pat->height * vid.dup)
|
||||
V_DrawScaledPatch(x, y, V_NOSCALESTART, pat);
|
||||
}
|
||||
|
||||
|
@ -2603,7 +2602,7 @@ static void F_LoadAlacroixGraphics(SINT8 newttscale)
|
|||
|
||||
static void F_FigureActiveTtScale(void)
|
||||
{
|
||||
SINT8 newttscale = max(1, min(6, vid.dupx));
|
||||
SINT8 newttscale = max(1, min(6, vid.dup));
|
||||
SINT8 oldttscale = activettscale;
|
||||
|
||||
if (newttscale == testttscale)
|
||||
|
@ -4095,7 +4094,7 @@ static fixed_t F_GetPromptHideHudBound(void)
|
|||
F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr);
|
||||
|
||||
// calc boxheight (see V_DrawPromptBack)
|
||||
boxh *= vid.dupy;
|
||||
boxh *= vid.dup;
|
||||
boxh = (boxh * 4) + (boxh/2)*5; // 4 lines of space plus gaps between and some leeway
|
||||
|
||||
// return a coordinate to check
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "filesrch.h"
|
||||
#include "d_netfil.h"
|
||||
#include "netcode/d_netfil.h"
|
||||
#include "m_misc.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_menu.h" // Addons_option_Onchange
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#define __FILESRCH_H__
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "d_netfil.h"
|
||||
#include "netcode/d_netfil.h"
|
||||
#include "m_menu.h" // MAXSTRINGLENGTH
|
||||
#include "w_wad.h"
|
||||
|
||||
|
|
102
src/g_demo.c
102
src/g_demo.c
|
@ -15,7 +15,7 @@
|
|||
#include "console.h"
|
||||
#include "d_main.h"
|
||||
#include "d_player.h"
|
||||
#include "d_clisrv.h"
|
||||
#include "netcode/d_clisrv.h"
|
||||
#include "p_setup.h"
|
||||
#include "i_time.h"
|
||||
#include "i_system.h"
|
||||
|
@ -39,7 +39,7 @@
|
|||
#include "v_video.h"
|
||||
#include "lua_hook.h"
|
||||
#include "md5.h" // demo checksums
|
||||
#include "d_netfil.h" // G_CheckDemoExtraFiles
|
||||
#include "netcode/d_netfil.h" // G_CheckDemoExtraFiles
|
||||
|
||||
boolean timingdemo; // if true, exit with report on completion
|
||||
boolean nodrawers; // for comparative timing purposes
|
||||
|
@ -1500,8 +1500,12 @@ void G_BeginRecording(void)
|
|||
demo_p += 16;
|
||||
|
||||
// Color
|
||||
for (i = 0; i < MAXCOLORNAME && cv_playercolor.string[i]; i++)
|
||||
name[i] = cv_playercolor.string[i];
|
||||
UINT16 skincolor = players[0].skincolor;
|
||||
if (skincolor >= numskincolors)
|
||||
skincolor = SKINCOLOR_NONE;
|
||||
const char *skincolor_name = skincolors[skincolor].name;
|
||||
for (i = 0; i < MAXCOLORNAME && skincolor_name[i]; i++)
|
||||
name[i] = skincolor_name[i];
|
||||
for (; i < MAXCOLORNAME; i++)
|
||||
name[i] = '\0';
|
||||
M_Memcpy(demo_p,name,MAXCOLORNAME);
|
||||
|
@ -1887,16 +1891,9 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
|||
p++; // VERSION
|
||||
p++; // SUBVERSION
|
||||
oldversion = READUINT16(p);
|
||||
switch(oldversion) // demoversion
|
||||
if (oldversion < 0x000c || oldversion > DEMOVERSION)
|
||||
{
|
||||
case DEMOVERSION: // latest always supported
|
||||
case 0x000f: // The previous demoversions also supported
|
||||
case 0x000e:
|
||||
case 0x000d: // all that changed between then and now was longer color name
|
||||
case 0x000c:
|
||||
break;
|
||||
// too old, cannot support.
|
||||
default:
|
||||
// too old (or new), cannot support
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("File '%s' invalid format. It will be overwritten.\n"), oldname);
|
||||
Z_Free(buffer);
|
||||
return UINT8_MAX;
|
||||
|
@ -1969,14 +1966,11 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
UINT8 i;
|
||||
lumpnum_t l;
|
||||
char skin[17],color[MAXCOLORNAME+1],*n,*pdemoname;
|
||||
UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration,cnamelen;
|
||||
UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration;
|
||||
pflags_t pflags;
|
||||
UINT32 randseed, followitem;
|
||||
fixed_t camerascale,shieldscale,actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor,height,spinheight;
|
||||
char msg[1024];
|
||||
#ifdef OLD22DEMOCOMPAT
|
||||
boolean use_old_demo_vars = false;
|
||||
#endif
|
||||
|
||||
skin[16] = '\0';
|
||||
color[MAXCOLORNAME] = '\0';
|
||||
|
@ -2035,23 +2029,13 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
subversion = READUINT8(demo_p);
|
||||
demoversion = READUINT16(demo_p);
|
||||
demo_forwardmove_rng = (demoversion < 0x0010);
|
||||
switch(demoversion)
|
||||
{
|
||||
case 0x000f:
|
||||
case 0x000d:
|
||||
case 0x000e:
|
||||
case DEMOVERSION: // latest always supported
|
||||
cnamelen = MAXCOLORNAME;
|
||||
break;
|
||||
#ifdef OLD22DEMOCOMPAT
|
||||
// all that changed between then and now was longer color name
|
||||
case 0x000c:
|
||||
cnamelen = 16;
|
||||
use_old_demo_vars = true;
|
||||
break;
|
||||
if (demoversion < 0x000c || demoversion > DEMOVERSION)
|
||||
#else
|
||||
if (demoversion < 0x000d || demoversion > DEMOVERSION)
|
||||
#endif
|
||||
// too old, cannot support.
|
||||
default:
|
||||
{
|
||||
// too old (or new), cannot support
|
||||
snprintf(msg, 1024, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
|
@ -2178,8 +2162,8 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
demo_p += 16;
|
||||
|
||||
// Color
|
||||
M_Memcpy(color,demo_p,cnamelen);
|
||||
demo_p += cnamelen;
|
||||
M_Memcpy(color, demo_p, (demoversion < 0x000d) ? 16 : MAXCOLORNAME);
|
||||
demo_p += (demoversion < 0x000d) ? 16 : MAXCOLORNAME;
|
||||
|
||||
charability = READUINT8(demo_p);
|
||||
charability2 = READUINT8(demo_p);
|
||||
|
@ -2215,7 +2199,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
|
||||
// net var data
|
||||
#ifdef OLD22DEMOCOMPAT
|
||||
if (use_old_demo_vars)
|
||||
if (demoversion < 0x000d)
|
||||
CV_LoadOldDemoVars(&demo_p);
|
||||
else
|
||||
#endif
|
||||
|
@ -2263,7 +2247,6 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
players[0].skincolor = i;
|
||||
break;
|
||||
}
|
||||
CV_StealthSetValue(&cv_playercolor, players[0].skincolor);
|
||||
if (players[0].mo)
|
||||
{
|
||||
players[0].mo->color = players[0].skincolor;
|
||||
|
@ -2349,19 +2332,13 @@ UINT8 G_CheckDemoForError(char *defdemoname)
|
|||
demo_p++; // version
|
||||
demo_p++; // subversion
|
||||
our_demo_version = READUINT16(demo_p);
|
||||
switch(our_demo_version)
|
||||
{
|
||||
case 0x000d:
|
||||
case 0x000e:
|
||||
case 0x000f:
|
||||
case DEMOVERSION: // latest always supported
|
||||
break;
|
||||
#ifdef OLD22DEMOCOMPAT
|
||||
case 0x000c:
|
||||
break;
|
||||
if (our_demo_version < 0x000c || our_demo_version > DEMOVERSION)
|
||||
#else
|
||||
if (our_demo_version < 0x000d || our_demo_version > DEMOVERSION)
|
||||
#endif
|
||||
// too old, cannot support.
|
||||
default:
|
||||
{
|
||||
// too old (or new), cannot support
|
||||
return DFILE_ERROR_NOTDEMO;
|
||||
}
|
||||
demo_p += 16; // demo checksum
|
||||
|
@ -2383,7 +2360,6 @@ void G_AddGhost(char *defdemoname)
|
|||
INT32 i;
|
||||
lumpnum_t l;
|
||||
char name[17],skin[17],color[MAXCOLORNAME+1],*n,*pdemoname,md5[16];
|
||||
UINT8 cnamelen;
|
||||
demoghost *gh;
|
||||
UINT8 flags, subversion;
|
||||
UINT8 *buffer,*p;
|
||||
|
@ -2435,20 +2411,9 @@ void G_AddGhost(char *defdemoname)
|
|||
p++; // VERSION
|
||||
subversion = READUINT8(p); // SUBVERSION
|
||||
ghostversion = READUINT16(p);
|
||||
switch(ghostversion)
|
||||
if (ghostversion < 0x000c || ghostversion > DEMOVERSION)
|
||||
{
|
||||
case 0x000f:
|
||||
case 0x000d:
|
||||
case 0x000e:
|
||||
case DEMOVERSION: // latest always supported
|
||||
cnamelen = MAXCOLORNAME;
|
||||
break;
|
||||
// all that changed between then and now was longer color name
|
||||
case 0x000c:
|
||||
cnamelen = 16;
|
||||
break;
|
||||
// too old, cannot support.
|
||||
default:
|
||||
// too old (or new), cannot support
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Demo version incompatible.\n"), pdemoname);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(buffer);
|
||||
|
@ -2511,8 +2476,8 @@ void G_AddGhost(char *defdemoname)
|
|||
p += 16;
|
||||
|
||||
// Color
|
||||
M_Memcpy(color, p,cnamelen);
|
||||
p += cnamelen;
|
||||
M_Memcpy(color, p, (ghostversion < 0x000d) ? 16 : MAXCOLORNAME);
|
||||
p += (ghostversion < 0x000d) ? 16 : MAXCOLORNAME;
|
||||
|
||||
// Ghosts do not have a player structure to put this in.
|
||||
p++; // charability
|
||||
|
@ -2695,16 +2660,9 @@ void G_DoPlayMetal(void)
|
|||
metal_p++; // VERSION
|
||||
metal_p++; // SUBVERSION
|
||||
metalversion = READUINT16(metal_p);
|
||||
switch(metalversion)
|
||||
if (metalversion < 0x000c || metalversion > DEMOVERSION)
|
||||
{
|
||||
case DEMOVERSION: // latest always supported
|
||||
case 0x000f:
|
||||
case 0x000e: // There are checks wheter the momentum is from older demo versions or not
|
||||
case 0x000d: // all that changed between then and now was longer color name
|
||||
case 0x000c:
|
||||
break;
|
||||
// too old, cannot support.
|
||||
default:
|
||||
// too old (or new), cannot support
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Failed to load bot recording for this map, format version incompatible.\n"));
|
||||
Z_Free(metalbuffer);
|
||||
return;
|
||||
|
|
43
src/g_game.c
43
src/g_game.c
|
@ -15,7 +15,8 @@
|
|||
#include "console.h"
|
||||
#include "d_main.h"
|
||||
#include "d_player.h"
|
||||
#include "d_clisrv.h"
|
||||
#include "netcode/d_clisrv.h"
|
||||
#include "netcode/net_command.h"
|
||||
#include "f_finale.h"
|
||||
#include "p_setup.h"
|
||||
#include "p_saveg.h"
|
||||
|
@ -55,6 +56,8 @@ gameaction_t gameaction;
|
|||
gamestate_t gamestate = GS_NULL;
|
||||
UINT8 ultimatemode = false;
|
||||
|
||||
INT32 pickedchar;
|
||||
|
||||
boolean botingame;
|
||||
UINT8 botskin;
|
||||
UINT16 botcolor;
|
||||
|
@ -2751,25 +2754,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
//if ((netgame || multiplayer) && !p->spectator) -- moved into P_SpawnPlayer to account for forced changes there
|
||||
//p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent
|
||||
|
||||
// Check to make sure their color didn't change somehow...
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
if (p->ctfteam == 1 && p->skincolor != skincolor_redteam)
|
||||
{
|
||||
if (p == &players[consoleplayer])
|
||||
CV_SetValue(&cv_playercolor, skincolor_redteam);
|
||||
else if (p == &players[secondarydisplayplayer])
|
||||
CV_SetValue(&cv_playercolor2, skincolor_redteam);
|
||||
}
|
||||
else if (p->ctfteam == 2 && p->skincolor != skincolor_blueteam)
|
||||
{
|
||||
if (p == &players[consoleplayer])
|
||||
CV_SetValue(&cv_playercolor, skincolor_blueteam);
|
||||
else if (p == &players[secondarydisplayplayer])
|
||||
CV_SetValue(&cv_playercolor2, skincolor_blueteam);
|
||||
}
|
||||
}
|
||||
|
||||
if (betweenmaps)
|
||||
return;
|
||||
|
||||
|
@ -4805,12 +4789,9 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
|
|||
Z_Free(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
|
||||
// gameaction = ga_nothing;
|
||||
// G_SetGamestate(GS_LEVEL);
|
||||
displayplayer = consoleplayer;
|
||||
multiplayer = splitscreen = false;
|
||||
|
||||
// G_DeferedInitNew(sk_medium, G_BuildMapName(1), 0, 0, 1);
|
||||
if (setsizeneeded)
|
||||
R_ExecuteSetViewSize();
|
||||
|
||||
|
@ -5003,9 +4984,9 @@ cleanup:
|
|||
// Can be called by the startup code or the menu task,
|
||||
// consoleplayer, displayplayer, playeringame[] should be set.
|
||||
//
|
||||
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, boolean SSSG, boolean FLS)
|
||||
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 character, boolean SSSG, boolean FLS)
|
||||
{
|
||||
UINT16 color = skins[pickedchar].prefcolor;
|
||||
pickedchar = character;
|
||||
paused = false;
|
||||
|
||||
if (demoplayback)
|
||||
|
@ -5026,10 +5007,7 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, b
|
|||
SplitScreen_OnChange();
|
||||
}
|
||||
|
||||
color = skins[pickedchar].prefcolor;
|
||||
SetPlayerSkinByNum(consoleplayer, pickedchar);
|
||||
CV_StealthSet(&cv_skin, skins[pickedchar].name);
|
||||
CV_StealthSetValue(&cv_playercolor, color);
|
||||
SetPlayerSkinByNum(consoleplayer, character);
|
||||
|
||||
if (mapname)
|
||||
D_MapChange(M_MapNumber(mapname[3], mapname[4]), gametype, pultmode, true, 1, false, FLS);
|
||||
|
@ -5109,6 +5087,10 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
|
|||
CV_StealthSetValue(&cv_itemfinder, 0);
|
||||
}
|
||||
|
||||
// Restore each player's skin if it was previously forced to be a specific one
|
||||
// (Looks a bit silly, but it works.)
|
||||
boolean reset_skin = netgame && mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0';
|
||||
|
||||
// internal game map
|
||||
// well this check is useless because it is done before (d_netcmd.c::command_map_f)
|
||||
// but in case of for demos....
|
||||
|
@ -5136,6 +5118,9 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
|
|||
automapactive = false;
|
||||
imcontinuing = false;
|
||||
|
||||
if (reset_skin)
|
||||
D_SendPlayerConfig();
|
||||
|
||||
// fetch saved data if available
|
||||
if (savedata.lives > 0)
|
||||
{
|
||||
|
|
|
@ -176,8 +176,7 @@ void G_SpawnPlayer(INT32 playernum);
|
|||
|
||||
// Can be called by the startup code or M_Responder.
|
||||
// A normal game starts at map 1, but a warp test can start elsewhere
|
||||
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar,
|
||||
boolean SSSG, boolean FLS);
|
||||
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 character, boolean SSSG, boolean FLS);
|
||||
void G_DoLoadLevel(boolean resetplayer);
|
||||
void G_StartTitleCard(void);
|
||||
void G_PreLevelTitleCard(void);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "g_input.h"
|
||||
#include "keys.h"
|
||||
#include "hu_stuff.h" // need HUFONT start & end
|
||||
#include "d_net.h"
|
||||
#include "netcode/d_net.h"
|
||||
#include "console.h"
|
||||
|
||||
#define MAXMOUSESENSITIVITY 100 // sensitivity steps
|
||||
|
|
|
@ -53,9 +53,11 @@ typedef enum
|
|||
|
||||
extern gamestate_t gamestate;
|
||||
extern UINT8 titlemapinaction;
|
||||
extern UINT8 ultimatemode; // was sk_insane
|
||||
extern UINT8 ultimatemode;
|
||||
extern gameaction_t gameaction;
|
||||
|
||||
extern INT32 pickedchar;
|
||||
|
||||
extern boolean botingame;
|
||||
extern UINT8 botskin;
|
||||
extern UINT16 botcolor;
|
||||
|
|
|
@ -78,10 +78,8 @@ void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option)
|
|||
// | /|
|
||||
// |/ |
|
||||
// 0--1
|
||||
float sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f;
|
||||
float sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f;
|
||||
float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f;
|
||||
float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f;
|
||||
float sdup = FIXED_TO_FLOAT(vid.fdup)*2.0f;
|
||||
float pdup = FIXED_TO_FLOAT(vid.fdup)*2.0f;
|
||||
|
||||
// make patch ready in hardware cache
|
||||
HWR_GetPatch(gpatch);
|
||||
|
@ -90,25 +88,23 @@ void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option)
|
|||
switch (option & V_SCALEPATCHMASK)
|
||||
{
|
||||
case V_NOSCALEPATCH:
|
||||
pdupx = pdupy = 2.0f;
|
||||
pdup = 2.0f;
|
||||
break;
|
||||
case V_SMALLSCALEPATCH:
|
||||
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupx);
|
||||
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupy);
|
||||
pdup = 2.0f * FIXED_TO_FLOAT(vid.fsmalldup);
|
||||
break;
|
||||
case V_MEDSCALEPATCH:
|
||||
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fmeddupx);
|
||||
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fmeddupy);
|
||||
pdup = 2.0f * FIXED_TO_FLOAT(vid.fmeddup);
|
||||
break;
|
||||
}
|
||||
|
||||
if (option & V_NOSCALESTART)
|
||||
sdupx = sdupy = 2.0f;
|
||||
sdup = 2.0f;
|
||||
|
||||
v[0].x = v[3].x = (x*sdupx-(gpatch->leftoffset)*pdupx)/vid.width - 1;
|
||||
v[2].x = v[1].x = (x*sdupx+(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1;
|
||||
v[0].y = v[1].y = 1-(y*sdupy-(gpatch->topoffset)*pdupy)/vid.height;
|
||||
v[2].y = v[3].y = 1-(y*sdupy+(gpatch->height-gpatch->topoffset)*pdupy)/vid.height;
|
||||
v[0].x = v[3].x = (x*sdup-(gpatch->leftoffset)*pdup)/vid.width - 1;
|
||||
v[2].x = v[1].x = (x*sdup+(gpatch->width-gpatch->leftoffset)*pdup)/vid.width - 1;
|
||||
v[0].y = v[1].y = 1-(y*sdup-(gpatch->topoffset)*pdup)/vid.height;
|
||||
v[2].y = v[3].y = 1-(y*sdup+(gpatch->height-gpatch->topoffset)*pdup)/vid.height;
|
||||
|
||||
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
||||
|
||||
|
@ -137,7 +133,7 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
|
|||
// | /|
|
||||
// |/ |
|
||||
// 0--1
|
||||
float dupx, dupy, fscalew, fscaleh, fwidth, fheight;
|
||||
float dup, fscalew, fscaleh, fwidth, fheight;
|
||||
|
||||
UINT8 perplayershuffle = 0;
|
||||
|
||||
|
@ -149,25 +145,21 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
|
|||
|
||||
hwrPatch = ((GLPatch_t *)gpatch->hardware);
|
||||
|
||||
dupx = (float)vid.dupx;
|
||||
dupy = (float)vid.dupy;
|
||||
dup = (float)vid.dup;
|
||||
|
||||
switch (option & V_SCALEPATCHMASK)
|
||||
{
|
||||
case V_NOSCALEPATCH:
|
||||
dupx = dupy = 1.0f;
|
||||
dup = 1.0f;
|
||||
break;
|
||||
case V_SMALLSCALEPATCH:
|
||||
dupx = (float)vid.smalldupx;
|
||||
dupy = (float)vid.smalldupy;
|
||||
dup = (float)vid.smalldup;
|
||||
break;
|
||||
case V_MEDSCALEPATCH:
|
||||
dupx = (float)vid.meddupx;
|
||||
dupy = (float)vid.meddupy;
|
||||
dup = (float)vid.meddup;
|
||||
break;
|
||||
}
|
||||
|
||||
dupx = dupy = (dupx < dupy ? dupx : dupy);
|
||||
fscalew = fscaleh = FIXED_TO_FLOAT(pscale);
|
||||
if (vscale != pscale)
|
||||
fscaleh = FIXED_TO_FLOAT(vscale);
|
||||
|
@ -261,8 +253,8 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
|
|||
|
||||
if (!(option & V_NOSCALESTART))
|
||||
{
|
||||
cx = cx * dupx;
|
||||
cy = cy * dupy;
|
||||
cx = cx * dup;
|
||||
cy = cy * dup;
|
||||
|
||||
if (!(option & V_SCALEPATCHMASK))
|
||||
{
|
||||
|
@ -279,40 +271,40 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
|
|||
}
|
||||
}
|
||||
// centre screen
|
||||
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
|
||||
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dup) > 1.0E-36f)
|
||||
{
|
||||
if (option & V_SNAPTORIGHT)
|
||||
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
|
||||
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dup));
|
||||
else if (!(option & V_SNAPTOLEFT))
|
||||
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
|
||||
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dup))/2;
|
||||
if (perplayershuffle & 4)
|
||||
cx -= ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/4;
|
||||
cx -= ((float)vid.width - ((float)BASEVIDWIDTH * dup))/4;
|
||||
else if (perplayershuffle & 8)
|
||||
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/4;
|
||||
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dup))/4;
|
||||
}
|
||||
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
|
||||
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dup) > 1.0E-36f)
|
||||
{
|
||||
if (option & V_SNAPTOBOTTOM)
|
||||
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
|
||||
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dup));
|
||||
else if (!(option & V_SNAPTOTOP))
|
||||
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2;
|
||||
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dup))/2;
|
||||
if (perplayershuffle & 1)
|
||||
cy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/4;
|
||||
cy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dup))/4;
|
||||
else if (perplayershuffle & 2)
|
||||
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/4;
|
||||
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dup))/4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pscale != FRACUNIT || vscale != FRACUNIT || (splitscreen && option & V_PERPLAYER))
|
||||
{
|
||||
fwidth = (float)(gpatch->width) * fscalew * dupx;
|
||||
fheight = (float)(gpatch->height) * fscaleh * dupy;
|
||||
fwidth = (float)(gpatch->width) * fscalew * dup;
|
||||
fheight = (float)(gpatch->height) * fscaleh * dup;
|
||||
}
|
||||
else
|
||||
{
|
||||
fwidth = (float)(gpatch->width) * dupx;
|
||||
fheight = (float)(gpatch->height) * dupy;
|
||||
fwidth = (float)(gpatch->width) * dup;
|
||||
fheight = (float)(gpatch->height) * dup;
|
||||
}
|
||||
|
||||
// positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
|
||||
|
@ -379,7 +371,7 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
|
|||
// | /|
|
||||
// |/ |
|
||||
// 0--1
|
||||
float dupx, dupy, fscalew, fscaleh, fwidth, fheight;
|
||||
float dup, fscalew, fscaleh, fwidth, fheight;
|
||||
|
||||
UINT8 perplayershuffle = 0;
|
||||
|
||||
|
@ -391,25 +383,21 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
|
|||
|
||||
hwrPatch = ((GLPatch_t *)gpatch->hardware);
|
||||
|
||||
dupx = (float)vid.dupx;
|
||||
dupy = (float)vid.dupy;
|
||||
dup = (float)vid.dup;
|
||||
|
||||
switch (option & V_SCALEPATCHMASK)
|
||||
{
|
||||
case V_NOSCALEPATCH:
|
||||
dupx = dupy = 1.0f;
|
||||
dup = 1.0f;
|
||||
break;
|
||||
case V_SMALLSCALEPATCH:
|
||||
dupx = (float)vid.smalldupx;
|
||||
dupy = (float)vid.smalldupy;
|
||||
dup = (float)vid.smalldup;
|
||||
break;
|
||||
case V_MEDSCALEPATCH:
|
||||
dupx = (float)vid.meddupx;
|
||||
dupy = (float)vid.meddupy;
|
||||
dup = (float)vid.meddup;
|
||||
break;
|
||||
}
|
||||
|
||||
dupx = dupy = (dupx < dupy ? dupx : dupy);
|
||||
fscalew = fscaleh = FIXED_TO_FLOAT(pscale);
|
||||
if (vscale != pscale)
|
||||
fscaleh = FIXED_TO_FLOAT(vscale);
|
||||
|
@ -487,8 +475,8 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
|
|||
|
||||
if (!(option & V_NOSCALESTART))
|
||||
{
|
||||
cx = cx * dupx;
|
||||
cy = cy * dupy;
|
||||
cx = cx * dup;
|
||||
cy = cy * dup;
|
||||
|
||||
if (!(option & V_SCALEPATCHMASK))
|
||||
{
|
||||
|
@ -496,27 +484,27 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
|
|||
// no the patch is cropped do not do this ever
|
||||
|
||||
// centre screen
|
||||
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
|
||||
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dup) > 1.0E-36f)
|
||||
{
|
||||
if (option & V_SNAPTORIGHT)
|
||||
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
|
||||
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dup));
|
||||
else if (!(option & V_SNAPTOLEFT))
|
||||
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
|
||||
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dup))/2;
|
||||
if (perplayershuffle & 4)
|
||||
cx -= ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/4;
|
||||
cx -= ((float)vid.width - ((float)BASEVIDWIDTH * dup))/4;
|
||||
else if (perplayershuffle & 8)
|
||||
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/4;
|
||||
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dup))/4;
|
||||
}
|
||||
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
|
||||
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dup) > 1.0E-36f)
|
||||
{
|
||||
if (option & V_SNAPTOBOTTOM)
|
||||
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
|
||||
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dup));
|
||||
else if (!(option & V_SNAPTOTOP))
|
||||
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2;
|
||||
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dup))/2;
|
||||
if (perplayershuffle & 1)
|
||||
cy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/4;
|
||||
cy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dup))/4;
|
||||
else if (perplayershuffle & 2)
|
||||
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/4;
|
||||
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dup))/4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -532,13 +520,13 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
|
|||
|
||||
if (pscale != FRACUNIT || vscale != FRACUNIT || (splitscreen && option & V_PERPLAYER))
|
||||
{
|
||||
fwidth *= fscalew * dupx;
|
||||
fheight *= fscaleh * dupy;
|
||||
fwidth *= fscalew * dup;
|
||||
fheight *= fscaleh * dup;
|
||||
}
|
||||
else
|
||||
{
|
||||
fwidth *= dupx;
|
||||
fheight *= dupy;
|
||||
fwidth *= dup;
|
||||
fheight *= dup;
|
||||
}
|
||||
|
||||
// positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
|
||||
|
@ -674,9 +662,9 @@ void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum)
|
|||
// 0--1
|
||||
|
||||
v[0].x = v[3].x = 2.0f * (float)x/vid.width - 1;
|
||||
v[2].x = v[1].x = 2.0f * (float)(x + patch->width*FIXED_TO_FLOAT(vid.fdupx))/vid.width - 1;
|
||||
v[2].x = v[1].x = 2.0f * (float)(x + patch->width*FIXED_TO_FLOAT(vid.fdup))/vid.width - 1;
|
||||
v[0].y = v[1].y = 1.0f - 2.0f * (float)y/vid.height;
|
||||
v[2].y = v[3].y = 1.0f - 2.0f * (float)(y + patch->height*FIXED_TO_FLOAT(vid.fdupy))/vid.height;
|
||||
v[2].y = v[3].y = 1.0f - 2.0f * (float)(y + patch->height*FIXED_TO_FLOAT(vid.fdup))/vid.height;
|
||||
|
||||
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
||||
|
||||
|
@ -866,35 +854,33 @@ void HWR_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT16 ac
|
|||
|
||||
if (!(color & V_NOSCALESTART))
|
||||
{
|
||||
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
|
||||
fx *= vid.dup;
|
||||
fy *= vid.dup;
|
||||
fw *= vid.dup;
|
||||
fh *= vid.dup;
|
||||
|
||||
fx *= dupx;
|
||||
fy *= dupy;
|
||||
fw *= dupx;
|
||||
fh *= dupy;
|
||||
|
||||
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
|
||||
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * vid.dup) > 1.0E-36f)
|
||||
{
|
||||
if (color & V_SNAPTORIGHT)
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * vid.dup));
|
||||
else if (!(color & V_SNAPTOLEFT))
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * vid.dup)) / 2;
|
||||
if (perplayershuffle & 4)
|
||||
fx -= ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
|
||||
fx -= ((float)vid.width - ((float)BASEVIDWIDTH * vid.dup)) / 4;
|
||||
else if (perplayershuffle & 8)
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * vid.dup)) / 4;
|
||||
}
|
||||
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
|
||||
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * vid.dup) > 1.0E-36f)
|
||||
{
|
||||
// same thing here
|
||||
if (color & V_SNAPTOBOTTOM)
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * vid.dup));
|
||||
else if (!(color & V_SNAPTOTOP))
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * vid.dup)) / 2;
|
||||
if (perplayershuffle & 1)
|
||||
fy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
|
||||
fy -= ((float)vid.height - ((float)BASEVIDHEIGHT * vid.dup)) / 4;
|
||||
else if (perplayershuffle & 2)
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * vid.dup)) / 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1032,10 +1018,10 @@ void HWR_DrawViewBorder(INT32 clearlines)
|
|||
clearlines = BASEVIDHEIGHT; // refresh all
|
||||
|
||||
// calc view size based on original game resolution
|
||||
baseviewwidth = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewwidth), vid.fdupx)); //(cv_viewsize.value * BASEVIDWIDTH/10)&~7;
|
||||
baseviewheight = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewheight), vid.fdupy));
|
||||
top = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_baseviewwindowy), vid.fdupy));
|
||||
side = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewwindowx), vid.fdupx));
|
||||
baseviewwidth = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewwidth), vid.fdup)); //(cv_viewsize.value * BASEVIDWIDTH/10)&~7;
|
||||
baseviewheight = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewheight), vid.fdup));
|
||||
top = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_baseviewwindowy), vid.fdup));
|
||||
side = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewwindowx), vid.fdup));
|
||||
|
||||
// top
|
||||
HWR_DrawFlatFill(0, 0,
|
||||
|
@ -1250,35 +1236,35 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT32
|
|||
|
||||
if (!(color & V_NOSCALESTART))
|
||||
{
|
||||
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
|
||||
float dup = (float)vid.dup;
|
||||
|
||||
fx *= dupx;
|
||||
fy *= dupy;
|
||||
fw *= dupx;
|
||||
fh *= dupy;
|
||||
fx *= dup;
|
||||
fy *= dup;
|
||||
fw *= dup;
|
||||
fh *= dup;
|
||||
|
||||
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
|
||||
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dup) > 1.0E-36f)
|
||||
{
|
||||
if (color & V_SNAPTORIGHT)
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dup));
|
||||
else if (!(color & V_SNAPTOLEFT))
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dup)) / 2;
|
||||
if (perplayershuffle & 4)
|
||||
fx -= ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
|
||||
fx -= ((float)vid.width - ((float)BASEVIDWIDTH * dup)) / 4;
|
||||
else if (perplayershuffle & 8)
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dup)) / 4;
|
||||
}
|
||||
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
|
||||
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dup) > 1.0E-36f)
|
||||
{
|
||||
// same thing here
|
||||
if (color & V_SNAPTOBOTTOM)
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dup));
|
||||
else if (!(color & V_SNAPTOTOP))
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dup)) / 2;
|
||||
if (perplayershuffle & 1)
|
||||
fy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
|
||||
fy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dup)) / 4;
|
||||
else if (perplayershuffle & 2)
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dup)) / 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1416,8 +1402,6 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
|
|||
|
||||
if (!(color & V_NOSCALESTART))
|
||||
{
|
||||
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
|
||||
|
||||
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
|
||||
{
|
||||
RGBA_t rgbaColour = V_GetColor(color);
|
||||
|
@ -1430,33 +1414,33 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
|
|||
return;
|
||||
}
|
||||
|
||||
fx *= dupx;
|
||||
fy *= dupy;
|
||||
fw *= dupx;
|
||||
fh *= dupy;
|
||||
fx *= vid.dup;
|
||||
fy *= vid.dup;
|
||||
fw *= vid.dup;
|
||||
fh *= vid.dup;
|
||||
|
||||
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
|
||||
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * vid.dup) > 1.0E-36f)
|
||||
{
|
||||
if (color & V_SNAPTORIGHT)
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * vid.dup));
|
||||
else if (!(color & V_SNAPTOLEFT))
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * vid.dup)) / 2;
|
||||
if (perplayershuffle & 4)
|
||||
fx -= ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
|
||||
fx -= ((float)vid.width - ((float)BASEVIDWIDTH * vid.dup)) / 4;
|
||||
else if (perplayershuffle & 8)
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * vid.dup)) / 4;
|
||||
}
|
||||
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
|
||||
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * vid.dup) > 1.0E-36f)
|
||||
{
|
||||
// same thing here
|
||||
if (color & V_SNAPTOBOTTOM)
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * vid.dup));
|
||||
else if (!(color & V_SNAPTOTOP))
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * vid.dup)) / 2;
|
||||
if (perplayershuffle & 1)
|
||||
fy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
|
||||
fy -= ((float)vid.height - ((float)BASEVIDHEIGHT * vid.dup)) / 4;
|
||||
else if (perplayershuffle & 2)
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * vid.dup)) / 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -341,6 +341,7 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_BMCH
|
||||
&lspr[NOLIGHT], // SPR_SMCE
|
||||
&lspr[NOLIGHT], // SPR_BMCE
|
||||
&lspr[NOLIGHT], // SPR_BSPB
|
||||
&lspr[NOLIGHT], // SPR_YSPB
|
||||
&lspr[NOLIGHT], // SPR_RSPB
|
||||
&lspr[REDBALL_L], // SPR_SFBR
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "../r_patch.h"
|
||||
#include "../r_picformats.h"
|
||||
#include "../r_bsp.h"
|
||||
#include "../d_clisrv.h"
|
||||
#include "../netcode/d_clisrv.h"
|
||||
#include "../w_wad.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../r_splats.h"
|
||||
|
@ -229,6 +229,8 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
|
|||
// Clamp the light level, since it can sometimes go out of the 0-255 range from animations
|
||||
light_level = min(max(light_level, 0), 255);
|
||||
|
||||
V_CubeApply(&tint_color.s.red, &tint_color.s.green, &tint_color.s.blue);
|
||||
V_CubeApply(&fade_color.s.red, &fade_color.s.green, &fade_color.s.blue);
|
||||
Surface->PolyColor.rgba = poly_color.rgba;
|
||||
Surface->TintColor.rgba = tint_color.rgba;
|
||||
Surface->FadeColor.rgba = fade_color.rgba;
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
#include "m_cond.h" // emblems
|
||||
#include "m_misc.h" // word jumping
|
||||
|
||||
#include "d_clisrv.h"
|
||||
#include "netcode/d_clisrv.h"
|
||||
#include "netcode/net_command.h"
|
||||
#include "netcode/gamestate.h"
|
||||
|
||||
#include "g_game.h"
|
||||
#include "g_input.h"
|
||||
|
@ -175,14 +177,12 @@ static huddrawlist_h luahuddrawlist_scores;
|
|||
|
||||
static tic_t resynch_ticker = 0;
|
||||
|
||||
#ifndef NONET
|
||||
// just after
|
||||
static void Command_Say_f(void);
|
||||
static void Command_Sayto_f(void);
|
||||
static void Command_Sayteam_f(void);
|
||||
static void Command_CSay_f(void);
|
||||
static void Got_Saycmd(UINT8 **p, INT32 playernum);
|
||||
#endif
|
||||
|
||||
void HU_LoadGraphics(void)
|
||||
{
|
||||
|
@ -327,13 +327,11 @@ void HU_LoadGraphics(void)
|
|||
//
|
||||
void HU_Init(void)
|
||||
{
|
||||
#ifndef NONET
|
||||
COM_AddCommand("say", Command_Say_f, COM_LUA);
|
||||
COM_AddCommand("sayto", Command_Sayto_f, COM_LUA);
|
||||
COM_AddCommand("sayteam", Command_Sayteam_f, COM_LUA);
|
||||
COM_AddCommand("csay", Command_CSay_f, COM_LUA);
|
||||
RegisterNetXCmd(XD_SAY, Got_Saycmd);
|
||||
#endif
|
||||
|
||||
// set shift translation table
|
||||
shiftxform = english_shiftxform;
|
||||
|
@ -363,8 +361,6 @@ void HU_Start(void)
|
|||
// EXECUTION
|
||||
//======================================================================
|
||||
|
||||
#ifndef NONET
|
||||
|
||||
// EVERY CHANGE IN THIS SCRIPT IS LOL XD! BY VINCYTM
|
||||
|
||||
static UINT32 chat_nummsg_log = 0;
|
||||
|
@ -412,11 +408,9 @@ static void HU_removeChatText_Log(void)
|
|||
}
|
||||
chat_nummsg_log--; // lost 1 msg.
|
||||
}
|
||||
#endif
|
||||
|
||||
void HU_AddChatText(const char *text, boolean playsound)
|
||||
{
|
||||
#ifndef NONET
|
||||
if (playsound && cv_consolechat.value != 2) // Don't play the sound if we're using hidden chat.
|
||||
S_StartSound(NULL, sfx_radio);
|
||||
// reguardless of our preferences, put all of this in the chat buffer in case we decide to change from oldchat mid-game.
|
||||
|
@ -438,14 +432,8 @@ void HU_AddChatText(const char *text, boolean playsound)
|
|||
CONS_Printf("%s\n", text);
|
||||
else // if we aren't, still save the message to log.txt
|
||||
CON_LogMessage(va("%s\n", text));
|
||||
#else
|
||||
(void)playsound;
|
||||
CONS_Printf("%s\n", text);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
|
||||
/** Runs a say command, sending an ::XD_SAY message.
|
||||
* A say command consists of a signed 8-bit integer for the target, an
|
||||
* unsigned 8-bit flag variable, and then the message itself.
|
||||
|
@ -865,8 +853,6 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
|||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
//
|
||||
void HU_Ticker(void)
|
||||
|
@ -882,7 +868,6 @@ void HU_Ticker(void)
|
|||
else
|
||||
hu_showscores = false;
|
||||
|
||||
#ifndef NONET
|
||||
if (chat_on)
|
||||
{
|
||||
// count down the scroll timer.
|
||||
|
@ -910,7 +895,6 @@ void HU_Ticker(void)
|
|||
HU_removeChatText_Mini();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cechotimer > 0) --cechotimer;
|
||||
|
||||
|
@ -918,8 +902,6 @@ void HU_Ticker(void)
|
|||
resynch_ticker++;
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
|
||||
static boolean teamtalk = false;
|
||||
static boolean justscrolleddown;
|
||||
static boolean justscrolledup;
|
||||
|
@ -1027,8 +1009,6 @@ static void HU_sendChatMessage(void)
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void HU_clearChatChars(void)
|
||||
{
|
||||
memset(w_chat, '\0', sizeof(w_chat));
|
||||
|
@ -1043,9 +1023,7 @@ void HU_clearChatChars(void)
|
|||
//
|
||||
boolean HU_Responder(event_t *ev)
|
||||
{
|
||||
#ifndef NONET
|
||||
INT32 c=0;
|
||||
#endif
|
||||
|
||||
if (ev->type != ev_keydown)
|
||||
return false;
|
||||
|
@ -1072,7 +1050,6 @@ boolean HU_Responder(event_t *ev)
|
|||
return false;
|
||||
}*/ //We don't actually care about that unless we get splitscreen netgames. :V
|
||||
|
||||
#ifndef NONET
|
||||
c = (INT32)ev->key;
|
||||
|
||||
if (!chat_on)
|
||||
|
@ -1222,7 +1199,6 @@ boolean HU_Responder(event_t *ev)
|
|||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1232,8 +1208,6 @@ boolean HU_Responder(event_t *ev)
|
|||
// HEADS UP DRAWING
|
||||
//======================================================================
|
||||
|
||||
#ifndef NONET
|
||||
|
||||
// Precompile a wordwrapped string to any given width.
|
||||
// This is a muuuch better method than V_WORDWRAP.
|
||||
// again stolen and modified a bit from video.c, don't mind me, will need to rearrange this one day.
|
||||
|
@ -1813,7 +1787,6 @@ static void HU_DrawChat_Old(void)
|
|||
if (hu_tick < 4)
|
||||
V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Draw crosshairs at the exact center of the view.
|
||||
// In splitscreen, crosshairs are stretched vertically to compensate for V_PERPLAYER squishing them.
|
||||
|
@ -1953,7 +1926,6 @@ static void HU_DrawDemoInfo(void)
|
|||
//
|
||||
void HU_Drawer(void)
|
||||
{
|
||||
#ifndef NONET
|
||||
// draw chat string plus cursor
|
||||
if (chat_on)
|
||||
{
|
||||
|
@ -1970,7 +1942,6 @@ void HU_Drawer(void)
|
|||
if (!OLDCHAT && cv_consolechat.value < 2 && netgame) // Don't display minimized chat if you set the mode to Window (Hidden)
|
||||
HU_drawMiniChat(); // draw messages in a cool fashion.
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cechotimer)
|
||||
HU_DrawCEcho();
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#include "command.h"
|
||||
#include "doomtype.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "netcode/d_netcmd.h"
|
||||
#include "m_fixed.h"
|
||||
#include "i_system.h"
|
||||
|
||||
|
|
35
src/info.c
35
src/info.c
|
@ -250,6 +250,7 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"BMCH", // Big Mace Chain
|
||||
"SMCE", // Small Mace
|
||||
"BMCE", // Big Mace
|
||||
"BSPB", // Blue spring on a ball
|
||||
"YSPB", // Yellow spring on a ball
|
||||
"RSPB", // Red spring on a ball
|
||||
"SFBR", // Small Firebar
|
||||
|
@ -2297,6 +2298,13 @@ state_t states[NUMSTATES] =
|
|||
{SPR_SMCH, 1, -1, {NULL}, 0, 0, S_NULL}, // S_SMALLGRABCHAIN
|
||||
{SPR_BMCH, 1, -1, {NULL}, 0, 0, S_NULL}, // S_BIGGRABCHAIN
|
||||
|
||||
// Blue spring on a ball
|
||||
{SPR_BSPB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPRINGBALL
|
||||
{SPR_BSPB, 4, 4, {A_Pain}, 0, 0, S_BLUESPRINGBALL3}, // S_BLUESPRINGBALL2
|
||||
{SPR_BSPB, 3, 1, {NULL}, 0, 0, S_BLUESPRINGBALL4}, // S_BLUESPRINGBALL3
|
||||
{SPR_BSPB, 2, 1, {NULL}, 0, 0, S_BLUESPRINGBALL5}, // S_BLUESPRINGBALL4
|
||||
{SPR_BSPB, 1, 1, {NULL}, 0, 0, S_BLUESPRINGBALL}, // S_BLUESPRINGBALL5
|
||||
|
||||
// Yellow spring on a ball
|
||||
{SPR_YSPB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YELLOWSPRINGBALL
|
||||
{SPR_YSPB, 4, 4, {A_Pain}, 0, 0, S_YELLOWSPRINGBALL3}, // S_YELLOWSPRINGBALL2
|
||||
|
@ -11679,6 +11687,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_BLUESPRINGBALL
|
||||
1133, // doomednum
|
||||
S_BLUESPRINGBALL, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_BLUESPRINGBALL2, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_spring, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
24*FRACUNIT, // speed
|
||||
17*FRACUNIT, // radius
|
||||
34*FRACUNIT, // height
|
||||
1, // display offset
|
||||
11*FRACUNIT, // mass
|
||||
0, // damage
|
||||
sfx_mswing, // activesound
|
||||
MF_SCENERY|MF_SPRING|MF_NOGRAVITY, // flags
|
||||
S_BLUESPRINGBALL2 // raisestate
|
||||
},
|
||||
|
||||
{ // MT_YELLOWSPRINGBALL
|
||||
1134, // doomednum
|
||||
S_YELLOWSPRINGBALL, // spawnstate
|
||||
|
|
|
@ -797,6 +797,7 @@ typedef enum sprite
|
|||
SPR_BMCH, // Big Mace Chain
|
||||
SPR_SMCE, // Small Mace
|
||||
SPR_BMCE, // Big Mace
|
||||
SPR_BSPB, // Blue spring on a ball
|
||||
SPR_YSPB, // Yellow spring on a ball
|
||||
SPR_RSPB, // Red spring on a ball
|
||||
SPR_SFBR, // Small Firebar
|
||||
|
@ -2744,6 +2745,13 @@ typedef enum state
|
|||
S_SMALLGRABCHAIN,
|
||||
S_BIGGRABCHAIN,
|
||||
|
||||
// Blue spring on a ball
|
||||
S_BLUESPRINGBALL,
|
||||
S_BLUESPRINGBALL2,
|
||||
S_BLUESPRINGBALL3,
|
||||
S_BLUESPRINGBALL4,
|
||||
S_BLUESPRINGBALL5,
|
||||
|
||||
// Yellow spring on a ball
|
||||
S_YELLOWSPRINGBALL,
|
||||
S_YELLOWSPRINGBALL2,
|
||||
|
@ -4722,6 +4730,7 @@ typedef enum mobj_type
|
|||
MT_BIGMACE, // Big Mace
|
||||
MT_SMALLGRABCHAIN, // Small Grab Chain
|
||||
MT_BIGGRABCHAIN, // Big Grab Chain
|
||||
MT_BLUESPRINGBALL, // Blue spring on a ball
|
||||
MT_YELLOWSPRINGBALL, // Yellow spring on a ball
|
||||
MT_REDSPRINGBALL, // Red spring on a ball
|
||||
MT_SMALLFIREBAR, // Small Firebar
|
||||
|
|
|
@ -26,11 +26,11 @@
|
|||
#include "y_inter.h"
|
||||
#include "hu_stuff.h" // HU_AddChatText
|
||||
#include "console.h"
|
||||
#include "d_netcmd.h" // IsPlayerAdmin
|
||||
#include "netcode/d_netcmd.h" // IsPlayerAdmin
|
||||
#include "m_menu.h" // Player Setup menu color stuff
|
||||
#include "m_misc.h" // M_MapNumber
|
||||
#include "b_bot.h" // B_UpdateBotleader
|
||||
#include "d_clisrv.h" // CL_RemovePlayer
|
||||
#include "netcode/d_clisrv.h" // CL_RemovePlayer
|
||||
#include "i_system.h" // I_GetPreciseTime, I_GetPrecisePrecision
|
||||
|
||||
#include "lua_script.h"
|
||||
|
@ -1567,6 +1567,19 @@ static int lib_pInstaThrust(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pInstaThrustEvenIn2D(lua_State *L)
|
||||
{
|
||||
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
angle_t angle = luaL_checkangle(L, 2);
|
||||
fixed_t move = luaL_checkfixed(L, 3);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!mo)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
P_InstaThrustEvenIn2D(mo, angle, move);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pReturnThrustX(lua_State *L)
|
||||
{
|
||||
angle_t angle;
|
||||
|
@ -2214,6 +2227,40 @@ static int lib_pThrust(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pThrustEvenIn2D(lua_State *L)
|
||||
{
|
||||
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
angle_t angle = luaL_checkangle(L, 2);
|
||||
fixed_t move = luaL_checkfixed(L, 3);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!mo)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
P_ThrustEvenIn2D(mo, angle, move);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pVectorInstaThrust(lua_State *L)
|
||||
{
|
||||
fixed_t xa = luaL_checkfixed(L, 1);
|
||||
fixed_t xb = luaL_checkfixed(L, 2);
|
||||
fixed_t xc = luaL_checkfixed(L, 3);
|
||||
fixed_t ya = luaL_checkfixed(L, 4);
|
||||
fixed_t yb = luaL_checkfixed(L, 5);
|
||||
fixed_t yc = luaL_checkfixed(L, 6);
|
||||
fixed_t za = luaL_checkfixed(L, 7);
|
||||
fixed_t zb = luaL_checkfixed(L, 8);
|
||||
fixed_t zc = luaL_checkfixed(L, 9);
|
||||
fixed_t momentum = luaL_checkfixed(L, 10);
|
||||
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 11, META_MOBJ));
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!mo)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
P_VectorInstaThrust(xa, xb, xc, ya, yb, yc, za, zb, zc, momentum, mo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pSetMobjStateNF(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
|
@ -4123,6 +4170,7 @@ static luaL_Reg lib[] = {
|
|||
{"P_DoPlayerFinish",lib_pDoPlayerFinish},
|
||||
{"P_DoPlayerExit",lib_pDoPlayerExit},
|
||||
{"P_InstaThrust",lib_pInstaThrust},
|
||||
{"P_InstaThrustEvenIn2D",lib_pInstaThrustEvenIn2D},
|
||||
{"P_ReturnThrustX",lib_pReturnThrustX},
|
||||
{"P_ReturnThrustY",lib_pReturnThrustY},
|
||||
{"P_LookForEnemies",lib_pLookForEnemies},
|
||||
|
@ -4176,6 +4224,8 @@ static luaL_Reg lib[] = {
|
|||
|
||||
// p_spec
|
||||
{"P_Thrust",lib_pThrust},
|
||||
{"P_ThrustEvenIn2D",lib_pThrustEvenIn2D},
|
||||
{"P_VectorInstaThrust",lib_pVectorInstaThrust},
|
||||
{"P_SetMobjStateNF",lib_pSetMobjStateNF},
|
||||
{"P_DoSuperTransformation",lib_pDoSuperTransformation},
|
||||
{"P_ExplodeMissile",lib_pExplodeMissile},
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "g_game.h"
|
||||
#include "byteptr.h"
|
||||
#include "z_zone.h"
|
||||
#include "netcode/net_command.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "lua_hud.h" // hud_running errors
|
||||
|
||||
#include "m_perfstats.h"
|
||||
#include "d_netcmd.h" // for cv_perfstats
|
||||
#include "netcode/d_netcmd.h" // for cv_perfstats
|
||||
#include "i_system.h" // I_GetPreciseTime
|
||||
|
||||
/* =========================================================================
|
||||
|
|
|
@ -1206,19 +1206,11 @@ static int libd_height(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int libd_dupx(lua_State *L)
|
||||
static int libd_dup(lua_State *L)
|
||||
{
|
||||
HUDONLY
|
||||
lua_pushinteger(L, vid.dupx); // push integral scale (patch scale)
|
||||
lua_pushfixed(L, vid.fdupx); // push fixed point scale (position scale)
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int libd_dupy(lua_State *L)
|
||||
{
|
||||
HUDONLY
|
||||
lua_pushinteger(L, vid.dupy); // push integral scale (patch scale)
|
||||
lua_pushfixed(L, vid.fdupy); // push fixed point scale (position scale)
|
||||
lua_pushinteger(L, vid.dup); // push integral scale (patch scale)
|
||||
lua_pushfixed(L, vid.fdup); // push fixed point scale (position scale)
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
@ -1338,8 +1330,8 @@ static luaL_Reg lib_draw[] = {
|
|||
// properties
|
||||
{"width", libd_width},
|
||||
{"height", libd_height},
|
||||
{"dupx", libd_dupx},
|
||||
{"dupy", libd_dupy},
|
||||
{"dupx", libd_dup},
|
||||
{"dupy", libd_dup},
|
||||
{"renderer", libd_renderer},
|
||||
{"localTransFlag", libd_getlocaltransflag},
|
||||
{"userTransFlag", libd_getusertransflag},
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "p_slopes.h" // for P_SlopeById and slopelist
|
||||
#include "p_polyobj.h" // polyobj_t, PolyObjects
|
||||
#ifdef LUA_ALLOW_BYTECODE
|
||||
#include "d_netfil.h" // for LUA_DumpFile
|
||||
#include "netcode/d_netfil.h" // for LUA_DumpFile
|
||||
#endif
|
||||
|
||||
#include "lua_script.h"
|
||||
|
|
|
@ -462,7 +462,7 @@ static void GIF_headwrite(void)
|
|||
// Image width/height
|
||||
if (gif_downscale)
|
||||
{
|
||||
scrbuf_downscaleamt = vid.dupx;
|
||||
scrbuf_downscaleamt = vid.dup;
|
||||
rwidth = (vid.width / scrbuf_downscaleamt);
|
||||
rheight = (vid.height / scrbuf_downscaleamt);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "r_local.h"
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "d_net.h"
|
||||
#include "netcode/d_net.h"
|
||||
|
||||
#include "m_cheat.h"
|
||||
#include "m_menu.h"
|
||||
|
|
|
@ -509,7 +509,7 @@ UINT8 M_CampaignWarpIsCheat(INT32 gt, INT32 mapnum, gamedata_t *data)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (mapheaderinfo[mapnum-1]->menuflags & LF2_HIDEINMENU)
|
||||
if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->menuflags & LF2_HIDEINMENU)
|
||||
{
|
||||
// You're never allowed to warp to this level.
|
||||
return true;
|
||||
|
|
139
src/m_menu.c
139
src/m_menu.c
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "doomdef.h"
|
||||
#include "d_main.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "netcode/d_netcmd.h"
|
||||
#include "console.h"
|
||||
#include "r_fps.h"
|
||||
#include "r_local.h"
|
||||
|
@ -53,8 +53,10 @@
|
|||
#include "hardware/hw_main.h"
|
||||
#endif
|
||||
|
||||
#include "d_net.h"
|
||||
#include "mserv.h"
|
||||
#include "netcode/d_net.h"
|
||||
#include "netcode/mserv.h"
|
||||
#include "netcode/server_connection.h"
|
||||
#include "netcode/client_connection.h"
|
||||
#include "m_misc.h"
|
||||
#include "m_anigif.h"
|
||||
#include "byteptr.h"
|
||||
|
@ -149,9 +151,7 @@ levellist_mode_t levellistmode = LLM_CREATESERVER;
|
|||
UINT8 maplistoption = 0;
|
||||
|
||||
static char joystickInfo[MAX_JOYSTICKS+1][29];
|
||||
#ifndef NONET
|
||||
static UINT32 serverlistpage;
|
||||
#endif
|
||||
|
||||
static UINT8 numsaves = 0;
|
||||
static saveinfo_t* savegameinfo = NULL; // Extra info about the save games.
|
||||
|
@ -190,10 +190,8 @@ static void M_GoBack(INT32 choice);
|
|||
static void M_StopMessage(INT32 choice);
|
||||
static boolean stopstopmessage = false;
|
||||
|
||||
#ifndef NONET
|
||||
static void M_HandleServerPage(INT32 choice);
|
||||
static void M_RoomMenu(INT32 choice);
|
||||
#endif
|
||||
|
||||
// Prototyping is fun, innit?
|
||||
// ==========================================================================
|
||||
|
@ -216,7 +214,7 @@ static fixed_t lsoffs[2];
|
|||
#define lshli levelselectselect[2]
|
||||
|
||||
#define lshseperation 101
|
||||
#define lsbasevseperation ((62*vid.height)/(BASEVIDHEIGHT*vid.dupy)) //62
|
||||
#define lsbasevseperation ((62*vid.height)/(BASEVIDHEIGHT*vid.dup)) //62
|
||||
#define lsheadingheight 16
|
||||
#define getheadingoffset(row) (levelselect.rows[row].header[0] ? lsheadingheight : 0)
|
||||
#define lsvseperation(row) (lsbasevseperation + getheadingoffset(row))
|
||||
|
@ -296,7 +294,6 @@ static void M_SetupMultiPlayer2(INT32 choice);
|
|||
static void M_StartSplitServerMenu(INT32 choice);
|
||||
static void M_StartServer(INT32 choice);
|
||||
static void M_ServerOptions(INT32 choice);
|
||||
#ifndef NONET
|
||||
static void M_StartServerMenu(INT32 choice);
|
||||
static void M_ConnectMenu(INT32 choice);
|
||||
static void M_ConnectMenuModChecks(INT32 choice);
|
||||
|
@ -304,7 +301,6 @@ static void M_Refresh(INT32 choice);
|
|||
static void M_Connect(INT32 choice);
|
||||
static void M_ChooseRoom(INT32 choice);
|
||||
menu_t MP_MainDef;
|
||||
#endif
|
||||
|
||||
// Options
|
||||
// Split into multiple parts due to size
|
||||
|
@ -382,11 +378,9 @@ static void M_DrawVideoMode(void);
|
|||
static void M_DrawColorMenu(void);
|
||||
static void M_DrawScreenshotMenu(void);
|
||||
static void M_DrawMonitorToggles(void);
|
||||
#ifndef NONET
|
||||
static void M_DrawConnectMenu(void);
|
||||
static void M_DrawMPMainMenu(void);
|
||||
static void M_DrawRoomMenu(void);
|
||||
#endif
|
||||
static void M_DrawJoystick(void);
|
||||
static void M_DrawSetupMultiPlayerMenu(void);
|
||||
static void M_DrawColorRamp(INT32 x, INT32 y, INT32 w, INT32 h, skincolor_t color);
|
||||
|
@ -401,10 +395,8 @@ static void M_HandleImageDef(INT32 choice);
|
|||
static void M_HandleLoadSave(INT32 choice);
|
||||
static void M_HandleLevelStats(INT32 choice);
|
||||
static void M_HandlePlaystyleMenu(INT32 choice);
|
||||
#ifndef NONET
|
||||
static boolean M_CancelConnect(void);
|
||||
static void M_HandleConnectIP(INT32 choice);
|
||||
#endif
|
||||
static void M_HandleSetupMultiPlayer(INT32 choice);
|
||||
static void M_HandleVideoMode(INT32 choice);
|
||||
|
||||
|
@ -503,11 +495,7 @@ consvar_t cv_dummyloadless = CVAR_INIT ("dummyloadless", "In-game", CV_HIDEN, lo
|
|||
static menuitem_t MainMenu[] =
|
||||
{
|
||||
{IT_STRING|IT_CALL, NULL, "1 Player", M_SinglePlayerMenu, 76},
|
||||
#ifndef NONET
|
||||
{IT_STRING|IT_SUBMENU, NULL, "Multiplayer", &MP_MainDef, 84},
|
||||
#else
|
||||
{IT_STRING|IT_CALL, NULL, "Multiplayer", M_StartSplitServerMenu, 84},
|
||||
#endif
|
||||
{IT_STRING|IT_CALL, NULL, "Extras", M_SecretsMenu, 92},
|
||||
{IT_CALL |IT_STRING, NULL, "Addons", M_Addons, 100},
|
||||
{IT_STRING|IT_CALL, NULL, "Options", M_Options, 108},
|
||||
|
@ -930,16 +918,10 @@ static menuitem_t SP_PlayerMenu[] =
|
|||
static menuitem_t MP_SplitServerMenu[] =
|
||||
{
|
||||
{IT_STRING|IT_CALL, NULL, "Select Gametype/Level...", M_MapChange, 100},
|
||||
#ifdef NONET // In order to keep player setup accessible.
|
||||
{IT_STRING|IT_CALL, NULL, "Player 1 setup...", M_SetupMultiPlayer, 110},
|
||||
{IT_STRING|IT_CALL, NULL, "Player 2 setup...", M_SetupMultiPlayer2, 120},
|
||||
#endif
|
||||
{IT_STRING|IT_CALL, NULL, "More Options...", M_ServerOptions, 130},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 140},
|
||||
};
|
||||
|
||||
#ifndef NONET
|
||||
|
||||
static menuitem_t MP_MainMenu[] =
|
||||
{
|
||||
{IT_HEADER, NULL, "Join a game", NULL, 0},
|
||||
|
@ -1026,8 +1008,6 @@ menuitem_t MP_RoomMenu[] =
|
|||
{IT_DISABLED, NULL, "", M_ChooseRoom, 162},
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static menuitem_t MP_PlayerSetupMenu[] =
|
||||
{
|
||||
{IT_KEYHANDLER, NULL, "", M_HandleSetupMultiPlayer, 0}, // name
|
||||
|
@ -1586,14 +1566,12 @@ enum
|
|||
static menuitem_t OP_ServerOptionsMenu[] =
|
||||
{
|
||||
{IT_HEADER, NULL, "General", NULL, 0},
|
||||
#ifndef NONET
|
||||
{IT_STRING | IT_CVAR | IT_CV_STRING,
|
||||
NULL, "Server name", &cv_servername, 7},
|
||||
{IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 21},
|
||||
{IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26},
|
||||
{IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 31},
|
||||
{IT_STRING | IT_CVAR, NULL, "Minutes for reconnecting", &cv_rejointimeout, 36},
|
||||
#endif
|
||||
{IT_STRING | IT_CVAR, NULL, "Map progression", &cv_advancemap, 41},
|
||||
{IT_STRING | IT_CVAR, NULL, "Intermission Timer", &cv_inttime, 46},
|
||||
|
||||
|
@ -1632,7 +1610,6 @@ static menuitem_t OP_ServerOptionsMenu[] =
|
|||
{IT_STRING | IT_CVAR, NULL, "Autobalance sizes", &cv_autobalance, 216},
|
||||
{IT_STRING | IT_CVAR, NULL, "Scramble on Map Change", &cv_scrambleonchange, 221},
|
||||
|
||||
#ifndef NONET
|
||||
{IT_HEADER, NULL, "Advanced", NULL, 230},
|
||||
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 236},
|
||||
|
||||
|
@ -1640,7 +1617,6 @@ static menuitem_t OP_ServerOptionsMenu[] =
|
|||
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 256},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Show IP Address of Joiners", &cv_showjoinaddress, 261},
|
||||
#endif
|
||||
};
|
||||
|
||||
static menuitem_t OP_MonitorToggleMenu[] =
|
||||
|
@ -1954,11 +1930,7 @@ menu_t MP_SplitServerDef =
|
|||
MTREE2(MN_MP_MAIN, MN_MP_SPLITSCREEN),
|
||||
"M_MULTI",
|
||||
sizeof (MP_SplitServerMenu)/sizeof (menuitem_t),
|
||||
#ifndef NONET
|
||||
&MP_MainDef,
|
||||
#else
|
||||
&MainDef,
|
||||
#endif
|
||||
MP_SplitServerMenu,
|
||||
M_DrawServerMenu,
|
||||
27, 30 - 50,
|
||||
|
@ -1966,8 +1938,6 @@ menu_t MP_SplitServerDef =
|
|||
NULL
|
||||
};
|
||||
|
||||
#ifndef NONET
|
||||
|
||||
menu_t MP_MainDef =
|
||||
{
|
||||
MN_MP_MAIN,
|
||||
|
@ -2019,15 +1989,10 @@ menu_t MP_RoomDef =
|
|||
0,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
menu_t MP_PlayerSetupDef =
|
||||
{
|
||||
#ifdef NONET
|
||||
MTREE2(MN_MP_MAIN, MN_MP_PLAYERSETUP),
|
||||
#else
|
||||
MTREE3(MN_MP_MAIN, MN_MP_SPLITSCREEN, MN_MP_PLAYERSETUP),
|
||||
#endif
|
||||
"M_SPLAYR",
|
||||
sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t),
|
||||
&MainDef, // doesn't matter
|
||||
|
@ -2787,6 +2752,7 @@ void M_SetMenuCurBackground(const char *defaultname)
|
|||
{
|
||||
char name[9];
|
||||
strncpy(name, defaultname, 8);
|
||||
name[8] = '\0';
|
||||
M_IterateMenuTree(MIT_SetCurBackground, &name);
|
||||
}
|
||||
|
||||
|
@ -3608,16 +3574,16 @@ void M_Drawer(void)
|
|||
{
|
||||
if (customversionstring[0] != '\0')
|
||||
{
|
||||
V_DrawThinString(vid.dupx, vid.height - 17*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT, "Mod version:");
|
||||
V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, customversionstring);
|
||||
V_DrawThinString(vid.dup, vid.height - 17*vid.dup, V_NOSCALESTART|V_TRANSLUCENT, "Mod version:");
|
||||
V_DrawThinString(vid.dup, vid.height - 9*vid.dup, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, customversionstring);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEVELOP // Development -- show revision / branch info
|
||||
V_DrawThinString(vid.dupx, vid.height - 17*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, compbranch);
|
||||
V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, comprevision);
|
||||
V_DrawThinString(vid.dup, vid.height - 17*vid.dup, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, compbranch);
|
||||
V_DrawThinString(vid.dup, vid.height - 9*vid.dup, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, comprevision);
|
||||
#else // Regular build
|
||||
V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s", VERSIONSTRING));
|
||||
V_DrawThinString(vid.dup, vid.height - 9*vid.dup, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s", VERSIONSTRING));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -3956,9 +3922,7 @@ void M_Init(void)
|
|||
OP_JoystickSetMenu[i].itemaction = M_AssignJoystick;
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
CV_RegisterVar(&cv_serversort);
|
||||
#endif
|
||||
}
|
||||
|
||||
void M_InitCharacterTables(void)
|
||||
|
@ -5793,16 +5757,15 @@ static void M_DrawRecordAttackForeground(void)
|
|||
|
||||
INT32 i;
|
||||
INT32 height = (fg->height / 2);
|
||||
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
|
||||
|
||||
for (i = -12; i < (BASEVIDHEIGHT/height) + 12; i++)
|
||||
{
|
||||
INT32 y = ((i*height) - (height - ((FixedInt(recatkdrawtimer*2))%height)));
|
||||
// don't draw above the screen
|
||||
{
|
||||
INT32 sy = FixedMul(y, dupz<<FRACBITS) >> FRACBITS;
|
||||
if (vid.height != BASEVIDHEIGHT * dupz)
|
||||
sy += (vid.height - (BASEVIDHEIGHT * dupz)) / 2;
|
||||
INT32 sy = FixedMul(y, vid.dup<<FRACBITS) >> FRACBITS;
|
||||
if (vid.height != BASEVIDHEIGHT * vid.dup)
|
||||
sy += (vid.height - (BASEVIDHEIGHT * vid.dup)) / 2;
|
||||
if ((sy+height) < 0)
|
||||
continue;
|
||||
}
|
||||
|
@ -5826,13 +5789,12 @@ static void M_DrawRecordAttackForeground(void)
|
|||
static void M_DrawNightsAttackMountains(void)
|
||||
{
|
||||
static fixed_t bgscrollx;
|
||||
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
|
||||
patch_t *background = W_CachePatchName(curbgname, PU_PATCH);
|
||||
INT16 w = background->width;
|
||||
INT32 x = FixedInt(-bgscrollx) % w;
|
||||
INT32 y = BASEVIDHEIGHT - (background->height * 2);
|
||||
|
||||
if (vid.height != BASEVIDHEIGHT * dupz)
|
||||
if (vid.height != BASEVIDHEIGHT * vid.dup)
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 158);
|
||||
V_DrawFill(0, y+50, vid.width, BASEVIDHEIGHT, V_SNAPTOLEFT|31);
|
||||
|
||||
|
@ -5988,7 +5950,7 @@ static void M_DrawLevelPlatterMenu(void)
|
|||
}
|
||||
|
||||
// draw from top to bottom
|
||||
while (y < (vid.height/vid.dupy))
|
||||
while (y < (vid.height/vid.dup))
|
||||
{
|
||||
M_DrawLevelPlatterRow(iter, y);
|
||||
y += lsvseperation(iter);
|
||||
|
@ -7835,9 +7797,9 @@ static void M_DrawSoundTest(void)
|
|||
}
|
||||
}
|
||||
|
||||
y = (BASEVIDWIDTH-(vid.width/vid.dupx))/2;
|
||||
y = (BASEVIDWIDTH-(vid.width/vid.dup))/2;
|
||||
|
||||
V_DrawFill(y, 20, vid.width/vid.dupx, 24, 159);
|
||||
V_DrawFill(y, 20, vid.width/vid.dup, 24, 159);
|
||||
{
|
||||
static fixed_t st_scroll = -FRACUNIT;
|
||||
const char* titl;
|
||||
|
@ -8407,8 +8369,8 @@ static void M_DrawLoadGameData(void)
|
|||
INT32 i, prev_i = 1, savetodraw, x, y, hsep = 90;
|
||||
skin_t *charskin = NULL;
|
||||
|
||||
if (vid.width != BASEVIDWIDTH*vid.dupx)
|
||||
hsep = (hsep*vid.width)/(BASEVIDWIDTH*vid.dupx);
|
||||
if (vid.width != BASEVIDWIDTH*vid.dup)
|
||||
hsep = (hsep*vid.width)/(BASEVIDWIDTH*vid.dup);
|
||||
|
||||
for (i = 2; prev_i; i = -(i + ((UINT32)i >> 31))) // draws from outwards in; 2, -2, 1, -1, 0
|
||||
{
|
||||
|
@ -9393,7 +9355,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
|
|||
INT16 bgwidth = charbg->width;
|
||||
INT16 fgwidth = charfg->width;
|
||||
INT32 x, y;
|
||||
INT32 w = (vid.width/vid.dupx);
|
||||
INT32 w = (vid.width/vid.dup);
|
||||
|
||||
if (abs(char_scroll) > FRACUNIT/4)
|
||||
char_scroll -= FixedMul((char_scroll>>2), renderdeltatics);
|
||||
|
@ -9429,7 +9391,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
|
|||
// Background and borders
|
||||
V_DrawFill(0, 0, bgwidth, vid.height, V_SNAPTOTOP|colormap[101]);
|
||||
{
|
||||
INT32 sw = (BASEVIDWIDTH * vid.dupx);
|
||||
INT32 sw = (BASEVIDWIDTH * vid.dup);
|
||||
INT32 bw = (vid.width - sw) / 2;
|
||||
col = colormap[106];
|
||||
if (bw)
|
||||
|
@ -10851,7 +10813,7 @@ void M_DrawMarathon(void)
|
|||
const char *cvstring;
|
||||
char *work;
|
||||
angle_t fa;
|
||||
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy), xspan = (vid.width/dupz), yspan = (vid.height/dupz), diffx = (xspan - BASEVIDWIDTH)/2, diffy = (yspan - BASEVIDHEIGHT)/2, maxy = BASEVIDHEIGHT + diffy;
|
||||
INT32 xspan = (vid.width/vid.dup), yspan = (vid.height/vid.dup), diffx = (xspan - BASEVIDWIDTH)/2, diffy = (yspan - BASEVIDHEIGHT)/2, maxy = BASEVIDHEIGHT + diffy;
|
||||
|
||||
curbgxspeed = 0;
|
||||
curbgyspeed = 18;
|
||||
|
@ -10924,16 +10886,17 @@ void M_DrawMarathon(void)
|
|||
INT32 trans = V_60TRANS+((cnt&~3)<<(V_ALPHASHIFT-2));
|
||||
INT32 height = fg->height / 2;
|
||||
char patchname[7] = "CEMGx0";
|
||||
INT32 dup;
|
||||
|
||||
dupz = (w*7)/6; //(w*42*120)/(360*6); -- I don't know why this works but I'm not going to complain.
|
||||
dupz = ((dupz>>FRACBITS) % height);
|
||||
dup = (w*7)/6; //(w*42*120)/(360*6); -- I don't know why this works but I'm not going to complain.
|
||||
dup = ((dup>>FRACBITS) % height);
|
||||
y = height/2;
|
||||
while (y+dupz >= -diffy)
|
||||
while (y+dup >= -diffy)
|
||||
y -= height;
|
||||
while (y-2-dupz < maxy)
|
||||
while (y-2-dup < maxy)
|
||||
{
|
||||
V_DrawFixedPatch(((BASEVIDWIDTH-190)<<(FRACBITS-1)), (y-2-dupz)<<FRACBITS, FRACUNIT/2, trans, fg, NULL);
|
||||
V_DrawFixedPatch(((BASEVIDWIDTH+190)<<(FRACBITS-1)), (y+dupz)<<FRACBITS, FRACUNIT/2, trans|V_FLIP, fg, NULL);
|
||||
V_DrawFixedPatch(((BASEVIDWIDTH-190)<<(FRACBITS-1)), (y-2-dup)<<FRACBITS, FRACUNIT/2, trans, fg, NULL);
|
||||
V_DrawFixedPatch(((BASEVIDWIDTH+190)<<(FRACBITS-1)), (y+dup)<<FRACBITS, FRACUNIT/2, trans|V_FLIP, fg, NULL);
|
||||
y += height;
|
||||
}
|
||||
|
||||
|
@ -10951,16 +10914,16 @@ void M_DrawMarathon(void)
|
|||
}
|
||||
|
||||
height = 18; // prevents the need for the next line
|
||||
//dupz = (w*height)/18;
|
||||
dupz = ((w>>FRACBITS) % height);
|
||||
y = dupz+(height/4);
|
||||
x = 105+dupz;
|
||||
//dup = (w*height)/18;
|
||||
dup = ((w>>FRACBITS) % height);
|
||||
y = dup+(height/4);
|
||||
x = 105+dup;
|
||||
while (y >= -diffy)
|
||||
{
|
||||
x -= height;
|
||||
y -= height;
|
||||
}
|
||||
while (y-dupz < maxy && x < (xspan/2))
|
||||
while (y-dup < maxy && x < (xspan/2))
|
||||
{
|
||||
V_DrawFill((BASEVIDWIDTH/2)-x-height, -diffy, height, diffy+y+height, 153);
|
||||
V_DrawFill((BASEVIDWIDTH/2)+x, (maxy-y)-height, height, height+y, 153);
|
||||
|
@ -11108,7 +11071,6 @@ static void M_EndGame(INT32 choice)
|
|||
|
||||
#define S_LINEY(n) currentMenu->y + SERVERHEADERHEIGHT + (n * SERVERLINEHEIGHT)
|
||||
|
||||
#ifndef NONET
|
||||
static UINT32 localservercount;
|
||||
|
||||
static void M_HandleServerPage(INT32 choice)
|
||||
|
@ -11380,11 +11342,9 @@ static int ServerListEntryComparator_modified(const void *entry1, const void *en
|
|||
// Default to strcmp.
|
||||
return strcmp(sa->info.servername, sb->info.servername);
|
||||
}
|
||||
#endif
|
||||
|
||||
void M_SortServerList(void)
|
||||
{
|
||||
#ifndef NONET
|
||||
switch(cv_serversort.value)
|
||||
{
|
||||
case 0: // Ping.
|
||||
|
@ -11406,10 +11366,8 @@ void M_SortServerList(void)
|
|||
qsort(serverlist, serverlistcount, sizeof(serverelem_t), ServerListEntryComparator_gametypename);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
#ifdef UPDATE_ALERT
|
||||
static boolean M_CheckMODVersion(int id)
|
||||
{
|
||||
|
@ -11608,7 +11566,6 @@ static void M_ChooseRoom(INT32 choice)
|
|||
if (currentMenu == &MP_ConnectDef)
|
||||
M_Refresh(0);
|
||||
}
|
||||
#endif //NONET
|
||||
|
||||
//===========================================================================
|
||||
// Start Server Menu
|
||||
|
@ -11656,7 +11613,6 @@ static void M_DrawServerMenu(void)
|
|||
{
|
||||
M_DrawGenericMenu();
|
||||
|
||||
#ifndef NONET
|
||||
// Room name
|
||||
if (currentMenu == &MP_ServerDef)
|
||||
{
|
||||
|
@ -11668,15 +11624,10 @@ static void M_DrawServerMenu(void)
|
|||
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey,
|
||||
V_YELLOWMAP, room_list[menuRoomIndex].name);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cv_nextmap.value)
|
||||
{
|
||||
#ifndef NONET
|
||||
#define imgheight MP_ServerMenu[mp_server_levelgt].alphaKey
|
||||
#else
|
||||
#define imgheight 100
|
||||
#endif
|
||||
patch_t *PictureOfLevel;
|
||||
lumpnum_t lumpnum;
|
||||
char headerstr[40];
|
||||
|
@ -11728,7 +11679,6 @@ static void M_ServerOptions(INT32 choice)
|
|||
{
|
||||
(void)choice;
|
||||
|
||||
#ifndef NONET
|
||||
if ((splitscreen && !netgame) || currentMenu == &MP_SplitServerDef)
|
||||
{
|
||||
OP_ServerOptionsMenu[ 1].status = IT_GRAYEDOUT; // Server name
|
||||
|
@ -11749,7 +11699,6 @@ static void M_ServerOptions(INT32 choice)
|
|||
OP_ServerOptionsMenu[37].status = IT_STRING | IT_CVAR;
|
||||
OP_ServerOptionsMenu[38].status = IT_STRING | IT_CVAR;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Disable fading because of different menu head. */
|
||||
if (currentMenu == &OP_MainDef)/* from Options menu */
|
||||
|
@ -11761,7 +11710,6 @@ static void M_ServerOptions(INT32 choice)
|
|||
M_SetupNextMenu(&OP_ServerOptionsDef);
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
static void M_StartServerMenu(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
@ -12028,7 +11976,6 @@ static void M_HandleConnectIP(INT32 choice)
|
|||
M_ClearMenus(true);
|
||||
}
|
||||
}
|
||||
#endif //!NONET
|
||||
|
||||
// ========================
|
||||
// MULTIPLAYER PLAYER SETUP
|
||||
|
@ -12690,11 +12637,7 @@ static void M_SetupMultiPlayer(INT32 choice)
|
|||
else
|
||||
MP_PlayerSetupMenu[1].status = (IT_KEYHANDLER|IT_STRING);
|
||||
|
||||
// ditto with colour
|
||||
if (Playing() && G_GametypeHasTeams())
|
||||
MP_PlayerSetupMenu[2].status = (IT_GRAYEDOUT);
|
||||
else
|
||||
MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER|IT_STRING);
|
||||
MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER|IT_STRING);
|
||||
|
||||
multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL);
|
||||
|
||||
|
@ -12709,7 +12652,7 @@ static void M_SetupMultiPlayer2(INT32 choice)
|
|||
|
||||
multi_frame = 0;
|
||||
multi_tics = 4*FRACUNIT;
|
||||
|
||||
|
||||
strcpy (setupm_name, cv_playername2.string);
|
||||
|
||||
// set for splitscreen secondary player
|
||||
|
@ -12735,11 +12678,7 @@ static void M_SetupMultiPlayer2(INT32 choice)
|
|||
else
|
||||
MP_PlayerSetupMenu[1].status = (IT_KEYHANDLER | IT_STRING);
|
||||
|
||||
// ditto with colour
|
||||
if (Playing() && G_GametypeHasTeams())
|
||||
MP_PlayerSetupMenu[2].status = (IT_GRAYEDOUT);
|
||||
else
|
||||
MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER|IT_STRING);
|
||||
MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER|IT_STRING);
|
||||
|
||||
multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "command.h"
|
||||
#include "f_finale.h" // for ttmode_enum
|
||||
#include "i_threads.h"
|
||||
#include "mserv.h"
|
||||
#include "netcode/mserv.h"
|
||||
#include "r_things.h" // for SKINNAMESIZE
|
||||
|
||||
// Compatibility with old-style named NiGHTS replay files.
|
||||
|
@ -74,7 +74,7 @@ typedef enum
|
|||
MN_MP_SERVER,
|
||||
MN_MP_CONNECT,
|
||||
MN_MP_ROOM,
|
||||
MN_MP_PLAYERSETUP, // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET
|
||||
MN_MP_PLAYERSETUP,
|
||||
MN_MP_SERVER_OPTIONS,
|
||||
|
||||
// Options
|
||||
|
|
|
@ -989,7 +989,7 @@ static inline boolean M_PNGLib(void)
|
|||
|
||||
static void M_PNGFrame(png_structp png_ptr, png_infop png_info_ptr, png_bytep png_buf)
|
||||
{
|
||||
png_uint_16 downscale = apng_downscale ? vid.dupx : 1;
|
||||
png_uint_16 downscale = apng_downscale ? vid.dup : 1;
|
||||
|
||||
png_uint_32 pitch = png_get_rowbytes(png_ptr, png_info_ptr);
|
||||
PNG_CONST png_uint_32 width = vid.width / downscale;
|
||||
|
@ -1055,7 +1055,7 @@ static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal)
|
|||
|
||||
apng_downscale = (!!cv_apng_downscale.value);
|
||||
|
||||
downscale = apng_downscale ? vid.dupx : 1;
|
||||
downscale = apng_downscale ? vid.dup : 1;
|
||||
|
||||
apng_FILE = fopen(filename,"wb+"); // + mode for reading
|
||||
if (!apng_FILE)
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "m_perfstats.h"
|
||||
#include "v_video.h"
|
||||
#include "i_video.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "netcode/d_netcmd.h"
|
||||
#include "r_main.h"
|
||||
#include "i_system.h"
|
||||
#include "z_zone.h"
|
||||
|
|
15
src/netcode/CMakeLists.txt
Normal file
15
src/netcode/CMakeLists.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
target_sources(SRB2SDL2 PRIVATE
|
||||
d_clisrv.c
|
||||
server_connection.c
|
||||
client_connection.c
|
||||
tic_command.c
|
||||
net_command.c
|
||||
gamestate.c
|
||||
commands.c
|
||||
d_net.c
|
||||
d_netcmd.c
|
||||
d_netfil.c
|
||||
http-mserv.c
|
||||
i_tcp.c
|
||||
mserv.c
|
||||
)
|
13
src/netcode/Sourcefile
Normal file
13
src/netcode/Sourcefile
Normal file
|
@ -0,0 +1,13 @@
|
|||
d_clisrv.c
|
||||
server_connection.c
|
||||
client_connection.c
|
||||
tic_command.c
|
||||
net_command.c
|
||||
gamestate.c
|
||||
commands.c
|
||||
d_net.c
|
||||
d_netcmd.c
|
||||
d_netfil.c
|
||||
http-mserv.c
|
||||
i_tcp.c
|
||||
mserv.c
|
1178
src/netcode/client_connection.c
Normal file
1178
src/netcode/client_connection.c
Normal file
File diff suppressed because it is too large
Load diff
61
src/netcode/client_connection.h
Normal file
61
src/netcode/client_connection.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file client_connection.h
|
||||
/// \brief Client connection handling
|
||||
|
||||
#ifndef __D_CLIENT_CONNECTION__
|
||||
#define __D_CLIENT_CONNECTION__
|
||||
|
||||
#include "../doomtype.h"
|
||||
#include "d_clisrv.h"
|
||||
|
||||
#define MAXSERVERLIST (MAXNETNODES-1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SINT8 node;
|
||||
serverinfo_pak info;
|
||||
} serverelem_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CL_SEARCHING,
|
||||
CL_CHECKFILES,
|
||||
CL_DOWNLOADFILES,
|
||||
CL_ASKJOIN,
|
||||
CL_LOADFILES,
|
||||
CL_WAITJOINRESPONSE,
|
||||
CL_DOWNLOADSAVEGAME,
|
||||
CL_CONNECTED,
|
||||
CL_ABORTED,
|
||||
CL_ASKFULLFILELIST,
|
||||
CL_CONFIRMCONNECT
|
||||
} cl_mode_t;
|
||||
|
||||
extern serverelem_t serverlist[MAXSERVERLIST];
|
||||
extern UINT32 serverlistcount;
|
||||
|
||||
extern cl_mode_t cl_mode;
|
||||
extern boolean serverisfull; //lets us be aware if the server was full after we check files, but before downloading, so we can ask if the user still wants to download or not
|
||||
extern tic_t firstconnectattempttime;
|
||||
extern UINT8 mynode; // my address pointofview server
|
||||
|
||||
void CL_QueryServerList(msg_server_t *list);
|
||||
void CL_UpdateServerList(boolean internetsearch, INT32 room);
|
||||
|
||||
void CL_ConnectToServer(void);
|
||||
boolean CL_SendJoin(void);
|
||||
|
||||
void PT_ServerInfo(SINT8 node);
|
||||
void PT_MoreFilesNeeded(SINT8 node);
|
||||
void PT_ServerRefuse(SINT8 node);
|
||||
void PT_ServerCFG(SINT8 node);
|
||||
|
||||
#endif
|
484
src/netcode/commands.c
Normal file
484
src/netcode/commands.c
Normal file
|
@ -0,0 +1,484 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file commands.c
|
||||
/// \brief Various netgame commands, such as kick and ban
|
||||
|
||||
#include "commands.h"
|
||||
#include "d_clisrv.h"
|
||||
#include "client_connection.h"
|
||||
#include "net_command.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "d_net.h"
|
||||
#include "i_net.h"
|
||||
#include "protocol.h"
|
||||
#include "../byteptr.h"
|
||||
#include "../d_main.h"
|
||||
#include "../g_game.h"
|
||||
#include "../w_wad.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../doomdef.h"
|
||||
#include "../r_local.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct banreason_s
|
||||
{
|
||||
char *reason;
|
||||
struct banreason_s *prev; //-1
|
||||
struct banreason_s *next; //+1
|
||||
} banreason_t;
|
||||
|
||||
static banreason_t *reasontail = NULL; //last entry, use prev
|
||||
static banreason_t *reasonhead = NULL; //1st entry, use next
|
||||
|
||||
void Ban_Add(const char *reason)
|
||||
{
|
||||
banreason_t *reasonlist = malloc(sizeof(*reasonlist));
|
||||
|
||||
if (!reasonlist)
|
||||
return;
|
||||
if (!reason)
|
||||
reason = "NA";
|
||||
|
||||
reasonlist->next = NULL;
|
||||
reasonlist->reason = Z_StrDup(reason);
|
||||
if ((reasonlist->prev = reasontail) == NULL)
|
||||
reasonhead = reasonlist;
|
||||
else
|
||||
reasontail->next = reasonlist;
|
||||
reasontail = reasonlist;
|
||||
}
|
||||
|
||||
static void Ban_Clear(void)
|
||||
{
|
||||
banreason_t *temp;
|
||||
|
||||
I_ClearBans();
|
||||
|
||||
reasontail = NULL;
|
||||
|
||||
while (reasonhead)
|
||||
{
|
||||
temp = reasonhead->next;
|
||||
Z_Free(reasonhead->reason);
|
||||
free(reasonhead);
|
||||
reasonhead = temp;
|
||||
}
|
||||
}
|
||||
|
||||
void Ban_Load_File(boolean warning)
|
||||
{
|
||||
FILE *f;
|
||||
const char *address, *mask;
|
||||
char buffer[MAX_WADPATH];
|
||||
|
||||
if (!I_ClearBans)
|
||||
return;
|
||||
|
||||
f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "r");
|
||||
|
||||
if (!f)
|
||||
{
|
||||
if (warning)
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Could not open ban.txt for ban list\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
Ban_Clear();
|
||||
|
||||
for (; fgets(buffer, (int)sizeof(buffer), f);)
|
||||
{
|
||||
address = strtok(buffer, " \t\r\n");
|
||||
mask = strtok(NULL, " \t\r\n");
|
||||
|
||||
I_SetBanAddress(address, mask);
|
||||
|
||||
Ban_Add(strtok(NULL, "\r\n"));
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void D_SaveBan(void)
|
||||
{
|
||||
FILE *f;
|
||||
banreason_t *reasonlist = reasonhead;
|
||||
const char *address, *mask;
|
||||
const char *path = va("%s"PATHSEP"%s", srb2home, "ban.txt");
|
||||
|
||||
if (!reasonhead)
|
||||
{
|
||||
remove(path);
|
||||
return;
|
||||
}
|
||||
|
||||
f = fopen(path, "w");
|
||||
|
||||
if (!f)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Could not save ban list into ban.txt\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0;(address = I_GetBanAddress(i)) != NULL;i++)
|
||||
{
|
||||
if (!I_GetBanMask || (mask = I_GetBanMask(i)) == NULL)
|
||||
fprintf(f, "%s 0", address);
|
||||
else
|
||||
fprintf(f, "%s %s", address, mask);
|
||||
|
||||
if (reasonlist && reasonlist->reason)
|
||||
fprintf(f, " %s\n", reasonlist->reason);
|
||||
else
|
||||
fprintf(f, " %s\n", "NA");
|
||||
|
||||
if (reasonlist) reasonlist = reasonlist->next;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void Command_ShowBan(void) //Print out ban list
|
||||
{
|
||||
size_t i;
|
||||
const char *address, *mask;
|
||||
banreason_t *reasonlist = reasonhead;
|
||||
|
||||
if (I_GetBanAddress)
|
||||
CONS_Printf(M_GetText("Ban List:\n"));
|
||||
else
|
||||
return;
|
||||
|
||||
for (i = 0;(address = I_GetBanAddress(i)) != NULL;i++)
|
||||
{
|
||||
if (!I_GetBanMask || (mask = I_GetBanMask(i)) == NULL)
|
||||
CONS_Printf("%s: %s ", sizeu1(i+1), address);
|
||||
else
|
||||
CONS_Printf("%s: %s/%s ", sizeu1(i+1), address, mask);
|
||||
|
||||
if (reasonlist && reasonlist->reason)
|
||||
CONS_Printf("(%s)\n", reasonlist->reason);
|
||||
else
|
||||
CONS_Printf("\n");
|
||||
|
||||
if (reasonlist) reasonlist = reasonlist->next;
|
||||
}
|
||||
|
||||
if (i == 0 && !address)
|
||||
CONS_Printf(M_GetText("(empty)\n"));
|
||||
}
|
||||
|
||||
void Command_ClearBans(void)
|
||||
{
|
||||
if (!I_ClearBans)
|
||||
return;
|
||||
|
||||
Ban_Clear();
|
||||
D_SaveBan();
|
||||
}
|
||||
|
||||
void Command_Ban(void)
|
||||
{
|
||||
if (COM_Argc() < 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("Ban <playername/playernum> <reason>: ban and kick a player\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!netgame) // Don't kick Tails in splitscreen!
|
||||
{
|
||||
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (server || IsPlayerAdmin(consoleplayer))
|
||||
{
|
||||
UINT8 buf[3 + MAX_REASONLENGTH];
|
||||
UINT8 *p = buf;
|
||||
const SINT8 pn = nametonum(COM_Argv(1));
|
||||
const INT32 node = playernode[(INT32)pn];
|
||||
|
||||
if (pn == -1 || pn == 0)
|
||||
return;
|
||||
|
||||
WRITEUINT8(p, pn);
|
||||
|
||||
if (server && I_Ban && !I_Ban(node)) // only the server is allowed to do this right now
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n"));
|
||||
WRITEUINT8(p, KICK_MSG_GO_AWAY);
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (server) // only the server is allowed to do this right now
|
||||
{
|
||||
Ban_Add(COM_Argv(2));
|
||||
D_SaveBan(); // save the ban list
|
||||
}
|
||||
|
||||
if (COM_Argc() == 2)
|
||||
{
|
||||
WRITEUINT8(p, KICK_MSG_BANNED);
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t j = COM_Argc();
|
||||
char message[MAX_REASONLENGTH];
|
||||
|
||||
//Steal from the motd code so you don't have to put the reason in quotes.
|
||||
strlcpy(message, COM_Argv(2), sizeof message);
|
||||
for (size_t i = 3; i < j; i++)
|
||||
{
|
||||
strlcat(message, " ", sizeof message);
|
||||
strlcat(message, COM_Argv(i), sizeof message);
|
||||
}
|
||||
|
||||
WRITEUINT8(p, KICK_MSG_CUSTOM_BAN);
|
||||
WRITESTRINGN(p, message, MAX_REASONLENGTH);
|
||||
SendNetXCmd(XD_KICK, &buf, p - buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||
|
||||
}
|
||||
|
||||
void Command_BanIP(void)
|
||||
{
|
||||
if (COM_Argc() < 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("banip <ip> <reason>: ban an ip address\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (server) // Only the server can use this, otherwise does nothing.
|
||||
{
|
||||
const char *address = (COM_Argv(1));
|
||||
const char *reason;
|
||||
|
||||
if (COM_Argc() == 2)
|
||||
reason = NULL;
|
||||
else
|
||||
reason = COM_Argv(2);
|
||||
|
||||
|
||||
if (I_SetBanAddress && I_SetBanAddress(address, NULL))
|
||||
{
|
||||
if (reason)
|
||||
CONS_Printf("Banned IP address %s for: %s\n", address, reason);
|
||||
else
|
||||
CONS_Printf("Banned IP address %s\n", address);
|
||||
|
||||
Ban_Add(reason);
|
||||
D_SaveBan();
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Command_ReloadBan(void) //recheck ban.txt
|
||||
{
|
||||
Ban_Load_File(true);
|
||||
}
|
||||
|
||||
void Command_Kick(void)
|
||||
{
|
||||
if (COM_Argc() < 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("kick <playername/playernum> <reason>: kick a player\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!netgame) // Don't kick Tails in splitscreen!
|
||||
{
|
||||
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (server || IsPlayerAdmin(consoleplayer))
|
||||
{
|
||||
UINT8 buf[3 + MAX_REASONLENGTH];
|
||||
UINT8 *p = buf;
|
||||
const SINT8 pn = nametonum(COM_Argv(1));
|
||||
|
||||
if (pn == -1 || pn == 0)
|
||||
return;
|
||||
|
||||
// Special case if we are trying to kick a player who is downloading the game state:
|
||||
// trigger a timeout instead of kicking them, because a kick would only
|
||||
// take effect after they have finished downloading
|
||||
if (server && playernode[pn] != UINT8_MAX && netnodes[playernode[pn]].sendingsavegame)
|
||||
{
|
||||
Net_ConnectionTimeout(playernode[pn]);
|
||||
return;
|
||||
}
|
||||
|
||||
WRITESINT8(p, pn);
|
||||
|
||||
if (COM_Argc() == 2)
|
||||
{
|
||||
WRITEUINT8(p, KICK_MSG_GO_AWAY);
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t j = COM_Argc();
|
||||
char message[MAX_REASONLENGTH];
|
||||
|
||||
//Steal from the motd code so you don't have to put the reason in quotes.
|
||||
strlcpy(message, COM_Argv(2), sizeof message);
|
||||
for (size_t i = 3; i < j; i++)
|
||||
{
|
||||
strlcat(message, " ", sizeof message);
|
||||
strlcat(message, COM_Argv(i), sizeof message);
|
||||
}
|
||||
|
||||
WRITEUINT8(p, KICK_MSG_CUSTOM_KICK);
|
||||
WRITESTRINGN(p, message, MAX_REASONLENGTH);
|
||||
SendNetXCmd(XD_KICK, &buf, p - buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||
}
|
||||
|
||||
void Command_connect(void)
|
||||
{
|
||||
if (COM_Argc() < 2 || *COM_Argv(1) == 0)
|
||||
{
|
||||
CONS_Printf(M_GetText(
|
||||
"Connect <serveraddress> (port): connect to a server\n"
|
||||
"Connect ANY: connect to the first lan server found\n"
|
||||
//"Connect SELF: connect to your own server.\n"
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Playing() || titledemo)
|
||||
{
|
||||
CONS_Printf(M_GetText("You cannot connect while in a game. End this game first.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
server = false;
|
||||
/*
|
||||
if (!stricmp(COM_Argv(1), "self"))
|
||||
{
|
||||
servernode = 0;
|
||||
server = true;
|
||||
/// \bug should be but...
|
||||
//SV_SpawnServer();
|
||||
}
|
||||
else
|
||||
*/
|
||||
{
|
||||
// used in menu to connect to a server in the list
|
||||
if (netgame && !stricmp(COM_Argv(1), "node"))
|
||||
{
|
||||
servernode = (SINT8)atoi(COM_Argv(2));
|
||||
}
|
||||
else if (netgame)
|
||||
{
|
||||
CONS_Printf(M_GetText("You cannot connect while in a game. End this game first.\n"));
|
||||
return;
|
||||
}
|
||||
else if (I_NetOpenSocket)
|
||||
{
|
||||
I_NetOpenSocket();
|
||||
netgame = true;
|
||||
multiplayer = true;
|
||||
|
||||
if (!stricmp(COM_Argv(1), "any"))
|
||||
servernode = BROADCASTADDR;
|
||||
else if (I_NetMakeNodewPort)
|
||||
{
|
||||
if (COM_Argc() >= 3) // address AND port
|
||||
servernode = I_NetMakeNodewPort(COM_Argv(1), COM_Argv(2));
|
||||
else // address only, or address:port
|
||||
servernode = I_NetMakeNode(COM_Argv(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("There is no server identification with this network driver\n"));
|
||||
D_CloseConnection();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
CONS_Alert(CONS_ERROR, M_GetText("There is no network driver\n"));
|
||||
}
|
||||
|
||||
splitscreen = false;
|
||||
SplitScreen_OnChange();
|
||||
botingame = false;
|
||||
botskin = 0;
|
||||
CL_ConnectToServer();
|
||||
}
|
||||
|
||||
void Command_GetPlayerNum(void)
|
||||
{
|
||||
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
{
|
||||
if (serverplayer == i)
|
||||
CONS_Printf(M_GetText("num:%2d node:%2d %s\n"), i, playernode[i], player_names[i]);
|
||||
else
|
||||
CONS_Printf(M_GetText("\x82num:%2d node:%2d %s\n"), i, playernode[i], player_names[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** Lists all players and their player numbers.
|
||||
*
|
||||
* \sa Command_GetPlayerNum
|
||||
*/
|
||||
void Command_Nodes(void)
|
||||
{
|
||||
size_t maxlen = 0;
|
||||
const char *address;
|
||||
|
||||
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
const size_t plen = strlen(player_names[i]);
|
||||
if (playeringame[i] && plen > maxlen)
|
||||
maxlen = plen;
|
||||
}
|
||||
|
||||
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
{
|
||||
CONS_Printf("%.2u: %*s", i, (int)maxlen, player_names[i]);
|
||||
|
||||
if (playernode[i] != UINT8_MAX)
|
||||
{
|
||||
CONS_Printf(" - node %.2d", playernode[i]);
|
||||
if (I_GetNodeAddress && (address = I_GetNodeAddress(playernode[i])) != NULL)
|
||||
CONS_Printf(" - %s", address);
|
||||
}
|
||||
|
||||
if (IsPlayerAdmin(i))
|
||||
CONS_Printf(M_GetText(" (verified admin)"));
|
||||
|
||||
if (players[i].spectator)
|
||||
CONS_Printf(M_GetText(" (spectator)"));
|
||||
|
||||
CONS_Printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
33
src/netcode/commands.h
Normal file
33
src/netcode/commands.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file commands.h
|
||||
/// \brief Various netgame commands, such as kick and ban
|
||||
|
||||
#ifndef __COMMANDS__
|
||||
#define __COMMANDS__
|
||||
|
||||
#include "../doomdef.h"
|
||||
|
||||
#define MAX_REASONLENGTH 30
|
||||
|
||||
void Ban_Add(const char *reason);
|
||||
void D_SaveBan(void);
|
||||
void Ban_Load_File(boolean warning);
|
||||
void Command_ShowBan(void);
|
||||
void Command_ClearBans(void);
|
||||
void Command_Ban(void);
|
||||
void Command_BanIP(void);
|
||||
void Command_ReloadBan(void);
|
||||
void Command_Kick(void);
|
||||
void Command_connect(void);
|
||||
void Command_GetPlayerNum(void);
|
||||
void Command_Nodes(void);
|
||||
|
||||
#endif
|
1736
src/netcode/d_clisrv.c
Normal file
1736
src/netcode/d_clisrv.c
Normal file
File diff suppressed because it is too large
Load diff
135
src/netcode/d_clisrv.h
Normal file
135
src/netcode/d_clisrv.h
Normal file
|
@ -0,0 +1,135 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file d_clisrv.h
|
||||
/// \brief high level networking stuff
|
||||
|
||||
#ifndef __D_CLISRV__
|
||||
#define __D_CLISRV__
|
||||
|
||||
#include "protocol.h"
|
||||
#include "../d_ticcmd.h"
|
||||
#include "d_net.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "d_net.h"
|
||||
#include "../tables.h"
|
||||
#include "../d_player.h"
|
||||
#include "mserv.h"
|
||||
|
||||
#define CLIENTBACKUPTICS 32
|
||||
|
||||
#ifdef PACKETDROP
|
||||
void Command_Drop(void);
|
||||
void Command_Droprate(void);
|
||||
#endif
|
||||
#ifdef _DEBUG
|
||||
void Command_Numnodes(void);
|
||||
#endif
|
||||
|
||||
extern INT32 mapchangepending;
|
||||
|
||||
// Points inside doomcom
|
||||
extern doomdata_t *netbuffer;
|
||||
|
||||
#define BASEPACKETSIZE offsetof(doomdata_t, u)
|
||||
#define BASESERVERTICSSIZE offsetof(doomdata_t, u.serverpak.cmds[0])
|
||||
|
||||
typedef enum
|
||||
{
|
||||
KR_KICK = 1, //Kicked by server
|
||||
KR_PINGLIMIT = 2, //Broke Ping Limit
|
||||
KR_SYNCH = 3, //Synch Failure
|
||||
KR_TIMEOUT = 4, //Connection Timeout
|
||||
KR_BAN = 5, //Banned by server
|
||||
KR_LEAVE = 6, //Quit the game
|
||||
|
||||
} kickreason_t;
|
||||
|
||||
/* the max number of name changes in some time period */
|
||||
#define MAXNAMECHANGES (5)
|
||||
#define NAMECHANGERATE (60*TICRATE)
|
||||
|
||||
extern boolean server;
|
||||
extern boolean serverrunning;
|
||||
#define client (!server)
|
||||
extern boolean dedicated; // For dedicated server
|
||||
extern UINT16 software_MAXPACKETLENGTH;
|
||||
extern boolean acceptnewnode;
|
||||
extern SINT8 servernode;
|
||||
extern tic_t maketic;
|
||||
extern tic_t neededtic;
|
||||
extern INT16 consistancy[BACKUPTICS];
|
||||
|
||||
void Command_Ping_f(void);
|
||||
extern tic_t connectiontimeout;
|
||||
extern UINT16 pingmeasurecount;
|
||||
extern UINT32 realpingtable[MAXPLAYERS];
|
||||
extern UINT32 playerpingtable[MAXPLAYERS];
|
||||
extern tic_t servermaxping;
|
||||
|
||||
extern consvar_t cv_netticbuffer, cv_resynchattempts, cv_blamecfail, cv_playbackspeed, cv_dedicatedidletime;
|
||||
|
||||
// Used in d_net, the only dependence
|
||||
void D_ClientServerInit(void);
|
||||
|
||||
// Create any new ticcmds and broadcast to other players.
|
||||
void NetUpdate(void);
|
||||
|
||||
// Maintain connections to nodes without timing them all out.
|
||||
void NetKeepAlive(void);
|
||||
|
||||
void GetPackets(void);
|
||||
void ResetNode(INT32 node);
|
||||
INT16 Consistancy(void);
|
||||
|
||||
void SV_StartSinglePlayerServer(void);
|
||||
void SV_SpawnServer(void);
|
||||
void SV_StopServer(void);
|
||||
void SV_ResetServer(void);
|
||||
void CL_AddSplitscreenPlayer(void);
|
||||
void CL_RemoveSplitscreenPlayer(void);
|
||||
void CL_Reset(void);
|
||||
void CL_ClearPlayer(INT32 playernum);
|
||||
void CL_RemovePlayer(INT32 playernum, kickreason_t reason);
|
||||
void CL_HandleTimeout(void);
|
||||
// Is there a game running
|
||||
boolean Playing(void);
|
||||
|
||||
// Broadcasts special packets to other players
|
||||
// to notify of game exit
|
||||
void D_QuitNetGame(void);
|
||||
|
||||
//? How many ticks to run?
|
||||
boolean TryRunTics(tic_t realtic);
|
||||
|
||||
// extra data for lmps
|
||||
// these functions scare me. they contain magic.
|
||||
/*boolean AddLmpExtradata(UINT8 **demo_p, INT32 playernum);
|
||||
void ReadLmpExtraData(UINT8 **demo_pointer, INT32 playernum);*/
|
||||
|
||||
// translate a playername in a player number return -1 if not found and
|
||||
// print a error message in the console
|
||||
SINT8 nametonum(const char *name);
|
||||
|
||||
extern char motd[254], server_context[8];
|
||||
extern UINT8 playernode[MAXPLAYERS];
|
||||
|
||||
INT32 D_NumPlayers(void);
|
||||
INT32 D_NumBots(void);
|
||||
|
||||
tic_t GetLag(INT32 node);
|
||||
|
||||
void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest);
|
||||
|
||||
extern UINT8 adminpassmd5[16];
|
||||
extern boolean adminpasswordset;
|
||||
|
||||
extern boolean hu_stopped;
|
||||
|
||||
#endif
|
|
@ -16,19 +16,21 @@
|
|||
/// This protocol uses a mix of "goback n" and "selective repeat" implementation
|
||||
/// The NOTHING packet is sent when connection is idle to acknowledge packets
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "g_game.h"
|
||||
#include "i_time.h"
|
||||
#include "../doomdef.h"
|
||||
#include "../g_game.h"
|
||||
#include "../i_time.h"
|
||||
#include "i_net.h"
|
||||
#include "i_system.h"
|
||||
#include "m_argv.h"
|
||||
#include "../i_system.h"
|
||||
#include "../m_argv.h"
|
||||
#include "d_net.h"
|
||||
#include "w_wad.h"
|
||||
#include "../w_wad.h"
|
||||
#include "d_netfil.h"
|
||||
#include "d_clisrv.h"
|
||||
#include "z_zone.h"
|
||||
#include "tic_command.h"
|
||||
#include "net_command.h"
|
||||
#include "../z_zone.h"
|
||||
#include "i_tcp.h"
|
||||
#include "d_main.h" // srb2home
|
||||
#include "../d_main.h" // srb2home
|
||||
|
||||
//
|
||||
// NETWORKING
|
||||
|
@ -138,7 +140,6 @@ boolean Net_GetNetStat(void)
|
|||
#define URGENTFREESLOTNUM 10
|
||||
#define ACKTOSENDTIMEOUT (TICRATE/11)
|
||||
|
||||
#ifndef NONET
|
||||
typedef struct
|
||||
{
|
||||
UINT8 acknum;
|
||||
|
@ -152,7 +153,6 @@ typedef struct
|
|||
doomdata_t data;
|
||||
} pak;
|
||||
} ackpak_t;
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -160,10 +160,8 @@ typedef enum
|
|||
NF_TIMEOUT = 2, // Flag is set when the node got a timeout
|
||||
} node_flags_t;
|
||||
|
||||
#ifndef NONET
|
||||
// Table of packets that were not acknowleged can be resent (the sender window)
|
||||
static ackpak_t ackpak[MAXACKPACKETS];
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -191,7 +189,6 @@ typedef struct
|
|||
static node_t nodes[MAXNETNODES];
|
||||
#define NODETIMEOUT 14
|
||||
|
||||
#ifndef NONET
|
||||
// return <0 if a < b (mod 256)
|
||||
// 0 if a = n (mod 256)
|
||||
// >0 if a > b (mod 256)
|
||||
|
@ -214,7 +211,7 @@ FUNCMATH static INT32 cmpack(UINT8 a, UINT8 b)
|
|||
static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer)
|
||||
{
|
||||
node_t *node = &nodes[doomcom->remotenode];
|
||||
INT32 i, numfreeslot = 0;
|
||||
INT32 numfreeslot = 0;
|
||||
|
||||
if (cmpack((UINT8)((node->remotefirstack + MAXACKTOSEND) % 256), node->nextacknum) < 0)
|
||||
{
|
||||
|
@ -222,7 +219,7 @@ static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer)
|
|||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXACKPACKETS; i++)
|
||||
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||
if (!ackpak[i].acknum)
|
||||
{
|
||||
// For low priority packets, make sure to let freeslots so urgent packets can be sent
|
||||
|
@ -279,10 +276,10 @@ static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer)
|
|||
*/
|
||||
INT32 Net_GetFreeAcks(boolean urgent)
|
||||
{
|
||||
INT32 i, numfreeslot = 0;
|
||||
INT32 numfreeslot = 0;
|
||||
INT32 n = 0; // Number of free acks found
|
||||
|
||||
for (i = 0; i < MAXACKPACKETS; i++)
|
||||
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||
if (!ackpak[i].acknum)
|
||||
{
|
||||
// For low priority packets, make sure to let freeslots so urgent packets can be sent
|
||||
|
@ -318,7 +315,6 @@ static void RemoveAck(INT32 i)
|
|||
// We have got a packet, proceed the ack request and ack return
|
||||
static boolean Processackpak(void)
|
||||
{
|
||||
INT32 i;
|
||||
boolean goodpacket = true;
|
||||
node_t *node = &nodes[doomcom->remotenode];
|
||||
|
||||
|
@ -327,7 +323,7 @@ static boolean Processackpak(void)
|
|||
{
|
||||
node->remotefirstack = netbuffer->ackreturn;
|
||||
// Search the ackbuffer and free it
|
||||
for (i = 0; i < MAXACKPACKETS; i++)
|
||||
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||
if (ackpak[i].acknum && ackpak[i].destinationnode == node - nodes
|
||||
&& cmpack(ackpak[i].acknum, netbuffer->ackreturn) <= 0)
|
||||
{
|
||||
|
@ -349,7 +345,7 @@ static boolean Processackpak(void)
|
|||
else
|
||||
{
|
||||
// Check if it is not already in the queue
|
||||
for (i = node->acktosend_tail; i != node->acktosend_head; i = (i+1) % MAXACKTOSEND)
|
||||
for (INT32 i = node->acktosend_tail; i != node->acktosend_head; i = (i+1) % MAXACKTOSEND)
|
||||
if (node->acktosend[i] == ack)
|
||||
{
|
||||
DEBFILE(va("Discard(2) ack %d (duplicated)\n", ack));
|
||||
|
@ -377,7 +373,7 @@ static boolean Processackpak(void)
|
|||
while (change)
|
||||
{
|
||||
change = false;
|
||||
for (i = node->acktosend_tail; i != node->acktosend_head;
|
||||
for (INT32 i = node->acktosend_tail; i != node->acktosend_head;
|
||||
i = (i+1) % MAXACKTOSEND)
|
||||
{
|
||||
if (cmpack(node->acktosend[i], nextfirstack) <= 0)
|
||||
|
@ -426,28 +422,20 @@ static boolean Processackpak(void)
|
|||
}
|
||||
return goodpacket;
|
||||
}
|
||||
#endif
|
||||
|
||||
// send special packet with only ack on it
|
||||
void Net_SendAcks(INT32 node)
|
||||
{
|
||||
#ifdef NONET
|
||||
(void)node;
|
||||
#else
|
||||
netbuffer->packettype = PT_NOTHING;
|
||||
M_Memcpy(netbuffer->u.textcmd, nodes[node].acktosend, MAXACKTOSEND);
|
||||
HSendPacket(node, false, 0, MAXACKTOSEND);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
static void GotAcks(void)
|
||||
{
|
||||
INT32 i, j;
|
||||
|
||||
for (j = 0; j < MAXACKTOSEND; j++)
|
||||
for (INT32 j = 0; j < MAXACKTOSEND; j++)
|
||||
if (netbuffer->u.textcmd[j])
|
||||
for (i = 0; i < MAXACKPACKETS; i++)
|
||||
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||
if (ackpak[i].acknum && ackpak[i].destinationnode == doomcom->remotenode)
|
||||
{
|
||||
if (ackpak[i].acknum == netbuffer->u.textcmd[j])
|
||||
|
@ -463,7 +451,6 @@ static void GotAcks(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void Net_ConnectionTimeout(INT32 node)
|
||||
{
|
||||
|
@ -472,14 +459,10 @@ void Net_ConnectionTimeout(INT32 node)
|
|||
return;
|
||||
nodes[node].flags |= NF_TIMEOUT;
|
||||
|
||||
// Send a very special packet to self (hack the reboundstore queue)
|
||||
// Main code will handle it
|
||||
reboundstore[rebound_head].packettype = PT_NODETIMEOUT;
|
||||
reboundstore[rebound_head].ack = 0;
|
||||
reboundstore[rebound_head].ackreturn = 0;
|
||||
reboundstore[rebound_head].u.textcmd[0] = (UINT8)node;
|
||||
reboundsize[rebound_head] = (INT16)(BASEPACKETSIZE + 1);
|
||||
rebound_head = (rebound_head+1) % MAXREBOUND;
|
||||
if (server)
|
||||
SendKicksForNode(node, KICK_MSG_TIMEOUT | KICK_MSG_KEEP_BODY);
|
||||
else
|
||||
CL_HandleTimeout();
|
||||
|
||||
// Do not redo it quickly (if we do not close connection it is
|
||||
// for a good reason!)
|
||||
|
@ -489,10 +472,8 @@ void Net_ConnectionTimeout(INT32 node)
|
|||
// Resend the data if needed
|
||||
void Net_AckTicker(void)
|
||||
{
|
||||
#ifndef NONET
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < MAXACKPACKETS; i++)
|
||||
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||
{
|
||||
const INT32 nodei = ackpak[i].destinationnode;
|
||||
node_t *node = &nodes[nodei];
|
||||
|
@ -519,7 +500,7 @@ void Net_AckTicker(void)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 1; i < MAXNETNODES; i++)
|
||||
for (INT32 i = 1; i < MAXNETNODES; i++)
|
||||
{
|
||||
// This is something like node open flag
|
||||
if (nodes[i].firstacktosend)
|
||||
|
@ -536,16 +517,12 @@ void Net_AckTicker(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Remove last packet received ack before resending the ackreturn
|
||||
// (the higher layer doesn't have room, or something else ....)
|
||||
void Net_UnAcknowledgePacket(INT32 node)
|
||||
{
|
||||
#ifdef NONET
|
||||
(void)node;
|
||||
#else
|
||||
INT32 hm1 = (nodes[node].acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND;
|
||||
DEBFILE(va("UnAcknowledge node %d\n", node));
|
||||
if (!node)
|
||||
|
@ -577,10 +554,8 @@ void Net_UnAcknowledgePacket(INT32 node)
|
|||
if (!nodes[node].firstacktosend)
|
||||
nodes[node].firstacktosend = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
/** Checks if all acks have been received
|
||||
*
|
||||
* \return True if all acks have been received
|
||||
|
@ -588,15 +563,12 @@ void Net_UnAcknowledgePacket(INT32 node)
|
|||
*/
|
||||
static boolean Net_AllAcksReceived(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < MAXACKPACKETS; i++)
|
||||
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||
if (ackpak[i].acknum)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Waits for all ackreturns
|
||||
*
|
||||
|
@ -605,9 +577,6 @@ static boolean Net_AllAcksReceived(void)
|
|||
*/
|
||||
void Net_WaitAllAckReceived(UINT32 timeout)
|
||||
{
|
||||
#ifdef NONET
|
||||
(void)timeout;
|
||||
#else
|
||||
tic_t tictac = I_GetTime();
|
||||
timeout = tictac + timeout*NEWTICRATE;
|
||||
|
||||
|
@ -623,7 +592,6 @@ void Net_WaitAllAckReceived(UINT32 timeout)
|
|||
HGetPacket();
|
||||
Net_AckTicker();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void InitNode(node_t *node)
|
||||
|
@ -637,14 +605,10 @@ static void InitNode(node_t *node)
|
|||
|
||||
static void InitAck(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
#ifndef NONET
|
||||
for (i = 0; i < MAXACKPACKETS; i++)
|
||||
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||
ackpak[i].acknum = 0;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
for (INT32 i = 0; i < MAXNETNODES; i++)
|
||||
InitNode(&nodes[i]);
|
||||
}
|
||||
|
||||
|
@ -655,17 +619,12 @@ static void InitAck(void)
|
|||
*/
|
||||
void Net_AbortPacketType(UINT8 packettype)
|
||||
{
|
||||
#ifdef NONET
|
||||
(void)packettype;
|
||||
#else
|
||||
INT32 i;
|
||||
for (i = 0; i < MAXACKPACKETS; i++)
|
||||
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||
if (ackpak[i].acknum && (ackpak[i].pak.data.packettype == packettype
|
||||
|| packettype == UINT8_MAX))
|
||||
{
|
||||
ackpak[i].acknum = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
@ -675,10 +634,6 @@ void Net_AbortPacketType(UINT8 packettype)
|
|||
// remove a node, clear all ack from this node and reset askret
|
||||
void Net_CloseConnection(INT32 node)
|
||||
{
|
||||
#ifdef NONET
|
||||
(void)node;
|
||||
#else
|
||||
INT32 i;
|
||||
boolean forceclose = (node & FORCECLOSE) != 0;
|
||||
|
||||
if (node == -1)
|
||||
|
@ -708,7 +663,7 @@ void Net_CloseConnection(INT32 node)
|
|||
}
|
||||
|
||||
// check if we are waiting for an ack from this node
|
||||
for (i = 0; i < MAXACKPACKETS; i++)
|
||||
for (INT32 i = 0; i < MAXACKPACKETS; i++)
|
||||
if (ackpak[i].acknum && ackpak[i].destinationnode == node)
|
||||
{
|
||||
if (!forceclose)
|
||||
|
@ -722,10 +677,8 @@ void Net_CloseConnection(INT32 node)
|
|||
if (server)
|
||||
SV_AbortLuaFileTransfer(node);
|
||||
I_NetFreeNodenum(node);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
//
|
||||
// Checksum
|
||||
//
|
||||
|
@ -734,23 +687,20 @@ static UINT32 NetbufferChecksum(void)
|
|||
UINT32 c = 0x1234567;
|
||||
const INT32 l = doomcom->datalength - 4;
|
||||
const UINT8 *buf = (UINT8 *)netbuffer + 4;
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < l; i++, buf++)
|
||||
for (INT32 i = 0; i < l; i++, buf++)
|
||||
c += (*buf) * (i+1);
|
||||
|
||||
return LONG(c);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
|
||||
static void fprintfstring(char *s, size_t len)
|
||||
{
|
||||
INT32 mode = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
for (size_t i = 0; i < len; i++)
|
||||
if (s[i] < 32)
|
||||
{
|
||||
if (!mode)
|
||||
|
@ -810,6 +760,8 @@ static const char *packettypename[NUMPACKETTYPE] =
|
|||
"ASKLUAFILE",
|
||||
"HASLUAFILE",
|
||||
|
||||
"PT_BASICKEEPALIVE",
|
||||
|
||||
"FILEFRAGMENT",
|
||||
"FILEACK",
|
||||
"FILERECEIVED",
|
||||
|
@ -817,7 +769,6 @@ static const char *packettypename[NUMPACKETTYPE] =
|
|||
"TEXTCMD",
|
||||
"TEXTCMD2",
|
||||
"CLIENTJOIN",
|
||||
"NODETIMEOUT",
|
||||
"LOGIN",
|
||||
"TELLFILESNEEDED",
|
||||
"MOREFILESNEEDED",
|
||||
|
@ -921,7 +872,6 @@ void Command_Drop(void)
|
|||
{
|
||||
INT32 packetquantity;
|
||||
const char *packetname;
|
||||
size_t i;
|
||||
|
||||
if (COM_Argc() < 2)
|
||||
{
|
||||
|
@ -951,11 +901,11 @@ void Command_Drop(void)
|
|||
packetname = COM_Argv(1);
|
||||
|
||||
if (!(stricmp(packetname, "all") && stricmp(packetname, "any")))
|
||||
for (i = 0; i < NUMPACKETTYPE; i++)
|
||||
for (size_t i = 0; i < NUMPACKETTYPE; i++)
|
||||
packetdropquantity[i] = packetquantity;
|
||||
else
|
||||
{
|
||||
for (i = 0; i < NUMPACKETTYPE; i++)
|
||||
for (size_t i = 0; i < NUMPACKETTYPE; i++)
|
||||
if (!stricmp(packetname, packettypename[i]))
|
||||
{
|
||||
packetdropquantity[i] = packetquantity;
|
||||
|
@ -986,14 +936,12 @@ void Command_Droprate(void)
|
|||
packetdroprate = droprate;
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
static boolean ShouldDropPacket(void)
|
||||
{
|
||||
return (packetdropquantity[netbuffer->packettype])
|
||||
|| (packetdroprate != 0 && rand() < (RAND_MAX * (packetdroprate / 100.f))) || packetdroprate == 100;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// HSendPacket
|
||||
|
@ -1028,11 +976,6 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen
|
|||
if (!netgame)
|
||||
I_Error("Tried to transmit to another node");
|
||||
|
||||
#ifdef NONET
|
||||
(void)node;
|
||||
(void)reliable;
|
||||
(void)acknum;
|
||||
#else
|
||||
// do this before GetFreeAcknum because this function backups
|
||||
// the current packet
|
||||
doomcom->remotenode = (INT16)node;
|
||||
|
@ -1093,8 +1036,6 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif // ndef NONET
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1112,10 +1053,7 @@ boolean HGetPacket(void)
|
|||
{
|
||||
M_Memcpy(netbuffer, &reboundstore[rebound_tail], reboundsize[rebound_tail]);
|
||||
doomcom->datalength = reboundsize[rebound_tail];
|
||||
if (netbuffer->packettype == PT_NODETIMEOUT)
|
||||
doomcom->remotenode = netbuffer->u.textcmd[0];
|
||||
else
|
||||
doomcom->remotenode = 0;
|
||||
doomcom->remotenode = 0;
|
||||
|
||||
rebound_tail = (rebound_tail+1) % MAXREBOUND;
|
||||
#ifdef DEBUGFILE
|
||||
|
@ -1128,8 +1066,6 @@ boolean HGetPacket(void)
|
|||
if (!netgame)
|
||||
return false;
|
||||
|
||||
#ifndef NONET
|
||||
|
||||
while(true)
|
||||
{
|
||||
//nodejustjoined = I_NetGet();
|
||||
|
@ -1189,7 +1125,6 @@ boolean HGetPacket(void)
|
|||
}
|
||||
break;
|
||||
}
|
||||
#endif // ndef NONET
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1399,13 +1334,12 @@ void Command_Ping_f(void)
|
|||
int name_width = 0;
|
||||
int ms_width = 0;
|
||||
|
||||
int n;
|
||||
INT32 i;
|
||||
|
||||
pingc = 0;
|
||||
for (i = 1; i < MAXPLAYERS; ++i)
|
||||
for (INT32 i = 1; i < MAXPLAYERS; ++i)
|
||||
if (playeringame[i])
|
||||
{
|
||||
int n;
|
||||
|
||||
n = strlen(player_names[i]);
|
||||
if (n > name_width)
|
||||
name_width = n;
|
||||
|
@ -1425,7 +1359,7 @@ void Command_Ping_f(void)
|
|||
|
||||
qsort(pingv, pingc, sizeof (struct pingcell), &pingcellcmp);
|
||||
|
||||
for (i = 0; i < pingc; ++i)
|
||||
for (INT32 i = 0; i < pingc; ++i)
|
||||
{
|
||||
CONS_Printf("%02d : %-*s %*d ms\n",
|
||||
pingv[i].num,
|
||||
|
@ -1441,15 +1375,13 @@ void Command_Ping_f(void)
|
|||
|
||||
void D_CloseConnection(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
if (netgame)
|
||||
{
|
||||
// wait the ackreturn with timout of 5 Sec
|
||||
Net_WaitAllAckReceived(5);
|
||||
|
||||
// close all connection
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
for (INT32 i = 0; i < MAXNETNODES; i++)
|
||||
Net_CloseConnection(i|FORCECLOSE);
|
||||
|
||||
InitAck();
|
|
@ -18,6 +18,8 @@
|
|||
#ifndef __D_NET__
|
||||
#define __D_NET__
|
||||
|
||||
#include "../doomtype.h"
|
||||
|
||||
// Max computers in a game
|
||||
// 127 is probably as high as this can go, because
|
||||
// SINT8 is used for nodes sometimes >:(
|
||||
|
@ -37,10 +39,24 @@ boolean Net_GetNetStat(void);
|
|||
extern INT32 getbytes;
|
||||
extern INT64 sendbytes; // Realtime updated
|
||||
|
||||
extern SINT8 nodetoplayer[MAXNETNODES];
|
||||
extern SINT8 nodetoplayer2[MAXNETNODES]; // Say the numplayer for this node if any (splitscreen)
|
||||
extern UINT8 playerpernode[MAXNETNODES]; // Used specially for splitscreen
|
||||
extern boolean nodeingame[MAXNETNODES]; // Set false as nodes leave game
|
||||
typedef struct netnode_s
|
||||
{
|
||||
boolean ingame; // set false as nodes leave game
|
||||
tic_t freezetimeout; // Until when can this node freeze the server before getting a timeout?
|
||||
|
||||
SINT8 player;
|
||||
SINT8 player2; // say the numplayer for this node if any (splitscreen)
|
||||
UINT8 numplayers; // used specialy for scplitscreen
|
||||
|
||||
tic_t tic; // what tic the client have received
|
||||
tic_t supposedtic; // nettics prevision for smaller packet
|
||||
|
||||
boolean sendingsavegame; // Are we sending the savegame?
|
||||
boolean resendingsavegame; // Are we resending the savegame?
|
||||
tic_t savegameresendcooldown; // How long before we can resend again?
|
||||
} netnode_t;
|
||||
|
||||
extern netnode_t netnodes[MAXNETNODES];
|
||||
|
||||
extern boolean serverrunning;
|
||||
|
||||
|
@ -52,9 +68,6 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum,
|
|||
size_t packetlength);
|
||||
boolean HGetPacket(void);
|
||||
void D_SetDoomcom(void);
|
||||
#ifndef NONET
|
||||
void D_SaveBan(void);
|
||||
#endif
|
||||
boolean D_CheckNetGame(void);
|
||||
void D_CloseConnection(void);
|
||||
void Net_UnAcknowledgePacket(INT32 node);
|
|
@ -12,44 +12,46 @@
|
|||
/// commands are executed through the command buffer
|
||||
/// like console commands, other miscellaneous commands (at the end)
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "../doomdef.h"
|
||||
|
||||
#include "console.h"
|
||||
#include "command.h"
|
||||
#include "i_time.h"
|
||||
#include "i_system.h"
|
||||
#include "g_game.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "g_input.h"
|
||||
#include "m_menu.h"
|
||||
#include "r_local.h"
|
||||
#include "r_skins.h"
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "s_sound.h"
|
||||
#include "i_sound.h"
|
||||
#include "m_misc.h"
|
||||
#include "am_map.h"
|
||||
#include "byteptr.h"
|
||||
#include "../console.h"
|
||||
#include "../command.h"
|
||||
#include "../i_time.h"
|
||||
#include "../i_system.h"
|
||||
#include "../g_game.h"
|
||||
#include "../hu_stuff.h"
|
||||
#include "../g_input.h"
|
||||
#include "../m_menu.h"
|
||||
#include "../r_local.h"
|
||||
#include "../r_skins.h"
|
||||
#include "../p_local.h"
|
||||
#include "../p_setup.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../i_sound.h"
|
||||
#include "../m_misc.h"
|
||||
#include "../am_map.h"
|
||||
#include "../byteptr.h"
|
||||
#include "d_netfil.h"
|
||||
#include "p_spec.h"
|
||||
#include "m_cheat.h"
|
||||
#include "../p_spec.h"
|
||||
#include "../m_cheat.h"
|
||||
#include "d_clisrv.h"
|
||||
#include "server_connection.h"
|
||||
#include "net_command.h"
|
||||
#include "d_net.h"
|
||||
#include "v_video.h"
|
||||
#include "d_main.h"
|
||||
#include "m_random.h"
|
||||
#include "f_finale.h"
|
||||
#include "filesrch.h"
|
||||
#include "../v_video.h"
|
||||
#include "../d_main.h"
|
||||
#include "../m_random.h"
|
||||
#include "../f_finale.h"
|
||||
#include "../filesrch.h"
|
||||
#include "mserv.h"
|
||||
#include "z_zone.h"
|
||||
#include "lua_script.h"
|
||||
#include "lua_hook.h"
|
||||
#include "m_cond.h"
|
||||
#include "m_anigif.h"
|
||||
#include "md5.h"
|
||||
#include "m_perfstats.h"
|
||||
#include "u_list.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../lua_script.h"
|
||||
#include "../lua_hook.h"
|
||||
#include "../m_cond.h"
|
||||
#include "../m_anigif.h"
|
||||
#include "../md5.h"
|
||||
#include "../m_perfstats.h"
|
||||
#include "../u_list.h"
|
||||
|
||||
#ifdef NETGAME_DEVMODE
|
||||
#define CV_RESTRICT CV_NETVAR
|
||||
|
@ -225,6 +227,7 @@ consvar_t cv_seenames = CVAR_INIT ("seenames", "Ally/Foe", CV_SAVE|CV_ALLOWLUA,
|
|||
consvar_t cv_allowseenames = CVAR_INIT ("allowseenames", "Yes", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL);
|
||||
|
||||
// names
|
||||
static char *lastskinnames[2];
|
||||
consvar_t cv_playername = CVAR_INIT ("name", "Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name_OnChange);
|
||||
consvar_t cv_playername2 = CVAR_INIT ("name2", "Tails", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name2_OnChange);
|
||||
// player colors
|
||||
|
@ -594,13 +597,10 @@ void D_RegisterServerCommands(void)
|
|||
CV_RegisterVar(&cv_maxsend);
|
||||
CV_RegisterVar(&cv_noticedownload);
|
||||
CV_RegisterVar(&cv_downloadspeed);
|
||||
#ifndef NONET
|
||||
CV_RegisterVar(&cv_allownewplayer);
|
||||
CV_RegisterVar(&cv_joinnextround);
|
||||
CV_RegisterVar(&cv_showjoinaddress);
|
||||
CV_RegisterVar(&cv_blamecfail);
|
||||
CV_RegisterVar(&cv_dedicatedidletime);
|
||||
#endif
|
||||
|
||||
COM_AddCommand("ping", Command_Ping_f, COM_LUA);
|
||||
CV_RegisterVar(&cv_nettimeout);
|
||||
|
@ -1208,45 +1208,47 @@ UINT8 CanChangeSkin(INT32 playernum)
|
|||
|
||||
static void ForceAllSkins(INT32 forcedskin)
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
for (INT32 i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
||||
SetPlayerSkinByNum(i, forcedskin);
|
||||
|
||||
// If it's me (or my brother), set appropriate skin value in cv_skin/cv_skin2
|
||||
if (!dedicated) // But don't do this for dedicated servers, of course.
|
||||
{
|
||||
if (i == consoleplayer)
|
||||
CV_StealthSet(&cv_skin, skins[forcedskin].name);
|
||||
else if (i == secondarydisplayplayer)
|
||||
CV_StealthSet(&cv_skin2, skins[forcedskin].name);
|
||||
}
|
||||
if (playeringame[i])
|
||||
SetPlayerSkinByNum(i, forcedskin);
|
||||
}
|
||||
}
|
||||
|
||||
static INT32 snacpending = 0, snac2pending = 0, chmappending = 0;
|
||||
|
||||
static void SetSkinLocal(INT32 playernum, INT32 skinnum)
|
||||
{
|
||||
if (metalrecording && playernum == consoleplayer)
|
||||
{
|
||||
// Starring Metal Sonic as themselves, obviously.
|
||||
SetPlayerSkinByNum(playernum, 5);
|
||||
return;
|
||||
}
|
||||
|
||||
if (skinnum != -1 && R_SkinUsable(playernum, skinnum))
|
||||
SetPlayerSkinByNum(playernum, skinnum);
|
||||
else
|
||||
SetPlayerSkinByNum(playernum, GetPlayerDefaultSkin(playernum));
|
||||
}
|
||||
|
||||
static void SetColorLocal(INT32 playernum, UINT16 color)
|
||||
{
|
||||
players[playernum].skincolor = color;
|
||||
|
||||
if (players[playernum].mo && !players[playernum].powers[pw_dye])
|
||||
players[playernum].mo->color = P_GetPlayerColor(&players[playernum]);
|
||||
}
|
||||
|
||||
// name, color, or skin has changed
|
||||
//
|
||||
static void SendNameAndColor(void)
|
||||
{
|
||||
char buf[MAXPLAYERNAME+6];
|
||||
char buf[MAXPLAYERNAME+7];
|
||||
char *p;
|
||||
|
||||
p = buf;
|
||||
|
||||
// normal player colors
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
if (players[consoleplayer].ctfteam == 1 && cv_playercolor.value != skincolor_redteam)
|
||||
CV_StealthSetValue(&cv_playercolor, skincolor_redteam);
|
||||
else if (players[consoleplayer].ctfteam == 2 && cv_playercolor.value != skincolor_blueteam)
|
||||
CV_StealthSetValue(&cv_playercolor, skincolor_blueteam);
|
||||
}
|
||||
|
||||
// don't allow inaccessible colors
|
||||
if (!skincolors[cv_playercolor.value].accessible)
|
||||
{
|
||||
|
@ -1277,50 +1279,15 @@ static void SendNameAndColor(void)
|
|||
// If you're not in a netgame, merely update the skin, color, and name.
|
||||
if (!netgame)
|
||||
{
|
||||
INT32 foundskin;
|
||||
|
||||
CleanupPlayerName(consoleplayer, cv_playername.zstring);
|
||||
strcpy(player_names[consoleplayer], cv_playername.zstring);
|
||||
|
||||
players[consoleplayer].skincolor = cv_playercolor.value;
|
||||
SetColorLocal(consoleplayer, cv_playercolor.value);
|
||||
|
||||
if (players[consoleplayer].mo && !players[consoleplayer].powers[pw_dye])
|
||||
players[consoleplayer].mo->color = players[consoleplayer].skincolor;
|
||||
|
||||
if (metalrecording)
|
||||
{ // Starring Metal Sonic as themselves, obviously.
|
||||
SetPlayerSkinByNum(consoleplayer, 5);
|
||||
CV_StealthSet(&cv_skin, skins[5].name);
|
||||
}
|
||||
else if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1 && R_SkinUsable(consoleplayer, foundskin))
|
||||
{
|
||||
//boolean notsame;
|
||||
|
||||
cv_skin.value = foundskin;
|
||||
|
||||
//notsame = (cv_skin.value != players[consoleplayer].skin);
|
||||
|
||||
SetPlayerSkin(consoleplayer, cv_skin.string);
|
||||
CV_StealthSet(&cv_skin, skins[cv_skin.value].name);
|
||||
|
||||
/*if (notsame)
|
||||
{
|
||||
CV_StealthSetValue(&cv_playercolor, skins[cv_skin.value].prefcolor);
|
||||
|
||||
players[consoleplayer].skincolor = cv_playercolor.value % numskincolors;
|
||||
|
||||
if (players[consoleplayer].mo)
|
||||
players[consoleplayer].mo->color = (UINT16)players[consoleplayer].skincolor;
|
||||
}*/
|
||||
}
|
||||
if (splitscreen)
|
||||
SetSkinLocal(consoleplayer, R_SkinAvailable(cv_skin.string));
|
||||
else
|
||||
{
|
||||
cv_skin.value = players[consoleplayer].skin;
|
||||
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
|
||||
// will always be same as current
|
||||
SetPlayerSkin(consoleplayer, cv_skin.string);
|
||||
}
|
||||
|
||||
SetSkinLocal(consoleplayer, pickedchar);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1337,10 +1304,6 @@ static void SendNameAndColor(void)
|
|||
else // Cleanup name if changing it
|
||||
CleanupPlayerName(consoleplayer, cv_playername.zstring);
|
||||
|
||||
// Don't change skin if the server doesn't want you to.
|
||||
if (!CanChangeSkin(consoleplayer))
|
||||
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
|
||||
|
||||
// check if player has the skin loaded (cv_skin may have
|
||||
// the name of a skin that was available in the previous game)
|
||||
cv_skin.value = R_SkinAvailable(cv_skin.string);
|
||||
|
@ -1372,16 +1335,6 @@ static void SendNameAndColor2(void)
|
|||
else // HACK
|
||||
secondplaya = 1;
|
||||
|
||||
// normal player colors
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
if (players[secondplaya].ctfteam == 1 && cv_playercolor2.value != skincolor_redteam)
|
||||
CV_StealthSetValue(&cv_playercolor2, skincolor_redteam);
|
||||
else if (players[secondplaya].ctfteam == 2 && cv_playercolor2.value != skincolor_blueteam)
|
||||
CV_StealthSetValue(&cv_playercolor2, skincolor_blueteam);
|
||||
}
|
||||
|
||||
// don't allow inaccessible colors
|
||||
if (!skincolors[cv_playercolor2.value].accessible)
|
||||
{
|
||||
if (players[secondplaya].skincolor && skincolors[players[secondplaya].skincolor].accessible)
|
||||
|
@ -1403,63 +1356,24 @@ static void SendNameAndColor2(void)
|
|||
if (!Playing())
|
||||
return;
|
||||
|
||||
// If you're not in a netgame, merely update the skin, color, and name.
|
||||
if (botingame)
|
||||
{
|
||||
players[secondplaya].skincolor = botcolor;
|
||||
if (players[secondplaya].mo && !players[secondplaya].powers[pw_dye])
|
||||
players[secondplaya].mo->color = players[secondplaya].skincolor;
|
||||
|
||||
SetColorLocal(secondplaya, botcolor);
|
||||
SetPlayerSkinByNum(secondplaya, botskin-1);
|
||||
return;
|
||||
}
|
||||
else if (!netgame)
|
||||
{
|
||||
INT32 foundskin;
|
||||
|
||||
// If you're not in a netgame, merely update the skin, color, and name.
|
||||
CleanupPlayerName(secondplaya, cv_playername2.zstring);
|
||||
strcpy(player_names[secondplaya], cv_playername2.zstring);
|
||||
|
||||
// don't use secondarydisplayplayer: the second player must be 1
|
||||
players[secondplaya].skincolor = cv_playercolor2.value;
|
||||
if (players[secondplaya].mo && !players[secondplaya].powers[pw_dye])
|
||||
players[secondplaya].mo->color = players[secondplaya].skincolor;
|
||||
SetColorLocal(secondplaya, cv_playercolor2.value);
|
||||
|
||||
if (cv_forceskin.value >= 0 && (netgame || multiplayer)) // Server wants everyone to use the same player
|
||||
{
|
||||
const INT32 forcedskin = cv_forceskin.value;
|
||||
|
||||
SetPlayerSkinByNum(secondplaya, forcedskin);
|
||||
CV_StealthSet(&cv_skin2, skins[forcedskin].name);
|
||||
}
|
||||
else if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1 && R_SkinUsable(secondplaya, foundskin))
|
||||
{
|
||||
//boolean notsame;
|
||||
|
||||
cv_skin2.value = foundskin;
|
||||
|
||||
//notsame = (cv_skin2.value != players[secondplaya].skin);
|
||||
|
||||
SetPlayerSkin(secondplaya, cv_skin2.string);
|
||||
CV_StealthSet(&cv_skin2, skins[cv_skin2.value].name);
|
||||
|
||||
/*if (notsame)
|
||||
{
|
||||
CV_StealthSetValue(&cv_playercolor2, skins[players[secondplaya].skin].prefcolor);
|
||||
|
||||
players[secondplaya].skincolor = cv_playercolor2.value % numskincolors;
|
||||
|
||||
if (players[secondplaya].mo)
|
||||
players[secondplaya].mo->color = players[secondplaya].skincolor;
|
||||
}*/
|
||||
}
|
||||
if (cv_forceskin.value >= 0)
|
||||
SetSkinLocal(secondplaya, cv_forceskin.value);
|
||||
else
|
||||
{
|
||||
cv_skin2.value = players[secondplaya].skin;
|
||||
CV_StealthSet(&cv_skin2, skins[players[secondplaya].skin].name);
|
||||
// will always be same as current
|
||||
SetPlayerSkin(secondplaya, cv_skin2.string);
|
||||
}
|
||||
SetSkinLocal(secondplaya, R_SkinAvailable(cv_skin2.string));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1503,7 +1417,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
|||
// set color
|
||||
p->skincolor = color % numskincolors;
|
||||
if (p->mo)
|
||||
p->mo->color = (UINT16)p->skincolor;
|
||||
p->mo->color = P_GetPlayerColor(p);
|
||||
|
||||
// normal player colors
|
||||
if (server && (p != &players[consoleplayer] && p != &players[secondarydisplayplayer]))
|
||||
|
@ -1512,15 +1426,6 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
|||
UINT32 unlockShift = 0;
|
||||
UINT32 i;
|
||||
|
||||
// team colors
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
if (p->ctfteam == 1 && p->skincolor != skincolor_redteam)
|
||||
kick = true;
|
||||
else if (p->ctfteam == 2 && p->skincolor != skincolor_blueteam)
|
||||
kick = true;
|
||||
}
|
||||
|
||||
// don't allow inaccessible colors
|
||||
if (skincolors[p->skincolor].accessible == false)
|
||||
kick = true;
|
||||
|
@ -1561,16 +1466,9 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
|||
}
|
||||
|
||||
// set skin
|
||||
if (cv_forceskin.value >= 0 && (netgame || multiplayer)) // Server wants everyone to use the same player
|
||||
{
|
||||
const INT32 forcedskin = cv_forceskin.value;
|
||||
INT32 forcedskin = R_GetForcedSkin(playernum);
|
||||
if (forcedskin != -1 && (netgame || multiplayer)) // Server wants everyone to use the same player (or the level is forcing one.)
|
||||
SetPlayerSkinByNum(playernum, forcedskin);
|
||||
|
||||
if (playernum == consoleplayer)
|
||||
CV_StealthSet(&cv_skin, skins[forcedskin].name);
|
||||
else if (playernum == secondarydisplayplayer)
|
||||
CV_StealthSet(&cv_skin2, skins[forcedskin].name);
|
||||
}
|
||||
else
|
||||
SetPlayerSkinByNum(playernum, skin);
|
||||
}
|
||||
|
@ -1846,8 +1744,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
|
|||
// reset players if there is a new one
|
||||
if (!IsPlayerAdmin(consoleplayer))
|
||||
{
|
||||
if (SV_SpawnServer())
|
||||
buf[0] &= ~(1<<1);
|
||||
SV_SpawnServer();
|
||||
if (!Playing()) // you failed to start a server somehow, so cancel the map change
|
||||
return;
|
||||
}
|
||||
|
@ -2180,7 +2077,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
{
|
||||
SetPlayerSkinByNum(0, cv_chooseskin.value-1);
|
||||
players[0].skincolor = skins[players[0].skin].prefcolor;
|
||||
CV_StealthSetValue(&cv_playercolor, players[0].skincolor);
|
||||
}
|
||||
|
||||
mapnumber = M_MapNumber(mapname[3], mapname[4]);
|
||||
|
@ -2934,17 +2830,6 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
|||
displayplayer = consoleplayer;
|
||||
}
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
if (NetPacket.packet.newteam)
|
||||
{
|
||||
if (playernum == consoleplayer) //CTF and Team Match colors.
|
||||
CV_SetValue(&cv_playercolor, NetPacket.packet.newteam + 5);
|
||||
else if (playernum == secondarydisplayplayer)
|
||||
CV_SetValue(&cv_playercolor2, NetPacket.packet.newteam + 5);
|
||||
}
|
||||
}
|
||||
|
||||
// In tag, check to see if you still have a game.
|
||||
if (G_TagGametype())
|
||||
P_CheckSurvivors();
|
||||
|
@ -4823,11 +4708,16 @@ static void ForceSkin_OnChange(void)
|
|||
return;
|
||||
|
||||
if (cv_forceskin.value < 0)
|
||||
{
|
||||
CONS_Printf("The server has lifted the forced skin restrictions.\n");
|
||||
if (Playing())
|
||||
D_SendPlayerConfig();
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf("The server is restricting all players to skin \"%s\".\n",skins[cv_forceskin.value].name);
|
||||
ForceAllSkins(cv_forceskin.value);
|
||||
if (Playing())
|
||||
ForceAllSkins(cv_forceskin.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4841,7 +4731,6 @@ static void Name_OnChange(void)
|
|||
}
|
||||
else
|
||||
SendNameAndColor();
|
||||
|
||||
}
|
||||
|
||||
static void Name2_OnChange(void)
|
||||
|
@ -4864,19 +4753,33 @@ static void Skin_OnChange(void)
|
|||
if (!Playing())
|
||||
return; // do whatever you want
|
||||
|
||||
if (!(cv_debug || devparm) && !(multiplayer || netgame) // In single player.
|
||||
&& (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y
|
||||
if (lastskinnames[0] == NULL)
|
||||
lastskinnames[0] = Z_StrDup(cv_skin.string);
|
||||
|
||||
if (!(multiplayer || netgame)) // In single player.
|
||||
{
|
||||
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
|
||||
if (!(cv_debug || devparm)
|
||||
&& (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y
|
||||
{
|
||||
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
|
||||
return;
|
||||
}
|
||||
|
||||
// Just do it here if devmode is enabled
|
||||
SetSkinLocal(consoleplayer, R_SkinAvailable(cv_skin.string));
|
||||
return;
|
||||
}
|
||||
|
||||
if (CanChangeSkin(consoleplayer) && !P_PlayerMoving(consoleplayer))
|
||||
{
|
||||
SendNameAndColor();
|
||||
Z_Free(lastskinnames[0]);
|
||||
lastskinnames[0] = Z_StrDup(cv_skin.string);
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
|
||||
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
|
||||
CV_StealthSet(&cv_skin, lastskinnames[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4890,12 +4793,19 @@ static void Skin2_OnChange(void)
|
|||
if (!Playing() || !splitscreen)
|
||||
return; // do whatever you want
|
||||
|
||||
if (lastskinnames[1] == NULL)
|
||||
lastskinnames[1] = Z_StrDup(cv_skin2.string);
|
||||
|
||||
if (CanChangeSkin(secondarydisplayplayer) && !P_PlayerMoving(secondarydisplayplayer))
|
||||
{
|
||||
SendNameAndColor2();
|
||||
Z_Free(lastskinnames[1]);
|
||||
lastskinnames[1] = Z_StrDup(cv_skin.string);
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
|
||||
CV_StealthSet(&cv_skin2, skins[players[secondarydisplayplayer].skin].name);
|
||||
CV_StealthSet(&cv_skin2, lastskinnames[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4905,15 +4815,18 @@ static void Skin2_OnChange(void)
|
|||
*/
|
||||
static void Color_OnChange(void)
|
||||
{
|
||||
if (!Playing()) {
|
||||
if (!Playing())
|
||||
{
|
||||
if (!cv_playercolor.value || !skincolors[cv_playercolor.value].accessible)
|
||||
CV_StealthSetValue(&cv_playercolor, lastgoodcolor);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player.
|
||||
if (!(multiplayer || netgame)) // In single player.
|
||||
{
|
||||
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
|
||||
// Just do it here if devmode is enabled
|
||||
if (cv_debug || devparm)
|
||||
SetColorLocal(consoleplayer, cv_playercolor.value);
|
||||
return;
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
#ifndef __D_NETCMD__
|
||||
#define __D_NETCMD__
|
||||
|
||||
#include "command.h"
|
||||
#include "../command.h"
|
||||
|
||||
// console vars
|
||||
extern consvar_t cv_playername;
|
|
@ -31,24 +31,25 @@
|
|||
#include <sys/utime.h>
|
||||
#endif
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "d_main.h"
|
||||
#include "g_game.h"
|
||||
#include "i_time.h"
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../d_main.h"
|
||||
#include "../g_game.h"
|
||||
#include "../i_time.h"
|
||||
#include "i_net.h"
|
||||
#include "i_system.h"
|
||||
#include "m_argv.h"
|
||||
#include "../i_system.h"
|
||||
#include "../m_argv.h"
|
||||
#include "d_net.h"
|
||||
#include "w_wad.h"
|
||||
#include "../w_wad.h"
|
||||
#include "d_netfil.h"
|
||||
#include "z_zone.h"
|
||||
#include "byteptr.h"
|
||||
#include "p_setup.h"
|
||||
#include "m_misc.h"
|
||||
#include "m_menu.h"
|
||||
#include "md5.h"
|
||||
#include "filesrch.h"
|
||||
#include "net_command.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../byteptr.h"
|
||||
#include "../p_setup.h"
|
||||
#include "../m_misc.h"
|
||||
#include "../m_menu.h"
|
||||
#include "../md5.h"
|
||||
#include "../filesrch.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -103,26 +104,31 @@ typedef struct
|
|||
} pauseddownload_t;
|
||||
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
|
||||
|
||||
luafiletransfer_t *luafiletransfers = NULL;
|
||||
boolean waitingforluafiletransfer = false;
|
||||
boolean waitingforluafilecommand = false;
|
||||
char luafiledir[256 + 16] = "luafiles";
|
||||
|
||||
// max file size to send to a player (in kilobytes)
|
||||
static CV_PossibleValue_t maxsend_cons_t[] = {{0, "MIN"}, {204800, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_maxsend = CVAR_INIT ("maxsend", "4096", CV_SAVE|CV_NETVAR, maxsend_cons_t, NULL);
|
||||
|
||||
consvar_t cv_noticedownload = CVAR_INIT ("noticedownload", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL);
|
||||
|
||||
// Speed of file downloading (in packets per tic)
|
||||
static CV_PossibleValue_t downloadspeed_cons_t[] = {{1, "MIN"}, {300, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_downloadspeed = CVAR_INIT ("downloadspeed", "16", CV_SAVE|CV_NETVAR, downloadspeed_cons_t, NULL);
|
||||
|
||||
static UINT16 GetWadNumFromFileNeededId(UINT8 id)
|
||||
{
|
||||
UINT16 wadnum;
|
||||
|
||||
for (wadnum = mainwads; wadnum < numwadfiles; wadnum++)
|
||||
for (UINT16 wadnum = mainwads; wadnum < numwadfiles; wadnum++)
|
||||
{
|
||||
if (!wadfiles[wadnum]->important)
|
||||
continue;
|
||||
|
@ -142,14 +148,13 @@ static UINT16 GetWadNumFromFileNeededId(UINT8 id)
|
|||
*/
|
||||
UINT8 *PutFileNeeded(UINT16 firstfile)
|
||||
{
|
||||
size_t i;
|
||||
UINT8 count = 0;
|
||||
UINT8 *p_start = netbuffer->packettype == PT_MOREFILESNEEDED ? netbuffer->u.filesneededcfg.files : netbuffer->u.serverinfo.fileneeded;
|
||||
UINT8 *p = p_start;
|
||||
char wadfilename[MAX_WADPATH] = "";
|
||||
UINT8 filestatus, folder;
|
||||
|
||||
for (i = mainwads; i < numwadfiles; i++) //mainwads, otherwise we start on the first mainwad
|
||||
for (size_t i = mainwads; i < numwadfiles; i++) //mainwads, 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)
|
||||
|
@ -224,7 +229,6 @@ void FreeFileNeeded(void)
|
|||
*/
|
||||
void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 firstfile)
|
||||
{
|
||||
INT32 i;
|
||||
UINT8 *p;
|
||||
UINT8 filestatus;
|
||||
|
||||
|
@ -233,7 +237,7 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi
|
|||
|
||||
AllocFileNeeded(fileneedednum);
|
||||
|
||||
for (i = firstfile; i < fileneedednum; i++)
|
||||
for (INT32 i = firstfile; i < fileneedednum; i++)
|
||||
{
|
||||
fileneeded[i].type = FILENEEDED_WAD;
|
||||
fileneeded[i].status = FS_NOTCHECKED; // We haven't even started looking for the file yet
|
||||
|
@ -250,9 +254,7 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi
|
|||
|
||||
void CL_PrepareDownloadSaveGame(const char *tmpsave)
|
||||
{
|
||||
#ifndef NONET
|
||||
lastfilenum = -1;
|
||||
#endif
|
||||
|
||||
FreeFileNeeded();
|
||||
AllocFileNeeded(1);
|
||||
|
@ -275,9 +277,9 @@ void CL_PrepareDownloadSaveGame(const char *tmpsave)
|
|||
*/
|
||||
boolean CL_CheckDownloadable(void)
|
||||
{
|
||||
UINT8 i,dlstatus = 0;
|
||||
UINT8 dlstatus = 0;
|
||||
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
for (UINT8 i = 0; i < fileneedednum; i++)
|
||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN)
|
||||
{
|
||||
if (fileneeded[i].willsend == 1)
|
||||
|
@ -298,7 +300,7 @@ boolean CL_CheckDownloadable(void)
|
|||
|
||||
// not downloadable, put reason in console
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("You need additional files to connect to this server:\n"));
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
for (UINT8 i = 0; i < fileneedednum; i++)
|
||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN)
|
||||
{
|
||||
CONS_Printf(" * \"%s\" (%dK)", fileneeded[i].filename, fileneeded[i].totalsize >> 10);
|
||||
|
@ -368,14 +370,13 @@ void CL_AbortDownloadResume(void)
|
|||
boolean CL_SendFileRequest(void)
|
||||
{
|
||||
char *p;
|
||||
INT32 i;
|
||||
INT64 totalfreespaceneeded = 0, availablefreespace;
|
||||
|
||||
#ifdef PARANOIA
|
||||
if (M_CheckParm("-nodownload"))
|
||||
I_Error("Attempted to download files in -nodownload mode");
|
||||
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
for (INT32 i = 0; i < fileneedednum; i++)
|
||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN
|
||||
&& (fileneeded[i].willsend == 0 || fileneeded[i].willsend == 2))
|
||||
{
|
||||
|
@ -385,7 +386,7 @@ boolean CL_SendFileRequest(void)
|
|||
|
||||
netbuffer->packettype = PT_REQUESTFILE;
|
||||
p = (char *)netbuffer->u.textcmd;
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
for (INT32 i = 0; i < fileneedednum; i++)
|
||||
if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD))
|
||||
{
|
||||
totalfreespaceneeded += fileneeded[i].totalsize;
|
||||
|
@ -413,26 +414,31 @@ boolean CL_SendFileRequest(void)
|
|||
}
|
||||
|
||||
// get request filepak and put it on the send queue
|
||||
// returns false if a requested file was not found or cannot be sent
|
||||
boolean PT_RequestFile(INT32 node)
|
||||
void PT_RequestFile(SINT8 node)
|
||||
{
|
||||
UINT8 *p = netbuffer->u.textcmd;
|
||||
UINT8 id;
|
||||
|
||||
if (client || !cv_downloading.value)
|
||||
{
|
||||
Net_CloseConnection(node); // close connection if you are not the server or disabled downloading
|
||||
return;
|
||||
}
|
||||
|
||||
while (p < netbuffer->u.textcmd + MAXTEXTCMD-1) // Don't allow hacked client to overflow
|
||||
{
|
||||
id = READUINT8(p);
|
||||
UINT8 id = READUINT8(p);
|
||||
if (id == 0xFF)
|
||||
break;
|
||||
|
||||
if (!AddFileToSendQueue(node, id))
|
||||
{
|
||||
SV_AbortSendFiles(node);
|
||||
return false; // don't read the rest of the files
|
||||
Net_CloseConnection(node); // close connection if one of the requested files could not be sent
|
||||
return; // don't read the rest of the files
|
||||
}
|
||||
}
|
||||
|
||||
return true; // no problems with any files
|
||||
return; // no problems with any files
|
||||
}
|
||||
|
||||
/** Checks if the files needed aren't already loaded or on the disk
|
||||
|
@ -531,9 +537,7 @@ INT32 CL_CheckFiles(void)
|
|||
// Load it now
|
||||
boolean CL_LoadServerFiles(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
for (INT32 i = 0; i < fileneedednum; i++)
|
||||
{
|
||||
if (fileneeded[i].status == FS_OPEN)
|
||||
continue; // Already loaded
|
||||
|
@ -629,11 +633,10 @@ void AddLuaFileTransfer(const char *filename, const char *mode)
|
|||
|
||||
static void SV_PrepareSendLuaFileToNextNode(void)
|
||||
{
|
||||
INT32 i;
|
||||
UINT8 success = 1;
|
||||
|
||||
// Find a client to send the file to
|
||||
for (i = 1; i < MAXNETNODES; i++)
|
||||
for (INT32 i = 1; i < MAXNETNODES; i++)
|
||||
if (luafiletransfers->nodestatus[i] == LFTNS_WAITING) // Node waiting
|
||||
{
|
||||
// Tell the client we're about to send them the file
|
||||
|
@ -655,13 +658,12 @@ static void SV_PrepareSendLuaFileToNextNode(void)
|
|||
void SV_PrepareSendLuaFile(void)
|
||||
{
|
||||
char *binfilename;
|
||||
INT32 i;
|
||||
|
||||
luafiletransfers->ongoing = true;
|
||||
|
||||
// Set status to "waiting" for everyone
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
luafiletransfers->nodestatus[i] = (nodeingame[i] ? LFTNS_WAITING : LFTNS_NONE);
|
||||
for (INT32 i = 0; i < MAXNETNODES; i++)
|
||||
luafiletransfers->nodestatus[i] = (netnodes[i].ingame ? LFTNS_WAITING : LFTNS_NONE);
|
||||
|
||||
if (FIL_ReadFileOK(luafiletransfers->realfilename))
|
||||
{
|
||||
|
@ -1137,12 +1139,13 @@ void FileSendTicker(void)
|
|||
}
|
||||
}
|
||||
|
||||
void PT_FileAck(void)
|
||||
void PT_FileAck(SINT8 node)
|
||||
{
|
||||
fileack_pak *packet = &netbuffer->u.fileack;
|
||||
INT32 node = doomcom->remotenode;
|
||||
filetran_t *trans = &transfer[node];
|
||||
INT32 i, j;
|
||||
|
||||
if (client)
|
||||
return;
|
||||
|
||||
// Wrong file id? Ignore it, it's probably a late packet
|
||||
if (!(trans->txlist && packet->fileid == trans->txlist->fileid))
|
||||
|
@ -1161,11 +1164,11 @@ void PT_FileAck(void)
|
|||
trans->dontsenduntil = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < packet->numsegments; i++)
|
||||
for (INT32 i = 0; i < packet->numsegments; i++)
|
||||
{
|
||||
fileacksegment_t *segment = &packet->segments[i];
|
||||
|
||||
for (j = 0; j < 32; j++)
|
||||
for (INT32 j = 0; j < 32; j++)
|
||||
if (LONG(segment->acks) & (1 << j))
|
||||
{
|
||||
if (LONG(segment->start) * FILEFRAGMENTSIZE >= trans->txlist->size)
|
||||
|
@ -1190,24 +1193,23 @@ void PT_FileAck(void)
|
|||
}
|
||||
}
|
||||
|
||||
void PT_FileReceived(void)
|
||||
void PT_FileReceived(SINT8 node)
|
||||
{
|
||||
filetx_t *trans = transfer[doomcom->remotenode].txlist;
|
||||
filetx_t *trans = transfer[node].txlist;
|
||||
|
||||
if (trans && netbuffer->u.filereceived == trans->fileid)
|
||||
SV_EndFileSend(doomcom->remotenode);
|
||||
if (server && trans && netbuffer->u.filereceived == trans->fileid)
|
||||
SV_EndFileSend(node);
|
||||
}
|
||||
|
||||
static void SendAckPacket(fileack_pak *packet, UINT8 fileid)
|
||||
{
|
||||
size_t packetsize;
|
||||
INT32 i;
|
||||
|
||||
packetsize = sizeof(*packet) + packet->numsegments * sizeof(*packet->segments);
|
||||
|
||||
// Finalise the packet
|
||||
packet->fileid = fileid;
|
||||
for (i = 0; i < packet->numsegments; i++)
|
||||
for (INT32 i = 0; i < packet->numsegments; i++)
|
||||
{
|
||||
packet->segments[i].start = LONG(packet->segments[i].start);
|
||||
packet->segments[i].acks = LONG(packet->segments[i].acks);
|
||||
|
@ -1247,9 +1249,7 @@ static void AddFragmentToAckPacket(fileack_pak *packet, UINT8 iteration, UINT32
|
|||
|
||||
void FileReceiveTicker(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
for (INT32 i = 0; i < fileneedednum; i++)
|
||||
{
|
||||
fileneeded_t *file = &fileneeded[i];
|
||||
|
||||
|
@ -1263,8 +1263,7 @@ void FileReceiveTicker(void)
|
|||
if (file->ackresendposition != UINT32_MAX && file->status == FS_DOWNLOADING)
|
||||
{
|
||||
// Acknowledge ~70 MB/s, whichs means the client sends ~18 KB/s
|
||||
INT32 j;
|
||||
for (j = 0; j < 2048; j++)
|
||||
for (INT32 j = 0; j < 2048; j++)
|
||||
{
|
||||
if (file->receivedfragments[file->ackresendposition])
|
||||
AddFragmentToAckPacket(file->ackpacket, file->iteration, file->ackresendposition, i);
|
||||
|
@ -1281,8 +1280,27 @@ void FileReceiveTicker(void)
|
|||
}
|
||||
}
|
||||
|
||||
void PT_FileFragment(void)
|
||||
void PT_FileFragment(SINT8 node, INT32 netconsole)
|
||||
{
|
||||
if (netnodes[node].ingame)
|
||||
{
|
||||
// Only accept PT_FILEFRAGMENT from the server.
|
||||
if (node != servernode)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_FILEFRAGMENT", node);
|
||||
if (server)
|
||||
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
if (server)
|
||||
return;
|
||||
}
|
||||
else if (server || node != servernode)
|
||||
{
|
||||
Net_CloseConnection(node);
|
||||
return;
|
||||
}
|
||||
|
||||
INT32 filenum = netbuffer->u.filetxpak.fileid;
|
||||
fileneeded_t *file = &fileneeded[filenum];
|
||||
UINT32 fragmentpos = LONG(netbuffer->u.filetxpak.position);
|
||||
|
@ -1439,9 +1457,7 @@ void PT_FileFragment(void)
|
|||
I_Error("Received a file not requested (file id: %d, file status: %s)\n", filenum, s);
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
lastfilenum = filenum;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Checks if a node is downloading a file
|
||||
|
@ -1469,15 +1485,14 @@ void SV_AbortSendFiles(INT32 node)
|
|||
|
||||
void CloseNetFile(void)
|
||||
{
|
||||
INT32 i;
|
||||
// Is sending?
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
for (INT32 i = 0; i < MAXNETNODES; i++)
|
||||
SV_AbortSendFiles(i);
|
||||
|
||||
// Receiving a file?
|
||||
if (fileneeded)
|
||||
{
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
for (INT32 i = 0; i < fileneedednum; i++)
|
||||
if (fileneeded[i].status == FS_DOWNLOADING && fileneeded[i].file)
|
||||
{
|
||||
fclose(fileneeded[i].file);
|
||||
|
@ -1510,9 +1525,7 @@ void CloseNetFile(void)
|
|||
|
||||
void Command_Downloads_f(void)
|
||||
{
|
||||
INT32 node;
|
||||
|
||||
for (node = 0; node < MAXNETNODES; node++)
|
||||
for (INT32 node = 0; node < MAXNETNODES; node++)
|
||||
if (transfer[node].txlist
|
||||
&& transfer[node].txlist->ram == SF_FILE) // Node is downloading a file?
|
||||
{
|
||||
|
@ -1546,14 +1559,11 @@ void Command_Downloads_f(void)
|
|||
|
||||
void nameonly(char *s)
|
||||
{
|
||||
size_t j, len;
|
||||
void *ns;
|
||||
|
||||
for (j = strlen(s); j != (size_t)-1; j--)
|
||||
for (size_t j = strlen(s); j != (size_t)-1; j--)
|
||||
if ((s[j] == '\\') || (s[j] == ':') || (s[j] == '/'))
|
||||
{
|
||||
ns = &(s[j+1]);
|
||||
len = strlen(ns);
|
||||
void *ns = &(s[j+1]);
|
||||
size_t len = strlen(ns);
|
||||
#if 0
|
||||
M_Memcpy(s, ns, len+1);
|
||||
#else
|
||||
|
@ -1566,9 +1576,9 @@ void nameonly(char *s)
|
|||
// Returns the length in characters of the last element of a path.
|
||||
size_t nameonlylength(const char *s)
|
||||
{
|
||||
size_t j, len = strlen(s);
|
||||
size_t len = strlen(s);
|
||||
|
||||
for (j = len; j != (size_t)-1; j--)
|
||||
for (size_t j = len; j != (size_t)-1; j--)
|
||||
if ((s[j] == '\\') || (s[j] == ':') || (s[j] == '/'))
|
||||
return len - j - 1;
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include "d_net.h"
|
||||
#include "d_clisrv.h"
|
||||
#include "w_wad.h"
|
||||
#include "../w_wad.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -70,13 +70,13 @@ extern INT32 fileneedednum;
|
|||
extern fileneeded_t *fileneeded;
|
||||
extern char downloaddir[512];
|
||||
|
||||
#ifndef NONET
|
||||
extern INT32 lastfilenum;
|
||||
extern INT32 downloadcompletednum;
|
||||
extern UINT32 downloadcompletedsize;
|
||||
extern INT32 totalfilesrequestednum;
|
||||
extern UINT32 totalfilesrequestedsize;
|
||||
#endif
|
||||
|
||||
extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||
|
||||
void AllocFileNeeded(INT32 size);
|
||||
void FreeFileNeeded(void);
|
||||
|
@ -90,16 +90,16 @@ void AddRamToSendQueue(INT32 node, void *data, size_t size, freemethod_t freemet
|
|||
UINT8 fileid);
|
||||
|
||||
void FileSendTicker(void);
|
||||
void PT_FileAck(void);
|
||||
void PT_FileReceived(void);
|
||||
void PT_FileAck(SINT8 node);
|
||||
void PT_FileReceived(SINT8 node);
|
||||
boolean SendingFile(INT32 node);
|
||||
|
||||
void FileReceiveTicker(void);
|
||||
void PT_FileFragment(void);
|
||||
void PT_FileFragment(SINT8 node, INT32 netconsole);
|
||||
|
||||
boolean CL_CheckDownloadable(void);
|
||||
boolean CL_SendFileRequest(void);
|
||||
boolean PT_RequestFile(INT32 node);
|
||||
void PT_RequestFile(SINT8 node);
|
||||
|
||||
typedef enum
|
||||
{
|
336
src/netcode/gamestate.c
Normal file
336
src/netcode/gamestate.c
Normal file
|
@ -0,0 +1,336 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file gamestate.c
|
||||
/// \brief Gamestate (re)sending
|
||||
|
||||
#include "d_clisrv.h"
|
||||
#include "d_netfil.h"
|
||||
#include "gamestate.h"
|
||||
#include "i_net.h"
|
||||
#include "protocol.h"
|
||||
#include "server_connection.h"
|
||||
#include "../am_map.h"
|
||||
#include "../byteptr.h"
|
||||
#include "../console.h"
|
||||
#include "../d_main.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../doomtype.h"
|
||||
#include "../f_finale.h"
|
||||
#include "../g_demo.h"
|
||||
#include "../g_game.h"
|
||||
#include "../i_time.h"
|
||||
#include "../lua_script.h"
|
||||
#include "../lzf.h"
|
||||
#include "../m_misc.h"
|
||||
#include "../p_local.h"
|
||||
#include "../p_saveg.h"
|
||||
#include "../r_main.h"
|
||||
#include "../tables.h"
|
||||
#include "../z_zone.h"
|
||||
#if defined (__GNUC__) || defined (__unix__)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define SAVEGAMESIZE (768*1024)
|
||||
|
||||
UINT8 hu_redownloadinggamestate = 0;
|
||||
boolean cl_redownloadinggamestate = false;
|
||||
|
||||
boolean SV_ResendingSavegameToAnyone(void)
|
||||
{
|
||||
for (INT32 i = 0; i < MAXNETNODES; i++)
|
||||
if (netnodes[i].resendingsavegame)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void SV_SendSaveGame(INT32 node, boolean resending)
|
||||
{
|
||||
size_t length, compressedlen;
|
||||
UINT8 *savebuffer;
|
||||
UINT8 *compressedsave;
|
||||
UINT8 *buffertosend;
|
||||
|
||||
// first save it in a malloced buffer
|
||||
savebuffer = (UINT8 *)malloc(SAVEGAMESIZE);
|
||||
if (!savebuffer)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Leave room for the uncompressed length.
|
||||
save_p = savebuffer + sizeof(UINT32);
|
||||
|
||||
P_SaveNetGame(resending);
|
||||
|
||||
length = save_p - savebuffer;
|
||||
if (length > SAVEGAMESIZE)
|
||||
{
|
||||
free(savebuffer);
|
||||
save_p = NULL;
|
||||
I_Error("Savegame buffer overrun");
|
||||
}
|
||||
|
||||
// Allocate space for compressed save: one byte fewer than for the
|
||||
// uncompressed data to ensure that the compression is worthwhile.
|
||||
compressedsave = malloc(length - 1);
|
||||
if (!compressedsave)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Attempt to compress it.
|
||||
if((compressedlen = lzf_compress(savebuffer + sizeof(UINT32), length - sizeof(UINT32), compressedsave + sizeof(UINT32), length - sizeof(UINT32) - 1)))
|
||||
{
|
||||
// Compressing succeeded; send compressed data
|
||||
|
||||
free(savebuffer);
|
||||
|
||||
// State that we're compressed.
|
||||
buffertosend = compressedsave;
|
||||
WRITEUINT32(compressedsave, length - sizeof(UINT32));
|
||||
length = compressedlen + sizeof(UINT32);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Compression failed to make it smaller; send original
|
||||
|
||||
free(compressedsave);
|
||||
|
||||
// State that we're not compressed
|
||||
buffertosend = savebuffer;
|
||||
WRITEUINT32(savebuffer, 0);
|
||||
}
|
||||
|
||||
AddRamToSendQueue(node, buffertosend, length, SF_RAM, 0);
|
||||
save_p = NULL;
|
||||
|
||||
// Remember when we started sending the savegame so we can handle timeouts
|
||||
netnodes[node].sendingsavegame = true;
|
||||
netnodes[node].freezetimeout = I_GetTime() + jointimeout + length / 1024; // 1 extra tic for each kilobyte
|
||||
}
|
||||
|
||||
#ifdef DUMPCONSISTENCY
|
||||
#define TMPSAVENAME "badmath.sav"
|
||||
static consvar_t cv_dumpconsistency = CVAR_INIT ("dumpconsistency", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL);
|
||||
|
||||
void SV_SavedGame(void)
|
||||
{
|
||||
size_t length;
|
||||
UINT8 *savebuffer;
|
||||
char tmpsave[256];
|
||||
|
||||
if (!cv_dumpconsistency.value)
|
||||
return;
|
||||
|
||||
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
|
||||
// first save it in a malloced buffer
|
||||
save_p = savebuffer = (UINT8 *)malloc(SAVEGAMESIZE);
|
||||
if (!save_p)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
P_SaveNetGame(false);
|
||||
|
||||
length = save_p - savebuffer;
|
||||
if (length > SAVEGAMESIZE)
|
||||
{
|
||||
free(savebuffer);
|
||||
save_p = NULL;
|
||||
I_Error("Savegame buffer overrun");
|
||||
}
|
||||
|
||||
// then save it!
|
||||
if (!FIL_WriteFile(tmpsave, savebuffer, length))
|
||||
CONS_Printf(M_GetText("Didn't save %s for netgame"), tmpsave);
|
||||
|
||||
free(savebuffer);
|
||||
save_p = NULL;
|
||||
}
|
||||
|
||||
#undef TMPSAVENAME
|
||||
#endif
|
||||
#define TMPSAVENAME "$$$.sav"
|
||||
|
||||
|
||||
void CL_LoadReceivedSavegame(boolean reloading)
|
||||
{
|
||||
UINT8 *savebuffer = NULL;
|
||||
size_t length, decompressedlen;
|
||||
char tmpsave[256];
|
||||
|
||||
FreeFileNeeded();
|
||||
|
||||
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
|
||||
length = FIL_ReadFile(tmpsave, &savebuffer);
|
||||
|
||||
CONS_Printf(M_GetText("Loading savegame length %s\n"), sizeu1(length));
|
||||
if (!length)
|
||||
{
|
||||
I_Error("Can't read savegame sent");
|
||||
return;
|
||||
}
|
||||
|
||||
save_p = savebuffer;
|
||||
|
||||
// Decompress saved game if necessary.
|
||||
decompressedlen = READUINT32(save_p);
|
||||
if(decompressedlen > 0)
|
||||
{
|
||||
UINT8 *decompressedbuffer = Z_Malloc(decompressedlen, PU_STATIC, NULL);
|
||||
lzf_decompress(save_p, length - sizeof(UINT32), decompressedbuffer, decompressedlen);
|
||||
Z_Free(savebuffer);
|
||||
save_p = savebuffer = decompressedbuffer;
|
||||
}
|
||||
|
||||
paused = false;
|
||||
demoplayback = false;
|
||||
titlemapinaction = TITLEMAP_OFF;
|
||||
titledemo = false;
|
||||
automapactive = false;
|
||||
|
||||
// load a base level
|
||||
if (P_LoadNetGame(reloading))
|
||||
{
|
||||
const UINT8 actnum = mapheaderinfo[gamemap-1]->actnum;
|
||||
CONS_Printf(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap));
|
||||
if (strcmp(mapheaderinfo[gamemap-1]->lvlttl, ""))
|
||||
{
|
||||
CONS_Printf(": %s", mapheaderinfo[gamemap-1]->lvlttl);
|
||||
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
|
||||
CONS_Printf(M_GetText(" Zone"));
|
||||
if (actnum > 0)
|
||||
CONS_Printf(" %2d", actnum);
|
||||
}
|
||||
CONS_Printf("\"\n");
|
||||
}
|
||||
|
||||
// done
|
||||
Z_Free(savebuffer);
|
||||
save_p = NULL;
|
||||
if (unlink(tmpsave) == -1)
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Can't delete %s\n"), tmpsave);
|
||||
consistancy[gametic%BACKUPTICS] = Consistancy();
|
||||
CON_ToggleOff();
|
||||
|
||||
// Tell the server we have received and reloaded the gamestate
|
||||
// so they know they can resume the game
|
||||
netbuffer->packettype = PT_RECEIVEDGAMESTATE;
|
||||
HSendPacket(servernode, true, 0, 0);
|
||||
}
|
||||
|
||||
void CL_ReloadReceivedSavegame(void)
|
||||
{
|
||||
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
LUA_InvalidatePlayer(&players[i]);
|
||||
sprintf(player_names[i], "Player %d", i + 1);
|
||||
}
|
||||
|
||||
CL_LoadReceivedSavegame(true);
|
||||
|
||||
neededtic = max(neededtic, gametic);
|
||||
maketic = neededtic;
|
||||
|
||||
ticcmd_oldangleturn[0] = players[consoleplayer].oldrelangleturn;
|
||||
P_ForceLocalAngle(&players[consoleplayer], (angle_t)(players[consoleplayer].angleturn << 16));
|
||||
if (splitscreen)
|
||||
{
|
||||
ticcmd_oldangleturn[1] = players[secondarydisplayplayer].oldrelangleturn;
|
||||
P_ForceLocalAngle(&players[secondarydisplayplayer], (angle_t)(players[secondarydisplayplayer].angleturn << 16));
|
||||
}
|
||||
|
||||
camera.subsector = R_PointInSubsector(camera.x, camera.y);
|
||||
camera2.subsector = R_PointInSubsector(camera2.x, camera2.y);
|
||||
|
||||
cl_redownloadinggamestate = false;
|
||||
|
||||
CONS_Printf(M_GetText("Game state reloaded\n"));
|
||||
}
|
||||
|
||||
void Command_ResendGamestate(void)
|
||||
{
|
||||
SINT8 playernum;
|
||||
|
||||
if (COM_Argc() == 1)
|
||||
{
|
||||
CONS_Printf(M_GetText("resendgamestate <playername/playernum>: resend the game state to a player\n"));
|
||||
return;
|
||||
}
|
||||
else if (client)
|
||||
{
|
||||
CONS_Printf(M_GetText("Only the server can use this.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
playernum = nametonum(COM_Argv(1));
|
||||
if (playernum == -1 || playernum == 0)
|
||||
return;
|
||||
|
||||
// Send a PT_WILLRESENDGAMESTATE packet to the client so they know what's going on
|
||||
netbuffer->packettype = PT_WILLRESENDGAMESTATE;
|
||||
if (!HSendPacket(playernode[playernum], true, 0, 0))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("A problem occurred, please try again.\n"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void PT_CanReceiveGamestate(SINT8 node)
|
||||
{
|
||||
if (client || netnodes[node].sendingsavegame)
|
||||
return;
|
||||
|
||||
CONS_Printf(M_GetText("Resending game state to %s...\n"), player_names[netnodes[node].player]);
|
||||
|
||||
SV_SendSaveGame(node, true); // Resend a complete game state
|
||||
netnodes[node].resendingsavegame = true;
|
||||
}
|
||||
|
||||
void PT_ReceivedGamestate(SINT8 node)
|
||||
{
|
||||
netnodes[node].sendingsavegame = false;
|
||||
netnodes[node].resendingsavegame = false;
|
||||
netnodes[node].savegameresendcooldown = I_GetTime() + 5 * TICRATE;
|
||||
}
|
||||
|
||||
void PT_WillResendGamestate(SINT8 node)
|
||||
{
|
||||
(void)node;
|
||||
|
||||
char tmpsave[256];
|
||||
|
||||
if (server || cl_redownloadinggamestate)
|
||||
return;
|
||||
|
||||
// Send back a PT_CANRECEIVEGAMESTATE packet to the server
|
||||
// so they know they can start sending the game state
|
||||
netbuffer->packettype = PT_CANRECEIVEGAMESTATE;
|
||||
if (!HSendPacket(servernode, true, 0, 0))
|
||||
return;
|
||||
|
||||
CONS_Printf(M_GetText("Reloading game state...\n"));
|
||||
|
||||
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
|
||||
// Don't get a corrupt savegame error because tmpsave already exists
|
||||
if (FIL_FileExists(tmpsave) && unlink(tmpsave) == -1)
|
||||
I_Error("Can't delete %s\n", tmpsave);
|
||||
|
||||
CL_PrepareDownloadSaveGame(tmpsave);
|
||||
|
||||
cl_redownloadinggamestate = true;
|
||||
}
|
31
src/netcode/gamestate.h
Normal file
31
src/netcode/gamestate.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file gamestate.h
|
||||
/// \brief Gamestate (re)sending
|
||||
|
||||
#ifndef __GAMESTATE__
|
||||
#define __GAMESTATE__
|
||||
|
||||
#include "../doomtype.h"
|
||||
|
||||
extern UINT8 hu_redownloadinggamestate;
|
||||
extern boolean cl_redownloadinggamestate;
|
||||
|
||||
boolean SV_ResendingSavegameToAnyone(void);
|
||||
void SV_SendSaveGame(INT32 node, boolean resending);
|
||||
void SV_SavedGame(void);
|
||||
void CL_LoadReceivedSavegame(boolean reloading);
|
||||
void CL_ReloadReceivedSavegame(void);
|
||||
void Command_ResendGamestate(void);
|
||||
void PT_CanReceiveGamestate(SINT8 node);
|
||||
void PT_ReceivedGamestate(SINT8 node);
|
||||
void PT_WillResendGamestate(SINT8 node);
|
||||
|
||||
#endif
|
|
@ -18,14 +18,15 @@ Documentation available here.
|
|||
#include <curl/curl.h>
|
||||
#endif
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "../doomdef.h"
|
||||
#include "d_clisrv.h"
|
||||
#include "command.h"
|
||||
#include "m_argv.h"
|
||||
#include "m_menu.h"
|
||||
#include "client_connection.h"
|
||||
#include "../command.h"
|
||||
#include "../m_argv.h"
|
||||
#include "../m_menu.h"
|
||||
#include "mserv.h"
|
||||
#include "i_tcp.h"/* for current_port */
|
||||
#include "i_threads.h"
|
||||
#include "../i_threads.h"
|
||||
|
||||
/* reasonable default I guess?? */
|
||||
#define DEFAULT_BUFFER_SIZE (4096)
|
||||
|
@ -95,7 +96,7 @@ init_user_agent_once(void)
|
|||
{
|
||||
if (hms_useragent[0] != '\0')
|
||||
return;
|
||||
|
||||
|
||||
get_user_agent(hms_useragent, 512);
|
||||
}
|
||||
|
|
@ -18,8 +18,8 @@
|
|||
#pragma interface
|
||||
#endif
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "command.h"
|
||||
#include "../doomdef.h"
|
||||
#include "../command.h"
|
||||
|
||||
/// \brief program net id
|
||||
#define DOOMCOM_ID (INT32)0x12345678l
|
|
@ -36,109 +36,100 @@
|
|||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "../doomdef.h"
|
||||
|
||||
#if defined (NOMD5) && !defined (NONET)
|
||||
//#define NONET
|
||||
#ifdef USE_WINSOCK1
|
||||
#include <winsock.h>
|
||||
#else
|
||||
#ifndef USE_WINSOCK
|
||||
#include <arpa/inet.h>
|
||||
#ifdef __APPLE_CC__
|
||||
#ifndef _BSD_SOCKLEN_T_
|
||||
#define _BSD_SOCKLEN_T_
|
||||
#endif //_BSD_SOCKLEN_T_
|
||||
#endif //__APPLE_CC__
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif //normal BSD API
|
||||
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
|
||||
#include <sys/time.h>
|
||||
#endif // UNIXCOMMON
|
||||
#endif
|
||||
|
||||
#ifdef NONET
|
||||
#undef HAVE_MINIUPNPC
|
||||
#else
|
||||
#ifdef USE_WINSOCK1
|
||||
#include <winsock.h>
|
||||
#else
|
||||
#ifndef USE_WINSOCK
|
||||
#include <arpa/inet.h>
|
||||
#ifdef __APPLE_CC__
|
||||
#ifndef _BSD_SOCKLEN_T_
|
||||
#define _BSD_SOCKLEN_T_
|
||||
#endif //_BSD_SOCKLEN_T_
|
||||
#endif //__APPLE_CC__
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif //normal BSD API
|
||||
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
|
||||
#include <sys/time.h>
|
||||
#endif // UNIXCOMMON
|
||||
#ifdef USE_WINSOCK
|
||||
// some undefined under win32
|
||||
#undef errno
|
||||
//#define errno WSAGetLastError() //Alam_GBC: this is the correct way, right?
|
||||
#define errno h_errno // some very strange things happen when not using h_error?!?
|
||||
#ifdef EWOULDBLOCK
|
||||
#undef EWOULDBLOCK
|
||||
#endif
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
// some undefined under win32
|
||||
#undef errno
|
||||
//#define errno WSAGetLastError() //Alam_GBC: this is the correct way, right?
|
||||
#define errno h_errno // some very strange things happen when not using h_error?!?
|
||||
#ifdef EWOULDBLOCK
|
||||
#undef EWOULDBLOCK
|
||||
#endif
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#ifdef EMSGSIZE
|
||||
#undef EMSGSIZE
|
||||
#endif
|
||||
#define EMSGSIZE WSAEMSGSIZE
|
||||
#ifdef ECONNREFUSED
|
||||
#undef ECONNREFUSED
|
||||
#endif
|
||||
#define ECONNREFUSED WSAECONNREFUSED
|
||||
#ifdef ETIMEDOUT
|
||||
#undef ETIMEDOUT
|
||||
#endif
|
||||
#define ETIMEDOUT WSAETIMEDOUT
|
||||
#ifndef IOC_VENDOR
|
||||
#define IOC_VENDOR 0x18000000
|
||||
#endif
|
||||
#ifndef _WSAIOW
|
||||
#define _WSAIOW(x,y) (IOC_IN|(x)|(y))
|
||||
#endif
|
||||
#ifndef SIO_UDP_CONNRESET
|
||||
#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
|
||||
#endif
|
||||
#ifndef AI_ADDRCONFIG
|
||||
#define AI_ADDRCONFIG 0x00000400
|
||||
#endif
|
||||
#ifndef STATUS_INVALID_PARAMETER
|
||||
#define STATUS_INVALID_PARAMETER 0xC000000D
|
||||
#endif
|
||||
#endif // USE_WINSOCK
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct sockaddr any;
|
||||
struct sockaddr_in ip4;
|
||||
#ifdef HAVE_IPV6
|
||||
struct sockaddr_in6 ip6;
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#ifdef EMSGSIZE
|
||||
#undef EMSGSIZE
|
||||
#endif
|
||||
} mysockaddr_t;
|
||||
#define EMSGSIZE WSAEMSGSIZE
|
||||
#ifdef ECONNREFUSED
|
||||
#undef ECONNREFUSED
|
||||
#endif
|
||||
#define ECONNREFUSED WSAECONNREFUSED
|
||||
#ifdef ETIMEDOUT
|
||||
#undef ETIMEDOUT
|
||||
#endif
|
||||
#define ETIMEDOUT WSAETIMEDOUT
|
||||
#ifndef IOC_VENDOR
|
||||
#define IOC_VENDOR 0x18000000
|
||||
#endif
|
||||
#ifndef _WSAIOW
|
||||
#define _WSAIOW(x,y) (IOC_IN|(x)|(y))
|
||||
#endif
|
||||
#ifndef SIO_UDP_CONNRESET
|
||||
#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
|
||||
#endif
|
||||
#ifndef AI_ADDRCONFIG
|
||||
#define AI_ADDRCONFIG 0x00000400
|
||||
#endif
|
||||
#ifndef STATUS_INVALID_PARAMETER
|
||||
#define STATUS_INVALID_PARAMETER 0xC000000D
|
||||
#endif
|
||||
#endif // USE_WINSOCK
|
||||
|
||||
#ifdef HAVE_MINIUPNPC
|
||||
#ifdef STATIC_MINIUPNPC
|
||||
#define STATICLIB
|
||||
#endif
|
||||
#include "miniupnpc/miniwget.h"
|
||||
#include "miniupnpc/miniupnpc.h"
|
||||
#include "miniupnpc/upnpcommands.h"
|
||||
#undef STATICLIB
|
||||
static UINT8 UPNP_support = TRUE;
|
||||
#endif // HAVE_MINIUPNC
|
||||
typedef union
|
||||
{
|
||||
struct sockaddr any;
|
||||
struct sockaddr_in ip4;
|
||||
#ifdef HAVE_IPV6
|
||||
struct sockaddr_in6 ip6;
|
||||
#endif
|
||||
} mysockaddr_t;
|
||||
|
||||
#endif // !NONET
|
||||
#ifdef HAVE_MINIUPNPC
|
||||
#ifdef STATIC_MINIUPNPC
|
||||
#define STATICLIB
|
||||
#endif
|
||||
#include "miniupnpc/miniwget.h"
|
||||
#include "miniupnpc/miniupnpc.h"
|
||||
#include "miniupnpc/upnpcommands.h"
|
||||
#undef STATICLIB
|
||||
static UINT8 UPNP_support = TRUE;
|
||||
#endif // HAVE_MINIUPNC
|
||||
|
||||
#define MAXBANS 100
|
||||
|
||||
#include "i_system.h"
|
||||
#include "../i_system.h"
|
||||
#include "i_net.h"
|
||||
#include "d_net.h"
|
||||
#include "d_netfil.h"
|
||||
#include "i_tcp.h"
|
||||
#include "m_argv.h"
|
||||
#include "../m_argv.h"
|
||||
|
||||
#include "doomstat.h"
|
||||
#include "../doomstat.h"
|
||||
|
||||
// win32
|
||||
#ifdef USE_WINSOCK
|
||||
|
@ -151,7 +142,7 @@
|
|||
#define SELECTTEST
|
||||
#define DEFAULTPORT "5029"
|
||||
|
||||
#if defined (USE_WINSOCK) && !defined (NONET)
|
||||
#ifdef USE_WINSOCK
|
||||
typedef SOCKET SOCKET_TYPE;
|
||||
#define ERRSOCKET (SOCKET_ERROR)
|
||||
#else
|
||||
|
@ -163,22 +154,20 @@
|
|||
#define ERRSOCKET (-1)
|
||||
#endif
|
||||
|
||||
#ifndef NONET
|
||||
// define socklen_t in DOS/Windows if it is not already defined
|
||||
#ifdef USE_WINSOCK1
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
static SOCKET_TYPE mysockets[MAXNETNODES+1] = {ERRSOCKET};
|
||||
static size_t mysocketses = 0;
|
||||
static int myfamily[MAXNETNODES+1] = {0};
|
||||
static SOCKET_TYPE nodesocket[MAXNETNODES+1] = {ERRSOCKET};
|
||||
static mysockaddr_t clientaddress[MAXNETNODES+1];
|
||||
static mysockaddr_t broadcastaddress[MAXNETNODES+1];
|
||||
static size_t broadcastaddresses = 0;
|
||||
static boolean nodeconnected[MAXNETNODES+1];
|
||||
static mysockaddr_t banned[MAXBANS];
|
||||
static UINT8 bannedmask[MAXBANS];
|
||||
// define socklen_t in DOS/Windows if it is not already defined
|
||||
#ifdef USE_WINSOCK1
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
static SOCKET_TYPE mysockets[MAXNETNODES+1] = {ERRSOCKET};
|
||||
static size_t mysocketses = 0;
|
||||
static int myfamily[MAXNETNODES+1] = {0};
|
||||
static SOCKET_TYPE nodesocket[MAXNETNODES+1] = {ERRSOCKET};
|
||||
static mysockaddr_t clientaddress[MAXNETNODES+1];
|
||||
static mysockaddr_t broadcastaddress[MAXNETNODES+1];
|
||||
static size_t broadcastaddresses = 0;
|
||||
static boolean nodeconnected[MAXNETNODES+1];
|
||||
static mysockaddr_t banned[MAXBANS];
|
||||
static UINT8 bannedmask[MAXBANS];
|
||||
|
||||
static size_t numbans = 0;
|
||||
static boolean SOCK_bannednode[MAXNETNODES+1]; /// \note do we really need the +1?
|
||||
|
@ -187,7 +176,6 @@ static boolean init_tcp_driver = false;
|
|||
static const char *serverport_name = DEFAULTPORT;
|
||||
static const char *clientport_name;/* any port */
|
||||
|
||||
#ifndef NONET
|
||||
#ifdef USE_WINSOCK
|
||||
// stupid microsoft makes things complicated
|
||||
static char *get_WSAErrorStr(int e)
|
||||
|
@ -387,47 +375,33 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
|
|||
#endif
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char *SOCK_GetNodeAddress(INT32 node)
|
||||
{
|
||||
if (node == 0)
|
||||
return "self";
|
||||
#ifdef NONET
|
||||
return NULL;
|
||||
#else
|
||||
if (!nodeconnected[node])
|
||||
return NULL;
|
||||
return SOCK_AddrToStr(&clientaddress[node]);
|
||||
#endif
|
||||
}
|
||||
|
||||
static const char *SOCK_GetBanAddress(size_t ban)
|
||||
{
|
||||
if (ban >= numbans)
|
||||
return NULL;
|
||||
#ifdef NONET
|
||||
return NULL;
|
||||
#else
|
||||
return SOCK_AddrToStr(&banned[ban]);
|
||||
#endif
|
||||
}
|
||||
|
||||
static const char *SOCK_GetBanMask(size_t ban)
|
||||
{
|
||||
#ifdef NONET
|
||||
(void)ban;
|
||||
#else
|
||||
static char s[16]; //255.255.255.255 netmask? no, just CDIR for only
|
||||
if (ban >= numbans)
|
||||
return NULL;
|
||||
if (sprintf(s,"%d",bannedmask[ban]) > 0)
|
||||
return s;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
|
||||
{
|
||||
UINT32 bitmask = INADDR_NONE;
|
||||
|
@ -455,24 +429,20 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
|
|||
*/
|
||||
static void cleanupnodes(void)
|
||||
{
|
||||
SINT8 j;
|
||||
|
||||
if (!Playing())
|
||||
return;
|
||||
|
||||
// Why can't I start at zero?
|
||||
for (j = 1; j < MAXNETNODES; j++)
|
||||
if (!(nodeingame[j] || SendingFile(j)))
|
||||
for (SINT8 j = 1; j < MAXNETNODES; j++)
|
||||
if (!(netnodes[j].ingame || SendingFile(j)))
|
||||
nodeconnected[j] = false;
|
||||
}
|
||||
|
||||
static SINT8 getfreenode(void)
|
||||
{
|
||||
SINT8 j;
|
||||
|
||||
cleanupnodes();
|
||||
|
||||
for (j = 0; j < MAXNETNODES; j++)
|
||||
for (SINT8 j = 0; j < MAXNETNODES; j++)
|
||||
if (!nodeconnected[j])
|
||||
{
|
||||
nodeconnected[j] = true;
|
||||
|
@ -485,8 +455,8 @@ static SINT8 getfreenode(void)
|
|||
* downloading a needed wad, but it's better than not letting anyone join...
|
||||
*/
|
||||
/*I_Error("No more free nodes!!1!11!11!!1111\n");
|
||||
for (j = 1; j < MAXNETNODES; j++)
|
||||
if (!nodeingame[j])
|
||||
for (SINT8 j = 1; j < MAXNETNODES; j++)
|
||||
if (!netnodes[j].ingame)
|
||||
return j;*/
|
||||
|
||||
return -1;
|
||||
|
@ -497,28 +467,27 @@ void Command_Numnodes(void)
|
|||
{
|
||||
INT32 connected = 0;
|
||||
INT32 ingame = 0;
|
||||
INT32 i;
|
||||
|
||||
for (i = 1; i < MAXNETNODES; i++)
|
||||
for (INT32 i = 1; i < MAXNETNODES; i++)
|
||||
{
|
||||
if (!(nodeconnected[i] || nodeingame[i]))
|
||||
if (!(nodeconnected[i] || netnodes[i].ingame))
|
||||
continue;
|
||||
|
||||
if (nodeconnected[i])
|
||||
connected++;
|
||||
if (nodeingame[i])
|
||||
if (netnodes[i].ingame)
|
||||
ingame++;
|
||||
|
||||
CONS_Printf("%2d - ", i);
|
||||
if (nodetoplayer[i] != -1)
|
||||
CONS_Printf("player %.2d", nodetoplayer[i]);
|
||||
if (netnodes[i].player != -1)
|
||||
CONS_Printf("player %.2d", netnodes[i].player);
|
||||
else
|
||||
CONS_Printf(" ");
|
||||
if (nodeconnected[i])
|
||||
CONS_Printf(" - connected");
|
||||
else
|
||||
CONS_Printf(" - ");
|
||||
if (nodeingame[i])
|
||||
if (netnodes[i].ingame)
|
||||
CONS_Printf(" - ingame");
|
||||
else
|
||||
CONS_Printf(" - ");
|
||||
|
@ -531,19 +500,17 @@ void Command_Numnodes(void)
|
|||
connected, ingame);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NONET
|
||||
// Returns true if a packet was received from a new node, false in all other cases
|
||||
static boolean SOCK_Get(void)
|
||||
{
|
||||
size_t i, n;
|
||||
size_t i;
|
||||
int j;
|
||||
ssize_t c;
|
||||
mysockaddr_t fromaddress;
|
||||
socklen_t fromlen;
|
||||
|
||||
for (n = 0; n < mysocketses; n++)
|
||||
for (size_t n = 0; n < mysocketses; n++)
|
||||
{
|
||||
fromlen = (socklen_t)sizeof(fromaddress);
|
||||
c = recvfrom(mysockets[n], (char *)&doomcom->data, MAXPACKETLENGTH, 0,
|
||||
|
@ -596,20 +563,17 @@ static boolean SOCK_Get(void)
|
|||
doomcom->remotenode = -1; // no packet
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// check if we can send (do not go over the buffer)
|
||||
#ifndef NONET
|
||||
|
||||
static fd_set masterset;
|
||||
|
||||
#ifdef SELECTTEST
|
||||
static boolean FD_CPY(fd_set *src, fd_set *dst, SOCKET_TYPE *fd, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
boolean testset = false;
|
||||
FD_ZERO(dst);
|
||||
for (i = 0; i < len;i++)
|
||||
for (size_t i = 0; i < len;i++)
|
||||
{
|
||||
if(fd[i] != (SOCKET_TYPE)ERRSOCKET &&
|
||||
FD_ISSET(fd[i], src) && !FD_ISSET(fd[i], dst)) // no checking for dups
|
||||
|
@ -649,9 +613,7 @@ static boolean SOCK_CanGet(void)
|
|||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NONET
|
||||
static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr)
|
||||
{
|
||||
socklen_t d4 = (socklen_t)sizeof(struct sockaddr_in);
|
||||
|
@ -675,16 +637,15 @@ static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr
|
|||
static void SOCK_Send(void)
|
||||
{
|
||||
ssize_t c = ERRSOCKET;
|
||||
size_t i, j;
|
||||
|
||||
if (!nodeconnected[doomcom->remotenode])
|
||||
return;
|
||||
|
||||
if (doomcom->remotenode == BROADCASTADDR)
|
||||
{
|
||||
for (i = 0; i < mysocketses; i++)
|
||||
for (size_t i = 0; i < mysocketses; i++)
|
||||
{
|
||||
for (j = 0; j < broadcastaddresses; j++)
|
||||
for (size_t j = 0; j < broadcastaddresses; j++)
|
||||
{
|
||||
if (myfamily[i] == broadcastaddress[j].any.sa_family)
|
||||
SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]);
|
||||
|
@ -694,7 +655,7 @@ static void SOCK_Send(void)
|
|||
}
|
||||
else if (nodesocket[doomcom->remotenode] == (SOCKET_TYPE)ERRSOCKET)
|
||||
{
|
||||
for (i = 0; i < mysocketses; i++)
|
||||
for (size_t i = 0; i < mysocketses; i++)
|
||||
{
|
||||
if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family)
|
||||
SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]);
|
||||
|
@ -714,9 +675,7 @@ static void SOCK_Send(void)
|
|||
SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NONET
|
||||
static void SOCK_FreeNodenum(INT32 numnode)
|
||||
{
|
||||
// can't disconnect from self :)
|
||||
|
@ -731,12 +690,10 @@ static void SOCK_FreeNodenum(INT32 numnode)
|
|||
// put invalid address
|
||||
memset(&clientaddress[numnode], 0, sizeof (clientaddress[numnode]));
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// UDPsocket
|
||||
//
|
||||
#ifndef NONET
|
||||
|
||||
// allocate a socket
|
||||
static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen)
|
||||
|
@ -1061,12 +1018,10 @@ static boolean UDP_Socket(void)
|
|||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
boolean I_InitTcpDriver(void)
|
||||
{
|
||||
boolean tcp_was_up = init_tcp_driver;
|
||||
#ifndef NONET
|
||||
if (!init_tcp_driver)
|
||||
{
|
||||
#ifdef USE_WINSOCK
|
||||
|
@ -1121,7 +1076,7 @@ boolean I_InitTcpDriver(void)
|
|||
#endif
|
||||
init_tcp_driver = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!tcp_was_up && init_tcp_driver)
|
||||
{
|
||||
I_AddExitFunc(I_ShutdownTcpDriver);
|
||||
|
@ -1135,11 +1090,9 @@ boolean I_InitTcpDriver(void)
|
|||
return init_tcp_driver;
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
static void SOCK_CloseSocket(void)
|
||||
{
|
||||
size_t i;
|
||||
for (i=0; i < MAXNETNODES+1; i++)
|
||||
for (size_t i=0; i < MAXNETNODES+1; i++)
|
||||
{
|
||||
if (mysockets[i] != (SOCKET_TYPE)ERRSOCKET
|
||||
&& FD_ISSET(mysockets[i], &masterset))
|
||||
|
@ -1150,11 +1103,9 @@ static void SOCK_CloseSocket(void)
|
|||
mysockets[i] = ERRSOCKET;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void I_ShutdownTcpDriver(void)
|
||||
{
|
||||
#ifndef NONET
|
||||
SOCK_CloseSocket();
|
||||
|
||||
CONS_Printf("I_ShutdownTcpDriver: ");
|
||||
|
@ -1164,10 +1115,8 @@ void I_ShutdownTcpDriver(void)
|
|||
#endif
|
||||
CONS_Printf("shut down\n");
|
||||
init_tcp_driver = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
||||
{
|
||||
SINT8 newnode = -1;
|
||||
|
@ -1223,17 +1172,13 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
|||
I_freeaddrinfo(ai);
|
||||
return newnode;
|
||||
}
|
||||
#endif
|
||||
|
||||
static boolean SOCK_OpenSocket(void)
|
||||
{
|
||||
#ifndef NONET
|
||||
size_t i;
|
||||
|
||||
memset(clientaddress, 0, sizeof (clientaddress));
|
||||
|
||||
nodeconnected[0] = true; // always connected to self
|
||||
for (i = 1; i < MAXNETNODES; i++)
|
||||
for (size_t i = 1; i < MAXNETNODES; i++)
|
||||
nodeconnected[i] = false;
|
||||
nodeconnected[BROADCASTADDR] = true;
|
||||
I_NetSend = SOCK_Send;
|
||||
|
@ -1251,18 +1196,12 @@ static boolean SOCK_OpenSocket(void)
|
|||
// build the socket but close it first
|
||||
SOCK_CloseSocket();
|
||||
return UDP_Socket();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static boolean SOCK_Ban(INT32 node)
|
||||
{
|
||||
if (node > MAXNETNODES)
|
||||
return false;
|
||||
#ifdef NONET
|
||||
return false;
|
||||
#else
|
||||
if (numbans == MAXBANS)
|
||||
return false;
|
||||
|
||||
|
@ -1281,16 +1220,10 @@ static boolean SOCK_Ban(INT32 node)
|
|||
#endif
|
||||
numbans++;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
static boolean SOCK_SetBanAddress(const char *address, const char *mask)
|
||||
{
|
||||
#ifdef NONET
|
||||
(void)address;
|
||||
(void)mask;
|
||||
return false;
|
||||
#else
|
||||
struct my_addrinfo *ai, *runp, hints;
|
||||
int gaie;
|
||||
|
||||
|
@ -1335,7 +1268,6 @@ static boolean SOCK_SetBanAddress(const char *address, const char *mask)
|
|||
I_freeaddrinfo(ai);
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void SOCK_ClearBans(void)
|
|
@ -15,13 +15,14 @@
|
|||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#include "doomstat.h"
|
||||
#include "doomdef.h"
|
||||
#include "command.h"
|
||||
#include "i_threads.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../doomdef.h"
|
||||
#include "../command.h"
|
||||
#include "../i_threads.h"
|
||||
#include "mserv.h"
|
||||
#include "m_menu.h"
|
||||
#include "z_zone.h"
|
||||
#include "client_connection.h"
|
||||
#include "../m_menu.h"
|
||||
#include "../z_zone.h"
|
||||
|
||||
#ifdef MASTERSERVER
|
||||
|
||||
|
@ -45,9 +46,7 @@ static I_cond MSCond;
|
|||
# define Unlock_state()
|
||||
#endif/*HAVE_THREADS*/
|
||||
|
||||
#ifndef NONET
|
||||
static void Command_Listserv_f(void);
|
||||
#endif
|
||||
|
||||
#endif/*MASTERSERVER*/
|
||||
|
||||
|
@ -89,7 +88,6 @@ msg_rooms_t room_list[NUM_LIST_ROOMS+1]; // +1 for easy test
|
|||
*/
|
||||
void AddMServCommands(void)
|
||||
{
|
||||
#ifndef NONET
|
||||
CV_RegisterVar(&cv_masterserver);
|
||||
CV_RegisterVar(&cv_masterserver_update_rate);
|
||||
CV_RegisterVar(&cv_masterserver_timeout);
|
||||
|
@ -100,7 +98,6 @@ void AddMServCommands(void)
|
|||
COM_AddCommand("listserv", Command_Listserv_f, 0);
|
||||
COM_AddCommand("masterserver_update", Update_parameters, COM_LUA); // allows people to updates manually in case you were delisted by accident
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MASTERSERVER
|
||||
|
@ -189,7 +186,6 @@ void GetMODVersion_Console(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef NONET
|
||||
/** Gets a list of game servers. Called from console.
|
||||
*/
|
||||
static void Command_Listserv_f(void)
|
||||
|
@ -200,7 +196,6 @@ static void Command_Listserv_f(void)
|
|||
HMS_list_servers();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
Finish_registration (void)
|
|
@ -14,7 +14,7 @@
|
|||
#ifndef _MSERV_H_
|
||||
#define _MSERV_H_
|
||||
|
||||
#include "i_threads.h"
|
||||
#include "../i_threads.h"
|
||||
|
||||
// lowered from 32 due to menu changes
|
||||
#define NUM_LIST_ROOMS 16
|
382
src/netcode/net_command.c
Normal file
382
src/netcode/net_command.c
Normal file
|
@ -0,0 +1,382 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file net_command.c
|
||||
/// \brief Net command handling
|
||||
|
||||
#include "net_command.h"
|
||||
#include "tic_command.h"
|
||||
#include "gamestate.h"
|
||||
#include "server_connection.h"
|
||||
#include "d_clisrv.h"
|
||||
#include "i_net.h"
|
||||
#include "../byteptr.h"
|
||||
#include "../g_game.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../doomtype.h"
|
||||
|
||||
textcmdtic_t *textcmds[TEXTCMD_HASH_SIZE] = {NULL};
|
||||
UINT8 localtextcmd[MAXTEXTCMD];
|
||||
UINT8 localtextcmd2[MAXTEXTCMD]; // splitscreen
|
||||
static void (*listnetxcmd[MAXNETXCMD])(UINT8 **p, INT32 playernum);
|
||||
|
||||
void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum))
|
||||
{
|
||||
#ifdef PARANOIA
|
||||
if (id >= MAXNETXCMD)
|
||||
I_Error("Command id %d too big", id);
|
||||
if (listnetxcmd[id] != 0)
|
||||
I_Error("Command id %d already used", id);
|
||||
#endif
|
||||
listnetxcmd[id] = cmd_f;
|
||||
}
|
||||
|
||||
void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam)
|
||||
{
|
||||
if (localtextcmd[0]+2+nparam > MAXTEXTCMD)
|
||||
{
|
||||
// for future reference: if (cv_debug) != debug disabled.
|
||||
CONS_Alert(CONS_ERROR, M_GetText("NetXCmd buffer full, cannot add netcmd %d! (size: %d, needed: %s)\n"), id, localtextcmd[0], sizeu1(nparam));
|
||||
return;
|
||||
}
|
||||
localtextcmd[0]++;
|
||||
localtextcmd[localtextcmd[0]] = (UINT8)id;
|
||||
if (param && nparam)
|
||||
{
|
||||
M_Memcpy(&localtextcmd[localtextcmd[0]+1], param, nparam);
|
||||
localtextcmd[0] = (UINT8)(localtextcmd[0] + (UINT8)nparam);
|
||||
}
|
||||
}
|
||||
|
||||
// splitscreen player
|
||||
void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam)
|
||||
{
|
||||
if (localtextcmd2[0]+2+nparam > MAXTEXTCMD)
|
||||
{
|
||||
I_Error("No more place in the buffer for netcmd %d\n",id);
|
||||
return;
|
||||
}
|
||||
localtextcmd2[0]++;
|
||||
localtextcmd2[localtextcmd2[0]] = (UINT8)id;
|
||||
if (param && nparam)
|
||||
{
|
||||
M_Memcpy(&localtextcmd2[localtextcmd2[0]+1], param, nparam);
|
||||
localtextcmd2[0] = (UINT8)(localtextcmd2[0] + (UINT8)nparam);
|
||||
}
|
||||
}
|
||||
|
||||
UINT8 GetFreeXCmdSize(void)
|
||||
{
|
||||
// -1 for the size and another -1 for the ID.
|
||||
return (UINT8)(localtextcmd[0] - 2);
|
||||
}
|
||||
|
||||
// Frees all textcmd memory for the specified tic
|
||||
void D_FreeTextcmd(tic_t tic)
|
||||
{
|
||||
textcmdtic_t **tctprev = &textcmds[tic & (TEXTCMD_HASH_SIZE - 1)];
|
||||
textcmdtic_t *textcmdtic = *tctprev;
|
||||
|
||||
while (textcmdtic && textcmdtic->tic != tic)
|
||||
{
|
||||
tctprev = &textcmdtic->next;
|
||||
textcmdtic = textcmdtic->next;
|
||||
}
|
||||
|
||||
if (textcmdtic)
|
||||
{
|
||||
// Remove this tic from the list.
|
||||
*tctprev = textcmdtic->next;
|
||||
|
||||
// Free all players.
|
||||
for (INT32 i = 0; i < TEXTCMD_HASH_SIZE; i++)
|
||||
{
|
||||
textcmdplayer_t *textcmdplayer = textcmdtic->playercmds[i];
|
||||
|
||||
while (textcmdplayer)
|
||||
{
|
||||
textcmdplayer_t *tcpnext = textcmdplayer->next;
|
||||
Z_Free(textcmdplayer);
|
||||
textcmdplayer = tcpnext;
|
||||
}
|
||||
}
|
||||
|
||||
// Free this tic's own memory.
|
||||
Z_Free(textcmdtic);
|
||||
}
|
||||
}
|
||||
|
||||
// Gets the buffer for the specified ticcmd, or NULL if there isn't one
|
||||
UINT8* D_GetExistingTextcmd(tic_t tic, INT32 playernum)
|
||||
{
|
||||
textcmdtic_t *textcmdtic = textcmds[tic & (TEXTCMD_HASH_SIZE - 1)];
|
||||
while (textcmdtic && textcmdtic->tic != tic) textcmdtic = textcmdtic->next;
|
||||
|
||||
// Do we have an entry for the tic? If so, look for player.
|
||||
if (textcmdtic)
|
||||
{
|
||||
textcmdplayer_t *textcmdplayer = textcmdtic->playercmds[playernum & (TEXTCMD_HASH_SIZE - 1)];
|
||||
while (textcmdplayer && textcmdplayer->playernum != playernum) textcmdplayer = textcmdplayer->next;
|
||||
|
||||
if (textcmdplayer) return textcmdplayer->cmd;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Gets the buffer for the specified ticcmd, creating one if necessary
|
||||
UINT8* D_GetTextcmd(tic_t tic, INT32 playernum)
|
||||
{
|
||||
textcmdtic_t *textcmdtic = textcmds[tic & (TEXTCMD_HASH_SIZE - 1)];
|
||||
textcmdtic_t **tctprev = &textcmds[tic & (TEXTCMD_HASH_SIZE - 1)];
|
||||
textcmdplayer_t *textcmdplayer, **tcpprev;
|
||||
|
||||
// Look for the tic.
|
||||
while (textcmdtic && textcmdtic->tic != tic)
|
||||
{
|
||||
tctprev = &textcmdtic->next;
|
||||
textcmdtic = textcmdtic->next;
|
||||
}
|
||||
|
||||
// If we don't have an entry for the tic, make it.
|
||||
if (!textcmdtic)
|
||||
{
|
||||
textcmdtic = *tctprev = Z_Calloc(sizeof (textcmdtic_t), PU_STATIC, NULL);
|
||||
textcmdtic->tic = tic;
|
||||
}
|
||||
|
||||
tcpprev = &textcmdtic->playercmds[playernum & (TEXTCMD_HASH_SIZE - 1)];
|
||||
textcmdplayer = *tcpprev;
|
||||
|
||||
// Look for the player.
|
||||
while (textcmdplayer && textcmdplayer->playernum != playernum)
|
||||
{
|
||||
tcpprev = &textcmdplayer->next;
|
||||
textcmdplayer = textcmdplayer->next;
|
||||
}
|
||||
|
||||
// If we don't have an entry for the player, make it.
|
||||
if (!textcmdplayer)
|
||||
{
|
||||
textcmdplayer = *tcpprev = Z_Calloc(sizeof (textcmdplayer_t), PU_STATIC, NULL);
|
||||
textcmdplayer->playernum = playernum;
|
||||
}
|
||||
|
||||
return textcmdplayer->cmd;
|
||||
}
|
||||
|
||||
void ExtraDataTicker(void)
|
||||
{
|
||||
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] || i == 0)
|
||||
{
|
||||
UINT8 *bufferstart = D_GetExistingTextcmd(gametic, i);
|
||||
|
||||
if (bufferstart)
|
||||
{
|
||||
UINT8 *curpos = bufferstart;
|
||||
UINT8 *bufferend = &curpos[curpos[0]+1];
|
||||
|
||||
curpos++;
|
||||
while (curpos < bufferend)
|
||||
{
|
||||
if (*curpos < MAXNETXCMD && listnetxcmd[*curpos])
|
||||
{
|
||||
const UINT8 id = *curpos;
|
||||
curpos++;
|
||||
DEBFILE(va("executing x_cmd %s ply %u ", netxcmdnames[id - 1], i));
|
||||
(listnetxcmd[id])(&curpos, i);
|
||||
DEBFILE("done\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (server)
|
||||
{
|
||||
SendKick(i, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
DEBFILE(va("player %d kicked [gametic=%u] reason as follows:\n", i, gametic));
|
||||
}
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Got unknown net command [%s]=%d (max %d)\n"), sizeu1(curpos - bufferstart), *curpos, bufferstart[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If you are a client, you can safely forget the net commands for this tic
|
||||
// If you are the server, you need to remember them until every client has been acknowledged,
|
||||
// because if you need to resend a PT_SERVERTICS packet, you will need to put the commands in it
|
||||
if (client)
|
||||
D_FreeTextcmd(gametic);
|
||||
}
|
||||
|
||||
// used at txtcmds received to check packetsize bound
|
||||
size_t TotalTextCmdPerTic(tic_t tic)
|
||||
{
|
||||
size_t total = 1; // num of textcmds in the tic (ntextcmd byte)
|
||||
|
||||
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
UINT8 *textcmd = D_GetExistingTextcmd(tic, i);
|
||||
if ((!i || playeringame[i]) && textcmd)
|
||||
total += 2 + textcmd[0]; // "+2" for size and playernum
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
void PT_TextCmd(SINT8 node, INT32 netconsole)
|
||||
{
|
||||
if (client)
|
||||
return;
|
||||
|
||||
// splitscreen special
|
||||
if (netbuffer->packettype == PT_TEXTCMD2)
|
||||
netconsole = netnodes[node].player2;
|
||||
|
||||
if (netconsole < 0 || netconsole >= MAXPLAYERS)
|
||||
Net_UnAcknowledgePacket(node);
|
||||
else
|
||||
{
|
||||
size_t j;
|
||||
tic_t tic = maketic;
|
||||
UINT8 *textcmd;
|
||||
|
||||
// ignore if the textcmd has a reported size of zero
|
||||
// this shouldn't be sent at all
|
||||
if (!netbuffer->u.textcmd[0])
|
||||
{
|
||||
DEBFILE(va("GetPacket: Textcmd with size 0 detected! (node %u, player %d)\n",
|
||||
node, netconsole));
|
||||
Net_UnAcknowledgePacket(node);
|
||||
return;
|
||||
}
|
||||
|
||||
// ignore if the textcmd size var is actually larger than it should be
|
||||
// BASEPACKETSIZE + 1 (for size) + textcmd[0] should == datalength
|
||||
if (netbuffer->u.textcmd[0] > (size_t)doomcom->datalength-BASEPACKETSIZE-1)
|
||||
{
|
||||
DEBFILE(va("GetPacket: Bad Textcmd packet size! (expected %d, actual %s, node %u, player %d)\n",
|
||||
netbuffer->u.textcmd[0], sizeu1((size_t)doomcom->datalength-BASEPACKETSIZE-1),
|
||||
node, netconsole));
|
||||
Net_UnAcknowledgePacket(node);
|
||||
return;
|
||||
}
|
||||
|
||||
// check if tic that we are making isn't too large else we cannot send it :(
|
||||
// doomcom->numslots+1 "+1" since doomcom->numslots can change within this time and sent time
|
||||
j = software_MAXPACKETLENGTH
|
||||
- (netbuffer->u.textcmd[0]+2+BASESERVERTICSSIZE
|
||||
+ (doomcom->numslots+1)*sizeof(ticcmd_t));
|
||||
|
||||
// search a tic that have enougth space in the ticcmd
|
||||
while ((textcmd = D_GetExistingTextcmd(tic, netconsole)),
|
||||
(TotalTextCmdPerTic(tic) > j || netbuffer->u.textcmd[0] + (textcmd ? textcmd[0] : 0) > MAXTEXTCMD)
|
||||
&& tic < firstticstosend + BACKUPTICS)
|
||||
tic++;
|
||||
|
||||
if (tic >= firstticstosend + BACKUPTICS)
|
||||
{
|
||||
DEBFILE(va("GetPacket: Textcmd too long (max %s, used %s, mak %d, "
|
||||
"tosend %u, node %u, player %d)\n", sizeu1(j), sizeu2(TotalTextCmdPerTic(maketic)),
|
||||
maketic, firstticstosend, node, netconsole));
|
||||
Net_UnAcknowledgePacket(node);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we have a buffer
|
||||
if (!textcmd) textcmd = D_GetTextcmd(tic, netconsole);
|
||||
|
||||
DEBFILE(va("textcmd put in tic %u at position %d (player %d) ftts %u mk %u\n",
|
||||
tic, textcmd[0]+1, netconsole, firstticstosend, maketic));
|
||||
|
||||
M_Memcpy(&textcmd[textcmd[0]+1], netbuffer->u.textcmd+1, netbuffer->u.textcmd[0]);
|
||||
textcmd[0] += (UINT8)netbuffer->u.textcmd[0];
|
||||
}
|
||||
}
|
||||
|
||||
void SV_WriteNetCommandsForTic(tic_t tic, UINT8 **buf)
|
||||
{
|
||||
UINT8 *numcmds;
|
||||
|
||||
numcmds = (*buf)++;
|
||||
*numcmds = 0;
|
||||
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
UINT8 *cmd = D_GetExistingTextcmd(tic, i);
|
||||
INT32 size = cmd ? cmd[0] : 0;
|
||||
|
||||
if ((!i || playeringame[i]) && size)
|
||||
{
|
||||
(*numcmds)++;
|
||||
WRITEUINT8(*buf, i);
|
||||
M_Memcpy(*buf, cmd, size + 1);
|
||||
*buf += size + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CL_CopyNetCommandsFromServerPacket(tic_t tic, UINT8 **buf)
|
||||
{
|
||||
UINT8 numcmds = *(*buf)++;
|
||||
|
||||
for (UINT32 i = 0; i < numcmds; i++)
|
||||
{
|
||||
INT32 playernum = *(*buf)++; // playernum
|
||||
size_t size = (*buf)[0]+1;
|
||||
|
||||
if (tic >= gametic) // Don't copy old net commands
|
||||
M_Memcpy(D_GetTextcmd(tic, playernum), *buf, size);
|
||||
*buf += size;
|
||||
}
|
||||
}
|
||||
|
||||
void CL_SendNetCommands(void)
|
||||
{
|
||||
// Send extra data if needed
|
||||
if (localtextcmd[0])
|
||||
{
|
||||
netbuffer->packettype = PT_TEXTCMD;
|
||||
M_Memcpy(netbuffer->u.textcmd,localtextcmd, localtextcmd[0]+1);
|
||||
// All extra data have been sent
|
||||
if (HSendPacket(servernode, true, 0, localtextcmd[0]+1)) // Send can fail...
|
||||
localtextcmd[0] = 0;
|
||||
}
|
||||
|
||||
// Send extra data if needed for player 2 (splitscreen)
|
||||
if (localtextcmd2[0])
|
||||
{
|
||||
netbuffer->packettype = PT_TEXTCMD2;
|
||||
M_Memcpy(netbuffer->u.textcmd, localtextcmd2, localtextcmd2[0]+1);
|
||||
// All extra data have been sent
|
||||
if (HSendPacket(servernode, true, 0, localtextcmd2[0]+1)) // Send can fail...
|
||||
localtextcmd2[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SendKick(UINT8 playernum, UINT8 msg)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
if (!(server && cv_rejointimeout.value))
|
||||
msg &= ~KICK_MSG_KEEP_BODY;
|
||||
|
||||
buf[0] = playernum;
|
||||
buf[1] = msg;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
|
||||
void SendKicksForNode(SINT8 node, UINT8 msg)
|
||||
{
|
||||
if (!netnodes[node].ingame)
|
||||
return;
|
||||
|
||||
for (INT32 playernum = netnodes[node].player; playernum != -1; playernum = netnodes[node].player2)
|
||||
if (playernum != -1 && playeringame[playernum])
|
||||
SendKick(playernum, msg);
|
||||
}
|
66
src/netcode/net_command.h
Normal file
66
src/netcode/net_command.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file net_command.h
|
||||
/// \brief Net command handling
|
||||
|
||||
#ifndef __D_NET_COMMAND__
|
||||
#define __D_NET_COMMAND__
|
||||
|
||||
#include "d_clisrv.h"
|
||||
#include "../doomtype.h"
|
||||
|
||||
// Must be a power of two
|
||||
#define TEXTCMD_HASH_SIZE 4
|
||||
|
||||
typedef struct textcmdplayer_s
|
||||
{
|
||||
INT32 playernum;
|
||||
UINT8 cmd[MAXTEXTCMD];
|
||||
struct textcmdplayer_s *next;
|
||||
} textcmdplayer_t;
|
||||
|
||||
typedef struct textcmdtic_s
|
||||
{
|
||||
tic_t tic;
|
||||
textcmdplayer_t *playercmds[TEXTCMD_HASH_SIZE];
|
||||
struct textcmdtic_s *next;
|
||||
} textcmdtic_t;
|
||||
|
||||
extern textcmdtic_t *textcmds[TEXTCMD_HASH_SIZE];
|
||||
|
||||
extern UINT8 localtextcmd[MAXTEXTCMD];
|
||||
extern UINT8 localtextcmd2[MAXTEXTCMD]; // splitscreen
|
||||
|
||||
void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum));
|
||||
void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam);
|
||||
void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam); // splitsreen player
|
||||
|
||||
UINT8 GetFreeXCmdSize(void);
|
||||
void D_FreeTextcmd(tic_t tic);
|
||||
|
||||
// Gets the buffer for the specified ticcmd, or NULL if there isn't one
|
||||
UINT8* D_GetExistingTextcmd(tic_t tic, INT32 playernum);
|
||||
|
||||
// Gets the buffer for the specified ticcmd, creating one if necessary
|
||||
UINT8* D_GetTextcmd(tic_t tic, INT32 playernum);
|
||||
|
||||
void ExtraDataTicker(void);
|
||||
|
||||
// used at txtcmds received to check packetsize bound
|
||||
size_t TotalTextCmdPerTic(tic_t tic);
|
||||
|
||||
void PT_TextCmd(SINT8 node, INT32 netconsole);
|
||||
void SV_WriteNetCommandsForTic(tic_t tic, UINT8 **buf);
|
||||
void CL_CopyNetCommandsFromServerPacket(tic_t tic, UINT8 **buf);
|
||||
void CL_SendNetCommands(void);
|
||||
void SendKick(UINT8 playernum, UINT8 msg);
|
||||
void SendKicksForNode(SINT8 node, UINT8 msg);
|
||||
|
||||
#endif
|
|
@ -7,19 +7,15 @@
|
|||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file d_clisrv.h
|
||||
/// \brief high level networking stuff
|
||||
/// \file protocol.h
|
||||
/// \brief Data exchanged through the network
|
||||
|
||||
#ifndef __D_CLISRV__
|
||||
#define __D_CLISRV__
|
||||
#ifndef __PROTOCOL__
|
||||
#define __PROTOCOL__
|
||||
|
||||
#include "d_ticcmd.h"
|
||||
#include "d_net.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "d_net.h"
|
||||
#include "tables.h"
|
||||
#include "d_player.h"
|
||||
#include "mserv.h"
|
||||
#include "../d_ticcmd.h"
|
||||
#include "../doomdef.h"
|
||||
|
||||
/*
|
||||
The 'packet version' is used to distinguish packet
|
||||
|
@ -38,10 +34,9 @@ therein, increment this number.
|
|||
// one that defines the actual packets to
|
||||
// be transmitted.
|
||||
|
||||
// Networking and tick handling related.
|
||||
#define BACKUPTICS 1024
|
||||
#define CLIENTBACKUPTICS 32
|
||||
#define MAXTEXTCMD 256
|
||||
|
||||
//
|
||||
// Packet structure
|
||||
//
|
||||
|
@ -77,7 +72,7 @@ typedef enum
|
|||
PT_ASKLUAFILE, // Client telling the server they don't have the file
|
||||
PT_HASLUAFILE, // Client telling the server they have the file
|
||||
|
||||
PT_BASICKEEPALIVE,// Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called
|
||||
PT_BASICKEEPALIVE, // Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called
|
||||
|
||||
// Add non-PT_CANFAIL packet types here to avoid breaking MS compatibility.
|
||||
|
||||
|
@ -92,7 +87,6 @@ typedef enum
|
|||
PT_TEXTCMD, // Extra text commands from the client.
|
||||
PT_TEXTCMD2, // Splitscreen text commands.
|
||||
PT_CLIENTJOIN, // Client wants to join; used in start game.
|
||||
PT_NODETIMEOUT, // Packet sent to self if the connection times out.
|
||||
|
||||
PT_LOGIN, // Login attempt from the client.
|
||||
|
||||
|
@ -103,14 +97,6 @@ typedef enum
|
|||
NUMPACKETTYPE
|
||||
} packettype_t;
|
||||
|
||||
#ifdef PACKETDROP
|
||||
void Command_Drop(void);
|
||||
void Command_Droprate(void);
|
||||
#endif
|
||||
#ifdef _DEBUG
|
||||
void Command_Numnodes(void);
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
@ -139,13 +125,12 @@ typedef struct
|
|||
#endif
|
||||
|
||||
// Server to client packet
|
||||
// this packet is too large
|
||||
typedef struct
|
||||
{
|
||||
tic_t starttic;
|
||||
UINT8 numtics;
|
||||
UINT8 numslots; // "Slots filled": Highest player number in use plus one.
|
||||
ticcmd_t cmds[45]; // Normally [BACKUPTIC][MAXPLAYERS] but too large
|
||||
ticcmd_t cmds[45];
|
||||
} ATTRPACK servertics_pak;
|
||||
|
||||
typedef struct
|
||||
|
@ -215,6 +200,7 @@ enum {
|
|||
|
||||
#define MAXSERVERNAME 32
|
||||
#define MAXFILENEEDED 915
|
||||
|
||||
// This packet is too large
|
||||
typedef struct
|
||||
{
|
||||
|
@ -275,7 +261,7 @@ typedef struct
|
|||
UINT8 data; // Color is first four bits, hasflag, isit and issuper have one bit each, the last is unused.
|
||||
UINT32 score;
|
||||
UINT16 timeinserver; // In seconds.
|
||||
} ATTRPACK plrinfo;
|
||||
} ATTRPACK plrinfo_pak;
|
||||
|
||||
// Shortest player information for join during intermission.
|
||||
typedef struct
|
||||
|
@ -286,7 +272,7 @@ typedef struct
|
|||
UINT32 pflags;
|
||||
UINT32 score;
|
||||
UINT8 ctfteam;
|
||||
} ATTRPACK plrconfig;
|
||||
} ATTRPACK plrconfig_pak;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -309,25 +295,25 @@ typedef struct
|
|||
UINT8 reserved; // Padding
|
||||
union
|
||||
{
|
||||
clientcmd_pak clientpak; // 144 bytes
|
||||
client2cmd_pak client2pak; // 200 bytes
|
||||
servertics_pak serverpak; // 132495 bytes (more around 360, no?)
|
||||
serverconfig_pak servercfg; // 773 bytes
|
||||
UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...)
|
||||
filetx_pak filetxpak; // 139 bytes
|
||||
clientcmd_pak clientpak;
|
||||
client2cmd_pak client2pak;
|
||||
servertics_pak serverpak;
|
||||
serverconfig_pak servercfg;
|
||||
UINT8 textcmd[MAXTEXTCMD+1];
|
||||
filetx_pak filetxpak;
|
||||
fileack_pak fileack;
|
||||
UINT8 filereceived;
|
||||
clientconfig_pak clientcfg; // 136 bytes
|
||||
clientconfig_pak clientcfg;
|
||||
UINT8 md5sum[16];
|
||||
serverinfo_pak serverinfo; // 1024 bytes
|
||||
serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...)
|
||||
askinfo_pak askinfo; // 61 bytes
|
||||
msaskinfo_pak msaskinfo; // 22 bytes
|
||||
plrinfo playerinfo[MAXPLAYERS]; // 576 bytes(?)
|
||||
plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?)
|
||||
INT32 filesneedednum; // 4 bytes
|
||||
filesneededconfig_pak filesneededcfg; // ??? bytes
|
||||
UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes
|
||||
serverinfo_pak serverinfo;
|
||||
serverrefuse_pak serverrefuse;
|
||||
askinfo_pak askinfo;
|
||||
msaskinfo_pak msaskinfo;
|
||||
plrinfo_pak playerinfo[MAXPLAYERS];
|
||||
plrconfig_pak playerconfig[MAXPLAYERS];
|
||||
INT32 filesneedednum;
|
||||
filesneededconfig_pak filesneededcfg;
|
||||
UINT32 pingtable[MAXPLAYERS+1];
|
||||
} u; // This is needed to pack diff packet types data together
|
||||
} ATTRPACK doomdata_t;
|
||||
|
||||
|
@ -335,26 +321,7 @@ typedef struct
|
|||
#pragma pack()
|
||||
#endif
|
||||
|
||||
#define MAXSERVERLIST (MAXNETNODES-1)
|
||||
typedef struct
|
||||
{
|
||||
SINT8 node;
|
||||
serverinfo_pak info;
|
||||
} serverelem_t;
|
||||
|
||||
extern serverelem_t serverlist[MAXSERVERLIST];
|
||||
extern UINT32 serverlistcount;
|
||||
extern INT32 mapchangepending;
|
||||
|
||||
// Points inside doomcom
|
||||
extern doomdata_t *netbuffer;
|
||||
|
||||
extern consvar_t cv_showjoinaddress;
|
||||
extern consvar_t cv_playbackspeed;
|
||||
|
||||
#define BASEPACKETSIZE offsetof(doomdata_t, u)
|
||||
#define FILETXHEADER offsetof(filetx_pak, data)
|
||||
#define BASESERVERTICSSIZE offsetof(doomdata_t, u.serverpak.cmds[0])
|
||||
|
||||
#define KICK_MSG_GO_AWAY 1
|
||||
#define KICK_MSG_CON_FAIL 2
|
||||
|
@ -366,107 +333,4 @@ extern consvar_t cv_playbackspeed;
|
|||
#define KICK_MSG_CUSTOM_BAN 8
|
||||
#define KICK_MSG_KEEP_BODY 0x80
|
||||
|
||||
typedef enum
|
||||
{
|
||||
KR_KICK = 1, //Kicked by server
|
||||
KR_PINGLIMIT = 2, //Broke Ping Limit
|
||||
KR_SYNCH = 3, //Synch Failure
|
||||
KR_TIMEOUT = 4, //Connection Timeout
|
||||
KR_BAN = 5, //Banned by server
|
||||
KR_LEAVE = 6, //Quit the game
|
||||
|
||||
} kickreason_t;
|
||||
|
||||
/* the max number of name changes in some time period */
|
||||
#define MAXNAMECHANGES (5)
|
||||
#define NAMECHANGERATE (60*TICRATE)
|
||||
|
||||
extern boolean server;
|
||||
extern boolean serverrunning;
|
||||
#define client (!server)
|
||||
extern boolean dedicated; // For dedicated server
|
||||
extern UINT16 software_MAXPACKETLENGTH;
|
||||
extern boolean acceptnewnode;
|
||||
extern SINT8 servernode;
|
||||
|
||||
void Command_Ping_f(void);
|
||||
extern tic_t connectiontimeout;
|
||||
extern tic_t jointimeout;
|
||||
extern UINT16 pingmeasurecount;
|
||||
extern UINT32 realpingtable[MAXPLAYERS];
|
||||
extern UINT32 playerpingtable[MAXPLAYERS];
|
||||
extern tic_t servermaxping;
|
||||
|
||||
extern consvar_t cv_netticbuffer, cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_joindelay, cv_rejointimeout;
|
||||
extern consvar_t cv_resynchattempts, cv_blamecfail;
|
||||
extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||
extern consvar_t cv_dedicatedidletime;
|
||||
|
||||
// Used in d_net, the only dependence
|
||||
tic_t ExpandTics(INT32 low, INT32 node);
|
||||
void D_ClientServerInit(void);
|
||||
|
||||
// Initialise the other field
|
||||
void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum));
|
||||
void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam);
|
||||
void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam); // splitsreen player
|
||||
void SendKick(UINT8 playernum, UINT8 msg);
|
||||
|
||||
// Create any new ticcmds and broadcast to other players.
|
||||
void NetUpdate(void);
|
||||
|
||||
// Maintain connections to nodes without timing them all out.
|
||||
void NetKeepAlive(void);
|
||||
|
||||
void SV_StartSinglePlayerServer(void);
|
||||
boolean SV_SpawnServer(void);
|
||||
void SV_StopServer(void);
|
||||
void SV_ResetServer(void);
|
||||
void CL_AddSplitscreenPlayer(void);
|
||||
void CL_RemoveSplitscreenPlayer(void);
|
||||
void CL_Reset(void);
|
||||
void CL_ClearPlayer(INT32 playernum);
|
||||
void CL_QueryServerList(msg_server_t *list);
|
||||
void CL_UpdateServerList(boolean internetsearch, INT32 room);
|
||||
void CL_RemovePlayer(INT32 playernum, kickreason_t reason);
|
||||
// Is there a game running
|
||||
boolean Playing(void);
|
||||
|
||||
// Broadcasts special packets to other players
|
||||
// to notify of game exit
|
||||
void D_QuitNetGame(void);
|
||||
|
||||
//? How many ticks to run?
|
||||
boolean TryRunTics(tic_t realtic);
|
||||
|
||||
// extra data for lmps
|
||||
// these functions scare me. they contain magic.
|
||||
/*boolean AddLmpExtradata(UINT8 **demo_p, INT32 playernum);
|
||||
void ReadLmpExtraData(UINT8 **demo_pointer, INT32 playernum);*/
|
||||
|
||||
#ifndef NONET
|
||||
// translate a playername in a player number return -1 if not found and
|
||||
// print a error message in the console
|
||||
SINT8 nametonum(const char *name);
|
||||
#endif
|
||||
|
||||
extern char motd[254], server_context[8];
|
||||
extern UINT8 playernode[MAXPLAYERS];
|
||||
|
||||
INT32 D_NumPlayers(void);
|
||||
INT32 D_NumBots(void);
|
||||
void D_ResetTiccmds(void);
|
||||
|
||||
tic_t GetLag(INT32 node);
|
||||
UINT8 GetFreeXCmdSize(void);
|
||||
|
||||
void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest);
|
||||
|
||||
extern UINT8 hu_redownloadinggamestate;
|
||||
|
||||
extern UINT8 adminpassmd5[16];
|
||||
extern boolean adminpasswordset;
|
||||
|
||||
extern boolean hu_stopped;
|
||||
|
||||
#endif
|
507
src/netcode/server_connection.c
Normal file
507
src/netcode/server_connection.c
Normal file
|
@ -0,0 +1,507 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file server_connection.c
|
||||
/// \brief Server-side part of connection handling
|
||||
|
||||
#include "server_connection.h"
|
||||
#include "i_net.h"
|
||||
#include "d_clisrv.h"
|
||||
#include "d_netfil.h"
|
||||
#include "mserv.h"
|
||||
#include "net_command.h"
|
||||
#include "gamestate.h"
|
||||
#include "../byteptr.h"
|
||||
#include "../g_game.h"
|
||||
#include "../g_state.h"
|
||||
#include "../p_setup.h"
|
||||
#include "../p_tick.h"
|
||||
#include "../command.h"
|
||||
#include "../doomstat.h"
|
||||
|
||||
// Minimum timeout for sending the savegame
|
||||
// The actual timeout will be longer depending on the savegame length
|
||||
tic_t jointimeout = (10*TICRATE);
|
||||
|
||||
// Incremented by cv_joindelay when a client joins, decremented each tic.
|
||||
// If higher than cv_joindelay * 2 (3 joins in a short timespan), joins are temporarily disabled.
|
||||
tic_t joindelay = 0;
|
||||
|
||||
// Minimum timeout for sending the savegame
|
||||
// The actual timeout will be longer depending on the savegame length
|
||||
char playeraddress[MAXPLAYERS][64];
|
||||
|
||||
consvar_t cv_showjoinaddress = CVAR_INIT ("showjoinaddress", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL);
|
||||
|
||||
consvar_t cv_allownewplayer = CVAR_INIT ("allowjoin", "On", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_OnOff, NULL);
|
||||
|
||||
static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_maxplayers = CVAR_INIT ("maxplayers", "8", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, maxplayers_cons_t, NULL);
|
||||
|
||||
static CV_PossibleValue_t joindelay_cons_t[] = {{1, "MIN"}, {3600, "MAX"}, {0, "Off"}, {0, NULL}};
|
||||
consvar_t cv_joindelay = CVAR_INIT ("joindelay", "10", CV_SAVE|CV_NETVAR, joindelay_cons_t, NULL);
|
||||
|
||||
static CV_PossibleValue_t rejointimeout_cons_t[] = {{1, "MIN"}, {60 * FRACUNIT, "MAX"}, {0, "Off"}, {0, NULL}};
|
||||
consvar_t cv_rejointimeout = CVAR_INIT ("rejointimeout", "2", CV_SAVE|CV_NETVAR|CV_FLOAT, rejointimeout_cons_t, NULL);
|
||||
|
||||
static INT32 FindRejoinerNum(SINT8 node)
|
||||
{
|
||||
char addressbuffer[64];
|
||||
const char *nodeaddress;
|
||||
const char *strippednodeaddress;
|
||||
|
||||
// Make sure there is no dead dress before proceeding to the stripping
|
||||
if (!I_GetNodeAddress)
|
||||
return -1;
|
||||
nodeaddress = I_GetNodeAddress(node);
|
||||
if (!nodeaddress)
|
||||
return -1;
|
||||
|
||||
// Strip the address of its port
|
||||
strcpy(addressbuffer, nodeaddress);
|
||||
strippednodeaddress = I_NetSplitAddress(addressbuffer, NULL);
|
||||
|
||||
// Check if any player matches the stripped address
|
||||
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && playeraddress[i][0] && playernode[i] == UINT8_MAX
|
||||
&& !strcmp(playeraddress[i], strippednodeaddress))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static UINT8
|
||||
GetRefuseReason (INT32 node)
|
||||
{
|
||||
if (!node || FindRejoinerNum(node) != -1)
|
||||
return 0;
|
||||
else if (bannednode && bannednode[node])
|
||||
return REFUSE_BANNED;
|
||||
else if (!cv_allownewplayer.value)
|
||||
return REFUSE_JOINS_DISABLED;
|
||||
else if (D_NumPlayers() >= cv_maxplayers.value)
|
||||
return REFUSE_SLOTS_FULL;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
||||
{
|
||||
UINT8 *p;
|
||||
|
||||
netbuffer->packettype = PT_SERVERINFO;
|
||||
netbuffer->u.serverinfo._255 = 255;
|
||||
netbuffer->u.serverinfo.packetversion = PACKETVERSION;
|
||||
netbuffer->u.serverinfo.version = VERSION;
|
||||
netbuffer->u.serverinfo.subversion = SUBVERSION;
|
||||
strncpy(netbuffer->u.serverinfo.application, SRB2APPLICATION,
|
||||
sizeof netbuffer->u.serverinfo.application);
|
||||
// return back the time value so client can compute their ping
|
||||
netbuffer->u.serverinfo.time = (tic_t)LONG(servertime);
|
||||
netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime);
|
||||
|
||||
// Exclude bots from both counts
|
||||
netbuffer->u.serverinfo.numberofplayer = (UINT8)(D_NumPlayers() - D_NumBots());
|
||||
netbuffer->u.serverinfo.maxplayer = (UINT8)(cv_maxplayers.value - D_NumBots());
|
||||
|
||||
netbuffer->u.serverinfo.refusereason = GetRefuseReason(node);
|
||||
|
||||
strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype],
|
||||
sizeof netbuffer->u.serverinfo.gametypename);
|
||||
netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame;
|
||||
netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled();
|
||||
netbuffer->u.serverinfo.flags = (dedicated ? SV_DEDICATED : 0);
|
||||
strncpy(netbuffer->u.serverinfo.servername, cv_servername.string,
|
||||
MAXSERVERNAME);
|
||||
strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7);
|
||||
|
||||
M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, 16);
|
||||
|
||||
memset(netbuffer->u.serverinfo.maptitle, 0, sizeof netbuffer->u.serverinfo.maptitle);
|
||||
|
||||
if (mapheaderinfo[gamemap-1] && *mapheaderinfo[gamemap-1]->lvlttl)
|
||||
{
|
||||
char *read = mapheaderinfo[gamemap-1]->lvlttl, *writ = netbuffer->u.serverinfo.maptitle;
|
||||
while (writ < (netbuffer->u.serverinfo.maptitle+32) && *read != '\0')
|
||||
{
|
||||
if (!(*read & 0x80))
|
||||
{
|
||||
*writ = toupper(*read);
|
||||
writ++;
|
||||
}
|
||||
read++;
|
||||
}
|
||||
*writ = '\0';
|
||||
//strncpy(netbuffer->u.serverinfo.maptitle, (char *)mapheaderinfo[gamemap-1]->lvlttl, 33);
|
||||
}
|
||||
else
|
||||
strncpy(netbuffer->u.serverinfo.maptitle, "UNKNOWN", 32);
|
||||
|
||||
if (mapheaderinfo[gamemap-1] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
|
||||
netbuffer->u.serverinfo.iszone = 1;
|
||||
else
|
||||
netbuffer->u.serverinfo.iszone = 0;
|
||||
|
||||
if (mapheaderinfo[gamemap-1])
|
||||
netbuffer->u.serverinfo.actnum = mapheaderinfo[gamemap-1]->actnum;
|
||||
|
||||
p = PutFileNeeded(0);
|
||||
|
||||
HSendPacket(node, false, 0, p - ((UINT8 *)&netbuffer->u));
|
||||
}
|
||||
|
||||
static void SV_SendPlayerInfo(INT32 node)
|
||||
{
|
||||
netbuffer->packettype = PT_PLAYERINFO;
|
||||
|
||||
for (UINT8 i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
{
|
||||
netbuffer->u.playerinfo[i].num = 255; // This slot is empty.
|
||||
continue;
|
||||
}
|
||||
|
||||
netbuffer->u.playerinfo[i].num = i;
|
||||
strncpy(netbuffer->u.playerinfo[i].name, (const char *)&player_names[i], MAXPLAYERNAME+1);
|
||||
netbuffer->u.playerinfo[i].name[MAXPLAYERNAME] = '\0';
|
||||
|
||||
//fetch IP address
|
||||
//No, don't do that, you fuckface.
|
||||
memset(netbuffer->u.playerinfo[i].address, 0, 4);
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
if (!players[i].ctfteam)
|
||||
netbuffer->u.playerinfo[i].team = 255;
|
||||
else
|
||||
netbuffer->u.playerinfo[i].team = (UINT8)players[i].ctfteam;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (players[i].spectator)
|
||||
netbuffer->u.playerinfo[i].team = 255;
|
||||
else
|
||||
netbuffer->u.playerinfo[i].team = 0;
|
||||
}
|
||||
|
||||
netbuffer->u.playerinfo[i].score = LONG(players[i].score);
|
||||
netbuffer->u.playerinfo[i].timeinserver = SHORT((UINT16)(players[i].jointime / TICRATE));
|
||||
netbuffer->u.playerinfo[i].skin = (UINT8)(players[i].skin
|
||||
#ifdef DEVELOP // it's safe to do this only because PLAYERINFO isn't read by the game itself
|
||||
% 3
|
||||
#endif
|
||||
);
|
||||
|
||||
// Extra data
|
||||
netbuffer->u.playerinfo[i].data = 0; //players[i].skincolor;
|
||||
|
||||
if (players[i].pflags & PF_TAGIT)
|
||||
netbuffer->u.playerinfo[i].data |= 0x20;
|
||||
|
||||
if (players[i].gotflag)
|
||||
netbuffer->u.playerinfo[i].data |= 0x40;
|
||||
|
||||
if (players[i].powers[pw_super])
|
||||
netbuffer->u.playerinfo[i].data |= 0x80;
|
||||
}
|
||||
|
||||
HSendPacket(node, false, 0, sizeof(plrinfo_pak) * MAXPLAYERS);
|
||||
}
|
||||
|
||||
/** Sends a PT_SERVERCFG packet
|
||||
*
|
||||
* \param node The destination
|
||||
* \return True if the packet was successfully sent
|
||||
*
|
||||
*/
|
||||
static boolean SV_SendServerConfig(INT32 node)
|
||||
{
|
||||
boolean waspacketsent;
|
||||
|
||||
netbuffer->packettype = PT_SERVERCFG;
|
||||
|
||||
netbuffer->u.servercfg.serverplayer = (UINT8)serverplayer;
|
||||
netbuffer->u.servercfg.totalslotnum = (UINT8)(doomcom->numslots);
|
||||
netbuffer->u.servercfg.gametic = (tic_t)LONG(gametic);
|
||||
netbuffer->u.servercfg.clientnode = (UINT8)node;
|
||||
netbuffer->u.servercfg.gamestate = (UINT8)gamestate;
|
||||
netbuffer->u.servercfg.gametype = (UINT8)gametype;
|
||||
netbuffer->u.servercfg.modifiedgame = (UINT8)modifiedgame;
|
||||
netbuffer->u.servercfg.usedCheats = (UINT8)usedCheats;
|
||||
|
||||
memcpy(netbuffer->u.servercfg.server_context, server_context, 8);
|
||||
|
||||
{
|
||||
const size_t len = sizeof (serverconfig_pak);
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
if (debugfile)
|
||||
{
|
||||
fprintf(debugfile, "ServerConfig Packet about to be sent, size of packet:%s to node:%d\n",
|
||||
sizeu1(len), node);
|
||||
}
|
||||
#endif
|
||||
|
||||
waspacketsent = HSendPacket(node, true, 0, len);
|
||||
}
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
if (debugfile)
|
||||
{
|
||||
if (waspacketsent)
|
||||
{
|
||||
fprintf(debugfile, "ServerConfig Packet was sent\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(debugfile, "ServerConfig Packet could not be sent right now\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return waspacketsent;
|
||||
}
|
||||
|
||||
// Adds a node to the game (player will follow at map change or at savegame....)
|
||||
static inline void SV_AddNode(INT32 node)
|
||||
{
|
||||
netnodes[node].tic = gametic;
|
||||
netnodes[node].supposedtic = gametic;
|
||||
// little hack because the server connects to itself and puts
|
||||
// nodeingame when connected not here
|
||||
if (node)
|
||||
netnodes[node].ingame = true;
|
||||
}
|
||||
|
||||
static void SV_AddPlayer(SINT8 node, const char *name)
|
||||
{
|
||||
INT32 n;
|
||||
UINT8 buf[2 + MAXPLAYERNAME];
|
||||
UINT8 *p;
|
||||
INT32 newplayernum;
|
||||
|
||||
newplayernum = FindRejoinerNum(node);
|
||||
if (newplayernum == -1)
|
||||
{
|
||||
// search for a free playernum
|
||||
// we can't use playeringame since it is not updated here
|
||||
for (newplayernum = dedicated ? 1 : 0; newplayernum < MAXPLAYERS; newplayernum++)
|
||||
{
|
||||
if (playeringame[newplayernum])
|
||||
continue;
|
||||
for (n = 0; n < MAXNETNODES; n++)
|
||||
if (netnodes[n].player == newplayernum || netnodes[n].player2 == newplayernum)
|
||||
break;
|
||||
if (n == MAXNETNODES)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// should never happen since we check the playernum
|
||||
// before accepting the join
|
||||
I_Assert(newplayernum < MAXPLAYERS);
|
||||
|
||||
playernode[newplayernum] = (UINT8)node;
|
||||
|
||||
p = buf + 2;
|
||||
buf[0] = (UINT8)node;
|
||||
buf[1] = newplayernum;
|
||||
if (netnodes[node].numplayers < 1)
|
||||
{
|
||||
netnodes[node].player = newplayernum;
|
||||
}
|
||||
else
|
||||
{
|
||||
netnodes[node].player2 = newplayernum;
|
||||
buf[1] |= 0x80;
|
||||
}
|
||||
WRITESTRINGN(p, name, MAXPLAYERNAME);
|
||||
netnodes[node].numplayers++;
|
||||
|
||||
SendNetXCmd(XD_ADDPLAYER, &buf, p - buf);
|
||||
|
||||
DEBFILE(va("Server added player %d node %d\n", newplayernum, node));
|
||||
}
|
||||
|
||||
static void SV_SendRefuse(INT32 node, const char *reason)
|
||||
{
|
||||
strcpy(netbuffer->u.serverrefuse.reason, reason);
|
||||
|
||||
netbuffer->packettype = PT_SERVERREFUSE;
|
||||
HSendPacket(node, true, 0, strlen(netbuffer->u.serverrefuse.reason) + 1);
|
||||
Net_CloseConnection(node);
|
||||
}
|
||||
|
||||
static const char *
|
||||
GetRefuseMessage (SINT8 node, INT32 rejoinernum)
|
||||
{
|
||||
clientconfig_pak *cc = &netbuffer->u.clientcfg;
|
||||
|
||||
boolean rejoining = (rejoinernum != -1);
|
||||
|
||||
if (!node)/* server connecting to itself */
|
||||
return NULL;
|
||||
|
||||
if (
|
||||
cc->modversion != MODVERSION ||
|
||||
strncmp(cc->application, SRB2APPLICATION,
|
||||
sizeof cc->application)
|
||||
){
|
||||
return/* this is probably client's fault */
|
||||
"Incompatible.";
|
||||
}
|
||||
else if (bannednode && bannednode[node])
|
||||
{
|
||||
return
|
||||
"You have been banned\n"
|
||||
"from the server.";
|
||||
}
|
||||
else if (cc->localplayers != 1)
|
||||
{
|
||||
return
|
||||
"Wrong player count.";
|
||||
}
|
||||
|
||||
if (!rejoining)
|
||||
{
|
||||
if (!cv_allownewplayer.value)
|
||||
{
|
||||
return
|
||||
"The server is not accepting\n"
|
||||
"joins for the moment.";
|
||||
}
|
||||
else if (D_NumPlayers() >= cv_maxplayers.value)
|
||||
{
|
||||
return va(
|
||||
"Maximum players reached: %d",
|
||||
cv_maxplayers.value);
|
||||
}
|
||||
}
|
||||
|
||||
if (luafiletransfers)
|
||||
{
|
||||
return
|
||||
"The serveris broadcasting a file\n"
|
||||
"requested by a Lua script.\n"
|
||||
"Please wait a bit and then\n"
|
||||
"try rejoining.";
|
||||
}
|
||||
|
||||
if (netgame)
|
||||
{
|
||||
const tic_t th = 2 * cv_joindelay.value * TICRATE;
|
||||
|
||||
if (joindelay > th)
|
||||
{
|
||||
return va(
|
||||
"Too many people are connecting.\n"
|
||||
"Please wait %d seconds and then\n"
|
||||
"try rejoining.",
|
||||
(joindelay - th) / TICRATE);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Called when a PT_CLIENTJOIN packet is received
|
||||
*
|
||||
* \param node The packet sender
|
||||
*
|
||||
*/
|
||||
void PT_ClientJoin(SINT8 node)
|
||||
{
|
||||
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1];
|
||||
INT32 numplayers = netbuffer->u.clientcfg.localplayers;
|
||||
INT32 rejoinernum;
|
||||
|
||||
// Ignore duplicate packets
|
||||
if (client || netnodes[node].ingame)
|
||||
return;
|
||||
|
||||
rejoinernum = FindRejoinerNum(node);
|
||||
|
||||
const char *refuse = GetRefuseMessage(node, rejoinernum);
|
||||
if (refuse)
|
||||
{
|
||||
SV_SendRefuse(node, refuse);
|
||||
return;
|
||||
}
|
||||
|
||||
for (INT32 i = 0; i < numplayers; i++)
|
||||
{
|
||||
strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1);
|
||||
if (!EnsurePlayerNameIsGood(names[i], rejoinernum))
|
||||
{
|
||||
SV_SendRefuse(node, "Bad player name");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SV_AddNode(node);
|
||||
|
||||
if (!SV_SendServerConfig(node))
|
||||
{
|
||||
/// \note Shouldn't SV_SendRefuse be called before ResetNode?
|
||||
ResetNode(node);
|
||||
SV_SendRefuse(node, M_GetText("Server couldn't send info, please try again"));
|
||||
/// \todo fix this !!!
|
||||
return;
|
||||
}
|
||||
DEBFILE("new node joined\n");
|
||||
|
||||
if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION)
|
||||
{
|
||||
SV_SendSaveGame(node, false); // send a complete game state
|
||||
DEBFILE("send savegame\n");
|
||||
}
|
||||
|
||||
// Splitscreen can allow 2 players in one node
|
||||
for (INT32 i = 0; i < numplayers; i++)
|
||||
SV_AddPlayer(node, names[i]);
|
||||
|
||||
joindelay += cv_joindelay.value * TICRATE;
|
||||
}
|
||||
|
||||
void PT_AskInfoViaMS(SINT8 node)
|
||||
{
|
||||
Net_CloseConnection(node);
|
||||
}
|
||||
|
||||
void PT_TellFilesNeeded(SINT8 node)
|
||||
{
|
||||
if (server && serverrunning)
|
||||
{
|
||||
UINT8 *p;
|
||||
INT32 firstfile = netbuffer->u.filesneedednum;
|
||||
|
||||
netbuffer->packettype = PT_MOREFILESNEEDED;
|
||||
netbuffer->u.filesneededcfg.first = firstfile;
|
||||
netbuffer->u.filesneededcfg.more = 0;
|
||||
|
||||
p = PutFileNeeded(firstfile);
|
||||
|
||||
HSendPacket(node, false, 0, p - ((UINT8 *)&netbuffer->u));
|
||||
}
|
||||
else // Shouldn't get this if you aren't the server...?
|
||||
Net_CloseConnection(node);
|
||||
}
|
||||
|
||||
void PT_AskInfo(SINT8 node)
|
||||
{
|
||||
if (server && serverrunning)
|
||||
{
|
||||
SV_SendServerInfo(node, (tic_t)LONG(netbuffer->u.askinfo.time));
|
||||
SV_SendPlayerInfo(node); // Send extra info
|
||||
}
|
||||
Net_CloseConnection(node);
|
||||
}
|
30
src/netcode/server_connection.h
Normal file
30
src/netcode/server_connection.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file server_connection.h
|
||||
/// \brief Server-side part of connection handling
|
||||
|
||||
#ifndef __D_SERVER_CONNECTION__
|
||||
#define __D_SERVER_CONNECTION__
|
||||
|
||||
#include "../command.h"
|
||||
#include "../doomdef.h"
|
||||
#include "../doomtype.h"
|
||||
|
||||
void PT_ClientJoin(SINT8 node);
|
||||
void PT_AskInfoViaMS(SINT8 node);
|
||||
void PT_TellFilesNeeded(SINT8 node);
|
||||
void PT_AskInfo(SINT8 node);
|
||||
|
||||
extern tic_t jointimeout;
|
||||
extern tic_t joindelay;
|
||||
extern char playeraddress[MAXPLAYERS][64];
|
||||
extern consvar_t cv_showjoinaddress, cv_allownewplayer, cv_maxplayers, cv_joindelay, cv_rejointimeout;
|
||||
|
||||
#endif
|
471
src/netcode/tic_command.c
Normal file
471
src/netcode/tic_command.c
Normal file
|
@ -0,0 +1,471 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file tic_command.c
|
||||
/// \brief Tic command handling
|
||||
|
||||
#include "tic_command.h"
|
||||
#include "d_clisrv.h"
|
||||
#include "net_command.h"
|
||||
#include "client_connection.h"
|
||||
#include "gamestate.h"
|
||||
#include "i_net.h"
|
||||
#include "../d_main.h"
|
||||
#include "../g_game.h"
|
||||
#include "../i_system.h"
|
||||
#include "../i_time.h"
|
||||
#include "../byteptr.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../doomtype.h"
|
||||
|
||||
tic_t firstticstosend; // Smallest netnode.tic
|
||||
tic_t tictoclear = 0; // Optimize D_ClearTiccmd
|
||||
ticcmd_t localcmds;
|
||||
ticcmd_t localcmds2;
|
||||
boolean cl_packetmissed;
|
||||
ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS];
|
||||
|
||||
static inline void *G_DcpyTiccmd(void* dest, const ticcmd_t* src, const size_t n)
|
||||
{
|
||||
const size_t d = n / sizeof(ticcmd_t);
|
||||
const size_t r = n % sizeof(ticcmd_t);
|
||||
UINT8 *ret = dest;
|
||||
|
||||
if (r)
|
||||
M_Memcpy(dest, src, n);
|
||||
else if (d)
|
||||
G_MoveTiccmd(dest, src, d);
|
||||
return ret+n;
|
||||
}
|
||||
|
||||
static inline void *G_ScpyTiccmd(ticcmd_t* dest, void* src, const size_t n)
|
||||
{
|
||||
const size_t d = n / sizeof(ticcmd_t);
|
||||
const size_t r = n % sizeof(ticcmd_t);
|
||||
UINT8 *ret = src;
|
||||
|
||||
if (r)
|
||||
M_Memcpy(dest, src, n);
|
||||
else if (d)
|
||||
G_MoveTiccmd(dest, src, d);
|
||||
return ret+n;
|
||||
}
|
||||
|
||||
/** Guesses the full value of a tic from its lowest byte, for a specific node
|
||||
*
|
||||
* \param low The lowest byte of the tic value
|
||||
* \param node The node to deduce the tic for
|
||||
* \return The full tic value
|
||||
*
|
||||
*/
|
||||
tic_t ExpandTics(INT32 low, INT32 node)
|
||||
{
|
||||
INT32 delta;
|
||||
|
||||
delta = low - (netnodes[node].tic & UINT8_MAX);
|
||||
|
||||
if (delta >= -64 && delta <= 64)
|
||||
return (netnodes[node].tic & ~UINT8_MAX) + low;
|
||||
else if (delta > 64)
|
||||
return (netnodes[node].tic & ~UINT8_MAX) - 256 + low;
|
||||
else //if (delta < -64)
|
||||
return (netnodes[node].tic & ~UINT8_MAX) + 256 + low;
|
||||
}
|
||||
|
||||
void D_Clearticcmd(tic_t tic)
|
||||
{
|
||||
D_FreeTextcmd(tic);
|
||||
|
||||
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||
netcmds[tic%BACKUPTICS][i].angleturn = 0;
|
||||
|
||||
DEBFILE(va("clear tic %5u (%2u)\n", tic, tic%BACKUPTICS));
|
||||
}
|
||||
|
||||
void D_ResetTiccmds(void)
|
||||
{
|
||||
memset(&localcmds, 0, sizeof(ticcmd_t));
|
||||
memset(&localcmds2, 0, sizeof(ticcmd_t));
|
||||
|
||||
// Reset the net command list
|
||||
for (INT32 i = 0; i < TEXTCMD_HASH_SIZE; i++)
|
||||
while (textcmds[i])
|
||||
D_Clearticcmd(textcmds[i]->tic);
|
||||
}
|
||||
|
||||
// Check ticcmd for "speed hacks"
|
||||
static void CheckTiccmdHacks(INT32 playernum, tic_t tic)
|
||||
{
|
||||
ticcmd_t *cmd = &netcmds[tic%BACKUPTICS][playernum];
|
||||
if (cmd->forwardmove > MAXPLMOVE || cmd->forwardmove < -MAXPLMOVE
|
||||
|| cmd->sidemove > MAXPLMOVE || cmd->sidemove < -MAXPLMOVE)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal movement value received from node %d\n"), playernum);
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
// Check player consistancy during the level
|
||||
static void CheckConsistancy(SINT8 nodenum, tic_t tic)
|
||||
{
|
||||
netnode_t *node = &netnodes[nodenum];
|
||||
INT16 neededconsistancy = consistancy[tic%BACKUPTICS];
|
||||
INT16 clientconsistancy = SHORT(netbuffer->u.clientpak.consistancy);
|
||||
|
||||
if (tic > gametic || tic + BACKUPTICS - 1 <= gametic || gamestate != GS_LEVEL
|
||||
|| neededconsistancy == clientconsistancy || SV_ResendingSavegameToAnyone()
|
||||
|| node->resendingsavegame || node->savegameresendcooldown > I_GetTime())
|
||||
return;
|
||||
|
||||
if (cv_resynchattempts.value)
|
||||
{
|
||||
// Tell the client we are about to resend them the gamestate
|
||||
netbuffer->packettype = PT_WILLRESENDGAMESTATE;
|
||||
HSendPacket(nodenum, true, 0, 0);
|
||||
|
||||
node->resendingsavegame = true;
|
||||
|
||||
if (cv_blamecfail.value)
|
||||
CONS_Printf(M_GetText("Synch failure for player %d (%s); expected %hd, got %hd\n"),
|
||||
node->player+1, player_names[node->player],
|
||||
neededconsistancy, clientconsistancy);
|
||||
|
||||
DEBFILE(va("Restoring player %d (synch failure) [%update] %d!=%d\n",
|
||||
node->player, tic, neededconsistancy, clientconsistancy));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendKick(node->player, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
|
||||
DEBFILE(va("player %d kicked (synch failure) [%u] %d!=%d\n",
|
||||
node->player, tic, neededconsistancy, clientconsistancy));
|
||||
}
|
||||
}
|
||||
|
||||
void PT_ClientCmd(SINT8 nodenum, INT32 netconsole)
|
||||
{
|
||||
netnode_t *node = &netnodes[nodenum];
|
||||
tic_t realend, realstart;
|
||||
|
||||
if (client)
|
||||
return;
|
||||
|
||||
// To save bytes, only the low byte of tic numbers are sent
|
||||
// Use ExpandTics to figure out what the rest of the bytes are
|
||||
realstart = ExpandTics(netbuffer->u.clientpak.client_tic, nodenum);
|
||||
realend = ExpandTics(netbuffer->u.clientpak.resendfrom, nodenum);
|
||||
|
||||
if (netbuffer->packettype == PT_CLIENTMIS || netbuffer->packettype == PT_CLIENT2MIS
|
||||
|| netbuffer->packettype == PT_NODEKEEPALIVEMIS
|
||||
|| node->supposedtic < realend)
|
||||
{
|
||||
node->supposedtic = realend;
|
||||
}
|
||||
// Discard out of order packet
|
||||
if (node->tic > realend)
|
||||
{
|
||||
DEBFILE(va("out of order ticcmd discarded nettics = %u\n", node->tic));
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the nettics
|
||||
node->tic = realend;
|
||||
|
||||
// This should probably still timeout though, as the node should always have a player 1 number
|
||||
if (netconsole == -1)
|
||||
return;
|
||||
|
||||
// As long as clients send valid ticcmds, the server can keep running, so reset the timeout
|
||||
/// \todo Use a separate cvar for that kind of timeout?
|
||||
node->freezetimeout = I_GetTime() + connectiontimeout;
|
||||
|
||||
// Don't do anything for packets of type NODEKEEPALIVE?
|
||||
// Sryder 2018/07/01: Update the freezetimeout still!
|
||||
if (netbuffer->packettype == PT_NODEKEEPALIVE
|
||||
|| netbuffer->packettype == PT_NODEKEEPALIVEMIS)
|
||||
return;
|
||||
|
||||
// If we've alredy received a ticcmd for this tic, just submit it for the next one.
|
||||
tic_t faketic = maketic;
|
||||
if ((!!(netcmds[maketic % BACKUPTICS][netconsole].angleturn & TICCMD_RECEIVED))
|
||||
&& (maketic - firstticstosend < BACKUPTICS - 1))
|
||||
faketic++;
|
||||
|
||||
// Copy ticcmd
|
||||
G_MoveTiccmd(&netcmds[faketic%BACKUPTICS][netconsole], &netbuffer->u.clientpak.cmd, 1);
|
||||
|
||||
// Splitscreen cmd
|
||||
if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS)
|
||||
&& node->player2 >= 0)
|
||||
G_MoveTiccmd(&netcmds[faketic%BACKUPTICS][(UINT8)node->player2],
|
||||
&netbuffer->u.client2pak.cmd2, 1);
|
||||
|
||||
CheckTiccmdHacks(netconsole, faketic);
|
||||
CheckConsistancy(nodenum, realstart);
|
||||
}
|
||||
|
||||
void PT_ServerTics(SINT8 node, INT32 netconsole)
|
||||
{
|
||||
tic_t realend, realstart;
|
||||
servertics_pak *packet = &netbuffer->u.serverpak;
|
||||
|
||||
if (!netnodes[node].ingame)
|
||||
{
|
||||
// Do not remove my own server (we have just get a out of order packet)
|
||||
if (node != servernode)
|
||||
{
|
||||
DEBFILE(va("unknown packet received (%d) from unknown host\n",netbuffer->packettype));
|
||||
Net_CloseConnection(node);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Only accept PT_SERVERTICS from the server.
|
||||
if (node != servernode)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_SERVERTICS", node);
|
||||
if (server)
|
||||
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
|
||||
realstart = packet->starttic;
|
||||
realend = realstart + packet->numtics;
|
||||
|
||||
realend = min(realend, gametic + CLIENTBACKUPTICS);
|
||||
cl_packetmissed = realstart > neededtic;
|
||||
|
||||
if (realstart <= neededtic && realend > neededtic)
|
||||
{
|
||||
UINT8 *pak = (UINT8 *)&packet->cmds;
|
||||
UINT8 *txtpak = (UINT8 *)&packet->cmds[packet->numslots * packet->numtics];
|
||||
|
||||
for (tic_t i = realstart; i < realend; i++)
|
||||
{
|
||||
// clear first
|
||||
D_Clearticcmd(i);
|
||||
|
||||
// copy the tics
|
||||
pak = G_ScpyTiccmd(netcmds[i%BACKUPTICS], pak,
|
||||
packet->numslots*sizeof (ticcmd_t));
|
||||
|
||||
CL_CopyNetCommandsFromServerPacket(i, &txtpak);
|
||||
}
|
||||
|
||||
neededtic = realend;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBFILE(va("frame not in bound: %u\n", neededtic));
|
||||
}
|
||||
}
|
||||
|
||||
// send the client packet to the server
|
||||
void CL_SendClientCmd(void)
|
||||
{
|
||||
size_t packetsize = 0;
|
||||
boolean mis = false;
|
||||
|
||||
netbuffer->packettype = PT_CLIENTCMD;
|
||||
|
||||
if (cl_packetmissed)
|
||||
{
|
||||
netbuffer->packettype = PT_CLIENTMIS;
|
||||
mis = true;
|
||||
}
|
||||
|
||||
netbuffer->u.clientpak.resendfrom = (UINT8)(neededtic & UINT8_MAX);
|
||||
netbuffer->u.clientpak.client_tic = (UINT8)(gametic & UINT8_MAX);
|
||||
|
||||
if (gamestate == GS_WAITINGPLAYERS)
|
||||
{
|
||||
// Send PT_NODEKEEPALIVE packet
|
||||
netbuffer->packettype = (mis ? PT_NODEKEEPALIVEMIS : PT_NODEKEEPALIVE);
|
||||
packetsize = sizeof (clientcmd_pak) - sizeof (ticcmd_t) - sizeof (INT16);
|
||||
HSendPacket(servernode, false, 0, packetsize);
|
||||
}
|
||||
else if (gamestate != GS_NULL && (addedtogame || dedicated))
|
||||
{
|
||||
packetsize = sizeof (clientcmd_pak);
|
||||
G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds, 1);
|
||||
netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic%BACKUPTICS]);
|
||||
|
||||
// Send a special packet with 2 cmd for splitscreen
|
||||
if (splitscreen || botingame)
|
||||
{
|
||||
netbuffer->packettype = (mis ? PT_CLIENT2MIS : PT_CLIENT2CMD);
|
||||
packetsize = sizeof (client2cmd_pak);
|
||||
G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds2, 1);
|
||||
}
|
||||
|
||||
HSendPacket(servernode, false, 0, packetsize);
|
||||
}
|
||||
|
||||
if (cl_mode == CL_CONNECTED || dedicated)
|
||||
CL_SendNetCommands();
|
||||
}
|
||||
|
||||
// PT_SERVERTICS packets can grow too large for a single UDP packet,
|
||||
// So this checks how many tics worth of data can be sent in one packet.
|
||||
// The rest can be sent later, usually the next tic.
|
||||
static tic_t SV_CalculateNumTicsForPacket(SINT8 nodenum, tic_t firsttic, tic_t lasttic)
|
||||
{
|
||||
size_t size = BASESERVERTICSSIZE;
|
||||
|
||||
for (tic_t tic = firsttic; tic < lasttic; tic++)
|
||||
{
|
||||
size += sizeof (ticcmd_t) * doomcom->numslots;
|
||||
size += TotalTextCmdPerTic(tic);
|
||||
|
||||
if (size > software_MAXPACKETLENGTH)
|
||||
{
|
||||
DEBFILE(va("packet too large (%s) at tic %d (should be from %d to %d)\n",
|
||||
sizeu1(size), tic, firsttic, lasttic));
|
||||
lasttic = tic;
|
||||
|
||||
// Too bad: too many players have sent extra data
|
||||
// and there is too much data for a single tic.
|
||||
// To avoid that, keep the data for the next tic (see PT_TEXTCMD).
|
||||
if (lasttic == firsttic)
|
||||
{
|
||||
if (size > MAXPACKETLENGTH)
|
||||
I_Error("Too many players: can't send %s data for %d players to node %d\n"
|
||||
"Well sorry nobody is perfect....\n",
|
||||
sizeu1(size), doomcom->numslots, nodenum);
|
||||
else
|
||||
{
|
||||
lasttic++; // send it anyway!
|
||||
DEBFILE("sending it anyway\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return lasttic - firsttic;
|
||||
}
|
||||
|
||||
// Sends the server packet
|
||||
// Sends tic/net commands from firstticstosend to maketic-1
|
||||
void SV_SendTics(void)
|
||||
{
|
||||
tic_t realfirsttic, lasttictosend;
|
||||
|
||||
// Send to all clients except yourself
|
||||
// For each node, create a packet with x tics and send it
|
||||
// x is computed using node.supposedtic, max packet size and maketic
|
||||
for (INT32 n = 1; n < MAXNETNODES; n++)
|
||||
if (netnodes[n].ingame)
|
||||
{
|
||||
netnode_t *node = &netnodes[n];
|
||||
|
||||
// assert node->supposedtic>=node->tic
|
||||
realfirsttic = node->supposedtic;
|
||||
lasttictosend = min(maketic, node->tic + CLIENTBACKUPTICS);
|
||||
|
||||
if (realfirsttic >= lasttictosend)
|
||||
{
|
||||
// Well, we have sent all the tics, so we will use extra bandwidth
|
||||
// to resend packets that are supposed lost.
|
||||
// This is necessary since lost packet detection
|
||||
// works when we receive a packet with firsttic > neededtic (PT_SERVERTICS)
|
||||
DEBFILE(va("Nothing to send node %u mak=%u sup=%u net=%u \n",
|
||||
n, maketic, node->supposedtic, node->tic));
|
||||
|
||||
realfirsttic = node->tic;
|
||||
|
||||
if (realfirsttic >= lasttictosend || (I_GetTime() + n)&3)
|
||||
// All tics are Ok
|
||||
continue;
|
||||
|
||||
DEBFILE(va("Sent %d anyway\n", realfirsttic));
|
||||
}
|
||||
realfirsttic = max(realfirsttic, firstticstosend);
|
||||
|
||||
lasttictosend = realfirsttic + SV_CalculateNumTicsForPacket(n, realfirsttic, lasttictosend);
|
||||
|
||||
// Prepare the packet header
|
||||
netbuffer->packettype = PT_SERVERTICS;
|
||||
netbuffer->u.serverpak.starttic = realfirsttic;
|
||||
netbuffer->u.serverpak.numtics = (UINT8)(lasttictosend - realfirsttic);
|
||||
netbuffer->u.serverpak.numslots = (UINT8)SHORT(doomcom->numslots);
|
||||
|
||||
// Fill and send the packet
|
||||
UINT8 *bufpos = (UINT8 *)&netbuffer->u.serverpak.cmds;
|
||||
for (tic_t i = realfirsttic; i < lasttictosend; i++)
|
||||
bufpos = G_DcpyTiccmd(bufpos, netcmds[i%BACKUPTICS], doomcom->numslots * sizeof (ticcmd_t));
|
||||
for (tic_t i = realfirsttic; i < lasttictosend; i++)
|
||||
SV_WriteNetCommandsForTic(i, &bufpos);
|
||||
size_t packsize = bufpos - (UINT8 *)&(netbuffer->u);
|
||||
HSendPacket(n, false, 0, packsize);
|
||||
|
||||
// When tics are too large, only one tic is sent so don't go backwards!
|
||||
if (lasttictosend-doomcom->extratics > realfirsttic)
|
||||
node->supposedtic = lasttictosend-doomcom->extratics;
|
||||
else
|
||||
node->supposedtic = lasttictosend;
|
||||
node->supposedtic = max(node->supposedtic, node->tic);
|
||||
}
|
||||
|
||||
// node 0 is me!
|
||||
netnodes[0].supposedtic = maketic;
|
||||
}
|
||||
|
||||
void Local_Maketic(INT32 realtics)
|
||||
{
|
||||
I_OsPolling(); // I_Getevent
|
||||
D_ProcessEvents(); // menu responder, cons responder,
|
||||
// game responder calls HU_Responder, AM_Responder,
|
||||
// and G_MapEventsToControls
|
||||
if (!dedicated)
|
||||
rendergametic = gametic;
|
||||
// translate inputs (keyboard/mouse/joystick) into game controls
|
||||
G_BuildTiccmd(&localcmds, realtics, 1);
|
||||
if (splitscreen || botingame)
|
||||
G_BuildTiccmd(&localcmds2, realtics, 2);
|
||||
|
||||
localcmds.angleturn |= TICCMD_RECEIVED;
|
||||
localcmds2.angleturn |= TICCMD_RECEIVED;
|
||||
}
|
||||
|
||||
// create missed tic
|
||||
void SV_Maketic(void)
|
||||
{
|
||||
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
||||
// We didn't receive this tic
|
||||
if ((netcmds[maketic % BACKUPTICS][i].angleturn & TICCMD_RECEIVED) == 0)
|
||||
{
|
||||
ticcmd_t * ticcmd = &netcmds[(maketic ) % BACKUPTICS][i];
|
||||
ticcmd_t *prevticcmd = &netcmds[(maketic - 1) % BACKUPTICS][i];
|
||||
|
||||
if (players[i].quittime)
|
||||
{
|
||||
// Copy the angle/aiming from the previous tic
|
||||
// and empty the other inputs
|
||||
memset(ticcmd, 0, sizeof(netcmds[0][0]));
|
||||
ticcmd->angleturn = prevticcmd->angleturn | TICCMD_RECEIVED;
|
||||
ticcmd->aiming = prevticcmd->aiming;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBFILE(va("MISS tic%4d for player %d\n", maketic, i));
|
||||
// Copy the input from the previous tic
|
||||
*ticcmd = *prevticcmd;
|
||||
ticcmd->angleturn &= ~TICCMD_RECEIVED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// All tics have been processed, make the next
|
||||
maketic++;
|
||||
}
|
44
src/netcode/tic_command.h
Normal file
44
src/netcode/tic_command.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file tic_command.h
|
||||
/// \brief Tic command handling
|
||||
|
||||
#ifndef __D_TIC_COMMAND__
|
||||
#define __D_TIC_COMMAND__
|
||||
|
||||
#include "d_clisrv.h"
|
||||
#include "../d_ticcmd.h"
|
||||
#include "../doomdef.h"
|
||||
#include "../doomtype.h"
|
||||
|
||||
extern tic_t firstticstosend; // min of the nettics
|
||||
extern tic_t tictoclear; // optimize d_clearticcmd
|
||||
|
||||
extern ticcmd_t localcmds;
|
||||
extern ticcmd_t localcmds2;
|
||||
extern boolean cl_packetmissed;
|
||||
|
||||
extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS];
|
||||
|
||||
tic_t ExpandTics(INT32 low, INT32 node);
|
||||
void D_Clearticcmd(tic_t tic);
|
||||
void D_ResetTiccmds(void);
|
||||
|
||||
void PT_ClientCmd(SINT8 nodenum, INT32 netconsole);
|
||||
void PT_ServerTics(SINT8 node, INT32 netconsole);
|
||||
|
||||
// send the client packet to the server
|
||||
void CL_SendClientCmd(void);
|
||||
|
||||
void SV_SendTics(void);
|
||||
void Local_Maketic(INT32 realtics);
|
||||
void SV_Maketic(void);
|
||||
|
||||
#endif
|
|
@ -17,7 +17,7 @@
|
|||
#include "r_main.h"
|
||||
#include "s_sound.h"
|
||||
#include "z_zone.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "netcode/d_netcmd.h"
|
||||
|
||||
// ==========================================================================
|
||||
// CEILINGS
|
||||
|
|
|
@ -5248,7 +5248,7 @@ void A_SignPlayer(mobj_t *actor)
|
|||
return;
|
||||
|
||||
skin = &skins[actor->target->player->skin];
|
||||
facecolor = actor->target->player->skincolor;
|
||||
facecolor = P_GetPlayerColor(actor->target->player);
|
||||
|
||||
if (signcolor)
|
||||
;
|
||||
|
@ -9059,7 +9059,7 @@ void A_Dye(mobj_t *actor)
|
|||
if (!color)
|
||||
{
|
||||
target->colorized = false;
|
||||
target->color = target->player ? target->player->skincolor : SKINCOLOR_NONE;
|
||||
target->color = target->player ? P_GetPlayerColor(target->player) : SKINCOLOR_NONE;
|
||||
}
|
||||
else if (!(target->player))
|
||||
{
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "m_misc.h"
|
||||
#include "v_video.h" // video flags for CEchos
|
||||
#include "f_finale.h"
|
||||
#include "netcode/net_command.h"
|
||||
|
||||
// CTF player names
|
||||
#define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : ""
|
||||
|
@ -2630,7 +2631,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
}
|
||||
}
|
||||
|
||||
target->color = target->player->skincolor;
|
||||
target->color = P_GetPlayerColor(target->player);
|
||||
target->colorized = false;
|
||||
G_GhostAddColor(GHC_NORMAL);
|
||||
|
||||
|
@ -3323,7 +3324,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
|
|||
|
||||
// Get rid of shield
|
||||
player->powers[pw_shield] = SH_NONE;
|
||||
player->mo->color = player->skincolor;
|
||||
player->mo->color = P_GetPlayerColor(player);
|
||||
|
||||
// Get rid of emeralds
|
||||
player->powers[pw_emeralds] = 0;
|
||||
|
@ -3440,7 +3441,7 @@ void P_RemoveShield(player_t *player)
|
|||
{ // Second layer shields
|
||||
if (((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) && !(player->powers[pw_super] || (mariomode && player->powers[pw_invulnerability])))
|
||||
{
|
||||
player->mo->color = player->skincolor;
|
||||
player->mo->color = P_GetPlayerColor(player);
|
||||
G_GhostAddColor(GHC_NORMAL);
|
||||
}
|
||||
player->powers[pw_shield] = SH_NONE;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "r_state.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_random.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "netcode/d_netcmd.h"
|
||||
|
||||
/** Removes any active lighting effects in a sector.
|
||||
*
|
||||
|
|
|
@ -146,6 +146,7 @@ void P_ForceLocalAngle(player_t *player, angle_t angle);
|
|||
boolean P_PlayerFullbright(player_t *player);
|
||||
boolean P_PlayerCanEnterSpinGaps(player_t *player);
|
||||
boolean P_PlayerShouldUseSpinHeight(player_t *player);
|
||||
UINT16 P_GetPlayerColor(player_t *player);
|
||||
|
||||
boolean P_IsObjectInGoop(mobj_t *mo);
|
||||
boolean P_IsObjectOnGround(mobj_t *mo);
|
||||
|
@ -534,6 +535,9 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle
|
|||
boolean P_SetMobjStateNF(mobj_t *mobj, statenum_t state);
|
||||
boolean P_CheckMissileSpawn(mobj_t *th);
|
||||
void P_Thrust(mobj_t *mo, angle_t angle, fixed_t move);
|
||||
void P_ThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move);
|
||||
void P_VectorInstaThrust(fixed_t xa, fixed_t xb, fixed_t xc, fixed_t ya, fixed_t yb, fixed_t yc,
|
||||
fixed_t za, fixed_t zb, fixed_t zc, fixed_t momentum, mobj_t *mo);
|
||||
void P_DoSuperTransformation(player_t *player, boolean giverings);
|
||||
void P_ExplodeMissile(mobj_t *mo);
|
||||
void P_CheckGravity(mobj_t *mo, boolean affect);
|
||||
|
|
13
src/p_mobj.c
13
src/p_mobj.c
|
@ -36,6 +36,7 @@
|
|||
#include "p_slopes.h"
|
||||
#include "f_finale.h"
|
||||
#include "m_cond.h"
|
||||
#include "netcode/net_command.h"
|
||||
|
||||
static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_movebob = CVAR_INIT ("movebob", "1.0", CV_FLOAT|CV_SAVE, CV_BobSpeed, NULL);
|
||||
|
@ -10543,6 +10544,7 @@ static fixed_t P_DefaultMobjShadowScale (mobj_t *thing)
|
|||
case MT_SMALLGRABCHAIN:
|
||||
case MT_BIGGRABCHAIN:
|
||||
|
||||
case MT_BLUESPRINGBALL:
|
||||
case MT_YELLOWSPRINGBALL:
|
||||
case MT_REDSPRINGBALL:
|
||||
|
||||
|
@ -11586,8 +11588,6 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
// Spawn as a spectator,
|
||||
// yes even in splitscreen mode
|
||||
p->spectator = true;
|
||||
if (playernum&1) p->skincolor = skincolor_redteam;
|
||||
else p->skincolor = skincolor_blueteam;
|
||||
|
||||
// but immediately send a team change packet.
|
||||
NetPacket.packet.playernum = playernum;
|
||||
|
@ -11607,13 +11607,6 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
// Fix stupid non spectator spectators.
|
||||
if (!p->spectator && !p->ctfteam)
|
||||
p->spectator = true;
|
||||
|
||||
// Fix team colors.
|
||||
// This code isn't being done right somewhere else. Oh well.
|
||||
if (p->ctfteam == 1)
|
||||
p->skincolor = skincolor_redteam;
|
||||
else if (p->ctfteam == 2)
|
||||
p->skincolor = skincolor_blueteam;
|
||||
}
|
||||
|
||||
if ((netgame || multiplayer) && ((gametyperules & GTR_SPAWNINVUL) || leveltime) && !p->spectator && !(maptol & TOL_NIGHTS))
|
||||
|
@ -11625,7 +11618,7 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
mobj->angle = 0;
|
||||
|
||||
// set color translations for player sprites
|
||||
mobj->color = p->skincolor;
|
||||
mobj->color = P_GetPlayerColor(p);
|
||||
|
||||
// set 'spritedef' override in mobj for player skins.. (see ProjectSprite)
|
||||
// (usefulness: when body mobj is detached from player (who respawns),
|
||||
|
|
|
@ -175,7 +175,7 @@ static void P_NetArchivePlayers(void)
|
|||
WRITEUINT16(save_p, players[i].flashpal);
|
||||
WRITEUINT16(save_p, players[i].flashcount);
|
||||
|
||||
WRITEUINT8(save_p, players[i].skincolor);
|
||||
WRITEUINT16(save_p, players[i].skincolor);
|
||||
WRITEINT32(save_p, players[i].skin);
|
||||
WRITEUINT32(save_p, players[i].availabilities);
|
||||
WRITEUINT32(save_p, players[i].score);
|
||||
|
@ -404,7 +404,7 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].flashpal = READUINT16(save_p);
|
||||
players[i].flashcount = READUINT16(save_p);
|
||||
|
||||
players[i].skincolor = READUINT8(save_p);
|
||||
players[i].skincolor = READUINT16(save_p);
|
||||
players[i].skin = READINT32(save_p);
|
||||
players[i].availabilities = READUINT32(save_p);
|
||||
players[i].score = READUINT32(save_p);
|
||||
|
|
|
@ -88,6 +88,8 @@
|
|||
|
||||
#include "taglist.h"
|
||||
|
||||
#include "netcode/net_command.h"
|
||||
|
||||
//
|
||||
// Map MD5, calculated on level load.
|
||||
// Sent to clients in PT_SERVERINFO.
|
||||
|
@ -7174,37 +7176,23 @@ static void P_RunLevelScript(const char *scriptname)
|
|||
|
||||
static void P_ForceCharacter(const char *forcecharskin)
|
||||
{
|
||||
if (netgame)
|
||||
{
|
||||
char skincmd[33];
|
||||
if (splitscreen)
|
||||
{
|
||||
sprintf(skincmd, "skin2 %s\n", forcecharskin);
|
||||
CV_Set(&cv_skin2, forcecharskin);
|
||||
}
|
||||
// Don't do anything if the server is forcing a skin already.
|
||||
if (netgame && cv_forceskin.value >= 0)
|
||||
return;
|
||||
|
||||
sprintf(skincmd, "skin %s\n", forcecharskin);
|
||||
COM_BufAddText(skincmd);
|
||||
}
|
||||
else
|
||||
for (unsigned i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (splitscreen)
|
||||
{
|
||||
SetPlayerSkin(secondarydisplayplayer, forcecharskin);
|
||||
if ((unsigned)cv_playercolor2.value != skins[players[secondarydisplayplayer].skin].prefcolor)
|
||||
{
|
||||
CV_StealthSetValue(&cv_playercolor2, skins[players[secondarydisplayplayer].skin].prefcolor);
|
||||
players[secondarydisplayplayer].skincolor = skins[players[secondarydisplayplayer].skin].prefcolor;
|
||||
}
|
||||
}
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
||||
SetPlayerSkin(consoleplayer, forcecharskin);
|
||||
// normal player colors in single player
|
||||
if ((unsigned)cv_playercolor.value != skins[players[consoleplayer].skin].prefcolor)
|
||||
{
|
||||
CV_StealthSetValue(&cv_playercolor, skins[players[consoleplayer].skin].prefcolor);
|
||||
players[consoleplayer].skincolor = skins[players[consoleplayer].skin].prefcolor;
|
||||
}
|
||||
INT32 skinnum = R_SkinAvailable(forcecharskin);
|
||||
if (skinnum == -1 || !R_SkinUsable(i, skinnum))
|
||||
continue;
|
||||
|
||||
SetPlayerSkinByNum(i, skinnum);
|
||||
|
||||
if (!netgame)
|
||||
players[i].skincolor = skins[skinnum].prefcolor;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "r_main.h"
|
||||
#include "r_fps.h"
|
||||
#include "i_video.h" // rendermode
|
||||
#include "netcode/net_command.h"
|
||||
#include "netcode/server_connection.h"
|
||||
|
||||
// Object place
|
||||
#include "m_cheat.h"
|
||||
|
|
32
src/p_user.c
32
src/p_user.c
|
@ -17,7 +17,8 @@
|
|||
#include "doomdef.h"
|
||||
#include "i_system.h"
|
||||
#include "d_event.h"
|
||||
#include "d_net.h"
|
||||
#include "netcode/d_net.h"
|
||||
#include "netcode/net_command.h"
|
||||
#include "g_game.h"
|
||||
#include "p_local.h"
|
||||
#include "r_fps.h"
|
||||
|
@ -105,8 +106,7 @@ void P_Thrust(mobj_t *mo, angle_t angle, fixed_t move)
|
|||
mo->momy += FixedMul(move, FINESINE(angle));
|
||||
}
|
||||
|
||||
#if 0
|
||||
static inline void P_ThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move)
|
||||
void P_ThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move)
|
||||
{
|
||||
angle >>= ANGLETOFINESHIFT;
|
||||
|
||||
|
@ -114,7 +114,7 @@ static inline void P_ThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move)
|
|||
mo->momy += FixedMul(move, FINESINE(angle));
|
||||
}
|
||||
|
||||
static inline void P_VectorInstaThrust(fixed_t xa, fixed_t xb, fixed_t xc, fixed_t ya, fixed_t yb, fixed_t yc,
|
||||
void P_VectorInstaThrust(fixed_t xa, fixed_t xb, fixed_t xc, fixed_t ya, fixed_t yb, fixed_t yc,
|
||||
fixed_t za, fixed_t zb, fixed_t zc, fixed_t momentum, mobj_t *mo)
|
||||
{
|
||||
fixed_t a1, b1, c1, a2, b2, c2, i, j, k;
|
||||
|
@ -144,7 +144,6 @@ static inline void P_VectorInstaThrust(fixed_t xa, fixed_t xb, fixed_t xc, fixed
|
|||
mo->momy = j;
|
||||
mo->momz = k;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// P_InstaThrust
|
||||
|
@ -686,7 +685,7 @@ static void P_DeNightserizePlayer(player_t *player)
|
|||
|
||||
player->mo->skin = &skins[player->skin];
|
||||
player->followitem = skins[player->skin].followitem;
|
||||
player->mo->color = player->skincolor;
|
||||
player->mo->color = P_GetPlayerColor(player);
|
||||
G_GhostAddColor(GHC_RETURNSKIN);
|
||||
|
||||
// Restore aiming angle
|
||||
|
@ -3032,7 +3031,7 @@ static void P_CheckInvincibilityTimer(player_t *player)
|
|||
}
|
||||
else
|
||||
{
|
||||
player->mo->color = player->skincolor;
|
||||
player->mo->color = P_GetPlayerColor(player);
|
||||
G_GhostAddColor(GHC_NORMAL);
|
||||
}
|
||||
}
|
||||
|
@ -4305,7 +4304,7 @@ static void P_DoSuperStuff(player_t *player)
|
|||
}
|
||||
else
|
||||
{
|
||||
player->mo->color = player->skincolor;
|
||||
player->mo->color = P_GetPlayerColor(player);
|
||||
G_GhostAddColor(GHC_NORMAL);
|
||||
}
|
||||
|
||||
|
@ -4355,7 +4354,7 @@ static void P_DoSuperStuff(player_t *player)
|
|||
}
|
||||
else
|
||||
{
|
||||
player->mo->color = player->skincolor;
|
||||
player->mo->color = P_GetPlayerColor(player);
|
||||
G_GhostAddColor(GHC_NORMAL);
|
||||
}
|
||||
|
||||
|
@ -11159,7 +11158,7 @@ static void P_MinecartThink(player_t *player)
|
|||
detright->drawonlyforplayer = player;
|
||||
}
|
||||
else
|
||||
P_RemoveMobj(detleft);
|
||||
P_RemoveMobj(detright);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -13119,3 +13118,16 @@ boolean P_PlayerShouldUseSpinHeight(player_t *player)
|
|||
&& player->dashmode >= DASHMODE_THRESHOLD && player->mo->state-states == S_PLAY_DASH)
|
||||
|| JUMPCURLED(player));
|
||||
}
|
||||
|
||||
UINT16 P_GetPlayerColor(player_t *player)
|
||||
{
|
||||
if (G_GametypeHasTeams() && player->ctfteam)
|
||||
{
|
||||
if (player->ctfteam == 1)
|
||||
return skincolor_redteam;
|
||||
else if (player->ctfteam == 2)
|
||||
return skincolor_blueteam;
|
||||
}
|
||||
|
||||
return player->skincolor;
|
||||
}
|
||||
|
|
|
@ -249,7 +249,7 @@ static void FlipCam2_OnChange(void)
|
|||
//
|
||||
// killough 5/2/98: reformatted
|
||||
//
|
||||
INT32 R_PointOnSide(fixed_t x, fixed_t y, node_t *node)
|
||||
INT32 R_PointOnSide(fixed_t x, fixed_t y, node_t *restrict node)
|
||||
{
|
||||
if (!node->dx)
|
||||
return x <= node->x ? node->dy > 0 : node->dy < 0;
|
||||
|
@ -261,9 +261,10 @@ INT32 R_PointOnSide(fixed_t x, fixed_t y, node_t *node)
|
|||
fixed_t dy = (y >> 1) - (node->y >> 1);
|
||||
|
||||
// Try to quickly decide by looking at sign bits.
|
||||
if ((node->dy ^ node->dx ^ dx ^ dy) < 0)
|
||||
return (node->dy ^ dx) < 0; // (left is negative)
|
||||
return FixedMul(dy, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, dx);
|
||||
// also use a mask to avoid branch prediction
|
||||
INT32 mask = (node->dy ^ node->dx ^ dx ^ dy) >> 31;
|
||||
return (mask & ((node->dy ^ dx) < 0)) | // (left is negative)
|
||||
(~mask & (FixedMul(dy, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, dx)));
|
||||
}
|
||||
|
||||
// killough 5/2/98: reformatted
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "netcode/d_netcmd.h"
|
||||
#include "m_misc.h"
|
||||
#include "p_local.h" // Camera...
|
||||
#include "p_slopes.h"
|
||||
|
|
|
@ -306,6 +306,21 @@ INT32 R_SkinAvailable(const char *name)
|
|||
return -1;
|
||||
}
|
||||
|
||||
INT32 R_GetForcedSkin(INT32 playernum)
|
||||
{
|
||||
if (netgame && cv_forceskin.value >= 0 && R_SkinUsable(playernum, cv_forceskin.value))
|
||||
return cv_forceskin.value;
|
||||
|
||||
if (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0')
|
||||
{
|
||||
INT32 skinnum = R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter);
|
||||
if (skinnum != -1 && R_SkinUsable(playernum, skinnum))
|
||||
return skinnum;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Auxillary function that actually sets the skin
|
||||
static void SetSkin(player_t *player, INT32 skinnum)
|
||||
{
|
||||
|
@ -347,10 +362,6 @@ static void SetSkin(player_t *player, INT32 skinnum)
|
|||
|
||||
if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback))
|
||||
{
|
||||
if (player == &players[consoleplayer])
|
||||
CV_StealthSetValue(&cv_playercolor, skin->prefcolor);
|
||||
else if (player == &players[secondarydisplayplayer])
|
||||
CV_StealthSetValue(&cv_playercolor2, skin->prefcolor);
|
||||
player->skincolor = newcolor = skin->prefcolor;
|
||||
if (player->bot && botingame)
|
||||
{
|
||||
|
|
|
@ -96,6 +96,7 @@ void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002
|
|||
boolean R_SkinUsable(INT32 playernum, INT32 skinnum);
|
||||
UINT32 R_GetSkinAvailabilities(void);
|
||||
INT32 R_SkinAvailable(const char *name);
|
||||
INT32 R_GetForcedSkin(INT32 playernum);
|
||||
void R_AddSkins(UINT16 wadnum, boolean mainfile);
|
||||
void R_PatchSkins(UINT16 wadnum, boolean mainfile);
|
||||
|
||||
|
|
|
@ -75,6 +75,6 @@ void R_SetupSkyDraw(void)
|
|||
*/
|
||||
void R_SetSkyScale(void)
|
||||
{
|
||||
fixed_t difference = vid.fdupx-(vid.dupx<<FRACBITS);
|
||||
skyscale = FixedDiv(fovtan, vid.fdupx+difference);
|
||||
fixed_t difference = vid.fdup-(vid.dup<<FRACBITS);
|
||||
skyscale = FixedDiv(fovtan, vid.fdup+difference);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "p_tick.h"
|
||||
#include "p_local.h"
|
||||
#include "p_slopes.h"
|
||||
#include "d_netfil.h" // blargh. for nameonly().
|
||||
#include "netcode/d_netfil.h" // blargh. for nameonly().
|
||||
#include "m_cheat.h" // objectplace
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_md2.h"
|
||||
|
|
12
src/screen.c
12
src/screen.c
|
@ -27,7 +27,7 @@
|
|||
#include "hu_stuff.h"
|
||||
#include "z_zone.h"
|
||||
#include "d_main.h"
|
||||
#include "d_clisrv.h"
|
||||
#include "netcode/d_clisrv.h"
|
||||
#include "f_finale.h"
|
||||
#include "y_inter.h" // usebuffer
|
||||
#include "i_sound.h" // closed captions
|
||||
|
@ -497,7 +497,7 @@ void SCR_CalculateFPS(void)
|
|||
void SCR_DisplayTicRate(void)
|
||||
{
|
||||
INT32 ticcntcolor = 0;
|
||||
const INT32 h = vid.height-(8*vid.dupy);
|
||||
const INT32 h = vid.height-(8*vid.dup);
|
||||
UINT32 cap = R_GetFramerateCap();
|
||||
double fps = round(averageFPS);
|
||||
|
||||
|
@ -533,7 +533,7 @@ void SCR_DisplayTicRate(void)
|
|||
|
||||
width = V_StringWidth(drawnstr, V_NOSCALESTART);
|
||||
|
||||
V_DrawString(vid.width - ((7 * 8 * vid.dupx) + V_StringWidth("FPS: ", V_NOSCALESTART)), h,
|
||||
V_DrawString(vid.width - ((7 * 8 * vid.dup) + V_StringWidth("FPS: ", V_NOSCALESTART)), h,
|
||||
V_YELLOWMAP|V_NOSCALESTART|V_USERHUDTRANS, "FPS:");
|
||||
V_DrawString(vid.width - width, h,
|
||||
ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, drawnstr);
|
||||
|
@ -592,7 +592,7 @@ void SCR_ClosedCaptions(void)
|
|||
|
||||
if (closedcaptions[i].b)
|
||||
{
|
||||
y -= closedcaptions[i].b * vid.dupy;
|
||||
y -= closedcaptions[i].b * vid.dup;
|
||||
if (renderisnewtic)
|
||||
{
|
||||
closedcaptions[i].b--;
|
||||
|
@ -642,9 +642,9 @@ void SCR_DisplayMarathonInfo(void)
|
|||
#define PRIMEV1 13
|
||||
#define PRIMEV2 17 // I can't believe it! I'm on TV!
|
||||
antisplice[0] += (entertic - oldentertics)*PRIMEV2;
|
||||
antisplice[0] %= PRIMEV1*((vid.width/vid.dupx)+1);
|
||||
antisplice[0] %= PRIMEV1*((vid.width/vid.dup)+1);
|
||||
antisplice[1] += (entertic - oldentertics)*PRIMEV1;
|
||||
antisplice[1] %= PRIMEV1*((vid.width/vid.dupx)+1);
|
||||
antisplice[1] %= PRIMEV1*((vid.width/vid.dup)+1);
|
||||
str = va("%i:%02i:%02i.%02i",
|
||||
G_TicsToHours(marathontime),
|
||||
G_TicsToMinutes(marathontime, false),
|
||||
|
|
12
src/screen.h
12
src/screen.h
|
@ -59,19 +59,19 @@ typedef struct viddef_s
|
|||
} u;
|
||||
INT32 recalc; // if true, recalc vid-based stuff
|
||||
UINT8 *direct; // linear frame buffer, or vga base mem.
|
||||
INT32 dupx, dupy; // scale 1, 2, 3 value for menus & overlays
|
||||
INT32/*fixed_t*/ fdupx, fdupy; // same as dupx, dupy, but exact value when aspect ratio isn't 320/200
|
||||
INT32 dup; // scale 1, 2, 3 value for menus & overlays
|
||||
INT32/*fixed_t*/ fdup; // same as dup, but exact value when aspect ratio isn't 320/200
|
||||
INT32 bpp; // BYTES per pixel: 1 = 256color, 2 = highcolor
|
||||
|
||||
INT32 baseratio; // Used to get the correct value for lighting walls
|
||||
|
||||
// for Win32 version
|
||||
DNWH WndParent; // handle of the application's window
|
||||
UINT8 smalldupx, smalldupy; // factor for a little bit of scaling
|
||||
UINT8 meddupx, meddupy; // factor for moderate, but not full, scaling
|
||||
UINT8 smalldup; // factor for a little bit of scaling
|
||||
UINT8 meddup; // factor for moderate, but not full, scaling
|
||||
#ifdef HWRENDER
|
||||
INT32/*fixed_t*/ fsmalldupx, fsmalldupy;
|
||||
INT32/*fixed_t*/ fmeddupx, fmeddupy;
|
||||
INT32/*fixed_t*/ fsmalldup;
|
||||
INT32/*fixed_t*/ fmeddup;
|
||||
INT32 glstate;
|
||||
#endif
|
||||
} viddef_t;
|
||||
|
|
|
@ -262,7 +262,6 @@
|
|||
<ClInclude Include="..\u_list.h" />
|
||||
<ClInclude Include="..\hu_stuff.h" />
|
||||
<ClInclude Include="..\info.h" />
|
||||
<ClInclude Include="..\i_addrinfo.h" />
|
||||
<ClInclude Include="..\i_joy.h" />
|
||||
<ClInclude Include="..\i_net.h" />
|
||||
<ClInclude Include="..\i_sound.h" />
|
||||
|
@ -297,6 +296,21 @@
|
|||
<ClInclude Include="..\m_queue.h" />
|
||||
<ClInclude Include="..\m_random.h" />
|
||||
<ClInclude Include="..\m_swap.h" />
|
||||
<ClInclude Include="..\netcode\client_connection.h" />
|
||||
<ClInclude Include="..\netcode\commands.h" />
|
||||
<ClInclude Include="..\netcode\d_clisrv.h" />
|
||||
<ClInclude Include="..\netcode\d_net.h" />
|
||||
<ClInclude Include="..\netcode\d_netcmd.h" />
|
||||
<ClInclude Include="..\netcode\d_netfil.h" />
|
||||
<ClInclude Include="..\netcode\gamestate.h" />
|
||||
<ClInclude Include="..\netcode\i_addrinfo.h" />
|
||||
<ClInclude Include="..\netcode\i_net.h" />
|
||||
<ClInclude Include="..\netcode\i_tcp.h" />
|
||||
<ClInclude Include="..\netcode\mserv.h" />
|
||||
<ClInclude Include="..\netcode\net_command.h" />
|
||||
<ClInclude Include="..\netcode\protocol.h" />
|
||||
<ClInclude Include="..\netcode\server_connection.h" />
|
||||
<ClInclude Include="..\netcode\tic_command.h" />
|
||||
<ClInclude Include="..\p5prof.h" />
|
||||
<ClInclude Include="..\p_haptic.h" />
|
||||
<ClInclude Include="..\p_local.h" />
|
||||
|
@ -329,6 +343,7 @@
|
|||
<ClInclude Include="..\r_textures.h" />
|
||||
<ClInclude Include="..\r_things.h" />
|
||||
<ClInclude Include="..\screen.h" />
|
||||
<ClInclude Include="..\snake.h" />
|
||||
<ClInclude Include="..\sounds.h" />
|
||||
<ClInclude Include="..\st_stuff.h" />
|
||||
<ClInclude Include="..\s_sound.h" />
|
||||
|
@ -400,11 +415,7 @@
|
|||
<ClCompile Include="..\deh_soc.c" />
|
||||
<ClCompile Include="..\deh_lua.c" />
|
||||
<ClCompile Include="..\deh_tables.c" />
|
||||
<ClCompile Include="..\d_clisrv.c" />
|
||||
<ClCompile Include="..\d_main.c" />
|
||||
<ClCompile Include="..\d_net.c" />
|
||||
<ClCompile Include="..\d_netcmd.c" />
|
||||
<ClCompile Include="..\d_netfil.c" />
|
||||
<ClCompile Include="..\filesrch.c" />
|
||||
<ClCompile Include="..\f_finale.c" />
|
||||
<ClCompile Include="..\f_wipe.c" />
|
||||
|
@ -427,10 +438,6 @@
|
|||
<ClCompile Include="..\u_list.c" />
|
||||
<ClCompile Include="..\hu_stuff.c" />
|
||||
<ClCompile Include="..\info.c" />
|
||||
<ClCompile Include="..\i_addrinfo.c">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\i_tcp.c" />
|
||||
<ClCompile Include="..\i_time.c" />
|
||||
<ClCompile Include="..\lua_baselib.c" />
|
||||
<ClCompile Include="..\lua_blockmaplib.c" />
|
||||
|
@ -451,8 +458,6 @@
|
|||
<ClCompile Include="..\lua_thinkerlib.c" />
|
||||
<ClCompile Include="..\lzf.c" />
|
||||
<ClCompile Include="..\md5.c" />
|
||||
<ClCompile Include="..\mserv.c" />
|
||||
<ClCompile Include="..\http-mserv.c" />
|
||||
<ClCompile Include="..\m_aatree.c" />
|
||||
<ClCompile Include="..\m_anigif.c" />
|
||||
<ClCompile Include="..\m_argv.c" />
|
||||
|
@ -466,6 +471,22 @@
|
|||
<ClCompile Include="..\m_perfstats.c" />
|
||||
<ClCompile Include="..\m_queue.c" />
|
||||
<ClCompile Include="..\m_random.c" />
|
||||
<ClCompile Include="..\netcode\client_connection.c" />
|
||||
<ClCompile Include="..\netcode\commands.c" />
|
||||
<ClCompile Include="..\netcode\d_clisrv.c" />
|
||||
<ClCompile Include="..\netcode\d_net.c" />
|
||||
<ClCompile Include="..\netcode\d_netcmd.c" />
|
||||
<ClCompile Include="..\netcode\d_netfil.c" />
|
||||
<ClCompile Include="..\netcode\gamestate.c" />
|
||||
<ClCompile Include="..\netcode\http-mserv.c" />
|
||||
<ClCompile Include="..\netcode\i_addrinfo.c">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\netcode\i_tcp.c" />
|
||||
<ClCompile Include="..\netcode\mserv.c" />
|
||||
<ClCompile Include="..\netcode\net_command.c" />
|
||||
<ClCompile Include="..\netcode\server_connection.c" />
|
||||
<ClCompile Include="..\netcode\tic_command.c" />
|
||||
<ClCompile Include="..\p_ceilng.c" />
|
||||
<ClCompile Include="..\p_enemy.c" />
|
||||
<ClCompile Include="..\p_floor.c" />
|
||||
|
@ -510,6 +531,7 @@
|
|||
<ClCompile Include="..\r_textures.c" />
|
||||
<ClCompile Include="..\r_things.c" />
|
||||
<ClCompile Include="..\screen.c" />
|
||||
<ClCompile Include="..\snake.c" />
|
||||
<ClCompile Include="..\sounds.c" />
|
||||
<ClCompile Include="..\string.c" />
|
||||
<ClCompile Include="..\st_stuff.c" />
|
||||
|
|
|
@ -156,24 +156,12 @@
|
|||
<ClInclude Include="..\doomtype.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\d_clisrv.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\d_event.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\d_main.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\d_net.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\d_netcmd.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\d_netfil.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\d_player.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
|
@ -279,9 +267,6 @@
|
|||
<ClInclude Include="..\filesrch.h">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\i_addrinfo.h">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\i_joy.h">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClInclude>
|
||||
|
@ -306,12 +291,6 @@
|
|||
<ClInclude Include="..\keys.h">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\mserv.h">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\http-mserv.h">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lua_hook.h">
|
||||
<Filter>LUA</Filter>
|
||||
</ClInclude>
|
||||
|
@ -372,6 +351,54 @@
|
|||
<ClInclude Include="..\m_swap.h">
|
||||
<Filter>M_Misc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\netcode\client_connection.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\netcode\commands.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\netcode\d_clisrv.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\netcode\d_net.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\netcode\d_netcmd.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\netcode\d_netfil.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\netcode\gamestate.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\netcode\http-mserv.h">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\netcode\i_addrinfo.h">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\netcode\i_net.h">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\netcode\i_tcp.h">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\netcode\mserv.h">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\netcode\net_command.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\netcode\protocol.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\netcode\server_connection.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\netcode\tic_command.h">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\comptime.h">
|
||||
<Filter>O_Other</Filter>
|
||||
</ClInclude>
|
||||
|
@ -465,6 +492,9 @@
|
|||
<ClInclude Include="..\v_video.h">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\snake.h">
|
||||
<Filter>M_Misc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\sounds.h">
|
||||
<Filter>S_Sounds</Filter>
|
||||
</ClInclude>
|
||||
|
@ -639,21 +669,9 @@
|
|||
<ClCompile Include="..\deh_tables.c">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\d_clisrv.c">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\d_main.c">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\d_net.c">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\d_netcmd.c">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\d_netfil.c">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\z_zone.c">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClCompile>
|
||||
|
@ -732,18 +750,9 @@
|
|||
<ClCompile Include="..\filesrch.c">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\i_addrinfo.c">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\i_tcp.c">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\mserv.c">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\http-mserv.c">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lua_baselib.c">
|
||||
<Filter>LUA</Filter>
|
||||
</ClCompile>
|
||||
|
@ -831,6 +840,48 @@
|
|||
<ClCompile Include="..\m_random.c">
|
||||
<Filter>M_Misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\netcode\client_connection.c">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\netcode\commands.c">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\netcode\d_clisrv.c">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\netcode\d_net.c">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\netcode\d_netcmd.c">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\netcode\d_netfil.c">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\netcode\gamestate.c">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\netcode\http-mserv.c">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\netcode\i_addrinfo.c">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\netcode\i_tcp.c">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\netcode\mserv.c">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\netcode\net_command.c">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\netcode\server_connection.c">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\netcode\tic_command.c">
|
||||
<Filter>D_Doom</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\string.c">
|
||||
<Filter>M_Misc</Filter>
|
||||
</ClCompile>
|
||||
|
@ -954,6 +1005,9 @@
|
|||
<ClCompile Include="..\v_video.c">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\snake.c">
|
||||
<Filter>M_Misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\sounds.c">
|
||||
<Filter>S_Sounds</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
@ -21,16 +21,16 @@
|
|||
|
||||
#include "../i_system.h"
|
||||
#include "../d_event.h"
|
||||
#include "../d_net.h"
|
||||
#include "../netcode/d_net.h"
|
||||
#include "../m_argv.h"
|
||||
|
||||
#include "../doomstat.h"
|
||||
|
||||
#include "../i_net.h"
|
||||
#include "../netcode/i_net.h"
|
||||
|
||||
#include "../z_zone.h"
|
||||
|
||||
#include "../i_tcp.h"
|
||||
#include "../netcode/i_tcp.h"
|
||||
|
||||
#ifdef HAVE_SDL
|
||||
|
||||
|
|
|
@ -187,7 +187,8 @@ static char returnWadPath[256];
|
|||
#include "../i_system.h"
|
||||
#include "../i_threads.h"
|
||||
#include "../screen.h" //vid.WndParent
|
||||
#include "../d_net.h"
|
||||
#include "../netcode/d_net.h"
|
||||
#include "../netcode/commands.h"
|
||||
#include "../g_game.h"
|
||||
#include "../filesrch.h"
|
||||
#include "endtxt.h"
|
||||
|
@ -208,7 +209,7 @@ static char returnWadPath[256];
|
|||
|
||||
#if !defined(NOMUMBLE) && defined(HAVE_MUMBLE)
|
||||
// Mumble context string
|
||||
#include "../d_clisrv.h"
|
||||
#include "../netcode/d_clisrv.h"
|
||||
#include "../byteptr.h"
|
||||
#endif
|
||||
|
||||
|
@ -2387,9 +2388,7 @@ void I_Quit(void)
|
|||
SDLforceUngrabMouse();
|
||||
quiting = SDL_FALSE;
|
||||
M_SaveConfig(NULL); //save game config, cvars..
|
||||
#ifndef NONET
|
||||
D_SaveBan(); // save the ban list
|
||||
#endif
|
||||
G_SaveGameData(clientGamedata); // Tails 12-08-2002
|
||||
//added:16-02-98: when recording a demo, should exit using 'q' key,
|
||||
// but sometimes we forget and use 'F10'.. so save here too.
|
||||
|
@ -2504,9 +2503,7 @@ void I_Error(const char *error, ...)
|
|||
// ---
|
||||
|
||||
M_SaveConfig(NULL); // save game config, cvars..
|
||||
#ifndef NONET
|
||||
D_SaveBan(); // save the ban list
|
||||
#endif
|
||||
G_SaveGameData(clientGamedata); // Tails 12-08-2002
|
||||
|
||||
// Shutdown. Here might be other errors.
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue