Skip to content

Commit

Permalink
Rewrite bits r/w to use bits cache.
Browse files Browse the repository at this point in the history
Avoids annoying requirement to maintain bitpos in SZ_*() functions.
  • Loading branch information
skullernet authored and res2k committed Sep 3, 2023
1 parent 121decb commit 0f5ef84
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 74 deletions.
1 change: 1 addition & 0 deletions inc/common/msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ void MSG_WriteString(const char *s);
void MSG_WritePos(const vec3_t pos);
void MSG_WriteAngle(float f);
#if USE_CLIENT
void MSG_FlushBits(void);
void MSG_WriteBits(int value, int bits);
int MSG_WriteDeltaUsercmd(const usercmd_t *from, const usercmd_t *cmd, int version);
int MSG_WriteDeltaUsercmd_Enhanced(const usercmd_t *from, const usercmd_t *cmd, int version);
Expand Down
3 changes: 2 additions & 1 deletion inc/common/sizebuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ typedef struct {
size_t maxsize;
size_t cursize;
size_t readcount;
size_t bitpos;
uint32_t bits_buf;
uint32_t bits_left;
const char *tag; // for debugging
} sizebuf_t;

Expand Down
4 changes: 4 additions & 0 deletions src/client/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,8 @@ static void CL_SendBatchedCmd(void)
cl.lastTransmitCmdNumber = cl.cmdNumber;
cl.lastTransmitCmdNumberReal = cl.cmdNumber;

MSG_BeginWriting();

// begin a client move command
patch = SZ_GetSpace(&msg_write, 1);

Expand Down Expand Up @@ -1043,6 +1045,8 @@ static void CL_SendBatchedCmd(void)
}
}

MSG_FlushBits();

P_FRAMES++;

//
Expand Down
118 changes: 50 additions & 68 deletions src/common/msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ MSG_BeginWriting
void MSG_BeginWriting(void)
{
msg_write.cursize = 0;
msg_write.bitpos = 0;
msg_write.bits_buf = 0;
msg_write.bits_left = 32;
msg_write.overflowed = false;
}

