-/*
-==================
-CL_ParseUpdate
-
-Parse an entity update message from the server
-If an entities model or origin changes from frame to frame, it must be
-relinked. Other attributes can change without relinking.
-==================
-*/
-void CL_ParseUpdate (int bits)
-{
- int num;
- entity_t *ent;
- entity_state_t new;
-
- if (bits & U_MOREBITS)
- bits |= (MSG_ReadByte()<<8);
- if ((bits & U_EXTEND1) && cl.protocol != PROTOCOL_NEHAHRAMOVIE)
- {
- bits |= MSG_ReadByte() << 16;
- if (bits & U_EXTEND2)
- bits |= MSG_ReadByte() << 24;
- }
-
- if (bits & U_LONGENTITY)
- num = (unsigned) MSG_ReadShort ();
- else
- num = (unsigned) MSG_ReadByte ();
-
- if (num >= MAX_EDICTS)
- Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
- if (num < 1)
- Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
-
- ent = cl_entities + num;
-
- // note: this inherits the 'active' state of the baseline chosen
- // (state_baseline is always active, state_current may not be active if
- // the entity was missing in the last frame)
- if (bits & U_DELTA)
- new = ent->state_current;
- else
- {
- new = ent->state_baseline;
- new.active = true;
- }
-
- new.number = num;
- new.time = cl.mtime[0];
- new.flags = 0;
- if (bits & U_MODEL) new.modelindex = (new.modelindex & 0xFF00) | MSG_ReadByte();
- if (bits & U_FRAME) new.frame = (new.frame & 0xFF00) | MSG_ReadByte();
- if (bits & U_COLORMAP) new.colormap = MSG_ReadByte();
- if (bits & U_SKIN) new.skin = MSG_ReadByte();
- if (bits & U_EFFECTS) new.effects = (new.effects & 0xFF00) | MSG_ReadByte();
- if (bits & U_ORIGIN1) new.origin[0] = MSG_ReadCoord();
- if (bits & U_ANGLE1) new.angles[0] = MSG_ReadAngle();
- if (bits & U_ORIGIN2) new.origin[1] = MSG_ReadCoord();
- if (bits & U_ANGLE2) new.angles[1] = MSG_ReadAngle();
- if (bits & U_ORIGIN3) new.origin[2] = MSG_ReadCoord();
- if (bits & U_ANGLE3) new.angles[2] = MSG_ReadAngle();
- if (bits & U_STEP) new.flags |= RENDER_STEP;
- if (bits & U_ALPHA) new.alpha = MSG_ReadByte();
- if (bits & U_SCALE) new.scale = MSG_ReadByte();
- if (bits & U_EFFECTS2) new.effects = (new.effects & 0x00FF) | (MSG_ReadByte() << 8);
- if (bits & U_GLOWSIZE) new.glowsize = MSG_ReadByte();
- if (bits & U_GLOWCOLOR) new.glowcolor = MSG_ReadByte();
- // apparently the dpcrush demo uses this (unintended, and it uses white anyway)
- if (bits & U_COLORMOD) MSG_ReadByte();
- if (bits & U_GLOWTRAIL) new.flags |= RENDER_GLOWTRAIL;
- if (bits & U_FRAME2) new.frame = (new.frame & 0x00FF) | (MSG_ReadByte() << 8);
- if (bits & U_MODEL2) new.modelindex = (new.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
- if (bits & U_VIEWMODEL) new.flags |= RENDER_VIEWMODEL;
- if (bits & U_EXTERIORMODEL) new.flags |= RENDER_EXTERIORMODEL;
-
- // LordHavoc: to allow playback of the Nehahra movie
- if (cl.protocol == PROTOCOL_NEHAHRAMOVIE && (bits & U_EXTEND1))
- {
- // LordHavoc: evil format
- int i = MSG_ReadFloat();
- int j = MSG_ReadFloat() * 255.0f;
- if (i == 2)
- {
- i = MSG_ReadFloat();
- if (i)
- new.effects |= EF_FULLBRIGHT;
- }
- if (j < 0)
- new.alpha = 0;
- else if (j == 0 || j >= 255)
- new.alpha = 255;
- else
- new.alpha = j;
- }
-
- if (new.active)
- CL_ValidateState(&new);
-
- ent->state_previous = ent->state_current;
- ent->state_current = new;
- if (ent->state_current.active)
- {
- CL_MoveLerpEntityStates(ent);
- cl_entities_active[ent->state_current.number] = true;
- // mark as visible (no kill this frame)
- entlife[ent->state_current.number] = 2;
- }
-}
-
-static entity_frame_t entityframe;
-extern mempool_t *cl_entities_mempool;
-void CL_ReadEntityFrame(void)
-{
- if (cl.protocol == PROTOCOL_DARKPLACES1 || cl.protocol == PROTOCOL_DARKPLACES2 || cl.protocol == PROTOCOL_DARKPLACES3)
- {
- int i;
- entity_t *ent;
- EntityFrame_Read(&cl.entitydatabase);
- EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
- for (i = 0;i < entityframe.numentities;i++)
- {
- // copy the states
- ent = &cl_entities[entityframe.entitydata[i].number];
- ent->state_previous = ent->state_current;
- ent->state_current = entityframe.entitydata[i];
- CL_MoveLerpEntityStates(ent);
- // the entity lives again...
- entlife[ent->state_current.number] = 2;
- cl_entities_active[ent->state_current.number] = true;
- }
- }
- else
- {
- if (!cl.entitydatabase4)
- cl.entitydatabase4 = EntityFrame4_AllocDatabase(cl_entities_mempool);
- EntityFrame4_CL_ReadFrame(cl.entitydatabase4);
- }
-}
-
-void CL_EntityUpdateSetup(void)
-{
-}
-
-void CL_EntityUpdateEnd(void)
-{
- if (cl.protocol == PROTOCOL_QUAKE || cl.protocol == PROTOCOL_NEHAHRAMOVIE || cl.protocol == PROTOCOL_DARKPLACES1 || cl.protocol == PROTOCOL_DARKPLACES2 || cl.protocol == PROTOCOL_DARKPLACES3)
- {
- int i;
- // disable entities that disappeared this frame
- for (i = 1;i < MAX_EDICTS;i++)
- {
- // clear only the entities that were active last frame but not this
- // frame, don't waste time clearing all entities (which would cause
- // cache misses)
- if (entlife[i])
- {
- entlife[i]--;
- if (!entlife[i])
- cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
- }
- }
- }
-}
-