Annotation of quake2/server/sv_game.c, revision 1.1.1.3

1.1.1.3 ! root        1: /*
        !             2: Copyright (C) 1997-2001 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: */
1.1       root       20: // sv_game.c -- interface to the game dll
                     21: 
                     22: #include "server.h"
                     23: 
                     24: game_export_t  *ge;
                     25: 
                     26: 
                     27: /*
                     28: ===============
                     29: PF_Unicast
                     30: 
                     31: Sends the contents of the mutlicast buffer to a single client
                     32: ===============
                     33: */
                     34: void PF_Unicast (edict_t *ent, qboolean reliable)
                     35: {
                     36:        int             p;
                     37:        client_t        *client;
                     38: 
                     39:        if (!ent)
                     40:                return;
                     41: 
                     42:        p = NUM_FOR_EDICT(ent);
                     43:        if (p < 1 || p > maxclients->value)
                     44:                return;
                     45: 
                     46:        client = svs.clients + (p-1);
                     47: 
                     48:        if (reliable)
                     49:                SZ_Write (&client->netchan.message, sv.multicast.data, sv.multicast.cursize);
                     50:        else
                     51:                SZ_Write (&client->datagram, sv.multicast.data, sv.multicast.cursize);
                     52: 
                     53:        SZ_Clear (&sv.multicast);
                     54: }
                     55: 
                     56: 
                     57: /*
                     58: ===============
                     59: PF_dprintf
                     60: 
                     61: Debug print to server console
                     62: ===============
                     63: */
                     64: void PF_dprintf (char *fmt, ...)
                     65: {
                     66:        char            msg[1024];
                     67:        va_list         argptr;
                     68:        
                     69:        va_start (argptr,fmt);
                     70:        vsprintf (msg, fmt, argptr);
                     71:        va_end (argptr);
                     72: 
                     73:        Com_Printf ("%s", msg);
                     74: }
                     75: 
                     76: 
                     77: /*
                     78: ===============
                     79: PF_cprintf
                     80: 
                     81: Print to a single client
                     82: ===============
                     83: */
                     84: void PF_cprintf (edict_t *ent, int level, char *fmt, ...)
                     85: {
                     86:        char            msg[1024];
                     87:        va_list         argptr;
                     88:        int                     n;
                     89: 
                     90:        if (ent)
                     91:        {
                     92:                n = NUM_FOR_EDICT(ent);
                     93:                if (n < 1 || n > maxclients->value)
                     94:                        Com_Error (ERR_DROP, "cprintf to a non-client");
                     95:        }
                     96: 
                     97:        va_start (argptr,fmt);
                     98:        vsprintf (msg, fmt, argptr);
                     99:        va_end (argptr);
                    100: 
                    101:        if (ent)
                    102:                SV_ClientPrintf (svs.clients+(n-1), level, "%s", msg);
                    103:        else
                    104:                Com_Printf ("%s", msg);
                    105: }
                    106: 
                    107: 
                    108: /*
                    109: ===============
                    110: PF_centerprintf
                    111: 
                    112: centerprint to a single client
                    113: ===============
                    114: */
                    115: void PF_centerprintf (edict_t *ent, char *fmt, ...)
                    116: {
                    117:        char            msg[1024];
                    118:        va_list         argptr;
                    119:        int                     n;
                    120:        
                    121:        n = NUM_FOR_EDICT(ent);
                    122:        if (n < 1 || n > maxclients->value)
                    123:                return; // Com_Error (ERR_DROP, "centerprintf to a non-client");
                    124: 
                    125:        va_start (argptr,fmt);
                    126:        vsprintf (msg, fmt, argptr);
                    127:        va_end (argptr);
                    128: 
                    129:        MSG_WriteByte (&sv.multicast,svc_centerprint);
                    130:        MSG_WriteString (&sv.multicast,msg);
                    131:        PF_Unicast (ent, true);
                    132: }
                    133: 
                    134: 
                    135: /*
                    136: ===============
                    137: PF_error
                    138: 
                    139: Abort the server with a game error
                    140: ===============
                    141: */
                    142: void PF_error (char *fmt, ...)
                    143: {
                    144:        char            msg[1024];
                    145:        va_list         argptr;
                    146:        
                    147:        va_start (argptr,fmt);
                    148:        vsprintf (msg, fmt, argptr);
                    149:        va_end (argptr);
                    150: 
                    151:        Com_Error (ERR_DROP, "Game Error: %s", msg);
                    152: }
                    153: 
                    154: 
                    155: /*
                    156: =================
                    157: PF_setmodel
                    158: 
                    159: Also sets mins and maxs for inline bmodels
                    160: =================
                    161: */
                    162: void PF_setmodel (edict_t *ent, char *name)
                    163: {
                    164:        int             i;
                    165:        cmodel_t        *mod;
                    166: 
                    167:        if (!name)
                    168:                Com_Error (ERR_DROP, "PF_setmodel: NULL");
                    169: 
                    170:        i = SV_ModelIndex (name);
                    171:                
                    172: //     ent->model = name;
                    173:        ent->s.modelindex = i;
                    174: 
                    175: // if it is an inline model, get the size information for it
                    176:        if (name[0] == '*')
                    177:        {
                    178:                mod = CM_InlineModel (name);
                    179:                VectorCopy (mod->mins, ent->mins);
                    180:                VectorCopy (mod->maxs, ent->maxs);
                    181:                SV_LinkEdict (ent);
                    182:        }
                    183: 
                    184: }
                    185: 
                    186: /*
                    187: ===============
                    188: PF_Configstring
                    189: 
                    190: ===============
                    191: */
                    192: void PF_Configstring (int index, char *val)
                    193: {
                    194:        if (index < 0 || index >= MAX_CONFIGSTRINGS)
                    195:                Com_Error (ERR_DROP, "configstring: bad index %i\n", index);
                    196: 
                    197:        if (!val)
                    198:                val = "";
                    199: 
                    200:        // change the string in sv
                    201:        strcpy (sv.configstrings[index], val);
1.1.1.3 ! root      202: 
1.1       root      203:        
                    204:        if (sv.state != ss_loading)
                    205:        {       // send the update to everyone
                    206:                SZ_Clear (&sv.multicast);
                    207:                MSG_WriteChar (&sv.multicast, svc_configstring);
                    208:                MSG_WriteShort (&sv.multicast, index);
                    209:                MSG_WriteString (&sv.multicast, val);
                    210: 
                    211:                SV_Multicast (vec3_origin, MULTICAST_ALL_R);
                    212:        }
                    213: }
                    214: 
                    215: 
                    216: 
                    217: void PF_WriteChar (int c) {MSG_WriteChar (&sv.multicast, c);}
                    218: void PF_WriteByte (int c) {MSG_WriteByte (&sv.multicast, c);}
                    219: void PF_WriteShort (int c) {MSG_WriteShort (&sv.multicast, c);}
                    220: void PF_WriteLong (int c) {MSG_WriteLong (&sv.multicast, c);}
                    221: void PF_WriteFloat (float f) {MSG_WriteFloat (&sv.multicast, f);}
                    222: void PF_WriteString (char *s) {MSG_WriteString (&sv.multicast, s);}
                    223: void PF_WritePos (vec3_t pos) {MSG_WritePos (&sv.multicast, pos);}
                    224: void PF_WriteDir (vec3_t dir) {MSG_WriteDir (&sv.multicast, dir);}
                    225: void PF_WriteAngle (float f) {MSG_WriteAngle (&sv.multicast, f);}
                    226: 
                    227: 
                    228: /*
                    229: =================
                    230: PF_inPVS
                    231: 
                    232: Also checks portalareas so that doors block sight
                    233: =================
                    234: */
                    235: qboolean PF_inPVS (vec3_t p1, vec3_t p2)
                    236: {
                    237:        int             leafnum;
                    238:        int             cluster;
                    239:        int             area1, area2;
                    240:        byte    *mask;
                    241: 
                    242:        leafnum = CM_PointLeafnum (p1);
                    243:        cluster = CM_LeafCluster (leafnum);
                    244:        area1 = CM_LeafArea (leafnum);
                    245:        mask = CM_ClusterPVS (cluster);
                    246: 
                    247:        leafnum = CM_PointLeafnum (p2);
                    248:        cluster = CM_LeafCluster (leafnum);
                    249:        area2 = CM_LeafArea (leafnum);
                    250:        if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) )
                    251:                return false;
                    252:        if (!CM_AreasConnected (area1, area2))
                    253:                return false;           // a door blocks sight
                    254:        return true;
                    255: }
                    256: 
                    257: 
                    258: /*
                    259: =================
                    260: PF_inPHS
                    261: 
                    262: Also checks portalareas so that doors block sound
                    263: =================
                    264: */
                    265: qboolean PF_inPHS (vec3_t p1, vec3_t p2)
                    266: {
                    267:        int             leafnum;
                    268:        int             cluster;
                    269:        int             area1, area2;
                    270:        byte    *mask;
                    271: 
                    272:        leafnum = CM_PointLeafnum (p1);
                    273:        cluster = CM_LeafCluster (leafnum);
                    274:        area1 = CM_LeafArea (leafnum);
                    275:        mask = CM_ClusterPHS (cluster);
                    276: 
                    277:        leafnum = CM_PointLeafnum (p2);
                    278:        cluster = CM_LeafCluster (leafnum);
                    279:        area2 = CM_LeafArea (leafnum);
                    280:        if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) )
                    281:                return false;           // more than one bounce away
                    282:        if (!CM_AreasConnected (area1, area2))
                    283:                return false;           // a door blocks hearing
                    284: 
                    285:        return true;
                    286: }
                    287: 
                    288: void PF_StartSound (edict_t *entity, int channel, int sound_num, float volume,
                    289:     float attenuation, float timeofs)
                    290: {
                    291:        if (!entity)
                    292:                return;
                    293:        SV_StartSound (NULL, entity, channel, sound_num, volume, attenuation, timeofs);
                    294: }
                    295: 
                    296: //==============================================
                    297: 
                    298: /*
                    299: ===============
                    300: SV_ShutdownGameProgs
                    301: 
                    302: Called when either the entire server is being killed, or
                    303: it is changing to a different game directory.
                    304: ===============
                    305: */
                    306: void SV_ShutdownGameProgs (void)
                    307: {
                    308:        if (!ge)
                    309:                return;
                    310:        ge->Shutdown ();
                    311:        Sys_UnloadGame ();
                    312:        ge = NULL;
                    313: }
                    314: 
                    315: /*
                    316: ===============
                    317: SV_InitGameProgs
                    318: 
                    319: Init the game subsystem for a new map
                    320: ===============
                    321: */
                    322: void SCR_DebugGraph (float value, int color);
                    323: 
                    324: void SV_InitGameProgs (void)
                    325: {
                    326:        game_import_t   import;
                    327: 
                    328:        // unload anything we have now
                    329:        if (ge)
                    330:                SV_ShutdownGameProgs ();
                    331: 
                    332: 
                    333:        // load a new game dll
                    334:        import.multicast = SV_Multicast;
                    335:        import.unicast = PF_Unicast;
                    336:        import.bprintf = SV_BroadcastPrintf;
                    337:        import.dprintf = PF_dprintf;
                    338:        import.cprintf = PF_cprintf;
                    339:        import.centerprintf = PF_centerprintf;
                    340:        import.error = PF_error;
                    341: 
                    342:        import.linkentity = SV_LinkEdict;
                    343:        import.unlinkentity = SV_UnlinkEdict;
                    344:        import.BoxEdicts = SV_AreaEdicts;
                    345:        import.trace = SV_Trace;
                    346:        import.pointcontents = SV_PointContents;
                    347:        import.setmodel = PF_setmodel;
                    348:        import.inPVS = PF_inPVS;
                    349:        import.inPHS = PF_inPHS;
                    350:        import.Pmove = Pmove;
                    351: 
                    352:        import.modelindex = SV_ModelIndex;
                    353:        import.soundindex = SV_SoundIndex;
                    354:        import.imageindex = SV_ImageIndex;
                    355: 
                    356:        import.configstring = PF_Configstring;
                    357:        import.sound = PF_StartSound;
                    358:        import.positioned_sound = SV_StartSound;
                    359: 
                    360:        import.WriteChar = PF_WriteChar;
                    361:        import.WriteByte = PF_WriteByte;
                    362:        import.WriteShort = PF_WriteShort;
                    363:        import.WriteLong = PF_WriteLong;
                    364:        import.WriteFloat = PF_WriteFloat;
                    365:        import.WriteString = PF_WriteString;
                    366:        import.WritePosition = PF_WritePos;
                    367:        import.WriteDir = PF_WriteDir;
                    368:        import.WriteAngle = PF_WriteAngle;
                    369: 
                    370:        import.TagMalloc = Z_TagMalloc;
                    371:        import.TagFree = Z_Free;
                    372:        import.FreeTags = Z_FreeTags;
                    373: 
                    374:        import.cvar = Cvar_Get;
                    375:        import.cvar_set = Cvar_Set;
                    376:        import.cvar_forceset = Cvar_ForceSet;
                    377: 
                    378:        import.argc = Cmd_Argc;
                    379:        import.argv = Cmd_Argv;
                    380:        import.args = Cmd_Args;
                    381:        import.AddCommandString = Cbuf_AddText;
                    382: 
                    383:        import.DebugGraph = SCR_DebugGraph;
                    384:        import.SetAreaPortalState = CM_SetAreaPortalState;
                    385:        import.AreasConnected = CM_AreasConnected;
                    386: 
                    387:        ge = (game_export_t *)Sys_GetGameAPI (&import);
                    388: 
                    389:        if (!ge)
                    390:                Com_Error (ERR_DROP, "failed to load game DLL");
                    391:        if (ge->apiversion != GAME_API_VERSION)
                    392:                Com_Error (ERR_DROP, "game is version %i, not %i", ge->apiversion,
                    393:                GAME_API_VERSION);
                    394: 
                    395:        ge->Init ();
                    396: }
                    397: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.