mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-03-03 16:11:33 +00:00
Merge branch 'clientserver' into HEAD
This commit is contained in:
commit
8881ef52dc
64 changed files with 2015 additions and 3367 deletions
|
@ -876,6 +876,9 @@ set (PCH_SOURCES
|
|||
d_main.cpp
|
||||
d_stats.cpp
|
||||
d_net.cpp
|
||||
d_netsingle.cpp
|
||||
d_netserver.cpp
|
||||
d_netclient.cpp
|
||||
d_netinfo.cpp
|
||||
d_protocol.cpp
|
||||
decallib.cpp
|
||||
|
|
|
@ -48,6 +48,8 @@
|
|||
#include "tflags.h"
|
||||
#include "portal.h"
|
||||
|
||||
#include "d_netsync.h"
|
||||
|
||||
struct subsector_t;
|
||||
struct FBlockNode;
|
||||
struct FPortalGroupArray;
|
||||
|
@ -635,6 +637,9 @@ public:
|
|||
AActor &operator= (const AActor &other);
|
||||
~AActor ();
|
||||
|
||||
NetSyncData syncdata;
|
||||
NetSyncData synccompare;
|
||||
|
||||
virtual void Finalize(FStateDefinitions &statedef);
|
||||
virtual void OnDestroy() override;
|
||||
virtual void Serialize(FSerializer &arc) override;
|
||||
|
|
|
@ -212,7 +212,7 @@ CCMD (removebots)
|
|||
return;
|
||||
}
|
||||
|
||||
Net_WriteByte (DEM_KILLBOTS);
|
||||
network->WriteByte (DEM_KILLBOTS);
|
||||
}
|
||||
|
||||
CCMD (freeze)
|
||||
|
@ -226,8 +226,8 @@ CCMD (freeze)
|
|||
return;
|
||||
}
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_FREEZE);
|
||||
network->WriteByte (DEM_GENERICCHEAT);
|
||||
network->WriteByte (CHT_FREEZE);
|
||||
}
|
||||
|
||||
CCMD (listbots)
|
||||
|
|
|
@ -314,8 +314,8 @@ bool FCajunMaster::SpawnBot (const char *name, int color)
|
|||
|
||||
thebot->inuse = BOTINUSE_Waiting;
|
||||
|
||||
Net_WriteByte (DEM_ADDBOT);
|
||||
Net_WriteByte (botshift);
|
||||
network->WriteByte (DEM_ADDBOT);
|
||||
network->WriteByte (botshift);
|
||||
{
|
||||
//Set color.
|
||||
char concat[512];
|
||||
|
@ -329,12 +329,12 @@ bool FCajunMaster::SpawnBot (const char *name, int color)
|
|||
mysnprintf (concat + strlen(concat), countof(concat) - strlen(concat),
|
||||
"\\team\\%d\n", thebot->lastteam);
|
||||
}
|
||||
Net_WriteString (concat);
|
||||
network->WriteString (concat);
|
||||
}
|
||||
Net_WriteByte(thebot->skill.aiming);
|
||||
Net_WriteByte(thebot->skill.perfection);
|
||||
Net_WriteByte(thebot->skill.reaction);
|
||||
Net_WriteByte(thebot->skill.isp);
|
||||
network->WriteByte(thebot->skill.aiming);
|
||||
network->WriteByte(thebot->skill.perfection);
|
||||
network->WriteByte(thebot->skill.reaction);
|
||||
network->WriteByte(thebot->skill.isp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -58,9 +58,7 @@ static FRandom pr_botmove ("BotMove");
|
|||
//so this is what the bot does.
|
||||
void DBot::Think ()
|
||||
{
|
||||
ticcmd_t *cmd = &netcmds[player - players][((gametic + 1)/ticdup)%BACKUPTICS];
|
||||
|
||||
memset (cmd, 0, sizeof(*cmd));
|
||||
ticcmd_t cmd;
|
||||
|
||||
if (enemy && enemy->health <= 0)
|
||||
enemy = NULL;
|
||||
|
@ -75,16 +73,16 @@ void DBot::Think ()
|
|||
DAngle oldpitch = actor->Angles.Pitch;
|
||||
|
||||
Set_enemy ();
|
||||
ThinkForMove (cmd);
|
||||
ThinkForMove (&cmd);
|
||||
TurnToAng ();
|
||||
|
||||
cmd->ucmd.yaw = (short)((actor->Angles.Yaw - oldyaw).Degrees * (65536 / 360.f)) / ticdup;
|
||||
cmd->ucmd.pitch = (short)((oldpitch - actor->Angles.Pitch).Degrees * (65536 / 360.f));
|
||||
if (cmd->ucmd.pitch == -32768)
|
||||
cmd->ucmd.pitch = -32767;
|
||||
cmd->ucmd.pitch /= ticdup;
|
||||
actor->Angles.Yaw = oldyaw + DAngle(cmd->ucmd.yaw * ticdup * (360 / 65536.f));
|
||||
actor->Angles.Pitch = oldpitch - DAngle(cmd->ucmd.pitch * ticdup * (360 / 65536.f));
|
||||
cmd.ucmd.yaw = (short)((actor->Angles.Yaw - oldyaw).Degrees * (65536 / 360.f)) / network->ticdup;
|
||||
cmd.ucmd.pitch = (short)((oldpitch - actor->Angles.Pitch).Degrees * (65536 / 360.f));
|
||||
if (cmd.ucmd.pitch == -32768)
|
||||
cmd.ucmd.pitch = -32767;
|
||||
cmd.ucmd.pitch /= network->ticdup;
|
||||
actor->Angles.Yaw = oldyaw + DAngle(cmd.ucmd.yaw * network->ticdup * (360 / 65536.f));
|
||||
actor->Angles.Pitch = oldpitch - DAngle(cmd.ucmd.pitch * network->ticdup * (360 / 65536.f));
|
||||
}
|
||||
|
||||
if (t_active) t_active--;
|
||||
|
@ -101,8 +99,10 @@ void DBot::Think ()
|
|||
}
|
||||
else if (player->mo->health <= 0)
|
||||
{ // Time to respawn
|
||||
cmd->ucmd.buttons |= BT_USE;
|
||||
cmd.ucmd.buttons |= BT_USE;
|
||||
}
|
||||
|
||||
network->WriteBotInput((int)(player - players), cmd);
|
||||
}
|
||||
|
||||
#define THINKDISTSQ (50000.*50000./(65536.*65536.))
|
||||
|
|
136
src/c_cmds.cpp
136
src/c_cmds.cpp
|
@ -117,8 +117,8 @@ CCMD (god)
|
|||
if (CheckCheatmode ())
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_GOD);
|
||||
network->WriteByte (DEM_GENERICCHEAT);
|
||||
network->WriteByte (CHT_GOD);
|
||||
}
|
||||
|
||||
CCMD(god2)
|
||||
|
@ -126,8 +126,8 @@ CCMD(god2)
|
|||
if (CheckCheatmode())
|
||||
return;
|
||||
|
||||
Net_WriteByte(DEM_GENERICCHEAT);
|
||||
Net_WriteByte(CHT_GOD2);
|
||||
network->WriteByte(DEM_GENERICCHEAT);
|
||||
network->WriteByte(CHT_GOD2);
|
||||
}
|
||||
|
||||
CCMD (iddqd)
|
||||
|
@ -135,8 +135,8 @@ CCMD (iddqd)
|
|||
if (CheckCheatmode ())
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_IDDQD);
|
||||
network->WriteByte (DEM_GENERICCHEAT);
|
||||
network->WriteByte (CHT_IDDQD);
|
||||
}
|
||||
|
||||
CCMD (buddha)
|
||||
|
@ -144,8 +144,8 @@ CCMD (buddha)
|
|||
if (CheckCheatmode())
|
||||
return;
|
||||
|
||||
Net_WriteByte(DEM_GENERICCHEAT);
|
||||
Net_WriteByte(CHT_BUDDHA);
|
||||
network->WriteByte(DEM_GENERICCHEAT);
|
||||
network->WriteByte(CHT_BUDDHA);
|
||||
}
|
||||
|
||||
CCMD(buddha2)
|
||||
|
@ -153,8 +153,8 @@ CCMD(buddha2)
|
|||
if (CheckCheatmode())
|
||||
return;
|
||||
|
||||
Net_WriteByte(DEM_GENERICCHEAT);
|
||||
Net_WriteByte(CHT_BUDDHA2);
|
||||
network->WriteByte(DEM_GENERICCHEAT);
|
||||
network->WriteByte(CHT_BUDDHA2);
|
||||
}
|
||||
|
||||
CCMD (notarget)
|
||||
|
@ -162,8 +162,8 @@ CCMD (notarget)
|
|||
if (CheckCheatmode ())
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_NOTARGET);
|
||||
network->WriteByte (DEM_GENERICCHEAT);
|
||||
network->WriteByte (CHT_NOTARGET);
|
||||
}
|
||||
|
||||
CCMD (fly)
|
||||
|
@ -171,8 +171,8 @@ CCMD (fly)
|
|||
if (CheckCheatmode ())
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_FLY);
|
||||
network->WriteByte (DEM_GENERICCHEAT);
|
||||
network->WriteByte (CHT_FLY);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -187,8 +187,8 @@ CCMD (noclip)
|
|||
if (CheckCheatmode ())
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_NOCLIP);
|
||||
network->WriteByte (DEM_GENERICCHEAT);
|
||||
network->WriteByte (CHT_NOCLIP);
|
||||
}
|
||||
|
||||
CCMD (noclip2)
|
||||
|
@ -196,8 +196,8 @@ CCMD (noclip2)
|
|||
if (CheckCheatmode())
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_NOCLIP2);
|
||||
network->WriteByte (DEM_GENERICCHEAT);
|
||||
network->WriteByte (CHT_NOCLIP2);
|
||||
}
|
||||
|
||||
CCMD (powerup)
|
||||
|
@ -205,8 +205,8 @@ CCMD (powerup)
|
|||
if (CheckCheatmode ())
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_POWER);
|
||||
network->WriteByte (DEM_GENERICCHEAT);
|
||||
network->WriteByte (CHT_POWER);
|
||||
}
|
||||
|
||||
CCMD (morphme)
|
||||
|
@ -216,13 +216,13 @@ CCMD (morphme)
|
|||
|
||||
if (argv.argc() == 1)
|
||||
{
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_MORPH);
|
||||
network->WriteByte (DEM_GENERICCHEAT);
|
||||
network->WriteByte (CHT_MORPH);
|
||||
}
|
||||
else
|
||||
{
|
||||
Net_WriteByte (DEM_MORPHEX);
|
||||
Net_WriteString (argv[1]);
|
||||
network->WriteByte (DEM_MORPHEX);
|
||||
network->WriteString (argv[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,8 +231,8 @@ CCMD (anubis)
|
|||
if (CheckCheatmode ())
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_ANUBIS);
|
||||
network->WriteByte (DEM_GENERICCHEAT);
|
||||
network->WriteByte (CHT_ANUBIS);
|
||||
}
|
||||
|
||||
// [GRB]
|
||||
|
@ -241,8 +241,8 @@ CCMD (resurrect)
|
|||
if (CheckCheatmode ())
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_RESSURECT);
|
||||
network->WriteByte (DEM_GENERICCHEAT);
|
||||
network->WriteByte (CHT_RESSURECT);
|
||||
}
|
||||
|
||||
EXTERN_CVAR (Bool, chasedemo)
|
||||
|
@ -273,8 +273,8 @@ CCMD (chase)
|
|||
if (gamestate != GS_LEVEL || (!(dmflags2 & DF2_CHASECAM) && deathmatch && CheckCheatmode ()))
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_CHASECAM);
|
||||
network->WriteByte (DEM_GENERICCHEAT);
|
||||
network->WriteByte (CHT_CHASECAM);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -372,14 +372,14 @@ CCMD (changemap)
|
|||
{
|
||||
if (argv.argc() > 2)
|
||||
{
|
||||
Net_WriteByte (DEM_CHANGEMAP2);
|
||||
Net_WriteByte (atoi(argv[2]));
|
||||
network->WriteByte (DEM_CHANGEMAP2);
|
||||
network->WriteByte (atoi(argv[2]));
|
||||
}
|
||||
else
|
||||
{
|
||||
Net_WriteByte (DEM_CHANGEMAP);
|
||||
network->WriteByte (DEM_CHANGEMAP);
|
||||
}
|
||||
Net_WriteString (mapname);
|
||||
network->WriteString (mapname);
|
||||
}
|
||||
}
|
||||
catch(CRecoverableError &error)
|
||||
|
@ -399,12 +399,12 @@ CCMD (give)
|
|||
if (CheckCheatmode () || argv.argc() < 2)
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GIVECHEAT);
|
||||
Net_WriteString (argv[1]);
|
||||
network->WriteByte (DEM_GIVECHEAT);
|
||||
network->WriteString (argv[1]);
|
||||
if (argv.argc() > 2)
|
||||
Net_WriteLong(atoi(argv[2]));
|
||||
network->WriteLong(atoi(argv[2]));
|
||||
else
|
||||
Net_WriteLong(0);
|
||||
network->WriteLong(0);
|
||||
}
|
||||
|
||||
CCMD (take)
|
||||
|
@ -412,12 +412,12 @@ CCMD (take)
|
|||
if (CheckCheatmode () || argv.argc() < 2)
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_TAKECHEAT);
|
||||
Net_WriteString (argv[1]);
|
||||
network->WriteByte (DEM_TAKECHEAT);
|
||||
network->WriteString (argv[1]);
|
||||
if (argv.argc() > 2)
|
||||
Net_WriteLong(atoi (argv[2]));
|
||||
network->WriteLong(atoi (argv[2]));
|
||||
else
|
||||
Net_WriteLong (0);
|
||||
network->WriteLong (0);
|
||||
}
|
||||
|
||||
CCMD(setinv)
|
||||
|
@ -425,17 +425,17 @@ CCMD(setinv)
|
|||
if (CheckCheatmode() || argv.argc() < 2)
|
||||
return;
|
||||
|
||||
Net_WriteByte(DEM_SETINV);
|
||||
Net_WriteString(argv[1]);
|
||||
network->WriteByte(DEM_SETINV);
|
||||
network->WriteString(argv[1]);
|
||||
if (argv.argc() > 2)
|
||||
Net_WriteLong(atoi(argv[2]));
|
||||
network->WriteLong(atoi(argv[2]));
|
||||
else
|
||||
Net_WriteLong(0);
|
||||
network->WriteLong(0);
|
||||
|
||||
if (argv.argc() > 3)
|
||||
Net_WriteByte(!!atoi(argv[3]));
|
||||
network->WriteByte(!!atoi(argv[3]));
|
||||
else
|
||||
Net_WriteByte(0);
|
||||
network->WriteByte(0);
|
||||
|
||||
}
|
||||
|
||||
|
@ -533,18 +533,18 @@ CCMD (puke)
|
|||
|
||||
if (script > 0)
|
||||
{
|
||||
Net_WriteByte (DEM_RUNSCRIPT);
|
||||
Net_WriteWord (script);
|
||||
network->WriteByte (DEM_RUNSCRIPT);
|
||||
network->WriteWord (script);
|
||||
}
|
||||
else
|
||||
{
|
||||
Net_WriteByte (DEM_RUNSCRIPT2);
|
||||
Net_WriteWord (-script);
|
||||
network->WriteByte (DEM_RUNSCRIPT2);
|
||||
network->WriteWord (-script);
|
||||
}
|
||||
Net_WriteByte (argn);
|
||||
network->WriteByte (argn);
|
||||
for (i = 0; i < argn; ++i)
|
||||
{
|
||||
Net_WriteLong (arg[i]);
|
||||
network->WriteLong (arg[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -577,12 +577,12 @@ CCMD (pukename)
|
|||
arg[i] = atoi(argv[argstart + i]);
|
||||
}
|
||||
}
|
||||
Net_WriteByte(DEM_RUNNAMEDSCRIPT);
|
||||
Net_WriteString(argv[1]);
|
||||
Net_WriteByte(argn | (always << 7));
|
||||
network->WriteByte(DEM_RUNNAMEDSCRIPT);
|
||||
network->WriteString(argv[1]);
|
||||
network->WriteByte(argn | (always << 7));
|
||||
for (i = 0; i < argn; ++i)
|
||||
{
|
||||
Net_WriteLong(arg[i]);
|
||||
network->WriteLong(arg[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -623,12 +623,12 @@ CCMD (special)
|
|||
return;
|
||||
}
|
||||
}
|
||||
Net_WriteByte(DEM_RUNSPECIAL);
|
||||
Net_WriteWord(specnum);
|
||||
Net_WriteByte(argc - 2);
|
||||
network->WriteByte(DEM_RUNSPECIAL);
|
||||
network->WriteWord(specnum);
|
||||
network->WriteByte(argc - 2);
|
||||
for (int i = 2; i < argc; ++i)
|
||||
{
|
||||
Net_WriteLong(atoi(argv[i]));
|
||||
network->WriteLong(atoi(argv[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -774,10 +774,10 @@ CCMD (warp)
|
|||
}
|
||||
else
|
||||
{
|
||||
Net_WriteByte (DEM_WARPCHEAT);
|
||||
Net_WriteWord (atoi (argv[1]));
|
||||
Net_WriteWord (atoi (argv[2]));
|
||||
Net_WriteWord (argv.argc() == 3 ? ONFLOORZ/65536 : atoi (argv[3]));
|
||||
network->WriteByte (DEM_WARPCHEAT);
|
||||
network->WriteWord (atoi (argv[1]));
|
||||
network->WriteWord (atoi (argv[2]));
|
||||
network->WriteWord (argv.argc() == 3 ? ONFLOORZ/65536 : atoi (argv[3]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1078,8 +1078,8 @@ CCMD(thaw)
|
|||
if (CheckCheatmode())
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_CLEARFROZENPROPS);
|
||||
network->WriteByte (DEM_GENERICCHEAT);
|
||||
network->WriteByte (CHT_CLEARFROZENPROPS);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -1238,7 +1238,7 @@ void C_FullConsole ()
|
|||
{
|
||||
if (demoplayback)
|
||||
G_CheckDemoStatus ();
|
||||
D_QuitNetGame ();
|
||||
network->D_QuitNetGame ();
|
||||
advancedemo = false;
|
||||
ConsoleState = c_down;
|
||||
HistPos = NULL;
|
||||
|
|
|
@ -1159,7 +1159,7 @@ void FBaseCVar::MarkUnsafe()
|
|||
// This type of cvar is not a "real" cvar. Instead, it gets and sets
|
||||
// the value of a FIntCVar, modifying it bit-by-bit. As such, it has
|
||||
// no default, and is not written to the .cfg or transferred around
|
||||
// the network. The "host" cvar is responsible for that.
|
||||
// the network-> The "host" cvar is responsible for that.
|
||||
//
|
||||
|
||||
FFlagCVar::FFlagCVar (const char *name, FIntCVar &realvar, uint32_t bitval)
|
||||
|
|
|
@ -621,7 +621,7 @@ void C_DoCommand (const char *cmd, int keynum)
|
|||
button->ReleaseKey (keynum);
|
||||
if (button == &Button_Mlook && lookspring)
|
||||
{
|
||||
Net_WriteByte (DEM_CENTERVIEW);
|
||||
network->WriteByte (DEM_CENTERVIEW);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -349,16 +349,16 @@ static void ShoveChatStr (const char *str, uint8_t who)
|
|||
who |= 2;
|
||||
}
|
||||
|
||||
Net_WriteByte (DEM_SAY);
|
||||
Net_WriteByte (who);
|
||||
network->WriteByte (DEM_SAY);
|
||||
network->WriteByte (who);
|
||||
|
||||
if (!chat_substitution || !DoSubstitution (substBuff, str))
|
||||
{
|
||||
Net_WriteString (str);
|
||||
network->WriteString (str);
|
||||
}
|
||||
else
|
||||
{
|
||||
Net_WriteString (substBuff);
|
||||
network->WriteString (substBuff);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -119,17 +119,13 @@ typedef enum
|
|||
// Called by IO functions when input is detected.
|
||||
void D_PostEvent (const event_t* ev);
|
||||
void D_RemoveNextCharEvent();
|
||||
|
||||
void D_AddPostedEvents();
|
||||
|
||||
//
|
||||
// GLOBAL VARIABLES
|
||||
//
|
||||
#define MAXEVENTS 128
|
||||
|
||||
extern event_t events[MAXEVENTS];
|
||||
extern int eventhead;
|
||||
extern int eventtail;
|
||||
|
||||
extern gameaction_t gameaction;
|
||||
|
||||
|
||||
|
|
213
src/d_main.cpp
213
src/d_main.cpp
|
@ -97,6 +97,7 @@
|
|||
#include "vm.h"
|
||||
#include "types.h"
|
||||
#include "r_data/r_vanillatrans.h"
|
||||
#include "d_netsingle.h"
|
||||
|
||||
EXTERN_CVAR(Bool, hud_althud)
|
||||
void DrawHUD();
|
||||
|
@ -122,9 +123,7 @@ const FIWADInfo *D_FindIWAD(TArray<FString> &wadfiles, const char *iwad, const c
|
|||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
void D_CheckNetGame ();
|
||||
void D_ProcessEvents ();
|
||||
void G_BuildTiccmd (ticcmd_t* cmd);
|
||||
void D_DoAdvanceDemo ();
|
||||
void D_AddWildFile (TArray<FString> &wadfiles, const char *pattern);
|
||||
void D_LoadWadSettings ();
|
||||
|
@ -218,9 +217,10 @@ FString StoredWarp;
|
|||
bool advancedemo;
|
||||
FILE *debugfile;
|
||||
FILE *hashfile;
|
||||
event_t events[MAXEVENTS];
|
||||
int eventhead;
|
||||
int eventtail;
|
||||
static TArray<event_t> FrameStartInputEvents;
|
||||
static event_t events[MAXEVENTS];
|
||||
static int eventhead;
|
||||
static int eventtail;
|
||||
gamestate_t wipegamestate = GS_DEMOSCREEN; // can be -1 to force a wipe
|
||||
bool PageBlank;
|
||||
FTexture *Page;
|
||||
|
@ -301,10 +301,20 @@ void D_ProcessEvents (void)
|
|||
|
||||
void D_PostEvent (const event_t *ev)
|
||||
{
|
||||
FrameStartInputEvents.Push(*ev);
|
||||
}
|
||||
|
||||
void D_AddPostedEvents()
|
||||
{
|
||||
unsigned int c = FrameStartInputEvents.Size();
|
||||
for (unsigned int i = 0; i < c; i++)
|
||||
{
|
||||
const event_t *ev = &FrameStartInputEvents[i];
|
||||
|
||||
// Do not post duplicate consecutive EV_DeviceChange events.
|
||||
if (ev->type == EV_DeviceChange && events[eventhead].type == EV_DeviceChange)
|
||||
{
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
events[eventhead] = *ev;
|
||||
if (ev->type == EV_Mouse && menuactive == MENU_Off && ConsoleState != c_down && ConsoleState != c_falling && !E_Responder(ev) && !paused)
|
||||
|
@ -314,20 +324,23 @@ void D_PostEvent (const event_t *ev)
|
|||
int look = int(ev->y * m_pitch * mouse_sensitivity * 16.0);
|
||||
if (invertmouse)
|
||||
look = -look;
|
||||
G_AddViewPitch (look, true);
|
||||
G_AddViewPitch(look, true);
|
||||
events[eventhead].y = 0;
|
||||
}
|
||||
if (!Button_Strafe.bDown && !lookstrafe)
|
||||
{
|
||||
G_AddViewAngle (int(ev->x * m_yaw * mouse_sensitivity * 8.0), true);
|
||||
G_AddViewAngle(int(ev->x * m_yaw * mouse_sensitivity * 8.0), true);
|
||||
events[eventhead].x = 0;
|
||||
}
|
||||
if ((events[eventhead].x | events[eventhead].y) == 0)
|
||||
{
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
eventhead = (eventhead+1)&(MAXEVENTS-1);
|
||||
eventhead = (eventhead + 1)&(MAXEVENTS - 1);
|
||||
}
|
||||
|
||||
FrameStartInputEvents.Clear();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -380,14 +393,14 @@ CUSTOM_CVAR (Int, dmflags, 0, CVAR_SERVERINFO)
|
|||
|
||||
if (self & DF_NO_FREELOOK)
|
||||
{
|
||||
Net_WriteByte (DEM_CENTERVIEW);
|
||||
network->WriteByte (DEM_CENTERVIEW);
|
||||
}
|
||||
// If nofov is set, force everybody to the arbitrator's FOV.
|
||||
if ((self & DF_NO_FOV) && consoleplayer == Net_Arbitrator)
|
||||
{
|
||||
float fov;
|
||||
|
||||
Net_WriteByte (DEM_FOV);
|
||||
network->WriteByte (DEM_FOV);
|
||||
|
||||
// If the game is started with DF_NO_FOV set, the arbitrator's
|
||||
// DesiredFOV will not be set when this callback is run, so
|
||||
|
@ -397,7 +410,7 @@ CUSTOM_CVAR (Int, dmflags, 0, CVAR_SERVERINFO)
|
|||
{
|
||||
fov = 90;
|
||||
}
|
||||
Net_WriteFloat (fov);
|
||||
network->WriteFloat (fov);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -899,7 +912,6 @@ void D_Display ()
|
|||
|
||||
if (!wipe || NoWipe < 0)
|
||||
{
|
||||
NetUpdate (); // send out any new accumulation
|
||||
// normal update
|
||||
// draw ZScript UI stuff
|
||||
C_DrawConsole (); // draw console
|
||||
|
@ -918,7 +930,6 @@ void D_Display ()
|
|||
screen->WipeEndScreen ();
|
||||
|
||||
wipestart = I_msTime();
|
||||
NetUpdate(); // send out any new accumulation
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -933,7 +944,6 @@ void D_Display ()
|
|||
C_DrawConsole (); // console and
|
||||
M_Drawer (); // menu are drawn even on top of wipes
|
||||
screen->Update (); // page flip or blit buffer
|
||||
NetUpdate (); // [RH] not sure this is needed anymore
|
||||
} while (!done);
|
||||
screen->WipeCleanup();
|
||||
I_FreezeTime(false);
|
||||
|
@ -955,10 +965,10 @@ void D_ErrorCleanup ()
|
|||
{
|
||||
savegamerestore = false;
|
||||
bglobal.RemoveAllBots (true);
|
||||
D_QuitNetGame ();
|
||||
network->D_QuitNetGame ();
|
||||
if (demorecording || demoplayback)
|
||||
G_CheckDemoStatus ();
|
||||
Net_ClearBuffers ();
|
||||
network->Net_ClearBuffers ();
|
||||
G_NewInit ();
|
||||
M_ClearMenus ();
|
||||
singletics = false;
|
||||
|
@ -982,53 +992,132 @@ void D_ErrorCleanup ()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void D_DoomLoop ()
|
||||
class GameTime
|
||||
{
|
||||
int lasttic = 0;
|
||||
public:
|
||||
void Update()
|
||||
{
|
||||
LastTic = CurrentTic;
|
||||
I_SetFrameTime();
|
||||
CurrentTic = I_GetTime();
|
||||
}
|
||||
|
||||
int TicsElapsed() const
|
||||
{
|
||||
return CurrentTic - LastTic;
|
||||
}
|
||||
|
||||
int BaseGameTic() const
|
||||
{
|
||||
return LastTic;
|
||||
}
|
||||
|
||||
int BaseMakeTic() const
|
||||
{
|
||||
return LastTic + 1;
|
||||
}
|
||||
|
||||
private:
|
||||
int LastTic = 0;
|
||||
int CurrentTic = 0;
|
||||
} gametime;
|
||||
|
||||
class GameInput
|
||||
{
|
||||
public:
|
||||
void Update()
|
||||
{
|
||||
// Not sure why the joystick can't be updated every frame..
|
||||
bool updateJoystick = gametime.TicsElapsed() > 0;
|
||||
if (updateJoystick)
|
||||
{
|
||||
I_StartFrame(); // To do: rename this silly function to I_UpdateJoystick
|
||||
}
|
||||
|
||||
// Grab input events at the beginning of the frame.
|
||||
// This ensures the mouse movement matches I_GetTimeFrac precisely.
|
||||
I_StartTic(); // To do: rename this to I_ProcessWindowMessages
|
||||
}
|
||||
|
||||
void BeforeDisplayUpdate()
|
||||
{
|
||||
// Apply the events we recorded in I_StartTic as the events for the next frame.
|
||||
D_AddPostedEvents();
|
||||
}
|
||||
|
||||
} input;
|
||||
|
||||
ticcmd_t G_BuildTiccmd();
|
||||
|
||||
class PlaySim
|
||||
{
|
||||
public:
|
||||
void Update()
|
||||
{
|
||||
int tics = gametime.TicsElapsed();
|
||||
if (tics == 0)
|
||||
return;
|
||||
|
||||
P_UnPredictPlayer();
|
||||
|
||||
D_ProcessEvents();
|
||||
|
||||
for (int i = 0; i < tics; i++)
|
||||
{
|
||||
network->SetCurrentTic(gametime.BaseGameTic() + i, gametime.BaseMakeTic() + i);
|
||||
network->WriteLocalInput(G_BuildTiccmd());
|
||||
|
||||
if (advancedemo)
|
||||
D_DoAdvanceDemo();
|
||||
|
||||
C_Ticker();
|
||||
M_Ticker();
|
||||
G_Ticker();
|
||||
|
||||
network->EndCurrentTic();
|
||||
}
|
||||
|
||||
P_PredictPlayer(&players[consoleplayer]);
|
||||
|
||||
S_UpdateSounds(players[consoleplayer].camera); // move positional sounds
|
||||
}
|
||||
|
||||
} playsim;
|
||||
|
||||
class GameDisplay
|
||||
{
|
||||
public:
|
||||
void Update()
|
||||
{
|
||||
// Render frame and present
|
||||
D_Display();
|
||||
}
|
||||
|
||||
} display;
|
||||
|
||||
void D_DoomLoop()
|
||||
{
|
||||
// Clamp the timer to TICRATE until the playloop has been entered.
|
||||
r_NoInterpolate = true;
|
||||
Page = Advisory = NULL;
|
||||
|
||||
vid_cursor.Callback();
|
||||
|
||||
for (;;)
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
// frame syncronous IO operations
|
||||
if (gametic > lasttic)
|
||||
{
|
||||
lasttic = gametic;
|
||||
I_StartFrame ();
|
||||
}
|
||||
I_SetFrameTime();
|
||||
gametime.Update();
|
||||
if (netconnect)
|
||||
netconnect->Update();
|
||||
network->Update();
|
||||
input.Update();
|
||||
playsim.Update();
|
||||
input.BeforeDisplayUpdate();
|
||||
display.Update();
|
||||
|
||||
GC::CheckGC();
|
||||
|
||||
// process one or more tics
|
||||
if (singletics)
|
||||
{
|
||||
I_StartTic ();
|
||||
D_ProcessEvents ();
|
||||
G_BuildTiccmd (&netcmds[consoleplayer][maketic%BACKUPTICS]);
|
||||
if (advancedemo)
|
||||
D_DoAdvanceDemo ();
|
||||
C_Ticker ();
|
||||
M_Ticker ();
|
||||
G_Ticker ();
|
||||
// [RH] Use the consoleplayer's camera to update sounds
|
||||
S_UpdateSounds (players[consoleplayer].camera); // move positional sounds
|
||||
gametic++;
|
||||
maketic++;
|
||||
GC::CheckGC ();
|
||||
Net_NewMakeTic ();
|
||||
}
|
||||
else
|
||||
{
|
||||
TryRunTics (); // will run at least one tic
|
||||
}
|
||||
// Update display, next frame, with current state.
|
||||
I_StartTic ();
|
||||
D_Display ();
|
||||
if (wantToRestart)
|
||||
{
|
||||
wantToRestart = false;
|
||||
|
@ -1037,11 +1126,11 @@ void D_DoomLoop ()
|
|||
}
|
||||
catch (CRecoverableError &error)
|
||||
{
|
||||
if (error.GetMessage ())
|
||||
if (error.GetMessage())
|
||||
{
|
||||
Printf (PRINT_BOLD, "\n%s\n", error.GetMessage());
|
||||
Printf(PRINT_BOLD, "\n%s\n", error.GetMessage());
|
||||
}
|
||||
D_ErrorCleanup ();
|
||||
D_ErrorCleanup();
|
||||
}
|
||||
catch (CVMAbortException &error)
|
||||
{
|
||||
|
@ -2313,6 +2402,8 @@ void D_DoomMain (void)
|
|||
|
||||
D_DoomInit();
|
||||
|
||||
network.reset(new NetSinglePlayer());
|
||||
|
||||
extern void D_ConfirmSendStats();
|
||||
D_ConfirmSendStats();
|
||||
|
||||
|
@ -2593,9 +2684,7 @@ void D_DoomMain (void)
|
|||
|
||||
if (!restart)
|
||||
{
|
||||
if (!batchrun) Printf ("D_CheckNetGame: Checking network game status.\n");
|
||||
StartScreen->LoadingStatus ("Checking network game status.", 0x3f);
|
||||
D_CheckNetGame ();
|
||||
D_SetupUserInfo();
|
||||
}
|
||||
|
||||
// [SP] Force vanilla transparency auto-detection to re-detect our game lumps now
|
||||
|
@ -2610,7 +2699,7 @@ void D_DoomMain (void)
|
|||
|
||||
// [RH] Run any saved commands from the command line or autoexec.cfg now.
|
||||
gamestate = GS_FULLCONSOLE;
|
||||
Net_NewMakeTic ();
|
||||
network->Startup();
|
||||
DThinker::RunThinkers ();
|
||||
gamestate = GS_STARTUP;
|
||||
|
||||
|
@ -2693,7 +2782,7 @@ void D_DoomMain (void)
|
|||
G_BeginRecording(NULL);
|
||||
}
|
||||
|
||||
atterm(D_QuitNetGame); // killough
|
||||
atterm([] { network->D_QuitNetGame(); }); // killough
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2867,7 +2956,7 @@ void FStartupScreen::NetInit(char const *,int) {}
|
|||
void FStartupScreen::NetProgress(int) {}
|
||||
void FStartupScreen::NetMessage(char const *,...) {}
|
||||
void FStartupScreen::NetDone(void) {}
|
||||
bool FStartupScreen::NetLoop(bool (*)(void *),void *) { return false; }
|
||||
bool FStartupScreen::NetLoop(std::function<bool()> callback) { return false; }
|
||||
|
||||
DEFINE_FIELD_X(InputEventData, event_t, type)
|
||||
DEFINE_FIELD_X(InputEventData, event_t, subtype)
|
||||
|
|
2065
src/d_net.cpp
2065
src/d_net.cpp
File diff suppressed because it is too large
Load diff
197
src/d_net.h
197
src/d_net.h
|
@ -3,6 +3,7 @@
|
|||
// Copyright 1993-1996 id Software
|
||||
// Copyright 1999-2016 Randy Heit
|
||||
// Copyright 2002-2016 Christoph Oelckers
|
||||
// Copyright 2018 Magnus Norddahl
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
|
@ -17,141 +18,109 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Networking stuff.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __D_NET__
|
||||
#define __D_NET__
|
||||
#pragma once
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "doomdef.h"
|
||||
#include "d_protocol.h"
|
||||
#include "i_net.h"
|
||||
#include <memory>
|
||||
|
||||
|
||||
//
|
||||
// Network play related stuff.
|
||||
// There is a data struct that stores network
|
||||
// communication related stuff, and another
|
||||
// one that defines the actual packets to
|
||||
// be transmitted.
|
||||
//
|
||||
|
||||
#define DOOMCOM_ID 0x12345678l
|
||||
#define MAXNETNODES 8 // max computers in a game
|
||||
#define BACKUPTICS 36 // number of tics to remember
|
||||
#define MAXTICDUP 5
|
||||
#define LOCALCMDTICS (BACKUPTICS*MAXTICDUP)
|
||||
|
||||
|
||||
#ifdef DJGPP
|
||||
// The DOS drivers provide a pretty skimpy buffer.
|
||||
// Probably not enough.
|
||||
#define MAX_MSGLEN (BACKUPTICS*10)
|
||||
#else
|
||||
#define MAX_MSGLEN 14000
|
||||
#endif
|
||||
|
||||
#define CMD_SEND 1
|
||||
#define CMD_GET 2
|
||||
|
||||
//
|
||||
// Network packet data.
|
||||
//
|
||||
struct doomcom_t
|
||||
{
|
||||
uint32_t id; // should be DOOMCOM_ID
|
||||
int16_t intnum; // DOOM executes an int to execute commands
|
||||
|
||||
// communication between DOOM and the driver
|
||||
int16_t command; // CMD_SEND or CMD_GET
|
||||
int16_t remotenode; // dest for send, set by get (-1 = no packet).
|
||||
int16_t datalength; // bytes in doomdata to be sent
|
||||
|
||||
// info common to all nodes
|
||||
int16_t numnodes; // console is always node 0.
|
||||
int16_t ticdup; // 1 = no duplication, 2-5 = dup for slow nets
|
||||
#ifdef DJGPP
|
||||
int16_t pad[5]; // keep things aligned for DOS drivers
|
||||
#endif
|
||||
|
||||
// info specific to this node
|
||||
int16_t consoleplayer;
|
||||
int16_t numplayers;
|
||||
#ifdef DJGPP
|
||||
int16_t angleoffset; // does not work, but needed to preserve
|
||||
int16_t drone; // alignment for DOS drivers
|
||||
#endif
|
||||
|
||||
// packet data to be sent
|
||||
uint8_t data[MAX_MSGLEN];
|
||||
|
||||
};
|
||||
|
||||
|
||||
class FDynamicBuffer
|
||||
{
|
||||
public:
|
||||
FDynamicBuffer ();
|
||||
~FDynamicBuffer ();
|
||||
FDynamicBuffer();
|
||||
FDynamicBuffer(const FDynamicBuffer &src);
|
||||
~FDynamicBuffer();
|
||||
|
||||
void SetData (const uint8_t *data, int len);
|
||||
uint8_t *GetData (int *len = NULL);
|
||||
FDynamicBuffer &operator=(const FDynamicBuffer &src);
|
||||
|
||||
void Clear() { SetData(nullptr, 0); }
|
||||
void SetData(const uint8_t *data, int len);
|
||||
void AppendData(const uint8_t *data, int len);
|
||||
|
||||
uint8_t *GetData() { return m_Len ? m_Data : nullptr; }
|
||||
const uint8_t *GetData() const { return m_Len ? m_Data : nullptr; }
|
||||
int GetSize() const { return m_Len; }
|
||||
|
||||
private:
|
||||
uint8_t *m_Data;
|
||||
int m_Len, m_BufferLen;
|
||||
uint8_t *m_Data = nullptr;
|
||||
int m_Len = 0;
|
||||
int m_BufferLen = 0;
|
||||
};
|
||||
|
||||
extern FDynamicBuffer NetSpecs[MAXPLAYERS][BACKUPTICS];
|
||||
class Network
|
||||
{
|
||||
public:
|
||||
virtual ~Network() { }
|
||||
|
||||
// Create any new ticcmds and broadcast to other players.
|
||||
void NetUpdate (void);
|
||||
// Check for incoming packets
|
||||
virtual void Update() = 0;
|
||||
|
||||
// Broadcasts special packets to other players
|
||||
// to notify of game exit
|
||||
void D_QuitNetGame (void);
|
||||
// Set current tic for reading and writing
|
||||
virtual void SetCurrentTic(int receivetic, int sendtic) = 0;
|
||||
|
||||
//? how many ticks to run?
|
||||
void TryRunTics (void);
|
||||
// Send any pending outgoing data
|
||||
virtual void EndCurrentTic() = 0;
|
||||
|
||||
//Use for checking to see if the netgame has stalled
|
||||
void Net_CheckLastReceived(int);
|
||||
// Retrieve data about the current tic
|
||||
virtual int GetSendTick() const = 0;
|
||||
virtual ticcmd_t GetPlayerInput(int player) const = 0;
|
||||
virtual ticcmd_t GetSentInput(int tic) const = 0;
|
||||
|
||||
// [RH] Functions for making and using special "ticcmds"
|
||||
void Net_NewMakeTic ();
|
||||
void Net_WriteByte (uint8_t);
|
||||
void Net_WriteWord (short);
|
||||
void Net_WriteLong (int);
|
||||
void Net_WriteFloat (float);
|
||||
void Net_WriteString (const char *);
|
||||
void Net_WriteBytes (const uint8_t *, int len);
|
||||
// Run network commands for the current tic
|
||||
virtual void RunCommands(int player) = 0;
|
||||
|
||||
// Write outgoing data for the current tic
|
||||
virtual void WriteLocalInput(ticcmd_t cmd) = 0;
|
||||
virtual void WriteBotInput(int player, const ticcmd_t &cmd) = 0;
|
||||
virtual void WriteBytes(const uint8_t *block, int len) = 0;
|
||||
void WriteByte(uint8_t it);
|
||||
void WriteWord(short it);
|
||||
void WriteLong(int it);
|
||||
void WriteFloat(float it);
|
||||
void WriteString(const char *it);
|
||||
|
||||
// Statistics
|
||||
virtual int GetPing(int player) const = 0;
|
||||
virtual int GetServerPing() const = 0;
|
||||
int GetHighPingThreshold() const;
|
||||
|
||||
// CCMDs
|
||||
virtual void ListPingTimes() = 0;
|
||||
virtual void Network_Controller(int playernum, bool add) = 0;
|
||||
|
||||
// Old init/deinit stuff
|
||||
void Startup() { }
|
||||
void Net_ClearBuffers() { }
|
||||
void D_QuitNetGame() { }
|
||||
|
||||
// Demo recording
|
||||
size_t CopySpecData(int player, uint8_t *dest, size_t dest_size) { return 0; }
|
||||
|
||||
// Obsolete; only needed for p2p
|
||||
bool IsInconsistent(int player, int16_t checkvalue) const { return false; }
|
||||
void SetConsistency(int player, int16_t checkvalue) { }
|
||||
int16_t GetConsoleConsistency() const { return 0; }
|
||||
|
||||
// Should probably be removed.
|
||||
int ticdup = 1;
|
||||
};
|
||||
|
||||
extern std::unique_ptr<Network> network;
|
||||
extern std::unique_ptr<Network> netconnect;
|
||||
|
||||
void Net_DoCommand (int type, uint8_t **stream, int player);
|
||||
void Net_SkipCommand (int type, uint8_t **stream);
|
||||
void Net_RunCommands (FDynamicBuffer &buffer, int player);
|
||||
|
||||
void Net_ClearBuffers ();
|
||||
|
||||
|
||||
// Netgame stuff (buffers and pointers, i.e. indices).
|
||||
|
||||
// This is the interface to the packet driver, a separate program
|
||||
// in DOS, but just an abstraction here.
|
||||
extern doomcom_t doomcom;
|
||||
|
||||
extern struct ticcmd_t localcmds[LOCALCMDTICS];
|
||||
|
||||
extern int maketic;
|
||||
extern int nettics[MAXNETNODES];
|
||||
extern int netdelay[MAXNETNODES][BACKUPTICS];
|
||||
extern int nodeforplayer[MAXPLAYERS];
|
||||
|
||||
extern ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS];
|
||||
extern int ticdup;
|
||||
// Old packet format. Kept for reference. Should be removed or updated once the c/s migration is complete.
|
||||
|
||||
// [RH]
|
||||
// New generic packet structure:
|
||||
|
@ -167,7 +136,7 @@ extern int ticdup;
|
|||
// - The first player's consolenum is not included in this list, because it always matches the sender
|
||||
//
|
||||
// For each tic:
|
||||
// Two bytes with consistancy check, followed by tic data
|
||||
// Two bytes with consistency check, followed by tic data
|
||||
//
|
||||
// Setup packets are different, and are described just before D_ArbitrateNetStart().
|
||||
|
||||
|
@ -183,4 +152,14 @@ extern int ticdup;
|
|||
#define NCMD_1TICS 0x01 // packet contains 1 tic
|
||||
#define NCMD_0TICS 0x00 // packet contains 0 tics
|
||||
|
||||
#endif
|
||||
enum
|
||||
{
|
||||
PRE_CONNECT, // Sent from guest to host for initial connection
|
||||
PRE_KEEPALIVE,
|
||||
PRE_DISCONNECT, // Sent from guest that aborts the game
|
||||
PRE_ALLHERE, // Sent from host to guest when everybody has connected
|
||||
PRE_CONACK, // Sent from host to guest to acknowledge PRE_CONNECT receipt
|
||||
PRE_ALLFULL, // Sent from host to an unwanted guest
|
||||
PRE_ALLHEREACK, // Sent from guest to host to acknowledge PRE_ALLHEREACK receipt
|
||||
PRE_GO // Sent from host to guest to continue game startup
|
||||
};
|
||||
|
|
283
src/d_netclient.cpp
Normal file
283
src/d_netclient.cpp
Normal file
|
@ -0,0 +1,283 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright 1993-1996 id Software
|
||||
// Copyright 1999-2016 Randy Heit
|
||||
// Copyright 2002-2016 Christoph Oelckers
|
||||
// Copyright 2018 Magnus Norddahl
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "version.h"
|
||||
#include "menu/menu.h"
|
||||
#include "m_random.h"
|
||||
#include "i_system.h"
|
||||
#include "i_video.h"
|
||||
#include "i_net.h"
|
||||
#include "g_game.h"
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "c_console.h"
|
||||
#include "d_netinf.h"
|
||||
#include "d_netclient.h"
|
||||
#include "d_netsingle.h"
|
||||
#include "cmdlib.h"
|
||||
#include "s_sound.h"
|
||||
#include "m_cheat.h"
|
||||
#include "p_local.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "sbar.h"
|
||||
#include "gi.h"
|
||||
#include "m_misc.h"
|
||||
#include "gameconfigfile.h"
|
||||
#include "d_gui.h"
|
||||
#include "templates.h"
|
||||
#include "p_acs.h"
|
||||
#include "p_trace.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "st_start.h"
|
||||
#include "teaminfo.h"
|
||||
#include "p_conversation.h"
|
||||
#include "g_level.h"
|
||||
#include "d_event.h"
|
||||
#include "m_argv.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "v_video.h"
|
||||
#include "p_spec.h"
|
||||
#include "hardware.h"
|
||||
#include "r_utility.h"
|
||||
#include "a_keys.h"
|
||||
#include "intermission/intermission.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
#include "i_time.h"
|
||||
|
||||
NetClient::NetClient(FString server)
|
||||
{
|
||||
Printf("Connecting to %s..\n", server.GetChars());
|
||||
|
||||
mComm = I_InitNetwork(0);
|
||||
mServerNode = mComm->Connect(server);
|
||||
mStatus = NodeStatus::InPreGame;
|
||||
|
||||
NetPacket packet;
|
||||
packet.node = mServerNode;
|
||||
packet.size = 1;
|
||||
packet[0] = (uint8_t)NetPacketType::ConnectRequest;
|
||||
mComm->PacketSend(packet);
|
||||
}
|
||||
|
||||
void NetClient::Update()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
NetPacket packet;
|
||||
mComm->PacketGet(packet);
|
||||
if (packet.node == -1)
|
||||
break;
|
||||
|
||||
if (packet.node != mServerNode)
|
||||
{
|
||||
mComm->Close(packet.node);
|
||||
}
|
||||
else if (packet.size == 0)
|
||||
{
|
||||
OnClose(packet);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
NetPacketType type = (NetPacketType)packet[0];
|
||||
switch (type)
|
||||
{
|
||||
default: OnClose(packet); break;
|
||||
case NetPacketType::ConnectResponse: OnConnectResponse(packet); break;
|
||||
case NetPacketType::Disconnect: OnDisconnect(packet); break;
|
||||
case NetPacketType::Tic: OnTic(packet); break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mStatus == NodeStatus::Closed)
|
||||
{
|
||||
if (network.get() == this)
|
||||
{
|
||||
network.reset(new NetSinglePlayer());
|
||||
G_EndNetGame();
|
||||
}
|
||||
else
|
||||
{
|
||||
netconnect.reset();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetClient::SetCurrentTic(int receivetic, int sendtic)
|
||||
{
|
||||
gametic = receivetic;
|
||||
mSendTic = sendtic;
|
||||
}
|
||||
|
||||
void NetClient::EndCurrentTic()
|
||||
{
|
||||
NetPacket packet;
|
||||
packet.node = mServerNode;
|
||||
packet.size = 2 + sizeof(usercmd_t);
|
||||
packet[0] = (uint8_t)NetPacketType::Tic;
|
||||
packet[1] = 0; // target gametic
|
||||
memcpy(&packet[2], &mCurrentInput[consoleplayer].ucmd, sizeof(usercmd_t));
|
||||
mComm->PacketSend(packet);
|
||||
|
||||
mCurrentCommands = mSendCommands;
|
||||
mSendCommands.Clear();
|
||||
}
|
||||
|
||||
int NetClient::GetSendTick() const
|
||||
{
|
||||
return mSendTic;
|
||||
}
|
||||
|
||||
ticcmd_t NetClient::GetPlayerInput(int player) const
|
||||
{
|
||||
return mCurrentInput[player];
|
||||
}
|
||||
|
||||
ticcmd_t NetClient::GetSentInput(int tic) const
|
||||
{
|
||||
return mSentInput[tic % BACKUPTICS];
|
||||
}
|
||||
|
||||
void NetClient::RunCommands(int player)
|
||||
{
|
||||
if (player == consoleplayer)
|
||||
{
|
||||
Net_RunCommands(mCurrentCommands, consoleplayer);
|
||||
}
|
||||
}
|
||||
|
||||
void NetClient::WriteLocalInput(ticcmd_t cmd)
|
||||
{
|
||||
mCurrentInput[consoleplayer] = cmd;
|
||||
mSentInput[gametic % BACKUPTICS] = cmd;
|
||||
}
|
||||
|
||||
void NetClient::WriteBotInput(int player, const ticcmd_t &cmd)
|
||||
{
|
||||
mCurrentInput[player] = cmd;
|
||||
}
|
||||
|
||||
void NetClient::WriteBytes(const uint8_t *block, int len)
|
||||
{
|
||||
mSendCommands.AppendData(block, len);
|
||||
}
|
||||
|
||||
int NetClient::GetPing(int player) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NetClient::GetServerPing() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NetClient::ListPingTimes()
|
||||
{
|
||||
}
|
||||
|
||||
void NetClient::Network_Controller(int playernum, bool add)
|
||||
{
|
||||
}
|
||||
|
||||
void NetClient::OnClose(const NetPacket &packet)
|
||||
{
|
||||
mComm->Close(mServerNode);
|
||||
mServerNode = -1;
|
||||
mStatus = NodeStatus::Closed;
|
||||
|
||||
if (network.get() == this)
|
||||
{
|
||||
Printf("Disconnected\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf("Could not connect\n");
|
||||
}
|
||||
}
|
||||
|
||||
void NetClient::OnConnectResponse(const NetPacket &packet)
|
||||
{
|
||||
if (packet.size != 3)
|
||||
return;
|
||||
|
||||
int version = packet[1]; // Protocol version
|
||||
if (version == 1)
|
||||
{
|
||||
if (packet[2] != 255) // Join accepted
|
||||
{
|
||||
mPlayer = packet[2];
|
||||
mStatus = NodeStatus::InGame;
|
||||
|
||||
G_InitClientNetGame(mPlayer, "e1m1");
|
||||
|
||||
network = std::move(netconnect);
|
||||
}
|
||||
else // Server full
|
||||
{
|
||||
mComm->Close(mServerNode);
|
||||
mServerNode = -1;
|
||||
mStatus = NodeStatus::Closed;
|
||||
|
||||
Printf("Could not connect: server is full!\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf("Could not connect: version mismatch.\n");
|
||||
mComm->Close(mServerNode);
|
||||
mServerNode = -1;
|
||||
mStatus = NodeStatus::Closed;
|
||||
}
|
||||
}
|
||||
|
||||
void NetClient::OnDisconnect(const NetPacket &packet)
|
||||
{
|
||||
mComm->Close(packet.node);
|
||||
mServerNode = -1;
|
||||
mStatus = NodeStatus::Closed;
|
||||
}
|
||||
|
||||
void NetClient::OnTic(const NetPacket &packet)
|
||||
{
|
||||
if (packet.size != 2 + sizeof(float) * 5)
|
||||
return;
|
||||
|
||||
int tic = packet[1];
|
||||
float x = *(float*)&packet[2];
|
||||
float y = *(float*)&packet[6];
|
||||
float z = *(float*)&packet[10];
|
||||
float yaw = *(float*)&packet[14];
|
||||
float pitch = *(float*)&packet[18];
|
||||
|
||||
if (playeringame[consoleplayer] && players[consoleplayer].mo)
|
||||
{
|
||||
players[consoleplayer].mo->SetXYZ(x, y, z);
|
||||
players[consoleplayer].mo->Angles.Yaw = yaw;
|
||||
players[consoleplayer].mo->Angles.Pitch = pitch;
|
||||
}
|
||||
}
|
68
src/d_netclient.h
Normal file
68
src/d_netclient.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright 1993-1996 id Software
|
||||
// Copyright 1999-2016 Randy Heit
|
||||
// Copyright 2002-2016 Christoph Oelckers
|
||||
// Copyright 2018 Magnus Norddahl
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "d_netserver.h"
|
||||
|
||||
class NetClient : public Network
|
||||
{
|
||||
public:
|
||||
NetClient(FString server);
|
||||
|
||||
void Update() override;
|
||||
|
||||
void SetCurrentTic(int receivetic, int sendtic) override;
|
||||
void EndCurrentTic() override;
|
||||
|
||||
int GetSendTick() const override;
|
||||
ticcmd_t GetPlayerInput(int player) const override;
|
||||
ticcmd_t GetSentInput(int tic) const override;
|
||||
|
||||
void RunCommands(int player) override;
|
||||
|
||||
void WriteLocalInput(ticcmd_t cmd) override;
|
||||
void WriteBotInput(int player, const ticcmd_t &cmd) override;
|
||||
void WriteBytes(const uint8_t *block, int len) override;
|
||||
|
||||
int GetPing(int player) const override;
|
||||
int GetServerPing() const override;
|
||||
|
||||
void ListPingTimes() override;
|
||||
void Network_Controller(int playernum, bool add) override;
|
||||
|
||||
private:
|
||||
void OnClose(const NetPacket &packet);
|
||||
void OnConnectResponse(const NetPacket &packet);
|
||||
void OnDisconnect(const NetPacket &packet);
|
||||
void OnTic(const NetPacket &packet);
|
||||
|
||||
std::unique_ptr<doomcom_t> mComm;
|
||||
int mServerNode = -1;
|
||||
int mPlayer = -1;
|
||||
NodeStatus mStatus = NodeStatus::Closed;
|
||||
int mSendTic = 0;
|
||||
|
||||
ticcmd_t mCurrentInput[MAXPLAYERS];
|
||||
ticcmd_t mSentInput[BACKUPTICS];
|
||||
FDynamicBuffer mCurrentCommands;
|
||||
FDynamicBuffer mSendCommands;
|
||||
};
|
|
@ -540,8 +540,8 @@ void D_UserInfoChanged (FBaseCVar *cvar)
|
|||
|
||||
mysnprintf (foo, countof(foo), "\\%s\\%s", cvar->GetName(), escaped_val.GetChars());
|
||||
|
||||
Net_WriteByte (DEM_UINFCHANGED);
|
||||
Net_WriteString (foo);
|
||||
network->WriteByte (DEM_UINFCHANGED);
|
||||
network->WriteString (foo);
|
||||
}
|
||||
|
||||
static const char *SetServerVar (char *name, ECVarType type, uint8_t **stream, bool singlebit)
|
||||
|
@ -624,15 +624,15 @@ void D_SendServerInfoChange (const FBaseCVar *cvar, UCVarValue value, ECVarType
|
|||
|
||||
namelen = strlen (cvar->GetName ());
|
||||
|
||||
Net_WriteByte (DEM_SINFCHANGED);
|
||||
Net_WriteByte ((uint8_t)(namelen | (type << 6)));
|
||||
Net_WriteBytes ((uint8_t *)cvar->GetName (), (int)namelen);
|
||||
network->WriteByte (DEM_SINFCHANGED);
|
||||
network->WriteByte ((uint8_t)(namelen | (type << 6)));
|
||||
network->WriteBytes ((uint8_t *)cvar->GetName (), (int)namelen);
|
||||
switch (type)
|
||||
{
|
||||
case CVAR_Bool: Net_WriteByte (value.Bool); break;
|
||||
case CVAR_Int: Net_WriteLong (value.Int); break;
|
||||
case CVAR_Float: Net_WriteFloat (value.Float); break;
|
||||
case CVAR_String: Net_WriteString (value.String); break;
|
||||
case CVAR_Bool: network->WriteByte (value.Bool); break;
|
||||
case CVAR_Int: network->WriteLong (value.Int); break;
|
||||
case CVAR_Float: network->WriteFloat (value.Float); break;
|
||||
case CVAR_String: network->WriteString (value.String); break;
|
||||
default: break; // Silence GCC
|
||||
}
|
||||
}
|
||||
|
@ -643,10 +643,10 @@ void D_SendServerFlagChange (const FBaseCVar *cvar, int bitnum, bool set)
|
|||
|
||||
namelen = (int)strlen (cvar->GetName ());
|
||||
|
||||
Net_WriteByte (DEM_SINFCHANGEDXOR);
|
||||
Net_WriteByte ((uint8_t)namelen);
|
||||
Net_WriteBytes ((uint8_t *)cvar->GetName (), namelen);
|
||||
Net_WriteByte (uint8_t(bitnum | (set << 5)));
|
||||
network->WriteByte (DEM_SINFCHANGEDXOR);
|
||||
network->WriteByte ((uint8_t)namelen);
|
||||
network->WriteBytes ((uint8_t *)cvar->GetName (), namelen);
|
||||
network->WriteByte (uint8_t(bitnum | (set << 5)));
|
||||
}
|
||||
|
||||
void D_DoServerInfoChange (uint8_t **stream, bool singlebit)
|
||||
|
|
305
src/d_netserver.cpp
Normal file
305
src/d_netserver.cpp
Normal file
|
@ -0,0 +1,305 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright 1993-1996 id Software
|
||||
// Copyright 1999-2016 Randy Heit
|
||||
// Copyright 2002-2016 Christoph Oelckers
|
||||
// Copyright 2018 Magnus Norddahl
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "version.h"
|
||||
#include "menu/menu.h"
|
||||
#include "m_random.h"
|
||||
#include "i_system.h"
|
||||
#include "i_video.h"
|
||||
#include "i_net.h"
|
||||
#include "g_game.h"
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "c_console.h"
|
||||
#include "d_netinf.h"
|
||||
#include "d_netserver.h"
|
||||
#include "cmdlib.h"
|
||||
#include "s_sound.h"
|
||||
#include "m_cheat.h"
|
||||
#include "p_local.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "sbar.h"
|
||||
#include "gi.h"
|
||||
#include "m_misc.h"
|
||||
#include "gameconfigfile.h"
|
||||
#include "d_gui.h"
|
||||
#include "templates.h"
|
||||
#include "p_acs.h"
|
||||
#include "p_trace.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "st_start.h"
|
||||
#include "teaminfo.h"
|
||||
#include "p_conversation.h"
|
||||
#include "g_level.h"
|
||||
#include "d_event.h"
|
||||
#include "m_argv.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "v_video.h"
|
||||
#include "p_spec.h"
|
||||
#include "hardware.h"
|
||||
#include "r_utility.h"
|
||||
#include "a_keys.h"
|
||||
#include "intermission/intermission.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
#include "i_time.h"
|
||||
|
||||
NetServer::NetServer()
|
||||
{
|
||||
Printf("Started hosting multiplayer game..\n");
|
||||
|
||||
mComm = I_InitNetwork(DOOMPORT);
|
||||
|
||||
G_InitServerNetGame("e1m1");
|
||||
}
|
||||
|
||||
void NetServer::Update()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
NetPacket packet;
|
||||
mComm->PacketGet(packet);
|
||||
if (packet.node == -1)
|
||||
break;
|
||||
|
||||
NetNode &node = mNodes[packet.node];
|
||||
|
||||
if (packet.size == 0)
|
||||
{
|
||||
OnClose(node, packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
NetPacketType type = (NetPacketType)packet[0];
|
||||
switch (type)
|
||||
{
|
||||
default: OnClose(node, packet); break;
|
||||
case NetPacketType::ConnectRequest: OnConnectRequest(node, packet); break;
|
||||
case NetPacketType::Disconnect: OnDisconnect(node, packet); break;
|
||||
case NetPacketType::Tic: OnTic(node, packet); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetServer::SetCurrentTic(int receivetic, int sendtic)
|
||||
{
|
||||
gametic = receivetic;
|
||||
mSendTic = sendtic;
|
||||
}
|
||||
|
||||
void NetServer::EndCurrentTic()
|
||||
{
|
||||
for (int i = 0; i < MAXNETNODES; i++)
|
||||
{
|
||||
if (mNodes[i].Status == NodeStatus::InGame)
|
||||
{
|
||||
NetPacket packet;
|
||||
packet.node = i;
|
||||
packet.size = 2 + sizeof(float) * 5;
|
||||
packet[0] = (uint8_t)NetPacketType::Tic;
|
||||
packet[1] = gametic;
|
||||
|
||||
int player = mNodes[i].Player;
|
||||
if (playeringame[player] && players[player].mo)
|
||||
{
|
||||
*(float*)&packet[2] = (float)players[player].mo->X();
|
||||
*(float*)&packet[6] = (float)players[player].mo->Y();
|
||||
*(float*)&packet[10] = (float)players[player].mo->Z();
|
||||
*(float*)&packet[14] = (float)players[player].mo->Angles.Yaw.Degrees;
|
||||
*(float*)&packet[18] = (float)players[player].mo->Angles.Pitch.Degrees;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(float*)&packet[2] = 0.0f;
|
||||
*(float*)&packet[6] = 0.0f;
|
||||
*(float*)&packet[10] = 0.0f;
|
||||
*(float*)&packet[14] = 0.0f;
|
||||
*(float*)&packet[18] = 0.0f;
|
||||
}
|
||||
|
||||
mComm->PacketSend(packet);
|
||||
}
|
||||
}
|
||||
|
||||
mCurrentCommands = mSendCommands;
|
||||
mSendCommands.Clear();
|
||||
}
|
||||
|
||||
int NetServer::GetSendTick() const
|
||||
{
|
||||
return mSendTic;
|
||||
}
|
||||
|
||||
ticcmd_t NetServer::GetPlayerInput(int player) const
|
||||
{
|
||||
return mCurrentInput[player];
|
||||
}
|
||||
|
||||
ticcmd_t NetServer::GetSentInput(int tic) const
|
||||
{
|
||||
return mCurrentInput[consoleplayer];
|
||||
}
|
||||
|
||||
void NetServer::RunCommands(int player)
|
||||
{
|
||||
if (player == consoleplayer)
|
||||
{
|
||||
Net_RunCommands(mCurrentCommands, consoleplayer);
|
||||
}
|
||||
}
|
||||
|
||||
void NetServer::WriteLocalInput(ticcmd_t cmd)
|
||||
{
|
||||
mCurrentInput[consoleplayer] = cmd;
|
||||
}
|
||||
|
||||
void NetServer::WriteBotInput(int player, const ticcmd_t &cmd)
|
||||
{
|
||||
mCurrentInput[player] = cmd;
|
||||
}
|
||||
|
||||
void NetServer::WriteBytes(const uint8_t *block, int len)
|
||||
{
|
||||
mSendCommands.AppendData(block, len);
|
||||
}
|
||||
|
||||
int NetServer::GetPing(int player) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NetServer::GetServerPing() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NetServer::ListPingTimes()
|
||||
{
|
||||
#if 0
|
||||
for (int i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
Printf("% 4" PRId64 " %s\n", currrecvtime[i] - lastrecvtime[i], players[i].userinfo.GetName());
|
||||
#endif
|
||||
}
|
||||
|
||||
void NetServer::Network_Controller(int playernum, bool add)
|
||||
{
|
||||
}
|
||||
|
||||
void NetServer::OnClose(NetNode &node, const NetPacket &packet)
|
||||
{
|
||||
if (node.Status == NodeStatus::InGame)
|
||||
{
|
||||
Printf("Player %d left the server", node.Player);
|
||||
|
||||
playeringame[node.Player] = false;
|
||||
players[node.Player].settings_controller = false;
|
||||
node.Player = -1;
|
||||
}
|
||||
|
||||
node.Status = NodeStatus::Closed;
|
||||
mComm->Close(packet.node);
|
||||
}
|
||||
|
||||
void NetServer::OnConnectRequest(NetNode &node, const NetPacket &packet)
|
||||
{
|
||||
// Search for a spot in the player list
|
||||
if (node.Status != NodeStatus::InGame)
|
||||
{
|
||||
for (int i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
{
|
||||
node.Player = i;
|
||||
playeringame[i] = true;
|
||||
players[i].settings_controller = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (node.Player != -1) // Join accepted.
|
||||
{
|
||||
Printf("Player %d joined the server", node.Player);
|
||||
|
||||
mNodeForPlayer[node.Player] = packet.node;
|
||||
|
||||
NetPacket response;
|
||||
response.node = packet.node;
|
||||
response[0] = (uint8_t)NetPacketType::ConnectResponse;
|
||||
response[1] = 1; // Protocol version
|
||||
response[2] = node.Player;
|
||||
response.size = 3;
|
||||
mComm->PacketSend(response);
|
||||
|
||||
node.Status = NodeStatus::InGame;
|
||||
}
|
||||
else // Server is full.
|
||||
{
|
||||
node.Status = NodeStatus::Closed;
|
||||
|
||||
NetPacket response;
|
||||
response.node = packet.node;
|
||||
response[0] = (uint8_t)NetPacketType::ConnectResponse;
|
||||
response[1] = 1; // Protocol version
|
||||
response[2] = 255;
|
||||
response.size = 3;
|
||||
mComm->PacketSend(response);
|
||||
|
||||
node.Status = NodeStatus::Closed;
|
||||
mComm->Close(packet.node);
|
||||
}
|
||||
}
|
||||
|
||||
void NetServer::OnDisconnect(NetNode &node, const NetPacket &packet)
|
||||
{
|
||||
if (node.Status == NodeStatus::InGame)
|
||||
{
|
||||
Printf("Player %d left the server", node.Player);
|
||||
|
||||
playeringame[node.Player] = false;
|
||||
players[node.Player].settings_controller = false;
|
||||
node.Player = -1;
|
||||
}
|
||||
|
||||
node.Status = NodeStatus::Closed;
|
||||
mComm->Close(packet.node);
|
||||
}
|
||||
|
||||
void NetServer::OnTic(NetNode &node, const NetPacket &packet)
|
||||
{
|
||||
if (node.Status == NodeStatus::InGame)
|
||||
{
|
||||
if (packet.size != 2 + sizeof(usercmd_t))
|
||||
return;
|
||||
|
||||
memcpy(&mCurrentInput[node.Player].ucmd, &packet[2], sizeof(usercmd_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
node.Status = NodeStatus::Closed;
|
||||
mComm->Close(packet.node);
|
||||
}
|
||||
}
|
93
src/d_netserver.h
Normal file
93
src/d_netserver.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright 1993-1996 id Software
|
||||
// Copyright 1999-2016 Randy Heit
|
||||
// Copyright 2002-2016 Christoph Oelckers
|
||||
// Copyright 2018 Magnus Norddahl
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "d_net.h"
|
||||
|
||||
enum class NetPacketType
|
||||
{
|
||||
ConnectRequest,
|
||||
ConnectResponse,
|
||||
Disconnect,
|
||||
Tic
|
||||
};
|
||||
|
||||
enum class NodeStatus
|
||||
{
|
||||
Closed,
|
||||
InPreGame,
|
||||
InGame
|
||||
};
|
||||
|
||||
struct NetNode
|
||||
{
|
||||
NodeStatus Status = NodeStatus::Closed;
|
||||
|
||||
int Ping = 0;
|
||||
int Gametic = 0;
|
||||
int Player = -1;
|
||||
|
||||
ticcmd_t PlayerMovement;
|
||||
FDynamicBuffer Commands; // "NetSpecs"
|
||||
};
|
||||
|
||||
class NetServer : public Network
|
||||
{
|
||||
public:
|
||||
NetServer();
|
||||
|
||||
void Update() override;
|
||||
|
||||
void SetCurrentTic(int receivetic, int sendtic) override;
|
||||
void EndCurrentTic() override;
|
||||
|
||||
int GetSendTick() const override;
|
||||
ticcmd_t GetPlayerInput(int player) const override;
|
||||
ticcmd_t GetSentInput(int tic) const override;
|
||||
|
||||
void RunCommands(int player) override;
|
||||
|
||||
void WriteLocalInput(ticcmd_t cmd) override;
|
||||
void WriteBotInput(int player, const ticcmd_t &cmd) override;
|
||||
void WriteBytes(const uint8_t *block, int len) override;
|
||||
|
||||
int GetPing(int player) const override;
|
||||
int GetServerPing() const override;
|
||||
|
||||
void ListPingTimes() override;
|
||||
void Network_Controller(int playernum, bool add) override;
|
||||
|
||||
private:
|
||||
void OnClose(NetNode &node, const NetPacket &packet);
|
||||
void OnConnectRequest(NetNode &node, const NetPacket &packet);
|
||||
void OnDisconnect(NetNode &node, const NetPacket &packet);
|
||||
void OnTic(NetNode &node, const NetPacket &packet);
|
||||
|
||||
std::unique_ptr<doomcom_t> mComm;
|
||||
NetNode mNodes[MAXNETNODES];
|
||||
int mNodeForPlayer[MAXPLAYERS];
|
||||
int mSendTic = 0;
|
||||
|
||||
ticcmd_t mCurrentInput[MAXPLAYERS];
|
||||
FDynamicBuffer mCurrentCommands;
|
||||
FDynamicBuffer mSendCommands;
|
||||
};
|
151
src/d_netsingle.cpp
Normal file
151
src/d_netsingle.cpp
Normal file
|
@ -0,0 +1,151 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright 1993-1996 id Software
|
||||
// Copyright 1999-2016 Randy Heit
|
||||
// Copyright 2002-2016 Christoph Oelckers
|
||||
// Copyright 2018 Magnus Norddahl
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "version.h"
|
||||
#include "menu/menu.h"
|
||||
#include "m_random.h"
|
||||
#include "i_system.h"
|
||||
#include "i_video.h"
|
||||
#include "i_net.h"
|
||||
#include "g_game.h"
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "c_console.h"
|
||||
#include "d_netinf.h"
|
||||
#include "d_netsingle.h"
|
||||
#include "cmdlib.h"
|
||||
#include "s_sound.h"
|
||||
#include "m_cheat.h"
|
||||
#include "p_local.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "sbar.h"
|
||||
#include "gi.h"
|
||||
#include "m_misc.h"
|
||||
#include "gameconfigfile.h"
|
||||
#include "d_gui.h"
|
||||
#include "templates.h"
|
||||
#include "p_acs.h"
|
||||
#include "p_trace.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "st_start.h"
|
||||
#include "teaminfo.h"
|
||||
#include "p_conversation.h"
|
||||
#include "g_level.h"
|
||||
#include "d_event.h"
|
||||
#include "m_argv.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "v_video.h"
|
||||
#include "p_spec.h"
|
||||
#include "hardware.h"
|
||||
#include "r_utility.h"
|
||||
#include "a_keys.h"
|
||||
#include "intermission/intermission.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
#include "i_time.h"
|
||||
|
||||
extern bool netserver, netclient;
|
||||
|
||||
NetSinglePlayer::NetSinglePlayer()
|
||||
{
|
||||
netgame = false;
|
||||
netclient = false;
|
||||
netserver = false;
|
||||
multiplayer = false;
|
||||
consoleplayer = 0;
|
||||
players[0].settings_controller = true;
|
||||
playeringame[0] = true;
|
||||
}
|
||||
|
||||
void NetSinglePlayer::Update()
|
||||
{
|
||||
}
|
||||
|
||||
void NetSinglePlayer::SetCurrentTic(int receivetic, int sendtic)
|
||||
{
|
||||
gametic = receivetic;
|
||||
mSendTic = sendtic;
|
||||
}
|
||||
|
||||
void NetSinglePlayer::EndCurrentTic()
|
||||
{
|
||||
mCurrentCommands = mSendCommands;
|
||||
mSendCommands.Clear();
|
||||
}
|
||||
|
||||
int NetSinglePlayer::GetSendTick() const
|
||||
{
|
||||
return mSendTic;
|
||||
}
|
||||
|
||||
ticcmd_t NetSinglePlayer::GetPlayerInput(int player) const
|
||||
{
|
||||
return mCurrentInput[player];
|
||||
}
|
||||
|
||||
ticcmd_t NetSinglePlayer::GetSentInput(int tic) const
|
||||
{
|
||||
return mCurrentInput[consoleplayer];
|
||||
}
|
||||
|
||||
void NetSinglePlayer::RunCommands(int player)
|
||||
{
|
||||
if (player == consoleplayer)
|
||||
{
|
||||
Net_RunCommands(mCurrentCommands, consoleplayer);
|
||||
}
|
||||
}
|
||||
|
||||
void NetSinglePlayer::WriteLocalInput(ticcmd_t cmd)
|
||||
{
|
||||
mCurrentInput[consoleplayer] = cmd;
|
||||
}
|
||||
|
||||
void NetSinglePlayer::WriteBotInput(int player, const ticcmd_t &cmd)
|
||||
{
|
||||
mCurrentInput[player] = cmd;
|
||||
}
|
||||
|
||||
void NetSinglePlayer::WriteBytes(const uint8_t *block, int len)
|
||||
{
|
||||
mSendCommands.AppendData(block, len);
|
||||
}
|
||||
|
||||
int NetSinglePlayer::GetPing(int player) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NetSinglePlayer::GetServerPing() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NetSinglePlayer::ListPingTimes()
|
||||
{
|
||||
}
|
||||
|
||||
void NetSinglePlayer::Network_Controller(int playernum, bool add)
|
||||
{
|
||||
}
|
58
src/d_netsingle.h
Normal file
58
src/d_netsingle.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright 1993-1996 id Software
|
||||
// Copyright 1999-2016 Randy Heit
|
||||
// Copyright 2002-2016 Christoph Oelckers
|
||||
// Copyright 2018 Magnus Norddahl
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "d_net.h"
|
||||
|
||||
class NetSinglePlayer : public Network
|
||||
{
|
||||
public:
|
||||
NetSinglePlayer();
|
||||
|
||||
void Update() override;
|
||||
|
||||
void SetCurrentTic(int receivetic, int sendtic) override;
|
||||
void EndCurrentTic() override;
|
||||
|
||||
int GetSendTick() const override;
|
||||
ticcmd_t GetPlayerInput(int player) const override;
|
||||
ticcmd_t GetSentInput(int tic) const override;
|
||||
|
||||
void RunCommands(int player) override;
|
||||
|
||||
void WriteLocalInput(ticcmd_t cmd) override;
|
||||
void WriteBotInput(int player, const ticcmd_t &cmd) override;
|
||||
void WriteBytes(const uint8_t *block, int len) override;
|
||||
|
||||
int GetPing(int player) const override;
|
||||
int GetServerPing() const override;
|
||||
|
||||
void ListPingTimes() override;
|
||||
void Network_Controller(int playernum, bool add) override;
|
||||
|
||||
private:
|
||||
ticcmd_t mCurrentInput[MAXPLAYERS];
|
||||
FDynamicBuffer mCurrentCommands;
|
||||
|
||||
int mSendTic = 0;
|
||||
FDynamicBuffer mSendCommands;
|
||||
};
|
33
src/d_netsync.h
Normal file
33
src/d_netsync.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#ifndef __D_NETSYNC_H__
|
||||
#define __D_NETSYNC_H__
|
||||
|
||||
struct NetSyncData {
|
||||
DVector3 Pos;
|
||||
DVector3 Vel;
|
||||
DAngle SpriteAngle;
|
||||
DAngle SpriteRotation;
|
||||
DRotator Angles;
|
||||
DVector2 Scale; // Scaling values; 1 is normal size
|
||||
double Alpha; // Since P_CheckSight makes an alpha check this can't be a float. It has to be a double.
|
||||
int sprite; // used to find patch_t and flip value
|
||||
uint8_t frame; // sprite frame to draw
|
||||
uint8_t effects; // [RH] see p_effect.h
|
||||
FRenderStyle RenderStyle; // Style to draw this actor with
|
||||
uint32_t Translation;
|
||||
uint32_t RenderRequired; // current renderer must have this feature set
|
||||
uint32_t RenderHidden; // current renderer must *not* have any of these features
|
||||
uint32_t renderflags; // Different rendering flags
|
||||
double Floorclip; // value to use for floor clipping
|
||||
DAngle VisibleStartAngle;
|
||||
DAngle VisibleStartPitch;
|
||||
DAngle VisibleEndAngle;
|
||||
DAngle VisibleEndPitch;
|
||||
double Speed;
|
||||
double FloatSpeed;
|
||||
double CameraHeight; // Height of camera when used as such
|
||||
double CameraFOV;
|
||||
double StealthAlpha; // Minmum alpha for MF_STEALTH.
|
||||
|
||||
};
|
||||
|
||||
#endif //__D_NETSYNC_H__
|
|
@ -290,7 +290,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, ticcmd_t &cmd, ticcmd_
|
|||
{
|
||||
if (arc.BeginObject(key))
|
||||
{
|
||||
arc("consistency", cmd.consistancy)
|
||||
arc("consistency", cmd.consistency)
|
||||
("ucmd", cmd.ucmd)
|
||||
.EndObject();
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ int SkipTicCmd (uint8_t **stream, int count)
|
|||
{
|
||||
bool moreticdata = true;
|
||||
|
||||
flow += 2; // Skip consistancy marker
|
||||
flow += 2; // Skip consistency marker
|
||||
while (moreticdata)
|
||||
{
|
||||
uint8_t type = *flow++;
|
||||
|
@ -407,68 +407,6 @@ int SkipTicCmd (uint8_t **stream, int count)
|
|||
return skip;
|
||||
}
|
||||
|
||||
extern short consistancy[MAXPLAYERS][BACKUPTICS];
|
||||
void ReadTicCmd (uint8_t **stream, int player, int tic)
|
||||
{
|
||||
int type;
|
||||
uint8_t *start;
|
||||
ticcmd_t *tcmd;
|
||||
|
||||
int ticmod = tic % BACKUPTICS;
|
||||
|
||||
tcmd = &netcmds[player][ticmod];
|
||||
tcmd->consistancy = ReadWord (stream);
|
||||
|
||||
start = *stream;
|
||||
|
||||
while ((type = ReadByte (stream)) != DEM_USERCMD && type != DEM_EMPTYUSERCMD)
|
||||
Net_SkipCommand (type, stream);
|
||||
|
||||
NetSpecs[player][ticmod].SetData (start, int(*stream - start - 1));
|
||||
|
||||
if (type == DEM_USERCMD)
|
||||
{
|
||||
UnpackUserCmd (&tcmd->ucmd,
|
||||
tic ? &netcmds[player][(tic-1)%BACKUPTICS].ucmd : NULL, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tic)
|
||||
{
|
||||
memcpy (&tcmd->ucmd, &netcmds[player][(tic-1)%BACKUPTICS].ucmd, sizeof(tcmd->ucmd));
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (&tcmd->ucmd, 0, sizeof(tcmd->ucmd));
|
||||
}
|
||||
}
|
||||
|
||||
if (player==consoleplayer&&tic>BACKUPTICS)
|
||||
assert(consistancy[player][ticmod] == tcmd->consistancy);
|
||||
}
|
||||
|
||||
void RunNetSpecs (int player, int buf)
|
||||
{
|
||||
uint8_t *stream;
|
||||
int len;
|
||||
|
||||
if (gametic % ticdup == 0)
|
||||
{
|
||||
stream = NetSpecs[player][buf].GetData (&len);
|
||||
if (stream)
|
||||
{
|
||||
uint8_t *end = stream + len;
|
||||
while (stream < end)
|
||||
{
|
||||
int type = ReadByte (&stream);
|
||||
Net_DoCommand (type, &stream, player);
|
||||
}
|
||||
if (!demorecording)
|
||||
NetSpecs[player][buf].SetData (NULL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *lenspot;
|
||||
|
||||
// Write the header of an IFF chunk and leave space
|
||||
|
|
|
@ -63,13 +63,13 @@ struct zdemoheader_s {
|
|||
|
||||
struct usercmd_t
|
||||
{
|
||||
uint32_t buttons;
|
||||
short pitch; // up/down
|
||||
short yaw; // left/right
|
||||
short roll; // "tilt"
|
||||
short forwardmove;
|
||||
short sidemove;
|
||||
short upmove;
|
||||
uint32_t buttons = 0;
|
||||
short pitch = 0; // up/down
|
||||
short yaw = 0; // left/right
|
||||
short roll = 0; // "tilt"
|
||||
short forwardmove = 0;
|
||||
short sidemove = 0;
|
||||
short upmove = 0;
|
||||
};
|
||||
|
||||
// When transmitted, the above message is preceded by a byte
|
||||
|
@ -238,12 +238,10 @@ int WriteUserCmdMessage (usercmd_t *ucmd, const usercmd_t *basis, uint8_t **stre
|
|||
struct ticcmd_t
|
||||
{
|
||||
usercmd_t ucmd;
|
||||
int16_t consistancy; // checks for net game
|
||||
int16_t consistency = 0; // checks for net game
|
||||
};
|
||||
|
||||
int SkipTicCmd (uint8_t **stream, int count);
|
||||
void ReadTicCmd (uint8_t **stream, int player, int tic);
|
||||
void RunNetSpecs (int player, int buf);
|
||||
|
||||
int ReadByte (uint8_t **stream);
|
||||
int ReadWord (uint8_t **stream);
|
||||
|
|
|
@ -79,6 +79,9 @@ extern bool multiplayer;
|
|||
// [SP] Map dm/coop implementation - invokes fake multiplayer without bots
|
||||
extern bool multiplayernext;
|
||||
|
||||
// clientside playsim
|
||||
extern bool netclient;
|
||||
|
||||
// Flag: true only if started as net deathmatch.
|
||||
EXTERN_CVAR (Int, deathmatch)
|
||||
|
||||
|
|
|
@ -153,13 +153,13 @@ bool E_SendNetworkEvent(FString name, int arg1, int arg2, int arg3, bool manual)
|
|||
if (gamestate != GS_LEVEL)
|
||||
return false;
|
||||
|
||||
Net_WriteByte(DEM_NETEVENT);
|
||||
Net_WriteString(name);
|
||||
Net_WriteByte(3);
|
||||
Net_WriteLong(arg1);
|
||||
Net_WriteLong(arg2);
|
||||
Net_WriteLong(arg3);
|
||||
Net_WriteByte(manual);
|
||||
network->WriteByte(DEM_NETEVENT);
|
||||
network->WriteString(name);
|
||||
network->WriteByte(3);
|
||||
network->WriteLong(arg1);
|
||||
network->WriteLong(arg2);
|
||||
network->WriteLong(arg3);
|
||||
network->WriteByte(manual);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
207
src/g_game.cpp
207
src/g_game.cpp
|
@ -77,6 +77,7 @@
|
|||
#include "g_hub.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "events.h"
|
||||
#include "gameconfigfile.h"
|
||||
|
||||
|
||||
static FRandom pr_dmspawn ("DMSpawn");
|
||||
|
@ -84,7 +85,7 @@ static FRandom pr_pspawn ("PlayerSpawn");
|
|||
|
||||
bool G_CheckDemoStatus (void);
|
||||
void G_ReadDemoTiccmd (ticcmd_t *cmd, int player);
|
||||
void G_WriteDemoTiccmd (ticcmd_t *cmd, int player, int buf);
|
||||
void G_WriteDemoTiccmd (ticcmd_t *cmd, int player);
|
||||
void G_PlayerReborn (int player);
|
||||
|
||||
void G_DoNewGame (void);
|
||||
|
@ -149,6 +150,8 @@ bool viewactive;
|
|||
bool netgame; // only true if packets are broadcast
|
||||
bool multiplayer;
|
||||
bool multiplayernext = false; // [SP] Map coop/dm implementation
|
||||
bool netclient; // clientside playsim
|
||||
bool netserver = false; // used to enforce 'netplay = true'
|
||||
player_t players[MAXPLAYERS];
|
||||
bool playeringame[MAXPLAYERS];
|
||||
|
||||
|
@ -176,9 +179,6 @@ bool precache = true; // if true, load all graphics at start
|
|||
|
||||
wbstartstruct_t wminfo; // parms for world map / intermission
|
||||
|
||||
short consistancy[MAXPLAYERS][BACKUPTICS];
|
||||
|
||||
|
||||
#define MAXPLMOVE (forwardmove[1])
|
||||
|
||||
#define TURBOTHRESHOLD 12800
|
||||
|
@ -296,12 +296,12 @@ CCMD (slot)
|
|||
|
||||
CCMD (centerview)
|
||||
{
|
||||
Net_WriteByte (DEM_CENTERVIEW);
|
||||
network->WriteByte (DEM_CENTERVIEW);
|
||||
}
|
||||
|
||||
CCMD(crouch)
|
||||
{
|
||||
Net_WriteByte(DEM_CROUCH);
|
||||
network->WriteByte(DEM_CROUCH);
|
||||
}
|
||||
|
||||
CCMD (land)
|
||||
|
@ -544,7 +544,7 @@ static inline int joyint(double val)
|
|||
// or reads it from the demo buffer.
|
||||
// If recording a demo, write it out
|
||||
//
|
||||
void G_BuildTiccmd (ticcmd_t *cmd)
|
||||
ticcmd_t G_BuildTiccmd ()
|
||||
{
|
||||
int strafe;
|
||||
int speed;
|
||||
|
@ -552,12 +552,9 @@ void G_BuildTiccmd (ticcmd_t *cmd)
|
|||
int side;
|
||||
int fly;
|
||||
|
||||
ticcmd_t *base;
|
||||
ticcmd_t cmd;
|
||||
|
||||
base = I_BaseTiccmd (); // empty, or external driver
|
||||
*cmd = *base;
|
||||
|
||||
cmd->consistancy = consistancy[consoleplayer][(maketic/ticdup)%BACKUPTICS];
|
||||
cmd.consistency = network->GetConsoleConsistency();
|
||||
|
||||
strafe = Button_Strafe.bDown;
|
||||
speed = Button_Speed.bDown ^ (int)cl_run;
|
||||
|
@ -568,7 +565,7 @@ void G_BuildTiccmd (ticcmd_t *cmd)
|
|||
// and not the joystick, since we treat the joystick as
|
||||
// the analog device it is.
|
||||
if (Button_Left.bDown || Button_Right.bDown)
|
||||
turnheld += ticdup;
|
||||
turnheld += network->ticdup;
|
||||
else
|
||||
turnheld = 0;
|
||||
|
||||
|
@ -632,32 +629,32 @@ void G_BuildTiccmd (ticcmd_t *cmd)
|
|||
side -= sidemove[speed];
|
||||
|
||||
// buttons
|
||||
if (Button_Attack.bDown) cmd->ucmd.buttons |= BT_ATTACK;
|
||||
if (Button_AltAttack.bDown) cmd->ucmd.buttons |= BT_ALTATTACK;
|
||||
if (Button_Use.bDown) cmd->ucmd.buttons |= BT_USE;
|
||||
if (Button_Jump.bDown) cmd->ucmd.buttons |= BT_JUMP;
|
||||
if (Button_Crouch.bDown) cmd->ucmd.buttons |= BT_CROUCH;
|
||||
if (Button_Zoom.bDown) cmd->ucmd.buttons |= BT_ZOOM;
|
||||
if (Button_Reload.bDown) cmd->ucmd.buttons |= BT_RELOAD;
|
||||
if (Button_Attack.bDown) cmd.ucmd.buttons |= BT_ATTACK;
|
||||
if (Button_AltAttack.bDown) cmd.ucmd.buttons |= BT_ALTATTACK;
|
||||
if (Button_Use.bDown) cmd.ucmd.buttons |= BT_USE;
|
||||
if (Button_Jump.bDown) cmd.ucmd.buttons |= BT_JUMP;
|
||||
if (Button_Crouch.bDown) cmd.ucmd.buttons |= BT_CROUCH;
|
||||
if (Button_Zoom.bDown) cmd.ucmd.buttons |= BT_ZOOM;
|
||||
if (Button_Reload.bDown) cmd.ucmd.buttons |= BT_RELOAD;
|
||||
|
||||
if (Button_User1.bDown) cmd->ucmd.buttons |= BT_USER1;
|
||||
if (Button_User2.bDown) cmd->ucmd.buttons |= BT_USER2;
|
||||
if (Button_User3.bDown) cmd->ucmd.buttons |= BT_USER3;
|
||||
if (Button_User4.bDown) cmd->ucmd.buttons |= BT_USER4;
|
||||
if (Button_User1.bDown) cmd.ucmd.buttons |= BT_USER1;
|
||||
if (Button_User2.bDown) cmd.ucmd.buttons |= BT_USER2;
|
||||
if (Button_User3.bDown) cmd.ucmd.buttons |= BT_USER3;
|
||||
if (Button_User4.bDown) cmd.ucmd.buttons |= BT_USER4;
|
||||
|
||||
if (Button_Speed.bDown) cmd->ucmd.buttons |= BT_SPEED;
|
||||
if (Button_Strafe.bDown) cmd->ucmd.buttons |= BT_STRAFE;
|
||||
if (Button_MoveRight.bDown) cmd->ucmd.buttons |= BT_MOVERIGHT;
|
||||
if (Button_MoveLeft.bDown) cmd->ucmd.buttons |= BT_MOVELEFT;
|
||||
if (Button_LookDown.bDown) cmd->ucmd.buttons |= BT_LOOKDOWN;
|
||||
if (Button_LookUp.bDown) cmd->ucmd.buttons |= BT_LOOKUP;
|
||||
if (Button_Back.bDown) cmd->ucmd.buttons |= BT_BACK;
|
||||
if (Button_Forward.bDown) cmd->ucmd.buttons |= BT_FORWARD;
|
||||
if (Button_Right.bDown) cmd->ucmd.buttons |= BT_RIGHT;
|
||||
if (Button_Left.bDown) cmd->ucmd.buttons |= BT_LEFT;
|
||||
if (Button_MoveDown.bDown) cmd->ucmd.buttons |= BT_MOVEDOWN;
|
||||
if (Button_MoveUp.bDown) cmd->ucmd.buttons |= BT_MOVEUP;
|
||||
if (Button_ShowScores.bDown) cmd->ucmd.buttons |= BT_SHOWSCORES;
|
||||
if (Button_Speed.bDown) cmd.ucmd.buttons |= BT_SPEED;
|
||||
if (Button_Strafe.bDown) cmd.ucmd.buttons |= BT_STRAFE;
|
||||
if (Button_MoveRight.bDown) cmd.ucmd.buttons |= BT_MOVERIGHT;
|
||||
if (Button_MoveLeft.bDown) cmd.ucmd.buttons |= BT_MOVELEFT;
|
||||
if (Button_LookDown.bDown) cmd.ucmd.buttons |= BT_LOOKDOWN;
|
||||
if (Button_LookUp.bDown) cmd.ucmd.buttons |= BT_LOOKUP;
|
||||
if (Button_Back.bDown) cmd.ucmd.buttons |= BT_BACK;
|
||||
if (Button_Forward.bDown) cmd.ucmd.buttons |= BT_FORWARD;
|
||||
if (Button_Right.bDown) cmd.ucmd.buttons |= BT_RIGHT;
|
||||
if (Button_Left.bDown) cmd.ucmd.buttons |= BT_LEFT;
|
||||
if (Button_MoveDown.bDown) cmd.ucmd.buttons |= BT_MOVEDOWN;
|
||||
if (Button_MoveUp.bDown) cmd.ucmd.buttons |= BT_MOVEUP;
|
||||
if (Button_ShowScores.bDown) cmd.ucmd.buttons |= BT_SHOWSCORES;
|
||||
|
||||
// Handle joysticks/game controllers.
|
||||
float joyaxes[NUM_JOYAXIS];
|
||||
|
@ -695,7 +692,7 @@ void G_BuildTiccmd (ticcmd_t *cmd)
|
|||
forward += (int)((float)mousey * m_forward);
|
||||
}
|
||||
|
||||
cmd->ucmd.pitch = LocalViewPitch >> 16;
|
||||
cmd.ucmd.pitch = LocalViewPitch >> 16;
|
||||
|
||||
if (SendLand)
|
||||
{
|
||||
|
@ -718,10 +715,10 @@ void G_BuildTiccmd (ticcmd_t *cmd)
|
|||
else if (side < -MAXPLMOVE)
|
||||
side = -MAXPLMOVE;
|
||||
|
||||
cmd->ucmd.forwardmove += forward;
|
||||
cmd->ucmd.sidemove += side;
|
||||
cmd->ucmd.yaw = LocalViewAngle >> 16;
|
||||
cmd->ucmd.upmove = fly;
|
||||
cmd.ucmd.forwardmove += forward;
|
||||
cmd.ucmd.sidemove += side;
|
||||
cmd.ucmd.yaw = LocalViewAngle >> 16;
|
||||
cmd.ucmd.upmove = fly;
|
||||
LocalViewAngle = 0;
|
||||
LocalViewPitch = 0;
|
||||
|
||||
|
@ -729,42 +726,44 @@ void G_BuildTiccmd (ticcmd_t *cmd)
|
|||
if (sendturn180)
|
||||
{
|
||||
sendturn180 = false;
|
||||
cmd->ucmd.buttons |= BT_TURN180;
|
||||
cmd.ucmd.buttons |= BT_TURN180;
|
||||
}
|
||||
if (sendpause)
|
||||
{
|
||||
sendpause = false;
|
||||
Net_WriteByte (DEM_PAUSE);
|
||||
network->WriteByte (DEM_PAUSE);
|
||||
}
|
||||
if (sendsave)
|
||||
{
|
||||
sendsave = false;
|
||||
Net_WriteByte (DEM_SAVEGAME);
|
||||
Net_WriteString (savegamefile);
|
||||
Net_WriteString (savedescription);
|
||||
network->WriteByte (DEM_SAVEGAME);
|
||||
network->WriteString (savegamefile);
|
||||
network->WriteString (savedescription);
|
||||
savegamefile = "";
|
||||
}
|
||||
if (SendItemUse == (const AInventory *)1)
|
||||
{
|
||||
Net_WriteByte (DEM_INVUSEALL);
|
||||
network->WriteByte (DEM_INVUSEALL);
|
||||
SendItemUse = NULL;
|
||||
}
|
||||
else if (SendItemUse != NULL)
|
||||
{
|
||||
Net_WriteByte (DEM_INVUSE);
|
||||
Net_WriteLong (SendItemUse->InventoryID);
|
||||
network->WriteByte (DEM_INVUSE);
|
||||
network->WriteLong (SendItemUse->InventoryID);
|
||||
SendItemUse = NULL;
|
||||
}
|
||||
if (SendItemDrop != NULL)
|
||||
{
|
||||
Net_WriteByte (DEM_INVDROP);
|
||||
Net_WriteLong (SendItemDrop->InventoryID);
|
||||
Net_WriteLong(SendItemDropAmount);
|
||||
network->WriteByte (DEM_INVDROP);
|
||||
network->WriteLong (SendItemDrop->InventoryID);
|
||||
network->WriteLong(SendItemDropAmount);
|
||||
SendItemDrop = NULL;
|
||||
}
|
||||
|
||||
cmd->ucmd.forwardmove <<= 8;
|
||||
cmd->ucmd.sidemove <<= 8;
|
||||
cmd.ucmd.forwardmove <<= 8;
|
||||
cmd.ucmd.sidemove <<= 8;
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
//[Graf Zahl] This really helps if the mouse update rate can't be increased!
|
||||
|
@ -863,7 +862,7 @@ static void ChangeSpy (int changespy)
|
|||
// has done this for you, since it could desync otherwise.
|
||||
if (!demoplayback)
|
||||
{
|
||||
Net_WriteByte(DEM_REVERTCAMERA);
|
||||
network->WriteByte(DEM_REVERTCAMERA);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1132,10 +1131,7 @@ void G_Ticker ()
|
|||
}
|
||||
}
|
||||
|
||||
// get commands, check consistancy, and build new consistancy check
|
||||
int buf = (gametic/ticdup)%BACKUPTICS;
|
||||
|
||||
// [RH] Include some random seeds and player stuff in the consistancy
|
||||
// [RH] Include some random seeds and player stuff in the consistency
|
||||
// check, not just the player's x position like BOOM.
|
||||
uint32_t rngsum = FRandom::StaticSumSeeds ();
|
||||
|
||||
|
@ -1147,15 +1143,13 @@ void G_Ticker ()
|
|||
if (playeringame[i])
|
||||
{
|
||||
ticcmd_t *cmd = &players[i].cmd;
|
||||
ticcmd_t *newcmd = &netcmds[i][buf];
|
||||
ticcmd_t newcmd = network->GetPlayerInput(i);
|
||||
|
||||
network->RunCommands(i);
|
||||
|
||||
if ((gametic % ticdup) == 0)
|
||||
{
|
||||
RunNetSpecs (i, buf);
|
||||
}
|
||||
if (demorecording)
|
||||
{
|
||||
G_WriteDemoTiccmd (newcmd, i, buf);
|
||||
G_WriteDemoTiccmd (&newcmd, i);
|
||||
}
|
||||
players[i].oldbuttons = cmd->ucmd.buttons;
|
||||
// If the user alt-tabbed away, paused gets set to -1. In this case,
|
||||
|
@ -1167,7 +1161,7 @@ void G_Ticker ()
|
|||
}
|
||||
else
|
||||
{
|
||||
memcpy(cmd, newcmd, sizeof(ticcmd_t));
|
||||
*cmd = newcmd;
|
||||
}
|
||||
|
||||
// check for turbo cheats
|
||||
|
@ -1177,22 +1171,21 @@ void G_Ticker ()
|
|||
Printf ("%s is turbo!\n", players[i].userinfo.GetName());
|
||||
}
|
||||
|
||||
if (netgame && players[i].Bot == NULL && !demoplayback && (gametic%ticdup) == 0)
|
||||
if (netgame && players[i].Bot == NULL && !demoplayback && (gametic%network->ticdup) == 0)
|
||||
{
|
||||
//players[i].inconsistant = 0;
|
||||
if (gametic > BACKUPTICS*ticdup && consistancy[i][buf] != cmd->consistancy)
|
||||
if (network->IsInconsistent(i, cmd->consistency))
|
||||
{
|
||||
players[i].inconsistant = gametic - BACKUPTICS*ticdup;
|
||||
players[i].inconsistant = gametic - BACKUPTICS*network->ticdup;
|
||||
}
|
||||
if (players[i].mo)
|
||||
{
|
||||
uint32_t sum = rngsum + int((players[i].mo->X() + players[i].mo->Y() + players[i].mo->Z())*257) + players[i].mo->Angles.Yaw.BAMs() + players[i].mo->Angles.Pitch.BAMs();
|
||||
sum ^= players[i].health;
|
||||
consistancy[i][buf] = sum;
|
||||
network->SetConsistency(i, sum);
|
||||
}
|
||||
else
|
||||
{
|
||||
consistancy[i][buf] = rngsum;
|
||||
network->SetConsistency(i, rngsum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2439,11 +2432,8 @@ CCMD (stop)
|
|||
|
||||
extern uint8_t *lenspot;
|
||||
|
||||
void G_WriteDemoTiccmd (ticcmd_t *cmd, int player, int buf)
|
||||
void G_WriteDemoTiccmd (ticcmd_t *cmd, int player)
|
||||
{
|
||||
uint8_t *specdata;
|
||||
int speclen;
|
||||
|
||||
if (stoprecording)
|
||||
{ // use "stop" console command to end demo recording
|
||||
G_CheckDemoStatus ();
|
||||
|
@ -2455,12 +2445,7 @@ void G_WriteDemoTiccmd (ticcmd_t *cmd, int player, int buf)
|
|||
}
|
||||
|
||||
// [RH] Write any special "ticcmds" for this player to the demo
|
||||
if ((specdata = NetSpecs[player][buf].GetData (&speclen)) && gametic % ticdup == 0)
|
||||
{
|
||||
memcpy (demo_p, specdata, speclen);
|
||||
demo_p += speclen;
|
||||
NetSpecs[player][buf].SetData (NULL, 0);
|
||||
}
|
||||
demo_p += network->CopySpecData(player, demo_p, maxdemosize - (demo_p - demobuffer));
|
||||
|
||||
// [RH] Now write out a "normal" ticcmd.
|
||||
WriteUserCmdMessage (&cmd->ucmd, &players[player].cmd.ucmd, &demo_p);
|
||||
|
@ -2861,6 +2846,62 @@ void G_TimeDemo (const char* name)
|
|||
gameaction = (gameaction == ga_loadgame) ? ga_loadgameplaydemo : ga_playdemo;
|
||||
}
|
||||
|
||||
void G_InitServerNetGame(const char *mapname)
|
||||
{
|
||||
netgame = true;
|
||||
netserver = true;
|
||||
netclient = false;
|
||||
multiplayer = true;
|
||||
multiplayernext = true;
|
||||
consoleplayer = 0;
|
||||
players[consoleplayer].settings_controller = true;
|
||||
playeringame[consoleplayer] = true;
|
||||
|
||||
GameConfig->ReadNetVars(); // [RH] Read network ServerInfo cvars
|
||||
D_SetupUserInfo();
|
||||
|
||||
G_DeferedInitNew(mapname);
|
||||
}
|
||||
|
||||
void G_InitClientNetGame(int player, const char* mapname)
|
||||
{
|
||||
netgame = true;
|
||||
netserver = false;
|
||||
netclient = true;
|
||||
multiplayer = true;
|
||||
multiplayernext = true;
|
||||
consoleplayer = player;
|
||||
players[consoleplayer].settings_controller = true;
|
||||
playeringame[consoleplayer] = true;
|
||||
|
||||
GameConfig->ReadNetVars(); // [RH] Read network ServerInfo cvars
|
||||
D_SetupUserInfo();
|
||||
|
||||
G_DeferedInitNew(mapname);
|
||||
}
|
||||
|
||||
void G_EndNetGame()
|
||||
{
|
||||
gameaction = ga_fullconsole;
|
||||
|
||||
// Should we do this?
|
||||
//C_RestoreCVars(); // Is this a good idea?
|
||||
|
||||
P_SetupWeapons_ntohton();
|
||||
demoplayback = false;
|
||||
netgame = false;
|
||||
netclient = false;
|
||||
multiplayer = false;
|
||||
multiplayernext = false;
|
||||
for (int i = 1; i < MAXPLAYERS; i++)
|
||||
playeringame[i] = 0;
|
||||
consoleplayer = 0;
|
||||
players[0].camera = NULL;
|
||||
if (StatusBar != NULL)
|
||||
{
|
||||
StatusBar->AttachToPlayer(&players[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
|
|
|
@ -63,6 +63,10 @@ void G_PlayDemo (char* name);
|
|||
void G_TimeDemo (const char* name);
|
||||
bool G_CheckDemoStatus (void);
|
||||
|
||||
void G_InitServerNetGame(const char *mapname);
|
||||
void G_InitClientNetGame(int player, const char* mapname);
|
||||
void G_EndNetGame();
|
||||
|
||||
void G_WorldDone (void);
|
||||
|
||||
void G_Ticker (void);
|
||||
|
|
|
@ -1103,15 +1103,15 @@ void FWeaponSlots::SendDifferences(int playernum, const FWeaponSlots &other)
|
|||
// The slots differ. Send mine.
|
||||
if (playernum == consoleplayer)
|
||||
{
|
||||
Net_WriteByte(DEM_SETSLOT);
|
||||
network->WriteByte(DEM_SETSLOT);
|
||||
}
|
||||
else
|
||||
{
|
||||
Net_WriteByte(DEM_SETSLOTPNUM);
|
||||
Net_WriteByte(playernum);
|
||||
network->WriteByte(DEM_SETSLOTPNUM);
|
||||
network->WriteByte(playernum);
|
||||
}
|
||||
Net_WriteByte(i);
|
||||
Net_WriteByte(Slots[i].Size());
|
||||
network->WriteByte(i);
|
||||
network->WriteByte(Slots[i].Size());
|
||||
for (j = 0; j < Slots[i].Size(); ++j)
|
||||
{
|
||||
Net_WriteWeapon(Slots[i].GetWeapon(j));
|
||||
|
@ -1241,9 +1241,9 @@ CCMD (setslot)
|
|||
Printf ("Slot %d cleared\n", slot);
|
||||
}
|
||||
|
||||
Net_WriteByte(DEM_SETSLOT);
|
||||
Net_WriteByte(slot);
|
||||
Net_WriteByte(argv.argc()-2);
|
||||
network->WriteByte(DEM_SETSLOT);
|
||||
network->WriteByte(slot);
|
||||
network->WriteByte(argv.argc()-2);
|
||||
for (int i = 2; i < argv.argc(); i++)
|
||||
{
|
||||
Net_WriteWeapon(PClass::FindActor(argv[i]));
|
||||
|
@ -1292,8 +1292,8 @@ CCMD (addslot)
|
|||
}
|
||||
else
|
||||
{
|
||||
Net_WriteByte(DEM_ADDSLOT);
|
||||
Net_WriteByte(slot);
|
||||
network->WriteByte(DEM_ADDSLOT);
|
||||
network->WriteByte(slot);
|
||||
Net_WriteWeapon(type);
|
||||
}
|
||||
}
|
||||
|
@ -1368,8 +1368,8 @@ CCMD (addslotdefault)
|
|||
}
|
||||
else
|
||||
{
|
||||
Net_WriteByte(DEM_ADDSLOTDEFAULT);
|
||||
Net_WriteByte(slot);
|
||||
network->WriteByte(DEM_ADDSLOTDEFAULT);
|
||||
network->WriteByte(slot);
|
||||
Net_WriteWeapon(type);
|
||||
}
|
||||
}
|
||||
|
@ -1440,7 +1440,7 @@ void P_SetupWeapons_ntohton()
|
|||
// for any game appear second, and weapons that filter for some other game
|
||||
// appear last. The idea here is to try to keep all the weapons that are
|
||||
// most likely to be used at the start of the list so that they only need
|
||||
// one byte to transmit across the network.
|
||||
// one byte to transmit across the network->
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
|
@ -1534,12 +1534,12 @@ void Net_WriteWeapon(PClassActor *type)
|
|||
assert(index >= 0 && index <= 32767);
|
||||
if (index < 128)
|
||||
{
|
||||
Net_WriteByte(index);
|
||||
network->WriteByte(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
Net_WriteByte(0x80 | index);
|
||||
Net_WriteByte(index >> 7);
|
||||
network->WriteByte(0x80 | index);
|
||||
network->WriteByte(index >> 7);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -150,6 +150,8 @@ extern bool sendpause, sendsave, sendturn180, SendLand;
|
|||
void *statcopy; // for statistics driver
|
||||
|
||||
FLevelLocals level; // info about current level
|
||||
extern bool netserver; // serverside playsim
|
||||
extern bool netclient; // clientside playsim
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
@ -350,7 +352,7 @@ void G_NewInit ()
|
|||
}
|
||||
|
||||
G_ClearSnapshots ();
|
||||
netgame = false;
|
||||
netgame = (netclient || netserver);
|
||||
multiplayer = multiplayernext;
|
||||
multiplayernext = false;
|
||||
if (demoplayback)
|
||||
|
@ -903,7 +905,7 @@ IMPLEMENT_CLASS(DAutosaver, false, false)
|
|||
|
||||
void DAutosaver::Tick ()
|
||||
{
|
||||
Net_WriteByte (DEM_CHECKAUTOSAVE);
|
||||
network->WriteByte (DEM_CHECKAUTOSAVE);
|
||||
Destroy ();
|
||||
}
|
||||
|
||||
|
|
|
@ -695,8 +695,8 @@ CCMD (spray)
|
|||
return;
|
||||
}
|
||||
|
||||
Net_WriteByte (DEM_SPRAY);
|
||||
Net_WriteString (argv[1]);
|
||||
network->WriteByte (DEM_SPRAY);
|
||||
network->WriteString (argv[1]);
|
||||
}
|
||||
|
||||
void SprayDecal(AActor *shooter, const char *name, double distance)
|
||||
|
|
|
@ -1051,11 +1051,8 @@ static void DrawLatency()
|
|||
{
|
||||
return;
|
||||
}
|
||||
int i, localdelay = 0, arbitratordelay = 0;
|
||||
for (i = 0; i < BACKUPTICS; i++) localdelay += netdelay[0][i];
|
||||
for (i = 0; i < BACKUPTICS; i++) arbitratordelay += netdelay[nodeforplayer[Net_Arbitrator]][i];
|
||||
localdelay = ((localdelay / BACKUPTICS) * ticdup) * (1000 / TICRATE);
|
||||
arbitratordelay = ((arbitratordelay / BACKUPTICS) * ticdup) * (1000 / TICRATE);
|
||||
int localdelay = network->GetPing(0);
|
||||
int arbitratordelay = network->GetServerPing();
|
||||
int color = CR_GREEN;
|
||||
if (MAX(localdelay, arbitratordelay) > 200)
|
||||
{
|
||||
|
@ -1065,7 +1062,7 @@ static void DrawLatency()
|
|||
{
|
||||
color = CR_ORANGE;
|
||||
}
|
||||
if (MAX(localdelay, arbitratordelay) >= ((BACKUPTICS / 2 - 1) * ticdup) * (1000 / TICRATE))
|
||||
if (MAX(localdelay, arbitratordelay) >= network->GetHighPingThreshold())
|
||||
{
|
||||
color = CR_RED;
|
||||
}
|
||||
|
|
|
@ -1214,7 +1214,7 @@ void DBaseStatusBar::DrawConsistancy () const
|
|||
{
|
||||
fprintf (debugfile, "%s as of tic %d (%d)\n", conbuff,
|
||||
players[1-consoleplayer].inconsistant,
|
||||
players[1-consoleplayer].inconsistant/ticdup);
|
||||
players[1-consoleplayer].inconsistant/network->ticdup);
|
||||
}
|
||||
}
|
||||
screen->DrawText (SmallFont, CR_GREEN,
|
||||
|
|
|
@ -404,7 +404,7 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2,
|
|||
{
|
||||
// The teamplay mode uses colors to show teams, so we need some
|
||||
// other way to do highlighting. And it may as well be used for
|
||||
// all modes for the sake of consistancy.
|
||||
// all modes for the sake of consistency.
|
||||
screen->Dim(MAKERGB(200,245,255), 0.125f, col1 - 12*CleanXfac, y - 1, col5 + (maxnamewidth + 24)*CleanXfac, height + 2);
|
||||
}
|
||||
|
||||
|
@ -431,14 +431,7 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2,
|
|||
screen->DrawText (SmallFont, color, col4, y + ypadding, player->userinfo.GetName(),
|
||||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
|
||||
int avgdelay = 0;
|
||||
for (int i = 0; i < BACKUPTICS; i++)
|
||||
{
|
||||
avgdelay += netdelay[nodeforplayer[(int)(player - players)]][i];
|
||||
}
|
||||
avgdelay /= BACKUPTICS;
|
||||
|
||||
mysnprintf(str, countof(str), "%d", (avgdelay * ticdup) * (1000 / TICRATE));
|
||||
mysnprintf(str, countof(str), "%d", network->GetPing((int)(player - players)));
|
||||
|
||||
screen->DrawText(SmallFont, color, col5, y + ypadding, str,
|
||||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
|
|
957
src/i_net.cpp
957
src/i_net.cpp
File diff suppressed because it is too large
Load diff
42
src/i_net.h
42
src/i_net.h
|
@ -1,8 +1,38 @@
|
|||
#ifndef __I_NET_H__
|
||||
#define __I_NET_H__
|
||||
|
||||
// Called by D_DoomMain.
|
||||
bool I_InitNetwork (void);
|
||||
void I_NetCmd (void);
|
||||
#pragma once
|
||||
|
||||
#endif
|
||||
#include <memory>
|
||||
|
||||
#define MAX_MSGLEN 14000
|
||||
#define DOOMPORT 5029
|
||||
|
||||
struct NetPacket
|
||||
{
|
||||
NetPacket() { memset(data, 0, sizeof(data)); }
|
||||
|
||||
// packet data to be sent
|
||||
uint8_t data[MAX_MSGLEN];
|
||||
|
||||
// bytes in data to be sent
|
||||
int16_t size = 0;
|
||||
|
||||
// dest for send, set by get (-1 = no packet).
|
||||
int16_t node = 0;
|
||||
|
||||
uint8_t &operator[](int i) { return data[i]; }
|
||||
const uint8_t &operator[](int i) const { return data[i]; }
|
||||
};
|
||||
|
||||
// Network packet data.
|
||||
struct doomcom_t
|
||||
{
|
||||
virtual ~doomcom_t() { }
|
||||
|
||||
virtual void PacketSend(const NetPacket &packet) = 0;
|
||||
virtual void PacketGet(NetPacket &packet) = 0;
|
||||
|
||||
virtual int Connect(const char *name) = 0;
|
||||
virtual void Close(int node) = 0;
|
||||
};
|
||||
|
||||
std::unique_ptr<doomcom_t> I_InitNetwork(int port);
|
||||
|
|
12
src/info.cpp
12
src/info.cpp
|
@ -587,17 +587,17 @@ static void SummonActor (int command, int command2, FCommandLine argv)
|
|||
Printf ("Unknown actor '%s'\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
Net_WriteByte (argv.argc() > 2 ? command2 : command);
|
||||
Net_WriteString (type->TypeName.GetChars());
|
||||
network->WriteByte (argv.argc() > 2 ? command2 : command);
|
||||
network->WriteString (type->TypeName.GetChars());
|
||||
|
||||
if (argv.argc () > 2)
|
||||
{
|
||||
Net_WriteWord (atoi (argv[2])); // angle
|
||||
Net_WriteWord ((argv.argc() > 3) ? atoi(argv[3]) : 0); // TID
|
||||
Net_WriteByte ((argv.argc() > 4) ? atoi(argv[4]) : 0); // special
|
||||
network->WriteWord (atoi (argv[2])); // angle
|
||||
network->WriteWord ((argv.argc() > 3) ? atoi(argv[3]) : 0); // TID
|
||||
network->WriteByte ((argv.argc() > 4) ? atoi(argv[4]) : 0); // special
|
||||
for (int i = 5; i < 10; i++)
|
||||
{ // args[5]
|
||||
Net_WriteLong((i < argv.argc()) ? atoi(argv[i]) : 0);
|
||||
network->WriteLong((i < argv.argc()) ? atoi(argv[i]) : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -761,7 +761,7 @@ bool DIntermissionController::Responder (event_t *ev)
|
|||
int res = mScreen->Responder(ev);
|
||||
if (res == -1 && !mSentAdvance)
|
||||
{
|
||||
Net_WriteByte(DEM_ADVANCEINTER);
|
||||
network->WriteByte(DEM_ADVANCEINTER);
|
||||
mSentAdvance = true;
|
||||
}
|
||||
return !!res;
|
||||
|
|
|
@ -689,6 +689,6 @@ CCMD (mdk)
|
|||
return;
|
||||
|
||||
const char *name = argv.argc() > 1 ? argv[1] : "";
|
||||
Net_WriteByte (DEM_MDK);
|
||||
Net_WriteString(name);
|
||||
network->WriteByte (DEM_MDK);
|
||||
network->WriteString(name);
|
||||
}
|
||||
|
|
|
@ -267,7 +267,7 @@ void FRandom::Init(uint32_t seed)
|
|||
//
|
||||
// FRandom :: StaticSumSeeds
|
||||
//
|
||||
// This function produces a uint32_t that can be used to check the consistancy
|
||||
// This function produces a uint32_t that can be used to check the consistency
|
||||
// of network games between different machines. Only a select few RNGs are
|
||||
// used for the sum, because not all RNGs are important to network sync.
|
||||
//
|
||||
|
|
|
@ -695,17 +695,17 @@ DEFINE_ACTION_FUNCTION(DConversationMenu, SendConversationReply)
|
|||
switch (node)
|
||||
{
|
||||
case -1:
|
||||
Net_WriteByte(DEM_CONVNULL);
|
||||
network->WriteByte(DEM_CONVNULL);
|
||||
break;
|
||||
|
||||
case -2:
|
||||
Net_WriteByte(DEM_CONVCLOSE);
|
||||
network->WriteByte(DEM_CONVCLOSE);
|
||||
break;
|
||||
|
||||
default:
|
||||
Net_WriteByte(DEM_CONVREPLY);
|
||||
Net_WriteWord(node);
|
||||
Net_WriteByte(reply);
|
||||
network->WriteByte(DEM_CONVREPLY);
|
||||
network->WriteWord(node);
|
||||
network->WriteByte(reply);
|
||||
break;
|
||||
}
|
||||
StaticLastReply = reply;
|
||||
|
|
|
@ -1987,8 +1987,8 @@ CCMD (kill)
|
|||
if (CheckCheatmode ())
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_MASSACRE);
|
||||
network->WriteByte (DEM_GENERICCHEAT);
|
||||
network->WriteByte (CHT_MASSACRE);
|
||||
}
|
||||
else if (!stricmp (argv[1], "baddies"))
|
||||
{
|
||||
|
@ -1996,13 +1996,13 @@ CCMD (kill)
|
|||
if (CheckCheatmode ())
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_MASSACRE2);
|
||||
network->WriteByte (DEM_GENERICCHEAT);
|
||||
network->WriteByte (CHT_MASSACRE2);
|
||||
}
|
||||
else
|
||||
{
|
||||
Net_WriteByte (DEM_KILLCLASSCHEAT);
|
||||
Net_WriteString (argv[1]);
|
||||
network->WriteByte (DEM_KILLCLASSCHEAT);
|
||||
network->WriteString (argv[1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2012,7 +2012,7 @@ CCMD (kill)
|
|||
return;
|
||||
|
||||
// Kill the player
|
||||
Net_WriteByte (DEM_SUICIDE);
|
||||
network->WriteByte (DEM_SUICIDE);
|
||||
}
|
||||
C_HideConsole ();
|
||||
}
|
||||
|
@ -2024,8 +2024,8 @@ CCMD(remove)
|
|||
if (CheckCheatmode())
|
||||
return;
|
||||
|
||||
Net_WriteByte(DEM_REMOVE);
|
||||
Net_WriteString(argv[1]);
|
||||
network->WriteByte(DEM_REMOVE);
|
||||
network->WriteString(argv[1]);
|
||||
C_HideConsole();
|
||||
}
|
||||
else
|
||||
|
@ -2033,5 +2033,4 @@ CCMD(remove)
|
|||
Printf("Usage: remove <actor class name>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3130,7 +3130,7 @@ FUNC(LS_Autosave)
|
|||
if (gameaction != ga_savegame)
|
||||
{
|
||||
level.flags2 &= ~LEVEL2_NOAUTOSAVEHINT;
|
||||
Net_WriteByte (DEM_CHECKAUTOSAVE);
|
||||
network->WriteByte (DEM_CHECKAUTOSAVE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1838,6 +1838,10 @@ void P_SpawnThings (int position)
|
|||
|
||||
for (int i=0; i < numthings; i++)
|
||||
{
|
||||
// Only spawn the player mobj for the client in a client/server game
|
||||
if (netclient && (MapThingsConverted[i].info->Type || MapThingsConverted[i].info->Special != SMT_Player1Start + position))
|
||||
continue;
|
||||
|
||||
AActor *actor = SpawnMapThing (i, &MapThingsConverted[i], position);
|
||||
unsigned *udi = MapThingsUserDataIndex.CheckKey((unsigned)i);
|
||||
if (udi != NULL)
|
||||
|
|
|
@ -592,7 +592,7 @@ void player_t::SetFOV(float fov)
|
|||
{
|
||||
if (consoleplayer == Net_Arbitrator)
|
||||
{
|
||||
Net_WriteByte(DEM_MYFOV);
|
||||
network->WriteByte(DEM_MYFOV);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -602,9 +602,9 @@ void player_t::SetFOV(float fov)
|
|||
}
|
||||
else
|
||||
{
|
||||
Net_WriteByte(DEM_MYFOV);
|
||||
network->WriteByte(DEM_MYFOV);
|
||||
}
|
||||
Net_WriteFloat(clamp<float>(fov, 5.f, 179.f));
|
||||
network->WriteFloat(clamp<float>(fov, 5.f, 179.f));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -747,9 +747,9 @@ void player_t::SendPitchLimits() const
|
|||
uppitch = downpitch = (int)maxviewpitch;
|
||||
}
|
||||
|
||||
Net_WriteByte(DEM_SETPITCHLIMIT);
|
||||
Net_WriteByte(uppitch);
|
||||
Net_WriteByte(downpitch);
|
||||
network->WriteByte(DEM_SETPITCHLIMIT);
|
||||
network->WriteByte(uppitch);
|
||||
network->WriteByte(downpitch);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1038,7 +1038,7 @@ void APlayerPawn::PostBeginPlay()
|
|||
//
|
||||
// Sets up the default weapon slots for this player. If this is also the
|
||||
// local player, determines local modifications and sends those across the
|
||||
// network. Ignores voodoo dolls.
|
||||
// network-> Ignores voodoo dolls.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
|
@ -2451,8 +2451,6 @@ nodetype *RestoreNodeList(AActor *act, nodetype *head, nodetype *linktype::*othe
|
|||
|
||||
void P_PredictPlayer (player_t *player)
|
||||
{
|
||||
int maxtic;
|
||||
|
||||
if (cl_noprediction ||
|
||||
singletics ||
|
||||
demoplayback ||
|
||||
|
@ -2466,7 +2464,7 @@ void P_PredictPlayer (player_t *player)
|
|||
return;
|
||||
}
|
||||
|
||||
maxtic = maketic;
|
||||
int maxtic = network->GetSendTick();
|
||||
|
||||
if (gametic == maxtic)
|
||||
{
|
||||
|
@ -2517,13 +2515,13 @@ void P_PredictPlayer (player_t *player)
|
|||
act->BlockNode = NULL;
|
||||
|
||||
// Values too small to be usable for lerping can be considered "off".
|
||||
bool CanLerp = (!(cl_predict_lerpscale < 0.01f) && (ticdup == 1)), DoLerp = false, NoInterpolateOld = R_GetViewInterpolationStatus();
|
||||
bool CanLerp = (!(cl_predict_lerpscale < 0.01f) && (network->ticdup == 1)), DoLerp = false, NoInterpolateOld = R_GetViewInterpolationStatus();
|
||||
for (int i = gametic; i < maxtic; ++i)
|
||||
{
|
||||
if (!NoInterpolateOld)
|
||||
R_RebuildViewInterpolation(player);
|
||||
|
||||
player->cmd = localcmds[i % LOCALCMDTICS];
|
||||
player->cmd = network->GetSentInput(i);
|
||||
P_PlayerThink (player);
|
||||
player->mo->Tick ();
|
||||
|
||||
|
@ -2590,6 +2588,7 @@ void P_UnPredictPlayer ()
|
|||
int inventorytics = player->inventorytics;
|
||||
|
||||
*player = PredictionPlayerBackup;
|
||||
PredictionPlayerBackup = {}; // Clear the copy so its destructor doesn't try delete the psprites list
|
||||
|
||||
// Restore the camera instead of using the backup's copy, because spynext/prev
|
||||
// could cause it to change during prediction.
|
||||
|
|
|
@ -119,8 +119,6 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines)
|
|||
PolyMaskedCycles.Reset();
|
||||
PolyDrawerWaitCycles.Reset();
|
||||
|
||||
NetUpdate();
|
||||
|
||||
DontMapLines = dontmaplines;
|
||||
|
||||
R_SetupFrame(Viewpoint, Viewwindow, actor);
|
||||
|
@ -169,8 +167,6 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines)
|
|||
if (Viewpoint.camera)
|
||||
Viewpoint.camera->renderflags = savedflags;
|
||||
interpolator.RestoreInterpolations ();
|
||||
|
||||
NetUpdate();
|
||||
}
|
||||
|
||||
void PolyRenderer::RenderRemainingPlayerSprites()
|
||||
|
|
|
@ -54,20 +54,10 @@ EXTERN_CVAR(String, language)
|
|||
|
||||
uint32_t LanguageIDs[4];
|
||||
|
||||
|
||||
void I_Tactile(int /*on*/, int /*off*/, int /*total*/)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ticcmd_t* I_BaseTiccmd()
|
||||
{
|
||||
static ticcmd_t emptycmd;
|
||||
return &emptycmd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// SetLanguageIDs
|
||||
//
|
||||
|
|
|
@ -71,7 +71,7 @@ public:
|
|||
virtual void NetProgress(int count);
|
||||
virtual void NetMessage(const char *format, ...);
|
||||
virtual void NetDone();
|
||||
virtual bool NetLoop(bool (*timerCallback)(void*), void* userData);
|
||||
virtual bool NetLoop(std::function<bool()> callback);
|
||||
};
|
||||
|
||||
|
||||
|
@ -153,11 +153,11 @@ void FBasicStartupScreen::NetDone()
|
|||
FConsoleWindow::GetInstance().NetDone();
|
||||
}
|
||||
|
||||
bool FBasicStartupScreen::NetLoop(bool (*timerCallback)(void*), void* const userData)
|
||||
bool FBasicStartupScreen::NetLoop(std::function<bool()> callback)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (timerCallback(userData))
|
||||
if (callback())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -79,17 +79,6 @@ void I_StartFrame (void);
|
|||
// Can call D_PostEvent.
|
||||
void I_StartTic (void);
|
||||
|
||||
// Asynchronous interrupt functions should maintain private queues
|
||||
// that are read by the synchronous functions
|
||||
// to be converted into events.
|
||||
|
||||
// Either returns a null ticcmd,
|
||||
// or calls a loadable driver to build it.
|
||||
// This ticcmd will then be modified by the gameloop
|
||||
// for normal input.
|
||||
ticcmd_t *I_BaseTiccmd (void);
|
||||
|
||||
|
||||
// Called by M_Responder when quit is selected.
|
||||
// Clean exit, displays sell blurb.
|
||||
void I_Quit (void);
|
||||
|
|
|
@ -75,12 +75,6 @@ void I_Tactile (int /*on*/, int /*off*/, int /*total*/)
|
|||
{
|
||||
}
|
||||
|
||||
ticcmd_t emptycmd;
|
||||
ticcmd_t *I_BaseTiccmd(void)
|
||||
{
|
||||
return &emptycmd;
|
||||
}
|
||||
|
||||
void I_BeginRead(void)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ class FTTYStartupScreen : public FStartupScreen
|
|||
void NetProgress(int count);
|
||||
void NetMessage(const char *format, ...); // cover for printf
|
||||
void NetDone();
|
||||
bool NetLoop(bool (*timer_callback)(void *), void *userdata);
|
||||
bool NetLoop(std::function<bool()> callback);
|
||||
protected:
|
||||
bool DidNetInit;
|
||||
int NetMaxPos, NetCurPos;
|
||||
|
@ -304,7 +304,7 @@ void FTTYStartupScreen::NetProgress(int count)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
bool FTTYStartupScreen::NetLoop(bool (*timer_callback)(void *), void *userdata)
|
||||
bool FTTYStartupScreen::NetLoop(std::function<bool()> callback)
|
||||
{
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
|
@ -328,7 +328,7 @@ bool FTTYStartupScreen::NetLoop(bool (*timer_callback)(void *), void *userdata)
|
|||
}
|
||||
else if (retval == 0)
|
||||
{
|
||||
if (timer_callback (userdata))
|
||||
if (callback())
|
||||
{
|
||||
fputc ('\n', stderr);
|
||||
return true;
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
** Actual implementation is system-specific.
|
||||
*/
|
||||
|
||||
#include <functional>
|
||||
|
||||
class FStartupScreen
|
||||
{
|
||||
public:
|
||||
|
@ -51,7 +53,7 @@ public:
|
|||
virtual void NetProgress(int count);
|
||||
virtual void NetMessage(const char *format, ...); // cover for printf
|
||||
virtual void NetDone();
|
||||
virtual bool NetLoop(bool (*timer_callback)(void *), void *userdata);
|
||||
virtual bool NetLoop(std::function<bool()> callback);
|
||||
protected:
|
||||
int MaxPos, CurPos, NotchPos;
|
||||
};
|
||||
|
|
|
@ -433,8 +433,8 @@ static bool CheatAddKey (cheatseq_t *cheat, uint8_t key, bool *eat)
|
|||
|
||||
static bool Cht_Generic (cheatseq_t *cheat)
|
||||
{
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (cheat->Args[0]);
|
||||
network->WriteByte (DEM_GENERICCHEAT);
|
||||
network->WriteByte (cheat->Args[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -584,7 +584,7 @@ CCMD(finishgame)
|
|||
return;
|
||||
}
|
||||
// This CCMD simulates an end-of-game action and exists to end mods that never exit their last level.
|
||||
Net_WriteByte(DEM_FINISHGAME);
|
||||
network->WriteByte(DEM_FINISHGAME);
|
||||
}
|
||||
|
||||
ADD_STAT(statistics)
|
||||
|
|
|
@ -85,9 +85,6 @@ namespace swrenderer
|
|||
return;
|
||||
}
|
||||
|
||||
if (Thread->MainThread)
|
||||
NetUpdate();
|
||||
|
||||
frontsector = curline->frontsector;
|
||||
backsector = curline->backsector;
|
||||
|
||||
|
|
|
@ -373,9 +373,6 @@ namespace swrenderer
|
|||
WallSampler sampler(Thread->Viewport.get(), y1, texturemid, swal[x], yrepeat, lwal[x] + xoffset, xmagnitude, rw_pic);
|
||||
Draw1Column(x, y1, y2, sampler);
|
||||
}
|
||||
|
||||
if (Thread->MainThread)
|
||||
NetUpdate();
|
||||
}
|
||||
|
||||
void RenderWallPart::ProcessNormalWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal)
|
||||
|
|
|
@ -142,7 +142,5 @@ namespace swrenderer
|
|||
renderer.Render(this, xscale, yscale, alpha, additive, masked, colormap, tex);
|
||||
}
|
||||
}
|
||||
if (thread->MainThread)
|
||||
NetUpdate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -455,14 +455,8 @@ namespace swrenderer
|
|||
int prevuniq2 = CurrentPortalUniq;
|
||||
CurrentPortalUniq = prevuniq;
|
||||
|
||||
if (Thread->MainThread)
|
||||
NetUpdate();
|
||||
|
||||
Thread->TranslucentPass->Render(); // this is required since with portals there often will be cases when more than 80% of the view is inside a portal.
|
||||
|
||||
if (Thread->MainThread)
|
||||
NetUpdate();
|
||||
|
||||
Thread->Clip3D->LeaveSkybox(); // pop 3D floor height map
|
||||
CurrentPortalUniq = prevuniq2;
|
||||
|
||||
|
|
|
@ -144,8 +144,6 @@ namespace swrenderer
|
|||
CameraLight::Instance()->SetCamera(MainThread()->Viewport->viewpoint, MainThread()->Viewport->RenderTarget, actor);
|
||||
MainThread()->Viewport->SetupFreelook();
|
||||
|
||||
NetUpdate();
|
||||
|
||||
this->dontmaplines = dontmaplines;
|
||||
|
||||
// [RH] Setup particles for this frame
|
||||
|
@ -271,9 +269,6 @@ namespace swrenderer
|
|||
thread->OpaquePass->RenderScene();
|
||||
thread->Clip3D->ResetClip(); // reset clips (floor/ceiling)
|
||||
|
||||
if (thread->MainThread)
|
||||
NetUpdate();
|
||||
|
||||
if (viewactive)
|
||||
{
|
||||
thread->PlaneList->Render();
|
||||
|
@ -281,13 +276,7 @@ namespace swrenderer
|
|||
thread->Portal->RenderPlanePortals();
|
||||
thread->Portal->RenderLinePortals();
|
||||
|
||||
if (thread->MainThread)
|
||||
NetUpdate();
|
||||
|
||||
thread->TranslucentPass->Render();
|
||||
|
||||
if (thread->MainThread)
|
||||
NetUpdate();
|
||||
}
|
||||
|
||||
DrawerThreads::Execute(thread->DrawQueue);
|
||||
|
|
|
@ -541,8 +541,5 @@ namespace swrenderer
|
|||
drawerargs.DrawMaskedColumn(thread, x, iscale, pic, frac + xiscale / 2, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, RenderStyle, false);
|
||||
frac += xiscale;
|
||||
}
|
||||
|
||||
if (thread->MainThread)
|
||||
NetUpdate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -371,8 +371,5 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (thread->MainThread)
|
||||
NetUpdate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,7 +142,6 @@ int sys_ostype = 0;
|
|||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
static ticcmd_t emptycmd;
|
||||
static bool HasExited;
|
||||
|
||||
static WadStuff *WadList;
|
||||
|
@ -166,20 +165,6 @@ void I_Tactile(int on, int off, int total)
|
|||
on = off = total = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// I_BaseTiccmd
|
||||
//
|
||||
// Returns an empty ticcmd. I have no idea why this should be system-
|
||||
// specific.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
ticcmd_t *I_BaseTiccmd()
|
||||
{
|
||||
return &emptycmd;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// I_DetectOS
|
||||
|
|
|
@ -72,16 +72,6 @@ void I_StartFrame (void);
|
|||
// Can call D_PostEvent.
|
||||
void I_StartTic (void);
|
||||
|
||||
// Asynchronous interrupt functions should maintain private queues
|
||||
// that are read by the synchronous functions
|
||||
// to be converted into events.
|
||||
|
||||
// Either returns a null ticcmd,
|
||||
// or calls a loadable driver to build it.
|
||||
// This ticcmd will then be modified by the gameloop
|
||||
// for normal input.
|
||||
ticcmd_t *I_BaseTiccmd (void);
|
||||
|
||||
|
||||
// Called by M_Responder when quit is selected.
|
||||
// Clean exit, displays sell blurb.
|
||||
|
|
|
@ -121,7 +121,7 @@ public:
|
|||
void NetProgress(int count);
|
||||
void NetMessage(const char *format, ...); // cover for printf
|
||||
void NetDone();
|
||||
bool NetLoop(bool (*timer_callback)(void *), void *userdata);
|
||||
bool NetLoop(std::function<bool()> callback);
|
||||
protected:
|
||||
LRESULT NetMarqueeMode;
|
||||
int NetMaxPos, NetCurPos;
|
||||
|
@ -528,7 +528,7 @@ void FBasicStartupScreen :: NetProgress(int count)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FBasicStartupScreen::NetLoop(bool (*timer_callback)(void *), void *userdata)
|
||||
bool FBasicStartupScreen::NetLoop(std::function<bool()> callback)
|
||||
{
|
||||
BOOL bRet;
|
||||
MSG msg;
|
||||
|
@ -549,7 +549,7 @@ bool FBasicStartupScreen::NetLoop(bool (*timer_callback)(void *), void *userdata
|
|||
{
|
||||
if (msg.message == WM_TIMER && msg.hwnd == Window && msg.wParam == 1337)
|
||||
{
|
||||
if (timer_callback (userdata))
|
||||
if (callback())
|
||||
{
|
||||
KillTimer (NetStartPane, 1);
|
||||
return true;
|
||||
|
|
Loading…
Reference in a new issue