home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quakeworld_src / server / sv_init.c < prev    next >
C/C++ Source or Header  |  2000-06-17  |  10KB  |  412 lines

  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.