2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 ============================================================================
29 ============================================================================
33 float BuffBigFloat (const unsigned char *buffer)
41 u.i = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
45 int BuffBigLong (const unsigned char *buffer)
47 return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
50 short BuffBigShort (const unsigned char *buffer)
52 return (buffer[0] << 8) | buffer[1];
55 float BuffLittleFloat (const unsigned char *buffer)
63 u.i = (buffer[3] << 24) | (buffer[2] << 16) | (buffer[1] << 8) | buffer[0];
67 int BuffLittleLong (const unsigned char *buffer)
69 return (buffer[3] << 24) | (buffer[2] << 16) | (buffer[1] << 8) | buffer[0];
72 short BuffLittleShort (const unsigned char *buffer)
74 return (buffer[1] << 8) | buffer[0];
77 void StoreBigLong (unsigned char *buffer, unsigned int i)
79 buffer[0] = (i >> 24) & 0xFF;
80 buffer[1] = (i >> 16) & 0xFF;
81 buffer[2] = (i >> 8) & 0xFF;
85 void StoreBigShort (unsigned char *buffer, unsigned short i)
87 buffer[0] = (i >> 8) & 0xFF;
91 void StoreLittleLong (unsigned char *buffer, unsigned int i)
94 buffer[1] = (i >> 8) & 0xFF;
95 buffer[2] = (i >> 16) & 0xFF;
96 buffer[3] = (i >> 24) & 0xFF;
99 void StoreLittleShort (unsigned char *buffer, unsigned short i)
101 buffer[0] = i & 0xFF;
102 buffer[1] = (i >> 8) & 0xFF;
106 ==============================================================================
110 Handles byte ordering and avoids alignment errors
111 ==============================================================================
118 void MSG_WriteChar (sizebuf_t *sb, int c)
122 buf = SZ_GetSpace (sb, 1);
126 void MSG_WriteByte (sizebuf_t *sb, int c)
130 buf = SZ_GetSpace (sb, 1);
134 void MSG_WriteShort (sizebuf_t *sb, int c)
138 buf = SZ_GetSpace (sb, 2);
143 void MSG_WriteLong (sizebuf_t *sb, int c)
147 buf = SZ_GetSpace (sb, 4);
149 buf[1] = (c>>8)&0xff;
150 buf[2] = (c>>16)&0xff;
154 void MSG_WriteFloat (sizebuf_t *sb, float f)
164 dat.l = LittleLong (dat.l);
166 SZ_Write (sb, (unsigned char *)&dat.l, 4);
169 void MSG_WriteString (sizebuf_t *sb, const char *s)
172 MSG_WriteChar (sb, 0);
174 SZ_Write (sb, (unsigned char *)s, (int)strlen(s)+1);
177 void MSG_WriteUnterminatedString (sizebuf_t *sb, const char *s)
180 SZ_Write (sb, (unsigned char *)s, (int)strlen(s));
183 void MSG_WriteCoord13i (sizebuf_t *sb, float f)
186 MSG_WriteShort (sb, (int)(f * 8.0 + 0.5));
188 MSG_WriteShort (sb, (int)(f * 8.0 - 0.5));
191 void MSG_WriteCoord16i (sizebuf_t *sb, float f)
194 MSG_WriteShort (sb, (int)(f + 0.5));
196 MSG_WriteShort (sb, (int)(f - 0.5));
199 void MSG_WriteCoord32f (sizebuf_t *sb, float f)
201 MSG_WriteFloat (sb, f);
204 void MSG_WriteCoord (sizebuf_t *sb, float f, protocolversion_t protocol)
206 if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_NEHAHRABJP || protocol == PROTOCOL_NEHAHRABJP2 || protocol == PROTOCOL_NEHAHRABJP3 || protocol == PROTOCOL_QUAKEWORLD)
207 MSG_WriteCoord13i (sb, f);
208 else if (protocol == PROTOCOL_DARKPLACES1)
209 MSG_WriteCoord32f (sb, f);
210 else if (protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4)
211 MSG_WriteCoord16i (sb, f);
213 MSG_WriteCoord32f (sb, f);
216 void MSG_WriteVector (sizebuf_t *sb, const vec3_t v, protocolversion_t protocol)
218 MSG_WriteCoord (sb, v[0], protocol);
219 MSG_WriteCoord (sb, v[1], protocol);
220 MSG_WriteCoord (sb, v[2], protocol);
223 // LadyHavoc: round to nearest value, rather than rounding toward zero, fixes crosshair problem
224 void MSG_WriteAngle8i (sizebuf_t *sb, float f)
227 MSG_WriteByte (sb, (int)(f*(256.0/360.0) + 0.5) & 255);
229 MSG_WriteByte (sb, (int)(f*(256.0/360.0) - 0.5) & 255);
232 void MSG_WriteAngle16i (sizebuf_t *sb, float f)
235 MSG_WriteShort (sb, (int)(f*(65536.0/360.0) + 0.5) & 65535);
237 MSG_WriteShort (sb, (int)(f*(65536.0/360.0) - 0.5) & 65535);
240 void MSG_WriteAngle32f (sizebuf_t *sb, float f)
242 MSG_WriteFloat (sb, f);
245 void MSG_WriteAngle (sizebuf_t *sb, float f, protocolversion_t protocol)
247 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)
248 MSG_WriteAngle8i (sb, f);
250 MSG_WriteAngle16i (sb, f);
257 void MSG_InitReadBuffer (sizebuf_t *buf, unsigned char *data, int size)
259 memset(buf, 0, sizeof(*buf));
261 buf->maxsize = buf->cursize = size;
262 MSG_BeginReading(buf);
265 void MSG_BeginReading(sizebuf_t *sb)
271 int MSG_ReadLittleShort(sizebuf_t *sb)
273 if (sb->readcount+2 > sb->cursize)
279 return (short)(sb->data[sb->readcount-2] | (sb->data[sb->readcount-1]<<8));
282 int MSG_ReadBigShort (sizebuf_t *sb)
284 if (sb->readcount+2 > sb->cursize)
290 return (short)((sb->data[sb->readcount-2]<<8) + sb->data[sb->readcount-1]);
293 int MSG_ReadLittleLong (sizebuf_t *sb)
295 if (sb->readcount+4 > sb->cursize)
301 return sb->data[sb->readcount-4] | (sb->data[sb->readcount-3]<<8) | (sb->data[sb->readcount-2]<<16) | (sb->data[sb->readcount-1]<<24);
304 int MSG_ReadBigLong (sizebuf_t *sb)
306 if (sb->readcount+4 > sb->cursize)
312 return (sb->data[sb->readcount-4]<<24) + (sb->data[sb->readcount-3]<<16) + (sb->data[sb->readcount-2]<<8) + sb->data[sb->readcount-1];
315 float MSG_ReadLittleFloat (sizebuf_t *sb)
322 if (sb->readcount+4 > sb->cursize)
328 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);
332 float MSG_ReadBigFloat (sizebuf_t *sb)
339 if (sb->readcount+4 > sb->cursize)
345 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];
349 char *MSG_ReadString (sizebuf_t *sb, char *string, size_t maxstring)
353 // read string into sbfer, but only store as many characters as will fit
354 while ((c = MSG_ReadByte(sb)) > 0)
355 if (l < maxstring - 1)
361 int MSG_ReadBytes (sizebuf_t *sb, int numbytes, unsigned char *out)
364 for (l = 0;l < numbytes && (c = MSG_ReadByte(sb)) != -1;l++)
369 float MSG_ReadCoord13i (sizebuf_t *sb)
371 return MSG_ReadLittleShort(sb) * (1.0/8.0);
374 float MSG_ReadCoord16i (sizebuf_t *sb)
376 return (signed short) MSG_ReadLittleShort(sb);
379 float MSG_ReadCoord32f (sizebuf_t *sb)
381 return MSG_ReadLittleFloat(sb);
384 float MSG_ReadCoord (sizebuf_t *sb, protocolversion_t protocol)
386 if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_NEHAHRABJP || protocol == PROTOCOL_NEHAHRABJP2 || protocol == PROTOCOL_NEHAHRABJP3 || protocol == PROTOCOL_QUAKEWORLD)
387 return MSG_ReadCoord13i(sb);
388 else if (protocol == PROTOCOL_DARKPLACES1)
389 return MSG_ReadCoord32f(sb);
390 else if (protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4)
391 return MSG_ReadCoord16i(sb);
393 return MSG_ReadCoord32f(sb);
396 void MSG_ReadVector (sizebuf_t *sb, vec3_t v, protocolversion_t protocol)
398 v[0] = MSG_ReadCoord(sb, protocol);
399 v[1] = MSG_ReadCoord(sb, protocol);
400 v[2] = MSG_ReadCoord(sb, protocol);
403 // LadyHavoc: round to nearest value, rather than rounding toward zero, fixes crosshair problem
404 float MSG_ReadAngle8i (sizebuf_t *sb)
406 return (signed char) MSG_ReadByte (sb) * (360.0/256.0);
409 float MSG_ReadAngle16i (sizebuf_t *sb)
411 return (signed short)MSG_ReadShort (sb) * (360.0/65536.0);
414 float MSG_ReadAngle32f (sizebuf_t *sb)
416 return MSG_ReadFloat (sb);
419 float MSG_ReadAngle (sizebuf_t *sb, protocolversion_t protocol)
421 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)
422 return MSG_ReadAngle8i (sb);
424 return MSG_ReadAngle16i (sb);