static void push_event(action_t action, const char *type, void *object) { if (!event_lock) return; /* Unit tests don't call qd_entity_cache_initialize */ sys_mutex_lock(event_lock); entity_event_t *event = entity_event(action, type, object); DEQ_INSERT_TAIL(event_list, event); sys_mutex_unlock(event_lock); }
/* ================== CL_DeltaFrame A valid frame has been parsed. ================== */ void CL_DeltaFrame(void) { centity_t *ent; entity_state_t *state; int i, j; int framenum; // getting a valid frame message ends the connection process if (cls.state == ca_precached) set_active_state(); // set server time framenum = cl.frame.number - cl.serverdelta; cl.servertime = framenum * CL_FRAMETIME; #if USE_FPS cl.keyservertime = (framenum / cl.framediv) * BASE_FRAMETIME; #endif // rebuild the list of solid entities for this frame cl.numSolidEntities = 0; // initialize position of the player's own entity from playerstate. // this is needed in situations when player entity is invisible, but // server sends an effect referencing it's origin (such as MZ_LOGIN, etc) ent = &cl_entities[cl.frame.clientNum + 1]; Com_PlayerToEntityState(&cl.frame.ps, &ent->current); for (i = 0; i < cl.frame.numEntities; i++) { j = (cl.frame.firstEntity + i) & PARSE_ENTITIES_MASK; state = &cl.entityStates[j]; // set current and prev entity_update(state); // fire events entity_event(state->number); } if (cls.demo.recording && !cls.demo.paused && !cls.demo.seeking && CL_FRAMESYNC) { CL_EmitDemoFrame(); } if (cls.demo.playback) { // this delta has nothing to do with local viewangles, // clear it to avoid interfering with demo freelook hack VectorClear(cl.frame.ps.pmove.delta_angles); } if (cl.oldframe.ps.pmove.pm_type != cl.frame.ps.pmove.pm_type) { IN_Activate(); } player_update(&cl.oldframe, &cl.frame, 1); #if USE_FPS if (CL_FRAMESYNC) player_update(&cl.oldkeyframe, &cl.keyframe, cl.framediv); #endif CL_CheckPredictionError(); SCR_SetCrosshairColor(); }