raze/source/sw/src/network.cpp
Mitchell Richters 40739d9176 - SW: Add ogameclock and use in places where ototalclock was used.
* Duke used `ototalclock` only to keep track of when the game ticked. SW uses it in the rendering code for differentials between tics so we should preserve that to prevent issues down the track.
2020-08-26 09:48:51 +10:00

251 lines
5.8 KiB
C++

//-------------------------------------------------------------------------
/*
Copyright (C) 1997, 2005 - 3D Realms Entertainment
This file is part of Shadow Warrior version 1.2
Shadow Warrior 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 2
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, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Original Source: 1997 - Frank Maddin and Jim Norwood
Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
#include "ns.h"
#include "build.h"
#include "baselayer.h"
#include "mmulti.h"
#include "gamecontrol.h"
#include "game.h"
#include "tags.h"
#include "names2.h"
#include "network.h"
#include "pal.h"
#include "weapon.h"
#include "menus.h"
#include "printf.h"
BEGIN_SW_NS
void getinput(SW_PACKET *, SWBOOL);
static uint8_t tempbuf[576], packbuf[576];
int PlayClock;
gNET gNet;
#define TIMERUPDATESIZ 32
//SW_PACKET fsync;
//Local multiplayer variables
// should move this to a local scope of faketimerhandler - do it when able to test
SW_PACKET loc;
//SW_PACKET oloc;
SWBOOL ready2send = 0;
SWBOOL CommEnabled = FALSE;
uint8_t CommPlayers = 0;
int movefifoplc, movefifosendplc; //, movefifoend[MAX_SW_PLAYERS];
unsigned int MoveThingsCount;
//int myminlag[MAX_SW_PLAYERS];
int mymaxlag, otherminlag, bufferjitter = 1;
extern char sync_first[MAXSYNCBYTES][60];
extern int sync_found;
//
// Tic Duplication - so you can move multiple times per packet. This is SW_PACKET with the 16 bit values extended to 32 bit.
//
typedef struct
{
int32_t fvel;
int32_t svel;
fix16_t q16avel;
fix16_t q16aimvel;
fix16_t q16ang;
fix16_t q16horz;
int32_t bits;
} SW_AVERAGE_PACKET;
int MovesPerPacket = 1;
SW_AVERAGE_PACKET AveragePacket;
// GAME.C sync state variables
uint8_t syncstat[MAXSYNCBYTES];
//int syncvalhead[MAX_SW_PLAYERS];
int syncvaltail, syncvaltottail;
void GetSyncInfoFromPacket(uint8_t *packbuf, int packbufleng, int *j, int otherconnectindex);
int ogameclock, gameclock;
int lastTic;
double smoothratio;
// must start out as 0
void
InitNetPlayerOptions(void)
{
// short pnum;
PLAYERp pp = Player + myconnectindex;
strncpy(pp->PlayerName, playername, 32);
// myconnectindex palette
pp->TeamColor = gs.NetColor;
if (pp->SpriteP)
{
pp->SpriteP->pal = PALETTE_PLAYER0 + pp->TeamColor;
User[pp->SpriteP - sprite]->spal = pp->SpriteP->pal;
}
}
void
waitforeverybody(void)
{
}
void
InitNetVars(void)
{
short pnum;
PLAYERp pp;
memset(&loc, 0, sizeof(loc));
TRAVERSE_CONNECT(pnum)
{
pp = Player + pnum;
pp->movefifoend = 0;
Player[pnum].syncvalhead = 0;
memset(pp->inputfifo,0,sizeof(pp->inputfifo));
}
movefifoplc = 0;
movefifosendplc = 0;
syncvaltail = 0;
syncvaltottail = 0;
predictmovefifoplc = 0;
memset(&syncstat, 0, sizeof(syncstat));
memset(sync_first, 0, sizeof(sync_first));
sync_found = FALSE;
TRAVERSE_CONNECT(pnum)
{
Player[pnum].myminlag = 0;
}
otherminlag = mymaxlag = 0;
}
void
InitTimingVars(void)
{
PlayClock = 0;
// resettiming();
totalsynctics = 0;
I_ResetTime();
lastTic = -1;
ogameclock = gameclock = 0;
randomseed = 17L;
MoveSkip8 = 2;
MoveSkip2 = 0;
MoveSkip4 = 1; // start slightly offset so these
// don't move the same
// as the Skip2's
MoveThingsCount = 0;
// CTW REMOVED
//if (gTenActivated)
// tenResetClock();
// CTW REMOVED END
}
void
UpdateInputs(void)
{
int i, j, k;
PLAYERp pp;
//getpackets();
if (Player[myconnectindex].movefifoend - movefifoplc >= 100)
return;
getinput(&loc, FALSE);
AveragePacket.fvel += loc.fvel;
AveragePacket.svel += loc.svel;
AveragePacket.q16avel += loc.q16avel;
AveragePacket.q16aimvel += loc.q16aimvel;
AveragePacket.q16ang = Player[myconnectindex].camq16ang;
AveragePacket.q16horz = Player[myconnectindex].camq16horiz;
SET(AveragePacket.bits, loc.bits);
Bmemset(&loc, 0, sizeof(loc));
pp = Player + myconnectindex;
if (pp->movefifoend & (MovesPerPacket-1))
{
memcpy(&pp->inputfifo[pp->movefifoend & (MOVEFIFOSIZ - 1)],
&pp->inputfifo[(pp->movefifoend-1) & (MOVEFIFOSIZ - 1)],
sizeof(SW_PACKET));
pp->movefifoend++;
return;
}
loc.fvel = AveragePacket.fvel / MovesPerPacket;
loc.svel = AveragePacket.svel / MovesPerPacket;
loc.q16avel = fix16_div(AveragePacket.q16avel, fix16_from_int(MovesPerPacket));
loc.q16aimvel = fix16_div(AveragePacket.q16aimvel, fix16_from_int(MovesPerPacket));
loc.q16ang = AveragePacket.q16ang;
loc.q16horz = AveragePacket.q16horz;
loc.bits = AveragePacket.bits;
memset(&AveragePacket, 0, sizeof(AveragePacket));
pp->inputfifo[Player[myconnectindex].movefifoend & (MOVEFIFOSIZ - 1)] = loc;
pp->movefifoend++;
Bmemset(&loc, 0, sizeof(loc));
if (!CommEnabled)
{
TRAVERSE_CONNECT(i)
{
if (i != myconnectindex)
{
memset(&Player[i].inputfifo[Player[i].movefifoend & (MOVEFIFOSIZ - 1)], 0, sizeof(Player[i].inputfifo[0]));
Player[i].movefifoend++;
}
}
return;
}
}
END_SW_NS