• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3 
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.
8 
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.
12 
13 See the GNU General Public License for more details.
14 
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.
18 
19 */
20 // sv_nchan.c, user reliable data stream writes
21 
22 #include "qwsvdef.h"
23 
24 // check to see if client block will fit, if not, rotate buffers
ClientReliableCheckBlock(client_t * cl,int maxsize)25 void ClientReliableCheckBlock(client_t *cl, int maxsize)
26 {
27 	if (cl->num_backbuf ||
28 		cl->netchan.message.cursize >
29 		cl->netchan.message.maxsize - maxsize - 1) {
30 		// we would probably overflow the buffer, save it for next
31 		if (!cl->num_backbuf) {
32 			memset(&cl->backbuf, 0, sizeof(cl->backbuf));
33 			cl->backbuf.allowoverflow = true;
34 			cl->backbuf.data = cl->backbuf_data[0];
35 			cl->backbuf.maxsize = sizeof(cl->backbuf_data[0]);
36 			cl->backbuf_size[0] = 0;
37 			cl->num_backbuf++;
38 		}
39 
40 		if (cl->backbuf.cursize > cl->backbuf.maxsize - maxsize - 1) {
41 			if (cl->num_backbuf == MAX_BACK_BUFFERS) {
42 				Con_Printf ("WARNING: MAX_BACK_BUFFERS for %s\n", cl->name);
43 				cl->backbuf.cursize = 0; // don't overflow without allowoverflow set
44 				cl->netchan.message.overflowed = true; // this will drop the client
45 				return;
46 			}
47 			memset(&cl->backbuf, 0, sizeof(cl->backbuf));
48 			cl->backbuf.allowoverflow = true;
49 			cl->backbuf.data = cl->backbuf_data[cl->num_backbuf];
50 			cl->backbuf.maxsize = sizeof(cl->backbuf_data[cl->num_backbuf]);
51 			cl->backbuf_size[cl->num_backbuf] = 0;
52 			cl->num_backbuf++;
53 		}
54 	}
55 }
56 
57 // begin a client block, estimated maximum size
ClientReliableWrite_Begin(client_t * cl,int c,int maxsize)58 void ClientReliableWrite_Begin(client_t *cl, int c, int maxsize)
59 {
60 	ClientReliableCheckBlock(cl, maxsize);
61 	ClientReliableWrite_Byte(cl, c);
62 }
63 
ClientReliable_FinishWrite(client_t * cl)64 void ClientReliable_FinishWrite(client_t *cl)
65 {
66 	if (cl->num_backbuf) {
67 		cl->backbuf_size[cl->num_backbuf - 1] = cl->backbuf.cursize;
68 
69 		if (cl->backbuf.overflowed) {
70 			Con_Printf ("WARNING: backbuf [%d] reliable overflow for %s\n",cl->num_backbuf,cl->name);
71 			cl->netchan.message.overflowed = true; // this will drop the client
72 		}
73 	}
74 }
75 
ClientReliableWrite_Angle(client_t * cl,float f)76 void ClientReliableWrite_Angle(client_t *cl, float f)
77 {
78 	if (cl->num_backbuf) {
79 		MSG_WriteAngle(&cl->backbuf, f);
80 		ClientReliable_FinishWrite(cl);
81 	} else
82 		MSG_WriteAngle(&cl->netchan.message, f);
83 }
84 
ClientReliableWrite_Angle16(client_t * cl,float f)85 void ClientReliableWrite_Angle16(client_t *cl, float f)
86 {
87 	if (cl->num_backbuf) {
88 		MSG_WriteAngle16(&cl->backbuf, f);
89 		ClientReliable_FinishWrite(cl);
90 	} else
91 		MSG_WriteAngle16(&cl->netchan.message, f);
92 }
93 
ClientReliableWrite_Byte(client_t * cl,int c)94 void ClientReliableWrite_Byte(client_t *cl, int c)
95 {
96 	if (cl->num_backbuf) {
97 		MSG_WriteByte(&cl->backbuf, c);
98 		ClientReliable_FinishWrite(cl);
99 	} else
100 		MSG_WriteByte(&cl->netchan.message, c);
101 }
102 
ClientReliableWrite_Char(client_t * cl,int c)103 void ClientReliableWrite_Char(client_t *cl, int c)
104 {
105 	if (cl->num_backbuf) {
106 		MSG_WriteChar(&cl->backbuf, c);
107 		ClientReliable_FinishWrite(cl);
108 	} else
109 		MSG_WriteChar(&cl->netchan.message, c);
110 }
111 
ClientReliableWrite_Float(client_t * cl,float f)112 void ClientReliableWrite_Float(client_t *cl, float f)
113 {
114 	if (cl->num_backbuf) {
115 		MSG_WriteFloat(&cl->backbuf, f);
116 		ClientReliable_FinishWrite(cl);
117 	} else
118 		MSG_WriteFloat(&cl->netchan.message, f);
119 }
120 
ClientReliableWrite_Coord(client_t * cl,float f)121 void ClientReliableWrite_Coord(client_t *cl, float f)
122 {
123 	if (cl->num_backbuf) {
124 		MSG_WriteCoord(&cl->backbuf, f);
125 		ClientReliable_FinishWrite(cl);
126 	} else
127 		MSG_WriteCoord(&cl->netchan.message, f);
128 }
129 
ClientReliableWrite_Long(client_t * cl,int c)130 void ClientReliableWrite_Long(client_t *cl, int c)
131 {
132 	if (cl->num_backbuf) {
133 		MSG_WriteLong(&cl->backbuf, c);
134 		ClientReliable_FinishWrite(cl);
135 	} else
136 		MSG_WriteLong(&cl->netchan.message, c);
137 }
138 
ClientReliableWrite_Short(client_t * cl,int c)139 void ClientReliableWrite_Short(client_t *cl, int c)
140 {
141 	if (cl->num_backbuf) {
142 		MSG_WriteShort(&cl->backbuf, c);
143 		ClientReliable_FinishWrite(cl);
144 	} else
145 		MSG_WriteShort(&cl->netchan.message, c);
146 }
147 
ClientReliableWrite_String(client_t * cl,char * s)148 void ClientReliableWrite_String(client_t *cl, char *s)
149 {
150 	if (cl->num_backbuf) {
151 		MSG_WriteString(&cl->backbuf, s);
152 		ClientReliable_FinishWrite(cl);
153 	} else
154 		MSG_WriteString(&cl->netchan.message, s);
155 }
156 
ClientReliableWrite_SZ(client_t * cl,void * data,int len)157 void ClientReliableWrite_SZ(client_t *cl, void *data, int len)
158 {
159 	if (cl->num_backbuf) {
160 		SZ_Write(&cl->backbuf, data, len);
161 		ClientReliable_FinishWrite(cl);
162 	} else
163 		SZ_Write(&cl->netchan.message, data, len);
164 }
165 
166