/* * Copyright(c) 1997-2001 Id Software, Inc. * Copyright(c) 2002 The Quakeforge Project. * Copyright(c) 2006 Quetoo. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or(at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "client.h" cvar_t *cl_testparticles; cvar_t *cl_testentities; cvar_t *cl_stats; int r_numentities; entity_t r_entities[MAX_ENTITIES]; int r_numparticles; particle_t r_particles[MAX_PARTICLES]; char cl_weaponmodels[MAX_CLIENTWEAPONMODELS][MAX_QPATH]; int num_cl_weaponmodels; /* V_ClearScene Specifies the model that will be used as the world */ void V_ClearScene(void){ r_numentities = 0; r_numparticles = 0; } /* V_AddEntity */ void V_AddEntity(entity_t *ent){ if(r_numentities >= MAX_ENTITIES) return; r_entities[r_numentities++] = *ent; } /* V_AddParticle */ void V_AddParticle(vec3_t org, int color, float alpha){ particle_t *p; if(r_numparticles >= MAX_PARTICLES) return; p = &r_particles[r_numparticles++]; VectorCopy(org, p->origin); p->color = color; p->alpha = alpha; } /* V_TestParticles If cl_testparticles is set, create 4096 particles in the view */ void V_TestParticles(void){ particle_t *p; int i, j; float d, r, u; r_numparticles = MAX_PARTICLES; for(i = 0; i < r_numparticles; i++){ d = i * 0.25; r = 4 * ((i & 7) - 3.5); u = 4 * (((i >> 3) & 7) - 3.5); p = &r_particles[i]; for(j = 0; j < 3; j++) p->origin[j] = cl.viewdef.vieworg[j] + cl.v_forward[j] * d + cl.v_right[j] * r + cl.v_up[j] * u; p->color = 8; p->alpha = cl_testparticles->value; } } /* V_TestEntities If cl_testentities is set, create 32 player models */ void V_TestEntities(void){ int i, j; float f, r; entity_t *ent; r_numentities = 32; memset(r_entities, 0, sizeof(r_entities)); for(i = 0; i < r_numentities; i++){ ent = &r_entities[i]; r = 64 *((i % 4) - 1.5); f = 64 *(i / 4) + 128; for(j = 0; j < 3; j++) ent->origin[j] = cl.viewdef.vieworg[j] + cl.v_forward[j] * f + cl.v_right[j] * r; ent->model = cl.baseclientinfo.model; ent->skin = cl.baseclientinfo.skin; } } qboolean update_viewdef = false; /* V_RegisterViewMedia Call before entering a new level */ void V_RegisterViewMedia(void){ char mapname[32]; char name[MAX_QPATH]; int i; if(!cl.configstrings[CS_MODELS + 1][0]) return; // no map loaded // let the render dll load the map strcpy(mapname, cl.configstrings[CS_MODELS + 1] + 5); // skip "maps/" mapname[strlen(mapname) - 4] = 0; // cut off ".bsp" // register models, pics, and skins Com_Printf("Map: %s\r", mapname); SCR_UpdateScreen(); GL_BeginRegistration(mapname); Com_Printf(" \r"); // precache status bar pics Com_Printf("pics\r"); SCR_UpdateScreen(); SCR_TouchPics(); Com_Printf(" \r"); CL_RegisterTEntModels(); num_cl_weaponmodels = 1; strcpy(cl_weaponmodels[0], "weapon.md2"); for(i = 1; i < MAX_MODELS && cl.configstrings[CS_MODELS + i][0]; i++){ strcpy(name, cl.configstrings[CS_MODELS + i]); name[37] = 0; // never go beyond one line if(name[0] != '*') Com_DPrintf("%s\r", name); SCR_UpdateScreen(); if(name[0] == '#'){ // special player weapon model if(num_cl_weaponmodels < MAX_CLIENTWEAPONMODELS){ strncpy(cl_weaponmodels[num_cl_weaponmodels], cl.configstrings[CS_MODELS + i] + 1, sizeof(cl_weaponmodels[num_cl_weaponmodels]) - 1); num_cl_weaponmodels++; } } else { cl.model_draw[i] = GL_RegisterModel(cl.configstrings[CS_MODELS + i]); if(name[0] == '*') cl.model_clip[i] = CM_InlineModel(cl.configstrings[CS_MODELS + i]); else cl.model_clip[i] = NULL; } if(name[0] != '*') Com_DPrintf(" \r"); } Com_Printf("images\r"); SCR_UpdateScreen(); for(i = 1; i < MAX_IMAGES && cl.configstrings[CS_IMAGES + i][0]; i++){ cl.image_precache[i] = Draw_FindPic(cl.configstrings[CS_IMAGES + i]); } Com_Printf(" \r"); for(i = 0; i < MAX_CLIENTS; i++){ if(!cl.configstrings[CS_PLAYERSKINS + i][0]) continue; Com_Printf("client %i\r", i); SCR_UpdateScreen(); CL_ParseClientinfo(i); Com_Printf(" \r"); } CL_LoadClientinfo(&cl.baseclientinfo, "unnamed\\male/grunt"); // set sky textures Com_Printf("sky\r"); SCR_UpdateScreen(); GL_SetSky(cl.configstrings[CS_SKY]); Com_Printf(" \r"); // the renderer can now free unneeded stuff GL_EndRegistration(); // clear any lines of console text Con_ClearNotify(); SCR_UpdateScreen(); cl.view_prepped = true; update_viewdef = true; } /* CalcFov */ float CalcFov(float fov_x, float width, float height){ float a; float x; if(fov_x < 1 || fov_x > 179) Com_Error(ERR_DROP, "Bad fov: %f", fov_x); x = width / tan(fov_x / 360 * M_PI); a = atan(height / x); a = a * 360 / M_PI; return a; } /* V_UpdateView */ void V_UpdateView(void){ if(cls.state != ca_active) return; if(!cl.view_prepped) return; // still loading if(timedemo->value){ if(!cl.timedemo_start) cl.timedemo_start = Sys_Milliseconds(); cl.timedemo_frames++; } // update viewdef in accordance with frame if(cl.frame.valid && (update_viewdef || !paused->value)){ update_viewdef = false; V_ClearScene(); // build the entity list CL_AddEntities(); if(cl_testparticles->value) V_TestParticles(); if(cl_testentities->value) V_TestEntities(); cl.viewdef.x = scr_vrect.x; cl.viewdef.y = scr_vrect.y; cl.viewdef.width = scr_vrect.width; cl.viewdef.height = scr_vrect.height; cl.viewdef.fov_y = CalcFov(cl.viewdef.fov_x, cl.viewdef.width, cl.viewdef.height); cl.viewdef.time = cl.time * 0.001; cl.viewdef.areabits = cl.frame.areabits; if(!cl_add_entities->value) r_numentities = 0; if(!cl_add_particles->value) r_numparticles = 0; cl.viewdef.num_entities = r_numentities; cl.viewdef.entities = r_entities; cl.viewdef.num_particles = r_numparticles; cl.viewdef.particles = r_particles; cl.viewdef.rdflags = cl.frame.playerstate.rdflags; } if(cl_stats->value) Com_Printf("ent:%i part:%i\n", r_numentities, r_numparticles); } /* V_Viewpos_f */ void V_Viewpos_f(void){ Com_Printf("(%i %i %i) : %i\n",(int)cl.viewdef.vieworg[0], (int)cl.viewdef.vieworg[1],(int)cl.viewdef.vieworg[2], (int)cl.viewdef.viewangles[YAW]); } /* V_Init */ void V_Init(void){ Cmd_AddCommand("viewpos", V_Viewpos_f); cl_testparticles = Cvar_Get("cl_testparticles", "0", 0); cl_testentities = Cvar_Get("cl_testentities", "0", 0); cl_stats = Cvar_Get("cl_stats", "0", 0); }