void ClientReliableWrite_Angle16(client_t *cl, float f) { if (cl->num_backbuf) { MSG_WriteAngle16(&cl->backbuf, f); ClientReliable_FinishWrite(cl); } else MSG_WriteAngle16(&cl->netchan.message, f); }
qbool SV_MVDWritePackets (int num) { demo_frame_t *frame, *nextframe; demo_client_t *cl, *nextcl = NULL; int i, j, flags; qbool valid; double time1, playertime, nexttime; vec3_t origin, angles; sizebuf_t msg; byte msg_buf[MAX_MSGLEN]; demoinfo_t *demoinfo; if (!sv.mvdrecording) return false; SZ_Init(&msg, msg_buf, sizeof(msg_buf)); if (num > demo.parsecount - demo.lastwritten + 1) num = demo.parsecount - demo.lastwritten + 1; // 'num' frames to write for ( ; num; num--, demo.lastwritten++) { SZ_Clear(&msg); frame = &demo.frames[demo.lastwritten&DEMO_FRAMES_MASK]; time1 = frame->time; nextframe = frame; demo.dbuf = &frame->buf; // find two frames // one before the exact time (time - msec) and one after, // then we can interpolte exact position for current frame for (i = 0, cl = frame->clients, demoinfo = demo.info; i < MAX_CLIENTS; i++, cl++, demoinfo++) { if (cl->parsecount != demo.lastwritten) continue; // not valid nexttime = playertime = time1 - cl->sec; valid = false; for (j = demo.lastwritten+1; nexttime < time1 && j < demo.parsecount; j++) { nextframe = &demo.frames[j&DEMO_FRAMES_MASK]; nextcl = &nextframe->clients[i]; if (nextcl->parsecount != j) break; // disconnected? if (nextcl->fixangle) break; // respawned, or walked into teleport, do not interpolate! if (!(nextcl->flags & DF_DEAD) && (cl->flags & DF_DEAD)) break; // respawned, do not interpolate nexttime = nextframe->time - nextcl->sec; if (nexttime >= time1) { // good, found what we were looking for valid = true; break; } } if (valid) { float f = 0; float z = nexttime - playertime; if ( z ) f = (time1 - nexttime) / z; for (j = 0; j < 3; j++) { angles[j] = adjustangle(cl->info.angles[j], nextcl->info.angles[j], 1.0 + f); origin[j] = nextcl->info.origin[j] + f * (nextcl->info.origin[j] - cl->info.origin[j]); } } else { VectorCopy(cl->info.origin, origin); VectorCopy(cl->info.angles, angles); } // now write it to buf flags = cl->flags; for (j=0; j < 3; j++) if (origin[j] != demoinfo->origin[i]) flags |= DF_ORIGIN << j; for (j=0; j < 3; j++) if (angles[j] != demoinfo->angles[j]) flags |= DF_ANGLES << j; if (cl->info.model != demoinfo->model) flags |= DF_MODEL; if (cl->info.effects != demoinfo->effects) flags |= DF_EFFECTS; if (cl->info.skinnum != demoinfo->skinnum) flags |= DF_SKINNUM; if (cl->info.weaponframe != demoinfo->weaponframe) flags |= DF_WEAPONFRAME; MSG_WriteByte (&msg, svc_playerinfo); MSG_WriteByte (&msg, i); MSG_WriteShort (&msg, flags); MSG_WriteByte (&msg, cl->frame); for (j=0 ; j<3 ; j++) if (flags & (DF_ORIGIN << j)) MSG_WriteCoord (&msg, origin[j]); for (j=0 ; j<3 ; j++) if (flags & (DF_ANGLES << j)) MSG_WriteAngle16 (&msg, angles[j]); if (flags & DF_MODEL) MSG_WriteByte (&msg, cl->info.model); if (flags & DF_SKINNUM) MSG_WriteByte (&msg, cl->info.skinnum); if (flags & DF_EFFECTS) MSG_WriteByte (&msg, cl->info.effects); if (flags & DF_WEAPONFRAME) MSG_WriteByte (&msg, cl->info.weaponframe); VectorCopy(cl->info.origin, demoinfo->origin); VectorCopy(cl->info.angles, demoinfo->angles); demoinfo->skinnum = cl->info.skinnum; demoinfo->effects = cl->info.effects; demoinfo->weaponframe = cl->info.weaponframe; demoinfo->model = cl->info.model; } SV_MVDWriteToDisk(demo.lasttype,demo.lastto, (float)time1); // this goes first to reduce demo size a bit SV_MVDWriteToDisk(0,0, (float)time1); // now goes the rest if (msg.cursize) SV_WriteMVDMessage(&msg, dem_all, 0, (float)time1); if (!sv.mvdrecording) { Com_DPrintf("SV_MVDWritePackets: error: in sv.mvdrecording\n"); return false; // ERROR } } if (!sv.mvdrecording) return false; // ERROR if (demo.lastwritten > demo.parsecount) demo.lastwritten = demo.parsecount; demo.dbuf = &demo.frames[demo.parsecount&DEMO_FRAMES_MASK].buf; demo.dbuf->maxsize = MAXSIZE + demo.dbuf->bufsize; return true; }
void ClientReliableWrite_Angle16 (float f) { assert (backbuf_write_started); MSG_WriteAngle16 (&backbuf, f); }
/* ============== CL_SendMove ============== */ void CL_SendMove (const usercmd_t *cmd) { int i; int bits; sizebuf_t buf; byte data[128]; buf.maxsize = 128; buf.cursize = 0; buf.data = data; cl.cmd = *cmd; // // send the movement message // MSG_WriteByte (&buf, clc_move); MSG_WriteFloat (&buf, cl.mtime[0]); // so server can get ping times for (i=0 ; i<3 ; i++) //johnfitz -- 16-bit angles for PROTOCOL_FITZQUAKE if (cl.protocol == PROTOCOL_NETQUAKE) MSG_WriteAngle (&buf, cl.viewangles[i]); else MSG_WriteAngle16 (&buf, cl.viewangles[i]); //johnfitz MSG_WriteShort (&buf, cmd->forwardmove); MSG_WriteShort (&buf, cmd->sidemove); MSG_WriteShort (&buf, cmd->upmove); // // send button bits // bits = 0; if ( in_attack.state & 3 ) bits |= 1; in_attack.state &= ~2; if (in_jump.state & 3) bits |= 2; in_jump.state &= ~2; MSG_WriteByte (&buf, bits); MSG_WriteByte (&buf, in_impulse); in_impulse = 0; // // deliver the message // if (cls.demoplayback) return; // // allways dump the first two message, because it may contain leftover inputs // from the last level // if (++cl.movemessages <= 2) return; if (NET_SendUnreliableMessage (cls.netcon, &buf) == -1) { Con_Printf ("CL_SendMove: lost server connection\n"); CL_Disconnect (); } }