Annotation of quake2/client/cl_pred.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: 
                     21: #include "client.h"
                     22: 
                     23: 
                     24: /*
                     25: ===================
                     26: CL_CheckPredictionError
                     27: ===================
                     28: */
                     29: void CL_CheckPredictionError (void)
                     30: {
                     31:        int             frame;
                     32:        int             delta[3];
                     33:        int             i;
                     34:        int             len;
                     35: 
                     36:        if (!cl_predict->value || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION))
                     37:                return;
                     38: 
                     39:        // calculate the last usercmd_t we sent that the server has processed
                     40:        frame = cls.netchan.incoming_acknowledged;
                     41:        frame &= (CMD_BACKUP-1);
                     42: 
                     43:        // compare what the server returned with what we had predicted it to be
                     44:        VectorSubtract (cl.frame.playerstate.pmove.origin, cl.predicted_origins[frame], delta);
                     45: 
                     46:        // save the prediction error for interpolation
                     47:        len = abs(delta[0]) + abs(delta[1]) + abs(delta[2]);
                     48:        if (len > 640)  // 80 world units
                     49:        {       // a teleport or something
                     50:                VectorClear (cl.prediction_error);
                     51:        }
                     52:        else
                     53:        {
                     54:                if (cl_showmiss->value && (delta[0] || delta[1] || delta[2]) )
                     55:                        Com_Printf ("prediction miss on %i: %i\n", cl.frame.serverframe, 
                     56:                        delta[0] + delta[1] + delta[2]);
                     57: 
                     58:                VectorCopy (cl.frame.playerstate.pmove.origin, cl.predicted_origins[frame]);
                     59: 
                     60:                // save for error itnerpolation
                     61:                for (i=0 ; i<3 ; i++)
                     62:                        cl.prediction_error[i] = delta[i]*0.125;
                     63:        }
                     64: }
                     65: 
                     66: 
                     67: /*
                     68: ====================
                     69: CL_ClipMoveToEntities
                     70: 
                     71: ====================
                     72: */
                     73: void CL_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, trace_t *tr )
                     74: {
                     75:        int                     i, x, zd, zu;
                     76:        trace_t         trace;
                     77:        int                     headnode;
                     78:        float           *angles;
                     79:        entity_state_t  *ent;
                     80:        int                     num;
                     81:        cmodel_t                *cmodel;
                     82:        vec3_t          bmins, bmaxs;
                     83: 
                     84:        for (i=0 ; i<cl.frame.num_entities ; i++)
                     85:        {
                     86:                num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
                     87:                ent = &cl_parse_entities[num];
                     88: 
                     89:                if (!ent->solid)
                     90:                        continue;
                     91: 
                     92:                if (ent->number == cl.playernum+1)
                     93:                        continue;
                     94: 
                     95:                if (ent->solid == 31)
                     96:                {       // special value for bmodel
                     97:                        cmodel = cl.model_clip[ent->modelindex];
                     98:                        if (!cmodel)
                     99:                                continue;
                    100:                        headnode = cmodel->headnode;
                    101:                        angles = ent->angles;
                    102:                }
                    103:                else
                    104:                {       // encoded bbox
                    105:                        x = 8*(ent->solid & 31);
                    106:                        zd = 8*((ent->solid>>5) & 31);
                    107:                        zu = 8*((ent->solid>>10) & 63) - 32;
                    108: 
                    109:                        bmins[0] = bmins[1] = -x;
                    110:                        bmaxs[0] = bmaxs[1] = x;
                    111:                        bmins[2] = -zd;
                    112:                        bmaxs[2] = zu;
                    113: 
                    114:                        headnode = CM_HeadnodeForBox (bmins, bmaxs);
                    115:                        angles = vec3_origin;   // boxes don't rotate
                    116:                }
                    117: 
                    118:                if (tr->allsolid)
                    119:                        return;
                    120: 
                    121:                trace = CM_TransformedBoxTrace (start, end,
                    122:                        mins, maxs, headnode,  MASK_PLAYERSOLID,
                    123:                        ent->origin, angles);
                    124: 
                    125:                if (trace.allsolid || trace.startsolid ||
                    126:                trace.fraction < tr->fraction)
                    127:                {
                    128:                        trace.ent = (struct edict_s *)ent;
                    129:                        if (tr->startsolid)
                    130:                        {
                    131:                                *tr = trace;
                    132:                                tr->startsolid = true;
                    133:                        }
                    134:                        else
                    135:                                *tr = trace;
                    136:                }
                    137:                else if (trace.startsolid)
                    138:                        tr->startsolid = true;
                    139:        }
                    140: }
                    141: 
                    142: 
                    143: /*
                    144: ================
                    145: CL_PMTrace
                    146: ================
                    147: */
                    148: trace_t                CL_PMTrace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
                    149: {
                    150:        trace_t t;
                    151: 
                    152:        // check against world
                    153:        t = CM_BoxTrace (start, end, mins, maxs, 0, MASK_PLAYERSOLID);
                    154:        if (t.fraction < 1.0)
                    155:                t.ent = (struct edict_s *)1;
                    156: 
                    157:        // check all other solid models
                    158:        CL_ClipMoveToEntities (start, mins, maxs, end, &t);
                    159: 
                    160:        return t;
                    161: }
                    162: 
                    163: int            CL_PMpointcontents (vec3_t point)
                    164: {
                    165:        int                     i;
                    166:        entity_state_t  *ent;
                    167:        int                     num;
                    168:        cmodel_t                *cmodel;
                    169:        int                     contents;
                    170: 
                    171:        contents = CM_PointContents (point, 0);
                    172: 
                    173:        for (i=0 ; i<cl.frame.num_entities ; i++)
                    174:        {
                    175:                num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
                    176:                ent = &cl_parse_entities[num];
                    177: 
                    178:                if (ent->solid != 31) // special value for bmodel
                    179:                        continue;
                    180: 
                    181:                cmodel = cl.model_clip[ent->modelindex];
                    182:                if (!cmodel)
                    183:                        continue;
                    184: 
                    185:                contents |= CM_TransformedPointContents (point, cmodel->headnode, ent->origin, ent->angles);
                    186:        }
                    187: 
                    188:        return contents;
                    189: }
                    190: 
                    191: 
                    192: /*
                    193: =================
                    194: CL_PredictMovement
                    195: 
                    196: Sets cl.predicted_origin and cl.predicted_angles
                    197: =================
                    198: */
                    199: void CL_PredictMovement (void)
                    200: {
                    201:        int                     ack, current;
                    202:        int                     frame;
                    203:        int                     oldframe;
                    204:        usercmd_t       *cmd;
                    205:        pmove_t         pm;
                    206:        int                     i;
                    207:        int                     step;
                    208:        int                     oldz;
                    209: 
                    210:        if (cls.state != ca_active)
                    211:                return;
                    212: 
                    213:        if (cl_paused->value)
                    214:                return;
                    215: 
                    216:        if (!cl_predict->value || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION))
                    217:        {       // just set angles
                    218:                for (i=0 ; i<3 ; i++)
                    219:                {
                    220:                        cl.predicted_angles[i] = cl.viewangles[i] + SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[i]);
                    221:                }
                    222:                return;
                    223:        }
                    224: 
                    225:        ack = cls.netchan.incoming_acknowledged;
                    226:        current = cls.netchan.outgoing_sequence;
                    227: 
                    228:        // if we are too far out of date, just freeze
                    229:        if (current - ack >= CMD_BACKUP)
                    230:        {
                    231:                if (cl_showmiss->value)
                    232:                        Com_Printf ("exceeded CMD_BACKUP\n");
                    233:                return; 
                    234:        }
                    235: 
                    236:        // copy current state to pmove
                    237:        memset (&pm, 0, sizeof(pm));
                    238:        pm.trace = CL_PMTrace;
                    239:        pm.pointcontents = CL_PMpointcontents;
                    240: 
