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
21 #include "qwsvdef.h"
22
23 server_static_t svs; // persistant server info
24 server_t sv; // local server
25
26 char localmodels[MAX_MODELS][5]; // inline model names for precache
27
28 char localinfo[MAX_LOCALINFO_STRING+1]; // local game info
29
30 /*
31 ================
32 SV_ModelIndex
33
34 ================
35 */
SV_ModelIndex(char * name)36 int SV_ModelIndex (char *name)
37 {
38 int i;
39
40 if (!name || !name[0])
41 return 0;
42
43 for (i=0 ; i<MAX_MODELS && sv.model_precache[i] ; i++)
44 if (!strcmp(sv.model_precache[i], name))
45 return i;
46 if (i==MAX_MODELS || !sv.model_precache[i])
47 SV_Error ("SV_ModelIndex: model %s not precached", name);
48 return i;
49 }
50
51 /*
52 ================
53 SV_FlushSignon
54
55 Moves to the next signon buffer if needed
56 ================
57 */
SV_FlushSignon(void)58 void SV_FlushSignon (void)
59 {
60 if (sv.signon.cursize < sv.signon.maxsize - 512)
61 return;
62
63 if (sv.num_signon_buffers == MAX_SIGNON_BUFFERS-1)
64 SV_Error ("sv.num_signon_buffers == MAX_SIGNON_BUFFERS-1");
65
66 sv.signon_buffer_size[sv.num_signon_buffers-1] = sv.signon.cursize;
67 sv.signon.data = sv.signon_buffers[sv.num_signon_buffers];
68 sv.num_signon_buffers++;
69 sv.signon.cursize = 0;
70 }
71
72 /*
73 ================
74 SV_CreateBaseline
75
76 Entity baselines are used to compress the update messages
77 to the clients -- only the fields that differ from the
78 baseline will be transmitted
79 ================
80 */
SV_CreateBaseline(void)81 void SV_CreateBaseline (void)
82 {
83 int i;
84 edict_t *svent;
85 int entnum;
86
87 for (entnum = 0; entnum < sv.num_edicts ; entnum++)
88 {
89 svent = EDICT_NUM(entnum);
90 if (svent->free)
91 continue;
92 // create baselines for all player slots,
93 // and any other edict that has a visible model
94 if (entnum > MAX_CLIENTS && !svent->v.modelindex)
95 continue;
96
97 //
98 // create entity baseline
99 //
100 VectorCopy (svent->v.origin, svent->baseline.origin);
101 VectorCopy (svent->v.angles, svent->baseline.angles);
102 svent->baseline.frame = svent->v.frame;
103 svent->baseline.skinnum = svent->v.skin;
104 if (entnum > 0 && entnum <= MAX_CLIENTS)
105 {
106 svent->baseline.colormap = entnum;
107 svent->baseline.modelindex = SV_ModelIndex("progs/player.mdl");
108 }
109 else
110 {
111 svent->baseline.colormap = 0;
112 svent->baseline.modelindex =
113 SV_ModelIndex(PR_GetString(svent->v.model));
114 }
115
116 //
117 // flush the signon message out to a seperate buffer if
118 // nearly full
119 //
120 SV_FlushSignon ();
121
122 //
123 // add to the message
124 //
125 MSG_WriteByte (&sv.signon,svc_spawnbaseline);
126 MSG_WriteShort (&sv.signon,entnum);
127
128 MSG_WriteByte (&sv.signon, svent->baseline.modelindex);
129 MSG_WriteByte (&sv.signon, svent->baseline.frame);
130 MSG_WriteByte (&sv.signon, svent->baseline.colormap);
131 MSG_WriteByte (&sv.signon, svent->baseline.skinnum);
132 for (i=0 ; i<3 ; i++)
133 {
134 MSG_WriteCoord(&sv.signon, svent->baseline.origin[i]);
135 MSG_WriteAngle(&sv.signon, svent->baseline.angles[i]);
136 }
137 }
138 }
139
140
141 /*
142 ================
143 SV_SaveSpawnparms
144
145 Grabs the current state of the progs serverinfo flags
146 and each client for saving across the
147 transition to another level
148 ================
149 */
SV_SaveSpawnparms(void)150 void SV_SaveSpawnparms (void)
151 {
152 int i, j;
153
154 if (!sv.state)
155 return; // no progs loaded yet
156
157 // serverflags is the only game related thing maintained
158 svs.serverflags = pr_global_struct->serverflags;
159
160 for (i=0, host_client = svs.clients ; i<MAX_CLIENTS ; i++, host_client++)
161 {
162 if (host_client->state != cs_spawned)
163 continue;
164
165 // needs to reconnect
166 host_client->state = cs_connected;
167
168 // call the progs to get default spawn parms for the new client
169 pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
170 PR_ExecuteProgram (pr_global_struct->SetChangeParms);
171 for (j=0 ; j<NUM_SPAWN_PARMS ; j++)
172 host_client->spawn_parms[j] = (&pr_global_struct->parm1)[j];
173 }
174 }
175
176 /*
177 ================
178 SV_CalcPHS
179
180 Expands the PVS and calculates the PHS
181 (Potentially Hearable Set)
182 ================
183 */
SV_CalcPHS(void)184 void SV_CalcPHS (void)
185 {
186 int rowbytes, rowwords;
187 int i, j, k, l, index, num;
188 int bitbyte;
189 unsigned *dest, *src;
190 byte *scan;
191 int count, vcount;
192
193 Con_Printf ("Building PHS...\n");
194
195 num = sv.worldmodel->numleafs;
196 rowwords = (num+31)>>5;
197 rowbytes = rowwords*4;
198
199 sv.pvs = Hunk_Alloc (rowbytes*num);
200 scan = sv.pvs;
201 vcount = 0;
202 for (i=0 ; i<num ; i++, scan+=rowbytes)
203 {
204 memcpy (scan, Mod_LeafPVS(sv.worldmodel->leafs+i, sv.worldmodel),
205 rowbytes);
206 if (i == 0)
207 continue;
208 for (j=0 ; j<num ; j++)
209 {
210 if ( scan[j>>3] & (1<<(j&7)) )
211 {
212 vcount++;
213 }
214 }
215 }
216
217
218 sv.phs = Hunk_Alloc (rowbytes*num);
219 count = 0;
220 scan = sv.pvs;
221 dest = (unsigned *)sv.phs;
222 for (i=0 ; i<num ; i++, dest += rowwords, scan += rowbytes)
223 {
224 memcpy (dest, scan, rowbytes);
225 for (j=0 ; j<rowbytes ; j++)
226 {
227 bitbyte = scan[j];
228 if (!bitbyte)
229 continue;
230 for (k=0 ; k<8 ; k++)
231 {
232 if (! (bitbyte & (1<<k)) )
233 continue;
234 // or this pvs row into the phs
235 // +1 because pvs is 1 based
236 index = ((j<<3)+k+1);
237 if (index >= num)
238 continue;
239 src = (unsigned *)sv.pvs + index*rowwords;
240 for (l=0 ; l<rowwords ; l++)
241 dest[l] |= src[l];
242 }
243 }
244
245 if (i == 0)
246 continue;
247 for (j=0 ; j<num ; j++)
248 if ( ((byte *)dest)[j>>3] & (1<<(j&7)) )
249 count++;
250 }
251
252 Con_Printf ("Average leafs visible / hearable / total: %i / %i / %i\n"
253 , vcount/num, count/num, num);
254 }
255
SV_CheckModel(char * mdl)256 unsigned SV_CheckModel(char *mdl)
257 {
258 byte stackbuf[1024]; // avoid dirtying the cache heap
259 byte *buf;
260 unsigned short crc;
261 // int len;
262
263 buf = (byte *)COM_LoadStackFile (mdl, stackbuf, sizeof(stackbuf));
264 crc = CRC_Block(buf, com_filesize);
265 // for (len = com_filesize; len; len--, buf++)
266 // CRC_ProcessByte(&crc, *buf);
267
268 return crc;
269 }
270
271 /*
272 ================
273 SV_SpawnServer
274
275 Change the server to a new map, taking all connected
276 clients along with it.
277
278 This is only called from the SV_Map_f() function.
279 ================
280 */
SV_SpawnServer(char * server)281 void SV_SpawnServer (char *server)
282 {
283 edict_t *ent;
284 int i;
285
286 Con_DPrintf ("SpawnServer: %s\n",server);
287
288 SV_SaveSpawnparms ();
289
290 svs.spawncount++; // any partially connected client will be
291 // restarted
292
293 sv.state = ss_dead;
294
295 Mod_ClearAll ();
296 Hunk_FreeToLowMark (host_hunklevel);
297
298 // wipe the entire per-level structure
299 memset (&sv, 0, sizeof(sv));
300
301 sv.datagram.maxsize = sizeof(sv.datagram_buf);
302 sv.datagram.data = sv.datagram_buf;
303 sv.datagram.allowoverflow = true;
304
305 sv.reliable_datagram.maxsize = sizeof(sv.reliable_datagram_buf);
306 sv.reliable_datagram.data = sv.reliable_datagram_buf;
307
308 sv.multicast.maxsize = sizeof(sv.multicast_buf);
309 sv.multicast.data = sv.multicast_buf;
310
311 sv.master.maxsize = sizeof(sv.master_buf);
312 sv.master.data = sv.master_buf;
313
314 sv.signon.maxsize = sizeof(sv.signon_buffers[0]);
315 sv.signon.data = sv.signon_buffers[0];
316 sv.num_signon_buffers = 1;
317
318 strcpy (sv.name, server);
319
320 // load progs to get entity field count
321 // which determines how big each edict is
322 PR_LoadProgs ();
323
324 // allocate edicts
325 sv.edicts = Hunk_AllocName (MAX_EDICTS*pr_edict_size, "edicts");
326
327 // leave slots at start for clients only
328 sv.num_edicts = MAX_CLIENTS+1;
329 for (i=0 ; i<MAX_CLIENTS ; i++)
330 {
331 ent = EDICT_NUM(i+1);
332 svs.clients[i].edict = ent;
333 //ZOID - make sure we update frags right
334 svs.clients[i].old_frags = 0;
335 }
336
337 sv.time = 1.0;
338
339 strcpy (sv.name, server);
340 sprintf (sv.modelname,"maps/%s.bsp", server);
341 sv.worldmodel = Mod_ForName (sv.modelname, true);
342 SV_CalcPHS ();
343
344 //
345 // clear physics interaction links
346 //
347 SV_ClearWorld ();
348
349 sv.sound_precache[0] = pr_strings;
350
351 sv.model_precache[0] = pr_strings;
352 sv.model_precache[1] = sv.modelname;
353 sv.models[1] = sv.worldmodel;
354 for (i=1 ; i<sv.worldmodel->numsubmodels ; i++)
355 {
356 sv.model_precache[1+i] = localmodels[i];
357 sv.models[i+1] = Mod_ForName (localmodels[i], false);
358 }
359
360 //check player/eyes models for hacks
361 sv.model_player_checksum = SV_CheckModel("progs/player.mdl");
362 sv.eyes_player_checksum = SV_CheckModel("progs/eyes.mdl");
363
364 //
365 // spawn the rest of the entities on the map
366 //
367
368 // precache and static commands can be issued during
369 // map initialization
370 sv.state = ss_loading;
371
372 ent = EDICT_NUM(0);
373 ent->free = false;
374 ent->v.model = PR_SetString(sv.worldmodel->name);
375 ent->v.modelindex = 1; // world model
376 ent->v.solid = SOLID_BSP;
377 ent->v.movetype = MOVETYPE_PUSH;
378
379 pr_global_struct->mapname = PR_SetString(sv.name);
380 // serverflags are for cross level information (sigils)
381 pr_global_struct->serverflags = svs.serverflags;
382
383 // run the frame start qc function to let progs check cvars
384 SV_ProgStartFrame ();
385
386 // load and spawn all other entities
387 ED_LoadFromFile (sv.worldmodel->entities);
388
389 // look up some model indexes for specialized message compression
390 SV_FindModelNumbers ();
391
392 // all spawning is completed, any further precache statements
393 // or prog writes to the signon message are errors
394 sv.state = ss_active;
395
396 // run two frames to allow everything to settle
397 host_frametime = 0.1;
398 SV_Physics ();
399 SV_Physics ();
400
401 // save movement vars
402 SV_SetMoveVars();
403
404 // create a baseline for more efficient communications
405 SV_CreateBaseline ();
406 sv.signon_buffer_size[sv.num_signon_buffers-1] = sv.signon.cursize;
407
408 Info_SetValueForKey (svs.info, "map", sv.name, MAX_SERVERINFO_STRING);
409 Con_DPrintf ("Server spawned.\n");
410 }
411
412