Expand Down Expand Up @@ -308,47 +309,48 @@ MSG_WriteBits
*/
void MSG_WriteBits(int value, int bits)
{
int i;
size_t bitpos;

if (bits == 0 || bits < -31 || bits > 32) {
Com_Error(ERR_FATAL, "MSG_WriteBits: bad bits: %d", bits);
}

if (msg_write.maxsize - msg_write.cursize < 4) {
Com_Error(ERR_FATAL, "MSG_WriteBits: overflow");
}

if (bits < 0) {
bits = -bits;
}

bitpos = msg_write.bitpos;
if ((bitpos & 7) == 0) {
// optimized case
switch (bits) {
case 8:
MSG_WriteByte(value);
return;
case 16:
MSG_WriteShort(value);
return;
case 32:
MSG_WriteLong(value);
return;
default:
break;
}
uint32_t bits_buf = msg_write.bits_buf;
uint32_t bits_left = msg_write.bits_left;
uint32_t v = value & ((1U << bits) - 1);

bits_buf |= v << (32 - bits_left);
if (bits >= bits_left) {
MSG_WriteLong(bits_buf);
bits_buf = v >> bits_left;
bits_left += 32;
}
for (i = 0; i < bits; i++, bitpos++) {
if ((bitpos & 7) == 0) {
msg_write.data[bitpos >> 3] = 0;
}
msg_write.data[bitpos >> 3] |= (value & 1) << (bitpos & 7);
value >>= 1;
bits_left -= bits;

msg_write.bits_buf = bits_buf;
msg_write.bits_left = bits_left;
}

/*
=============
MSG_FlushBits
=============
*/
void MSG_FlushBits(void)
{
uint32_t bits_buf = msg_write.bits_buf;
uint32_t bits_left = msg_write.bits_left;

while (bits_left < 32) {
MSG_WriteByte(bits_buf & 255);
bits_buf >>= 8;
bits_left += 8;
}
msg_write.bitpos = bitpos;
msg_write.cursize = (bitpos + 7) >> 3;

msg_write.bits_buf = 0;
msg_write.bits_left = 32;
}

/*
Expand Down Expand Up @@ -1374,7 +1376,8 @@ void MSG_WriteDeltaPlayerstate_Packet(const player_packed_t *from,
void MSG_BeginReading(void)
{
msg_read.readcount = 0;
msg_read.bitpos = 0;
msg_read.bits_buf = 0;
msg_read.bits_left = 0;
}

byte *MSG_ReadData(size_t len)
Expand Down Expand Up @@ -1642,53 +1645,32 @@ void MSG_ReadDeltaUsercmd_Hacked(const usercmd_t *from, usercmd_t *to)

int MSG_ReadBits(int bits)
{
int i, value;
size_t bitpos;
bool sgn;
bool sgn = false;

if (bits == 0 || bits < -31 || bits > 32) {
if (bits == 0 || bits < -25 || bits > 25) {
Com_Error(ERR_FATAL, "MSG_ReadBits: bad bits: %d", bits);
}

bitpos = msg_read.bitpos;
if ((bitpos & 7) == 0) {
// optimized case
switch (bits) {
case -8:
value = MSG_ReadChar();
return value;
case 8:
value = MSG_ReadByte();
return value;
case -16:
value = MSG_ReadShort();
return value;
case 32:
value = MSG_ReadLong();
return value;
default:
break;
}
}

sgn = false;
if (bits < 0) {
bits = -bits;
sgn = true;
}

value = 0;
for (i = 0; i < bits; i++, bitpos++) {
unsigned get = (msg_read.data[bitpos >> 3] >> (bitpos & 7)) & 1;
value |= get << i;
uint32_t bits_buf = msg_read.bits_buf;
uint32_t bits_left = msg_read.bits_left;

while (bits > bits_left) {
bits_buf |= (uint32_t)MSG_ReadByte() << bits_left;
bits_left += 8;
}
msg_read.bitpos = bitpos;
msg_read.readcount = (bitpos + 7) >> 3;

uint32_t value = bits_buf & ((1U << bits) - 1);

msg_read.bits_buf = bits_buf >> bits;
msg_read.bits_left = bits_left - bits;

if (sgn) {
if (value & (1 << (bits - 1))) {
value |= -1 ^ ((1U << bits) - 1);
}
return (int32_t)(value << (32 - bits)) >> (32 - bits);
}

return value;
Expand Down
4 changes: 0 additions & 4 deletions src/common/sizebuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ void SZ_Clear(sizebuf_t *buf)
{
buf->cursize = 0;
buf->readcount = 0;
buf->bitpos = 0;
buf->overflowed = false;
}

Expand Down Expand Up @@ -77,7 +76,6 @@ void *SZ_GetSpace(sizebuf_t *buf, size_t len)

data = buf->data + buf->cursize;
buf->cursize += len;
buf->bitpos = buf->cursize << 3;
return data;
}

Expand Down Expand Up @@ -139,13 +137,11 @@ void *SZ_ReadData(sizebuf_t *buf, size_t len)
Com_Error(ERR_DROP, "%s: read past end of message", __func__);
}
buf->readcount = buf->cursize + 1;
buf->bitpos = buf->readcount << 3;
return NULL;
}

data = buf->data + buf->readcount;
buf->readcount += len;
buf->bitpos = buf->readcount << 3;
return data;
}

Expand Down
2 changes: 1 addition & 1 deletion src/server/user.c
Original file line number Diff line number Diff line change
Expand Up @@ -1184,7 +1184,7 @@ static void SV_NewClientExecuteMove(int c)
lastcmd = NULL;
for (i = 0; i <= numDups; i++) {
numCmds[i] = MSG_ReadBits(5);
if (numCmds[i] == -1) {
if (msg_read.readcount > msg_read.cursize) {
SV_DropClient(sv_client, "read past end of message");
return;
}
Expand Down

0 comments on commit 0f5ef84

Please sign in to comment.