added back r_speeds2, with masses of information (6 lines high), and made it print...
authorlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 9 Feb 2001 12:11:11 +0000 (12:11 +0000)
committerlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 9 Feb 2001 12:11:11 +0000 (12:11 +0000)
changed fps reading to be integer, no fraction (is this desirable?) and moved it to bottom right corner
changed rendering order yet again
made sky and waterripple speed dependent on cl.time rather than realtime (undecided if this is desirable)
made console scrolling not subject to slowmo time scaling
some whitespace changes/cleanup
moved some registervariable definitions around
optional new worldnode function (r_newworldnode, defaults to off), very different approach, minimal speed differences...  sigh
added backface culling on surfaces (r_nobacks, defaults to off), barely a gain
in worldnode, made 'trivial inclusion' case for all children nodes of a completely successful CullBox test, defaults to off because it was no speed gain even on the most complex maps I could find
readability cleanup and minor speedup in lightmap conversion
added host_minfps (if framerate drops below this it will be slowmo, this replaces quake's hardcoded 10fps limit)
added host_maxfps (limit your framerate if desired, defaults to 1000, this does affect timedemo)
improved slowmo behavior
optimized out most vec3_origin uses (created VectorNegate and VectorClear for this reason)
fixed VectorDistance (old definition didn't work correctly, but never got used anyway)
darkened blood trails a bit
split R_DrawParticles into R_MoveParticles and R_DrawParticles (for speed profiling reasons)
fix for extremely rare and probably unnoticable bug in particle compacter
fixed a number of prediction issues, prediction does not occur in local games anymore, prediction also made optional (sv_predict cvar)

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@147 d7cf8633-e32d-0410-b094-e92efae38249

22 files changed:
cl_main.c
gl_models.c
gl_poly.c
gl_refrag.c
gl_rmain.c
gl_rmisc.c
gl_rsurf.c
gl_screen.c
gl_warp.c
glquake.h
host.c
mathlib.h
model_brush.h
pr_edict.c
quakedef.h
r_part.c
r_sprites.c
render.h
sv_main.c
sv_phys.c
sv_user.c
world.c

index 7732166..56d77ab 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -350,7 +350,9 @@ void CL_DecayLights (void)
        {
                if (dl->die < cl.time || !dl->radius)
                        continue;
-               
+
+               c_dlights++; // count every dlight in use
+
                dl->radius -= time*dl->decay;
                if (dl->radius < 0)
                        dl->radius = 0;
index 87adbe9..8b2d282 100644 (file)
@@ -650,6 +650,8 @@ void R_DrawAliasModel (entity_t *ent, int cull, float alpha, model_t *clmodel, i
        if (cull && R_CullBox (mins, maxs))
                return;
 
+       c_models++;
+
        leaf = Mod_PointInLeaf (org, cl.worldmodel);
        if (leaf->dlightframe == r_dlightframecount)
                for (i = 0;i < 8;i++)
index 4252170..2631e35 100644 (file)
--- a/gl_poly.c
+++ b/gl_poly.c
@@ -813,7 +813,7 @@ void skypolyrender()
                glDisable(GL_BLEND);
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                glBindTexture(GL_TEXTURE_2D, solidskytexture); // upper clouds
-               speedscale = realtime*8;
+               speedscale = cl.time*8;
                speedscale -= (int)speedscale & ~127 ;
                for (i = 0,p = &skypoly[0];i < currentskypoly;i++, p++)
                {
@@ -836,7 +836,7 @@ void skypolyrender()
                glEnable(GL_BLEND);
                glDepthMask(0);
                glBindTexture(GL_TEXTURE_2D, alphaskytexture); // lower clouds
-               speedscale = realtime*16;
+               speedscale = cl.time*16;
                speedscale -= (int)speedscale & ~127 ;
                for (i = 0,p = &skypoly[0];i < currentskypoly;i++, p++)
                {
index 1a85e7c..224899f 100644 (file)
@@ -229,20 +229,17 @@ void R_StoreEfrags (efrag_t **ppefrag)
                case mod_sprite:
                        pent = pefrag->entity;
 
-                       if ((pent->visframe != r_framecount) &&
-                               (cl_numvisedicts < MAX_VISEDICTS))
+                       if ((pent->visframe != r_framecount) && (cl_numvisedicts < MAX_VISEDICTS))
                        {
                                cl_visedicts[cl_numvisedicts++] = pent;
-
-                       // mark that we've recorded this entity for this frame
-                               pent->visframe = r_framecount;
+                               pent->visframe = r_framecount; // render each entity only once per frame
                        }
 
                        ppefrag = &pefrag->leafnext;
                        break;
 
                default:        
-                       Sys_Error ("R_StoreEfrags: Bad entity type %d\n", clmodel->type);
+                       Host_Error ("R_StoreEfrags: Bad entity type %d\n", clmodel->type);
                }
        }
 }
index 1575fc0..907822e 100644 (file)
@@ -33,7 +33,7 @@ int                   r_framecount;           // used for dlight push checking
 
 mplane_t       frustum[4];
 
-int                    c_brush_polys, c_alias_polys, c_light_polys, c_nodes, c_leafs;
+int                    c_brush_polys, c_alias_polys, c_light_polys, c_faces, c_nodes, c_leafs, c_models, c_bmodels, c_sprites, c_particles, c_dlights;
 
 qboolean       envmap;                         // true during envmap command capture 
 
@@ -223,6 +223,10 @@ void glmain_shutdown()
 void GL_Main_Init()
 {
        FOG_registercvars();
+       Cvar_RegisterVariable (&r_drawentities);
+       Cvar_RegisterVariable (&r_drawviewmodel);
+       Cvar_RegisterVariable (&r_shadows);
+       Cvar_RegisterVariable (&r_speeds);
        Cvar_RegisterVariable (&r_speeds2);
        Cvar_RegisterVariable (&contrast);
        Cvar_RegisterVariable (&brightness);
@@ -230,6 +234,10 @@ void GL_Main_Init()
 //     Cvar_RegisterVariable (&r_dynamicwater);
 //     Cvar_RegisterVariable (&r_dynamicbothsides);
        Cvar_RegisterVariable (&r_fullbrights);
+       Cvar_RegisterVariable (&r_wateralpha);
+       Cvar_RegisterVariable (&r_dynamic);
+       Cvar_RegisterVariable (&r_novis);
+       Cvar_RegisterVariable (&r_waterripple); // LordHavoc: added waterripple
        if (nehahra)
                Cvar_SetValue("r_fullbrights", 0);
 //     if (gl_vendor && strstr(gl_vendor, "3Dfx"))
@@ -484,8 +492,14 @@ void R_SetupFrame (void)
        c_brush_polys = 0;
        c_alias_polys = 0;
        c_light_polys = 0;
+       c_faces = 0;
        c_nodes = 0;
        c_leafs = 0;
+       c_models = 0;
+       c_bmodels = 0;
+       c_sprites = 0;
+       c_particles = 0;
+       c_dlights = 0;
 
 }
 
@@ -586,10 +600,6 @@ void R_SetupGL (void)
        glShadeModel(GL_SMOOTH);
 }
 
-void R_DrawWorld (void);
-//void R_RenderDlights (void);
-void R_DrawParticles (void);
-
 /*
 =============
 R_Clear
@@ -680,6 +690,7 @@ void GL_BlendView()
        glEnable(GL_TEXTURE_2D);
 }
 
+/*
 #define TIMEREPORT(DESC) \
        if (r_speeds2.value)\
        {\
@@ -688,6 +699,14 @@ void GL_BlendView()
                temptime += currtime;\
                Con_Printf(DESC " %.4fms ", temptime * 1000.0);\
        }
+*/
+#define TIMEREPORT(VAR) \
+       if (r_speeds2.value)\
+       {\
+               temptime = currtime;\
+               currtime = Sys_FloatTime();\
+               VAR = (int) ((currtime - temptime) * 1000000.0);\
+       }
 
 /*
 ================
@@ -700,8 +719,11 @@ extern qboolean intimerefresh;
 extern qboolean skyisvisible;
 extern void R_Sky();
 extern void UploadLightmaps();
+char r_speeds2_string1[81], r_speeds2_string2[81], r_speeds2_string3[81], r_speeds2_string4[81], r_speeds2_string5[81], r_speeds2_string6[81];
 void R_RenderView (void)
 {
+       double starttime, currtime, temptime;
+       int time_clear, time_setup, time_world, time_bmodels, time_upload, time_sky, time_wall, time_models, time_moveparticles, time_drawparticles, time_transpoly, time_blend, time_total;
 //     double currtime, temptime;
 //     if (r_norefresh.value)
 //             return;
@@ -713,47 +735,71 @@ void R_RenderView (void)
 
        FOG_framebegin();
 
-//     if (r_speeds2.value)
-//     {
-//             currtime = Sys_FloatTime();
+       if (r_speeds2.value)
+       {
+               starttime = currtime = Sys_FloatTime();
 //             Con_Printf("render time: ");
-//     }
+       }
        R_Clear();
-//     TIMEREPORT("R_Clear")
+       skypolyclear();
+       wallpolyclear();
+       transpolyclear();
+       skyisvisible = false;
+       TIMEREPORT(time_clear)
 
        // render normal view
 
        R_SetupFrame ();
        R_SetFrustum ();
        R_SetupGL ();
-
-       skypolyclear();
-       wallpolyclear();
-       transpolyclear();
-       skyisvisible = false;
+       TIMEREPORT(time_setup)
 
        R_MarkLeaves ();        // done here so we know if we're in water
        R_DrawWorld ();         // adds static entities to the list
-       if (!intimerefresh)
-               S_ExtraUpdate ();       // don't let sound get messed up if going slow
+       TIMEREPORT(time_world)
        R_DrawEntitiesOnList1 (); // BSP models
+       TIMEREPORT(time_bmodels)
+
+       UploadLightmaps();
+       TIMEREPORT(time_upload)
 
        skypolyrender(); // fogged sky polys, affects depth
+
        if (skyname[0] && skyisvisible && !fogenabled)
                R_Sky(); // does not affect depth, draws over the sky polys
+       TIMEREPORT(time_sky)
 
-       UploadLightmaps();
        wallpolyrender();
+       TIMEREPORT(time_wall)
+
+//     if (!intimerefresh)
+//             S_ExtraUpdate ();       // don't let sound get messed up if going slow
 
        R_DrawEntitiesOnList2 (); // other models
 //     R_RenderDlights ();
        R_DrawViewModel ();
+       TIMEREPORT(time_models)
+       R_MoveParticles ();
+       TIMEREPORT(time_moveparticles)
        R_DrawParticles ();
+       TIMEREPORT(time_drawparticles)
 
        transpolyrender();
+       TIMEREPORT(time_transpoly)
 
        FOG_frameend();
+
        GL_BlendView();
-//     if (r_speeds2.value)
+       TIMEREPORT(time_blend)
+       if (r_speeds2.value)
+       {
+               time_total = (int) ((Sys_FloatTime() - starttime) * 1000000.0);
 //             Con_Printf("\n");
+               sprintf(r_speeds2_string1, "%6i walls %6i dlitwalls %7i modeltris %7i transpoly\n", c_brush_polys, c_light_polys, c_alias_polys, currenttranspoly);
+               sprintf(r_speeds2_string2, "BSP: %6i faces %6i nodes %6i leafs\n", c_faces, c_nodes, c_leafs);
+               sprintf(r_speeds2_string3, "%4i models %4i bmodels %4i sprites %5i particles %3i dlights\n", c_models, c_bmodels, c_sprites, c_particles, c_dlights);
+               sprintf(r_speeds2_string4, "%6ius clear  %6ius setup  %6ius world  %6ius bmodel %6ius upload", time_clear, time_setup, time_world, time_bmodels, time_upload);
+               sprintf(r_speeds2_string5, "%6ius sky    %6ius wall   %6ius models %6ius mpart  %6ius dpart ", time_sky, time_wall, time_models, time_moveparticles, time_drawparticles);
+               sprintf(r_speeds2_string6, "%6ius trans  %6ius blend  %6ius total  %6ius permdl", time_transpoly, time_blend, time_total, time_models / max(c_models, 1));
+       }
 }
index 0d9df63..2a07083 100644 (file)
@@ -143,18 +143,8 @@ R_Init
 */
 void GL_Misc_Init (void)
 {      
-       Cmd_AddCommand ("timerefresh", R_TimeRefresh_f);        
        Cmd_AddCommand ("envmap", R_Envmap_f);  
-       Cmd_AddCommand ("pointfile", R_ReadPointFile_f);        
-
-       Cvar_RegisterVariable (&r_drawentities);
-       Cvar_RegisterVariable (&r_drawviewmodel);
-       Cvar_RegisterVariable (&r_shadows);
-       Cvar_RegisterVariable (&r_wateralpha);
-       Cvar_RegisterVariable (&r_dynamic);
-       Cvar_RegisterVariable (&r_novis);
-       Cvar_RegisterVariable (&r_speeds);
-       Cvar_RegisterVariable (&r_waterripple); // LordHavoc: added waterripple
+       Cmd_AddCommand ("timerefresh", R_TimeRefresh_f);        
 
        R_RegisterModule("GL_Misc", gl_misc_start, gl_misc_shutdown);
 }
index 70afc09..6ab30c4 100644 (file)
@@ -48,6 +48,8 @@ cvar_t r_ambient = {"r_ambient", "0"};
 cvar_t gl_vertex = {"gl_vertex", "0"};
 cvar_t gl_texsort = {"gl_texsort", "1"};
 //cvar_t gl_funnywalls = {"gl_funnywalls", "0"}; // LordHavoc: see BuildSurfaceDisplayList
+cvar_t r_newworldnode = {"r_newworldnode", "0"};
+cvar_t r_oldclip = {"r_oldclip", "1"};
 
 qboolean lightmaprgba, nosubimagefragments, nosubimage, skyisvisible;
 int lightmapbytes;
@@ -77,6 +79,8 @@ void GL_Surf_Init()
 //     Cvar_RegisterVariable(&gl_funnywalls);
        Cvar_RegisterVariable(&gl_vertex);
        Cvar_RegisterVariable(&gl_texsort);
+       Cvar_RegisterVariable(&r_newworldnode);
+       Cvar_RegisterVariable(&r_oldclip);
        // check if it's the glquake minigl driver
        if (strncasecmp(gl_vendor,"3Dfx",4)==0)
        if (!gl_arrays)
@@ -99,7 +103,6 @@ Combine and scale multiple lightmaps into the 8.8 format in blocklights
 void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
 {
        int                     smax, tmax;
-       int                     t;
        int                     i, j, size;
        byte            *lightmap;
        int                     scale;
@@ -139,6 +142,7 @@ void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
 
 // add all the lightmaps
                if (lightmap)
+               {
                        for (maps = 0;maps < MAXLIGHTMAPS && surf->styles[maps] != 255;maps++)
                        {
                                scale = d_lightstylevalue[surf->styles[maps]];
@@ -151,6 +155,7 @@ void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
                                        *bl++ += *lightmap++ * scale;
                                }
                        }
+               }
        }
        stride -= (smax*lightmapbytes);
        bl = blocklights;
@@ -160,26 +165,26 @@ void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
                // the image is brightened as a processing pass
                if (lightmaprgba)
                {
-                       for (i=0 ; i<tmax ; i++, dest += stride)
+                       for (i = 0;i < tmax;i++, dest += stride)
                        {
-                               for (j=0 ; j<smax ; j++)
+                               for (j = 0;j < smax;j++, bl += 3, dest += 4)
                                {
-                                       t = *bl++ >> 8;if (t > 255) t = 255;else if (t < 0) t = 0;*dest++ = t;
-                                       t = *bl++ >> 8;if (t > 255) t = 255;else if (t < 0) t = 0;*dest++ = t;
-                                       t = *bl++ >> 8;if (t > 255) t = 255;else if (t < 0) t = 0;*dest++ = t;
-                                       *dest++ = 255;
+                                       dest[0] = min(bl[0] >> 8, 255);
+                                       dest[1] = min(bl[1] >> 8, 255);
+                                       dest[2] = min(bl[2] >> 8, 255);
+                                       dest[3] = 255;
                                }
                        }
                }
                else
                {
-                       for (i=0 ; i<tmax ; i++, dest += stride)
+                       for (i = 0;i < tmax;i++, dest += stride)
                        {
-                               for (j=0 ; j<smax ; j++)
+                               for (j = 0;j < smax;j++, bl += 3, dest += 3)
                                {
-                                       t = *bl++ >> 8;if (t > 255) t = 255;else if (t < 0) t = 0;*dest++ = t;
-                                       t = *bl++ >> 8;if (t > 255) t = 255;else if (t < 0) t = 0;*dest++ = t;
-                                       t = *bl++ >> 8;if (t > 255) t = 255;else if (t < 0) t = 0;*dest++ = t;
+                                       dest[0] = min(bl[0] >> 8, 255);
+                                       dest[1] = min(bl[1] >> 8, 255);
+                                       dest[2] = min(bl[2] >> 8, 255);
                                }
                        }
                }
@@ -188,26 +193,26 @@ void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
        {
                if (lightmaprgba)
                {
-                       for (i=0 ; i<tmax ; i++, dest += stride)
+                       for (i = 0;i < tmax;i++, dest += stride)
                        {
-                               for (j=0 ; j<smax ; j++)
+                               for (j = 0;j < smax;j++, bl += 3, dest += 4)
                                {
-                                       t = *bl++ >> 7;if (t > 255) t = 255;else if (t < 0) t = 0;*dest++ = t;
-                                       t = *bl++ >> 7;if (t > 255) t = 255;else if (t < 0) t = 0;*dest++ = t;
-                                       t = *bl++ >> 7;if (t > 255) t = 255;else if (t < 0) t = 0;*dest++ = t;
-                                       *dest++ = 255;
+                                       dest[0] = min(bl[0] >> 7, 255);
+                                       dest[1] = min(bl[1] >> 7, 255);
+                                       dest[2] = min(bl[2] >> 7, 255);
+                                       dest[3] = 255;
                                }
                        }
                }
                else
                {
-                       for (i=0 ; i<tmax ; i++, dest += stride)
+                       for (i = 0;i < tmax;i++, dest += stride)
                        {
-                               for (j=0 ; j<smax ; j++)
+                               for (j = 0;j < smax;j++, bl += 3, dest += 3)
                                {
-                                       t = *bl++ >> 7;if (t > 255) t = 255;else if (t < 0) t = 0;*dest++ = t;
-                                       t = *bl++ >> 7;if (t > 255) t = 255;else if (t < 0) t = 0;*dest++ = t;
-                                       t = *bl++ >> 7;if (t > 255) t = 255;else if (t < 0) t = 0;*dest++ = t;
+                                       dest[0] = min(bl[0] >> 7, 255);
+                                       dest[1] = min(bl[1] >> 7, 255);
+                                       dest[2] = min(bl[2] >> 7, 255);
                                }
                        }
                }
@@ -441,7 +446,7 @@ int RSurf_Light(int *dlightbits, glpoly_t *polys)
 void RSurf_DrawWater(msurface_t *s, texture_t *t, int transform, int alpha)
 {
        int             i;
-       float   os = turbsin[(int)(realtime * TURBSCALE) & 255], ot = turbsin[(int)(realtime * TURBSCALE + 96.0) & 255];
+       float   os = turbsin[(int)(realtime * TURBSCALE) & 255], ot = turbsin[(int)(cl.time * TURBSCALE + 96.0) & 255];
        glpoly_t *p;
        float   *wv, *v;
        wv = wvert;
@@ -454,7 +459,7 @@ void RSurf_DrawWater(msurface_t *s, texture_t *t, int transform, int alpha)
                        else
                                VectorCopy(v, wv);
                        if (r_waterripple.value)
-                               wv[2] += r_waterripple.value * turbsin[(int)((wv[0]*(1.0f/32.0f)+realtime) * TURBSCALE) & 255] * turbsin[(int)((wv[1]*(1.0f/32.0f)+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f);
+                               wv[2] += r_waterripple.value * turbsin[(int)((wv[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((wv[1]*(1.0f/32.0f)+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f);
                        wv[3] = wv[4] = wv[5] = 128.0f;
                        wv += 6;
                }
@@ -732,6 +737,8 @@ void R_DrawBrushModel (entity_t *e)
        if (R_CullBox (mins, maxs))
                return;
 
+       c_bmodels++;
+
        VectorSubtract (r_refdef.vieworg, e->origin, modelorg);
        if (rotated)
        {
@@ -799,10 +806,78 @@ e->angles[0] = -e->angles[0];     // stupid quake bug
 
 void R_StoreEfrags (efrag_t **ppefrag);
 
+void R_NewWorldNode ()
+{
+       int l, texsort = gl_texsort.value, vertex = gl_vertex.value;
+       mleaf_t *leaf;
+       msurface_t *surf, **mark, **endmark;
+
+       for (l = 0, leaf = cl.worldmodel->leafs;l < cl.worldmodel->numleafs;l++, leaf++)
+       {
+               if ((leaf->visframe == r_visframecount) && (leaf->efrags || leaf->nummarksurfaces))
+               {
+                       if (R_CullBox(leaf->minmaxs, leaf->minmaxs+3))
+                               continue;
+
+                       c_leafs++;
+
+                       // deal with model fragments in this leaf
+                       if (leaf->efrags)
+                               R_StoreEfrags (&leaf->efrags);
+
+                       if (leaf->nummarksurfaces)
+                       {
+                               mark = leaf->firstmarksurface;
+                               endmark = mark + leaf->nummarksurfaces;
+                               do
+                               {
+                                       surf = *mark++;
+                                       // make sure surfaces are only processed once
+                                       if (surf->worldnodeframe == r_framecount)
+                                               continue;
+                                       surf->worldnodeframe = r_framecount;
+                                       if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
+                                       {
+                                               if ( (surf->flags & SURF_PLANEBACK))
+                                               {
+                                                       surf->visframe = r_framecount;
+                                                       c_faces++;
+                                                       if (texsort)
+                                                       {
+                                                               surf->texturechain = surf->texinfo->texture->texturechain;
+                                                               surf->texinfo->texture->texturechain = surf;
+                                                       }
+                                                       else
+                                                               R_DrawSurf(surf, false, vertex);
+                                               }
+                                       }
+                                       else
+                                       {
+                                               if (!(surf->flags & SURF_PLANEBACK))
+                                               {
+                                                       surf->visframe = r_framecount;
+                                                       c_faces++;
+                                                       if (texsort)
+                                                       {
+                                                               surf->texturechain = surf->texinfo->texture->texturechain;
+                                                               surf->texinfo->texture->texturechain = surf;
+                                                       }
+                                                       else
+                                                               R_DrawSurf(surf, false, vertex);
+                                               }
+                                       }
+                               }
+                               while (mark < endmark);
+                       }
+               }
+       }
+}
+
 struct nodestack_s
 {
        int side;
        mnode_t *node;
+       int noclipping;
 } nodestack[8192];
 
 /*
@@ -812,20 +887,43 @@ R_WorldNode
 */
 void R_WorldNode ()
 {
-       int side, texsort, vertex;
+       int side, texsort = gl_texsort.value, vertex = gl_vertex.value, ca, cb, cc, cd, noclipping = false, oldclip = r_oldclip.value;
        struct nodestack_s *nstack;
        mnode_t *node;
        mleaf_t *pleaf;
        msurface_t *surf, *endsurf, **mark, **endmark;
        nstack = nodestack;
-       texsort = gl_texsort.value;
-       vertex = gl_vertex.value;
 
        if (!(node = cl.worldmodel->nodes))
                return;
 
        while(1)
        {
+               if (oldclip)
+               {
+                       if (R_CullBox(node->minmaxs, node->minmaxs+3))
+                       {
+backupstack:
+                               if (nstack <= nodestack)
+                                       break;
+                               nstack--;
+                               node = nstack->node;
+                               side = nstack->side;
+                               noclipping = nstack->noclipping;
+                               goto loc0;
+                       }
+               }
+               else
+               if (!noclipping)
+               {
+                       ca = frustum[0].BoxOnPlaneSideFunc(node->minmaxs, node->minmaxs+3, &frustum[0]);if (ca == 2) goto backupstack; // completely clipped away
+                       cb = frustum[1].BoxOnPlaneSideFunc(node->minmaxs, node->minmaxs+3, &frustum[1]);if (cb == 2) goto backupstack; // completely clipped away
+                       cc = frustum[2].BoxOnPlaneSideFunc(node->minmaxs, node->minmaxs+3, &frustum[2]);if (cc == 2) goto backupstack; // completely clipped away
+                       cd = frustum[3].BoxOnPlaneSideFunc(node->minmaxs, node->minmaxs+3, &frustum[3]);if (cd == 2) goto backupstack; // completely clipped away
+                       if (ca == 0 && cb == 0 && cc == 0 && cd == 0)
+                               noclipping = true; // not clipped at all, no need to clip any children of this node
+                       // partially clipped node
+               }
        // if a leaf node, draw stuff
                if (node->contents < 0)
                {
@@ -856,6 +954,7 @@ void R_WorldNode ()
                        nstack--;
                        node = nstack->node;
                        side = nstack->side;
+                       noclipping = nstack->noclipping;
                        goto loc0;
                }
 
@@ -867,10 +966,11 @@ void R_WorldNode ()
                side = PlaneDist(modelorg, node->plane) < node->plane->dist;
 
                // recurse down the children, front side first
-               if (node->children[side]->visframe == r_visframecount && R_NotCulledBox(node->children[side]->minmaxs, node->children[side]->minmaxs+3))
+               if (node->children[side]->visframe == r_visframecount)
                {
                        nstack->node = node;
                        nstack->side = !side; // go down back side when we come back up
+                       nstack->noclipping = noclipping;
                        nstack++;
                        node = node->children[side];
                        continue;
@@ -892,9 +992,12 @@ loc0:
                                        {
                                                if (surf->visframe == r_framecount && !(surf->flags & SURF_PLANEBACK))
                                                {
+                                                       c_faces++;
                                                        surf->texturechain = surf->texinfo->texture->texturechain;
                                                        surf->texinfo->texture->texturechain = surf;
                                                }
+                                               else
+                                                       surf->visframe = -1; // LordHavoc: mark as not visible, so lighting will not touch it
                                                surf++;
                                        }
                                        while (surf < endsurf);
@@ -905,9 +1008,12 @@ loc0:
                                        {
                                                if (surf->visframe == r_framecount && (surf->flags & SURF_PLANEBACK))
                                                {
+                                                       c_faces++;
                                                        surf->texturechain = surf->texinfo->texture->texturechain;
                                                        surf->texinfo->texture->texturechain = surf;
                                                }
+                                               else
+                                                       surf->visframe = -1; // LordHavoc: mark as not visible, so lighting will not touch it
                                                surf++;
                                        }
                                        while (surf < endsurf);
@@ -920,7 +1026,12 @@ loc0:
                                        do
                                        {
                                                if (surf->visframe == r_framecount && !(surf->flags & SURF_PLANEBACK))
+                                               {
+                                                       c_faces++;
                                                        R_DrawSurf(surf, false, vertex);
+                                               }
+                                               else
+                                                       surf->visframe = -1; // LordHavoc: mark as not visible, so lighting will not touch it
                                                surf++;
                                        }
                                        while (surf < endsurf);
@@ -930,7 +1041,12 @@ loc0:
                                        do
                                        {
                                                if (surf->visframe == r_framecount && (surf->flags & SURF_PLANEBACK))
+                                               {
+                                                       c_faces++;
                                                        R_DrawSurf(surf, false, vertex);
+                                               }
+                                               else
+                                                       surf->visframe = -1; // LordHavoc: mark as not visible, so lighting will not touch it
                                                surf++;
                                        }
                                        while (surf < endsurf);
@@ -939,7 +1055,7 @@ loc0:
                }
 
        // recurse down the back side
-               if (node->children[side]->visframe == r_visframecount && R_NotCulledBox(node->children[side]->minmaxs, node->children[side]->minmaxs+3))
+               if (node->children[side]->visframe == r_visframecount)
                {
                        node = node->children[side];
                        continue;
@@ -950,6 +1066,7 @@ loc0:
                nstack--;
                node = nstack->node;
                side = nstack->side;
+               noclipping = nstack->noclipping;
                goto loc0;
        }
 }
@@ -977,7 +1094,12 @@ void R_DrawWorld (void)
        softwaretransformidentity(); // LordHavoc: clear transform
 
        if (cl.worldmodel)
-               R_WorldNode ();
+       {
+               if (r_newworldnode.value)
+                       R_NewWorldNode ();
+               else
+                       R_WorldNode ();
+       }
 
        R_PushDlights (); // now mark the lit surfaces
 
index ab123c0..0e59395 100644 (file)
@@ -541,14 +541,14 @@ void SCR_SetUpToDrawConsole (void)
        
        if (scr_conlines < scr_con_current)
        {
-               scr_con_current -= scr_conspeed.value*host_frametime;
+               scr_con_current -= scr_conspeed.value*host_realframetime;
                if (scr_conlines > scr_con_current)
                        scr_con_current = scr_conlines;
 
        }
        else if (scr_conlines > scr_con_current)
        {
-               scr_con_current += scr_conspeed.value*host_frametime;
+               scr_con_current += scr_conspeed.value*host_realframetime;
                if (scr_conlines < scr_con_current)
                        scr_con_current = scr_conlines;
        }
@@ -772,6 +772,7 @@ extern void SHOWLMP_drawall();
 extern cvar_t contrast;
 extern cvar_t brightness;
 extern cvar_t gl_lightmode;
+extern cvar_t r_speeds2;
 
 void GL_BrightenScreen()
 {
@@ -936,10 +937,21 @@ void SCR_UpdateScreen (void)
                char temp[32];
                int calc;
                newtime = Sys_FloatTime();
-               calc = (int) (100.0 / (newtime - currtime));
-               sprintf(temp, "% 4i.%02i fps", calc / 100, calc % 100);
+               calc = (int) ((1.0 / (newtime - currtime)) + 0.5);
+               sprintf(temp, "%4i fps", calc);
                currtime = newtime;
-               Draw_String(vid.width - (12*8), 0, temp, 9999);
+               Draw_String(vid.width - (8*8), vid.height - sb_lines - 8, temp, 9999);
+       }
+
+       if (r_speeds2.value)
+       {
+               extern char r_speeds2_string1[81], r_speeds2_string2[81], r_speeds2_string3[81], r_speeds2_string4[81], r_speeds2_string5[81], r_speeds2_string6[81];
+               Draw_String(0, vid.height - sb_lines - 48, r_speeds2_string1, 80);
+               Draw_String(0, vid.height - sb_lines - 40, r_speeds2_string2, 80);
+               Draw_String(0, vid.height - sb_lines - 32, r_speeds2_string3, 80);
+               Draw_String(0, vid.height - sb_lines - 24, r_speeds2_string4, 80);
+               Draw_String(0, vid.height - sb_lines - 16, r_speeds2_string5, 80);
+               Draw_String(0, vid.height - sb_lines -  8, r_speeds2_string6, 80);
        }
 
        V_UpdateBlends ();
@@ -951,7 +963,7 @@ void SCR_UpdateScreen (void)
        if (r_speeds.value)
        {
                time2 = Sys_FloatTime ();
-               Con_Printf ("%3i ms  %4i wpoly %4i epoly %4i transpoly %4i lightpoly %4i BSPnodes %4i BSPleafs\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys, currenttranspoly, c_light_polys, c_nodes, c_leafs);
+               Con_Printf ("%3i ms  %4i wpoly %4i epoly %4i transpoly %4i lightpoly %4i BSPnodes %4i BSPleafs %4i BSPfaces %4i models %4i bmodels %4i sprites %4i particles %3i dlights\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys, currenttranspoly, c_light_polys, c_nodes, c_leafs, c_faces, c_models, c_bmodels, c_sprites, c_particles, c_dlights);
        }
        GL_EndRendering ();
 }
index 296da18..8f35afb 100644 (file)
--- a/gl_warp.c
+++ b/gl_warp.c
@@ -391,12 +391,12 @@ void R_SkyDome()
                skydomecalc(skydomeouter, 1024, 1024, 256);
                skydomecalc(skydomeinner, 512, 512, 128);
        }
-       speedscale = realtime*8.0/256.0;
+       speedscale = cl.time*8.0/256.0;
        speedscale -= (int)speedscale;
        skydome(skydomeouter, speedscale, 1.0 / 256.0);
        glEnable (GL_BLEND);
        glBindTexture(GL_TEXTURE_2D, alphaskytexture); // lower clouds
-       speedscale = realtime*8.0/128.0;
+       speedscale = cl.time*8.0/128.0;
        speedscale -= (int)speedscale;
        skydome(skydomeinner, speedscale, 1.0 / 128.0);
        glDisable (GL_BLEND);
index c7830ee..89dc8c2 100644 (file)
--- a/glquake.h
+++ b/glquake.h
@@ -71,7 +71,6 @@ extern        int glx, gly, glwidth, glheight;
 
 
 extern void R_TimeRefresh_f (void);
-extern void R_ReadPointFile_f (void);
 
 //====================================================
 
@@ -83,7 +82,7 @@ extern        entity_t        *currententity;
 extern int                     r_visframecount;        // ??? what difs?
 extern int                     r_framecount;
 extern mplane_t        frustum[4];
-extern int             c_brush_polys, c_alias_polys, c_light_polys, c_nodes, c_leafs;
+extern int             c_brush_polys, c_alias_polys, c_light_polys, c_faces, c_nodes, c_leafs, c_models, c_bmodels, c_sprites, c_particles, c_dlights;
 
 
 //
diff --git a/host.c b/host.c
index 8ca544a..25240ec 100644 (file)
--- a/host.c
+++ b/host.c
@@ -37,6 +37,7 @@ quakeparms_t host_parms;
 qboolean       host_initialized;               // true if into command execution
 
 double         host_frametime;
+double         host_realframetime;             // LordHavoc: the real frametime, before slowmo and clamping are applied (used for console scrolling)
 double         host_time;
 double         realtime;                               // without any filtering or bounding
 double         oldrealtime;                    // last frame run
@@ -55,6 +56,8 @@ jmp_buf       host_abortserver;
 cvar_t host_framerate = {"host_framerate","0"};        // set for slow motion
 cvar_t host_speeds = {"host_speeds","0"};                      // set for running times
 cvar_t slowmo = {"slowmo", "1.0"};                                     // LordHavoc: framerate independent slowmo
+cvar_t host_minfps = {"host_minfps", "10"};            // LordHavoc: game logic lower cap on framerate (if framerate is below this is, it pretends it is this, so game logic will run normally)
+cvar_t host_maxfps = {"host_maxfps", "1000"};          // LordHavoc: framerate upper cap
 
 cvar_t sys_ticrate = {"sys_ticrate","0.05"};
 cvar_t serverprofile = {"serverprofile","0"};
@@ -216,6 +219,8 @@ void Host_InitLocal (void)
        Cvar_RegisterVariable (&host_framerate);
        Cvar_RegisterVariable (&host_speeds);
        Cvar_RegisterVariable (&slowmo);
+       Cvar_RegisterVariable (&host_minfps);
+       Cvar_RegisterVariable (&host_maxfps);
 
        Cvar_RegisterVariable (&sys_ticrate);
        Cvar_RegisterVariable (&serverprofile);
@@ -507,21 +512,32 @@ qboolean Host_FilterTime (float time)
 {
        realtime += time;
 
-//     if (!cls.timedemo && realtime - oldrealtime < (1.0 / 72.0))
-//             return false;           // framerate is too high
+       if (slowmo.value < 0.0f)
+               Cvar_SetValue("slowmo", 0.0f);
+       if (host_minfps.value < 10.0f)
+               Cvar_SetValue("host_minfps", 10.0f);
+       if (host_maxfps.value < host_minfps.value)
+               Cvar_SetValue("host_maxfps", host_minfps.value);
 
-       host_frametime = (realtime - oldrealtime) * slowmo.value; // LordHavoc: slowmo cvar
+       if ((!cls.timedemo) && ((realtime - oldrealtime) < (1.0 / host_maxfps.value)))
+               return false;           // framerate is too high
+
+       host_realframetime = host_frametime = realtime - oldrealtime; // LordHavoc: copy into host_realframetime as well
        oldrealtime = realtime;
 
+       if (cls.timedemo)
+               return true; // disable time effects
+
        if (host_framerate.value > 0)
                host_frametime = host_framerate.value;
        else
-       {       // don't allow really long or short frames
-               if (host_frametime > 0.1)
-                       host_frametime = 0.1;
-               if (host_frametime < 0.001)
-                       host_frametime = 0.001;
+       {
+               // don't allow really short frames
+               if (host_frametime > (1.0 / host_minfps.value))
+                       host_frametime = (1.0 / host_minfps.value);
        }
+
+       host_frametime *= slowmo.value;
        
        return true;
 }
index 42c76ea..3b669e9 100644 (file)
--- a/mathlib.h
+++ b/mathlib.h
@@ -40,6 +40,9 @@ extern        int nanmask;
 
 #define bound(min,num,max) (num >= min ? (num < max ? num : max) : min)
 
+#define VectorNegate(a,b) {b[0] = -(a[0]);b[1] = -(a[1]);b[2] = -(a[2]);}
+#define VectorSet(a,b,c,d) {d[0]=(a);d[1]=(b);d[2]=(c);}
+#define VectorClear(a) {a[0]=a[1]=a[2]=0;}
 #define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2])
 #define VectorSubtract(a,b,c) {c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];}
 #define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];}
@@ -48,7 +51,7 @@ extern        int nanmask;
 #define VectorNormalize(v) {float ilength = 1.0f / (float) sqrt(DotProduct(v,v));v[0] *= ilength;v[1] *= ilength;v[2] *= ilength;}
 #define VectorNormalize2(v,dest) {float ilength = 1.0f / (float) sqrt(DotProduct(v,v));dest[0] = v[0] * ilength;dest[1] = v[1] * ilength;dest[2] = v[2] * ilength;}
 #define VectorDistance2(a, b) ((a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]) + (a[2] - b[2]) * (a[2] - b[2]))
-#define VectorDistance(a, b) sqrt(VectorDistance(a,b))
+#define VectorDistance(a, b) (sqrt(VectorDistance2(a,b)))
 #define VectorLength(a) sqrt(DotProduct(a, a))
 
 
index ec31bec..172ae41 100644 (file)
@@ -130,6 +130,7 @@ typedef struct msurface_s
        int                     dlightbits[8];
 
        int                     lightframe; // avoid redundent addition of dlights
+       int                     worldnodeframe; // only render each surface once
 
        int                     lightmaptexturenum;
        byte            styles[MAXLIGHTMAPS];
index f816537..0bb47d9 100644 (file)
@@ -235,8 +235,8 @@ void ED_Free (edict_t *ed)
        ed->v.colormap = 0;
        ed->v.skin = 0;
        ed->v.frame = 0;
-       VectorCopy (vec3_origin, ed->v.origin);
-       VectorCopy (vec3_origin, ed->v.angles);
+       VectorClear(ed->v.origin);
+       VectorClear(ed->v.angles);
        ed->v.nextthink = -1;
        ed->v.solid = 0;
        
index e49cc20..3aee507 100644 (file)
@@ -266,6 +266,7 @@ extern      cvar_t          developer;
 
 extern qboolean        host_initialized;               // true if into command execution
 extern double          host_frametime;
+extern double          host_realframetime;     // LordHavoc: the real frametime, before slowmo and clamping are applied (used for console scrolling)
 extern int                     host_framecount;        // incremented every frame, never reset
 extern double          realtime;                       // not bounded in any way, changed at
                                                                                // start of every frame, never reset
index 0398080..7f8627c 100644 (file)
--- a/r_part.c
+++ b/r_part.c
@@ -205,6 +205,7 @@ void r_part_shutdown()
 R_InitParticles
 ===============
 */
+void R_ReadPointFile_f (void);
 void R_Particles_Init (void)
 {
        int             i;
@@ -222,6 +223,8 @@ void R_Particles_Init (void)
                r_numparticles = MAX_PARTICLES;
        }
 
+       Cmd_AddCommand ("pointfile", R_ReadPointFile_f);        
+
        Cvar_RegisterVariable (&r_particles);
        Cvar_RegisterVariable (&r_dynamicparticles);
 
@@ -887,7 +890,7 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
                                p->texnum = smokeparticletexture[rand()&7];
                                p->scale = lhrandom(4, 6);
                                p->alpha = type == 4 ? 192 : 255;
-                               p->color = 251; //(rand()&3)+68;
+                               p->color = 247; //(rand()&3)+68;
                                p->type = pt_bloodcloud;
                                p->die = cl.time + 9999;
                                for (j=0 ; j<3 ; j++)
@@ -967,84 +970,37 @@ R_DrawParticles
 ===============
 */
 extern cvar_t  sv_gravity;
-void R_CompleteLightPoint (vec3_t color, vec3_t p);
 
 void TraceLine (vec3_t start, vec3_t end, vec3_t impact);
 
-void R_DrawParticles (void)
+void R_MoveParticles (void)
 {
        particle_t              *p;
-       int                             i, r,g,b,a;
-       float                   gravity, dvel, frametime, scale, scale2, minparticledist;
-       byte                    *color24;
-       vec3_t                  up, right, uprightangles, forward2, up2, right2, tempcolor, v;
-       int                             activeparticles, maxparticle, j, k;
+       int                             i, activeparticles, maxparticle, j, a;
+       vec3_t                  v;
+       float                   gravity, dvel, frametime;
 
        // LordHavoc: early out condition
        if (!numparticles)
                return;
 
-       VectorScale (vup, 1.5, up);
-       VectorScale (vright, 1.5, right);
-
-       uprightangles[0] = 0;
-       uprightangles[1] = r_refdef.viewangles[1];
-       uprightangles[2] = 0;
-       AngleVectors (uprightangles, forward2, right2, up2);
-
        frametime = cl.time - cl.oldtime;
        gravity = frametime * sv_gravity.value;
        dvel = 1+4*frametime;
 
-       minparticledist = DotProduct(r_refdef.vieworg, vpn) + 16.0f;
-
        activeparticles = 0;
        maxparticle = -1;
        j = 0;
-       for (k = 0, p = particles;k < numparticles;k++, p++)
+       for (i = 0, p = particles;i < numparticles;i++, p++)
        {
                if (p->die < cl.time)
                {
                        freeparticles[j++] = p;
                        continue;
                }
-               maxparticle = k;
+               maxparticle = i;
                activeparticles++;
 
-               // LordHavoc: only render if not too close
-               if (DotProduct(p->org, vpn) >= minparticledist)
-               {
-                       color24 = (byte *) &d_8to24table[(int)p->color];
-                       r = color24[0];
-                       g = color24[1];
-                       b = color24[2];
-                       a = p->alpha;
-                       if (r_dynamicparticles.value)
-                       {
-                               R_CompleteLightPoint(tempcolor, p->org);
-                               r = (r * (int) tempcolor[0]) >> 7;
-                               g = (g * (int) tempcolor[1]) >> 7;
-                               b = (b * (int) tempcolor[2]) >> 7;
-                       }
-                       transpolybegin(p->texnum, 0, p->texnum, TPOLYTYPE_ALPHA);
-                       scale = p->scale * -0.5;scale2 = p->scale * 0.5;
-                       if (p->texnum == rainparticletexture) // rain streak
-                       {
-                               transpolyvert(p->org[0] + up2[0]*scale  + right2[0]*scale , p->org[1] + up2[1]*scale  + right2[1]*scale , p->org[2] + up2[2]*scale  + right2[2]*scale , 0,1,r,g,b,a);
-                               transpolyvert(p->org[0] + up2[0]*scale2 + right2[0]*scale , p->org[1] + up2[1]*scale2 + right2[1]*scale , p->org[2] + up2[2]*scale2 + right2[2]*scale , 0,0,r,g,b,a);
-                               transpolyvert(p->org[0] + up2[0]*scale2 + right2[0]*scale2, p->org[1] + up2[1]*scale2 + right2[1]*scale2, p->org[2] + up2[2]*scale2 + right2[2]*scale2, 1,0,r,g,b,a);
-                               transpolyvert(p->org[0] + up2[0]*scale  + right2[0]*scale2, p->org[1] + up2[1]*scale  + right2[1]*scale2, p->org[2] + up2[2]*scale  + right2[2]*scale2, 1,1,r,g,b,a);
-                       }
-                       else
-                       {
-                               transpolyvert(p->org[0] + up[0]*scale  + right[0]*scale , p->org[1] + up[1]*scale  + right[1]*scale , p->org[2] + up[2]*scale  + right[2]*scale , 0,1,r,g,b,a);
-                               transpolyvert(p->org[0] + up[0]*scale2 + right[0]*scale , p->org[1] + up[1]*scale2 + right[1]*scale , p->org[2] + up[2]*scale2 + right[2]*scale , 0,0,r,g,b,a);
-                               transpolyvert(p->org[0] + up[0]*scale2 + right[0]*scale2, p->org[1] + up[1]*scale2 + right[1]*scale2, p->org[2] + up[2]*scale2 + right[2]*scale2, 1,0,r,g,b,a);
-                               transpolyvert(p->org[0] + up[0]*scale  + right[0]*scale2, p->org[1] + up[1]*scale  + right[1]*scale2, p->org[2] + up[2]*scale  + right[2]*scale2, 1,1,r,g,b,a);
-                       }
-                       transpolyend();
-               }
-
                VectorCopy(p->org, p->oldorg);
                p->org[0] += p->vel[0]*frametime;
                p->org[1] += p->vel[1]*frametime;
@@ -1055,14 +1011,12 @@ void R_DrawParticles (void)
                case pt_static:
                        break;
 
+                       // LordHavoc: drop-through because of shared code
                case pt_blob:
-                       for (i=0 ; i<3 ; i++)
-                               p->vel[i] *= dvel;
-                       break;
-
+                       p->vel[2] *= dvel;
                case pt_blob2:
-                       for (i=0 ; i<2 ; i++)
-                               p->vel[i] *= dvel;
+                       p->vel[0] *= dvel;
+                       p->vel[1] *= dvel;
                        break;
 
                case pt_grav:
@@ -1085,19 +1039,13 @@ void R_DrawParticles (void)
 //                     }
                        p->scale += frametime * 16;
                        p->alpha -= frametime * 512;
-                       if (p->alpha < 1 || p->scale < 1)
-                               p->die = -1;
                        break;
                case pt_fallfadespark:
                        p->alpha -= frametime * 256;
                        p->vel[2] -= gravity;
-                       if (p->alpha < 1)
-                               p->die = -1;
                        break;
                case pt_fade:
                        p->alpha -= frametime * 512;
-                       if (p->alpha < 1)
-                               p->die = -1;
                        break;
                case pt_bubble:
                        a = Mod_PointInLeaf(p->org, cl.worldmodel)->contents;
@@ -1123,27 +1071,19 @@ void R_DrawParticles (void)
                                p->vel[2] += lhrandom(-32,32);
                        }
                        p->alpha -= frametime * 64;
-                       if (p->alpha < 1)
-                               p->die = -1;
                        break;
 // LordHavoc: for smoke trails
                case pt_smoke:
                        p->scale += frametime * 16;
-                       p->alpha -= frametime * 384;
-                       if (p->alpha < 16)
-                               p->die = -1;
+                       p->alpha -= frametime * 256;
                        break;
                case pt_smokecloud:
                        p->scale += frametime * 64;
-                       p->alpha -= frametime * 384;
-                       if (p->alpha < 16)
-                               p->die = -1;
+                       p->alpha -= frametime * 256;
                        break;
                case pt_splash:
                        p->scale += frametime * 24;
                        p->alpha -= frametime * 512;
-                       if (p->alpha < 1)
-                               p->die = -1;
                        break;
                case pt_rain:
                        a = Mod_PointInLeaf(p->org, cl.worldmodel)->contents;
@@ -1185,6 +1125,14 @@ void R_DrawParticles (void)
                        }
                        break;
                }
+
+               // LordHavoc: most particles did this check anyway, consistency...
+               if (p->alpha < 1)
+                       p->die = -1;
+
+               // LordHavoc: immediate removal of unnecessary particles (must be done to ensure compactor below operates properly in all cases)
+               if (p->die < cl.time)
+                       freeparticles[j++] = p;
        }
        // fill in gaps to compact the array
        i = 0;
@@ -1197,3 +1145,70 @@ void R_DrawParticles (void)
        numparticles = activeparticles;
 }
 
+void R_CompleteLightPoint (vec3_t color, vec3_t p);
+
+void R_DrawParticles (void)
+{
+       particle_t              *p;
+       int                             i, r,g,b,a;
+       float                   scale, scale2, minparticledist;
+       byte                    *color24;
+       vec3_t                  up, right, uprightangles, forward2, up2, right2, tempcolor;
+
+       // LordHavoc: early out condition
+       if (!numparticles)
+               return;
+
+       c_particles += numparticles;
+
+       VectorScale (vup, 1.5, up);
+       VectorScale (vright, 1.5, right);
+
+       uprightangles[0] = 0;
+       uprightangles[1] = r_refdef.viewangles[1];
+       uprightangles[2] = 0;
+       AngleVectors (uprightangles, forward2, right2, up2);
+
+       minparticledist = DotProduct(r_refdef.vieworg, vpn) + 16.0f;
+
+       for (i = 0, p = particles;i < numparticles;i++, p++)
+       {
+               // LordHavoc: unnecessary (array was already compacted)
+//             if (p->die < cl.time)
+//                     continue;
+
+               // LordHavoc: only render if not too close
+               if (DotProduct(p->org, vpn) < minparticledist)
+                       continue;
+
+               color24 = (byte *) &d_8to24table[(int)p->color];
+               r = color24[0];
+               g = color24[1];
+               b = color24[2];
+               a = p->alpha;
+               if (r_dynamicparticles.value)
+               {
+                       R_CompleteLightPoint(tempcolor, p->org);
+                       r = (r * (int) tempcolor[0]) >> 7;
+                       g = (g * (int) tempcolor[1]) >> 7;
+                       b = (b * (int) tempcolor[2]) >> 7;
+               }
+               transpolybegin(p->texnum, 0, p->texnum, TPOLYTYPE_ALPHA);
+               scale = p->scale * -0.5;scale2 = p->scale * 0.5;
+               if (p->texnum == rainparticletexture) // rain streak
+               {
+                       transpolyvert(p->org[0] + up2[0]*scale  + right2[0]*scale , p->org[1] + up2[1]*scale  + right2[1]*scale , p->org[2] + up2[2]*scale  + right2[2]*scale , 0,1,r,g,b,a);
+                       transpolyvert(p->org[0] + up2[0]*scale2 + right2[0]*scale , p->org[1] + up2[1]*scale2 + right2[1]*scale , p->org[2] + up2[2]*scale2 + right2[2]*scale , 0,0,r,g,b,a);
+                       transpolyvert(p->org[0] + up2[0]*scale2 + right2[0]*scale2, p->org[1] + up2[1]*scale2 + right2[1]*scale2, p->org[2] + up2[2]*scale2 + right2[2]*scale2, 1,0,r,g,b,a);
+                       transpolyvert(p->org[0] + up2[0]*scale  + right2[0]*scale2, p->org[1] + up2[1]*scale  + right2[1]*scale2, p->org[2] + up2[2]*scale  + right2[2]*scale2, 1,1,r,g,b,a);
+               }
+               else
+               {
+                       transpolyvert(p->org[0] + up[0]*scale  + right[0]*scale , p->org[1] + up[1]*scale  + right[1]*scale , p->org[2] + up[2]*scale  + right[2]*scale , 0,1,r,g,b,a);
+                       transpolyvert(p->org[0] + up[0]*scale2 + right[0]*scale , p->org[1] + up[1]*scale2 + right[1]*scale , p->org[2] + up[2]*scale2 + right[2]*scale , 0,0,r,g,b,a);
+                       transpolyvert(p->org[0] + up[0]*scale2 + right[0]*scale2, p->org[1] + up[1]*scale2 + right[1]*scale2, p->org[2] + up[2]*scale2 + right[2]*scale2, 1,0,r,g,b,a);
+                       transpolyvert(p->org[0] + up[0]*scale  + right[0]*scale2, p->org[1] + up[1]*scale  + right[1]*scale2, p->org[2] + up[2]*scale  + right[2]*scale2, 1,1,r,g,b,a);
+               }
+               transpolyend();
+       }
+}
index 512dad1..ef05490 100644 (file)
@@ -100,6 +100,9 @@ void R_DrawSpriteModel (entity_t *e)
 
        // don't even bother culling, because it's just a single
        // polygon without a surface cache
+
+       c_sprites++;
+       
        R_GetSpriteFrame (e, &oldframe, &newframe, &lerp);
        if (lerp < 0) lerp = 0;
        if (lerp > 1) lerp = 1;
index 5bc09af..c713eb4 100644 (file)
--- a/render.h
+++ b/render.h
@@ -157,6 +157,10 @@ extern void R_LavaSplash (vec3_t org);
 extern void R_TeleportSplash (vec3_t org);
 
 extern void R_PushDlights (void);
+extern void R_DrawWorld (void);
+//extern void R_RenderDlights (void);
+extern void R_DrawParticles (void);
+extern void R_MoveParticles (void);
 
 extern void R_DynamicLightPoint(vec3_t color, vec3_t org, int *dlightbits);
 extern void R_DynamicLightPointNoMask(vec3_t color, vec3_t org);
index 27ed2e5..8bf174b 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -46,6 +46,7 @@ void SV_Init (void)
        extern  cvar_t  sv_accelerate;
        extern  cvar_t  sv_idealpitchscale;
        extern  cvar_t  sv_aim;
+       extern  cvar_t  sv_predict;
 
        Cvar_RegisterVariable (&sv_maxvelocity);
        Cvar_RegisterVariable (&sv_gravity);
@@ -57,6 +58,7 @@ void SV_Init (void)
        Cvar_RegisterVariable (&sv_idealpitchscale);
        Cvar_RegisterVariable (&sv_aim);
        Cvar_RegisterVariable (&sv_nostep);
+       Cvar_RegisterVariable (&sv_predict);
 
        for (i=0 ; i<MAX_MODELS ; i++)
                sprintf (localmodels[i], "*%i", i);
@@ -598,7 +600,7 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                        angles[0] = angles[0] * movelerp + ent->stepoldangles[0];
                        angles[1] = angles[1] * movelerp + ent->stepoldangles[1];
                        angles[2] = angles[2] * movelerp + ent->stepoldangles[2];
-                       VectorMA(origin, host_client->ping, ent->v.velocity, origin);
+                       VectorMA(origin, host_client->latency, ent->v.velocity, origin);
                }
                else // copy as they are
                {
@@ -1015,8 +1017,7 @@ void SV_SendClientMessages (void)
                                SV_DropClient (false);  // went to another level
                        else
                        {
-                               if (NET_SendMessage (host_client->netconnection
-                               , &host_client->message) == -1)
+                               if (NET_SendMessage (host_client->netconnection, &host_client->message) == -1)
                                        SV_DropClient (true);   // if the message couldn't send, kick off
                                SZ_Clear (&host_client->message);
                                host_client->last_message = realtime;
index 06e1f40..48af07c 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -270,7 +270,7 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
 
                if (trace.allsolid)
                {       // entity is trapped in another solid
-                       VectorCopy (vec3_origin, ent->v.velocity);
+                       VectorClear(ent->v.velocity);
                        return 3;
                }
 
@@ -316,7 +316,7 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
        // cliped to another plane
                if (numplanes >= MAX_CLIP_PLANES)
                {       // this shouldn't really happen
-                       VectorCopy (vec3_origin, ent->v.velocity);
+                       VectorClear(ent->v.velocity);
                        return 3;
                }
 
@@ -348,7 +348,7 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
                        if (numplanes != 2)
                        {
 //                             Con_Printf ("clip velocity, numplanes == %i\n",numplanes);
-                               VectorCopy (vec3_origin, ent->v.velocity);
+                               VectorClear(ent->v.velocity);
                                return 7;
                        }
                        CrossProduct (planes[0], planes[1], dir);
@@ -362,7 +362,7 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
 //
                if (DotProduct (ent->v.velocity, primal_velocity) <= 0)
                {
-                       VectorCopy (vec3_origin, ent->v.velocity);
+                       VectorClear(ent->v.velocity);
                        return blocked;
                }
        }
@@ -625,7 +625,7 @@ void SV_PushRotate (edict_t *pusher, float movetime)
        for (i=0 ; i<3 ; i++)
                amove[i] = pusher->v.avelocity[i] * movetime;
 
-       VectorSubtract (vec3_origin, amove, a);
+       VectorNegate (amove, a);
        AngleVectors (a, forward, right, up);
 
        VectorCopy (pusher->v.origin, pushorigin);
@@ -923,7 +923,7 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel)
        trace_t steptrace;
        
        VectorCopy (ent->v.origin, oldorg);
-       VectorCopy (vec3_origin, dir);
+       VectorClear (dir);
 
        for (i=0 ; i<8 ; i++)
        {
@@ -959,7 +959,7 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel)
                VectorCopy (oldorg, ent->v.origin);
        }
        
-       VectorCopy (vec3_origin, ent->v.velocity);
+       VectorClear (ent->v.velocity);
        return 7;               // still not moving
 }
 
@@ -1014,8 +1014,8 @@ void SV_WalkMove (edict_t *ent)
 //
        VectorCopy (oldorg, ent->v.origin);     // back to start pos
 
-       VectorCopy (vec3_origin, upmove);
-       VectorCopy (vec3_origin, downmove);
+       VectorClear (upmove);
+       VectorClear (downmove);
        upmove[2] = STEPSIZE;
        downmove[2] = -STEPSIZE + oldvel[2]*host_frametime;
 
@@ -1116,12 +1116,14 @@ void SV_Physics_Client (edict_t *ent, int num)
        case MOVETYPE_FLY:
                if (!SV_RunThink (ent))
                        return;
+               SV_CheckWater (ent);
                SV_FlyMove (ent, host_frametime, NULL);
                break;
                
        case MOVETYPE_NOCLIP:
                if (!SV_RunThink (ent))
                        return;
+               SV_CheckWater (ent);
                VectorMA (ent->v.origin, host_frametime, ent->v.velocity, ent->v.origin);
                break;
                
@@ -1314,8 +1316,8 @@ void SV_Physics_Toss (edict_t *ent)
                {
                        ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
                        ent->v.groundentity = EDICT_TO_PROG(trace.ent);
-                       VectorCopy (vec3_origin, ent->v.velocity);
-                       VectorCopy (vec3_origin, ent->v.avelocity);
+                       VectorClear (ent->v.velocity);
+                       VectorClear (ent->v.avelocity);
                }
        }
        
index 12ef615..8ddff99 100644 (file)
--- a/sv_user.c
+++ b/sv_user.c
@@ -25,6 +25,7 @@ edict_t       *sv_player;
 
 extern cvar_t  sv_friction;
 cvar_t sv_edgefriction = {"edgefriction", "2"};
+cvar_t sv_predict = {"sv_predict", "1"};
 extern cvar_t  sv_stopspeed;
 
 static vec3_t          forward, right, up;
@@ -459,8 +460,9 @@ void SV_ReadClientMove (usercmd_t *move)
        for (i=0, total = 0;i < NUM_PING_TIMES;i++)
                total += host_client->ping_times[i];
        host_client->ping = total / NUM_PING_TIMES; // can be used for prediction
-       if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) ) // if paused for any reason, don't predict
-               host_client->latency = host_client->ping + sv_frametime; // push ahead by ticrate
+       host_client->latency = 0;
+       if (sv_predict.value && (svs.maxclients > 1) && (!sv.paused)) // if paused or a local game, don't predict
+               host_client->latency = host_client->ping;
        if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_ping)))
                val->_float = host_client->ping * 1000.0;
 
