X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=cl_main.c;h=ef8ab01cd55361f94e9a5a73c2af692de5bd3f19;hp=0cb016a842b007468bba7595d6df6149184da3ee;hb=4e402f83fc7aa1989f298c38847661bdf6d7883d;hpb=9709b79717c940af0cf13121edf869dfdd94962a diff --git a/cl_main.c b/cl_main.c index 0cb016a8..ef8ab01c 100644 --- a/cl_main.c +++ b/cl_main.c @@ -72,6 +72,8 @@ cvar_t cl_beams_quakepositionhack = {CVAR_SAVE, "cl_beams_quakepositionhack", "1 cvar_t cl_beams_instantaimhack = {CVAR_SAVE, "cl_beams_instantaimhack", "0", "makes your lightning gun aiming update instantly"}; cvar_t cl_beams_lightatend = {CVAR_SAVE, "cl_beams_lightatend", "0", "make a light at the end of the beam"}; +cvar_t cl_deathfade = {CVAR_SAVE, "cl_deathfade", "0", "fade screen to dark red when dead, value = how fast the fade is"}; + cvar_t cl_noplayershadow = {CVAR_SAVE, "cl_noplayershadow", "0","hide player shadow"}; cvar_t cl_dlights_decayradius = {CVAR_SAVE, "cl_dlights_decayradius", "1", "reduces size of light flashes over time"}; @@ -86,6 +88,8 @@ cvar_t cl_deathnoviewmodel = {0, "cl_deathnoviewmodel", "1", "hides gun model wh cvar_t cl_locs_enable = {CVAR_SAVE, "locs_enable", "1", "enables replacement of certain % codes in chat messages: %l (location), %d (last death location), %h (health), %a (armor), %x (rockets), %c (cells), %r (rocket launcher status), %p (powerup status), %w (weapon status), %t (current time in level)"}; cvar_t cl_locs_show = {0, "locs_show", "0", "shows defined locations for editing purposes"}; +extern cvar_t r_equalize_entities_fullbright; + client_static_t cls; client_state_t cl; @@ -126,6 +130,7 @@ void CL_ClearState(void) cl.num_brushmodel_entities = 0; // tweak these if the game runs out + cl.max_csqcrenderentities = 0; cl.max_entities = 256; cl.max_static_entities = 256; cl.max_effects = 256; @@ -141,6 +146,7 @@ void CL_ClearState(void) cl.num_effects = 0; cl.num_beams = 0; + cl.csqcrenderentities = NULL; cl.entities = (entity_t *)Mem_Alloc(cls.levelmempool, cl.max_entities * sizeof(entity_t)); cl.entities_active = (unsigned char *)Mem_Alloc(cls.levelmempool, cl.max_brushmodel_entities * sizeof(unsigned char)); cl.static_entities = (entity_t *)Mem_Alloc(cls.levelmempool, cl.max_static_entities * sizeof(entity_t)); @@ -186,6 +192,7 @@ void CL_ClearState(void) ent->render.alpha = 1; ent->render.flags = RENDER_SHADOW | RENDER_LIGHT; Matrix4x4_CreateFromQuakeEntity(&ent->render.matrix, 0, 0, 0, 0, 0, 0, 1); + ent->render.allowdecals = true; CL_UpdateRenderEntity(&ent->render); // noclip is turned off at start @@ -284,6 +291,26 @@ void CL_ExpandEntities(int num) } } +void CL_ExpandCSQCRenderEntities(int num) +{ + int oldmaxcsqcrenderentities; + entity_render_t *oldcsqcrenderentities; + if (num >= cl.max_csqcrenderentities) + { + if (num >= MAX_EDICTS) + Host_Error("CL_ExpandEntities: num %i >= %i", num, MAX_EDICTS); + oldmaxcsqcrenderentities = cl.max_csqcrenderentities; + oldcsqcrenderentities = cl.csqcrenderentities; + cl.max_csqcrenderentities = (num & ~255) + 256; + cl.csqcrenderentities = (entity_render_t *)Mem_Alloc(cls.levelmempool, cl.max_csqcrenderentities * sizeof(entity_render_t)); + if (oldcsqcrenderentities) + { + memcpy(cl.csqcrenderentities, oldcsqcrenderentities, oldmaxcsqcrenderentities * sizeof(entity_render_t)); + Mem_Free(oldcsqcrenderentities); + } + } +} + /* ===================== CL_Disconnect @@ -454,17 +481,19 @@ List information on all models in the client modelindex */ static void CL_ModelIndexList_f(void) { - int i = 1; + int i; + dp_model_t *model; // Print Header Con_Printf("%3s: %-30s %-8s %-8s\n", "ID", "Name", "Type", "Triangles"); - while(cl.model_precache[i] && i != MAX_MODELS) - { // Valid Model - if(cl.model_precache[i]->loaded || i == 1) - Con_Printf("%3i: %-30s %-8s %-10i\n", i, cl.model_precache[i]->name, cl.model_precache[i]->modeldatatypestring, cl.model_precache[i]->surfmesh.num_triangles); + for (i = -MAX_MODELS;i < MAX_MODELS;i++) + { + model = CL_GetModelByIndex(i); + if(model->loaded || i == 1) + Con_Printf("%3i: %-30s %-8s %-10i\n", i, model->name, model->modeldatatypestring, model->surfmesh.num_triangles); else - Con_Printf("%3i: %-30s %-30s\n", i, cl.model_precache[i]->name, "--no local model found--"); + Con_Printf("%3i: %-30s %-30s\n", i, model->name, "--no local model found--"); i++; } } @@ -502,7 +531,7 @@ void CL_UpdateRenderEntity(entity_render_t *ent) // update the inverse matrix for the renderer Matrix4x4_Invert_Simple(&ent->inversematrix, &ent->matrix); // update the animation blend state - R_LerpAnimation(ent); + VM_FrameBlendFromFrameGroupBlend(ent->frameblend, ent->framegroupblend, ent->model); // we need the matrix origin to center the box Matrix4x4_OriginFromMatrix(&ent->matrix, org); // update entity->render.scale because the renderer needs it @@ -593,6 +622,7 @@ entity_render_t *CL_NewTempEntity(double shadertime) render->shadertime = shadertime; render->alpha = 1; VectorSet(render->colormod, 1, 1, 1); + VectorSet(render->glowmod, 1, 1, 1); return render; } @@ -738,6 +768,16 @@ void CL_RelinkLightFlashes(void) } } + if (!cl.lightstyle) + { + for (j = 0;j < cl.max_lightstyle;j++) + { + r_refdef.scene.rtlightstylevalue[j] = 1; + r_refdef.scene.lightstylevalue[j] = 256; + } + return; + } + // light animations // 'm' is normal light, 'a' is no light, 'z' is double bright f = cl.time * 10; @@ -745,12 +785,20 @@ void CL_RelinkLightFlashes(void) frac = f - i; for (j = 0;j < cl.max_lightstyle;j++) { - if (!cl.lightstyle || !cl.lightstyle[j].length) + if (!cl.lightstyle[j].length) { r_refdef.scene.rtlightstylevalue[j] = 1; r_refdef.scene.lightstylevalue[j] = 256; continue; } + // static lightstyle "=value" + if (cl.lightstyle[j].map[0] == '=') + { + r_refdef.scene.rtlightstylevalue[j] = atof(cl.lightstyle[j].map + 1); + if ( r_lerplightstyles.integer || ((int)f - f) < 0.01) + r_refdef.scene.lightstylevalue[j] = r_refdef.scene.rtlightstylevalue[j]; + continue; + } k = i % cl.lightstyle[j].length; l = (i-1) % cl.lightstyle[j].length; k = cl.lightstyle[j].map[k] - 'a'; @@ -808,10 +856,11 @@ void CL_AddQWCTFFlagModel(entity_t *player, int skin) if (!flagrender) return; - flagrender->model = cl.model_precache[cl.qw_modelindex_flag]; + flagrender->model = CL_GetModelByIndex(cl.qw_modelindex_flag); flagrender->skinnum = skin; flagrender->alpha = 1; VectorSet(flagrender->colormod, 1, 1, 1); + VectorSet(flagrender->glowmod, 1, 1, 1); // attach the flag to the player matrix Matrix4x4_CreateFromQuakeEntity(&flagmatrix, -f, -22, 0, 0, 0, -45, 1); Matrix4x4_Concat(&flagrender->matrix, &player->render.matrix, &flagmatrix); @@ -849,10 +898,9 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat { const matrix4x4_t *matrix; matrix4x4_t blendmatrix, tempmatrix, matrix2; - int j, k, l, frame; - float origin[3], angles[3], delta[3], lerp, d; + int frame; + float origin[3], angles[3], lerp; entity_t *t; - dp_model_t *model; //entity_persistent_t *p = &e->persistent; //entity_render_t *r = &e->render; // skip inactive entities and world @@ -865,6 +913,7 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat e->render.flags = e->state_current.flags; e->render.effects = e->state_current.effects; VectorScale(e->state_current.colormod, (1.0f / 32.0f), e->render.colormod); + VectorScale(e->state_current.glowmod, (1.0f / 32.0f), e->render.glowmod); if(e >= cl.entities && e < cl.entities + cl.num_entities) e->render.entitynumber = e - cl.entities; else @@ -894,23 +943,15 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat e->render.flags |= t->render.flags & (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL); // if a valid tagindex is used, make it relative to that tag instead // FIXME: use a model function to get tag info (need to handle skeletal) - if (e->state_current.tagentity && e->state_current.tagindex >= 1 && (model = t->render.model)) + if (e->state_current.tagentity && e->state_current.tagindex >= 1 && t->render.model) { - // blend the matrices - memset(&blendmatrix, 0, sizeof(blendmatrix)); - for (j = 0;j < MAX_FRAMEBLENDS && t->render.frameblend[j].lerp > 0;j++) + if(!Mod_Alias_GetTagMatrix(t->render.model, t->render.frameblend, t->render.skeleton, e->state_current.tagindex - 1, &blendmatrix)) // i.e. no error { - matrix4x4_t tagmatrix; - Mod_Alias_GetTagMatrix(model, t->render.frameblend[j].subframe, e->state_current.tagindex - 1, &tagmatrix); - d = t->render.frameblend[j].lerp; - for (l = 0;l < 4;l++) - for (k = 0;k < 4;k++) - blendmatrix.m[l][k] += d * tagmatrix.m[l][k]; + // concat the tag matrices onto the entity matrix + Matrix4x4_Concat(&tempmatrix, &t->render.matrix, &blendmatrix); + // use the constructed tag matrix + matrix = &tempmatrix; } - // concat the tag matrices onto the entity matrix - Matrix4x4_Concat(&tempmatrix, &t->render.matrix, &blendmatrix); - // use the constructed tag matrix - matrix = &tempmatrix; } } else if (e->render.flags & RENDER_VIEWMODEL) @@ -945,11 +986,23 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat // interpolate the origin and angles lerp = max(0, lerp); VectorLerp(e->persistent.oldorigin, lerp, e->persistent.neworigin, origin); +#if 0 + // this fails at the singularity of euler angles VectorSubtract(e->persistent.newangles, e->persistent.oldangles, delta); if (delta[0] < -180) delta[0] += 360;else if (delta[0] >= 180) delta[0] -= 360; if (delta[1] < -180) delta[1] += 360;else if (delta[1] >= 180) delta[1] -= 360; if (delta[2] < -180) delta[2] += 360;else if (delta[2] >= 180) delta[2] -= 360; VectorMA(e->persistent.oldangles, lerp, delta, angles); +#else + { + vec3_t f0, u0, f1, u1; + AngleVectors(e->persistent.oldangles, f0, NULL, u0); + AngleVectors(e->persistent.newangles, f1, NULL, u1); + VectorMAM(1-lerp, f0, lerp, f1, f0); + VectorMAM(1-lerp, u0, lerp, u1, u0); + AnglesFromVectors(angles, f0, u0, false); + } +#endif } else { @@ -960,10 +1013,7 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat // model setup and some modelflags frame = e->state_current.frame; - if (e->state_current.modelindex < MAX_MODELS) - e->render.model = cl.model_precache[e->state_current.modelindex]; - else - e->render.model = NULL; + e->render.model = CL_GetModelByIndex(e->state_current.modelindex); if (e->render.model) { if (e->render.skinnum >= e->render.model->numskins) @@ -978,11 +1028,15 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat if (e->render.model->type == mod_alias) angles[0] = -angles[0]; if ((e->render.effects & EF_SELECTABLE) && cl.cmd.cursor_entitynumber == e->state_current.number) + { VectorScale(e->render.colormod, 2, e->render.colormod); + VectorScale(e->render.glowmod, 2, e->render.glowmod); + } } // if model is alias or this is a tenebrae-like dlight, reverse pitch direction else if (e->state_current.lightpflags & PFLAGS_FULLDYNAMIC) angles[0] = -angles[0]; + // NOTE: this must be synced to SV_GetPitchSign! if ((e->render.effects & EF_ROTATE) && !(e->render.flags & RENDER_VIEWMODEL)) { @@ -1036,13 +1090,18 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat // tenebrae's sprites are all additive mode (weird) if (gamemode == GAME_TENEBRAE && e->render.model && e->render.model->type == mod_sprite) - e->render.effects |= EF_ADDITIVE; + e->render.flags |= RENDER_ADDITIVE; // player model is only shown with chase_active on if (e->state_current.number == cl.viewentity) e->render.flags |= RENDER_EXTERIORMODEL; // either fullbright or lit - if (!(e->render.effects & EF_FULLBRIGHT) && !r_fullbright.integer) - e->render.flags |= RENDER_LIGHT; + if(!r_fullbright.integer) + { + if (!(e->render.effects & EF_FULLBRIGHT)) + e->render.flags |= RENDER_LIGHT; + else if(r_equalize_entities_fullbright.integer) + e->render.flags |= RENDER_LIGHT | RENDER_EQUALIZE; + } // hide player shadow during intermission or nehahra movie if (!(e->render.effects & (EF_NOSHADOW | EF_ADDITIVE | EF_NODEPTHTEST)) && (e->render.alpha >= 1) @@ -1053,8 +1112,15 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat e->render.flags |= RENDER_NOSELFSHADOW; if (e->render.effects & EF_NOSELFSHADOW) e->render.flags |= RENDER_NOSELFSHADOW; + if (e->render.effects & EF_NODEPTHTEST) + e->render.flags |= RENDER_NODEPTHTEST; + if (e->render.effects & EF_ADDITIVE) + e->render.flags |= RENDER_ADDITIVE; + if (e->render.effects & EF_DOUBLESIDED) + e->render.flags |= RENDER_DOUBLESIDED; // make the other useful stuff + e->render.allowdecals = true; CL_UpdateRenderEntity(&e->render); } @@ -1193,6 +1259,8 @@ void CL_UpdateNetworkCollisionEntities(void) } } +extern void R_DecalSystem_Reset(decalsystem_t *decalsystem); + /* =============== CL_UpdateNetworkEntities @@ -1217,7 +1285,10 @@ void CL_UpdateNetworkEntities(void) CL_UpdateNetworkEntityTrail(ent); } else + { + R_DecalSystem_Reset(&ent->render.decalsystem); cl.entities_active[i] = false; + } } } } @@ -1229,7 +1300,7 @@ void CL_UpdateViewModel(void) ent->state_previous = ent->state_current; ent->state_current = defaultstate; ent->state_current.time = cl.time; - ent->state_current.number = -1; + ent->state_current.number = (unsigned short)-1; ent->state_current.active = true; ent->state_current.modelindex = cl.stats[STAT_WEAPON]; ent->state_current.frame = cl.stats[STAT_WEAPONFRAME]; @@ -1342,7 +1413,7 @@ void CL_LinkNetworkEntity(entity_t *e) trace_t trace; matrix4x4_t tempmatrix; Matrix4x4_Transform(&e->render.matrix, muzzleflashorigin, v2); - trace = CL_Move(origin, vec3_origin, vec3_origin, v2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, true, false, NULL, false); + trace = CL_TraceLine(origin, v2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, true, false, NULL, false); Matrix4x4_Normalize(&tempmatrix, &e->render.matrix); Matrix4x4_SetOrigin(&tempmatrix, trace.endpos[0], trace.endpos[1], trace.endpos[2]); Matrix4x4_Scale(&tempmatrix, 150, 1); @@ -1435,6 +1506,8 @@ void CL_RelinkWorld(void) if (!r_fullbright.integer) ent->render.flags |= RENDER_LIGHT; VectorSet(ent->render.colormod, 1, 1, 1); + VectorSet(ent->render.glowmod, 1, 1, 1); + ent->render.allowdecals = true; CL_UpdateRenderEntity(&ent->render); r_refdef.scene.worldentity = &ent->render; r_refdef.scene.worldmodel = cl.worldmodel; @@ -1449,15 +1522,22 @@ static void CL_RelinkStaticEntities(void) e->render.flags = 0; // if the model was not loaded when the static entity was created we // need to re-fetch the model pointer - e->render.model = cl.model_precache[e->state_baseline.modelindex]; + e->render.model = CL_GetModelByIndex(e->state_baseline.modelindex); // either fullbright or lit - if (!(e->render.effects & EF_FULLBRIGHT) && !r_fullbright.integer) - e->render.flags |= RENDER_LIGHT; + if(!r_fullbright.integer) + { + if (!(e->render.effects & EF_FULLBRIGHT)) + e->render.flags |= RENDER_LIGHT; + else if(r_equalize_entities_fullbright.integer) + e->render.flags |= RENDER_LIGHT | RENDER_EQUALIZE; + } // hide player shadow during intermission or nehahra movie if (!(e->render.effects & (EF_NOSHADOW | EF_ADDITIVE | EF_NODEPTHTEST)) && (e->render.alpha >= 1)) e->render.flags |= RENDER_SHADOW; VectorSet(e->render.colormod, 1, 1, 1); - R_LerpAnimation(&e->render); + VectorSet(e->render.glowmod, 1, 1, 1); + VM_FrameBlendFromFrameGroupBlend(e->render.frameblend, e->render.framegroupblend, e->render.model); + e->render.allowdecals = true; CL_UpdateRenderEntity(&e->render); r_refdef.scene.entities[r_refdef.scene.numentities++] = &e->render; } @@ -1537,12 +1617,10 @@ static void CL_RelinkEffects(void) } // normal stuff - if(e->modelindex < MAX_MODELS) - entrender->model = cl.model_precache[e->modelindex]; - else - entrender->model = cl.csqc_model_precache[-(e->modelindex+1)]; + entrender->model = CL_GetModelByIndex(e->modelindex); entrender->alpha = 1; VectorSet(entrender->colormod, 1, 1, 1); + VectorSet(entrender->glowmod, 1, 1, 1); Matrix4x4_CreateFromQuakeEntity(&entrender->matrix, e->origin[0], e->origin[1], e->origin[2], 0, 0, 0, 1); CL_UpdateRenderEntity(entrender); @@ -1686,9 +1764,10 @@ static void CL_RelinkQWNails(void) continue; // normal stuff - entrender->model = cl.model_precache[cl.qw_modelindex_spike]; + entrender->model = CL_GetModelByIndex(cl.qw_modelindex_spike); entrender->alpha = 1; VectorSet(entrender->colormod, 1, 1, 1); + VectorSet(entrender->glowmod, 1, 1, 1); Matrix4x4_CreateFromQuakeEntity(&entrender->matrix, v[0], v[1], v[2], v[3], v[4], v[5], 1); CL_UpdateRenderEntity(entrender); @@ -1817,12 +1896,10 @@ static void CL_Fog_f (void) { if (Cmd_Argc () == 1) { - Con_Printf("\"fog\" is \"%f %f %f %f %f %f %f\"\n", r_refdef.fog_density, r_refdef.fog_red, r_refdef.fog_green, r_refdef.fog_blue, r_refdef.fog_alpha, r_refdef.fog_start, r_refdef.fog_end); + Con_Printf("\"fog\" is \"%f %f %f %f %f %f %f %f %f\"\n", r_refdef.fog_density, r_refdef.fog_red, r_refdef.fog_green, r_refdef.fog_blue, r_refdef.fog_alpha, r_refdef.fog_start, r_refdef.fog_end, r_refdef.fog_height, r_refdef.fog_fadedepth); return; } - r_refdef.fog_start = 0; - r_refdef.fog_end = 16384; - r_refdef.fog_alpha = 1; + FOG_clear(); // so missing values get good defaults if(Cmd_Argc() > 1) r_refdef.fog_density = atof(Cmd_Argv(1)); if(Cmd_Argc() > 2) @@ -1837,6 +1914,10 @@ static void CL_Fog_f (void) r_refdef.fog_start = atof(Cmd_Argv(6)); if(Cmd_Argc() > 7) r_refdef.fog_end = atof(Cmd_Argv(7)); + if(Cmd_Argc() > 8) + r_refdef.fog_height = atof(Cmd_Argv(8)); + if(Cmd_Argc() > 9) + r_refdef.fog_fadedepth = atof(Cmd_Argv(9)); } /* @@ -2238,6 +2319,7 @@ void CL_Init (void) Cvar_RegisterVariable (&cl_anglespeedkey); Cvar_RegisterVariable (&cl_shownet); Cvar_RegisterVariable (&cl_nolerp); + Cvar_RegisterVariable (&cl_deathfade); Cvar_RegisterVariable (&lookspring); Cvar_RegisterVariable (&lookstrafe); Cvar_RegisterVariable (&sensitivity);