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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 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