|
|
1.1 root 1: // cl_ents.c -- entity parsing and management 1.1.1.2 ! root 2: 1.1 root 3: #include "client.h" 4: 1.1.1.2 ! root 5: 1.1 root 6: extern struct model_s *cl_mod_powerscreen; 1.1.1.2 ! root 7: 1.1 root 8: /* 9: ========================================================================= 1.1.1.2 ! root 10: 1.1 root 11: FRAME PARSING 1.1.1.2 ! root 12: 1.1 root 13: ========================================================================= 14: */ 1.1.1.2 ! root 15: ! 16: #if 0 ! 17: ! 18: typedef struct ! 19: { ! 20: int modelindex; ! 21: int num; // entity number ! 22: int effects; ! 23: vec3_t origin; ! 24: vec3_t oldorigin; ! 25: vec3_t angles; ! 26: qboolean present; ! 27: } projectile_t; ! 28: ! 29: #define MAX_PROJECTILES 64 ! 30: projectile_t cl_projectiles[MAX_PROJECTILES]; ! 31: ! 32: void CL_ClearProjectiles (void) ! 33: { ! 34: int i; ! 35: ! 36: for (i = 0; i < MAX_PROJECTILES; i++) { ! 37: // if (cl_projectiles[i].present) ! 38: // Com_DPrintf("PROJ: %d CLEARED\n", cl_projectiles[i].num); ! 39: cl_projectiles[i].present = false; ! 40: } ! 41: } ! 42: ! 43: /* ! 44: ===================== ! 45: CL_ParseProjectiles ! 46: ! 47: Nails are passed as efficient temporary entities ! 48: ===================== ! 49: */ ! 50: void CL_ParseProjectiles (void) ! 51: { ! 52: int i, c, j; ! 53: byte bits[8]; ! 54: byte b; ! 55: projectile_t pr; ! 56: int lastempty = -1; ! 57: qboolean old = false; ! 58: ! 59: c = MSG_ReadByte (&net_message); ! 60: for (i=0 ; i<c ; i++) ! 61: { ! 62: bits[0] = MSG_ReadByte (&net_message); ! 63: bits[1] = MSG_ReadByte (&net_message); ! 64: bits[2] = MSG_ReadByte (&net_message); ! 65: bits[3] = MSG_ReadByte (&net_message); ! 66: bits[4] = MSG_ReadByte (&net_message); ! 67: pr.origin[0] = ( ( bits[0] + ((bits[1]&15)<<8) ) <<1) - 4096; ! 68: pr.origin[1] = ( ( (bits[1]>>4) + (bits[2]<<4) ) <<1) - 4096; ! 69: pr.origin[2] = ( ( bits[3] + ((bits[4]&15)<<8) ) <<1) - 4096; ! 70: VectorCopy(pr.origin, pr.oldorigin); ! 71: ! 72: if (bits[4] & 64) ! 73: pr.effects = EF_BLASTER; ! 74: else ! 75: pr.effects = 0; ! 76: ! 77: if (bits[4] & 128) { ! 78: old = true; ! 79: bits[0] = MSG_ReadByte (&net_message); ! 80: bits[1] = MSG_ReadByte (&net_message); ! 81: bits[2] = MSG_ReadByte (&net_message); ! 82: bits[3] = MSG_ReadByte (&net_message); ! 83: bits[4] = MSG_ReadByte (&net_message); ! 84: pr.oldorigin[0] = ( ( bits[0] + ((bits[1]&15)<<8) ) <<1) - 4096; ! 85: pr.oldorigin[1] = ( ( (bits[1]>>4) + (bits[2]<<4) ) <<1) - 4096; ! 86: pr.oldorigin[2] = ( ( bits[3] + ((bits[4]&15)<<8) ) <<1) - 4096; ! 87: } ! 88: ! 89: bits[0] = MSG_ReadByte (&net_message); ! 90: bits[1] = MSG_ReadByte (&net_message); ! 91: bits[2] = MSG_ReadByte (&net_message); ! 92: ! 93: pr.angles[0] = 360*bits[0]/256; ! 94: pr.angles[1] = 360*bits[1]/256; ! 95: pr.modelindex = bits[2]; ! 96: ! 97: b = MSG_ReadByte (&net_message); ! 98: pr.num = (b & 0x7f); ! 99: if (b & 128) // extra entity number byte ! 100: pr.num |= (MSG_ReadByte (&net_message) << 7); ! 101: ! 102: pr.present = true; ! 103: ! 104: // find if this projectile already exists from previous frame ! 105: for (j = 0; j < MAX_PROJECTILES; j++) { ! 106: if (cl_projectiles[j].modelindex) { ! 107: if (cl_projectiles[j].num == pr.num) { ! 108: // already present, set up oldorigin for interpolation ! 109: if (!old) ! 110: VectorCopy(cl_projectiles[j].origin, pr.oldorigin); ! 111: cl_projectiles[j] = pr; ! 112: break; ! 113: } ! 114: } else ! 115: lastempty = j; ! 116: } ! 117: ! 118: // not present previous frame, add it ! 119: if (j == MAX_PROJECTILES) { ! 120: if (lastempty != -1) { ! 121: cl_projectiles[lastempty] = pr; ! 122: } ! 123: } ! 124: } ! 125: } ! 126: ! 127: /* ! 128: ============= ! 129: CL_LinkProjectiles ! 130: ! 131: ============= ! 132: */ ! 133: void CL_AddProjectiles (void) ! 134: { ! 135: int i, j; ! 136: projectile_t *pr; ! 137: entity_t ent; ! 138: ! 139: memset (&ent, 0, sizeof(ent)); ! 140: ! 141: for (i=0, pr=cl_projectiles ; i < MAX_PROJECTILES ; i++, pr++) ! 142: { ! 143: // grab an entity to fill in ! 144: if (pr->modelindex < 1) ! 145: continue; ! 146: if (!pr->present) { ! 147: pr->modelindex = 0; ! 148: continue; // not present this frame (it was in the previous frame) ! 149: } ! 150: ! 151: ent.model = cl.model_draw[pr->modelindex]; ! 152: ! 153: // interpolate origin ! 154: for (j=0 ; j<3 ; j++) ! 155: { ! 156: ent.origin[j] = ent.oldorigin[j] = pr->oldorigin[j] + cl.lerpfrac * ! 157: (pr->origin[j] - pr->oldorigin[j]); ! 158: ! 159: } ! 160: ! 161: if (pr->effects & EF_BLASTER) ! 162: CL_BlasterTrail (pr->oldorigin, ent.origin); ! 163: V_AddLight (pr->origin, 200, 1, 1, 0); ! 164: ! 165: VectorCopy (pr->angles, ent.angles); ! 166: V_AddEntity (&ent); ! 167: } ! 168: } ! 169: #endif ! 170: 1.1 root 171: /* 172: ================= 173: CL_ParseEntityBits 174: 175: Returns the entity number and the header bits 176: ================= 177: */ 178: int bitcounts[32]; /// just for protocol profiling 179: int CL_ParseEntityBits (unsigned *bits) 180: { 181: unsigned b, total; 182: int i; 1.1.1.2 ! root 183: int number; 1.1 root 184: 185: total = MSG_ReadByte (&net_message); 186: if (total & U_MOREBITS1) 187: { 188: b = MSG_ReadByte (&net_message); 189: total |= b<<8; 190: } 191: if (total & U_MOREBITS2) 192: { 193: b = MSG_ReadByte (&net_message); 194: total |= b<<16; 195: } 196: if (total & U_MOREBITS3) 197: { 198: b = MSG_ReadByte (&net_message); 199: total |= b<<24; 200: } 201: 202: // count the bits for net profiling 203: for (i=0 ; i<32 ; i++) 204: if (total&(1<<i)) 205: bitcounts[i]++; 206: 207: if (total & U_NUMBER16) 208: number = MSG_ReadShort (&net_message); 209: else 210: number = MSG_ReadByte (&net_message); 211: 212: *bits = total; 213: 214: return number; 215: } 1.1.1.2 ! root 216: 1.1 root 217: /* 218: ================== 219: CL_ParseDelta 1.1.1.2 ! root 220: 1.1 root 221: Can go from either a baseline or a previous packet_entity 222: ================== 223: */ 224: void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int number, int bits) 225: { 226: // set everything to the state we are delta'ing from 227: *to = *from; 1.1.1.2 ! root 228: ! 229: VectorCopy (from->origin, to->old_origin); 1.1 root 230: to->number = number; 1.1.1.2 ! root 231: 1.1 root 232: if (bits & U_MODEL) 233: to->modelindex = MSG_ReadByte (&net_message); 234: if (bits & U_MODEL2) 235: to->modelindex2 = MSG_ReadByte (&net_message); 236: if (bits & U_MODEL3) 237: to->modelindex3 = MSG_ReadByte (&net_message); 238: if (bits & U_MODEL4) 239: to->modelindex4 = MSG_ReadByte (&net_message); 240: 241: if (bits & U_FRAME8) 242: to->frame = MSG_ReadByte (&net_message); 243: if (bits & U_FRAME16) 244: to->frame = MSG_ReadShort (&net_message); 1.1.1.2 ! root 245: 1.1 root 246: if ((bits & U_SKIN8) && (bits & U_SKIN16)) //used for laser colors 247: to->skinnum = MSG_ReadLong(&net_message); 248: else if (bits & U_SKIN8) 249: to->skinnum = MSG_ReadByte(&net_message); 250: else if (bits & U_SKIN16) 251: to->skinnum = MSG_ReadShort(&net_message); 252: 253: if ( (bits & (U_EFFECTS8|U_EFFECTS16)) == (U_EFFECTS8|U_EFFECTS16) ) 254: to->effects = MSG_ReadLong(&net_message); 255: else if (bits & U_EFFECTS8) 256: to->effects = MSG_ReadByte(&net_message); 257: else if (bits & U_EFFECTS16) 258: to->effects = MSG_ReadShort(&net_message); 1.1.1.2 ! root 259: 1.1 root 260: if ( (bits & (U_RENDERFX8|U_RENDERFX16)) == (U_RENDERFX8|U_RENDERFX16) ) 261: to->renderfx = MSG_ReadLong(&net_message); 262: else if (bits & U_RENDERFX8) 263: to->renderfx = MSG_ReadByte(&net_message); 264: else if (bits & U_RENDERFX16) 265: to->renderfx = MSG_ReadShort(&net_message); 1.1.1.2 ! root 266: 1.1 root 267: if (bits & U_ORIGIN1) 268: to->origin[0] = MSG_ReadCoord (&net_message); 269: if (bits & U_ORIGIN2) 270: to->origin[1] = MSG_ReadCoord (&net_message); 271: if (bits & U_ORIGIN3) 272: to->origin[2] = MSG_ReadCoord (&net_message); 273: 274: if (bits & U_ANGLE1) 275: to->angles[0] = MSG_ReadAngle(&net_message); 276: if (bits & U_ANGLE2) 277: to->angles[1] = MSG_ReadAngle(&net_message); 278: if (bits & U_ANGLE3) 279: to->angles[2] = MSG_ReadAngle(&net_message); 1.1.1.2 ! root 280: 1.1 root 281: if (bits & U_OLDORIGIN) 282: MSG_ReadPos (&net_message, to->old_origin); 1.1.1.2 ! root 283: 1.1 root 284: if (bits & U_SOUND) 285: to->sound = MSG_ReadByte (&net_message); 286: 287: if (bits & U_EVENT) 288: to->event = MSG_ReadByte (&net_message); 289: else 290: to->event = 0; 291: 292: if (bits & U_SOLID) 293: to->solid = MSG_ReadShort (&net_message); 294: } 295: 296: /* 297: ================== 298: CL_DeltaEntity 299: 300: Parses deltas from the given base and adds the resulting entity 301: to the current frame 302: ================== 303: */ 304: void CL_DeltaEntity (frame_t *frame, int newnum, entity_state_t *old, int bits) 305: { 306: centity_t *ent; 307: entity_state_t *state; 308: 309: ent = &cl_entities[newnum]; 310: 311: state = &cl_parse_entities[cl.parse_entities & (MAX_PARSE_ENTITIES-1)]; 312: cl.parse_entities++; 313: frame->num_entities++; 314: 315: CL_ParseDelta (old, state, newnum, bits); 316: 317: // some data changes will force no lerping 318: if (state->modelindex != ent->current.modelindex 319: || state->modelindex2 != ent->current.modelindex2 320: || state->modelindex3 != ent->current.modelindex3 321: || state->modelindex4 != ent->current.modelindex4 322: || abs(state->origin[0] - ent->current.origin[0]) > 512 323: || abs(state->origin[1] - ent->current.origin[1]) > 512 324: || abs(state->origin[2] - ent->current.origin[2]) > 512 325: || state->event == EV_PLAYER_TELEPORT 1.1.1.2 ! root 326: || state->event == EV_OTHER_TELEPORT 1.1 root 327: ) 328: { 329: ent->serverframe = -99; 330: } 331: 332: if (ent->serverframe != cl.frame.serverframe - 1) 333: { // wasn't in last update, so initialize some things 334: ent->trailcount = 1024; // for diminishing rocket / grenade trails 335: // duplicate the current state so lerping doesn't hurt anything 336: ent->prev = *state; 1.1.1.2 ! root 337: if (state->event == EV_OTHER_TELEPORT) ! 338: { ! 339: VectorCopy (state->origin, ent->prev.origin); ! 340: VectorCopy (state->origin, ent->lerp_origin); ! 341: } ! 342: else ! 343: { ! 344: VectorCopy (state->old_origin, ent->prev.origin); ! 345: VectorCopy (state->old_origin, ent->lerp_origin); ! 346: } 1.1 root 347: } 348: else 349: { // shuffle the last state to previous 350: ent->prev = ent->current; 351: } 352: 353: ent->serverframe = cl.frame.serverframe; 354: ent->current = *state; 355: } 1.1.1.2 ! root 356: 1.1 root 357: /* 358: ================== 359: CL_ParsePacketEntities 1.1.1.2 ! root 360: 1.1 root 361: An svc_packetentities has just been parsed, deal with the 362: rest of the data stream. 363: ================== 364: */ 365: void CL_ParsePacketEntities (frame_t *oldframe, frame_t *newframe) 366: { 367: int newnum; 368: int bits; 369: entity_state_t *oldstate; 370: int oldindex, oldnum; 371: 372: newframe->parse_entities = cl.parse_entities; 373: newframe->num_entities = 0; 374: 375: // delta from the entities present in oldframe 376: oldindex = 0; 377: if (!oldframe) 378: oldnum = 99999; 379: else 380: { 381: if (oldindex >= oldframe->num_entities) 382: oldnum = 99999; 383: else 384: { 385: oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)]; 386: oldnum = oldstate->number; 387: } 388: } 1.1.1.2 ! root 389: 1.1 root 390: while (1) 391: { 392: newnum = CL_ParseEntityBits (&bits); 393: if (newnum >= MAX_EDICTS) 394: Com_Error (ERR_DROP,"CL_ParsePacketEntities: bad number:%i", newnum); 395: 396: if (net_message.readcount > net_message.cursize) 397: Com_Error (ERR_DROP,"CL_ParsePacketEntities: end of message"); 398: 399: if (!newnum) 400: break; 401: 402: while (oldnum < newnum) 403: { // one or more entities from the old packet are unchanged 404: if (cl_shownet->value == 3) 405: Com_Printf (" unchanged: %i\n", oldnum); 406: CL_DeltaEntity (newframe, oldnum, oldstate, 0); 407: 408: oldindex++; 409: 410: if (oldindex >= oldframe->num_entities) 411: oldnum = 99999; 412: else 413: { 414: oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)]; 415: oldnum = oldstate->number; 416: } 417: } 418: 419: if (bits & U_REMOVE) 420: { // the entity present in oldframe is not in the current frame 421: if (cl_shownet->value == 3) 422: Com_Printf (" remove: %i\n", newnum); 423: if (oldnum != newnum) 424: Com_Printf ("U_REMOVE: oldnum != newnum\n"); 425: 426: oldindex++; 427: 428: if (oldindex >= oldframe->num_entities) 429: oldnum = 99999; 430: else 431: { 432: oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)]; 433: oldnum = oldstate->number; 434: } 435: continue; 436: } 437: 438: if (oldnum == newnum) 439: { // delta from previous state 440: if (cl_shownet->value == 3) 441: Com_Printf (" delta: %i\n", newnum); 442: CL_DeltaEntity (newframe, newnum, oldstate, bits); 443: 444: oldindex++; 445: 446: if (oldindex >= oldframe->num_entities) 447: oldnum = 99999; 448: else 449: { 450: oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)]; 451: oldnum = oldstate->number; 452: } 453: continue; 454: } 455: 456: if (oldnum > newnum) 457: { // delta from baseline 458: if (cl_shownet->value == 3) 459: Com_Printf (" baseline: %i\n", newnum); 460: CL_DeltaEntity (newframe, newnum, &cl_entities[newnum].baseline, bits); 461: continue; 462: } 463: 464: } 465: 466: // any remaining entities in the old frame are copied over 467: while (oldnum != 99999) 468: { // one or more entities from the old packet are unchanged 469: if (cl_shownet->value == 3) 470: Com_Printf (" unchanged: %i\n", oldnum); 471: CL_DeltaEntity (newframe, oldnum, oldstate, 0); 472: 473: oldindex++; 474: 475: if (oldindex >= oldframe->num_entities) 476: oldnum = 99999; 477: else 478: { 479: oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)]; 480: oldnum = oldstate->number; 481: } 482: } 483: } 1.1.1.2 ! root 484: ! 485: ! 486: 1.1 root 487: /* 488: =================== 489: CL_ParsePlayerstate 490: =================== 491: */ 492: void CL_ParsePlayerstate (frame_t *oldframe, frame_t *newframe) 493: { 494: int flags; 495: player_state_t *state; 496: int i; 497: int statbits; 1.1.1.2 ! root 498: 1.1 root 499: state = &newframe->playerstate; 500: 501: // clear to old value before delta parsing 502: if (oldframe) 503: *state = oldframe->playerstate; 504: else 505: memset (state, 0, sizeof(*state)); 1.1.1.2 ! root 506: 1.1 root 507: flags = MSG_ReadShort (&net_message); 508: 509: // 510: // parse the pmove_state_t 511: // 512: if (flags & PS_M_TYPE) 513: state->pmove.pm_type = MSG_ReadByte (&net_message); 514: 515: if (flags & PS_M_ORIGIN) 516: { 517: state->pmove.origin[0] = MSG_ReadShort (&net_message); 518: state->pmove.origin[1] = MSG_ReadShort (&net_message); 519: state->pmove.origin[2] = MSG_ReadShort (&net_message); 520: } 521: 522: if (flags & PS_M_VELOCITY) 523: { 524: state->pmove.velocity[0] = MSG_ReadShort (&net_message); 525: state->pmove.velocity[1] = MSG_ReadShort (&net_message); 526: state->pmove.velocity[2] = MSG_ReadShort (&net_message); 527: } 528: 529: if (flags & PS_M_TIME) 530: state->pmove.pm_time = MSG_ReadByte (&net_message); 531: 532: if (flags & PS_M_FLAGS) 533: state->pmove.pm_flags = MSG_ReadByte (&net_message); 534: 535: if (flags & PS_M_GRAVITY) 536: state->pmove.gravity = MSG_ReadShort (&net_message); 537: 538: if (flags & PS_M_DELTA_ANGLES) 539: { 540: state->pmove.delta_angles[0] = MSG_ReadShort (&net_message); 541: state->pmove.delta_angles[1] = MSG_ReadShort (&net_message); 542: state->pmove.delta_angles[2] = MSG_ReadShort (&net_message); 543: } 544: 545: if (cl.attractloop) 546: state->pmove.pm_type = PM_FREEZE; // demo playback 547: 548: // 549: // parse the rest of the player_state_t 550: // 551: if (flags & PS_VIEWOFFSET) 552: { 553: state->viewoffset[0] = MSG_ReadChar (&net_message) * 0.25; 554: state->viewoffset[1] = MSG_ReadChar (&net_message) * 0.25; 555: state->viewoffset[2] = MSG_ReadChar (&net_message) * 0.25; 556: } 557: 558: if (flags & PS_VIEWANGLES) 559: { 560: state->viewangles[0] = MSG_ReadAngle16 (&net_message); 561: state->viewangles[1] = MSG_ReadAngle16 (&net_message); 562: state->viewangles[2] = MSG_ReadAngle16 (&net_message); 563: } 564: 565: if (flags & PS_KICKANGLES) 566: { 567: state->kick_angles[0] = MSG_ReadChar (&net_message) * 0.25; 568: state->kick_angles[1] = MSG_ReadChar (&net_message) * 0.25; 569: state->kick_angles[2] = MSG_ReadChar (&net_message) * 0.25; 570: } 1.1.1.2 ! root 571: 1.1 root 572: if (flags & PS_WEAPONINDEX) 573: { 574: state->gunindex = MSG_ReadByte (&net_message); 575: } 1.1.1.2 ! root 576: 1.1 root 577: if (flags & PS_WEAPONFRAME) 578: { 579: state->gunframe = MSG_ReadByte (&net_message); 580: state->gunoffset[0] = MSG_ReadChar (&net_message)*0.25; 581: state->gunoffset[1] = MSG_ReadChar (&net_message)*0.25; 582: state->gunoffset[2] = MSG_ReadChar (&net_message)*0.25; 583: state->gunangles[0] = MSG_ReadChar (&net_message)*0.25; 584: state->gunangles[1] = MSG_ReadChar (&net_message)*0.25; 585: state->gunangles[2] = MSG_ReadChar (&net_message)*0.25; 586: } 1.1.1.2 ! root 587: 1.1 root 588: if (flags & PS_BLEND) 589: { 590: state->blend[0] = MSG_ReadByte (&net_message)/255.0; 591: state->blend[1] = MSG_ReadByte (&net_message)/255.0; 592: state->blend[2] = MSG_ReadByte (&net_message)/255.0; 593: state->blend[3] = MSG_ReadByte (&net_message)/255.0; 594: } 1.1.1.2 ! root 595: 1.1 root 596: if (flags & PS_FOV) 597: state->fov = MSG_ReadByte (&net_message); 1.1.1.2 ! root 598: 1.1 root 599: if (flags & PS_RDFLAGS) 600: state->rdflags = MSG_ReadByte (&net_message); 1.1.1.2 ! root 601: 1.1 root 602: // parse stats 603: statbits = MSG_ReadLong (&net_message); 604: for (i=0 ; i<MAX_STATS ; i++) 605: if (statbits & (1<<i) ) 606: state->stats[i] = MSG_ReadShort(&net_message); 607: } 1.1.1.2 ! root 608: ! 609: 1.1 root 610: /* 611: ================== 612: CL_FireEntityEvents 613: 614: ================== 615: */ 616: void CL_FireEntityEvents (frame_t *frame) 617: { 618: entity_state_t *s1; 619: int pnum, num; 620: 621: for (pnum = 0 ; pnum<frame->num_entities ; pnum++) 622: { 623: num = (frame->parse_entities + pnum)&(MAX_PARSE_ENTITIES-1); 624: s1 = &cl_parse_entities[num]; 625: if (s1->event) 626: CL_EntityEvent (s1); 627: 628: // EF_TELEPORTER acts like an event, but is not cleared each frame 629: if (s1->effects & EF_TELEPORTER) 630: CL_TeleporterParticles (s1); 631: } 632: } 633: 634: 635: /* 636: ================ 637: CL_ParseFrame 638: ================ 639: */ 640: void CL_ParseFrame (void) 641: { 642: int cmd; 643: int len; 644: frame_t *old; 1.1.1.2 ! root 645: 1.1 root 646: memset (&cl.frame, 0, sizeof(cl.frame)); 1.1.1.2 ! root 647: ! 648: #if 0 ! 649: CL_ClearProjectiles(); // clear projectiles for new frame ! 650: #endif ! 651: 1.1 root 652: cl.frame.serverframe = MSG_ReadLong (&net_message); 653: cl.frame.deltaframe = MSG_ReadLong (&net_message); 654: cl.frame.servertime = cl.frame.serverframe*100; 655: 656: // BIG HACK to let old demos continue to work 657: if (cls.serverProtocol != 26) 658: cl.surpressCount = MSG_ReadByte (&net_message); 659: 660: if (cl_shownet->value == 3) 661: Com_Printf (" frame:%i delta:%i\n", cl.frame.serverframe, 662: cl.frame.deltaframe); 663: 664: // If the frame is delta compressed from data that we 665: // no longer have available, we must suck up the rest of 666: // the frame, but not use it, then ask for a non-compressed 667: // message 668: if (cl.frame.deltaframe <= 0) 669: { 670: cl.frame.valid = true; // uncompressed frame 671: old = NULL; 672: cls.demowaiting = false; // we can start recording now 673: } 674: else 675: { 676: old = &cl.frames[cl.frame.deltaframe & UPDATE_MASK]; 677: if (!old->valid) 678: { // should never happen 679: Com_Printf ("Delta from invalid frame (not supposed to happen!).\n"); 680: } 681: if (old->serverframe != cl.frame.deltaframe) 682: { // The frame that the server did the delta from 683: // is too old, so we can't reconstruct it properly. 684: Com_Printf ("Delta frame too old.\n"); 685: } 686: else if (cl.parse_entities - old->parse_entities > MAX_PARSE_ENTITIES-128) 687: { 688: Com_Printf ("Delta parse_entities too old.\n"); 689: } 690: else 691: cl.frame.valid = true; // valid delta parse 692: } 1.1.1.2 ! root 693: 1.1 root 694: // clamp time 695: if (cl.time > cl.frame.servertime) 696: cl.time = cl.frame.servertime; 697: else if (cl.time < cl.frame.servertime - 100) 698: cl.time = cl.frame.servertime - 100; 699: 700: // read areabits 701: len = MSG_ReadByte (&net_message); 702: MSG_ReadData (&net_message, &cl.frame.areabits, len); 703: 704: // read playerinfo 705: cmd = MSG_ReadByte (&net_message); 706: SHOWNET(svc_strings[cmd]); 707: if (cmd != svc_playerinfo) 708: Com_Error (ERR_DROP, "CL_ParseFrame: not playerinfo"); 709: CL_ParsePlayerstate (old, &cl.frame); 710: 711: // read packet entities 712: cmd = MSG_ReadByte (&net_message); 713: SHOWNET(svc_strings[cmd]); 714: if (cmd != svc_packetentities) 715: Com_Error (ERR_DROP, "CL_ParseFrame: not packetentities"); 716: CL_ParsePacketEntities (old, &cl.frame); 717: 1.1.1.2 ! root 718: #if 0 ! 719: if (cmd == svc_packetentities2) ! 720: CL_ParseProjectiles(); ! 721: #endif ! 722: 1.1 root 723: // save the frame off in the backup array for later delta comparisons 724: cl.frames[cl.frame.serverframe & UPDATE_MASK] = cl.frame; 725: 726: if (cl.frame.valid) 727: { 728: // getting a valid frame message ends the connection process 729: if (cls.state != ca_active) 730: { 731: cls.state = ca_active; 732: cl.force_refdef = true; 733: cl.predicted_origin[0] = cl.frame.playerstate.pmove.origin[0]*0.125; 734: cl.predicted_origin[1] = cl.frame.playerstate.pmove.origin[1]*0.125; 735: cl.predicted_origin[2] = cl.frame.playerstate.pmove.origin[2]*0.125; 736: VectorCopy (cl.frame.playerstate.viewangles, cl.predicted_angles); 737: if (cls.disable_servercount != cl.servercount 738: && cl.refresh_prepped) 739: SCR_EndLoadingPlaque (); // get rid of loading plaque 740: } 741: cl.sound_prepped = true; // can start mixing ambient sounds 742: 743: // fire entity events 744: CL_FireEntityEvents (&cl.frame); 745: CL_CheckPredictionError (); 746: } 747: } 1.1.1.2 ! root 748: 1.1 root 749: /* 750: ========================================================================== 751: 752: INTERPOLATE BETWEEN FRAMES TO GET RENDERING PARMS 753: 754: ========================================================================== 755: */ 756: 1.1.1.2 ! root 757: struct model_s *S_RegisterSexedModel (entity_state_t *ent, char *base) ! 758: { ! 759: int n; ! 760: char *p; ! 761: struct model_s *mdl; ! 762: char model[MAX_QPATH]; ! 763: char buffer[MAX_QPATH]; ! 764: ! 765: // determine what model the client is using ! 766: model[0] = 0; ! 767: n = CS_PLAYERSKINS + ent->number - 1; ! 768: if (cl.configstrings[n][0]) ! 769: { ! 770: p = strchr(cl.configstrings[n], '\\'); ! 771: if (p) ! 772: { ! 773: p += 1; ! 774: strcpy(model, p); ! 775: p = strchr(model, '/'); ! 776: if (p) ! 777: *p = 0; ! 778: } ! 779: } ! 780: // if we can't figure it out, they're male ! 781: if (!model[0]) ! 782: strcpy(model, "male"); ! 783: ! 784: Com_sprintf (buffer, sizeof(buffer), "players/%s/%s", model, base+1); ! 785: mdl = re.RegisterModel(buffer); ! 786: if (!mdl) { ! 787: // not found, try default weapon model ! 788: Com_sprintf (buffer, sizeof(buffer), "players/%s/weapon.md2", model); ! 789: mdl = re.RegisterModel(buffer); ! 790: if (!mdl) { ! 791: // no, revert to the male model ! 792: Com_sprintf (buffer, sizeof(buffer), "players/%s/%s", "male", base+1); ! 793: mdl = re.RegisterModel(buffer); ! 794: if (!mdl) { ! 795: // last try, default male weapon.md2 ! 796: Com_sprintf (buffer, sizeof(buffer), "players/male/weapon.md2"); ! 797: mdl = re.RegisterModel(buffer); ! 798: } ! 799: } ! 800: } ! 801: ! 802: return mdl; ! 803: } ! 804: 1.1 root 805: /* 806: =============== 807: CL_AddPacketEntities 808: 809: =============== 810: */ 811: void CL_AddPacketEntities (frame_t *frame) 812: { 813: entity_t ent; 814: entity_state_t *s1; 815: float autorotate; 816: int i; 817: int pnum; 818: centity_t *cent; 819: int autoanim; 820: clientinfo_t *ci; 821: int effects, renderfx; 822: 823: // bonus items rotate at a fixed rate 824: autorotate = anglemod(cl.time/10); 825: 826: // brush models can auto animate their frames 827: autoanim = 2*cl.time/1000; 828: 829: memset (&ent, 0, sizeof(ent)); 830: 831: for (pnum = 0 ; pnum<frame->num_entities ; pnum++) 832: { 833: s1 = &cl_parse_entities[(frame->parse_entities+pnum)&(MAX_PARSE_ENTITIES-1)]; 834: 835: cent = &cl_entities[s1->number]; 836: 837: effects = s1->effects; 838: renderfx = s1->renderfx; 839: 840: // set frame 841: if (effects & EF_ANIM01) 842: ent.frame = autoanim & 1; 843: else if (effects & EF_ANIM23) 844: ent.frame = 2 + (autoanim & 1); 845: else if (effects & EF_ANIM_ALL) 846: ent.frame = autoanim; 847: else if (effects & EF_ANIM_ALLFAST) 848: ent.frame = cl.time / 100; 849: else 850: ent.frame = s1->frame; 851: 852: // quad and pent can do different things on client 853: if (effects & EF_PENT) 854: { 855: effects &= ~EF_PENT; 856: effects |= EF_COLOR_SHELL; 857: renderfx |= RF_SHELL_RED; 858: } 859: 860: if (effects & EF_QUAD) 861: { 862: effects &= ~EF_QUAD; 863: effects |= EF_COLOR_SHELL; 864: renderfx |= RF_SHELL_BLUE; 865: } 866: 867: ent.oldframe = cent->prev.frame; 868: ent.backlerp = 1.0 - cl.lerpfrac; 869: 870: if (renderfx & (RF_FRAMELERP|RF_BEAM)) 871: { // step origin discretely, because the frames 872: // do the animation properly 873: VectorCopy (cent->current.origin, ent.origin); 874: VectorCopy (cent->current.old_origin, ent.oldorigin); 875: } 876: else 877: { // interpolate origin 878: for (i=0 ; i<3 ; i++) 879: { 880: ent.origin[i] = ent.oldorigin[i] = cent->prev.origin[i] + cl.lerpfrac * 881: (cent->current.origin[i] - cent->prev.origin[i]); 882: } 883: } 884: 885: // create a new entity 886: 887: // tweak the color of beams 888: if ( renderfx & RF_BEAM ) 889: { // the four beam colors are encoded in 32 bits of skinnum (hack) 890: ent.alpha = 0.30; 891: ent.skinnum = (s1->skinnum >> ((rand() % 4)*8)) & 0xff; 892: ent.model = NULL; 893: } 894: else 895: { 896: // set skin 897: if (s1->modelindex == 255) 898: { // use custom player skin 899: ent.skinnum = 0; 1.1.1.2 ! root 900: ci = &cl.clientinfo[s1->skinnum & 0xff]; 1.1 root 901: ent.skin = ci->skin; 902: ent.model = ci->model; 903: if (!ent.skin || !ent.model) 904: { 905: ent.skin = cl.baseclientinfo.skin; 906: ent.model = cl.baseclientinfo.model; 907: } 908: } 909: else 910: { 911: ent.skinnum = s1->skinnum; 912: ent.skin = NULL; 913: ent.model = cl.model_draw[s1->modelindex]; 914: } 915: } 916: 917: // only used for black hole model right now, FIXME: do better 918: if (renderfx == RF_TRANSLUCENT) 919: ent.alpha = 0.70; 920: 921: // render effects (fullbright, translucent, etc) 922: if ((effects & EF_COLOR_SHELL)) 923: ent.flags = 0; // renderfx go on color shell entity 924: else 925: ent.flags = renderfx; 926: 927: // calculate angles 928: if (effects & EF_ROTATE) 929: { // some bonus items auto-rotate 930: ent.angles[0] = 0; 931: ent.angles[1] = autorotate; 932: ent.angles[2] = 0; 933: } 1.1.1.2 ! root 934: // RAFAEL ! 935: else if (effects & EF_SPINNINGLIGHTS) ! 936: { ! 937: ent.angles[0] = 0; ! 938: ent.angles[1] = anglemod(cl.time/2) + s1->angles[1]; ! 939: ent.angles[2] = 180; ! 940: { ! 941: vec3_t forward; ! 942: vec3_t start; ! 943: ! 944: AngleVectors (ent.angles, forward, NULL, NULL); ! 945: VectorMA (ent.origin, 64, forward, start); ! 946: V_AddLight (start, 100, 1, 0, 0); ! 947: } ! 948: } 1.1 root 949: else 950: { // interpolate angles 951: float a1, a2; 952: 953: for (i=0 ; i<3 ; i++) 954: { 955: a1 = cent->current.angles[i]; 956: a2 = cent->prev.angles[i]; 957: ent.angles[i] = LerpAngle (a2, a1, cl.lerpfrac); 958: } 959: } 960: 961: if (s1->number == cl.playernum+1) 962: { 963: ent.flags |= RF_VIEWERMODEL; // only draw from mirrors 964: // FIXME: still pass to refresh 965: 966: if (effects & EF_FLAG1) 967: V_AddLight (ent.origin, 225, 1.0, 0.1, 0.1); 968: else if (effects & EF_FLAG2) 969: V_AddLight (ent.origin, 225, 0.1, 0.1, 1.0); 970: 971: continue; 972: } 973: 974: // if set to invisible, skip 975: if (!s1->modelindex) 976: continue; 977: 978: if (effects & EF_BFG) 979: { 980: ent.flags |= RF_TRANSLUCENT; 981: ent.alpha = 0.30; 982: } 983: 1.1.1.2 ! root 984: // RAFAEL ! 985: if (effects & EF_PLASMA) ! 986: { ! 987: ent.flags |= RF_TRANSLUCENT; ! 988: ent.alpha = 0.6; ! 989: } ! 990: 1.1 root 991: // add to refresh list 992: V_AddEntity (&ent); 993: 994: // color shells generate a seperate entity for the main model 995: if (effects & EF_COLOR_SHELL) 996: { 997: ent.flags = renderfx | RF_TRANSLUCENT; 998: ent.alpha = 0.30; 999: V_AddEntity (&ent); 1000: } 1001: 1002: ent.skin = NULL; // never use a custom skin on others 1003: ent.skinnum = 0; 1004: ent.flags = 0; 1005: ent.alpha = 0; 1006: 1007: // duplicate for linked models 1008: if (s1->modelindex2) 1009: { 1010: if (s1->modelindex2 == 255) 1011: { // custom weapon 1.1.1.2 ! root 1012: ci = &cl.clientinfo[s1->skinnum & 0xff]; ! 1013: i = (s1->skinnum >> 8); // 0 is default weapon model ! 1014: if (!cl_vwep->value || i > MAX_CLIENTWEAPONMODELS - 1) ! 1015: i = 0; ! 1016: ent.model = ci->weaponmodel[i]; ! 1017: if (!ent.model) { ! 1018: if (i != 0) ! 1019: ent.model = ci->weaponmodel[0]; ! 1020: if (!ent.model) ! 1021: ent.model = cl.baseclientinfo.weaponmodel[0]; ! 1022: } 1.1 root 1023: } 1024: else 1025: ent.model = cl.model_draw[s1->modelindex2]; 1026: V_AddEntity (&ent); 1027: } 1028: if (s1->modelindex3) 1029: { 1030: ent.model = cl.model_draw[s1->modelindex3]; 1031: V_AddEntity (&ent); 1032: } 1033: if (s1->modelindex4) 1034: { 1035: ent.model = cl.model_draw[s1->modelindex4]; 1036: V_AddEntity (&ent); 1037: } 1038: 1039: if ( effects & EF_POWERSCREEN ) 1040: { 1041: ent.model = cl_mod_powerscreen; 1042: ent.oldframe = 0; 1043: ent.frame = 0; 1044: ent.flags |= (RF_TRANSLUCENT | RF_SHELL_GREEN); 1045: ent.alpha = 0.30; 1046: V_AddEntity (&ent); 1047: } 1048: 1049: // add automatic particle trails 1050: if ( (effects&~EF_ROTATE) ) 1051: { 1052: if (effects & EF_ROCKET) 1053: { 1054: CL_RocketTrail (cent->lerp_origin, ent.origin, cent); 1055: V_AddLight (ent.origin, 200, 1, 1, 0); 1056: } 1057: else if (effects & EF_BLASTER) 1058: { 1059: CL_BlasterTrail (cent->lerp_origin, ent.origin); 1060: V_AddLight (ent.origin, 200, 1, 1, 0); 1061: } 1062: else if (effects & EF_HYPERBLASTER) 1063: { 1064: V_AddLight (ent.origin, 200, 1, 1, 0); 1065: } 1066: else if (effects & EF_GIB) 1067: { 1068: CL_DiminishingTrail (cent->lerp_origin, ent.origin, cent, effects); 1069: } 1070: else if (effects & EF_GRENADE) 1071: { 1072: CL_DiminishingTrail (cent->lerp_origin, ent.origin, cent, effects); 1073: } 1074: else if (effects & EF_FLIES) 1075: { 1076: CL_FlyEffect (cent, ent.origin); 1077: } 1078: else if (effects & EF_BFG) 1079: { 1080: static int bfg_lightramp[6] = {300, 400, 600, 300, 150, 75}; 1081: 1082: if (effects & EF_ANIM_ALLFAST) 1083: { 1084: CL_BfgParticles (&ent); 1085: i = 200; 1086: } 1087: else 1088: { 1089: i = bfg_lightramp[s1->frame]; 1090: } 1091: V_AddLight (ent.origin, i, 0, 1, 0); 1092: } 1.1.1.2 ! root 1093: // RAFAEL ! 1094: else if (effects & EF_TRAP) ! 1095: { ! 1096: ent.origin[2] += 32; ! 1097: CL_TrapParticles (&ent); ! 1098: i = (rand()%100) + 100; ! 1099: V_AddLight (ent.origin, i, 1, 0.8, 0.1); ! 1100: } 1.1 root 1101: else if (effects & EF_FLAG1) 1102: { 1103: CL_FlagTrail (cent->lerp_origin, ent.origin, 242); 1104: V_AddLight (ent.origin, 225, 1, 0.1, 0.1); 1105: } 1106: else if (effects & EF_FLAG2) 1107: { 1108: CL_FlagTrail (cent->lerp_origin, ent.origin, 115); 1109: V_AddLight (ent.origin, 225, 0.1, 0.1, 1); 1110: } 1.1.1.2 ! root 1111: // RAFAEL 1.1 root 1112: else if (effects & EF_GREENGIB) 1113: { 1114: CL_DiminishingTrail (cent->lerp_origin, ent.origin, cent, effects); 1115: } 1.1.1.2 ! root 1116: // RAFAEL ! 1117: else if (effects & EF_IONRIPPER) 1.1 root 1118: { 1.1.1.2 ! root 1119: CL_IonripperTrail (cent->lerp_origin, ent.origin); 1.1 root 1120: V_AddLight (ent.origin, 100, 1, 0.5, 0.5); 1121: } 1.1.1.2 ! root 1122: // RAFAEL ! 1123: else if (effects & EF_BLUEHYPERBLASTER) ! 1124: { ! 1125: V_AddLight (ent.origin, 200, 0, 0, 1); ! 1126: } ! 1127: // RAFAEL ! 1128: else if (effects & EF_PLASMA) ! 1129: { ! 1130: if (effects & EF_ANIM_ALLFAST) ! 1131: { ! 1132: CL_BlasterTrail (cent->lerp_origin, ent.origin); ! 1133: } ! 1134: V_AddLight (ent.origin, 130, 1, 0.5, 0.5); ! 1135: } 1.1 root 1136: } 1137: 1138: VectorCopy (ent.origin, cent->lerp_origin); 1139: } 1140: } 1141: 1142: 1143: 1144: /* 1145: ============== 1146: CL_AddViewWeapon 1147: ============== 1148: */ 1149: void CL_AddViewWeapon (player_state_t *ps, player_state_t *ops) 1150: { 1151: entity_t gun; // view model 1152: int i; 1153: 1154: // allow the gun to be completely removed 1155: if (!cl_gun->value) 1156: return; 1157: 1158: // don't draw gun if in wide angle view 1159: if (ps->fov > 90) 1160: return; 1161: 1162: memset (&gun, 0, sizeof(gun)); 1163: 1164: if (gun_model) 1165: gun.model = gun_model; // development tool 1166: else 1167: gun.model = cl.model_draw[ps->gunindex]; 1168: if (!gun.model) 1169: return; 1170: 1171: // set up gun position 1172: for (i=0 ; i<3 ; i++) 1173: { 1174: gun.origin[i] = cl.refdef.vieworg[i] + ops->gunoffset[i] 1175: + cl.lerpfrac * (ps->gunoffset[i] - ops->gunoffset[i]); 1176: gun.angles[i] = cl.refdef.viewangles[i] + LerpAngle (ops->gunangles[i], 1177: ps->gunangles[i], cl.lerpfrac); 1178: } 1179: 1180: if (gun_frame) 1181: { 1182: gun.frame = gun_frame; // development tool 1183: gun.oldframe = gun_frame; // development tool 1184: } 1185: else 1186: { 1187: gun.frame = ps->gunframe; 1188: if (gun.frame == 0) 1189: gun.oldframe = 0; // just changed weapons, don't lerp from old 1190: else 1191: gun.oldframe = ops->gunframe; 1192: } 1193: 1194: gun.flags = RF_MINLIGHT | RF_DEPTHHACK | RF_WEAPONMODEL; 1195: gun.backlerp = 1.0 - cl.lerpfrac; 1196: VectorCopy (gun.origin, gun.oldorigin); // don't lerp at all 1197: V_AddEntity (&gun); 1198: } 1199: 1.1.1.2 ! root 1200: 1.1 root 1201: /* 1202: =============== 1203: CL_CalcViewValues 1.1.1.2 ! root 1204: 1.1 root 1205: Sets cl.refdef view values 1206: =============== 1207: */ 1208: void CL_CalcViewValues (void) 1209: { 1210: int i; 1211: float lerp, backlerp; 1212: centity_t *ent; 1213: frame_t *oldframe; 1214: player_state_t *ps, *ops; 1215: 1216: // find the previous frame to interpolate from 1217: ps = &cl.frame.playerstate; 1218: i = (cl.frame.serverframe - 1) & UPDATE_MASK; 1219: oldframe = &cl.frames[i]; 1220: if (oldframe->serverframe != cl.frame.serverframe-1 || !oldframe->valid) 1221: oldframe = &cl.frame; // previous frame was dropped or involid 1222: ops = &oldframe->playerstate; 1.1.1.2 ! root 1223: 1.1 root 1224: // see if the player entity was teleported this frame 1225: if ( fabs(ops->pmove.origin[0] - ps->pmove.origin[0]) > 256*8 1226: || abs(ops->pmove.origin[1] - ps->pmove.origin[1]) > 256*8 1227: || abs(ops->pmove.origin[2] - ps->pmove.origin[2]) > 256*8) 1228: ops = ps; // don't interpolate 1229: 1230: ent = &cl_entities[cl.playernum+1]; 1231: lerp = cl.lerpfrac; 1232: 1233: // calculate the origin 1234: if ((cl_predict->value) && !(cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION)) 1235: { // use predicted values 1236: unsigned delta; 1237: 1238: backlerp = 1.0 - lerp; 1239: for (i=0 ; i<3 ; i++) 1240: { 1241: cl.refdef.vieworg[i] = cl.predicted_origin[i] + ops->viewoffset[i] 1242: + cl.lerpfrac * (ps->viewoffset[i] - ops->viewoffset[i]) 1243: - backlerp * cl.prediction_error[i]; 1244: } 1245: 1246: // smooth out stair climbing 1247: delta = cls.realtime - cl.predicted_step_time; 1248: if (delta < 100) 1249: cl.refdef.vieworg[2] -= cl.predicted_step * (100 - delta) * 0.01; 1250: } 1251: else 1252: { // just use interpolated values 1253: for (i=0 ; i<3 ; i++) 1254: cl.refdef.vieworg[i] = ops->pmove.origin[i]*0.125 + ops->viewoffset[i] 1255: + lerp * (ps->pmove.origin[i]*0.125 + ps->viewoffset[i] 1256: - (ops->pmove.origin[i]*0.125 + ops->viewoffset[i]) ); 1257: } 1258: 1259: // if not running a demo or on a locked frame, add the local angle movement 1260: if ( cl.frame.playerstate.pmove.pm_type < PM_DEAD ) 1261: { // use predicted values 1262: for (i=0 ; i<3 ; i++) 1263: cl.refdef.viewangles[i] = cl.predicted_angles[i]; 1264: } 1265: else 1266: { // just use interpolated values 1267: for (i=0 ; i<3 ; i++) 1268: cl.refdef.viewangles[i] = LerpAngle (ops->viewangles[i], ps->viewangles[i], lerp); 1269: } 1270: 1271: for (i=0 ; i<3 ; i++) 1272: cl.refdef.viewangles[i] += LerpAngle (ops->kick_angles[i], ps->kick_angles[i], lerp); 1.1.1.2 ! root 1273: 1.1 root 1274: AngleVectors (cl.refdef.viewangles, cl.v_forward, cl.v_right, cl.v_up); 1275: 1276: // interpolate field of view 1277: cl.refdef.fov_x = ops->fov + lerp * (ps->fov - ops->fov); 1.1.1.2 ! root 1278: 1.1 root 1279: // don't interpolate blend color 1280: for (i=0 ; i<4 ; i++) 1281: cl.refdef.blend[i] = ps->blend[i]; 1282: 1283: // add the weapon 1284: CL_AddViewWeapon (ps, ops); 1285: } 1.1.1.2 ! root 1286: 1.1 root 1287: /* 1288: =============== 1289: CL_AddEntities 1.1.1.2 ! root 1290: 1.1 root 1291: Emits all entities, particles, and lights to the refresh 1292: =============== 1293: */ 1294: void CL_AddEntities (void) 1295: { 1296: if (cls.state != ca_active) 1297: return; 1.1.1.2 ! root 1298: 1.1 root 1299: if (cl.time > cl.frame.servertime) 1300: { 1301: if (cl_showclamp->value) 1302: Com_Printf ("high clamp %i\n", cl.time - cl.frame.servertime); 1303: cl.time = cl.frame.servertime; 1304: cl.lerpfrac = 1.0; 1305: } 1306: else if (cl.time < cl.frame.servertime - 100) 1307: { 1308: if (cl_showclamp->value) 1309: Com_Printf ("low clamp %i\n", cl.frame.servertime-100 - cl.time); 1310: cl.time = cl.frame.servertime - 100; 1311: cl.lerpfrac = 0; 1312: } 1313: else 1314: cl.lerpfrac = 1.0 - (cl.frame.servertime - cl.time) * 0.01; 1315: 1316: if (cl_timedemo->value) 1317: cl.lerpfrac = 1.0; 1318: 1319: CL_AddPacketEntities (&cl.frame); 1.1.1.2 ! root 1320: #if 0 ! 1321: CL_AddProjectiles (); ! 1322: #endif 1.1 root 1323: CL_AddTEnts (); 1324: CL_AddParticles (); 1325: CL_AddDLights (); 1326: CL_AddLightStyles (); 1.1.1.2 ! root 1327: 1.1 root 1328: CL_CalcViewValues (); 1329: } 1.1.1.2 ! root 1330: ! 1331: ! 1332: 1.1 root 1333: /* 1334: =============== 1335: CL_GetEntitySoundOrigin 1.1.1.2 ! root 1336: 1.1 root 1337: Called to get the sound spatialization origin 1338: =============== 1339: */ 1340: void CL_GetEntitySoundOrigin (int ent, vec3_t org) 1341: { 1342: centity_t *old; 1.1.1.2 ! root 1343: 1.1 root 1344: if (ent < 0 || ent >= MAX_EDICTS) 1345: Com_Error (ERR_DROP, "CL_GetEntitySoundOrigin: bad ent"); 1346: old = &cl_entities[ent]; 1347: VectorCopy (old->lerp_origin, org); 1.1.1.2 ! root 1348: 1.1 root 1349: // FIXME: bmodel issues... 1350: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.