1.1.1.2   root      241:        pm_airaccelerate = atof(cl.configstrings[CS_AIRACCEL]);
                    242: 
1.1       root      243:        pm.s = cl.frame.playerstate.pmove;
                    244: 
                    245: //     SCR_DebugGraph (current - ack - 1, 0);
                    246: 
                    247:        frame = 0;
                    248: 
                    249:        // run frames
                    250:        while (++ack < current)
                    251:        {
                    252:                frame = ack & (CMD_BACKUP-1);
                    253:                cmd = &cl.cmds[frame];
                    254: 
                    255:                pm.cmd = *cmd;
                    256:                Pmove (&pm);
                    257: 
                    258:                // save for debug checking
                    259:                VectorCopy (pm.s.origin, cl.predicted_origins[frame]);
                    260:        }
                    261: 
                    262:        oldframe = (ack-2) & (CMD_BACKUP-1);
                    263:        oldz = cl.predicted_origins[oldframe][2];
                    264:        step = pm.s.origin[2] - oldz;
                    265:        if (step > 63 && step < 160 && (pm.s.pm_flags & PMF_ON_GROUND) )
                    266:        {
                    267:                cl.predicted_step = step * 0.125;
                    268:                cl.predicted_step_time = cls.realtime - cls.frametime * 500;
                    269:        }
                    270: 
                    271: 
                    272:        // copy results out for rendering
                    273:        cl.predicted_origin[0] = pm.s.origin[0]*0.125;
                    274:        cl.predicted_origin[1] = pm.s.origin[1]*0.125;
                    275:        cl.predicted_origin[2] = pm.s.origin[2]*0.125;
                    276: 
                    277:        VectorCopy (pm.viewangles, cl.predicted_angles);
                    278: }

unix.superglobalmegacorp.com

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