diff --git a/world.c b/world.c
index a37612b..ec9942e 100644 (file)
--- a/world.c
+++ b/world.c
@@ -692,11 +692,7 @@ loc0:
        }
        else
        {
-               // LordHavoc: unrolled vector operation because the compiler can't be sure vec3_origin is 0
-//             VectorSubtract (vec3_origin, plane->normal, trace->plane.normal);
-               trace->plane.normal[0] = -plane->normal[0];
-               trace->plane.normal[1] = -plane->normal[1];
-               trace->plane.normal[2] = -plane->normal[2];
+               VectorNegate (plane->normal, trace->plane.normal);
                trace->plane.dist = -plane->dist;
        }
 
@@ -824,11 +820,7 @@ loc0:
        }
        else
        {
-               // LordHavoc: vec3_origin is evil; the compiler can not rely on it being '0 0 0'
-//             VectorSubtract (vec3_origin, plane->normal, trace->plane.normal);
-               trace->plane.normal[0] = -plane->normal[0];
-               trace->plane.normal[1] = -plane->normal[1];
-               trace->plane.normal[2] = -plane->normal[2];
+               VectorNegate (plane->normal, trace->plane.normal);
                trace->plane.dist = -plane->dist;
        }
 
@@ -974,7 +966,7 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max
 
                if (trace.fraction != 1)
                {
-                       VectorSubtract (vec3_origin, ent->v.angles, a);
+                       VectorNegate (ent->v.angles, a);
                        AngleVectors (a, forward, right, up);
 
                        VectorCopy (trace.endpos, temp);