]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - com_msg.c
Split off common CRC16 and MSG_ functions into separate files
[xonotic/darkplaces.git] / com_msg.c
diff --git a/com_msg.c b/com_msg.c
new file mode 100644 (file)
index 0000000..a39dcac
--- /dev/null
+++ b/com_msg.c
@@ -0,0 +1,425 @@
+/*
+Copyright (C) 1996-1997 Id Software, Inc.
+
+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 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// com_msg.c
+
+#include "quakedef.h"
+
+/*
+============================================================================
+
+                                       BYTE ORDER FUNCTIONS
+
+============================================================================
+*/
+
+
+float BuffBigFloat (const unsigned char *buffer)
+{
+       union
+       {
+               float f;
+               unsigned int i;
+       }
+       u;
+       u.i = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
+       return u.f;
+}
+
+int BuffBigLong (const unsigned char *buffer)
+{
+       return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
+}
+
+short BuffBigShort (const unsigned char *buffer)
+{
+       return (buffer[0] << 8) | buffer[1];
+}
+
+float BuffLittleFloat (const unsigned char *buffer)
+{
+       union
+       {
+               float f;
+               unsigned int i;
+       }
+       u;
+       u.i = (buffer[3] << 24) | (buffer[2] << 16) | (buffer[1] << 8) | buffer[0];
+       return u.f;
+}
+
+int BuffLittleLong (const unsigned char *buffer)
+{
+       return (buffer[3] << 24) | (buffer[2] << 16) | (buffer[1] << 8) | buffer[0];
+}
+
+short BuffLittleShort (const unsigned char *buffer)
+{
+       return (buffer[1] << 8) | buffer[0];
+}
+
+void StoreBigLong (unsigned char *buffer, unsigned int i)
+{
+       buffer[0] = (i >> 24) & 0xFF;
+       buffer[1] = (i >> 16) & 0xFF;
+       buffer[2] = (i >>  8) & 0xFF;
+       buffer[3] = i         & 0xFF;
+}
+
+void StoreBigShort (unsigned char *buffer, unsigned short i)
+{
+       buffer[0] = (i >>  8) & 0xFF;
+       buffer[1] = i         & 0xFF;
+}
+
+void StoreLittleLong (unsigned char *buffer, unsigned int i)
+{
+       buffer[0] = i         & 0xFF;
+       buffer[1] = (i >>  8) & 0xFF;
+       buffer[2] = (i >> 16) & 0xFF;
+       buffer[3] = (i >> 24) & 0xFF;
+}
+
+void StoreLittleShort (unsigned char *buffer, unsigned short i)
+{
+       buffer[0] = i         & 0xFF;
+       buffer[1] = (i >>  8) & 0xFF;
+}
+
+/*
+==============================================================================
+
+                       MESSAGE IO FUNCTIONS
+
+Handles byte ordering and avoids alignment errors
+==============================================================================
+*/
+
+//
+// writing functions
+//
+
+void MSG_WriteChar (sizebuf_t *sb, int c)
+{
+       unsigned char    *buf;
+
+       buf = SZ_GetSpace (sb, 1);
+       buf[0] = c;
+}
+
+void MSG_WriteByte (sizebuf_t *sb, int c)
+{
+       unsigned char    *buf;
+
+       buf = SZ_GetSpace (sb, 1);
+       buf[0] = c;
+}
+
+void MSG_WriteShort (sizebuf_t *sb, int c)
+{
+       unsigned char    *buf;
+
+       buf = SZ_GetSpace (sb, 2);
+       buf[0] = c&0xff;
+       buf[1] = c>>8;
+}
+
+void MSG_WriteLong (sizebuf_t *sb, int c)
+{
+       unsigned char    *buf;
+
+       buf = SZ_GetSpace (sb, 4);
+       buf[0] = c&0xff;
+       buf[1] = (c>>8)&0xff;
+       buf[2] = (c>>16)&0xff;
+       buf[3] = c>>24;
+}
+
+void MSG_WriteFloat (sizebuf_t *sb, float f)
+{
+       union
+       {
+               float   f;
+               int     l;
+       } dat;
+
+
+       dat.f = f;
+       dat.l = LittleLong (dat.l);
+
+       SZ_Write (sb, (unsigned char *)&dat.l, 4);
+}
+
+void MSG_WriteString (sizebuf_t *sb, const char *s)
+{
+       if (!s || !*s)
+               MSG_WriteChar (sb, 0);
+       else
+               SZ_Write (sb, (unsigned char *)s, (int)strlen(s)+1);
+}
+
+void MSG_WriteUnterminatedString (sizebuf_t *sb, const char *s)
+{
+       if (s && *s)
+               SZ_Write (sb, (unsigned char *)s, (int)strlen(s));
+}
+
+void MSG_WriteCoord13i (sizebuf_t *sb, float f)
+{
+       if (f >= 0)
+               MSG_WriteShort (sb, (int)(f * 8.0 + 0.5));
+       else
+               MSG_WriteShort (sb, (int)(f * 8.0 - 0.5));
+}
+
+void MSG_WriteCoord16i (sizebuf_t *sb, float f)
+{
+       if (f >= 0)
+               MSG_WriteShort (sb, (int)(f + 0.5));
+       else
+               MSG_WriteShort (sb, (int)(f - 0.5));
+}
+
+void MSG_WriteCoord32f (sizebuf_t *sb, float f)
+{
+       MSG_WriteFloat (sb, f);
+}
+
+void MSG_WriteCoord (sizebuf_t *sb, float f, protocolversion_t protocol)
+{
+       if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_NEHAHRABJP || protocol == PROTOCOL_NEHAHRABJP2 || protocol == PROTOCOL_NEHAHRABJP3 || protocol == PROTOCOL_QUAKEWORLD)
+               MSG_WriteCoord13i (sb, f);
+       else if (protocol == PROTOCOL_DARKPLACES1)
+               MSG_WriteCoord32f (sb, f);
+       else if (protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4)
+               MSG_WriteCoord16i (sb, f);
+       else
+               MSG_WriteCoord32f (sb, f);
+}
+
+void MSG_WriteVector (sizebuf_t *sb, const vec3_t v, protocolversion_t protocol)
+{
+       MSG_WriteCoord (sb, v[0], protocol);
+       MSG_WriteCoord (sb, v[1], protocol);
+       MSG_WriteCoord (sb, v[2], protocol);
+}
+
+// LadyHavoc: round to nearest value, rather than rounding toward zero, fixes crosshair problem
+void MSG_WriteAngle8i (sizebuf_t *sb, float f)
+{
+       if (f >= 0)
+               MSG_WriteByte (sb, (int)(f*(256.0/360.0) + 0.5) & 255);
+       else
+               MSG_WriteByte (sb, (int)(f*(256.0/360.0) - 0.5) & 255);
+}
+
+void MSG_WriteAngle16i (sizebuf_t *sb, float f)
+{
+       if (f >= 0)
+               MSG_WriteShort (sb, (int)(f*(65536.0/360.0) + 0.5) & 65535);
+       else
+               MSG_WriteShort (sb, (int)(f*(65536.0/360.0) - 0.5) & 65535);
+}
+
+void MSG_WriteAngle32f (sizebuf_t *sb, float f)
+{
+       MSG_WriteFloat (sb, f);
+}
+
+void MSG_WriteAngle (sizebuf_t *sb, float f, protocolversion_t protocol)
+{
+       if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_NEHAHRABJP || protocol == PROTOCOL_NEHAHRABJP2 || protocol == PROTOCOL_NEHAHRABJP3 || protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4 || protocol == PROTOCOL_QUAKEWORLD)
+               MSG_WriteAngle8i (sb, f);
+       else
+               MSG_WriteAngle16i (sb, f);
+}
+
+//
+// reading functions
+//
+
+void MSG_InitReadBuffer (sizebuf_t *buf, unsigned char *data, int size)
+{
+       memset(buf, 0, sizeof(*buf));
+       buf->data = data;
+       buf->maxsize = buf->cursize = size;
+       MSG_BeginReading(buf);
+}
+
+void MSG_BeginReading(sizebuf_t *sb)
+{
+       sb->readcount = 0;
+       sb->badread = false;
+}
+
+int MSG_ReadLittleShort(sizebuf_t *sb)
+{
+       if (sb->readcount+2 > sb->cursize)
+       {
+               sb->badread = true;
+               return -1;
+       }
+       sb->readcount += 2;
+       return (short)(sb->data[sb->readcount-2] | (sb->data[sb->readcount-1]<<8));
+}
+
+int MSG_ReadBigShort (sizebuf_t *sb)
+{
+       if (sb->readcount+2 > sb->cursize)
+       {
+               sb->badread = true;
+               return -1;
+       }
+       sb->readcount += 2;
+       return (short)((sb->data[sb->readcount-2]<<8) + sb->data[sb->readcount-1]);
+}
+
+int MSG_ReadLittleLong (sizebuf_t *sb)
+{
+       if (sb->readcount+4 > sb->cursize)
+       {
+               sb->badread = true;
+               return -1;
+       }
+       sb->readcount += 4;
+       return sb->data[sb->readcount-4] | (sb->data[sb->readcount-3]<<8) | (sb->data[sb->readcount-2]<<16) | (sb->data[sb->readcount-1]<<24);
+}
+
+int MSG_ReadBigLong (sizebuf_t *sb)
+{
+       if (sb->readcount+4 > sb->cursize)
+       {
+               sb->badread = true;
+               return -1;
+       }
+       sb->readcount += 4;
+       return (sb->data[sb->readcount-4]<<24) + (sb->data[sb->readcount-3]<<16) + (sb->data[sb->readcount-2]<<8) + sb->data[sb->readcount-1];
+}
+
+float MSG_ReadLittleFloat (sizebuf_t *sb)
+{
+       union
+       {
+               float f;
+               int l;
+       } dat;
+       if (sb->readcount+4 > sb->cursize)
+       {
+               sb->badread = true;
+               return -1;
+       }
+       sb->readcount += 4;
+       dat.l = sb->data[sb->readcount-4] | (sb->data[sb->readcount-3]<<8) | (sb->data[sb->readcount-2]<<16) | (sb->data[sb->readcount-1]<<24);
+       return dat.f;
+}
+
+float MSG_ReadBigFloat (sizebuf_t *sb)
+{
+       union
+       {
+               float f;
+               int l;
+       } dat;
+       if (sb->readcount+4 > sb->cursize)
+       {
+               sb->badread = true;
+               return -1;
+       }
+       sb->readcount += 4;
+       dat.l = (sb->data[sb->readcount-4]<<24) | (sb->data[sb->readcount-3]<<16) | (sb->data[sb->readcount-2]<<8) | sb->data[sb->readcount-1];
+       return dat.f;
+}
+
+char *MSG_ReadString (sizebuf_t *sb, char *string, size_t maxstring)
+{
+       int c;
+       size_t l = 0;
+       // read string into sbfer, but only store as many characters as will fit
+       while ((c = MSG_ReadByte(sb)) > 0)
+               if (l < maxstring - 1)
+                       string[l++] = c;
+       string[l] = 0;
+       return string;
+}
+
+int MSG_ReadBytes (sizebuf_t *sb, int numbytes, unsigned char *out)
+{
+       int l, c;
+       for (l = 0;l < numbytes && (c = MSG_ReadByte(sb)) != -1;l++)
+               out[l] = c;
+       return l;
+}
+
+float MSG_ReadCoord13i (sizebuf_t *sb)
+{
+       return MSG_ReadLittleShort(sb) * (1.0/8.0);
+}
+
+float MSG_ReadCoord16i (sizebuf_t *sb)
+{
+       return (signed short) MSG_ReadLittleShort(sb);
+}
+
+float MSG_ReadCoord32f (sizebuf_t *sb)
+{
+       return MSG_ReadLittleFloat(sb);
+}
+
+float MSG_ReadCoord (sizebuf_t *sb, protocolversion_t protocol)
+{
+       if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_NEHAHRABJP || protocol == PROTOCOL_NEHAHRABJP2 || protocol == PROTOCOL_NEHAHRABJP3 || protocol == PROTOCOL_QUAKEWORLD)
+               return MSG_ReadCoord13i(sb);
+       else if (protocol == PROTOCOL_DARKPLACES1)
+               return MSG_ReadCoord32f(sb);
+       else if (protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4)
+               return MSG_ReadCoord16i(sb);
+       else
+               return MSG_ReadCoord32f(sb);
+}
+
+void MSG_ReadVector (sizebuf_t *sb, vec3_t v, protocolversion_t protocol)
+{
+       v[0] = MSG_ReadCoord(sb, protocol);
+       v[1] = MSG_ReadCoord(sb, protocol);
+       v[2] = MSG_ReadCoord(sb, protocol);
+}
+
+// LadyHavoc: round to nearest value, rather than rounding toward zero, fixes crosshair problem
+float MSG_ReadAngle8i (sizebuf_t *sb)
+{
+       return (signed char) MSG_ReadByte (sb) * (360.0/256.0);
+}
+
+float MSG_ReadAngle16i (sizebuf_t *sb)
+{
+       return (signed short)MSG_ReadShort (sb) * (360.0/65536.0);
+}
+
+float MSG_ReadAngle32f (sizebuf_t *sb)
+{
+       return MSG_ReadFloat (sb);
+}
+
+float MSG_ReadAngle (sizebuf_t *sb, protocolversion_t protocol)
+{
+       if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_NEHAHRABJP || protocol == PROTOCOL_NEHAHRABJP2 || protocol == PROTOCOL_NEHAHRABJP3 || protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4 || protocol == PROTOCOL_QUAKEWORLD)
+               return MSG_ReadAngle8i (sb);
+       else
+               return MSG_ReadAngle16i (sb);
+}
\ No newline at end of file