/* Copyright (C) 1996-1997 Id Software, Inc. 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. */ // r_misc.c #include "quakedef.h" #include "r_local.h" extern int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2; /* =============== R_CheckVariables =============== */ void R_CheckVariables (void) { } /* ============ Show Debugging use ============ */ void Show (void) { vrect_t vr; vr.x = vr.y = 0; vr.width = vid.width; vr.height = vid.height; vr.pnext = NULL; SWVID_Update (&vr); } /* ==================== R_TimeRefresh_f For program optimization ==================== */ void SWR_TimeRefresh_f (void) { int i; float start, stop, time; int startangle; vrect_t vr; startangle = r_refdef.viewangles[1]; start = Sys_DoubleTime (); for (i=0 ; i<128 ; i++) { r_refdef.viewangles[1] = i/128.0*360.0; VID_LockBuffer (); R_RenderView (); VID_UnlockBuffer (); vr.x = r_refdef.vrect.x; vr.y = r_refdef.vrect.y; vr.width = r_refdef.vrect.width; vr.height = r_refdef.vrect.height; vr.pnext = NULL; SWVID_Update (&vr); } stop = Sys_DoubleTime (); time = stop-start; Con_Printf ("%f seconds (%f fps)\n", time, 128/time); r_refdef.viewangles[1] = startangle; } /* ================ R_LineGraph Only called by R_DisplayTime ================ */ void R_LineGraph (int x, int y, int h) { int i; qbyte *dest; int s; int color; // FIXME: should be disabled on no-buffer adapters, or should be in the driver // x += r_refdef.vrect.x; // y += r_refdef.vrect.y; dest = vid.buffer + vid.rowbytes*y + x; s = r_graphheight.value; if (h == 10000) color = 0x6f; // yellow else if (h == 9999) color = 0x4f; // red else if (h == 9998) color = 0xd0; // blue else color = 0xff; // pink if (h>s) h = s; for (i=0 ; i>1); y = vid.height - sb_lines - 24 - (int)r_graphheight.value*2 - 2; M_DrawTextBox (x, y, (w+7)/8, ((int)r_graphheight.value*2+7)/8 + 1); y2 = y + 8; y = vid.height - sb_lines - 8 - 2; x = 8; lost = CL_CalcNet(); for (a=NET_TIMINGS-w ; anormal); *dist = p->dist - d; // TODO: when we have rotating entities, this will need to use the view matrix TransformVector (p->normal, normal); } /* =============== R_SetUpFrustumIndexes =============== */ void R_SetUpFrustumIndexes (void) { int i, j, *pindex; pindex = r_frustum_indexes; for (i=0 ; i<4 ; i++) { for (j=0 ; j<3 ; j++) { if (view_clipplanes[i].normal[j] < 0) { pindex[j] = j; pindex[j+3] = j+3; } else { pindex[j] = j+3; pindex[j+3] = j; } } // FIXME: do just once at start pfrustum_indexes[i] = pindex; pindex += 6; } } /* =============== R_SetupFrame =============== */ void SWR_SetupFrame (void) { static mleaf_t fakeleaf; extern int r_dosirds; extern int scr_chatmode; int edgecount; vrect_t vrect; float w, h; // don't allow cheats in multiplayer if (r_numsurfs.value) { if ((surface_p - surfaces) > r_maxsurfsseen) r_maxsurfsseen = surface_p - surfaces; Con_Printf ("Used %d of %d surfs; %d max\n", surface_p - surfaces, surf_max - surfaces, r_maxsurfsseen); } if (r_numedges.value) { edgecount = edge_p - r_edges; if (edgecount > r_maxedgesseen) r_maxedgesseen = edgecount; Con_Printf ("Used %d of %d edges; %d max\n", edgecount, r_numallocatededges, r_maxedgesseen); } r_refdef.ambientlight = r_ambient.value; if (r_refdef.ambientlight < 0) r_refdef.ambientlight = 0; // if (!sv.active) r_draworder.value = 0; // don't let cheaters look behind walls R_CheckVariables (); SWR_AnimateLight (); r_framecount++; numbtofpolys = 0; // debugging #if 0 r_refdef.vieworg[0]= 80; r_refdef.vieworg[1]= 64; r_refdef.vieworg[2]= 40; r_refdef.viewangles[0]= 0; r_refdef.viewangles[1]= 46.763641357; r_refdef.viewangles[2]= 0; #endif // build the transformation matrix for the given view angles VectorCopy (r_refdef.vieworg, modelorg); VectorCopy (r_refdef.vieworg, r_origin); AngleVectors (r_refdef.viewangles, vpn, vright, vup); if (r_refdef.flags & 1) { r_oldviewleaf = r_viewleaf = &fakeleaf; //so we can use quake1 rendering routines for q2 bsps. r_viewleaf->contents = Q1CONTENTS_EMPTY; } else if (cl.worldmodel->fromgame == fg_quake2) { mleaf_t *leaf; r_viewleaf = &fakeleaf; //so we can use quake1 rendering routines for q2 bsps. r_viewleaf->contents = Q1CONTENTS_EMPTY; r_oldviewcluster = r_viewcluster; r_oldviewcluster2 = r_viewcluster2; leaf = SWMod_PointInLeaf (r_origin, cl.worldmodel); r_viewcluster = r_viewcluster2 = leaf->cluster; // check above and below so crossing solid water doesn't draw wrong if (!leaf->contents) { // look down a bit vec3_t temp; VectorCopy (r_origin, temp); temp[2] -= 16; leaf = SWMod_PointInLeaf (temp, cl.worldmodel); if ( !(leaf->contents & Q2CONTENTS_SOLID) && (leaf->cluster != r_viewcluster2) ) r_viewcluster2 = leaf->cluster; } else { // look up a bit vec3_t temp; VectorCopy (r_origin, temp); temp[2] += 16; leaf = SWMod_PointInLeaf (temp, cl.worldmodel); if ( !(leaf->contents & Q2CONTENTS_SOLID) && (leaf->cluster != r_viewcluster2) ) r_viewcluster2 = leaf->cluster; } } else { // current viewleaf r_oldviewleaf = r_viewleaf; r_viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel); } r_dowarpold = r_dowarp; #ifdef SIDEVIEWS r_dowarp = r_waterwarp.value && (r_viewleaf->contents <= Q1CONTENTS_WATER) && !r_secondaryview; #else r_dowarp = r_waterwarp.value && (r_viewleaf->contents <= Q1CONTENTS_WATER); #endif if (vid.width > MAXWIDTH || r_pixbytes != 1 || scr_chatmode) r_dowarp = 0; if (r_dosirds) r_dowarp = 0; if ((r_dowarp != r_dowarpold) || r_viewchanged) { if (r_dowarp) { if ((vid.width <= vid.maxwarpwidth) && (vid.height <= vid.maxwarpheight)) { vrect.x = 0; vrect.y = 0; vrect.width = vid.width; vrect.height = vid.height; SWR_ViewChanged (&vrect, sb_lines, vid.aspect); } else { w = vid.width; h = vid.height; if (w > vid.maxwarpwidth) { h *= (float)vid.maxwarpwidth / w; w = vid.maxwarpwidth; } if (h > vid.maxwarpheight) { h = vid.maxwarpheight; w *= (float)vid.maxwarpheight / h; } vrect.x = 0; vrect.y = 0; vrect.width = (int)w; vrect.height = (int)h; SWR_ViewChanged (&vrect, (int)((float)sb_lines * (h/(float)vid.height)), vid.aspect * (h / w) * ((float)vid.width / (float)vid.height)); } } else { vrect.x = 0; vrect.y = 0; vrect.width = vid.width; vrect.height = vid.height; SWR_ViewChanged (&vrect, sb_lines, vid.aspect); } r_viewchanged = false; } // start off with just the four screen edge clip planes R_TransformFrustum (); // save base values VectorCopy (vpn, base_vpn); VectorCopy (vright, base_vright); VectorCopy (vup, base_vup); VectorCopy (modelorg, base_modelorg); R_SetSkyFrame (); R_SetUpFrustumIndexes (); r_cache_thrash = false; // clear frame counts c_faceclip = 0; d_spanpixcount = 0; r_polycount = 0; r_drawnpolycount = 0; r_wholepolycount = 0; r_amodels_drawn = 0; r_outofsurfaces = 0; r_outofedges = 0; D_SetupFrame (); }