]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
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 7732166305250383155271fe8f6840b50d44edad..56d77abbe72e3c21d2553d2e98b88ce5de1d6a50 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 87adbe99d39548dc95b0f0302d9abff63f23bc0f..8b2d2823db8d942dd8858513a582ba919356940e 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 4252170e3119cc3a8d978a462ae773cd51d6604f..2631e3520ce319611708a14f5ebf91bb0605b24e 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 1a85e7c6e5565abfdc1d7d2dc33a0bf182d5a782..224899f84f046821315e3ffe32728f34aea035ed 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 1575fc0306f8581006b7c661dbcb5e869b1b3bc6..907822e19cbc1295a82a4bacd4eb131960d25e88 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 0d9df6360433dee87c11d2243b68f1e280bbe975..2a07083b6fdd72fc7be58420d190345b35491137 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 70afc0949a9a310c7942d59f2f98103d72c6b789..6ab30c4de943d417877350be801a8829a0a82413 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 ab123c0c80ef2dce67b8efd0c846c6eaa5022c8f..0e593950b467a474dcdc4ab275f31dabb3c0f0cf 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 296da1860d0a5fedd04f27543cb2ebde77730cf6..8f35afba4df63e3d9f474ebd6483537d2fca09ac 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 c7830ee882ee5770c92753f9448c878ded2da20f..89dc8c25659a3067f9f5cc7e4f13deb523d796f0 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 8ca544a437d354c33660c6ed7a17f2d6a3a7cb2b..25240ec386594ed5afa6ac18ce2d68fc79cbc7d1 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 42c76ea8559428b598850f7ed47961aff9348700..3b669e90838d348fd991e06ee0fb933683cc1b8d 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 ec31becdfda2d75e5ee1400cf58b1a159fad3b25..172ae413a927bad33be27b3a85d716d244023a84 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 f816537dd3660462c450aab3907a3655ff8baf34..0bb47d99be013566ef4ce6c0a703018d55ec1bd2 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 e49cc2048c04c7ec6dc0e7408023a953f1fe6d0c..3aee507574eff07f720c5d0faef432655bfc54c3 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 03980806f05b15e5b94c259b082f4c19099b49d7..7f8627c96238dfd0223ef1b544f72366d0340d2e 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 512dad12d7376e0154e43d5779bfaa899a9e3e47..ef0549015ea915c85d880a5b464c51271ab98685 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 5bc09aff444cb554811a8031f77d2cdb2dce8169..c713eb4041b07dcf725427c83dcdb23a6b77ed72 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 27ed2e5bc319d12fa6a1eaa52b5d6317d7f88c79..8bf174b641a8ad049a4c5731fe0dce1ffc44c7a8 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 06e1f40ee68b52382bcce35cb07bc97847acee2c..48af07c47b113b5b4093a4fc6078a38e60d077e3 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 12ef6157b964a51d775e7a9beab341299d52f2f8..8ddff9948e7a980a1d89973871eb62bd6f3a8c26 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 a37612bf146b35f387955b2e87db89833e1c8fc4..ec9942e4d5f23d0b15877a4ee89f6abca378178e 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);