|
|
1.1 ! root 1: // cl_view.c -- player rendering positioning ! 2: #include "client.h" ! 3: //============= ! 4: // ! 5: // development tools for weapons ! 6: // ! 7: int gun_frame; ! 8: struct model_s *gun_model; ! 9: //============= ! 10: cvar_t *crosshair; ! 11: cvar_t *cl_testparticles; ! 12: cvar_t *cl_testentities; ! 13: cvar_t *cl_testlights; ! 14: cvar_t *cl_testblend; ! 15: cvar_t *cl_stats; ! 16: int r_numdlights; ! 17: dlight_t r_dlights[MAX_DLIGHTS]; ! 18: int r_numentities; ! 19: entity_t r_entities[MAX_ENTITIES]; ! 20: int r_numparticles; ! 21: particle_t r_particles[MAX_PARTICLES]; ! 22: lightstyle_t r_lightstyles[MAX_LIGHTSTYLES]; ! 23: /* ! 24: ==================== ! 25: V_ClearScene ! 26: Specifies the model that will be used as the world ! 27: ==================== ! 28: */ ! 29: void V_ClearScene (void) ! 30: { ! 31: r_numdlights = 0; ! 32: r_numentities = 0; ! 33: r_numparticles = 0; ! 34: } ! 35: /* ! 36: ===================== ! 37: V_AddEntity ! 38: ===================== ! 39: */ ! 40: void V_AddEntity (entity_t *ent) ! 41: { ! 42: if (r_numentities >= MAX_ENTITIES) ! 43: return; ! 44: r_entities[r_numentities++] = *ent; ! 45: } ! 46: /* ! 47: ===================== ! 48: V_AddParticle ! 49: ===================== ! 50: */ ! 51: void V_AddParticle (vec3_t org, int color, float alpha) ! 52: { ! 53: particle_t *p; ! 54: if (r_numparticles >= MAX_PARTICLES) ! 55: return; ! 56: p = &r_particles[r_numparticles++]; ! 57: VectorCopy (org, p->origin); ! 58: p->color = color; ! 59: p->alpha = alpha; ! 60: } ! 61: /* ! 62: ===================== ! 63: V_AddLight ! 64: ===================== ! 65: */ ! 66: void V_AddLight (vec3_t org, float intensity, float r, float g, float b) ! 67: { ! 68: dlight_t *dl; ! 69: if (r_numdlights >= MAX_DLIGHTS) ! 70: return; ! 71: dl = &r_dlights[r_numdlights++]; ! 72: VectorCopy (org, dl->origin); ! 73: dl->intensity = intensity; ! 74: dl->color[0] = r; ! 75: dl->color[1] = g; ! 76: dl->color[2] = b; ! 77: } ! 78: /* ! 79: ===================== ! 80: V_AddLightStyle ! 81: ===================== ! 82: */ ! 83: void V_AddLightStyle (int style, float r, float g, float b) ! 84: { ! 85: lightstyle_t *ls; ! 86: if (style < 0 || style > MAX_LIGHTSTYLES) ! 87: Com_Error (ERR_DROP, "Bad light style %i", style); ! 88: ls = &r_lightstyles[style]; ! 89: ls->white = r+g+b; ! 90: ls->rgb[0] = r; ! 91: ls->rgb[1] = g; ! 92: ls->rgb[2] = b; ! 93: } ! 94: /* ! 95: ================ ! 96: V_TestParticles ! 97: If cl_testparticles is set, create 4096 particles in the view ! 98: ================ ! 99: */ ! 100: void V_TestParticles (void) ! 101: { ! 102: particle_t *p; ! 103: int i, j; ! 104: float d, r, u; ! 105: r_numparticles = MAX_PARTICLES; ! 106: for (i=0 ; i<r_numparticles ; i++) ! 107: { ! 108: d = i*0.25; ! 109: r = 4*((i&7)-3.5); ! 110: u = 4*(((i>>3)&7)-3.5); ! 111: p = &r_particles[i]; ! 112: for (j=0 ; j<3 ; j++) ! 113: p->origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j]*d + ! 114: cl.v_right[j]*r + cl.v_up[j]*u; ! 115: p->color = 8; ! 116: p->alpha = cl_testparticles->value; ! 117: } ! 118: } ! 119: /* ! 120: ================ ! 121: V_TestEntities ! 122: ! 123: If cl_testentities is set, create 32 player models ! 124: ================ ! 125: */ ! 126: void V_TestEntities (void) ! 127: { ! 128: int i, j; ! 129: float f, r; ! 130: entity_t *ent; ! 131: ! 132: r_numentities = 32; ! 133: memset (r_entities, 0, sizeof(r_entities)); ! 134: ! 135: for (i=0 ; i<r_numentities ; i++) ! 136: { ! 137: ent = &r_entities[i]; ! 138: ! 139: r = 64 * ( (i%4) - 1.5 ); ! 140: f = 64 * (i/4) + 128; ! 141: ! 142: for (j=0 ; j<3 ; j++) ! 143: ent->origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j]*f + ! 144: cl.v_right[j]*r; ! 145: ! 146: ent->model = cl.baseclientinfo.model; ! 147: ent->skin = cl.baseclientinfo.skin; ! 148: } ! 149: } ! 150: ! 151: /* ! 152: ================ ! 153: V_TestLights ! 154: ! 155: If cl_testlights is set, create 32 lights models ! 156: ================ ! 157: */ ! 158: void V_TestLights (void) ! 159: { ! 160: int i, j; ! 161: float f, r; ! 162: dlight_t *dl; ! 163: ! 164: r_numdlights = 32; ! 165: memset (r_dlights, 0, sizeof(r_dlights)); ! 166: ! 167: for (i=0 ; i<r_numdlights ; i++) ! 168: { ! 169: dl = &r_dlights[i]; ! 170: ! 171: r = 64 * ( (i%4) - 1.5 ); ! 172: f = 64 * (i/4) + 128; ! 173: ! 174: for (j=0 ; j<3 ; j++) ! 175: dl->origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j]*f + ! 176: cl.v_right[j]*r; ! 177: dl->color[0] = ((i%6)+1) & 1; ! 178: dl->color[1] = (((i%6)+1) & 2)>>1; ! 179: dl->color[2] = (((i%6)+1) & 4)>>2; ! 180: dl->intensity = 200; ! 181: } ! 182: } ! 183: ! 184: //=================================================================== ! 185: /* ! 186: ================= ! 187: CL_PrepRefresh ! 188: Call before entering a new level, or after changing dlls ! 189: ================= ! 190: */ ! 191: void CL_PrepRefresh (void) ! 192: { ! 193: char mapname[32]; ! 194: int i; ! 195: char name[MAX_QPATH]; ! 196: float rotate; ! 197: vec3_t axis; ! 198: if (!cl.configstrings[CS_MODELS+1][0]) ! 199: return; // no map loaded ! 200: SCR_AddDirtyPoint (0, 0); ! 201: SCR_AddDirtyPoint (viddef.width-1, viddef.height-1); ! 202: // let the render dll load the map ! 203: strcpy (mapname, cl.configstrings[CS_MODELS+1] + 5); // skip "maps/" ! 204: mapname[strlen(mapname)-4] = 0; // cut off ".bsp" ! 205: // register models, pics, and skins ! 206: Com_Printf ("Map: %s\r", mapname); ! 207: SCR_UpdateScreen (); ! 208: re.BeginRegistration (mapname); ! 209: Com_Printf (" \r"); ! 210: // precache status bar pics ! 211: Com_Printf ("pics\r"); ! 212: SCR_UpdateScreen (); ! 213: SCR_TouchPics (); ! 214: Com_Printf (" \r"); ! 215: ! 216: CL_RegisterTEntModels (); ! 217: for (i=1 ; i<MAX_MODELS && cl.configstrings[CS_MODELS+i][0] ; i++) ! 218: { ! 219: strcpy (name, cl.configstrings[CS_MODELS+i]); ! 220: name[37] = 0; // never go beyond one line ! 221: if (name[0] != '*') ! 222: Com_Printf ("%s\r", name); ! 223: SCR_UpdateScreen (); ! 224: Sys_SendKeyEvents (); // pump message loop ! 225: cl.model_draw[i] = re.RegisterModel (cl.configstrings[CS_MODELS+i]); ! 226: if (name[0] == '*') ! 227: cl.model_clip[i] = CM_InlineModel (cl.configstrings[CS_MODELS+i]); ! 228: else ! 229: cl.model_clip[i] = NULL; ! 230: if (name[0] != '*') ! 231: Com_Printf (" \r"); ! 232: } ! 233: Com_Printf ("images\r", i); ! 234: SCR_UpdateScreen (); ! 235: for (i=1 ; i<MAX_IMAGES && cl.configstrings[CS_IMAGES+i][0] ; i++) ! 236: { ! 237: cl.image_precache[i] = re.RegisterPic (cl.configstrings[CS_IMAGES+i]); ! 238: Sys_SendKeyEvents (); // pump message loop ! 239: } ! 240: Com_Printf (" \r"); ! 241: for (i=0 ; i<MAX_CLIENTS ; i++) ! 242: { ! 243: if (!cl.configstrings[CS_PLAYERSKINS+i][0]) ! 244: continue; ! 245: Com_Printf ("client %i\r", i); ! 246: SCR_UpdateScreen (); ! 247: Sys_SendKeyEvents (); // pump message loop ! 248: CL_ParseClientinfo (i); ! 249: Com_Printf (" \r"); ! 250: } ! 251: CL_LoadClientinfo (&cl.baseclientinfo, "unnamed\\male/grunt"); ! 252: // set sky textures and speed ! 253: Com_Printf ("sky\r", i); ! 254: SCR_UpdateScreen (); ! 255: rotate = atof (cl.configstrings[CS_SKYROTATE]); ! 256: sscanf (cl.configstrings[CS_SKYAXIS], "%f %f %f", ! 257: &axis[0], &axis[1], &axis[2]); ! 258: re.SetSky (cl.configstrings[CS_SKY], rotate, axis); ! 259: Com_Printf (" \r"); ! 260: // the renderer can now free unneeded stuff ! 261: re.EndRegistration (); ! 262: // clear any lines of console text ! 263: Con_ClearNotify (); ! 264: SCR_UpdateScreen (); ! 265: cl.refresh_prepped = true; ! 266: cl.force_refdef = true; // make sure we have a valid refdef ! 267: ! 268: // start the cd track ! 269: CDAudio_Play (atoi(cl.configstrings[CS_CDTRACK]), true); ! 270: } ! 271: /* ! 272: ==================== ! 273: CalcFov ! 274: ==================== ! 275: */ ! 276: float CalcFov (float fov_x, float width, float height) ! 277: { ! 278: float a; ! 279: float x; ! 280: if (fov_x < 1 || fov_x > 179) ! 281: Com_Error (ERR_DROP, "Bad fov: %f", fov_x); ! 282: x = width/tan(fov_x/360*M_PI); ! 283: a = atan (height/x); ! 284: a = a*360/M_PI; ! 285: return a; ! 286: } ! 287: //============================================================================ ! 288: // gun frame debugging functions ! 289: void V_Gun_Next_f (void) ! 290: { ! 291: gun_frame++; ! 292: Com_Printf ("frame %i\n", gun_frame); ! 293: } ! 294: void V_Gun_Prev_f (void) ! 295: { ! 296: gun_frame--; ! 297: if (gun_frame < 0) ! 298: gun_frame = 0; ! 299: Com_Printf ("frame %i\n", gun_frame); ! 300: } ! 301: void V_Gun_Model_f (void) ! 302: { ! 303: char name[MAX_QPATH]; ! 304: if (Cmd_Argc() != 2) ! 305: { ! 306: gun_model = NULL; ! 307: return; ! 308: } ! 309: Com_sprintf (name, sizeof(name), "models/%s/tris.md2", Cmd_Argv(1)); ! 310: gun_model = re.RegisterModel (name); ! 311: } ! 312: //============================================================================ ! 313: ! 314: /* ! 315: ================= ! 316: SCR_DrawCrosshair ! 317: ================= ! 318: */ ! 319: void SCR_DrawCrosshair (void) ! 320: { ! 321: if (!crosshair->value) ! 322: return; ! 323: ! 324: if (crosshair->modified) ! 325: { ! 326: crosshair->modified = false; ! 327: SCR_TouchPics (); ! 328: } ! 329: ! 330: if (!crosshair_pic[0]) ! 331: return; ! 332: ! 333: re.DrawPic (scr_vrect.x + ((scr_vrect.width - crosshair_width)>>1) ! 334: , scr_vrect.y + ((scr_vrect.height - crosshair_height)>>1), crosshair_pic); ! 335: } ! 336: /* ! 337: ================== ! 338: V_RenderView ! 339: ================== ! 340: */ ! 341: void V_RenderView( float stereo_separation ) ! 342: { ! 343: extern int entitycmpfnc( const entity_t *, const entity_t * ); ! 344: ! 345: if (cls.state != ca_active) ! 346: return; ! 347: if (!cl.refresh_prepped) ! 348: return; // still loading ! 349: ! 350: if (cl_timedemo->value) ! 351: { ! 352: if (!cl.timedemo_start) ! 353: cl.timedemo_start = Sys_Milliseconds (); ! 354: cl.timedemo_frames++; ! 355: } ! 356: ! 357: // an invalid frame will just use the exact previous refdef ! 358: // we can't use the old frame if the video mode has changed, though... ! 359: if ( cl.frame.valid && (cl.force_refdef || !cl_paused->value) ) ! 360: { ! 361: cl.force_refdef = false; ! 362: V_ClearScene (); ! 363: ! 364: // build a refresh entity list and calc cl.sim* ! 365: // this also calls CL_CalcViewValues which loads ! 366: // v_forward, etc. ! 367: CL_AddEntities (); ! 368: if (cl_testparticles->value) ! 369: V_TestParticles (); ! 370: if (cl_testentities->value) ! 371: V_TestEntities (); ! 372: if (cl_testlights->value) ! 373: V_TestLights (); ! 374: if (cl_testblend->value) ! 375: { ! 376: cl.refdef.blend[0] = 1; ! 377: cl.refdef.blend[1] = 0.5; ! 378: cl.refdef.blend[2] = 0.25; ! 379: cl.refdef.blend[3] = 0.5; ! 380: } ! 381: // offset vieworg appropriately if we're doing stereo separation ! 382: if ( stereo_separation != 0 ) ! 383: { ! 384: vec3_t tmp; ! 385: ! 386: VectorScale( cl.v_right, stereo_separation, tmp ); ! 387: VectorAdd( cl.refdef.vieworg, tmp, cl.refdef.vieworg ); ! 388: } ! 389: // never let it sit exactly on a node line, because a water plane can ! 390: // dissapear when viewed with the eye exactly on it. ! 391: // the server protocol only specifies to 1/8 pixel, so add 1/16 in each axis ! 392: cl.refdef.vieworg[0] += 1.0/16; ! 393: cl.refdef.vieworg[1] += 1.0/16; ! 394: cl.refdef.vieworg[2] += 1.0/16; ! 395: ! 396: cl.refdef.x = scr_vrect.x; ! 397: cl.refdef.y = scr_vrect.y; ! 398: cl.refdef.width = scr_vrect.width; ! 399: cl.refdef.height = scr_vrect.height; ! 400: cl.refdef.fov_y = CalcFov (cl.refdef.fov_x, cl.refdef.width, cl.refdef.height); ! 401: cl.refdef.time = cl.time*0.001; ! 402: cl.refdef.areabits = cl.frame.areabits; ! 403: ! 404: if (!cl_add_entities->value) ! 405: r_numentities = 0; ! 406: if (!cl_add_particles->value) ! 407: r_numparticles = 0; ! 408: if (!cl_add_lights->value) ! 409: r_numdlights = 0; ! 410: if (!cl_add_blend->value) ! 411: { ! 412: VectorClear (cl.refdef.blend); ! 413: } ! 414: cl.refdef.num_entities = r_numentities; ! 415: cl.refdef.entities = r_entities; ! 416: cl.refdef.num_particles = r_numparticles; ! 417: cl.refdef.particles = r_particles; ! 418: cl.refdef.num_dlights = r_numdlights; ! 419: cl.refdef.dlights = r_dlights; ! 420: cl.refdef.lightstyles = r_lightstyles; ! 421: cl.refdef.rdflags = cl.frame.playerstate.rdflags; ! 422: // sort entities for better cache locality ! 423: qsort( cl.refdef.entities, cl.refdef.num_entities, sizeof( cl.refdef.entities[0] ), (int (*)(const void *, const void *))entitycmpfnc ); ! 424: } ! 425: re.RenderFrame (&cl.refdef); ! 426: if (cl_stats->value) ! 427: Com_Printf ("ent:%i lt:%i part:%i\n", r_numentities, r_numdlights, r_numparticles); ! 428: if ( log_stats->value && ( log_stats_file != 0 ) ) ! 429: fprintf( log_stats_file, "%i,%i,%i,",r_numentities, r_numdlights, r_numparticles); ! 430: ! 431: ! 432: SCR_AddDirtyPoint (scr_vrect.x, scr_vrect.y); ! 433: SCR_AddDirtyPoint (scr_vrect.x+scr_vrect.width-1, ! 434: scr_vrect.y+scr_vrect.height-1); ! 435: ! 436: SCR_DrawCrosshair (); ! 437: } ! 438: ! 439: /* ! 440: ============= ! 441: V_Viewpos_f ! 442: ============= ! 443: */ ! 444: void V_Viewpos_f (void) ! 445: { ! 446: Com_Printf ("(%i %i %i) : %i\n", (int)cl.refdef.vieworg[0], ! 447: (int)cl.refdef.vieworg[1], (int)cl.refdef.vieworg[2], ! 448: (int)cl.refdef.viewangles[YAW]); ! 449: } ! 450: /* ! 451: ============= ! 452: V_Init ! 453: ============= ! 454: */ ! 455: void V_Init (void) ! 456: { ! 457: Cmd_AddCommand ("gun_next", V_Gun_Next_f); ! 458: Cmd_AddCommand ("gun_prev", V_Gun_Prev_f); ! 459: Cmd_AddCommand ("gun_model", V_Gun_Model_f); ! 460: ! 461: Cmd_AddCommand ("viewpos", V_Viewpos_f); ! 462: crosshair = Cvar_Get ("crosshair", "0", CVAR_ARCHIVE); ! 463: cl_testblend = Cvar_Get ("cl_testblend", "0", 0); ! 464: cl_testparticles = Cvar_Get ("cl_testparticles", "0", 0); ! 465: cl_testentities = Cvar_Get ("cl_testentities", "0", 0); ! 466: cl_testlights = Cvar_Get ("cl_testlights", "0", 0); ! 467: ! 468: cl_stats = Cvar_Get ("cl_stats", "0", 0); ! 469: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.