X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=cl_main.c;h=89c2f6ca4ed0b189ea4c32e0617884b74c6ebb62;hb=06d8455f84631224fb6bb29ab1bd56e3f849a086;hp=34a0b42f3e8aed6b24bd192d1b3cb618ed713b50;hpb=9f6e4476fe8049342ac61c87ab7286912c1ff97c;p=xonotic%2Fdarkplaces.git diff --git a/cl_main.c b/cl_main.c index 34a0b42f..89c2f6ca 100644 --- a/cl_main.c +++ b/cl_main.c @@ -41,11 +41,13 @@ cvar_t m_yaw = {"m_yaw","0.022", true}; cvar_t m_forward = {"m_forward","1", true}; cvar_t m_side = {"m_side","0.8", true}; +cvar_t freelook = {"freelook", "1", true}; + +cvar_t demo_nehahra = {"demo_nehahra", "0"}; client_static_t cls; client_state_t cl; // FIXME: put these on hunk? -efrag_t cl_efrags[MAX_EFRAGS]; entity_t cl_entities[MAX_EDICTS]; entity_t cl_static_entities[MAX_STATIC_ENTITIES]; lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; @@ -73,7 +75,6 @@ void CL_ClearState (void) SZ_Clear (&cls.message); // clear other arrays - memset (cl_efrags, 0, sizeof(cl_efrags)); memset (cl_entities, 0, sizeof(cl_entities)); memset (cl_dlights, 0, sizeof(cl_dlights)); memset (cl_lightstyle, 0, sizeof(cl_lightstyle)); @@ -82,20 +83,10 @@ void CL_ClearState (void) // LordHavoc: have to set up the baseline info for alpha and other stuff for (i = 0;i < MAX_EDICTS;i++) { - cl_entities[i].baseline.alpha = 255; - cl_entities[i].baseline.scale = 16; - cl_entities[i].baseline.glowsize = 0; - cl_entities[i].baseline.glowcolor = 254; - cl_entities[i].baseline.colormod = 255; + ClearStateToDefault(&cl_entities[i].state_baseline); + ClearStateToDefault(&cl_entities[i].state_previous); + ClearStateToDefault(&cl_entities[i].state_current); } - -// -// allocate the efrags and chain together into a free list -// - cl.free_efrags = cl_efrags; - for (i=0 ; imodel) + Con_Printf ("%3i:", i); + if (!ent->render.model) { Con_Printf ("EMPTY\n"); continue; } - Con_Printf ("%s:%2i (%5.1f,%5.1f,%5.1f) [%5.1f %5.1f %5.1f]\n" - ,ent->model->name,ent->frame, ent->origin[0], ent->origin[1], ent->origin[2], ent->angles[0], ent->angles[1], ent->angles[2]); + Con_Printf ("%s:%2i (%5.1f,%5.1f,%5.1f) [%5.1f %5.1f %5.1f]\n", ent->render.model->name, ent->render.frame, ent->render.origin[0], ent->render.origin[1], ent->render.origin[2], ent->render.angles[0], ent->render.angles[1], ent->render.angles[2]); } } @@ -292,42 +281,39 @@ CL_AllocDlight =============== */ -dlight_t *CL_AllocDlight (int key) +void CL_AllocDlight (entity_t *ent, vec3_t org, float radius, float red, float green, float blue, float decay, float lifetime) { int i; dlight_t *dl; // first look for an exact key match - if (key) + if (ent) { dl = cl_dlights; - for (i=0 ; ikey == key) - { - memset (dl, 0, sizeof(*dl)); - dl->key = key; - return dl; - } - } + for (i = 0;i < MAX_DLIGHTS;i++, dl++) + if (dl->ent == ent) + goto dlightsetup; } // then look for anything else dl = cl_dlights; - for (i=0 ; idie < cl.time) - { - memset (dl, 0, sizeof(*dl)); - dl->key = key; - return dl; - } - } + for (i = 0;i < MAX_DLIGHTS;i++, dl++) + if (!dl->radius) + goto dlightsetup; - dl = &cl_dlights[0]; + // unable to find one + return; + +dlightsetup: memset (dl, 0, sizeof(*dl)); - dl->key = key; - return dl; + dl->ent = ent; + VectorCopy(org, dl->origin); + dl->radius = radius; + dl->color[0] = red; + dl->color[1] = green; + dl->color[2] = blue; + dl->decay = decay; + dl->die = cl.time + lifetime; } @@ -345,12 +331,20 @@ void CL_DecayLights (void) time = cl.time - cl.oldtime; + c_dlights = 0; dl = cl_dlights; for (i=0 ; idie < cl.time || !dl->radius) + if (!dl->radius) continue; - + if (dl->die < cl.time) + { + dl->radius = 0; + continue; + } + + c_dlights++; // count every dlight in use + dl->radius -= time*dl->decay; if (dl->radius < 0) dl->radius = 0; @@ -371,8 +365,9 @@ float CL_LerpPoint (void) float f, frac; f = cl.mtime[0] - cl.mtime[1]; - - if (!f || cl_nolerp.value || cls.timedemo || sv.active) + + // LordHavoc: lerp in listen games as the server is being capped below the client (usually) + if (!f || cl_nolerp.value || cls.timedemo || (sv.active && svs.maxclients == 1)) { cl.time = cl.mtime[0]; return 1; @@ -384,13 +379,13 @@ float CL_LerpPoint (void) f = 0.1; } frac = (cl.time - cl.mtime[1]) / f; -//Con_Printf ("frac: %f\n",frac); +// Con_Printf ("frac: %f\n",frac); if (frac < 0) { if (frac < -0.01) { cl.time = cl.mtime[1]; -// Con_Printf ("low frac\n"); +// Con_Printf ("low frac\n"); } frac = 0; } @@ -399,7 +394,7 @@ float CL_LerpPoint (void) if (frac > 1.01) { cl.time = cl.mtime[0]; -// Con_Printf ("high frac\n"); +// Con_Printf ("high frac\n"); } frac = 1; } @@ -407,6 +402,37 @@ float CL_LerpPoint (void) return frac; } +float CL_EntityLerpPoint (entity_t *ent) +{ + float f; + + if (cl_nolerp.value || cls.timedemo || (sv.active && svs.maxclients == 1)) + return 1; + + f = ent->state_current.time - ent->state_previous.time; +// Con_Printf(" %g-%g=%g", ent->state_current.time, ent->state_previous.time, f); + + if (f <= 0) + return 1; + if (f >= 0.1) + f = 0.1; + +// Con_Printf(" %g-%g/%g=%f", cl.time, ent->state_previous.time, f, (cl.time - ent->state_previous.time) / f); + f = (cl.time - ent->state_previous.time) / f; + return bound(0, f, 1); +} + +void CL_RelinkStaticEntities() +{ + entity_t *ent, *endent; + if (cl.num_statics > MAX_VISEDICTS) + Host_Error("CL_RelinkStaticEntities: cl.num_statics > MAX_VISEDICTS??\n"); + + ent = cl_static_entities; + endent = ent + cl.num_statics; + for (;ent < endent;ent++) + cl_visedicts[cl_numvisedicts++] = ent; +} /* =============== @@ -418,28 +444,26 @@ void CL_RelinkEntities (void) { entity_t *ent; int i, j; - float frac, f, d; - vec3_t delta; - float bobjrotate; - vec3_t oldorg; - dlight_t *dl; - byte *tempcolor; + float frac, f, d, bobjrotate/*, bobjoffset*/, dlightradius; + vec3_t oldorg, delta, dlightcolor; // determine partial update time frac = CL_LerpPoint (); cl_numvisedicts = 0; + CL_RelinkStaticEntities(); + // // interpolate player info // - for (i=0 ; i<3 ; i++) + for (i = 0;i < 3;i++) cl.velocity[i] = cl.mvelocity[1][i] + frac * (cl.mvelocity[0][i] - cl.mvelocity[1][i]); if (cls.demoplayback) { // interpolate the angles - for (j=0 ; j<3 ; j++) + for (j = 0;j < 3;j++) { d = cl.mviewangles[0][j] - cl.mviewangles[1][j]; if (d > 180) @@ -450,184 +474,218 @@ void CL_RelinkEntities (void) } } - bobjrotate = anglemod(100*cl.time); + bobjrotate = ANGLEMOD(100*cl.time); +// bobjoffset = cos(180 * cl.time * M_PI / 180) * 4.0f + 4.0f; // start on the entity after the world - for (i=1,ent=cl_entities+1 ; imodel) - { // empty slot - if (ent->forcelink) - R_RemoveEfrags (ent); // just became empty - continue; - } - -// if the object wasn't included in the last packet, remove it - if (ent->msgtime != cl.mtime[0]) - { - ent->model = NULL; + // if the object wasn't included in the latest packet, remove it + if (!ent->state_current.active) continue; - } - VectorCopy (ent->origin, oldorg); + VectorCopy (ent->render.origin, oldorg); - if (ent->forcelink) - { // the entity was not updated in the last message - // so move to the final spot - VectorCopy (ent->msg_origins[0], ent->origin); - VectorCopy (ent->msg_angles[0], ent->angles); + if (!ent->state_previous.active) + { + // only one state available + VectorCopy (ent->state_current.origin, ent->render.origin); + VectorCopy (ent->state_current.angles, ent->render.angles); +// Con_Printf(" %i", i); } else - { // if the delta is large, assume a teleport and don't lerp - f = frac; - for (j=0 ; j<3 ; j++) + { + // if the delta is large, assume a teleport and don't lerp + f = CL_EntityLerpPoint(ent); + if (f < 1) { - delta[j] = ent->msg_origins[0][j] - ent->msg_origins[1][j]; - // LordHavoc: increased lerp tolerance from 100 to 200 - if (delta[j] > 200 || delta[j] < -200) - f = 1; // assume a teleportation, not a motion + for (j = 0;j < 3;j++) + { + delta[j] = ent->state_current.origin[j] - ent->state_previous.origin[j]; + // LordHavoc: increased lerp tolerance from 100 to 200 + if (delta[j] > 200 || delta[j] < -200) + f = 1; + } } - - // interpolate the origin and angles - for (j=0 ; j<3 ; j++) + if (f >= 1) + { + // no interpolation + VectorCopy (ent->state_current.origin, ent->render.origin); + VectorCopy (ent->state_current.angles, ent->render.angles); + } + else { - ent->origin[j] = ent->msg_origins[1][j] + f*delta[j]; - - d = ent->msg_angles[0][j] - ent->msg_angles[1][j]; - if (d > 180) - d -= 360; - else if (d < -180) - d += 360; - ent->angles[j] = ent->msg_angles[1][j] + f*d; + // interpolate the origin and angles + for (j = 0;j < 3;j++) + { + ent->render.origin[j] = ent->state_previous.origin[j] + f*delta[j]; + + d = ent->state_current.angles[j] - ent->state_previous.angles[j]; + if (d > 180) + d -= 360; + else if (d < -180) + d += 360; + ent->render.angles[j] = ent->state_previous.angles[j] + f*d; + } } - } - if (ent->effects & EF_BRIGHTFIELD) - R_EntityParticles (ent); - if (ent->effects & EF_MUZZLEFLASH) + ent->render.flags = ent->state_current.flags; + ent->render.effects = ent->state_current.effects; + ent->render.model = cl.model_precache[ent->state_current.modelindex]; + ent->render.frame = ent->state_current.frame; + if (cl.scores == NULL || !ent->state_current.colormap) + ent->render.colormap = -1; // no special coloring + else + ent->render.colormap = cl.scores[ent->state_current.colormap - 1].colors; // color it + ent->render.skinnum = ent->state_current.skin; + ent->render.alpha = ent->state_current.alpha * (1.0f / 255.0f); // FIXME: interpolate? + ent->render.scale = ent->state_current.scale * (1.0f / 16.0f); // FIXME: interpolate? + ent->render.glowsize = ent->state_current.glowsize * 4.0f; // FIXME: interpolate? + ent->render.glowcolor = ent->state_current.glowcolor; + ent->render.colormod[0] = (float) ((ent->state_current.colormod >> 5) & 7) * (1.0f / 7.0f); + ent->render.colormod[1] = (float) ((ent->state_current.colormod >> 2) & 7) * (1.0f / 7.0f); + ent->render.colormod[2] = (float) (ent->state_current.colormod & 3) * (1.0f / 3.0f); + + dlightradius = 0; + dlightcolor[0] = 0; + dlightcolor[1] = 0; + dlightcolor[2] = 0; + + // LordHavoc: if the entity has no effects, don't check each + if (ent->render.effects) { - vec3_t fv, rv, uv; - - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->origin[2] += 16; - AngleVectors (ent->angles, fv, rv, uv); - - VectorMA (dl->origin, 18, fv, dl->origin); - dl->radius = 200 + (rand()&31); - dl->minlight = 32; - dl->die = cl.time + 0.1; - dl->color[0] = 1.0;dl->color[1] = 1.0;dl->color[2] = 1.0; - } - if (ent->effects & EF_BRIGHTLIGHT) - { - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->origin[2] += 16; - dl->radius = 400 + (rand()&31); - dl->die = cl.time + 0.001; - dl->color[0] = 1.0;dl->color[1] = 1.0;dl->color[2] = 1.0; - } - if (ent->effects & EF_DIMLIGHT) - { - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->radius = 200 + (rand()&31); - dl->die = cl.time + 0.001; - dl->color[0] = 1.0;dl->color[1] = 1.0;dl->color[2] = 1.0; - } - // LordHavoc: added EF_RED and EF_BLUE - if (ent->effects & EF_RED) // red - { - if (ent->effects & EF_BLUE) // magenta + if (ent->render.effects & EF_BRIGHTFIELD) + R_EntityParticles (ent); + if (ent->render.effects & EF_MUZZLEFLASH) + { + vec3_t v; + + AngleVectors (ent->render.angles, v, NULL, NULL); + + v[0] = v[0] * 18 + ent->render.origin[0]; + v[1] = v[1] * 18 + ent->render.origin[1]; + v[2] = v[2] * 18 + ent->render.origin[2] + 16; + + CL_AllocDlight (NULL, v, 100, 1, 1, 1, 0, 0.1); + } + if (ent->render.effects & EF_DIMLIGHT) { - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->radius = 200 + (rand()&31); - dl->die = cl.time + 0.001; - dl->color[0] = 0.7;dl->color[1] = 0.07;dl->color[2] = 0.7; + dlightcolor[0] += 200.0f; + dlightcolor[1] += 200.0f; + dlightcolor[2] += 200.0f; } - else // red + if (ent->render.effects & EF_BRIGHTLIGHT) { - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->radius = 200 + (rand()&31); - dl->die = cl.time + 0.001; - dl->color[0] = 0.8;dl->color[1] = 0.05;dl->color[2] = 0.05; + dlightcolor[0] += 400.0f; + dlightcolor[1] += 400.0f; + dlightcolor[2] += 400.0f; + } + // LordHavoc: added EF_RED and EF_BLUE + if (ent->render.effects & EF_RED) // red + { + dlightcolor[0] += 200.0f; + dlightcolor[1] += 20.0f; + dlightcolor[2] += 20.0f; + } + if (ent->render.effects & EF_BLUE) // blue + { + dlightcolor[0] += 20.0f; + dlightcolor[1] += 20.0f; + dlightcolor[2] += 200.0f; + } + else if (ent->render.effects & EF_FLAME) + { + if (ent->render.model) + { + vec3_t mins, maxs; + int temp; + VectorAdd(ent->render.origin, ent->render.model->mins, mins); + VectorAdd(ent->render.origin, ent->render.model->maxs, maxs); + // how many flames to make + temp = (int) (cl.time * 300) - (int) (cl.oldtime * 300); + R_FlameCube(mins, maxs, temp); + } + d = lhrandom(200, 250); + dlightcolor[0] += d * 1.0f; + dlightcolor[1] += d * 0.7f; + dlightcolor[2] += d * 0.3f; } - } - else if (ent->effects & EF_BLUE) // blue - { - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->radius = 200 + (rand()&31); - dl->die = cl.time + 0.001; - dl->color[0] = 0.05;dl->color[1] = 0.05;dl->color[2] = 0.8; } - if (ent->model->flags) // LordHavoc: if the model has no flags, don't check each + // LordHavoc: if the model has no flags, don't check each + if (ent->render.model && ent->render.model->flags) { - // rotate binary objects locally - if (ent->model->flags & EF_ROTATE) - ent->angles[1] = bobjrotate; - if (ent->model->flags & EF_GIB) - R_RocketTrail (oldorg, ent->origin, 2, ent); - else if (ent->model->flags & EF_ZOMGIB) - R_RocketTrail (oldorg, ent->origin, 4, ent); - else if (ent->model->flags & EF_TRACER) - R_RocketTrail (oldorg, ent->origin, 3, ent); - else if (ent->model->flags & EF_TRACER2) - R_RocketTrail (oldorg, ent->origin, 5, ent); - else if (ent->model->flags & EF_ROCKET) + if (ent->render.model->flags & EF_ROTATE) { - R_RocketTrail (oldorg, ent->origin, 0, ent); - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->radius = 200; - dl->die = cl.time + 0.001; - dl->color[0] = 1.0;dl->color[1] = 0.8;dl->color[2] = 0.4; + ent->render.angles[1] = bobjrotate; +// ent->render.origin[2] += bobjoffset; } - else if (ent->model->flags & EF_GRENADE) + // only do trails if present in the previous frame as well + if (ent->state_previous.active) { - if (ent->alpha == -1) // LordHavoc: Nehahra dem compatibility - R_RocketTrail (oldorg, ent->origin, 7, ent); - else - R_RocketTrail (oldorg, ent->origin, 1, ent); + if (ent->render.model->flags & EF_GIB) + R_RocketTrail (oldorg, ent->render.origin, 2, ent); + else if (ent->render.model->flags & EF_ZOMGIB) + R_RocketTrail (oldorg, ent->render.origin, 4, ent); + else if (ent->render.model->flags & EF_TRACER) + R_RocketTrail (oldorg, ent->render.origin, 3, ent); + else if (ent->render.model->flags & EF_TRACER2) + R_RocketTrail (oldorg, ent->render.origin, 5, ent); + else if (ent->render.model->flags & EF_ROCKET) + { + R_RocketTrail (oldorg, ent->render.origin, 0, ent); + dlightcolor[0] += 200.0f; + dlightcolor[1] += 160.0f; + dlightcolor[2] += 80.0f; + } + else if (ent->render.model->flags & EF_GRENADE) + { + if (ent->render.alpha == -1) // LordHavoc: Nehahra dem compatibility + R_RocketTrail (oldorg, ent->render.origin, 7, ent); + else + R_RocketTrail (oldorg, ent->render.origin, 1, ent); + } + else if (ent->render.model->flags & EF_TRACER3) + R_RocketTrail (oldorg, ent->render.origin, 6, ent); } - else if (ent->model->flags & EF_TRACER3) - R_RocketTrail (oldorg, ent->origin, 6, ent); } - if (ent->glowsize) // LordHavoc: customizable glow + // LordHavoc: customizable glow + if (ent->render.glowsize) { - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->radius = ent->glowsize; - dl->die = cl.time + 0.001; - tempcolor = (byte *)&d_8to24table[ent->glowcolor]; - dl->color[0] = tempcolor[0]*(1.0/255.0);dl->color[1] = tempcolor[1]*(1.0/255.0);dl->color[2] = tempcolor[2]*(1.0/255.0); + byte *tempcolor = (byte *)&d_8to24table[ent->render.glowcolor]; + dlightcolor[0] += ent->render.glowsize * tempcolor[0] * (1.0f / 255.0f); + dlightcolor[1] += ent->render.glowsize * tempcolor[1] * (1.0f / 255.0f); + dlightcolor[2] += ent->render.glowsize * tempcolor[2] * (1.0f / 255.0f); } - if (ent->glowtrail) // LordHavoc: customizable glow and trail - R_RocketTrail2 (oldorg, ent->origin, ent->glowcolor, ent); + // LordHavoc: customizable trail + if (ent->render.flags & RENDER_GLOWTRAIL) + R_RocketTrail2 (oldorg, ent->render.origin, ent->render.glowcolor, ent); - ent->forcelink = false; + if (dlightcolor[0] || dlightcolor[1] || dlightcolor[2]) + { + dlightradius = VectorLength(dlightcolor); + d = 1.0f / dlightradius; + CL_AllocDlight (ent, ent->render.origin, dlightradius, dlightcolor[0] * d, dlightcolor[1] * d, dlightcolor[2] * d, 0, 0); + } - if (i == cl.viewentity && !chase_active.value) + if (!chase_active.value && ((i == cl.viewentity) || (ent->render.flags & RENDER_EXTERIORMODEL))) continue; -// LordHavoc: enabled EF_NODRAW - if (!ent->model || ent->effects & EF_NODRAW) + if (ent->render.model == NULL) + continue; + if (ent->render.effects & EF_NODRAW) continue; if (cl_numvisedicts < MAX_VISEDICTS) - { - cl_visedicts[cl_numvisedicts] = ent; - cl_numvisedicts++; - } + cl_visedicts[cl_numvisedicts++] = ent; } - +// Con_Printf("\n"); } +// used by cl_shownet +int netshown; + /* =============== CL_ReadFromServer @@ -640,8 +698,9 @@ int CL_ReadFromServer (void) int ret; cl.oldtime = cl.time; - cl.time += host_frametime; + cl.time += cl.frametime; + netshown = false; do { ret = CL_GetMessage (); @@ -654,11 +713,12 @@ int CL_ReadFromServer (void) CL_ParseServerMessage (); } while (ret && cls.state == ca_connected); - if (cl_shownet.value) + if (netshown) Con_Printf ("\n"); CL_RelinkEntities (); CL_UpdateTEnts (); + CL_DoEffects (); // // bring the links up to date @@ -688,7 +748,6 @@ void CL_SendCmd (void) // send the unreliable message CL_SendMove (&cmd); - } if (cls.demoplayback) @@ -761,7 +820,6 @@ void CL_PModel_f (void) CL_Fog_f ====================== */ -extern float fog_density, fog_red, fog_green, fog_blue; void CL_Fog_f (void) { if (Cmd_Argc () == 1) @@ -775,8 +833,6 @@ void CL_Fog_f (void) fog_blue = atof(Cmd_Argv(4)); } -cvar_t demo_nehahra = {"demo_nehahra", "0"}; - /* ================= CL_Init @@ -808,6 +864,7 @@ void CL_Init (void) Cvar_RegisterVariable (&lookspring); Cvar_RegisterVariable (&lookstrafe); Cvar_RegisterVariable (&sensitivity); + Cvar_RegisterVariable (&freelook); Cvar_RegisterVariable (&m_pitch); Cvar_RegisterVariable (&m_yaw); @@ -817,6 +874,7 @@ void CL_Init (void) // Cvar_RegisterVariable (&cl_autofire); Cmd_AddCommand ("entities", CL_PrintEntities_f); + Cmd_AddCommand ("bitprofile", CL_BitProfile_f); Cmd_AddCommand ("disconnect", CL_Disconnect_f); Cmd_AddCommand ("record", CL_Record_f); Cmd_AddCommand ("stop", CL_Stop_f);