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