Gigantic commit - dlight system rewritten
authorlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 15 Oct 2000 15:45:12 +0000 (15:45 +0000)
committerlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 15 Oct 2000 15:45:12 +0000 (15:45 +0000)
added serverside prediction
removed dark light support
removed explosion sparks
removed blastparticles code
particle effects changed
added build numbering
removed SetPal
removed remnants of surface cache code
fixed SZ_Clear in Host_Spawn_f
forgot what else...

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

36 files changed:
buildnum/buildnum.c [new file with mode: 0644]
buildnumber.c [new file with mode: 0644]
chase.c
cl_main.c
cl_parse.c
cl_tent.c
common.c
common.h
console.c
cpu_x86.nasm
cpu_x86.obj
gl_draw.c
gl_poly.c
gl_poly.h
gl_rmain.c
gl_rmisc.c
gl_rsurf.c
gl_screen.c
glquake.h
host.c
mathlib.h
model_brush.h
net_dgrm.c
protocol.h
quakedef.h
r_light.c
r_part.c
render.h
sbar.c
server.h
sv_main.c
sv_user.c
sys_win.c
vid_wgl.c
view.c
world.c

diff --git a/buildnum/buildnum.c b/buildnum/buildnum.c
new file mode 100644 (file)
index 0000000..1fb390b
--- /dev/null
@@ -0,0 +1,99 @@
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+// LordHavoc: wait for a key press so the window doesn't disappear immediately
+#if _DEBUG && WIN32
+#define ERROR fprintf(stderr, "press any key\n");getchar();return -1;
+#else
+#define ERROR return -1;
+#endif
+
+// version template:
+#define BUILDNUMBER 1
+
+int main(int argc, char **argv)
+{
+       FILE *file;
+       unsigned int insize, outsize, sizedifference, inbuildsize, outbuildsize, writtensize;
+       unsigned char *data, *in, *out, *buildstring, *endofbuildstring, outbuildstring[32];
+       int inbuildnumber, outbuildnumber, remainder;
+       if (argc != 2)
+       {
+               fprintf(stderr, "usage: buildnum <filename.c or .h>\npurpose: increments build number in version string for darkplaces engine");
+               ERROR
+       }
+
+       file = fopen(argv[1], "rb");
+       if (!file)
+       {
+               fprintf(stderr, "buildnum: unable to open file \"%s\" for reading\n", argv[1]);
+               ERROR
+       }
+
+       fseek(file, 0, SEEK_END);
+       insize = ftell(file);
+       data = calloc(1, insize+20);
+       fseek(file, 0, SEEK_SET);
+       if (fread(data, 1, insize, file) < insize)
+       {
+               fprintf(stderr, "buildnum: unable to read file \"%s\"\n", argv[1]);
+               ERROR
+       }
+       fclose(file);
+       buildstring = strstr(data, "#define BUILDNUMBER ");
+       if (!buildstring)
+       {
+               fprintf(stderr, "buildnum: unable to find \"#define BUILDNUMBER \"\n");
+               ERROR
+       }
+       buildstring += strlen("#define BUILDNUMBER ");
+       endofbuildstring = buildstring;
+       while (*endofbuildstring && *endofbuildstring != '\r' && *endofbuildstring != '\n')
+               endofbuildstring++;
+       inbuildnumber = atoi(buildstring);
+       outbuildnumber = inbuildnumber + 1;
+       printf("incrementing build number %d to %d\n", inbuildnumber, outbuildnumber);
+       sprintf(outbuildstring, "%d", outbuildnumber);
+       inbuildsize = endofbuildstring - buildstring;
+       outbuildsize = strlen(outbuildstring);
+       sizedifference = outbuildsize-inbuildsize;
+       remainder = (data + insize) - buildstring;
+       outsize = insize + sizedifference;
+       memmove(buildstring + sizedifference, buildstring, remainder);
+       in = outbuildstring;
+       out = buildstring;
+       while (*in)
+               *out++ = *in++;
+
+       file = fopen(argv[1], "wb");
+       if (!file)
+       {
+               fprintf(stderr, "buildnum: unable to open file \"%s\" for writing\n", argv[1]);
+               ERROR
+       }
+
+       writtensize = fwrite(data, 1, outsize, file);
+       fclose(file);
+       if (writtensize < outsize)
+       {
+               fprintf(stderr, "buildnum: error writing file \"%s\", emergency code trying to save to buildnum.dmp\n", argv[1]);
+               file = fopen("buildnum.dmp", "wb");
+               if (!file)
+               {
+                       fprintf(stderr, "buildnum: unable to open file for writing\n");
+                       ERROR
+               }
+
+               writtensize = fwrite(data, 1, outsize, file);
+               fclose(file);
+               if (writtensize < outsize)
+               {
+                       fprintf(stderr, "buildnum: error writing emergency dump file!\n");
+                       ERROR
+               }
+       }
+
+       return 0;
+}
\ No newline at end of file
diff --git a/buildnumber.c b/buildnumber.c
new file mode 100644 (file)
index 0000000..dc105a7
--- /dev/null
@@ -0,0 +1,4 @@
+
+#define BUILDNUMBER 68
+
+int buildnumber = BUILDNUMBER;
diff --git a/chase.c b/chase.c
index f89a5d6..f42e762 100644 (file)
--- a/chase.c
+++ b/chase.c
@@ -38,19 +38,16 @@ void Chase_Reset (void)
 //     start position 12 units behind head
 }
 
-qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t *trace);
+extern qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t *trace);
 
 void TraceLine (vec3_t start, vec3_t end, vec3_t impact)
 {
-       /*
        trace_t trace;
 
        memset (&trace, 0, sizeof(trace));
        SV_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &trace);
 
        VectorCopy (trace.endpos, impact);
-       */
-       VectorCopy (end, impact);
 }
 
 void Chase_Update (void)
index 6b2343e..34a0b42 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -286,49 +286,6 @@ void CL_PrintEntities_f (void)
 }
 
 
-/*
-===============
-SetPal
-
-Debugging tool, just flashes the screen
-===============
-*/
-void SetPal (int i)
-{
-#if 0
-       static int old;
-       byte    pal[768];
-       int             c;
-       
-       if (i == old)
-               return;
-       old = i;
-
-       if (i==0)
-               VID_SetPalette (host_basepal);
-       else if (i==1)
-       {
-               for (c=0 ; c<768 ; c+=3)
-               {
-                       pal[c] = 0;
-                       pal[c+1] = 255;
-                       pal[c+2] = 0;
-               }
-               VID_SetPalette (pal);
-       }
-       else
-       {
-               for (c=0 ; c<768 ; c+=3)
-               {
-                       pal[c] = 0;
-                       pal[c+1] = 0;
-                       pal[c+2] = 255;
-               }
-               VID_SetPalette (pal);
-       }
-#endif
-}
-
 /*
 ===============
 CL_AllocDlight
@@ -432,7 +389,6 @@ float       CL_LerpPoint (void)
        {
                if (frac < -0.01)
                {
-SetPal(1);
                        cl.time = cl.mtime[1];
 //                             Con_Printf ("low frac\n");
                }
@@ -442,14 +398,11 @@ SetPal(1);
        {
                if (frac > 1.01)
                {
-SetPal(2);
                        cl.time = cl.mtime[0];
 //                             Con_Printf ("high frac\n");
                }
                frac = 1;
        }
-       else
-               SetPal(0);
                
        return frac;
 }
@@ -649,21 +602,12 @@ void CL_RelinkEntities (void)
                {
                        dl = CL_AllocDlight (i);
                        VectorCopy (ent->origin, dl->origin);
-                       dl->dark = ent->glowsize < 0; // darklight
                        dl->radius = ent->glowsize;
-                       if (dl->dark)
-                       {
-                               if (ent->glowtrail) // LordHavoc: all darklights leave black trails
-                                       R_RocketTrail2 (oldorg, ent->origin, 0, ent);
-                               dl->radius = -ent->glowsize;
-                       }
-                       else if (ent->glowtrail) // LordHavoc: customizable glow and trail
-                               R_RocketTrail2 (oldorg, ent->origin, ent->glowcolor, ent);
                        dl->die = cl.time + 0.001;
                        tempcolor = (byte *)&d_8to24table[ent->glowcolor];
                        dl->color[0] = tempcolor[0]*(1.0/255.0);dl->color[1] = tempcolor[1]*(1.0/255.0);dl->color[2] = tempcolor[2]*(1.0/255.0);
                }
-               else if (ent->glowtrail) // LordHavoc: customizable glow and trail
+               if (ent->glowtrail) // LordHavoc: customizable glow and trail
                        R_RocketTrail2 (oldorg, ent->origin, ent->glowcolor, ent);
 
                ent->forcelink = false;
index e7b0cb7..75d53fe 100644 (file)
@@ -81,12 +81,14 @@ char *svc_strings[] =
        "?", // 48
        "?", // 49
        "svc_farclip", // [coord] size
-       "svc_fog" // [byte] enable <optional past this point, only included if enable is true> [short * 4096] density [byte] red [byte] green [byte] blue
+       "svc_fog", // [byte] enable <optional past this point, only included if enable is true> [short * 4096] density [byte] red [byte] green [byte] blue
+       "svc_playerposition" // [float] x [float] y [float] z
 };
 
 //=============================================================================
 
-int Nehahrademcompatibility; // LordHavoc: to allow playback of the early Nehahra movie segments
+qboolean Nehahrademcompatibility; // LordHavoc: to allow playback of the early Nehahra movie segments
+qboolean dpprotocol; // LordHavoc: whether or not the current network stream is the enhanced DarkPlaces protocol
 
 /*
 ===============
@@ -343,6 +345,7 @@ void CL_ParseServerInfo (void)
                Nehahrademcompatibility = true;
        if (cls.demoplayback && demo_nehahra.value)
                Nehahrademcompatibility = true;
+       dpprotocol = i == DPPROTOCOL_VERSION;
 
 // parse maxclients
        cl.maxclients = MSG_ReadByte ();
@@ -573,7 +576,7 @@ void CL_ParseUpdate (int bits)
        ent->deltabaseline.frame = ent->frame;
        ent->alpha = (float) alpha * (1.0 / 255.0);
        ent->scale = (float) scale * (1.0 / 16.0);
-       ent->glowsize = glowsize < 128 ? glowsize * 8.0 : (glowsize - 256) * 8.0;
+       ent->glowsize = glowsize * 4.0;
        ent->glowcolor = glowcolor;
        ent->colormod[0] = (float) ((colormod >> 5) & 7) * (1.0 / 7.0);
        ent->colormod[1] = (float) ((colormod >> 2) & 7) * (1.0 / 7.0);
index c633df6..95f6699 100644 (file)
--- a/cl_tent.c
+++ b/cl_tent.c
@@ -99,7 +99,7 @@ void CL_ParseBeam (model_t *m)
        Con_Printf ("beam list overflow!\n");   
 }
 
-void R_BlastParticles(vec3_t org, vec_t radius, vec_t power);
+//void R_BlastParticles(vec3_t org, vec_t radius, vec_t power);
 void R_BloodShower (vec3_t mins, vec3_t maxs, float velspeed, int count);
 void R_ParticleCube (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int colorbase, int gravity, int randomvel);
 void R_ParticleRain (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int colorbase, int type);
@@ -340,7 +340,7 @@ void CL_ParseTEnt (void)
                pos[1] = MSG_ReadCoord ();
                pos[2] = MSG_ReadCoord ();
                R_ParticleExplosion (pos, false);
-               R_BlastParticles (pos, 120, 120);
+//             R_BlastParticles (pos, 120, 120);
                dl = CL_AllocDlight (0);
                VectorCopy (pos, dl->origin);
                dl->radius = 350;
@@ -355,7 +355,7 @@ void CL_ParseTEnt (void)
                pos[1] = MSG_ReadCoord ();
                pos[2] = MSG_ReadCoord ();
                R_ParticleExplosion (pos, false);
-               R_BlastParticles (pos, 120, 480);
+//             R_BlastParticles (pos, 120, 480);
                dl = CL_AllocDlight (0);
                VectorCopy (pos, dl->origin);
                dl->radius = 600;
@@ -386,7 +386,7 @@ void CL_ParseTEnt (void)
                pos[1] = MSG_ReadCoord ();
                pos[2] = MSG_ReadCoord ();
                R_ParticleExplosion (pos, false);
-               R_BlastParticles (pos, 120, 120);
+//             R_BlastParticles (pos, 120, 120);
                dl = CL_AllocDlight (0);
                VectorCopy (pos, dl->origin);
                dl->radius = 350;
@@ -401,7 +401,7 @@ void CL_ParseTEnt (void)
                pos[1] = MSG_ReadCoord ();
                pos[2] = MSG_ReadCoord ();
                R_ParticleExplosion (pos, false);
-               R_BlastParticles (pos, 120, 120);
+//             R_BlastParticles (pos, 120, 120);
                dl = CL_AllocDlight (0);
                VectorCopy (pos, dl->origin);
                dl->radius = 350;
@@ -416,7 +416,7 @@ void CL_ParseTEnt (void)
                pos[1] = MSG_ReadCoord ();
                pos[2] = MSG_ReadCoord ();
                R_BlobExplosion (pos);
-               R_BlastParticles (pos, 120, 120);
+//             R_BlastParticles (pos, 120, 120);
 
                S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
                dl = CL_AllocDlight (0);
@@ -472,7 +472,7 @@ void CL_ParseTEnt (void)
                colorStart = MSG_ReadByte ();
                colorLength = MSG_ReadByte ();
                R_ParticleExplosion2 (pos, colorStart, colorLength);
-               R_BlastParticles (pos, 80, 80);
+//             R_BlastParticles (pos, 80, 80);
                dl = CL_AllocDlight (0);
                VectorCopy (pos, dl->origin);
                dl->radius = 350;
index 7a750b6..27fd8bf 100644 (file)
--- a/common.c
+++ b/common.c
@@ -583,9 +583,51 @@ void MSG_WriteString (sizebuf_t *sb, char *s)
                SZ_Write (sb, s, strlen(s)+1);
 }
 
+/*
+void MSG_WriteCoord (sizebuf_t *sb, float f)
+{
+       if (dpprotocol)
+       {
+               byte    *buf;
+               int c = (int)f;
+               buf = SZ_GetSpace (sb, 3);
+               buf[0] =  c        & 0xff;
+               buf[1] = (c >>  8) & 0xff;
+               buf[2] = (c >> 16) & 0xff;
+       }
+       else
+               MSG_WriteShort (sb, (int)(f*8));
+}
+*/
+
 void MSG_WriteCoord (sizebuf_t *sb, float f)
 {
-       MSG_WriteShort (sb, (int)(f*8));
+       if (dpprotocol)
+               MSG_WriteFloat(sb, f);
+       /*
+       {
+               int     i = (int) (f * 16.0f), j = 0, k, l;
+               // 1 sign bit, 5bit exponent, 10bit mantissa with implicit 1
+               if (i < 0)
+               {
+                       i = -i;
+                       j = 0x8000;
+               }
+
+               // LordHavoc: lets hope the compiler is good, if not it will still perform tolerably
+               for (k = 31,l = 0x80000000;!(i & l);k--,l >>= 1);
+               j |= k << 10 | ((i >> (k - 10)) & 0x3FF);
+               
+               MSG_WriteShort(sb, j);
+       }
+       */
+       else
+               MSG_WriteShort (sb, (int)(f*8));
+}
+
+void MSG_WritePreciseAngle (sizebuf_t *sb, float f)
+{
+       MSG_WriteShort (sb, (int) (f*65536.0f/360) & 65535);
 }
 
 void MSG_WriteAngle (sizebuf_t *sb, float f)
@@ -722,6 +764,95 @@ char *MSG_ReadString (void)
        return string;
 }
 
+/*
+float MSG_ReadAbsoluteCoord (void)
+{
+       if (dpprotocol)
+       {
+               int     c;
+               
+               if (msg_readcount+3 > net_message.cursize)
+               {
+                       msg_badread = true;
+                       return 0;
+               }
+                       
+               c  = net_message.data[msg_readcount  ];
+               c |= net_message.data[msg_readcount+1] << 8;
+               c |= net_message.data[msg_readcount+2] << 16;
+               if (c & 0x800000)
+                       c |= ~0xFFFFFF; // sign extend
+               
+               msg_readcount += 3;
+               
+               return (float) c * (1.0f / 16.0f);
+       }
+       else
+       {
+               int     c;
+               
+               if (msg_readcount+2 > net_message.cursize)
+               {
+                       msg_badread = true;
+                       return 0;
+               }
+                       
+               c  = (short) (net_message.data[msg_readcount  ] |= net_message.data[msg_readcount+1] << 8);
+               
+               msg_readcount += 2;
+               
+               return (float) c * (1.0f / 8.0f);
+//             return MSG_ReadShort() * (1.0f/8.0f);
+       }
+}
+*/
+
+float MSG_ReadCoord (void)
+{
+       if (dpprotocol)
+               return MSG_ReadFloat();
+       /*
+       {
+               int     c, i;
+               
+               if (msg_readcount+2 > net_message.cursize)
+               {
+                       msg_badread = true;
+                       return 0;
+               }
+                       
+               c  = net_message.data[msg_readcount  ] |= net_message.data[msg_readcount+1] << 8;
+               
+               msg_readcount += 2;
+
+               if (!c)
+                       return 0.0f;
+               // 1 sign bit, 5bit exponent, 10bit mantissa with implicit 1
+               i = ((c & 0x03FF) | (0x0400)) << (((c & 0x7C00) >> 10) - 10);
+               if (c & 0x8000)
+                       i = -i;
+               return i * (1.0f / 16.0f);
+       }
+       */
+       else
+       {
+               int     c;
+               
+               if (msg_readcount+2 > net_message.cursize)
+               {
+                       msg_badread = true;
+                       return 0;
+               }
+                       
+               c  = (short) (net_message.data[msg_readcount  ] | (net_message.data[msg_readcount+1] << 8));
+               
+               msg_readcount += 2;
+               
+               return ((float) c * (1.0f / 8.0f));
+//             return MSG_ReadShort() * (1.0f/8.0f);
+       }
+}
+
 /*
 float MSG_ReadCoord (void)
 {
@@ -734,6 +865,10 @@ float MSG_ReadAngle (void)
 }
 */
 
+float MSG_ReadPreciseAngle (void)
+{
+       return MSG_ReadShort() * (360.0f/65536);
+}
 
 
 //===========================================================================
index f062af0..8f17193 100644 (file)
--- a/common.h
+++ b/common.h
@@ -130,11 +130,12 @@ char *MSG_ReadString (void);
 //#define MSG_ReadShort() ((msg_readcount + 2) > net_message.cursize ? (msg_badread = true, -1) : (short)net_message.data[msg_readcount+=2, msg_readcount-2] | (net_message.data[msg_readcount-1] << 8))
 //#define MSG_ReadLong() ((msg_readcount + 4) > net_message.cursize ? (msg_badread = true, -1) : (int)net_message.data[msg_readcount+=4, msg_readcount-4] | (net_message.data[msg_readcount-3] << 8) | (net_message.data[msg_readcount-2] << 16) | (net_message.data[msg_readcount-1] << 24))
 
-//float MSG_ReadCoord (void);
+float MSG_ReadCoord (void);
 //float MSG_ReadAngle (void);
 
-#define MSG_ReadAngle() (MSG_ReadByte() * (360.0f / 256.0f))
-#define MSG_ReadCoord() (MSG_ReadShort() * 0.125f)
+#define MSG_ReadAngle() (dpprotocol ? MSG_ReadShort() * (360.0f / 65536.0f) : MSG_ReadByte() * (360.0f / 256.0f))
+
+extern qboolean dpprotocol;
 
 //============================================================================
 
index c3ce5a1..be48c8d 100644 (file)
--- a/console.c
+++ b/console.c
@@ -166,7 +166,7 @@ void Con_CheckResize (void)
 
        if (width < 1)                  // video hasn't been initialized yet
        {
-               width = 38;
+               width = 78; // LordHavoc: changed from 38 to 78 (320 -> 640 conversion)
                con_linewidth = width;
                con_totallines = CON_TEXTSIZE / con_linewidth;
                memset (con_text, ' ', CON_TEXTSIZE);
index aa68a74..4ab9875 100644 (file)
@@ -14,11 +14,11 @@ _Mod_PointInLeaf
 ;       mnode_t         *node;
 ;       node = model->nodes;
 
-        mov     esi, dword [eax+200]
+        mov     esi, dword [eax+200] ; model->nodes
 
 ;       if (node->contents < 0)
 
-        cmp     dword [esi], 0
+        cmp     dword [esi], 0 ; node->contents
         jge     .firstvalid
 
 ;               return (mleaf_t *)node;
@@ -34,29 +34,29 @@ _Mod_PointInLeaf
 
 ;       while (1)
 
-        mov     eax, dword [esi+36]
-        mov     cl, byte [eax+16]
+        xor     ecx, ecx
+        mov     eax, dword [esi+76] ; node->plane
+        mov     cl, byte [eax+16] ; node->plane->type
 
 ;       {
 ;               node = node->children[(node->plane->type < 3 ? p[node->plane->type] : DotProduct (p,node->plane->normal)) < node->plane->dist];
 
        cmp     cl, 3
         jb      .axisplane
-        fld     dword [eax+4]
-        fmul    dword [edx+4]
-        fld     dword [eax+8]
-        fmul    dword [edx+8]
-        fld     dword [eax]
-        fmul    dword [edx]
+        fld     dword [eax+4] ; node->plane->normal[1]
+        fmul    dword [edx+4] ; p[1]
+        fld     dword [eax+8] ; node->plane->normal[2]
+        fmul    dword [edx+8] ; p[2]
+        fld     dword [eax]   ; node->plane->normal[0]
+        fmul    dword [edx]   ; p[0]
         faddp   st1, st0
         faddp   st1, st0
-        fld     dword [eax+12]
+        fld     dword [eax+12] ; node->plane->dist
         fcompp
-       xor     ecx, ecx
        fnstsw  ax
        test    ah, 65                                  ; 00000041H
        sete    cl
-        mov     esi, dword [esi+ecx*4+40]
+        mov     esi, dword [esi+ecx*4+80] ; node = node->children[condition]
 
 ;               if (node->contents < 0)
 
@@ -76,16 +76,13 @@ _Mod_PointInLeaf
        add     esp, 4
        ret     0
 .axisplane:
-       xor     ebx, ebx
-       mov     bl, cl
-        fld     dword [edx+ebx*4]
+        fld     dword [edx+ecx*4]
         fld     dword [eax+12]
         fcompp
-       xor     ecx, ecx
-       fnstsw  ax
+        fnstsw  ax
        test    ah, 65                                  ; 00000041H
        sete    cl
-        mov     esi, dword [esi+ecx*4+40]
+        mov     esi, dword [esi+ecx*4+80] ; node = node->children[condition]
 
 ;               if (node->contents < 0)
 
index 5daa7b2..3c13863 100644 (file)
Binary files a/cpu_x86.obj and b/cpu_x86.obj differ
index 2e6772f..7777801 100644 (file)
--- a/gl_draw.c
+++ b/gl_draw.c
@@ -365,6 +365,7 @@ Draw_Init
 ===============
 */
 void rmain_registercvars();
+extern int buildnumber;
 void Draw_Init (void)
 {
        int             i;
@@ -412,15 +413,19 @@ void Draw_Init (void)
        // hack the version number directly into the pic
 #ifdef NEHAHRA
 #if defined(__linux__)
-       sprintf (ver, "DPNehahra Linux GL %.2f", (float) VERSION);
+       sprintf (ver, "DPNehahra Linux GL %.2f build %5i", (float) VERSION, buildnumber);
+#elif defined(WIN32)
+       sprintf (ver, "DPNehahra Windows GL %.2f build %5i", (float) VERSION, buildnumber);
 #else
-       sprintf (ver, "DPNehahra Windows GL %.2f", (float) VERSION);
+       sprintf (ver, "DPNehahra Unknown GL %.2f build %5i", (float) VERSION, buildnumber);
 #endif
 #else
 #if defined(__linux__)
-       sprintf (ver, "DarkPlaces Linux GL %.2f", (float)VERSION);
+       sprintf (ver, "DarkPlaces Linux GL %.2f build %5i", (float) VERSION, buildnumber);
+#elif defined(WIN32)
+       sprintf (ver, "DarkPlaces Windows GL %.2f build %5i", (float) VERSION, buildnumber);
 #else
-       sprintf (ver, "DarkPlaces Windows GL %.2f", (float)VERSION);
+       sprintf (ver, "DarkPlaces Unknown GL %.2f build %5i", (float) VERSION, buildnumber);
 #endif
 #endif
        dest = cb->data + 320*186 + 320 - 11 - 8*strlen(ver);
index 0905f0c..d312335 100644 (file)
--- a/gl_poly.c
+++ b/gl_poly.c
@@ -18,8 +18,25 @@ unsigned short currentskyvert;
 cvar_t gl_multitexture = {"gl_multitexture", "1"};
 cvar_t gl_vertexarrays = {"gl_vertexarrays", "1"};
 
+typedef struct translistitem_s
+{
+       transpoly_t *poly;
+       struct translistitem_s *next;
+}
+translistitem;
+
+translistitem translist[MAX_TRANSPOLYS];
+translistitem *currenttranslist;
+
+translistitem *translisthash[4096];
+
+float transviewdist; // distance of view origin along the view normal
+
+float transreciptable[256];
+
 void glpoly_init()
 {
+       int i;
        Cvar_RegisterVariable (&gl_multitexture);
        Cvar_RegisterVariable (&gl_vertexarrays);
        transvert = malloc(MAX_TRANSVERTS * sizeof(transvert_t));
@@ -29,11 +46,17 @@ void glpoly_init()
        wallpoly = malloc(MAX_WALLPOLYS * sizeof(wallpoly_t));
        skyvert = malloc(MAX_SKYVERTS * sizeof(skyvert_t));
        skypoly = malloc(MAX_SKYPOLYS * sizeof(skypoly_t));
+       transreciptable[0] = 0.0f;
+       for (i = 1;i < 256;i++)
+               transreciptable[i] = 1.0f / i;
 }
 
 void transpolyclear()
 {
        currenttranspoly = currenttransvert = 0;
+       currenttranslist = translist;
+       memset(translisthash, 0, sizeof(translisthash));
+       transviewdist = DotProduct(r_refdef.vieworg, vpn);
 }
 
 void transpolybegin(int texnum, int glowtexnum, int fogtexnum, int transpolytype)
@@ -72,15 +95,38 @@ void transpolyvert(float x, float y, float z, float s, float t, int r, int g, in
 
 void transpolyend()
 {
-       if (currenttranspoly >= MAX_TRANSPOLYS)
+       float center, d, maxdist;
+       int i;
+       transvert_t *v;
+       if (currenttranspoly >= MAX_TRANSPOLYS || currenttransvert >= MAX_TRANSVERTS)
                return;
        if (transpoly[currenttranspoly].verts < 3) // skip invalid polygons
        {
                currenttransvert = transpoly[currenttranspoly].firstvert; // reset vert pointer
                return;
        }
-       if (currenttransvert >= MAX_TRANSVERTS)
+       center = 0;
+       maxdist = -1000000000000000.0f; // eh, it's definitely behind it, so...
+       for (i = 0,v = &transvert[transpoly[currenttranspoly].firstvert];i < transpoly[currenttranspoly].verts;i++, v++)
+       {
+               d = DotProduct(v->v, vpn);
+               center += d;
+               if (d > maxdist)
+                       maxdist = d;
+       }
+       maxdist -= transviewdist;
+       if (maxdist < 4.0f) // behind view
+       {
+               currenttransvert = transpoly[currenttranspoly].firstvert; // reset vert pointer
                return;
+       }
+       center *= transreciptable[transpoly[currenttranspoly].verts];
+       center -= transviewdist;
+       i = bound(0, (int) center, 4095);
+       currenttranslist->next = translisthash[i];
+       currenttranslist->poly = transpoly + currenttranspoly;
+       translisthash[i] = currenttranslist;
+       currenttranslist++;
        currenttranspoly++;
 }
 
@@ -217,11 +263,14 @@ int transpolyqsort(const void *ia, const void *ib)
 }
 */
 
+/*
 int transpolyqsort(const void *ia, const void *ib)
 {
        return (transpoly[*((unsigned short *)ib)].distance - transpoly[*((unsigned short *)ia)].distance);
 }
+*/
 
+/*
 void transpolyrenderminmax()
 {
        int i, j, lastvert;
@@ -249,6 +298,7 @@ void transpolyrenderminmax()
        }
        qsort(&transpolyindex[0], transpolyindices, sizeof(unsigned short), transpolyqsort);
 }
+*/
 /*
        int i, j, a;
        a = true;
@@ -302,9 +352,9 @@ void transpolyrender()
        transpoly_t *p;
        if (currenttranspoly < 1)
                return;
-       transpolyrenderminmax();
-       if (transpolyindices < 1)
-               return;
+//     transpolyrenderminmax();
+//     if (transpolyindices < 1)
+//             return;
        // testing
 //     Con_DPrintf("transpolyrender: %i polys %i infront %i vertices\n", currenttranspoly, transpolyindices, currenttransvert);
 //     if (transpolyindices >= 2)
@@ -366,116 +416,122 @@ void transpolyrender()
        */
        {
                int points = -1;
+               translistitem *item;
                transvert_t *vert;
-               for (i = 0;i < transpolyindices;i++)
+               for (i = 4095;i >= 0;i--)
                {
-                       p = &transpoly[transpolyindex[i]];
-                       if (p->texnum != texnum || p->verts != points || p->transpolytype != tpolytype)
+                       item = translisthash[i];
+                       while (item)
                        {
-                               glEnd();
-                               if (isG200)
-                               {
-                                       if (p->fogtexnum) // alpha
-                                               glEnable(GL_ALPHA_TEST);
-                                       else
-                                               glDisable(GL_ALPHA_TEST);
-                               }
-                               if (p->texnum != texnum)
-                               {
-                                       texnum = p->texnum;
-                                       glBindTexture(GL_TEXTURE_2D, texnum);
-                               }
-                               if (p->transpolytype != tpolytype)
+                               p = item->poly;
+                               item = item->next;
+                               if (p->texnum != texnum || p->verts != points || p->transpolytype != tpolytype)
                                {
-                                       tpolytype = p->transpolytype;
-                                       if (tpolytype == TPOLYTYPE_ADD) // additive
-                                               glBlendFunc(GL_SRC_ALPHA, GL_ONE);
-                                       else // alpha
-                                               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-                               }
-                               points = p->verts;
-                               switch (points)
-                               {
-                               case 3:
-                                       glBegin(GL_TRIANGLES);
-                                       break;
-                               case 4:
-                                       glBegin(GL_QUADS);
-                                       break;
-                               default:
-                                       glBegin(GL_TRIANGLE_FAN);
-                                       points = -1; // to force a reinit on the next poly
-                                       break;
-                               }
-                       }
-                       for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
-                       {
-                               // would be 2fv, but windoze Matrox G200 and probably G400 drivers don't support that (dumb...)
-                               glTexCoord2f(vert->s, vert->t);
-                               // again, vector version isn't supported I think
-                               glColor4ub(vert->r, vert->g, vert->b, vert->a);
-                               glVertex3fv(vert->v);
-                       }
-                       if (p->glowtexnum)
-                       {
-                               glEnd();
-                               texnum = p->glowtexnum; // highly unlikely to match next poly, but...
-                               glBindTexture(GL_TEXTURE_2D, texnum);
-                               if (tpolytype != TPOLYTYPE_ADD)
-                               {
-                                       tpolytype = TPOLYTYPE_ADD; // might match next poly
-                                       glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+                                       glEnd();
+                                       if (isG200)
+                                       {
+                                               if (p->fogtexnum) // alpha
+                                                       glEnable(GL_ALPHA_TEST);
+                                               else
+                                                       glDisable(GL_ALPHA_TEST);
+                                       }
+                                       if (p->texnum != texnum)
+                                       {
+                                               texnum = p->texnum;
+                                               glBindTexture(GL_TEXTURE_2D, texnum);
+                                       }
+                                       if (p->transpolytype != tpolytype)
+                                       {
+                                               tpolytype = p->transpolytype;
+                                               if (tpolytype == TPOLYTYPE_ADD) // additive
+                                                       glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+                                               else // alpha
+                                                       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+                                       }
+                                       points = p->verts;
+                                       switch (points)
+                                       {
+                                       case 3:
+                                               glBegin(GL_TRIANGLES);
+                                               break;
+                                       case 4:
+                                               glBegin(GL_QUADS);
+                                               break;
+                                       default:
+                                               glBegin(GL_TRIANGLE_FAN);
+                                               points = -1; // to force a reinit on the next poly
+                                               break;
+                                       }
                                }
-                               points = -1;
-                               glBegin(GL_TRIANGLE_FAN);
                                for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
                                {
-                                       glColor4ub(255,255,255,vert->a);
                                        // would be 2fv, but windoze Matrox G200 and probably G400 drivers don't support that (dumb...)
                                        glTexCoord2f(vert->s, vert->t);
+                                       // again, vector version isn't supported I think
+                                       glColor4ub(vert->r, vert->g, vert->b, vert->a);
                                        glVertex3fv(vert->v);
                                }
-                               glEnd();
-                       }
-                       if (fogenabled && p->transpolytype == TPOLYTYPE_ALPHA)
-                       {
-                               vec3_t diff;
-                               glEnd();
-                               points = -1; // to force a reinit on the next poly
-                               if (tpolytype != TPOLYTYPE_ALPHA)
+                               if (p->glowtexnum)
                                {
-                                       tpolytype = TPOLYTYPE_ALPHA; // probably matchs next poly
-                                       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-                               }
-                               if (p->fogtexnum)
-                               {
-                                       if (texnum != p->fogtexnum) // highly unlikely to match next poly, but...
+                                       glEnd();
+                                       texnum = p->glowtexnum; // highly unlikely to match next poly, but...
+                                       glBindTexture(GL_TEXTURE_2D, texnum);
+                                       if (tpolytype != TPOLYTYPE_ADD)
                                        {
-                                               texnum = p->fogtexnum;
-                                               glBindTexture(GL_TEXTURE_2D, texnum);
+                                               tpolytype = TPOLYTYPE_ADD; // might match next poly
+                                               glBlendFunc(GL_SRC_ALPHA, GL_ONE);
                                        }
+                                       points = -1;
                                        glBegin(GL_TRIANGLE_FAN);
                                        for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
                                        {
-                                               VectorSubtract(vert->v, r_refdef.vieworg,diff);
+                                               glColor4ub(255,255,255,vert->a);
+                                               // would be 2fv, but windoze Matrox G200 and probably G400 drivers don't support that (dumb...)
                                                glTexCoord2f(vert->s, vert->t);
-                                               glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], vert->a*(1.0f/255.0f)*exp(fogdensity/DotProduct(diff,diff)));
                                                glVertex3fv(vert->v);
                                        }
-                                       glEnd ();
+                                       glEnd();
                                }
-                               else
+                               if (fogenabled && p->transpolytype == TPOLYTYPE_ALPHA)
                                {
-                                       glDisable(GL_TEXTURE_2D);
-                                       glBegin(GL_TRIANGLE_FAN);
-                                       for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
+                                       vec3_t diff;
+                                       glEnd();
+                                       points = -1; // to force a reinit on the next poly
+                                       if (tpolytype != TPOLYTYPE_ALPHA)
                                        {
-                                               VectorSubtract(vert->v, r_refdef.vieworg,diff);
-                                               glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], vert->a*(1.0f/255.0f)*exp(fogdensity/DotProduct(diff,diff)));
-                                               glVertex3fv(vert->v);
+                                               tpolytype = TPOLYTYPE_ALPHA; // probably matchs next poly
+                                               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+                                       }
+                                       if (p->fogtexnum)
+                                       {
+                                               if (texnum != p->fogtexnum) // highly unlikely to match next poly, but...
+                                               {
+                                                       texnum = p->fogtexnum;
+                                                       glBindTexture(GL_TEXTURE_2D, texnum);
+                                               }
+                                               glBegin(GL_TRIANGLE_FAN);
+                                               for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
+                                               {
+                                                       VectorSubtract(vert->v, r_refdef.vieworg,diff);
+                                                       glTexCoord2f(vert->s, vert->t);
+                                                       glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], vert->a*(1.0f/255.0f)*exp(fogdensity/DotProduct(diff,diff)));
+                                                       glVertex3fv(vert->v);
+                                               }
+                                               glEnd ();
+                                       }
+                                       else
+                                       {
+                                               glDisable(GL_TEXTURE_2D);
+                                               glBegin(GL_TRIANGLE_FAN);
+                                               for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
+                                               {
+                                                       VectorSubtract(vert->v, r_refdef.vieworg,diff);
+                                                       glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], vert->a*(1.0f/255.0f)*exp(fogdensity/DotProduct(diff,diff)));
+                                                       glVertex3fv(vert->v);
+                                               }
+                                               glEnd ();
+                                               glEnable(GL_TEXTURE_2D);
                                        }
-                                       glEnd ();
-                                       glEnable(GL_TEXTURE_2D);
                                }
                        }
                }
@@ -488,6 +544,35 @@ void transpolyrender()
        glDisable(GL_ALPHA_TEST);
 }
 
+/*
+void lightpolybegin(int texnum)
+{
+       if (currentlightpoly >= MAX_LIGHTPOLYS || currentlightvert >= MAX_LIGHTVERTS)
+               return;
+       lightpoly[currentlightpoly].texnum = (unsigned short) texnum;
+       lightpoly[currentlightpoly].firstvert = currentlightvert;
+       lightpoly[currentlightpoly].verts = 0;
+}
+
+// lightpolyvert is a #define
+
+void lightpolyend()
+{
+       if (currentlightpoly >= MAX_LIGHTPOLYS)
+               return;
+       if (lightpoly[currentlightpoly].verts < 3) // skip invalid polygons
+       {
+               currentlightvert = lightpoly[currentlightpoly].firstvert; // reset vert pointer
+               return;
+       }
+       if (currentlightvert >= MAX_LIGHTVERTS)
+               return;
+       currentlightpoly++;
+}
+*/
+
+extern qboolean isG200;
+
 void wallpolyclear()
 {
        currentwallpoly = currentwallvert = 0;
@@ -518,7 +603,7 @@ void wallpolyrender()
        {
                glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
                texnum = -1;
-               for (i = 0,p = &wallpoly[0];i < currentwallpoly;i++, p++)
+               for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
                {
                        if (p->texnum != texnum)
                        {
@@ -527,7 +612,7 @@ void wallpolyrender()
                        }
                        vert = &wallvert[p->firstvert];
                        glBegin(GL_POLYGON);
-                       for (j=0 ; j<p->verts ; j++, vert++)
+                       for (j=0 ; j<p->numverts ; j++, vert++)
                        {
                                glTexCoord2f (vert->s, vert->t);
                                glVertex3fv (vert->vert);
@@ -545,20 +630,20 @@ void wallpolyrender()
                glEnable(GL_TEXTURE_2D);
                texnum = -1;
                lighttexnum = -1;
-               for (i = 0,p = &wallpoly[0];i < currentwallpoly;i++, p++)
+               for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
                {
-//                     if (p->texnum != texnum || p->lighttexnum != lighttexnum)
-//                     {
+                       if (p->texnum != texnum || p->lighttexnum != lighttexnum)
+                       {
                                texnum = p->texnum;
                                lighttexnum = p->lighttexnum;
                                qglSelectTexture(gl_mtex_enum+0);
                                glBindTexture(GL_TEXTURE_2D, texnum);
                                qglSelectTexture(gl_mtex_enum+1);
                                glBindTexture(GL_TEXTURE_2D, lighttexnum);
-//                     }
+                       }
                        vert = &wallvert[p->firstvert];
                        glBegin(GL_POLYGON);
-                       for (j=0 ; j<p->verts ; j++, vert++)
+                       for (j=0 ; j<p->numverts ; j++, vert++)
                        {
                                qglMTexCoord2f(gl_mtex_enum, vert->s, vert->t); // texture
                                qglMTexCoord2f((gl_mtex_enum+1), vert->u, vert->v); // lightmap
@@ -578,7 +663,7 @@ void wallpolyrender()
                // first do the textures
                glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
                texnum = -1;
-               for (i = 0,p = &wallpoly[0];i < currentwallpoly;i++, p++)
+               for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
                {
                        if (p->texnum != texnum)
                        {
@@ -587,7 +672,7 @@ void wallpolyrender()
                        }
                        vert = &wallvert[p->firstvert];
                        glBegin(GL_POLYGON);
-                       for (j=0 ; j<p->verts ; j++, vert++)
+                       for (j=0 ; j<p->numverts ; j++, vert++)
                        {
                                glTexCoord2f (vert->s, vert->t);
                                glVertex3fv (vert->vert);
@@ -599,7 +684,7 @@ void wallpolyrender()
                glBlendFunc(GL_ZERO, GL_SRC_COLOR);
                glEnable(GL_BLEND);
                texnum = -1;
-               for (i = 0,p = &wallpoly[0];i < currentwallpoly;i++, p++)
+               for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
                {
                        if (p->lighttexnum != texnum)
                        {
@@ -608,7 +693,7 @@ void wallpolyrender()
                        }
                        vert = &wallvert[p->firstvert];
                        glBegin(GL_POLYGON);
-                       for (j=0 ; j<p->verts ; j++, vert++)
+                       for (j=0 ; j<p->numverts ; j++, vert++)
                        {
                                glTexCoord2f (vert->u, vert->v);
                                glVertex3fv (vert->vert);
@@ -616,17 +701,50 @@ void wallpolyrender()
                        glEnd ();
                }
        }
-       // render glow textures
+       // switch to additive mode settings
        glDepthMask(0);
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-       glBlendFunc(GL_ONE, GL_ONE);
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE);
        glEnable(GL_BLEND);
+       glDisable(GL_ALPHA_TEST);
+       glShadeModel(GL_SMOOTH);
+       // render vertex lit overlays ontop
+       texnum = -1;
+       for (i = 0, p = wallpoly;i < currentwallpoly;i++, p++)
+       {
+               if (!p->lit)
+                       continue;
+               for (j = 0,vert = &wallvert[p->firstvert];j < p->numverts;j++, vert++)
+                       if (vert->r || vert->g || vert->b)
+                               goto lit;
+               continue;
+lit:
+               c_light_polys++;
+               if (p->texnum != texnum)
+               {
+                       texnum = p->texnum;
+                       glBindTexture(GL_TEXTURE_2D, texnum);
+               }
+               glBegin(GL_POLYGON);
+               for (j = 0,vert = &wallvert[p->firstvert];j < p->numverts;j++, vert++)
+               {
+                       // would be 2fv, but windoze Matrox G200 and probably G400 drivers don't support that (dumb...)
+                       glTexCoord2f(vert->s, vert->t);
+                       // again, vector version isn't supported I think
+                       glColor3ub(vert->r, vert->g, vert->b);
+                       glVertex3fv(vert->vert);
+               }
+               glEnd();
+       }
+       // render glow textures
+       glShadeModel(GL_FLAT);
+       glBlendFunc(GL_ONE, GL_ONE);
        if (lighthalf)
                glColor3f(0.5,0.5,0.5);
        else
                glColor3f(1,1,1);
        texnum = -1;
-       for (i = 0,p = &wallpoly[0];i < currentwallpoly;i++, p++)
+       for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
        {
                if (!p->glowtexnum)
                        continue;
@@ -637,12 +755,12 @@ void wallpolyrender()
                }
                vert = &wallvert[p->firstvert];
                glBegin(GL_POLYGON);
-               for (j=0 ; j<p->verts ; j++, vert++)
+               for (j=0 ; j<p->numverts ; j++, vert++)
                {
                        glTexCoord2f (vert->s, vert->t);
                        glVertex3fv (vert->vert);
                }
-               glEnd ();
+               glEnd();
        }
        glColor3f(1,1,1);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -655,7 +773,7 @@ void wallpolyrender()
                {
                        vert = &wallvert[p->firstvert];
                        glBegin(GL_POLYGON);
-                       for (j=0 ; j<p->verts ; j++, vert++)
+                       for (j=0 ; j<p->numverts ; j++, vert++)
                        {
                                VectorSubtract(vert->vert, r_refdef.vieworg,diff);
                                glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], exp(fogdensity/DotProduct(diff,diff)));
@@ -665,6 +783,10 @@ void wallpolyrender()
                }
                glEnable(GL_TEXTURE_2D);
        }
+       glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       glDisable(GL_ALPHA_TEST);
+       glShadeModel(GL_SMOOTH);
        glDisable(GL_BLEND);
        glDepthMask(1);
 }
index b25a1b3..48cd075 100644 (file)
--- a/gl_poly.h
+++ b/gl_poly.h
@@ -18,8 +18,8 @@ extern void skypolyend();
 
 #define MAX_TRANSPOLYS 8192
 #define MAX_TRANSVERTS (MAX_TRANSPOLYS*4)
-#define MAX_WALLPOLYS 16384
-#define MAX_WALLVERTS (MAX_WALLPOLYS*4)
+#define MAX_WALLPOLYS 65536
+#define MAX_WALLVERTS (MAX_WALLPOLYS*3)
 #define MAX_SKYPOLYS 2048
 #define MAX_SKYVERTS (MAX_SKYPOLYS*4)
 
@@ -32,8 +32,8 @@ typedef struct
 
 typedef struct
 {
-       vec_t mindistance, maxdistance; // closest and farthest distance along v_forward
-       vec_t distance; // distance to center
+//     vec_t mindistance, maxdistance; // closest and farthest distance along v_forward
+//     vec_t distance; // distance to center
 //     vec3_t n; // normal
 //     vec_t ndist; // distance from origin along that normal
        unsigned short texnum;
@@ -48,13 +48,15 @@ typedef struct
 {
        vec3_t vert;
        vec_t s, t, u, v;
+       byte r,g,b,a;
 } wallvert_t;
 
 typedef struct
 {
        unsigned short texnum, lighttexnum, glowtexnum;
        unsigned short firstvert;
-       unsigned short verts;
+       unsigned short numverts;
+       unsigned short lit; // doesn't need to be an unsigned short, but to keep the structure consistent...
 } wallpoly_t;
 
 typedef struct
index 6179c7e..806a7b1 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;
+int                    c_brush_polys, c_alias_polys, c_light_polys, c_nodes, c_leafs;
 
 qboolean       envmap;                         // true during envmap command capture 
 
@@ -85,7 +85,6 @@ cvar_t        r_fullbrights = {"r_fullbrights", "1"};
 //cvar_t       gl_cull = {"gl_cull","1"};
 //cvar_t       gl_affinemodels = {"gl_affinemodels","0"};
 //cvar_t       gl_polyblend = {"gl_polyblend","1"};
-//cvar_t       gl_flashblend = {"gl_flashblend","0"};
 cvar_t gl_playermip = {"gl_playermip","0"};
 //cvar_t       gl_nocolors = {"gl_nocolors","0"};
 //cvar_t       gl_keeptjunctions = {"gl_keeptjunctions","1"};
@@ -1090,6 +1089,9 @@ void R_DrawQ2AliasFrame (md2mem_t *pheader)
        glDepthMask(1);
 }
 
+int modeldlightbits[8];
+extern int r_dlightframecount;
+
 /*
 =================
 R_DrawAliasModel
@@ -1119,6 +1121,16 @@ void R_DrawAliasModel (entity_t *e, int cull)
        VectorCopy (currententity->origin, r_entorigin);
        VectorSubtract (r_origin, r_entorigin, modelorg);
 
+       {
+               mleaf_t *leaf = Mod_PointInLeaf (currententity->origin, cl.worldmodel);
+               if (leaf->dlightframe == r_dlightframecount)
+                       for (i = 0;i < 8;i++)
+                               modeldlightbits[i] = leaf->dlightbits[i];
+               else
+                       for (i = 0;i < 8;i++)
+                               modeldlightbits[i] = 0;
+       }
+
        // get lighting information
 
        if (currententity->model->flags & EF_FULLBRIGHT || currententity->effects & EF_FULLBRIGHT)
@@ -1349,6 +1361,9 @@ void R_SetupFrame (void)
 
        c_brush_polys = 0;
        c_alias_polys = 0;
+       c_light_polys = 0;
+       c_nodes = 0;
+       c_leafs = 0;
 
 }
 
@@ -1551,6 +1566,7 @@ R_RenderView
 r_refdef must be set before the first call
 ================
 */
+extern qboolean intimerefresh;
 void R_RenderView (void)
 {
 //     double currtime, temptime;
@@ -1580,7 +1596,8 @@ void R_RenderView (void)
        R_SetupGL ();
        R_MarkLeaves ();        // done here so we know if we're in water
        R_DrawWorld ();         // adds static entities to the list
-       S_ExtraUpdate ();       // don't let sound get messed up if going slow
+       if (!intimerefresh)
+               S_ExtraUpdate ();       // don't let sound get messed up if going slow
        wallpolyclear();
        R_DrawEntitiesOnList1 (); // BSP models
        wallpolyrender();
index ceb7908..ab7573c 100644 (file)
@@ -152,7 +152,6 @@ void R_Init (void)
 //     Cvar_RegisterVariable (&gl_cull);
 //     Cvar_RegisterVariable (&gl_affinemodels);
 //     Cvar_RegisterVariable (&gl_polyblend);
-//     Cvar_RegisterVariable (&gl_flashblend);
        Cvar_RegisterVariable (&gl_playermip);
 //     Cvar_RegisterVariable (&gl_nocolors);
 
@@ -371,11 +370,13 @@ R_TimeRefresh_f
 For program optimization
 ====================
 */
+qboolean intimerefresh = 0;
 void R_TimeRefresh_f (void)
 {
        int                     i;
        float           start, stop, time;
 
+       intimerefresh = 1;
        start = Sys_FloatTime ();
        for (i=0 ; i<128 ; i++)
        {
@@ -384,12 +385,9 @@ void R_TimeRefresh_f (void)
        }
 
        stop = Sys_FloatTime ();
+       intimerefresh = 0;
        time = stop-start;
        Con_Printf ("%f seconds (%f fps)\n", time, 128/time);
 }
 
-void D_FlushCaches (void)
-{
-}
-
 
index 9f09d2a..e7b3c1b 100644 (file)
@@ -32,7 +32,7 @@ signed blocklights[18*18*3]; // LordHavoc: *3 for colored lighting
 #define        BLOCK_HEIGHT    128
 // LordHavoc: increased lightmap limit from 64 to 1024
 #define        MAX_LIGHTMAPS   1024
-#define LIGHTMAPSIZE   (BLOCK_WIDTH*BLOCK_HEIGHT*3)
+#define LIGHTMAPSIZE   (BLOCK_WIDTH*BLOCK_HEIGHT*4)
 
 int                    active_lightmaps;
 
@@ -47,6 +47,7 @@ cvar_t gl_lightmaprgba = {"gl_lightmaprgba", "1"};
 cvar_t gl_nosubimagefragments = {"gl_nosubimagefragments", "0"};
 cvar_t gl_nosubimage = {"gl_nosubimage", "0"};
 cvar_t r_ambient = {"r_ambient", "0"};
+//cvar_t gl_funnywalls = {"gl_funnywalls", "0"}; // LordHavoc: see BuildSurfaceDisplayList
 
 qboolean lightmaprgba, nosubimagefragments, nosubimage;
 int lightmapbytes;
@@ -54,6 +55,8 @@ int lightmapbytes;
 qboolean skyisvisible;
 extern qboolean gl_arrays;
 
+extern int r_dlightframecount;
+
 void glrsurf_init()
 {
        int i;
@@ -64,6 +67,7 @@ void glrsurf_init()
        Cvar_RegisterVariable(&gl_nosubimagefragments);
        Cvar_RegisterVariable(&gl_nosubimage);
        Cvar_RegisterVariable(&r_ambient);
+//     Cvar_RegisterVariable(&gl_funnywalls);
        // check if it's the glquake minigl driver
        if (strncasecmp(gl_vendor,"3Dfx",4)==0)
        if (!gl_arrays)
@@ -74,102 +78,6 @@ void glrsurf_init()
        }
 }
 
-int dlightdivtable[8192];
-int dlightdivtableinitialized = 0;
-
-/*
-===============
-R_AddDynamicLights
-===============
-*/
-void R_AddDynamicLights (msurface_t *surf)
-{
-       int                     sdtable[18], lnum, td, maxdist, maxdist2, maxdist3, i, s, t, smax, tmax, red, green, blue, j;
-       unsigned        *bl;
-       float           dist, f;
-       vec3_t          impact, local;
-       // use 64bit integer...  shame it's not very standardized...
-#if _MSC_VER || __BORLANDC__
-       __int64         k; // MSVC
-#else
-       long long       k; // GCC
-#endif
-
-       if (!dlightdivtableinitialized)
-       {
-               dlightdivtable[0] = 1048576 >> 7;
-               for (s = 1;s < 8192;s++)
-                       dlightdivtable[s] = 1048576 / (s << 7);
-               dlightdivtableinitialized = 1;
-       }
-
-       smax = (surf->extents[0]>>4)+1;
-       tmax = (surf->extents[1]>>4)+1;
-
-       for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++)
-       {
-               if ( !(surf->dlightbits[lnum >> 5] & (1<<(lnum&31)) ) )
-                       continue;               // not lit by this light
-
-               VectorSubtract(cl_dlights[lnum].origin, currententity->origin, local);
-               dist = DotProduct (local, surf->plane->normal) - surf->plane->dist;
-               for (i=0 ; i<3 ; i++)
-                       impact[i] = cl_dlights[lnum].origin[i] - surf->plane->normal[i]*dist;
-
-               f = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0];
-               i = f;
-
-               // reduce calculations
-               t = dist*dist;
-               for (s = 0;s < smax;s++, i -= 16)
-                       sdtable[s] = i*i + t;
-
-               f = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1];
-               i = f;
-
-               maxdist = (int) (cl_dlights[lnum].radius*cl_dlights[lnum].radius); // for comparisons to minimum acceptable light
-               // clamp radius to avoid exceeding 8192 entry division table
-               if (maxdist > 1048576)
-                       maxdist = 1048576;
-               maxdist3 = maxdist - (int) (dist*dist);
-               // convert to 8.8 blocklights format
-               if (!cl_dlights[lnum].dark)
-               {
-                       f = cl_dlights[lnum].color[0] * maxdist;red = f;
-                       f = cl_dlights[lnum].color[1] * maxdist;green = f;
-                       f = cl_dlights[lnum].color[2] * maxdist;blue = f;
-               }
-               else // negate for darklight
-               {
-                       f = cl_dlights[lnum].color[0] * -maxdist;red = f;
-                       f = cl_dlights[lnum].color[1] * -maxdist;green = f;
-                       f = cl_dlights[lnum].color[2] * -maxdist;blue = f;
-               }
-               bl = blocklights;
-               for (t = 0;t < tmax;t++,i -= 16)
-               {
-                       td = i*i;
-                       if (td < maxdist3) // make sure some part of it is visible on this line
-                       {
-                               maxdist2 = maxdist - td;
-                               for (s = 0;s < smax;s++)
-                               {
-                                       if (sdtable[s] < maxdist2)
-                                       {
-                                               j = dlightdivtable[(sdtable[s]+td) >> 7];
-                                               k = (red   * j) >> 8;bl[0] += k;
-                                               k = (green * j) >> 8;bl[1] += k;
-                                               k = (blue  * j) >> 8;bl[2] += k;
-                                       }
-                                       bl += 3;
-                               }
-                       }
-                       else
-                               bl+=smax*3; // skip line
-               }
-       }
-}
-
 extern qboolean lighthalf;
 /*
 ===============
@@ -188,7 +96,6 @@ void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
        int                     maps;
        int                     *bl;
 
-       surf->cached_dlight = (surf->dlightframe == r_framecount);
        surf->cached_lighthalf = lighthalf;
        surf->cached_ambient = r_ambient.value;
 
@@ -234,10 +141,6 @@ void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
                                        *bl++ += *lightmap++ * scale;
                                }
                        }
-
-// add all the dynamic lights
-               if (surf->dlightframe == r_framecount)
-                       R_AddDynamicLights (surf);
        }
        stride -= (smax*lightmapbytes);
        bl = blocklights;
@@ -402,7 +305,6 @@ extern char skyname[];
 
 void R_DynamicLightPoint(vec3_t color, vec3_t org, int *dlightbits);
 //extern cvar_t r_dynamicwater;
-extern int r_dlightframecount;
 float  turbsin[256] =
 {
        #include "gl_warp_sin.h"
@@ -449,14 +351,16 @@ DrawTextureChains
 extern qboolean hlbsp;
 extern void R_Sky();
 extern char skyname[];
+//extern qboolean SV_TestLine (hull_t *hull, int num, vec3_t p1, vec3_t p2);
 void DrawTextureChains (void)
 {
-       int             i, j, maps;
+//     int             i, j, l;
+       int             i, j;
        msurface_t      *s;
        texture_t       *t;
        glpoly_t        *p;
-       float           *v;
-       float           os = turbsin[(int)(realtime * TURBSCALE) & 255], ot = turbsin[(int)(realtime * TURBSCALE + 96.0) & 255];
+       float           *v, os = turbsin[(int)(realtime * TURBSCALE) & 255], ot = turbsin[(int)(realtime * TURBSCALE + 96.0) & 255];
+//     vec3_t shadecolor;
 
        // first the sky
        skypolyclear();
@@ -465,7 +369,6 @@ void DrawTextureChains (void)
                if (!cl.worldmodel->textures[j] || !(s = cl.worldmodel->textures[j]->texturechain))
                        continue;
                // LordHavoc: decide the render type only once, because the surface properties were determined by texture anyway
-               // subdivided water surface warp
                if (s->flags & SURF_DRAWSKY)
                {
                        cl.worldmodel->textures[j]->texturechain = NULL;
@@ -504,41 +407,136 @@ void DrawTextureChains (void)
        {
                if (!cl.worldmodel->textures[j] || !(s = cl.worldmodel->textures[j]->texturechain))
                        continue;
+               // subdivided water surface warp
                if (!(s->flags & SURF_DRAWTURB))
                {
                        cl.worldmodel->textures[j]->texturechain = NULL;
                        t = R_TextureAnimation (cl.worldmodel->textures[j]);
                        for (;s;s = s->texturechain)
                        {
-                               if (currentwallpoly < MAX_WALLPOLYS && currentwallvert < MAX_WALLVERTS && (currentwallvert + s->polys->numverts) <= MAX_WALLVERTS)
+                               // check for lightmap modification
+                               if (r_dynamic.value)
                                {
-                                       // check for lightmap modification
-                                       if (r_dynamic.value)
-                                       {
-                                               if (s->dlightframe == r_framecount || s->cached_dlight || r_ambient.value != s->cached_ambient || lighthalf != s->cached_lighthalf) // dynamic this frame or previously, or lighthalf changed, or r_ambient changed
-                                                       R_UpdateLightmap(s, s->lightmaptexturenum);
-                                               else
-                                                       for (maps = 0 ; maps < MAXLIGHTMAPS && s->styles[maps] != 255 ; maps++)
-                                                               if (d_lightstylevalue[s->styles[maps]] != s->cached_light[maps])
-                                                               {
-                                                                       R_UpdateLightmap(s, s->lightmaptexturenum);
-                                                                       break;
-                                                               }
-                                       }
+                                       if (r_ambient.value != s->cached_ambient || lighthalf != s->cached_lighthalf
+                                       || (s->styles[0] != 255 && d_lightstylevalue[s->styles[0]] != s->cached_light[0])
+                                       || (s->styles[1] != 255 && d_lightstylevalue[s->styles[1]] != s->cached_light[1])
+                                       || (s->styles[2] != 255 && d_lightstylevalue[s->styles[2]] != s->cached_light[2])
+                                       || (s->styles[3] != 255 && d_lightstylevalue[s->styles[3]] != s->cached_light[3]))
+                                               R_UpdateLightmap(s, s->lightmaptexturenum);
+                               }
+                               for (p = s->polys;p;p = p->next)
+                               {
+                                       if (currentwallpoly >= MAX_WALLPOLYS)
+                                               break;
+                                       v = &s->polys->verts[0][0];
                                        wallpoly[currentwallpoly].texnum = (unsigned short) t->gl_texturenum;
                                        wallpoly[currentwallpoly].lighttexnum = (unsigned short) lightmap_textures + s->lightmaptexturenum;
                                        wallpoly[currentwallpoly].glowtexnum = (unsigned short) t->gl_glowtexturenum;
                                        wallpoly[currentwallpoly].firstvert = currentwallvert;
-                                       wallpoly[currentwallpoly++].verts = s->polys->numverts;
-                                       for (i = 0,v = s->polys->verts[0];i<s->polys->numverts;i++, v += VERTEXSIZE)
+                                       wallpoly[currentwallpoly].numverts = p->numverts;
+                                       if (wallpoly[currentwallpoly++].lit = s->dlightframe == r_dlightframecount && r_dynamic.value)
                                        {
-                                               wallvert[currentwallvert].vert[0] = v[0];
-                                               wallvert[currentwallvert].vert[1] = v[1];
-                                               wallvert[currentwallvert].vert[2] = v[2];
-                                               wallvert[currentwallvert].s = v[3];
-                                               wallvert[currentwallvert].t = v[4];
-                                               wallvert[currentwallvert].u = v[5];
-                                               wallvert[currentwallvert++].v = v[6];
+                                               for (i = 0;i<p->numverts;i++, v += VERTEXSIZE)
+                                               {
+                                                       /*
+                                                       int dj;
+                                                       shadecolor[0] = shadecolor[1] = shadecolor[2] = 0;
+                                                       for (dj = 0;dj < (MAX_DLIGHTS >> 5);dj++)
+                                                       {
+                                                               if (s->dlightbits[dj])
+                                                               {
+                                                                       int di;
+                                                                       for (di=0 ; di<32 ; di++)
+                                                                       {
+                                                                               if ((1 << (di&31)) & s->dlightbits[di>>5])
+                                                                               {
+                                                                                       vec3_t ddist;
+                                                                                       dlight_t *dl;
+                                                                                       float dr;
+                                                                                       float df;
+                                                                                       float dt;
+                                                                                       dl = &cl_dlights[(dj<<5)+di];
+                                                                                       VectorSubtract(dl->origin, v, ddist);
+                                                                                       df = DotProduct(ddist, ddist) + 65536.0f;
+                                                                                       dr = dl->radius * dl->radius * 16.0f;
+                                                                                       if (df < dr)
+                                                                                       {
+                                                                                               VectorNormalize(ddist);
+                                                                                               dt = DotProduct(ddist, s->plane->normal);
+                                                                                               if (s->flags & SURF_PLANEBACK)
+                                                                                                       dt = -dt;
+                                                                                               if (dt > 0.0f)
+                                                                                               {
+                                                                                                       dr *= (dt * 0.5f + 0.5f);
+                                                                                                       if (df < dr)
+                                                                                                       {
+                                                       */
+                                                                                                               /*
+                                                                                                               vec3_t v2, v3;
+                                                                                                               VectorSubtract(v, ddist, v3); // pull off surface
+                                                                                                               if (s->flags & SURF_PLANEBACK)
+                                                                                                               {
+                                                                                                                       VectorSubtract(dl->origin, s->plane->normal, v2);
+                                                                                                                       VectorSubtract(v3, s->plane->normal, v3);
+                                                                                                               }
+                                                                                                               else
+                                                                                                               {
+                                                                                                                       VectorAdd(dl->origin, s->plane->normal, v2);
+                                                                                                                       VectorAdd(v3, s->plane->normal, v3);
+                                                                                                               }
+                                                                                                               if (SV_TestLine(&cl.worldmodel->hulls[0], 0, v2, v3))
+//                                                                                                             if (SV_TestLine(&cl.worldmodel->hulls[0], 0, dl->origin, v))
+                                                                                                               {
+                                                                                                               */
+                                                       /*
+                                                                                                                       float dbrightness = dr * 16.0f / df;
+                                                                                                                       shadecolor[0] += dbrightness * dl->color[0];
+                                                                                                                       shadecolor[1] += dbrightness * dl->color[1];
+                                                                                                                       shadecolor[2] += dbrightness * dl->color[2];
+                                                                                                               //}
+                                                                                                       }
+                                                                                               }
+                                                                                       }
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+                                                       //R_DynamicLightPoint(shadecolor, v, s->dlightbits);
+                                                       if (lighthalf)
+                                                       {
+                                                               shadecolor[0] *= 0.5f;
+                                                               shadecolor[1] *= 0.5f;
+                                                               shadecolor[2] *= 0.5f;
+                                                       }
+                                                       wallvert[currentwallvert].r = (byte) (bound(0, (int) shadecolor[0], 255));
+                                                       wallvert[currentwallvert].g = (byte) (bound(0, (int) shadecolor[1], 255));
+                                                       wallvert[currentwallvert].b = (byte) (bound(0, (int) shadecolor[2], 255));
+                                                       */
+                                                       wallvert[currentwallvert].r = (byte) (bound(0, (int) v[9], 255));
+                                                       wallvert[currentwallvert].g = (byte) (bound(0, (int) v[10], 255));
+                                                       wallvert[currentwallvert].b = (byte) (bound(0, (int) v[11], 255));
+                                                       wallvert[currentwallvert].a = 255;
+                                                       wallvert[currentwallvert].vert[0] = v[0];
+                                                       wallvert[currentwallvert].vert[1] = v[1];
+                                                       wallvert[currentwallvert].vert[2] = v[2];
+                                                       wallvert[currentwallvert].s = v[3];
+                                                       wallvert[currentwallvert].t = v[4];
+                                                       wallvert[currentwallvert].u = v[5];
+                                                       wallvert[currentwallvert++].v = v[6];
+                                               }
+                                       }
+                                       else
+                                       {
+                                               for (i = 0;i<p->numverts;i++, v += VERTEXSIZE)
+                                               {
+                                                       wallvert[currentwallvert].vert[0] = v[0];
+                                                       wallvert[currentwallvert].vert[1] = v[1];
+                                                       wallvert[currentwallvert].vert[2] = v[2];
+                                                       wallvert[currentwallvert].s = v[3];
+                                                       wallvert[currentwallvert].t = v[4];
+                                                       wallvert[currentwallvert].u = v[5];
+                                                       wallvert[currentwallvert++].v = v[6];
+                                               }
                                        }
                                }
                        }
@@ -558,6 +556,67 @@ void DrawTextureChains (void)
                // subdivided water surface warp
                if (s->flags & SURF_DRAWTURB)
                {
+                       int alpha = s->flags & SURF_DRAWNOALPHA ? 255 : r_wateralpha.value*255.0f;
+                       // FIXME: make fog texture if water texture is transparent?
+                       if (r_waterripple.value)
+                       {
+                               if (lighthalf)
+                               {
+                                       for (;s;s = s->texturechain)
+                                       {
+                                               for (p=s->polys ; p ; p=p->next)
+                                               {
+                                                       transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA);
+                                                       for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
+                                                               transpolyvert(v[0], v[1], v[2] + r_waterripple.value * turbsin[(int)((v[3]*0.125f+realtime) * TURBSCALE) & 255] * turbsin[(int)((v[4]*0.125f+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f), (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) (v[9]+128) >> 1,(int) (v[10]+128) >> 1,(int) (v[11]+128) >> 1,alpha);
+                                                       transpolyend();
+                                               }
+                                       }
+                               }
+                               else
+                               {
+                                       for (;s;s = s->texturechain)
+                                       {
+                                               for (p=s->polys ; p ; p=p->next)
+                                               {
+                                                       transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA);
+                                                       for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
+                                                               transpolyvert(v[0], v[1], v[2] + r_waterripple.value * turbsin[(int)((v[3]*0.125f+realtime) * TURBSCALE) & 255] * turbsin[(int)((v[4]*0.125f+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f), (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) (v[9]+128),(int) (v[10]+128),(int) (v[11]+128),alpha);
+                                                       transpolyend();
+                                               }
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               if (lighthalf)
+                               {
+                                       for (;s;s = s->texturechain)
+                                       {
+                                               for (p=s->polys ; p ; p=p->next)
+                                               {
+                                                       transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA);
+                                                       for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
+                                                               transpolyvert(v[0], v[1], v[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) (v[9]+128) >> 1,(int) (v[10]+128) >> 1,(int) (v[11]+128) >> 1,alpha);
+                                                       transpolyend();
+                                               }
+                                       }
+                               }
+                               else
+                               {
+                                       for (;s;s = s->texturechain)
+                                       {
+                                               for (p=s->polys ; p ; p=p->next)
+                                               {
+                                                       transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA);
+                                                       for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
+                                                               transpolyvert(v[0], v[1], v[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) (v[9]+128),(int) (v[10]+128),(int) (v[11]+128),alpha);
+                                                       transpolyend();
+                                               }
+                                       }
+                               }
+                       }
+                       /*
                        int light, alpha, r = 0, g = 0, b = 0;
                        vec3_t nv, shadecolor;
                        alpha = s->flags & SURF_DRAWNOALPHA ? 255 : r_wateralpha.value*255.0f;
@@ -734,6 +793,7 @@ void DrawTextureChains (void)
                                        }
                                }
                        }
+                       */
                }
        }
 }
@@ -746,7 +806,7 @@ extern vec3_t shadecolor;
 void R_DynamicLightPoint(vec3_t color, vec3_t org, int *dlightbits);
 void R_DynamicLightPointNoMask(vec3_t color, vec3_t org);
 void EmitWaterPolys (msurface_t *fa);
-void R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex, mnode_t *node);
+void R_OldMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex, model_t *model);
 
 /*
 =================
@@ -755,7 +815,7 @@ R_DrawBrushModel
 */
 void R_DrawBrushModel (entity_t *e)
 {
-       int                     i, j, k, smax, tmax, size3, maps;
+       int                     i, j/*, l*/, smax, tmax, size3, maps;
        vec3_t          mins, maxs, nv;
        msurface_t      *s;
        mplane_t        *pplane;
@@ -765,6 +825,7 @@ void R_DrawBrushModel (entity_t *e)
        texture_t       *t;
        byte            *lm;
        float           os = turbsin[(int)(realtime * TURBSCALE) & 255], ot = turbsin[(int)(realtime * TURBSCALE + 96.0) & 255];
+       glpoly_t        *p;
 
        currententity = e;
 
@@ -808,18 +869,16 @@ void R_DrawBrushModel (entity_t *e)
 // instanced model
        if (modelalpha == 1 && clmodel->firstmodelsurface != 0 && !(currententity->effects & EF_FULLBRIGHT) && currententity->colormod[0] == 1 && currententity->colormod[2] == 1 && currententity->colormod[2] == 1)
        {
-//             if (!gl_flashblend.value)
-//             {
-                       vec3_t org;
-                       for (k=0 ; k<MAX_DLIGHTS ; k++)
-                       {
-                               if ((cl_dlights[k].die < cl.time) || (!cl_dlights[k].radius))
-                                       continue;
+               int k;
+               vec3_t org;
+               for (k=0 ; k<MAX_DLIGHTS ; k++)
+               {
+                       if ((cl_dlights[k].die < cl.time) || (!cl_dlights[k].radius))
+                               continue;
 
-                               VectorSubtract(cl_dlights[k].origin, currententity->origin, org);
-                               R_MarkLights (org, &cl_dlights[k], 1<<(k&31), k >> 5, clmodel->nodes + clmodel->hulls[0].firstclipnode);
-                       }
-//             }
+                       VectorSubtract(cl_dlights[k].origin, currententity->origin, org);
+                       R_OldMarkLights (org, &cl_dlights[k], 1<<(k&31), k >> 5, clmodel); //, clmodel->nodes + clmodel->hulls[0].firstclipnode);
+               }
        }
        else
                vertexlit = true;
@@ -844,6 +903,67 @@ e->angles[0] = -e->angles[0];      // stupid quake bug
                                continue;
                        if (s->flags & SURF_DRAWTURB)
                        {
+                               int                     alpha = s->flags & SURF_DRAWNOALPHA ? 255 : r_wateralpha.value*255.0f;
+                               // FIXME: make fog texture if water texture is transparent?
+                               if (r_waterripple.value)
+                               {
+                                       if (lighthalf)
+                                       {
+                                               for (p=s->polys ; p ; p=p->next)
+                                               {
+                                                       transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA);
+                                                       for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
+                                                       {
+                                                               softwaretransform(v, nv);
+                                                               transpolyvert(nv[0], nv[1], nv[2] + r_waterripple.value * turbsin[(int)((v[3]*0.125f+realtime) * TURBSCALE) & 255] * turbsin[(int)((v[4]*0.125f+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f), (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) (v[9]+128) >> 1,(int) (v[10]+128) >> 1,(int) (v[11]+128) >> 1,alpha);
+                                                       }
+                                                       transpolyend();
+                                               }
+                                       }
+                                       else
+                                       {
+                                               for (p=s->polys ; p ; p=p->next)
+                                               {
+                                                       transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA);
+                                                       for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
+                                                       {
+                                                               softwaretransform(v, nv);
+                                                               transpolyvert(nv[0], nv[1], nv[2] + r_waterripple.value * turbsin[(int)((v[3]*0.125f+realtime) * TURBSCALE) & 255] * turbsin[(int)((v[4]*0.125f+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f), (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) (v[9]+128),(int) (v[10]+128),(int) (v[11]+128),alpha);
+                                                       }
+                                                       transpolyend();
+                                               }
+                                       }
+                               }
+                               else
+                               {
+                                       if (lighthalf)
+                                       {
+                                               for (p=s->polys ; p ; p=p->next)
+                                               {
+                                                       transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA);
+                                                       for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
+                                                       {
+                                                               softwaretransform(v, nv);
+                                                               transpolyvert(nv[0], nv[1], nv[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) (v[9]+128) >> 1,(int) (v[10]+128) >> 1,(int) (v[11]+128) >> 1,alpha);
+                                                       }
+                                                       transpolyend();
+                                               }
+                                       }
+                                       else
+                                       {
+                                               for (p=s->polys ; p ; p=p->next)
+                                               {
+                                                       transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA);
+                                                       for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
+                                                       {
+                                                               softwaretransform(v, nv);
+                                                               transpolyvert(nv[0], nv[1], nv[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) (v[9]+128),(int) (v[10]+128),(int) (v[11]+128),alpha);
+                                                       }
+                                                       transpolyend();
+                                               }
+                                       }
+                               }
+                               /*
                                glpoly_t        *p;
                                int                     light, alpha, r = 0, g = 0, b = 0;
                                vec3_t          shadecolor;
@@ -915,20 +1035,27 @@ e->angles[0] = -e->angles[0];    // stupid quake bug
                                        }
                                        transpolyend();
                                }
+                               */
                                continue;
                        }
                        t = R_TextureAnimation (s->texinfo->texture);
-                       v = s->polys->verts[0];
                        if (vertexlit || s->texinfo->texture->transparent)
                        {
                                // FIXME: could be a transparent water texture
-                               transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
                                if ((currententity->effects & EF_FULLBRIGHT) || !s->samples)
                                {
-                                       for (i = 0;i < s->polys->numverts;i++, v += VERTEXSIZE)
+                                       for (p = s->polys;p;p = p->next)
                                        {
-                                               softwaretransform(v, nv);
-                                               transpolyvert(nv[0], nv[1], nv[2], v[3], v[4], 255,255,255,modelalpha*255.0f);
+                                               if (currenttranspoly >= MAX_TRANSPOLYS)
+                                                       continue;
+                                               v = &p->verts[0][0];
+                                               transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
+                                               for (i = 0;i < p->numverts;i++, v += VERTEXSIZE)
+                                               {
+                                                       softwaretransform(v, nv);
+                                                       transpolyvert(nv[0], nv[1], nv[2], v[3], v[4], 255,255,255,modelalpha*255.0f);
+                                               }
+                                               transpolyend();
                                        }
                                }
                                else
@@ -936,61 +1063,105 @@ e->angles[0] = -e->angles[0];   // stupid quake bug
                                        smax = (s->extents[0]>>4)+1;
                                        tmax = (s->extents[1]>>4)+1;
                                        size3 = smax*tmax*3; // *3 for colored lighting
-                                       for (i = 0;i < s->polys->numverts;i++, v += VERTEXSIZE)
+                                       for (p = s->polys;p;p = p->next)
                                        {
-                                               shadecolor[0] = shadecolor[1] = shadecolor[2] = r_ambient.value * 2.0f;
-                                               lm = (byte *)((long) s->samples + ((int) v[8] * smax + (int) v[7]) * 3); // LordHavoc: *3 for colored lighting
-                                               for (maps = 0;maps < MAXLIGHTMAPS && s->styles[maps] != 255;maps++)
-                                               {
-                                                       scale = d_lightstylevalue[s->styles[maps]] * (1.0 / 128.0);
-                                                       shadecolor[0] += lm[0] * scale;
-                                                       shadecolor[1] += lm[1] * scale;
-                                                       shadecolor[2] += lm[2] * scale;
-                                                       lm += size3; // LordHavoc: *3 for colored lighting
-                                               }
-                                               softwaretransform(v, nv);
-                                               R_DynamicLightPointNoMask(shadecolor, nv); // LordHavoc: dynamic lighting
-                                               if (lighthalf)
-                                               {
-                                                       transpolyvert(nv[0], nv[1], nv[2], v[3], v[4], (int) shadecolor[0] >> 1, (int) shadecolor[1] >> 1, (int) shadecolor[2] >> 1, modelalpha*255.0f);
-                                               }
-                                               else
+                                               if (currenttranspoly >= MAX_TRANSPOLYS)
+                                                       continue;
+                                               v = &p->verts[0][0];
+                                               transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
+                                               for (i = 0;i < p->numverts;i++, v += VERTEXSIZE)
                                                {
-                                                       transpolyvert(nv[0], nv[1], nv[2], v[3], v[4], shadecolor[0], shadecolor[1], shadecolor[2], modelalpha*255.0f);
+                                                       shadecolor[0] = shadecolor[1] = shadecolor[2] = r_ambient.value * 2.0f;
+                                                       lm = (byte *)((long) s->samples + ((int) v[8] * smax + (int) v[7]) * 3); // LordHavoc: *3 for colored lighting
+                                                       for (maps = 0;maps < MAXLIGHTMAPS && s->styles[maps] != 255;maps++)
+                                                       {
+                                                               scale = d_lightstylevalue[s->styles[maps]] * (1.0 / 128.0);
+                                                               shadecolor[0] += lm[0] * scale;
+                                                               shadecolor[1] += lm[1] * scale;
+                                                               shadecolor[2] += lm[2] * scale;
+                                                               lm += size3; // LordHavoc: *3 for colored lighting
+                                                       }
+                                                       softwaretransform(v, nv);
+                                                       R_DynamicLightPointNoMask(shadecolor, nv); // LordHavoc: dynamic lighting
+                                                       if (lighthalf)
+                                                       {
+                                                               transpolyvert(nv[0], nv[1], nv[2], v[3], v[4], (int) shadecolor[0] >> 1, (int) shadecolor[1] >> 1, (int) shadecolor[2] >> 1, modelalpha*255.0f);
+                                                       }
+                                                       else
+                                                       {
+                                                               transpolyvert(nv[0], nv[1], nv[2], v[3], v[4], shadecolor[0], shadecolor[1], shadecolor[2], modelalpha*255.0f);
+                                                       }
                                                }
+                                               transpolyend();
                                        }
                                }
-                               transpolyend();
                        }
                        else
                        {
                                // check for lightmap modification
                                if (r_dynamic.value)
                                {
-                                       if (s->dlightframe == r_framecount || s->cached_dlight || r_ambient.value != s->cached_ambient || lighthalf != s->cached_lighthalf) // dynamic this frame or previously, or lighthalf changed
+                                       if (r_ambient.value != s->cached_ambient || lighthalf != s->cached_lighthalf
+                                       || (s->styles[0] != 255 && d_lightstylevalue[s->styles[0]] != s->cached_light[0])
+                                       || (s->styles[1] != 255 && d_lightstylevalue[s->styles[1]] != s->cached_light[1])
+                                       || (s->styles[2] != 255 && d_lightstylevalue[s->styles[2]] != s->cached_light[2])
+                                       || (s->styles[3] != 255 && d_lightstylevalue[s->styles[3]] != s->cached_light[3]))
                                                R_UpdateLightmap(s, s->lightmaptexturenum);
-                                       else
-                                               for (maps = 0 ; maps < MAXLIGHTMAPS && s->styles[maps] != 255 ; maps++)
-                                                       if (d_lightstylevalue[s->styles[maps]] != s->cached_light[maps])
-                                                       {
-                                                               R_UpdateLightmap(s, s->lightmaptexturenum);
-                                                               break;
-                                                       }
                                }
-                               if (currentwallpoly < MAX_WALLPOLYS && (currentwallvert + s->polys->numverts) <= MAX_WALLVERTS)
+                               for (p = s->polys;p;p = p->next)
                                {
+                                       if (currentwallpoly >= MAX_WALLPOLYS)
+                                               break;
+                                       v = &s->polys->verts[0][0];
                                        wallpoly[currentwallpoly].texnum = (unsigned short) t->gl_texturenum;
                                        wallpoly[currentwallpoly].lighttexnum = (unsigned short) lightmap_textures + s->lightmaptexturenum;
                                        wallpoly[currentwallpoly].glowtexnum = (unsigned short) t->gl_glowtexturenum;
                                        wallpoly[currentwallpoly].firstvert = currentwallvert;
-                                       wallpoly[currentwallpoly++].verts = s->polys->numverts;
-                                       for (i = 0;i<s->polys->numverts;i++, v += VERTEXSIZE)
+                                       wallpoly[currentwallpoly].numverts = p->numverts;
+                                       if (wallpoly[currentwallpoly++].lit = s->dlightframe == r_dlightframecount && r_dynamic.value)
+                                       {
+                                               for (i = 0;i<p->numverts;i++, v += VERTEXSIZE)
+                                               {
+                                                       /*
+                                                       softwaretransform(v, nv);
+                                                       shadecolor[0] = shadecolor[1] = shadecolor[2] = 0;
+//                                                     R_DynamicLightPoint(shadecolor, nv, s->dlightbits);
+                                                       R_DynamicLightPointNoMask(shadecolor, nv);
+                                                       if (lighthalf)
+                                                       {
+                                                               shadecolor[0] *= 0.5f;
+                                                               shadecolor[1] *= 0.5f;
+                                                               shadecolor[2] *= 0.5f;
+                                                       }
+                                                       wallvert[currentwallvert].r = (byte) (bound(0, (int) shadecolor[0], 255));
+                                                       wallvert[currentwallvert].g = (byte) (bound(0, (int) shadecolor[1], 255));
+                                                       wallvert[currentwallvert].b = (byte) (bound(0, (int) shadecolor[2], 255));
+                                                       wallvert[currentwallvert].a = 255;
+                                                       wallvert[currentwallvert].vert[0] = nv[0];
+                                                       wallvert[currentwallvert].vert[1] = nv[1];
+                                                       wallvert[currentwallvert].vert[2] = nv[2];
+                                                       */
+                                                       softwaretransform(v, wallvert[currentwallvert].vert);
+                                                       wallvert[currentwallvert].r = (byte) (bound(0, (int) v[9], 255));
+                                                       wallvert[currentwallvert].g = (byte) (bound(0, (int) v[10], 255));
+                                                       wallvert[currentwallvert].b = (byte) (bound(0, (int) v[11], 255));
+                                                       wallvert[currentwallvert].a = 255;
+                                                       wallvert[currentwallvert].s = v[3];
+                                                       wallvert[currentwallvert].t = v[4];
+                                                       wallvert[currentwallvert].u = v[5];
+                                                       wallvert[currentwallvert++].v = v[6];
+                                               }
+                                       }
+                                       else
                                        {
-                                               softwaretransform(v, wallvert[currentwallvert].vert);
-                                               wallvert[currentwallvert].s = v[3];
-                                               wallvert[currentwallvert].t = v[4];
-                                               wallvert[currentwallvert].u = v[5];
-                                               wallvert[currentwallvert++].v = v[6];
+                                               for (i = 0;i<p->numverts;i++, v += VERTEXSIZE)
+                                               {
+                                                       softwaretransform(v, wallvert[currentwallvert].vert);
+                                                       wallvert[currentwallvert].s = v[3];
+                                                       wallvert[currentwallvert].t = v[4];
+                                                       wallvert[currentwallvert].u = v[5];
+                                                       wallvert[currentwallvert++].v = v[6];
+                                               }
                                        }
                                }
                        }
@@ -1011,123 +1182,18 @@ void R_StoreEfrags (efrag_t **ppefrag);
 
 /*
 ================
-R_RecursiveWorldNode
+R_WorldNode
 ================
 */
-//extern qboolean R_CullBox (vec3_t mins, vec3_t maxs);
-/*
-void R_RecursiveWorldNode (mnode_t *node)
-{
-       int                     c, side;
-       double          dot;
-
-loc0:
-// if a leaf node, draw stuff
-       if (node->contents < 0)
-       {
-               mleaf_t         *pleaf;
-               pleaf = (mleaf_t *)node;
-
-               if (c = pleaf->nummarksurfaces)
-               {
-                       msurface_t      **mark;
-                       mark = pleaf->firstmarksurface;
-                       do
-                       {
-                               (*mark)->visframe = r_framecount;
-                               mark++;
-                       } while (--c);
-               }
-
-       // deal with model fragments in this leaf
-               if (pleaf->efrags)
-                       R_StoreEfrags (&pleaf->efrags);
-
-               return;
-       }
-
-// node is just a decision point, so go down the apropriate sides
-
-// find which side of the node we are on
-       dot = (node->plane->type < 3 ? modelorg[node->plane->type] : DotProduct (modelorg, node->plane->normal)) - node->plane->dist;
-
-// recurse down the children, front side first
-       side = dot < 0;
-       // LordHavoc: save a stack frame by avoiding a call
-//     if (node->children[side]->contents != CONTENTS_SOLID && node->children[side]->visframe == r_visframecount && !R_CullBox (node->children[side]->minmaxs, node->children[side]->minmaxs+3))
-       // LordHavoc: inlined further to reduce conditions
-       if (node->children[side]->contents != CONTENTS_SOLID
-        && node->children[side]->visframe == r_visframecount
-        && frustum[0].BoxOnPlaneSideFunc(node->children[side]->minmaxs, node->children[side]->minmaxs+3, &frustum[0]) != 2
-        && frustum[1].BoxOnPlaneSideFunc(node->children[side]->minmaxs, node->children[side]->minmaxs+3, &frustum[1]) != 2
-        && frustum[2].BoxOnPlaneSideFunc(node->children[side]->minmaxs, node->children[side]->minmaxs+3, &frustum[2]) != 2
-        && frustum[3].BoxOnPlaneSideFunc(node->children[side]->minmaxs, node->children[side]->minmaxs+3, &frustum[3]) != 2)
-               R_RecursiveWorldNode (node->children[side]);
-
-       // backside
-       side = dot >= 0;
-// draw stuff
-       if (c = node->numsurfaces)
-       {
-               msurface_t      *surf;
-               surf = cl.worldmodel->surfaces + node->firstsurface;
-
-               // LordHavoc: caused a crash due to texsort (it could render twice...)
-               // back side
-               //side = dot >= -BACKFACE_EPSILON;
-               if (dot < 0)
-               {
-                       for (;c;c--, surf++)
-                       {
-                               if (surf->visframe == r_framecount && (surf->flags & SURF_PLANEBACK))
-                               {
-                                       surf->texturechain = surf->texinfo->texture->texturechain;
-                                       surf->texinfo->texture->texturechain = surf;
-                               }
-                       }
-               }
-               else
-               {
-                       for (;c;c--, surf++)
-                       {
-                               if (surf->visframe == r_framecount && (!(surf->flags & SURF_PLANEBACK)))
-                               {
-                                       surf->texturechain = surf->texinfo->texture->texturechain;
-                                       surf->texinfo->texture->texturechain = surf;
-                               }
-                       }
-               }
-       }
-
-// recurse down the back side
-       // LordHavoc: save a stack frame by avoiding a call
-//     if (node->children[side]->contents != CONTENTS_SOLID && node->children[side]->visframe == r_visframecount && !R_CullBox (node->children[side]->minmaxs, node->children[side]->minmaxs+3))
-       // LordHavoc: inlined further to reduce conditions
-       if (node->children[side]->contents != CONTENTS_SOLID
-        && node->children[side]->visframe == r_visframecount
-        && frustum[0].BoxOnPlaneSideFunc(node->children[side]->minmaxs, node->children[side]->minmaxs+3, &frustum[0]) != 2
-        && frustum[1].BoxOnPlaneSideFunc(node->children[side]->minmaxs, node->children[side]->minmaxs+3, &frustum[1]) != 2
-        && frustum[2].BoxOnPlaneSideFunc(node->children[side]->minmaxs, node->children[side]->minmaxs+3, &frustum[2]) != 2
-        && frustum[3].BoxOnPlaneSideFunc(node->children[side]->minmaxs, node->children[side]->minmaxs+3, &frustum[3]) != 2)
-       {
-               node = node->children[side];
-               goto loc0;
-       }
-//             R_RecursiveWorldNode (node->children[side]);
-}
-*/
-
-extern int c_nodes;
 void R_WorldNode ()
 {
-       int             c, side;
+       int             c, side, s = 0;
        double  dot;
        struct
        {
                double dot;
                mnode_t *node;
-       } nodestack[1024];
-       int             s = 0;
+       } nodestack[8192];
        mnode_t *node;
 
        if (!(node = cl.worldmodel->nodes))
@@ -1136,7 +1202,6 @@ void R_WorldNode ()
        while(1)
        {
        // if a leaf node, draw stuff
-               c_nodes++;
                if (node->contents < 0)
                {
                        if (node->contents != CONTENTS_SOLID)
@@ -1144,6 +1209,7 @@ void R_WorldNode ()
                                mleaf_t         *pleaf;
                                pleaf = (mleaf_t *)node;
 
+                               c_leafs++;
                                if ((c = pleaf->nummarksurfaces))
                                {
                                        msurface_t      **mark;
@@ -1167,6 +1233,8 @@ void R_WorldNode ()
                        goto loc0;
                }
 
+               c_nodes++;
+
        // node is just a decision point, so go down the apropriate sides
 
        // find which side of the node we are on
@@ -1174,11 +1242,7 @@ void R_WorldNode ()
 
        // recurse down the children, front side first
                side = dot < 0;
-               if (node->children[side]->visframe == r_visframecount
-                && frustum[0].BoxOnPlaneSideFunc(node->children[side]->minmaxs, node->children[side]->minmaxs+3, &frustum[0]) != 2
-                && frustum[1].BoxOnPlaneSideFunc(node->children[side]->minmaxs, node->children[side]->minmaxs+3, &frustum[1]) != 2
-                && frustum[2].BoxOnPlaneSideFunc(node->children[side]->minmaxs, node->children[side]->minmaxs+3, &frustum[2]) != 2
-                && frustum[3].BoxOnPlaneSideFunc(node->children[side]->minmaxs, node->children[side]->minmaxs+3, &frustum[3]) != 2)
+               if (node->children[side]->visframe == r_visframecount && R_NotCulledBox(node->children[side]->minmaxs, node->children[side]->minmaxs+3))
                {
                        nodestack[s].node = node;
                        nodestack[s++].dot = dot;
@@ -1220,11 +1284,7 @@ loc0:
                }
 
        // recurse down the back side
-               if (node->children[side]->visframe == r_visframecount
-                && frustum[0].BoxOnPlaneSideFunc(node->children[side]->minmaxs, node->children[side]->minmaxs+3, &frustum[0]) != 2
-                && frustum[1].BoxOnPlaneSideFunc(node->children[side]->minmaxs, node->children[side]->minmaxs+3, &frustum[1]) != 2
-                && frustum[2].BoxOnPlaneSideFunc(node->children[side]->minmaxs, node->children[side]->minmaxs+3, &frustum[2]) != 2
-                && frustum[3].BoxOnPlaneSideFunc(node->children[side]->minmaxs, node->children[side]->minmaxs+3, &frustum[3]) != 2)
+               if (node->children[side]->visframe == r_visframecount && R_NotCulledBox(node->children[side]->minmaxs, node->children[side]->minmaxs+3))
                {
                        node = node->children[side];
                        continue;
@@ -1266,6 +1326,8 @@ void R_DrawWorld (void)
 
        glClear (GL_DEPTH_BUFFER_BIT);
 
+       R_PushDlights (); // now mark the lit surfaces
+
        DrawTextureChains ();
 
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
@@ -1518,6 +1580,165 @@ void BuildSurfaceDisplayList (msurface_t *fa)
        */
        poly->numverts = lnumverts;
 
+       /*
+       int                     i, k, lindex, lnumverts;
+       medge_t         *pedges, *r_pedge;
+       int                     vertpage, points;
+       float           *vec;
+       float           s, t;
+       glpoly_t        *poly;
+       float           point1[1024][VERTEXSIZE], point[1024][VERTEXSIZE];
+
+// reconstruct the polygon
+       pedges = currentmodel->edges;
+       lnumverts = fa->numedges;
+       vertpage = 0;
+
+       //
+       // draw texture
+       //
+       for (i=0 ; i<lnumverts ; i++)
+       {
+               lindex = currentmodel->surfedges[fa->firstedge + i];
+
+               if (lindex > 0)
+               {
+                       r_pedge = &pedges[lindex];
+                       vec = r_pcurrentvertbase[r_pedge->v[0]].position;
+               }
+               else
+               {
+                       r_pedge = &pedges[-lindex];
+                       vec = r_pcurrentvertbase[r_pedge->v[1]].position;
+               }
+               s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
+               s /= fa->texinfo->texture->width;
+
+               t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
+               t /= fa->texinfo->texture->height;
+
+               VectorCopy (vec, point1[i]);
+               point1[i][3] = s;
+               point1[i][4] = t;
+
+               //
+               // lightmap texture coordinates
+               //
+               s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
+               s -= fa->texturemins[0];
+               point1[i][7] = bound(0l, ((int)s>>4), (fa->extents[0]>>4)); // LordHavoc: raw lightmap coordinates
+               s += fa->light_s*16;
+               s += 8;
+               s /= BLOCK_WIDTH*16; //fa->texinfo->texture->width;
+
+               t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
+               t -= fa->texturemins[1];
+               point1[i][8] = bound(0l, ((int)t>>4), (fa->extents[1]>>4)); // LordHavoc: raw lightmap coordinates
+               t += fa->light_t*16;
+               t += 8;
+               t /= BLOCK_HEIGHT*16; //fa->texinfo->texture->height;
+
+               point1[i][5] = s;
+               point1[i][6] = t;
+       }
+
+       if (fa->flags & (SURF_DRAWSKY | SURF_DRAWTURB))
+       {
+               poly = Hunk_Alloc (sizeof(glpoly_t) + (lnumverts-4) * VERTEXSIZE*sizeof(float));
+               poly->next = fa->polys;
+               poly->flags = fa->flags;
+               fa->polys = poly;
+               poly->numverts = lnumverts;
+               memcpy(poly->verts, &point1[0][0], lnumverts*VERTEXSIZE*sizeof(float));
+               return;
+       }
+
+#define VectorCopy9(a,b) {for(k = 0;k < VERTEXSIZE;k++) b[k]=a[k];}
+       points = 0;
+#if 0
+       int                     j;
+       float           center[VERTEXSIZE];
+       // subdivide by placing a point at the center (more tris)
+       // LordHavoc:
+       // you, the reader, have stumbled upon the most amusing visual artifact I have
+       // encountered to date, saved here for historical/hysterical reasons :)
+       if (gl_funnywalls.value)
+               for (j = 0;j < 5;j++)
+                       center[j] = 0;
+       else
+               for (j = 0;j < VERTEXSIZE;j++)
+                       center[j] = 0;
+       for (i = 0;i < lnumverts;i++)
+               for (j = 0;j < VERTEXSIZE;j++)
+                       center[j] += point1[i][j];
+       s = 1.0f / lnumverts;
+       for (i = 0;i < VERTEXSIZE;i++)
+               center[i] *= s;
+       for (i = 0;i < lnumverts;i++)
+       {
+               VectorCopy9(center, point[points]);points++;
+               VectorCopy9(point1[i], point[points]);points++;
+               VectorCopy9(point1[(i+1)%lnumverts], point[points]);points++;
+       }
+#else
+       // subdivide by turning it into a fan (less tris)
+       for (i = 1;i < lnumverts-1;i++)
+       {
+               VectorCopy9(point1[0], point[points]);points++;
+               VectorCopy9(point1[i], point[points]);points++;
+               VectorCopy9(point1[i+1], point[points]);points++;
+       }
+#endif
+#if 0
+       {
+               float p1[VERTEXSIZE], p2[VERTEXSIZE], p3[VERTEXSIZE], p4[VERTEXSIZE], p5[VERTEXSIZE], p6[VERTEXSIZE]
+               // now subdivide any large triangles
+               for (j = 0;j < points;j+=3)
+               {
+                       if (points > (1024-9))
+                               break;
+                       while ((max(point[j][0], max(point[j+1][0], point[j+2][0])) - min(point[j][0], min(point[j+1][0], point[j+2][0]))) > 128
+                               || (max(point[j][1], max(point[j+1][1], point[j+2][1])) - min(point[j][1], min(point[j+1][1], point[j+2][1]))) > 128
+                               || (max(point[j][2], max(point[j+1][2], point[j+2][2])) - min(point[j][2], min(point[j+1][2], point[j+2][2]))) > 128)
+                       {
+                               if (points > (1024-9))
+                                       break;
+       #define halfway(v, a, b) for (k = 0;k < VERTEXSIZE;k++) v[k] = (a[k] + b[k]) * 0.5f;
+                               VectorCopy9(point[j+0], p1);
+                               VectorCopy9(point[j+1], p3);
+                               VectorCopy9(point[j+2], p5);
+                               halfway(p2, p1, p3);
+                               halfway(p4, p3, p5);
+                               halfway(p6, p5, p1);
+                               // build tri 1 (top middle)
+                               VectorCopy9(p1, point[j+0]);
+                               VectorCopy9(p2, point[j+1]);
+                               VectorCopy9(p6, point[j+2]);
+                               // build tri 2 (bottom right)
+                               VectorCopy9(p2, point[points+0]);
+                               VectorCopy9(p3, point[points+1]);
+                               VectorCopy9(p4, point[points+2]);
+                               // build tri 3 (bottom left)
+                               VectorCopy9(p4, point[points+3]);
+                               VectorCopy9(p5, point[points+4]);
+                               VectorCopy9(p6, point[points+5]);
+                               // build tri 4 (middle)
+                               VectorCopy9(p2, point[points+6]);
+                               VectorCopy9(p4, point[points+7]);
+                               VectorCopy9(p6, point[points+8]);
+                               points+=9;
+                       }
+               }
+       }
+#endif
+       poly = Hunk_Alloc (sizeof(glpoly_t) + (points-4) * VERTEXSIZE*sizeof(float));
+       poly->next = fa->polys;
+       poly->flags = fa->flags;
+       fa->polys = poly;
+       poly->numverts = 0;
+       poly->numtris = points / 3;
+       memcpy(&poly->verts[0][0], &point[0][0], points * VERTEXSIZE*sizeof(float));
+       */
 }
 
 /*
index ad3691a..43923c6 100644 (file)
@@ -838,25 +838,18 @@ SCR_UpdateScreen
 This is called every frame, and can also be called explicitly to flush
 text to the screen.
 
-WARNING: be very careful calling this from elsewhere, because the refresh
-needs almost the entire 256k of stack space!
+LordHavoc: due to my rewrite of R_WorldNode, it no longer takes 256k of stack space :)
 ==================
 */
 extern cvar_t gl_vertexarrays;
 extern qboolean gl_arrays;
 void GL_Finish();
-int c_nodes;
 void SCR_UpdateScreen (void)
 {
        double  time1 = 0, time2;
 
        if (r_speeds.value)
-       {
                time1 = Sys_FloatTime ();
-               c_brush_polys = 0;
-               c_alias_polys = 0;
-               c_nodes = 0;
-       }
 
        if (!gl_arrays)
                gl_vertexarrays.value = 0;
@@ -899,7 +892,7 @@ void SCR_UpdateScreen (void)
        if (vid.recalc_refdef)
                SCR_CalcRefdef ();
 
-       glClearColor(0,0,0,0);
+       glClearColor(1,0,0,0);
        glClear (GL_COLOR_BUFFER_BIT); // LordHavoc: clear the screen (around the view as well)
 
 //
@@ -970,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 BSPnodes\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys, currenttranspoly, c_nodes); 
+               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);
        }
        GL_EndRendering ();
 }
index 2e51ce0..555a2d1 100644 (file)
--- a/glquake.h
+++ b/glquake.h
@@ -73,36 +73,10 @@ extern      int glx, gly, glwidth, glheight;
 void R_TimeRefresh_f (void);
 void R_ReadPointFile_f (void);
 
-typedef struct surfcache_s
-{
-       struct surfcache_s      *next;
-       struct surfcache_s      **owner;                // NULL is an empty chunk of memory
-       int                                     lightadj[MAXLIGHTMAPS]; // checked for strobe flush
-       int                                     dlight;
-       int                                     size;           // including header
-       unsigned                        width;
-       unsigned                        height;         // DEBUG only needed for debug
-       float                           mipscale;
-       struct texture_s        *texture;       // checked for animating textures
-       byte                            data[4];        // width*height elements
-} surfcache_t;
-
-
-typedef struct
-{
-       pixel_t         *surfdat;       // destination for generated surface
-       msurface_t      *surf;          // description for surface to generate
-       fixed8_t        lightadj[MAXLIGHTMAPS];
-                                                       // adjust for lightmap levels for dynamic lighting
-       texture_t       *texture;       // corrected for animating textures
-       int                     surfmip;        // mipmapped ratio of surface texels / world pixels
-       int                     surfwidth;      // in mipmapped texels
-       int                     surfheight;     // in mipmapped texels
-} drawsurf_t;
 
 // LordHavoc: added dust, smoke, snow, bloodcloud, and many others
 typedef enum {
-       pt_static, pt_grav, pt_slowgrav, pt_fire, pt_explode, pt_explode2, pt_blob, pt_blob2, pt_dust, pt_smoke, pt_snow, pt_bulletpuff, pt_bloodcloud, pt_fadespark, pt_fadespark2, pt_fallfadespark, pt_fallfadespark2, pt_bubble, pt_fade
+       pt_static, pt_grav, pt_slowgrav, pt_fire, pt_explode, pt_explode2, pt_blob, pt_blob2, pt_dust, pt_smoke, pt_snow, pt_bulletpuff, pt_bloodcloud, pt_fadespark, pt_fadespark2, pt_fallfadespark, pt_fallfadespark2, pt_bubble, pt_fade, pt_smokecloud
 } ptype_t;
 
 // !!! if this is changed, it must be changed in d_ifacea.h too !!!
@@ -123,7 +97,7 @@ typedef struct particle_s
        float           alpha; // 0-255
        float           time2; // used for various things (snow fluttering, for example)
        vec3_t          vel2; // used for snow fluttering (base velocity, wind for instance)
-       vec3_t          pushvel; // temporary boost from explosions
+//     vec3_t          pushvel; // temporary boost from explosions
 } particle_t;
 
 
@@ -137,7 +111,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;
+extern int             c_brush_polys, c_alias_polys, c_light_polys, c_nodes, c_leafs;
 
 
 //
@@ -185,7 +159,6 @@ extern      cvar_t  r_waterripple;
 //extern       cvar_t  gl_polyblend;
 //extern       cvar_t  gl_keeptjunctions;
 //extern       cvar_t  gl_reporttjunctions;
-//extern       cvar_t  gl_flashblend;
 //extern       cvar_t  gl_nocolors;
 //extern       cvar_t  gl_doubleeyes;
 
@@ -306,6 +279,7 @@ extern void (*glColorTableEXT)(int, int, int, int, int, const void*);
 
 // LordHavoc: was a major time waster
 #define R_CullBox(mins,maxs) (frustum[0].BoxOnPlaneSideFunc(mins, maxs, &frustum[0]) == 2 || frustum[1].BoxOnPlaneSideFunc(mins, maxs, &frustum[1]) == 2 || frustum[2].BoxOnPlaneSideFunc(mins, maxs, &frustum[2]) == 2 || frustum[3].BoxOnPlaneSideFunc(mins, maxs, &frustum[3]) == 2)
+#define R_NotCulledBox(mins,maxs) (frustum[0].BoxOnPlaneSideFunc(mins, maxs, &frustum[0]) != 2 && frustum[1].BoxOnPlaneSideFunc(mins, maxs, &frustum[1]) != 2 && frustum[2].BoxOnPlaneSideFunc(mins, maxs, &frustum[2]) != 2 && frustum[3].BoxOnPlaneSideFunc(mins, maxs, &frustum[3]) != 2)
 
 extern qboolean fogenabled;
 extern vec3_t fogcolor;
diff --git a/host.c b/host.c
index c435335..2c9cdd5 100644 (file)
--- a/host.c
+++ b/host.c
@@ -42,6 +42,8 @@ double                realtime;                               // without any filtering or bounding
 double         oldrealtime;                    // last frame run
 int                    host_framecount;
 
+double         sv_frametime;
+
 int                    host_hunklevel;
 
 int                    minimum_memory;
@@ -479,7 +481,6 @@ not reinitialize anything.
 void Host_ClearMemory (void)
 {
        Con_DPrintf ("Clearing memory\n");
-       D_FlushCaches ();
        Mod_ClearAll ();
        if (host_hunklevel)
                Hunk_FreeToLowMark (host_hunklevel);
@@ -626,7 +627,7 @@ void Host_ServerFrame (void)
        if (!isDedicated && svs.maxclients > 1 && ((realtime - lastservertime) < sys_ticrate.value))
                return;
 // run the world state
-       pr_global_struct->frametime = frametimetotal;
+       sv_frametime = pr_global_struct->frametime = frametimetotal;
        frametimetotal = 0;
 //     pr_global_struct->frametime = host_frametime;
 
index cdd8e43..881b243 100644 (file)
--- a/mathlib.h
+++ b/mathlib.h
@@ -47,6 +47,9 @@ extern        int nanmask;
 #define CrossProduct(v1,v2,cross) {cross[0] = v1[1]*v2[2] - v1[2]*v2[1];cross[1] = v1[2]*v2[0] - v1[0]*v2[2];cross[2] = v1[0]*v2[1] - v1[1]*v2[0];}
 #define VectorNormalize(v) {float ilength;if ((ilength = sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]))) {ilength = 1/ilength;v[0] *= ilength;v[1] *= ilength;v[2] *= ilength;}}
 #define VectorNormalize2(v,dest) {float ilength;if ((ilength = sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]))) {ilength = 1/ilength;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 VectorLength(a) sqrt(DotProduct(a, a))
 
 
 void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc);
@@ -92,8 +95,8 @@ void BoxOnPlaneSideClassify(struct mplane_s *p);
        :                                                                               \
                (p)->BoxOnPlaneSideFunc( (emins), (emaxs), (p)))
 
-#define PlaneDist(point,plane) ((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal))
-#define PlaneDiff(point,plane) ((plane)->type < 3 ? (point)[(plane)->type] - (plane)->dist : DotProduct((point), (plane)->normal) - (plane)->dist)
+#define PlaneDist(point,plane)  ((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal))
+#define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist)
 
 #define lhrandom(MIN,MAX) ((rand() & 32767) * (((MAX)-(MIN)) * (1.0f / 32767.0f)) + (MIN))
 
index 40970db..84e3f8e 100644 (file)
@@ -47,8 +47,6 @@ typedef struct mplane_s
        vec3_t  normal;
        float   dist;
        byte    type;                   // for texture axis selection and fast side tests
-//     byte    signbits;               // signx + signy<<1 + signz<<2
-//     byte    pad[2];
        byte    pad[3];
        int (*BoxOnPlaneSideFunc) (vec3_t emins, vec3_t emaxs, struct mplane_s *p);
 } mplane_t;
@@ -95,8 +93,8 @@ typedef struct
        int                     flags;
 } mtexinfo_t;
 
-// LordHavoc: was 7, I added two more for raw lightmap coordinates
-#define        VERTEXSIZE      9
+// LordHavoc: was 7, I added two more for raw lightmap coordinates, and then 3 more for light accumulation
+#define        VERTEXSIZE      12
 
 typedef struct glpoly_s
 {
@@ -129,27 +127,35 @@ typedef struct msurface_s
        
 // lighting info
        int                     dlightframe;
-       int                     dlightbits[8];
+//     int                     dlightbits[8];
+
+       int                     lightframe; // avoid redundent addition of dlights
 
        int                     lightmaptexturenum;
        byte            styles[MAXLIGHTMAPS];
        int                     cached_light[MAXLIGHTMAPS];     // values currently used in lightmap
-       qboolean        cached_dlight;                          // true if dynamic light in cache
+//     qboolean        cached_dlight;                          // true if dynamic light in cache
        qboolean        cached_lighthalf;                       // LordHavoc: to cause lightmap to be rerendered when lighthalf changes
        float           cached_ambient;                         // LordHavoc: rerender lightmaps when r_ambient changes
        byte            *samples;               // [numstyles*surfsize]
 } msurface_t;
 
+// warning: if this is changed, references must be updated in cpu_* assembly files
 typedef struct mnode_s
 {
 // common with leaf
        int                     contents;               // 0, to differentiate from leafs
        int                     visframe;               // node needs to be traversed if current
+       int                     lightframe;             // LordHavoc: to avoid redundent parent chasing in R_VisMarkLights
        
        float           minmaxs[6];             // for bounding box culling
 
        struct mnode_s  *parent;
 
+       // LordHavoc: node based dynamic lighting
+       int                     dlightbits[8];
+       int                     dlightframe;
+
 // node specific
        mplane_t        *plane;
        struct mnode_s  *children[2];   
@@ -165,11 +171,16 @@ typedef struct mleaf_s
 // common with node
        int                     contents;               // wil be a negative contents number
        int                     visframe;               // node needs to be traversed if current
+       int                     lightframe;             // LordHavoc: to avoid redundent parent chasing in R_VisMarkLights
 
        float           minmaxs[6];             // for bounding box culling
 
        struct mnode_s  *parent;
 
+       // LordHavoc: node based dynamic lighting
+       int                     dlightbits[8];
+       int                     dlightframe;
+
 // leaf specific
        byte            *compressed_vis;
        efrag_t         *efrags;
index 78ec74a..b9ef1c1 100644 (file)
@@ -84,7 +84,7 @@ extern qboolean m_return_onerror;
 extern char m_return_reason[32];
 
 
-#ifdef DEBUG
+//#ifdef DEBUG
 char *StrAddr (struct qsockaddr *addr)
 {
        static char buf[34];
@@ -95,7 +95,7 @@ char *StrAddr (struct qsockaddr *addr)
                sprintf (buf + n * 2, "%02x", *p++);
        return buf;
 }
-#endif
+//#endif
 
 
 #ifdef BAN_TEST
@@ -1265,12 +1265,12 @@ static qsocket_t *_Datagram_Connect (char *host)
                                // is it from the right place?
                                if (sfunc.AddrCompare(&readaddr, &sendaddr) != 0)
                                {
-#ifdef DEBUG
-                                       Con_Printf("wrong reply address\n");
-                                       Con_Printf("Expected: %s\n", StrAddr (&sendaddr));
-                                       Con_Printf("Received: %s\n", StrAddr (&readaddr));
+//#ifdef DEBUG
+                                       Con_DPrintf("wrong reply address\n");
+                                       Con_DPrintf("Expected: %s\n", StrAddr (&sendaddr));
+                                       Con_DPrintf("Received: %s\n", StrAddr (&readaddr));
                                        SCR_UpdateScreen ();
-#endif
+//#endif
                                        ret = 0;
                                        continue;
                                }
index 8d7cecf..daa2bea 100644 (file)
@@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // protocol.h -- communications protocols
 
 #define        PROTOCOL_VERSION        15
+#define        DPPROTOCOL_VERSION      96
 
 // model effects
 #define        EF_ROCKET       1                       // leave a trail
@@ -181,6 +182,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #define svc_farclip                    50              // [coord] size (default is 6144)
 #define svc_fog                                51              // [byte] enable <optional past this point, only included if enable is true> [float] density [byte] red [byte] green [byte] blue
+#define svc_playerposition     52              // only used in dpprotocol mode
 
 //
 // client to server
index 5a8d932..8b4d26a 100644 (file)
@@ -266,6 +266,8 @@ 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
 
+extern double          sv_frametime;
+
 void Host_ClearMemory (void);
 void Host_ServerFrame (void);
 void Host_InitCommands (void);
index defa8f0..502a8ae 100644 (file)
--- a/r_light.c
+++ b/r_light.c
@@ -70,18 +70,27 @@ DYNAMIC LIGHTS
 R_MarkLights
 =============
 */
-void R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex, mnode_t *node)
+void R_OldMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex, mnode_t *node)
 {
-       float           dist, l, maxdist;
+       float           dist;
        msurface_t      *surf;
-       int                     i, j, s, t;
-       vec3_t          impact;
-       
+       int                     i;
+//     float           l, maxdist;
+//     int                     j, s, t;
+//     vec3_t          impact;
+       float cr = light->color[0];
+       float cg = light->color[1];
+       float cb = light->color[2];
+       float radius = light->radius*light->radius*16.0f;
+       float radius2 = radius * 16.0f;
+       radius -= 65536.0f; // for comparisons
+
 loc0:
        if (node->contents < 0)
                return;
 
-       dist = DotProduct (lightorigin, node->plane->normal) - node->plane->dist;
+//     dist = DotProduct (lightorigin, node->plane->normal) - node->plane->dist;
+       dist = PlaneDiff(lightorigin, node->plane);
        
        if (dist > light->radius)
        {
@@ -102,12 +111,65 @@ loc0:
                return;
        }
 
-       maxdist = light->radius*light->radius;
+       if (node->dlightframe != r_dlightframecount) // not dynamic until now
+       {
+               node->dlightbits[0] = node->dlightbits[1] = node->dlightbits[2] = node->dlightbits[3] = node->dlightbits[4] = node->dlightbits[5] = node->dlightbits[6] = node->dlightbits[7] = 0;
+               node->dlightframe = r_dlightframecount;
+       }
+       node->dlightbits[bitindex] |= bit;
+
+//     maxdist = light->radius*light->radius;
 
 // mark the polygons
        surf = cl.worldmodel->surfaces + node->firstsurface;
        for (i=0 ; i<node->numsurfaces ; i++, surf++)
        {
+               glpoly_t *p;
+               float f;
+               int j;
+               float *v;
+               if (surf->dlightframe != r_dlightframecount) // not dynamic until now
+               {
+//                     surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0;
+//                     surf->dlightframe = r_dlightframecount;
+//                     surf->dlightbits[bitindex] = bit;
+                       for (p = surf->polys;p;p = p->next)
+                       {
+                               for (j = 0, v = p->verts[0];j < p->numverts;j++, v += VERTEXSIZE)
+                               {
+                                       f = VectorDistance2(v, lightorigin);
+                                       if (f < radius)
+                                       {
+                                               surf->dlightframe = r_dlightframecount;
+                                               f = radius2 / (f + 65536.0f);
+                                               v[ 9] = cr * f;
+                                               v[10] = cg * f;
+                                               v[11] = cb * f;
+                                       }
+                                       else
+                                               v[9] = v[10] = v[11] = 0;
+                               }
+                       }
+               }
+               else
+               {
+//                     surf->dlightbits[bitindex] |= bit;
+                       for (p = surf->polys;p;p = p->next)
+                       {
+                               for (j = 0, v = p->verts[0];j < p->numverts;j++, v += VERTEXSIZE)
+                               {
+                                       f = VectorDistance2(v, lightorigin);
+                                       if (f < radius)
+                                       {
+                                               f = radius2 / (f + 65536.0f);
+                                               v[ 9] += cr * f;
+                                               v[10] += cg * f;
+                                               v[11] += cb * f;
+                                       }
+                               }
+                       }
+               }
+/*
                if (surf->flags & SURF_DRAWTURB) // water
                {
                        if (surf->dlightframe != r_dlightframecount) // not dynamic until now
@@ -118,7 +180,8 @@ loc0:
                        surf->dlightbits[bitindex] |= bit;
                }
                // LordHavoc: MAJOR dynamic light speedup here, eliminates marking of surfaces that are too far away from light, thus preventing unnecessary uploads
-               else /*if (r_dynamicbothsides.value || (((surf->flags & SURF_PLANEBACK) && (dist < -BACKFACE_EPSILON)) || (!(surf->flags & SURF_PLANEBACK) && (dist > BACKFACE_EPSILON))))*/
+//             else if (r_dynamicbothsides.value || (((surf->flags & SURF_PLANEBACK) && (dist < -BACKFACE_EPSILON)) || (!(surf->flags & SURF_PLANEBACK) && (dist > BACKFACE_EPSILON))))
+               else if (((surf->flags & SURF_PLANEBACK) != 0) != (dist >= 0))
                {
                        // passed the plane side check
                        for (j=0 ; j<3 ; j++)
@@ -142,13 +205,14 @@ loc0:
                                surf->dlightbits[bitindex] |= bit;
                        }
                }
+*/
        }
 
        if (node->children[0]->contents >= 0)
        {
                if (node->children[1]->contents >= 0)
                {
-                       R_MarkLights (lightorigin, light, bit, bitindex, node->children[0]);
+                       R_OldMarkLights (lightorigin, light, bit, bitindex, node->children[0]);
                        node = node->children[1];
                        goto loc0;
                }
@@ -165,6 +229,125 @@ loc0:
        }
 }
 
+void R_VisMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex, model_t *model)
+{
+       mleaf_t *pvsleaf = Mod_PointInLeaf (lightorigin, model);
+
+       if (!pvsleaf->compressed_vis)
+       {       // no vis info, so make all visible
+               R_OldMarkLights(lightorigin, light, bit, bitindex, model->nodes + model->hulls[0].firstclipnode);
+               return;
+       }
+       else
+       {
+               int             i, j, k, l, m, c;
+               msurface_t *surf, **mark;
+               mleaf_t *leaf;
+               static int lightframe = 0;
+               byte    *in = pvsleaf->compressed_vis;
+               int             row = (model->numleafs+7)>>3;
+               float   cr = light->color[0];
+               float   cg = light->color[1];
+               float   cb = light->color[2];
+               float   radius = light->radius*light->radius*16.0f;
+               float   radius2 = radius * 16.0f;
+               glpoly_t *p;
+               float f;
+               float *v;
+
+               lightframe++;
+               k = 0;
+               while (k < row)
+               {
+                       c = *in++;
+                       if (c)
+                       {
+                               l = model->numleafs - (k << 3);
+                               if (l > 8)
+                                       l = 8;
+                               for (i=0 ; i<l ; i++)
+                               {
+                                       if (c & (1<<i))
+                                       {
+                                               leaf = &model->leafs[(k << 3)+i+1];
+                                               if (leaf->visframe != r_visframecount)
+                                                       continue;
+                                               if (leaf->contents == CONTENTS_SOLID)
+                                                       continue;
+                                               leaf->lightframe = lightframe;
+                                               if (leaf->dlightframe != r_dlightframecount) // not dynamic until now
+                                               {
+                                                       leaf->dlightbits[0] = leaf->dlightbits[1] = leaf->dlightbits[2] = leaf->dlightbits[3] = leaf->dlightbits[4] = leaf->dlightbits[5] = leaf->dlightbits[6] = leaf->dlightbits[7] = 0;
+                                                       leaf->dlightframe = r_dlightframecount;
+                                               }
+                                               leaf->dlightbits[bitindex] |= bit;
+                                               if ((m = leaf->nummarksurfaces))
+                                               {
+                                                       mark = leaf->firstmarksurface;
+                                                       do
+                                                       {
+                                                               surf = *mark++;
+                                                               if (surf->visframe != r_framecount || surf->lightframe == lightframe)
+                                                                       continue;
+                                                               surf->lightframe = lightframe;
+//                                                             if (((surf->flags & SURF_PLANEBACK) == 0) == ((PlaneDiff(lightorigin, surf->plane)) >= 0))
+//                                                             {
+                                                                       if (surf->dlightframe != r_dlightframecount) // not dynamic until now
+                                                                       {
+//                                                                             surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0;
+//                                                                             surf->dlightframe = r_dlightframecount;
+//                                                                             surf->dlightbits[bitindex] = bit;
+                                                                               for (p = surf->polys;p;p = p->next)
+                                                                               {
+                                                                                       for (j = 0, v = p->verts[0];j < p->numverts;j++, v += VERTEXSIZE)
+                                                                                       {
+                                                                                               f = VectorDistance2(v, lightorigin);
+                                                                                               if (f < radius)
+                                                                                               {
+                                                                                                       surf->dlightframe = r_dlightframecount;
+                                                                                                       f = radius2 / (f + 65536.0f);
+                                                                                                       v[ 9] = cr * f;
+                                                                                                       v[10] = cg * f;
+                                                                                                       v[11] = cb * f;
+                                                                                               }
+                                                                                               else
+                                                                                                       v[9] = v[10] = v[11] = 0;
+                                                                                       }
+                                                                               }
+                                                                       }
+                                                                       else
+                                                                       {
+//                                                                             surf->dlightbits[bitindex] |= bit;
+                                                                               for (p = surf->polys;p;p = p->next)
+                                                                               {
+                                                                                       for (j = 0, v = p->verts[0];j < p->numverts;j++, v += VERTEXSIZE)
+                                                                                       {
+                                                                                               f = VectorDistance2(v, lightorigin);
+                                                                                               if (f < radius)
+                                                                                               {
+                                                                                                       f = radius2 / (f + 65536.0f);
+                                                                                                       v[ 9] += cr * f;
+                                                                                                       v[10] += cg * f;
+                                                                                                       v[11] += cb * f;
+                                                                                               }
+                                                                                       }
+                                                                               }
+                                                                       }
+//                                                             }
+                                                       }
+                                                       while (--m);
+                                               }
+                                       }
+                               }
+                               k++;
+                               continue;
+                       }
+               
+                       k += *in++;
+               }
+       }
+}
+
 
 /*
 =============
@@ -178,7 +361,7 @@ void R_PushDlights (void)
 
        r_dlightframecount = r_framecount + 1;  // because the count hasn't advanced yet for this frame
 
-       if (/*gl_flashblend.value ||*/ !r_dynamic.value)
+       if (!r_dynamic.value)
                return;
 
        l = cl_dlights;
@@ -187,7 +370,8 @@ void R_PushDlights (void)
        {
                if (l->die < cl.time || !l->radius)
                        continue;
-               R_MarkLights (l->origin, l, 1<<(i&31), i >> 5, cl.worldmodel->nodes );
+//             R_MarkLights (l->origin, l, 1<<(i&31), i >> 5, cl.worldmodel->nodes );
+               R_VisMarkLights (l->origin, l, 1<<(i&31), i >> 5, cl.worldmodel);
        }
 }
 
@@ -312,28 +496,33 @@ void R_LightPoint (vec3_t color, vec3_t p)
 // LordHavoc: R_DynamicLightPoint - acumulates the dynamic lighting
 void R_DynamicLightPoint(vec3_t color, vec3_t org, int *dlightbits)
 {
-       int             i;
+       int             i, j, k;
        vec3_t  dist;
        float   brightness, r, f;
 
-       if (/*gl_flashblend.value ||*/ !r_dynamic.value || (!dlightbits[0] && !dlightbits[1] && !dlightbits[2] && !dlightbits[3] && !dlightbits[4] && !dlightbits[5] && !dlightbits[6] && !dlightbits[7]))
+       if (!r_dynamic.value || (!dlightbits[0] && !dlightbits[1] && !dlightbits[2] && !dlightbits[3] && !dlightbits[4] && !dlightbits[5] && !dlightbits[6] && !dlightbits[7]))
                return;
 
-       for (i=0 ; i<MAX_DLIGHTS ; i++)
+       for (j = 0;j < (MAX_DLIGHTS >> 5);j++)
        {
-               if (!((1 << (i&31)) & dlightbits[i>>5]))
-                       continue;
-               if (cl_dlights[i].die < cl.time || !cl_dlights[i].radius)
-                       continue;
-               VectorSubtract (org, cl_dlights[i].origin, dist);
-               if ((f = DotProduct(dist, dist) + 64.0) < (r = cl_dlights[i].radius*cl_dlights[i].radius))
+               if (dlightbits[j])
                {
-                       brightness = r * 16.0 / f;
-                       if (cl_dlights[i].dark)
-                               brightness = -brightness;
-                       color[0] += brightness * cl_dlights[i].color[0];
-                       color[1] += brightness * cl_dlights[i].color[1];
-                       color[2] += brightness * cl_dlights[i].color[2];
+                       for (i=0 ; i<32 ; i++)
+                       {
+                               if ((!((1 << (i&31)) & dlightbits[i>>5])) || cl_dlights[i].die < cl.time || !cl_dlights[i].radius)
+                                       continue;
+                               k = (j<<5)+i;
+                               VectorSubtract (org, cl_dlights[k].origin, dist);
+                               f = DotProduct(dist, dist) + 65536.0f;
+                               r = cl_dlights[k].radius*cl_dlights[k].radius*16.0f;
+                               if (f < r)
+                               {
+                                       brightness = r * 16.0f / f;
+                                       color[0] += brightness * cl_dlights[k].color[0];
+                                       color[1] += brightness * cl_dlights[k].color[1];
+                                       color[2] += brightness * cl_dlights[k].color[2];
+                               }
+                       }
                }
        }
 }
@@ -345,7 +534,7 @@ void R_DynamicLightPointNoMask(vec3_t color, vec3_t org)
        vec3_t  dist;
        float   brightness, r, f;
 
-       if (/*gl_flashblend.value ||*/ !r_dynamic.value)
+       if (!r_dynamic.value)
                return;
 
        for (i=0 ; i<MAX_DLIGHTS ; i++)
@@ -353,9 +542,11 @@ void R_DynamicLightPointNoMask(vec3_t color, vec3_t org)
                if (cl_dlights[i].die < cl.time || !cl_dlights[i].radius)
                        continue;
                VectorSubtract (org, cl_dlights[i].origin, dist);
-               if ((f = DotProduct(dist, dist) + 64.0) < (r = cl_dlights[i].radius*cl_dlights[i].radius))
+               f = DotProduct(dist, dist) + 65536.0f;
+               r = cl_dlights[i].radius*cl_dlights[i].radius*16.0f;
+               if (f < r)
                {
-                       brightness = r * 16.0 / f;
+                       brightness = r * 16.0f / f;
                        if (cl_dlights[i].dark)
                                brightness = -brightness;
                        color[0] += brightness * cl_dlights[i].color[0];
@@ -377,6 +568,7 @@ extern byte *aliasvertcolor;
 extern vec_t shadecolor[];
 extern float modelalpha;
 extern qboolean lighthalf;
+extern int modeldlightbits[8];
 void R_LightModel(int numverts, vec3_t center)
 {
        int i, j, nearlights = 0;
@@ -424,28 +616,31 @@ void R_LightModel(int numverts, vec3_t center)
        {
                for (i = 0;i < MAX_DLIGHTS;i++)
                {
-                       if (cl_dlights[i].die < cl.time || !cl_dlights[i].radius)
+                       if (!modeldlightbits[i >> 5])
+                       {
+                               i |= 31;
+                               continue;
+                       }
+                       if (!(modeldlightbits[i >> 5] & (1 << (i & 31))))
                                continue;
+//                     if (cl_dlights[i].die < cl.time || !cl_dlights[i].radius)
+//                             continue;
                        VectorSubtract (center, cl_dlights[i].origin, dist);
-                       if ((t2 = DotProduct(dist,dist) + 16.0f) + 64.0f < (t1 = cl_dlights[i].radius*cl_dlights[i].radius))
+                       t1 = cl_dlights[i].radius*cl_dlights[i].radius*16.0f;
+                       t2 = DotProduct(dist,dist) + 65536.0f;
+                       if (t2 < t1)
                        {
                                VectorCopy(cl_dlights[i].origin, nearlight[nearlights].origin);
                                nearlight[nearlights].color[0] = cl_dlights[i].color[0] * cl_dlights[i].radius * cl_dlights[i].radius * 0.5f;
                                nearlight[nearlights].color[1] = cl_dlights[i].color[1] * cl_dlights[i].radius * cl_dlights[i].radius * 0.5f;
                                nearlight[nearlights].color[2] = cl_dlights[i].color[2] * cl_dlights[i].radius * cl_dlights[i].radius * 0.5f;
-                               if (cl_dlights[i].dark)
-                               {
-                                       nearlight[nearlights].color[0] = -nearlight[nearlights].color[0];
-                                       nearlight[nearlights].color[1] = -nearlight[nearlights].color[1];
-                                       nearlight[nearlights].color[2] = -nearlight[nearlights].color[2];
-                               }
                                if (lighthalf)
                                {
                                        nearlight[nearlights].color[0] *= 0.5f;
                                        nearlight[nearlights].color[1] *= 0.5f;
                                        nearlight[nearlights].color[2] *= 0.5f;
                                }
-                               t1 = 1.0f / t2;
+                               t1 = 0.5f / t2;
                                shadecolor[0] += nearlight[nearlights].color[0] * t1;
                                shadecolor[1] += nearlight[nearlights].color[1] * t1;
                                shadecolor[2] += nearlight[nearlights].color[2] * t1;
@@ -460,27 +655,30 @@ void R_LightModel(int numverts, vec3_t center)
        {
                for (i = 0;i < MAX_DLIGHTS;i++)
                {
-                       if (cl_dlights[i].die < cl.time || !cl_dlights[i].radius)
+                       if (!modeldlightbits[i >> 5])
+                       {
+                               i |= 31;
                                continue;
+                       }
+                       if (!(modeldlightbits[i >> 5] & (1 << (i & 31))))
+                               continue;
+//                     if (cl_dlights[i].die < cl.time || !cl_dlights[i].radius)
+//                             continue;
                        VectorSubtract (center, cl_dlights[i].origin, dist);
-                       if ((t2 = DotProduct(dist,dist)) + 64.0f < (t1 = cl_dlights[i].radius*cl_dlights[i].radius))
+                       t2 = DotProduct(dist,dist) + 65536.0f;
+                       t1 = cl_dlights[i].radius*cl_dlights[i].radius*16.0f;
+                       if (t2 < t1)
                        {
                                dist[0] = cl_dlights[i].color[0] * cl_dlights[i].radius * cl_dlights[i].radius * 0.5f;
                                dist[1] = cl_dlights[i].color[1] * cl_dlights[i].radius * cl_dlights[i].radius * 0.5f;
                                dist[2] = cl_dlights[i].color[2] * cl_dlights[i].radius * cl_dlights[i].radius * 0.5f;
-                               if (cl_dlights[i].dark)
-                               {
-                                       dist[0] = -dist[0];
-                                       dist[1] = -dist[1];
-                                       dist[2] = -dist[2];
-                               }
                                if (lighthalf)
                                {
                                        dist[0] *= 0.5f;
                                        dist[1] *= 0.5f;
                                        dist[2] *= 0.5f;
                                }
-                               t1 = 1.5f / t2;
+                               t1 = 0.75f / t2;
                                shadecolor[0] += dist[0] * t1;
                                shadecolor[1] += dist[1] * t1;
                                shadecolor[2] += dist[2] * t1;
index 12a5a60..b443d83 100644 (file)
--- a/r_part.c
+++ b/r_part.c
@@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "quakedef.h"
 
-#define MAX_PARTICLES                  4096    // default max # of particles at one
+#define MAX_PARTICLES                  32768   // default max # of particles at one
                                                                                //  time
 #define ABSOLUTE_MIN_PARTICLES 512             // no fewer than this no matter what's
                                                                                //  on the command line
@@ -348,7 +348,7 @@ avelocities[0][i] = (rand()&255) * 0.01;
 
                ALLOCPARTICLE
 
-               p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = p->vel[0] = p->vel[1] = p->vel[2] = 0;
+//             p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = p->vel[0] = p->vel[1] = p->vel[2] = 0;
                p->texnum = flareparticletexture;
                p->scale = 2;
                p->alpha = 255;
@@ -421,7 +421,7 @@ void R_ReadPointFile_f (void)
                p->die = 99999;
                p->color = (-c)&15;
                p->type = pt_static;
-               p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = p->vel[0] = p->vel[1] = p->vel[2] = 0;
+//             p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = p->vel[0] = p->vel[1] = p->vel[2] = 0;
                VectorCopy (org, p->org);
        }
 
@@ -436,6 +436,7 @@ R_BlastParticles
 LordHavoc: blasts away particles in the area, used for explosions to disturb the smoke trail and such
 ===============
 */
+/*
 void R_BlastParticles(vec3_t org, vec_t radius, vec_t power)
 {
        vec3_t v;
@@ -457,6 +458,7 @@ void R_BlastParticles(vec3_t org, vec_t radius, vec_t power)
                p = p->next;
        }
 }
+*/
 
 /*
 ===============
@@ -496,12 +498,13 @@ void R_ParticleExplosion (vec3_t org, int smoke)
        int                     i, j;
        particle_t      *p;
        if (!r_particles.value) return; // LordHavoc: particles are optional
-       
+
+       /*
        for (i=0 ; i<1024 ; i++)
        {
                ALLOCPARTICLE
 
-               p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
+//             p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
                p->texnum = particletexture;
                p->scale = lhrandom(1,3);
                p->alpha = rand()&255;
@@ -521,6 +524,7 @@ void R_ParticleExplosion (vec3_t org, int smoke)
                }
                p->vel[2] += 160;
        }
+       */
 
        i = Mod_PointInLeaf(org, cl.worldmodel)->contents;
        if (i == CONTENTS_SLIME || i == CONTENTS_WATER)
@@ -529,7 +533,7 @@ void R_ParticleExplosion (vec3_t org, int smoke)
                {
                        ALLOCPARTICLE
 
-                       p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
+//                     p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
                        p->texnum = bubbleparticletexture;
                        p->scale = lhrandom(1,2);
                        p->alpha = 255;
@@ -543,26 +547,29 @@ void R_ParticleExplosion (vec3_t org, int smoke)
                        }
                }
        }
-       else if (smoke)
+       else // if (smoke)
        {
-               for (i=0 ; i<32 ; i++)
-               {
+//             for (i=0 ; i<32 ; i++)
+//             {
                        ALLOCPARTICLE
 
-                       p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
+//                     p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
                        p->texnum = smokeparticletexture[rand()&7];
-                       p->scale = 12;
-                       p->alpha = 80;
+//                     p->scale = 12;
+                       p->scale = 30;
+                       p->alpha = 96;
                        p->die = cl.time + 2;
-                       p->type = pt_smoke;
+                       p->type = pt_smokecloud;
                        p->color = (rand()&7) + 8;
                        for (j=0 ; j<3 ; j++)
                        {
-                               p->org[j] = org[j] + ((rand()%96)-48);
-                               p->vel[j] = (rand()&63)-32;
+//                             p->org[j] = org[j] + ((rand()%96)-48);
+//                             p->vel[j] = (rand()&63)-32;
+                               p->org[j] = org[j];
+                               p->vel[j] = 0;
                        }
                }
-       }
+//     }
 }
 
 /*
@@ -582,8 +589,8 @@ void R_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength)
        {
                ALLOCPARTICLE
 
-               p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
-               p->texnum = smokeparticletexture[rand()&7];
+//             p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
+               p->texnum = particletexture;
                p->scale = 1.5;
                p->alpha = 255;
                p->die = cl.time + 0.3;
@@ -615,8 +622,8 @@ void R_BlobExplosion (vec3_t org)
        {
                ALLOCPARTICLE
 
-               p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
-               p->texnum = smokeparticletexture[rand()&7];
+//             p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
+               p->texnum = particletexture;
                p->scale = 2;
                p->alpha = 255;
                p->die = cl.time + 1 + (rand()&8)*0.05;
@@ -677,7 +684,7 @@ void R_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count)
                        count -= 8;
                }
 
-               p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
+//             p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
                p->texnum = particletexture;
                p->scale = 6;
                p->die = cl.time + 1; //lhrandom(0.1, 0.5);
@@ -705,12 +712,12 @@ void R_SparkShower (vec3_t org, vec3_t dir, int count, int type)
        if (!r_particles.value) return; // LordHavoc: particles are optional
 
        ALLOCPARTICLE
-       p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
+//     p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
        if (type == 0) // sparks
        {
                p->texnum = smokeparticletexture[rand()&7];
-               p->scale = 15;
-               p->alpha = 64;
+               p->scale = 10;
+               p->alpha = 48;
                p->color = (rand()&3)+12;
                p->type = pt_bulletpuff;
                p->die = cl.time + 1;
@@ -733,10 +740,10 @@ void R_SparkShower (vec3_t org, vec3_t dir, int count, int type)
        {
                ALLOCPARTICLE
 
-               p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
+//             p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
                p->texnum = flareparticletexture;
                p->scale = 2;
-               p->alpha = 255;
+               p->alpha = 192;
                p->die = cl.time + 0.0625 * (rand()&15);
                /*
                if (type == 0) // sparks
@@ -787,7 +794,7 @@ void R_BloodShower (vec3_t mins, vec3_t maxs, float velspeed, int count)
        {
                ALLOCPARTICLE
 
-               p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
+//             p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
                p->texnum = bloodcloudparticletexture;
                p->scale = 12;
                p->alpha = 96 + (rand()&63);
@@ -820,7 +827,7 @@ void R_ParticleCube (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int colorb
        {
                ALLOCPARTICLE
 
-               p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
+//             p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
                p->texnum = flareparticletexture;
                p->scale = 6;
                p->alpha = 255;
@@ -880,7 +887,7 @@ void R_ParticleRain (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int colorb
                org[1] = diff[1] * (float) (rand()&1023) * (1.0 / 1024.0) + mins[1];
                org[2] = z;
 
-               p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
+//             p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
                p->scale = 1.5;
                p->alpha = 255;
                p->die = t;
@@ -922,7 +929,7 @@ void R_LavaSplash (vec3_t org)
                        {
                                ALLOCPARTICLE
                
-                               p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
+//                             p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
                                p->texnum = flareparticletexture;
                                p->scale = 10;
                                p->alpha = 128;
@@ -964,7 +971,7 @@ void R_TeleportSplash (vec3_t org)
                        {
                                ALLOCPARTICLE
                
-                               p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
+//                             p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
                                p->contents = 0;
                                p->texnum = particletexture;
                                p->scale = 2;
@@ -993,7 +1000,7 @@ void R_TeleportSplash (vec3_t org)
                        {
                                ALLOCPARTICLE
                
-                               p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
+//                             p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
                                p->texnum = flareparticletexture;
                                p->scale = 4;
                                p->alpha = lhrandom(32,256);
@@ -1045,7 +1052,8 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
        {
                ALLOCPARTICLE
                
-               p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = p->vel[0] = p->vel[1] = p->vel[2] = 0;
+//             p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
+               p->vel[0] = p->vel[1] = p->vel[2] = 0;
                p->die = cl.time + 2;
 
                switch (type)
@@ -1071,7 +1079,7 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
                                {
                                        dec = 0.02f;
                                        p->texnum = smokeparticletexture[rand()&7];
-                                       p->scale = lhrandom(6, 10);
+                                       p->scale = lhrandom(8, 12);
                                        p->alpha = 64 + (rand()&31);
                                        p->color = (rand()&3)+12;
                                        p->type = pt_smoke;
@@ -1103,7 +1111,7 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
                                p->alpha = 255;
                                p->color = (rand()&3)+68;
                                p->type = pt_bloodcloud;
-                               p->die = cl.time + 2;
+                               p->die = cl.time + 9999;
                                for (j=0 ; j<3 ; j++)
                                {
                                        p->vel[j] = (rand()&15)-8;
@@ -1146,7 +1154,7 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
                                p->alpha = 192;
                                p->color = (rand()&3)+68;
                                p->type = pt_fadespark2;
-                               p->die = cl.time + 2;
+                               p->die = cl.time + 9999;
                                for (j=0 ; j<3 ; j++)
                                {
                                        p->vel[j] = (rand()&15)-8;
@@ -1204,7 +1212,8 @@ void R_RocketTrail2 (vec3_t start, vec3_t end, int color, entity_t *ent)
 
                ALLOCPARTICLE
                
-               p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = p->vel[0] = p->vel[1] = p->vel[2] = 0;
+//             p->pushvel[0] = p->pushvel[1] = p->pushvel[2] = 0;
+               p->vel[0] = p->vel[1] = p->vel[2] = 0;
 
                p->texnum = flareparticletexture;
                p->scale = 8;
@@ -1235,9 +1244,9 @@ void R_DrawParticles (void)
 {
        particle_t              *p, *kill;
        int                             i, r,g,b,a;
-       float                   grav, grav1, time1, time2, time3, dvel, frametime, scale, scale2, f1, f2;
+       float                   grav, grav1, time1, time2, time3, dvel, frametime, scale, scale2/*, f1, f2*/, minparticledist;
        byte                    *color24;
-       vec3_t                  up, right, uprightangles, forward2, up2, right2, v, tempcolor;
+       vec3_t                  up, right, uprightangles, forward2, up2, right2, tempcolor;
 
        // LordHavoc: early out condition
        if (!active_particles)
@@ -1258,6 +1267,9 @@ void R_DrawParticles (void)
        grav = (grav1 = frametime * sv_gravity.value) * 0.05;
        dvel = 1+4*frametime;
 
+       minparticledist = DotProduct(r_refdef.vieworg, vpn) + 16.0f;
+
+       // remove dead particles at beginning of list
        for ( ;; ) 
        {
                kill = active_particles;
@@ -1273,6 +1285,7 @@ void R_DrawParticles (void)
 
        for (p=active_particles ; p ; p=p->next)
        {
+               // remove dead particles following this one
                for ( ;; )
                {
                        kill = p->next;
@@ -1285,14 +1298,10 @@ void R_DrawParticles (void)
                        }
                        break;
                }
-               // LordHavoc: 'removed last in list' condition
-               if (!p)
-                       break;
 
-               VectorSubtract(p->org, r_refdef.vieworg, v);
-               if (DotProduct(v, v) >= 256.0f)
+               // LordHavoc: only render if not too close
+               if (DotProduct(p->org, vpn) >= minparticledist)
                {
-                       scale = p->scale * -0.5;scale2 = p->scale * 0.5;
                        color24 = (byte *) &d_8to24table[(int)p->color];
                        r = color24[0];
                        g = color24[1];
@@ -1312,6 +1321,7 @@ void R_DrawParticles (void)
                                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);
@@ -1329,6 +1339,7 @@ void R_DrawParticles (void)
                        transpolyend();
                }
 
+               /*
                if (p->pushvel[0] || p->pushvel[1] || p->pushvel[2])
                {
                        p->org[0] += (p->vel[0]+p->pushvel[0])*frametime;
@@ -1348,10 +1359,16 @@ void R_DrawParticles (void)
                }
                else
                {
-                       p->org[0] += p->vel[0]*frametime;
-                       p->org[1] += p->vel[1]*frametime;
-                       p->org[2] += p->vel[2]*frametime;
+                       if (p->type != pt_smokecloud)
+                       {
+               */
+                               p->org[0] += p->vel[0]*frametime;
+                               p->org[1] += p->vel[1]*frametime;
+                               p->org[2] += p->vel[2]*frametime;
+               /*
+                       }
                }
+               */
                
                switch (p->type)
                {
@@ -1413,7 +1430,8 @@ void R_DrawParticles (void)
                case pt_dust:
                        p->ramp += time1;
                        p->scale -= frametime * 4;
-                       if (p->ramp >= 8 || p->scale <= 0)
+                       p->alpha -= frametime * 48;
+                       if (p->ramp >= 8 || p->scale < 1 || p->alpha < 1)
                                p->die = -1;
                        else
                                p->color = ramp3[(int)p->ramp];
@@ -1421,7 +1439,7 @@ void R_DrawParticles (void)
                        break;
 // LordHavoc: for smoke trails
                case pt_smoke:
-                       p->scale += frametime * 4;
+                       p->scale += frametime * 6;
                        p->alpha -= frametime * 128;
 //                     p->vel[2] += grav;
                        if (p->alpha < 1)
@@ -1444,6 +1462,11 @@ void R_DrawParticles (void)
                                p->die = -1;
                        break;
                case pt_bloodcloud:
+                       if (Mod_PointInLeaf(p->org, cl.worldmodel)->contents != CONTENTS_EMPTY)
+                       {
+                               p->die = -1;
+                               break;
+                       }
                        p->scale += frametime * 4;
                        p->alpha -= frametime * 64;
                        p->vel[2] -= grav;
@@ -1495,6 +1518,12 @@ void R_DrawParticles (void)
                        if (p->alpha < 1)
                                p->die = -1;
                        break;
+               case pt_smokecloud:
+                       p->scale += frametime * 60;
+                       p->alpha -= frametime * 96;
+                       if (p->alpha < 1)
+                               p->die = -1;
+                       break;
                }
        }
 }
index 5f5d224..9495016 100644 (file)
--- a/render.h
+++ b/render.h
@@ -120,7 +120,6 @@ typedef struct
 //
 // refresh
 //
-extern int             reinit_surfcache;
 
 
 extern refdef_t        r_refdef;
@@ -162,17 +161,3 @@ void R_LavaSplash (vec3_t org);
 void R_TeleportSplash (vec3_t org);
 
 void R_PushDlights (void);
-
-
-//
-// surface cache related
-//
-extern int             reinit_surfcache;       // if 1, surface cache is currently empty and
-extern qboolean        r_cache_thrash; // set if thrashing the surface cache
-
-int    D_SurfaceCacheForRes (int width, int height);
-void D_FlushCaches (void);
-void D_DeleteSurfaceCache (void);
-void D_InitCaches (void *buffer, int size);
-void R_SetVrect (vrect_t *pvrect, vrect_t *pvrectin, int lineadj);
-
diff --git a/sbar.c b/sbar.c
index 2d69abe..d429f69 100644 (file)
--- a/sbar.c
+++ b/sbar.c
@@ -75,7 +75,6 @@ void Sbar_ShowScores (void)
        if (sb_showscores)
                return;
        sb_showscores = true;
-//     sb_updates = 0;
 }
 
 /*
@@ -88,19 +87,8 @@ Tab key up
 void Sbar_DontShowScores (void)
 {
        sb_showscores = false;
-//     sb_updates = 0;
 }
 
-/*
-===============
-Sbar_Changed
-===============
-*/
-//void Sbar_Changed (void)
-//{
-//     sb_updates = 0; // update next frame
-//}
-
 /*
 ===============
 Sbar_Init
@@ -420,11 +408,6 @@ void Sbar_SortFrags (void)
                        }
 }
 
-int    Sbar_ColorForMap (int m)
-{
-       return m < 128 ? m + 8 : m + 8;
-}
-
 /*
 ===============
 Sbar_UpdateScoreboard
@@ -449,8 +432,8 @@ void Sbar_UpdateScoreboard (void)
 
                top = s->colors & 0xf0;
                bottom = (s->colors & 15) <<4;
-               scoreboardtop[i] = Sbar_ColorForMap (top);
-               scoreboardbottom[i] = Sbar_ColorForMap (bottom);
+               scoreboardtop[i] = top + 8;
+               scoreboardbottom[i] = bottom + 8;
        }
 }
 
@@ -496,51 +479,6 @@ void Sbar_DrawScoreboard (void)
        Sbar_SoloScoreboard ();
        if (cl.gametype == GAME_DEATHMATCH)
                Sbar_DeathmatchOverlay ();
-#if 0
-       int             i, j, c;
-       int             x, y;
-       int             l;
-       int             top, bottom;
-       scoreboard_t    *s;
-
-       if (cl.gametype != GAME_DEATHMATCH)
-       {
-               Sbar_SoloScoreboard ();
-               return;
-       }
-
-       Sbar_UpdateScoreboard ();
-
-       l = scoreboardlines <= 6 ? scoreboardlines : 6;
-
-       for (i=0 ; i<l ; i++)
-       {
-               x = 20*(i&1);
-               y = i/2 * 8;
-
-               s = &cl.scores[fragsort[i]];
-               if (!s->name[0])
-                       continue;
-
-       // draw background
-               top = s->colors & 0xf0;
-               bottom = (s->colors & 15)<<4;
-               top = Sbar_ColorForMap (top);
-               bottom = Sbar_ColorForMap (bottom);
-
-               Draw_Fill ( x*8+10 + ((vid.width - 320)>>1), y + vid.height - SBAR_HEIGHT, 28, 4, top);
-               Draw_Fill ( x*8+10 + ((vid.width - 320)>>1), y+4 + vid.height - SBAR_HEIGHT, 28, 4, bottom);
-
-       // draw text
-               for (j=0 ; j<20 ; j++)
-               {
-                       c = scoreboardtext[i][j];
-                       if (c == 0 || c == ' ')
-                               continue;
-                       Sbar_DrawCharacter ( (x+j)*8, y, c);
-               }
-       }
-#endif
 }
 
 //=============================================================================
@@ -565,11 +503,9 @@ void Sbar_DrawInventory (void)
                        Sbar_DrawAlphaPic (0, -24, rsb_invbar[1], 0.4);
        }
        else
-       {
                Sbar_DrawAlphaPic (0, -24, sb_ibar, 0.4);
-       }
 
-// weapons
+       // weapons
        for (i=0 ; i<7 ; i++)
        {
                if (cl.items & (IT_SHOTGUN<<i) )
@@ -586,86 +522,69 @@ void Sbar_DrawInventory (void)
                        else
                                flashon = (flashon%5) + 2;
 
-         Sbar_DrawAlphaPic (i*24, -16, sb_weapons[flashon][i], 0.4);
-
-//                     if (flashon > 1)
-//                             sb_updates = 0;         // force update to remove flash
+                       Sbar_DrawAlphaPic (i*24, -16, sb_weapons[flashon][i], 0.4);
                }
        }
 
-// MED 01/04/97
-// hipnotic weapons
-    if (hipnotic)
-    {
-      int grenadeflashing=0;
-      for (i=0 ; i<4 ; i++)
-      {
-         if (cl.items & (1<<hipweapons[i]) )
-         {
-            time = cl.item_gettime[hipweapons[i]];
-            flashon = (int)((cl.time - time)*10);
-            if (flashon >= 10)
-            {
-               if ( cl.stats[STAT_ACTIVEWEAPON] == (1<<hipweapons[i])  )
-                  flashon = 1;
-               else
-                  flashon = 0;
-            }
-            else
-               flashon = (flashon%5) + 2;
-
-            // check grenade launcher
-            if (i==2)
-            {
-               if (cl.items & HIT_PROXIMITY_GUN)
-               {
-                  if (flashon)
-                  {
-                     grenadeflashing = 1;
-                     Sbar_DrawPic (96, -16, hsb_weapons[flashon][2]);
-                  }
-               }
-            }
-            else if (i==3)
-            {
-               if (cl.items & (IT_SHOTGUN<<4))
-               {
-                  if (flashon && !grenadeflashing)
-                  {
-                     Sbar_DrawPic (96, -16, hsb_weapons[flashon][3]);
-                  }
-                  else if (!grenadeflashing)
-                  {
-                     Sbar_DrawPic (96, -16, hsb_weapons[0][3]);
-                  }
-               }
-               else
-                  Sbar_DrawPic (96, -16, hsb_weapons[flashon][4]);
-            }
-            else
-               Sbar_DrawPic (176 + (i*24), -16, hsb_weapons[flashon][i]);
-//            if (flashon > 1)
-//               sb_updates = 0;      // force update to remove flash
-         }
-      }
-    }
-
-       if (rogue)
+       // MED 01/04/97
+       // hipnotic weapons
+       if (hipnotic)
        {
-    // check for powered up weapon.
-               if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
+               int grenadeflashing=0;
+               for (i=0 ; i<4 ; i++)
                {
-                       for (i=0;i<5;i++)
+                       if (cl.items & (1<<hipweapons[i]) )
                        {
-                               if (cl.stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i))
+                               time = cl.item_gettime[hipweapons[i]];
+                               flashon = (int)((cl.time - time)*10);
+                               if (flashon >= 10)
                                {
-                                       Sbar_DrawPic ((i+2)*24, -16, rsb_weapons[i]);
+                                       if ( cl.stats[STAT_ACTIVEWEAPON] == (1<<hipweapons[i])  )
+                                               flashon = 1;
+                                       else
+                                               flashon = 0;
+                               }
+                               else
+                                       flashon = (flashon%5) + 2;
+
+                               // check grenade launcher
+                               if (i==2)
+                               {
+                                       if (cl.items & HIT_PROXIMITY_GUN)
+                                       {
+                                               if (flashon)
+                                               {
+                                                       grenadeflashing = 1;
+                                                       Sbar_DrawPic (96, -16, hsb_weapons[flashon][2]);
+                                               }
+                                       }
                                }
+                               else if (i==3)
+                               {
+                                       if (cl.items & (IT_SHOTGUN<<4))
+                                       {
+                                               if (!grenadeflashing)
+                                                       Sbar_DrawPic (96, -16, hsb_weapons[flashon][3]);
+                                       }
+                                       else
+                                               Sbar_DrawPic (96, -16, hsb_weapons[flashon][4]);
+                               }
+                               else
+                                       Sbar_DrawPic (176 + (i*24), -16, hsb_weapons[flashon][i]);
                        }
                }
        }
 
-// ammo counts
+       if (rogue)
+       {
+               // check for powered up weapon.
+               if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
+                       for (i=0;i<5;i++)
+                               if (cl.stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i))
+                                       Sbar_DrawPic ((i+2)*24, -16, rsb_weapons[i]);
+       }
+
+       // ammo counts
        for (i=0 ; i<4 ; i++)
        {
                sprintf (num, "%3i",cl.stats[STAT_SHELLS+i] );
@@ -678,86 +597,53 @@ void Sbar_DrawInventory (void)
        }
 
        flashon = 0;
-   // items
-   for (i=0 ; i<6 ; i++)
-      if (cl.items & (1<<(17+i)))
-      {
-         time = cl.item_gettime[17+i];
-         if (time && time > cl.time - 2 && flashon )
-         {  // flash frame
-//            sb_updates = 0;
-         }
-         else
-         {
-         //MED 01/04/97 changed keys
-            if (!hipnotic || (i>1))
-            {
-               Sbar_DrawPic (192 + i*16, -16, sb_items[i]);
-            }
-         }
-//         if (time && time > cl.time - 2)
-//            sb_updates = 0;
-      }
-   //MED 01/04/97 added hipnotic items
-   // hipnotic items
-   if (hipnotic)
-   {
-      for (i=0 ; i<2 ; i++)
-         if (cl.items & (1<<(24+i)))
-         {
-            time = cl.item_gettime[24+i];
-            if (time && time > cl.time - 2 && flashon )
-            {  // flash frame
-//               sb_updates = 0;
-            }
-            else
-            {
-               Sbar_DrawPic (288 + i*16, -16, hsb_items[i]);
-            }
-//            if (time && time > cl.time - 2)
-//               sb_updates = 0;
-         }
-   }
+       // items
+       for (i=0 ; i<6 ; i++)
+               if (cl.items & (1<<(17+i)))
+               {
+                       time = cl.item_gettime[17+i];
+                       if (time && time > cl.time - 2 && flashon )
+                       {  // flash frame
+                       }
+                       else
+                       //MED 01/04/97 changed keys
+                               if (!hipnotic || (i>1))
+                                       Sbar_DrawPic (192 + i*16, -16, sb_items[i]);
+               }
+       //MED 01/04/97 added hipnotic items
+       // hipnotic items
+       if (hipnotic)
+       {
+               for (i=0 ; i<2 ; i++)
+                       if (cl.items & (1<<(24+i)))
+                       {
+                               time = cl.item_gettime[24+i];
+                               if (!time || time <= cl.time - 2 || !flashon)
+                                       Sbar_DrawPic (288 + i*16, -16, hsb_items[i]);
+                       }
+       }
 
        if (rogue)
        {
-       // new rogue items
+               // new rogue items
                for (i=0 ; i<2 ; i++)
-               {
                        if (cl.items & (1<<(29+i)))
                        {
                                time = cl.item_gettime[29+i];
-
-                               if (time &&     time > cl.time - 2 && flashon )
-                               {       // flash frame
-//                                     sb_updates = 0;
-                               }
-                               else
-                               {
+                               if (!time || time <= cl.time - 2 || !flashon)
                                        Sbar_DrawPic (288 + i*16, -16, rsb_items[i]);
-                               }
-
-//                             if (time &&     time > cl.time - 2)
-//                                     sb_updates = 0;
                        }
-               }
        }
        else
        {
-       // sigils
+               // sigils
                for (i=0 ; i<4 ; i++)
                {
                        if (cl.items & (1<<(28+i)))
                        {
                                time = cl.item_gettime[28+i];
-                               if (time &&     time > cl.time - 2 && flashon )
-                               {       // flash frame
-//                                     sb_updates = 0;
-                               }
-                               else
+                               if (!time || time <= cl.time - 2 || !flashon)
                                        Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]);
-//                             if (time &&     time > cl.time - 2)
-//                                     sb_updates = 0;
                        }
                }
        }
@@ -799,10 +685,8 @@ void Sbar_DrawFrags (void)
                        continue;
 
        // draw background
-               top = s->colors & 0xf0;
-               bottom = (s->colors & 15)<<4;
-               top = Sbar_ColorForMap (top);
-               bottom = Sbar_ColorForMap (bottom);
+               top = (s->colors & 0xf0) + 8;
+               bottom = ((s->colors & 15)<<4) + 8;
 
                Draw_Fill (xofs + x*8 + 10, y, 28, 4, top);
                Draw_Fill (xofs + x*8 + 10, y+4, 28, 3, bottom);
@@ -850,10 +734,8 @@ void Sbar_DrawFace (void)
                
                s = &cl.scores[cl.viewentity - 1];
                // draw background
-               top = s->colors & 0xf0;
-               bottom = (s->colors & 15)<<4;
-               top = Sbar_ColorForMap (top);
-               bottom = Sbar_ColorForMap (bottom);
+               top = (s->colors & 0xf0) + 8;
+               bottom = ((s->colors & 15)<<4) + 8;
 
                if (cl.gametype == GAME_DEATHMATCH)
                        xofs = 113;
@@ -1113,10 +995,8 @@ void Sbar_DeathmatchOverlay (void)
                        continue;
 
        // draw background
-               top = s->colors & 0xf0;
-               bottom = (s->colors & 15)<<4;
-               top = Sbar_ColorForMap (top);
-               bottom = Sbar_ColorForMap (bottom);
+               top = (s->colors & 0xf0) + 8;
+               bottom = ((s->colors & 15)<<4) + 8;
 
                Draw_Fill ( x, y+1, 88, 3, top);
                Draw_Fill ( x, y+4, 88, 3, bottom);
@@ -1191,8 +1071,8 @@ void Sbar_MiniDeathmatchOverlay (void)
                        continue;
 
        // draw background
-               top = Sbar_ColorForMap (s->colors & 0xf0);
-               bottom = Sbar_ColorForMap ((s->colors & 15)<<4);
+               top = (s->colors & 0xf0) + 8;
+               bottom = ((s->colors & 15)<<4) + 8;
 
                Draw_Fill ( x, y+1, 72, 3, top);
                Draw_Fill ( x, y+4, 72, 3, bottom);
index 3ab515d..7cc93b1 100644 (file)
--- a/server.h
+++ b/server.h
@@ -96,6 +96,8 @@ typedef struct client_s
                
        float                   ping_times[NUM_PING_TIMES];
        int                             num_pings;                      // ping_times[num_pings%NUM_PING_TIMES]
+       float                   ping;                           // LordHavoc: can be used for prediction or whatever...
+       float                   latency;                        // LordHavoc: specifically used for prediction, accounts for sys_ticrate too
 
 // spawn parms are carried from level to level
        float                   spawn_parms[NUM_SPAWN_PARMS];
index 6b802a0..d3abe08 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -435,6 +435,13 @@ void SV_WriteEntitiesToClient (edict_t     *clent, sizebuf_t *msg)
 // find the client's PVS
        VectorAdd (clent->v.origin, clent->v.view_ofs, org);
        pvs = SV_FatPVS (org);
+       if (dpprotocol)
+       {
+               MSG_WriteByte(msg, svc_playerposition);
+               MSG_WriteFloat(msg, org[0]);
+               MSG_WriteFloat(msg, org[1]);
+               MSG_WriteFloat(msg, org[2]);
+       }
 
        clentnum = NUM_FOR_EDICT(clent); // LordHavoc: for comparison purposes
 // send over all entities (except the client) that touch the pvs
@@ -485,9 +492,9 @@ void SV_WriteEntitiesToClient (edict_t      *clent, sizebuf_t *msg)
                if (alpha > 255) alpha = 255;
 
                if ((val = GETEDICTFIELDVALUE(ent, eval_glow_size)))
-                       glowsize = (int) val->_float >> 3;
-               if (glowsize > 127) glowsize = 127;
-               if (glowsize < -128) glowsize = -128;
+                       glowsize = (int) val->_float >> 2;
+               if (glowsize > 255) glowsize = 255;
+               if (glowsize < 0) glowsize = 0;
 
                if ((val = GETEDICTFIELDVALUE(ent, eval_scale)))
                if ((scale = (int) (val->_float * 16.0)) == 0) scale = 16;
@@ -593,11 +600,13 @@ void SV_WriteEntitiesToClient (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);
                }
                else // copy as they are
                {
-                       VectorCopy(ent->v.origin, origin);
+//                     VectorCopy(ent->v.origin, origin);
                        VectorCopy(ent->v.angles, angles);
+                       VectorMA(ent->v.origin, host_client->latency, ent->v.velocity, origin);
                        if (ent->v.movetype == MOVETYPE_STEP) // monster, but airborn, update lerp info
                        {
                                // update lerp positions
@@ -673,7 +682,7 @@ void SV_WriteEntitiesToClient (edict_t      *clent, sizebuf_t *msg)
                if (bits & U_COLORMAP)  MSG_WriteByte (msg, ent->v.colormap);
                if (bits & U_SKIN)              MSG_WriteByte (msg, ent->v.skin);
                if (bits & U_EFFECTS)   MSG_WriteByte (msg, ent->v.effects);
-               if (bits & U_ORIGIN1)   MSG_WriteCoord (msg, origin[0]);                
+               if (bits & U_ORIGIN1)   MSG_WriteCoord (msg, origin[0]);
                if (bits & U_ANGLE1)    MSG_WriteAngle(msg, angles[0]);
                if (bits & U_ORIGIN2)   MSG_WriteCoord (msg, origin[1]);
                if (bits & U_ANGLE2)    MSG_WriteAngle(msg, angles[1]);
index 4006279..7b286dd 100644 (file)
--- a/sv_user.c
+++ b/sv_user.c
@@ -456,12 +456,12 @@ void SV_ReadClientMove (usercmd_t *move)
        host_client->ping_times[host_client->num_pings%NUM_PING_TIMES]
                = sv.time - MSG_ReadFloat ();
        host_client->num_pings++;
+       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
+       host_client->latency = host_client->ping + sv_frametime; // push ahead by ticrate
        if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_ping)))
-       {
-               for (i=0, total = 0;i < NUM_PING_TIMES;i++)
-                       total += host_client->ping_times[i];
-               val->_float = 1000.0 / NUM_PING_TIMES;
-       }
+               val->_float = host_client->ping * 1000.0;
 
 // read current angles 
        for (i=0 ; i<3 ; i++)
index f593a56..9a40abc 100644 (file)
--- a/sys_win.c
+++ b/sys_win.c
@@ -26,10 +26,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "conproc.h"
 #include "direct.h"
 
-// LordHavoc: raised min to 24mb (was 8.5mb)
-#define MINIMUM_WIN_MEMORY             0x1800000
-// LordHavoc: raised max to 24mb (was 16mb)
-#define MAXIMUM_WIN_MEMORY             0x1800000
+// LordHavoc: raised min to 64mb (was 8.5mb)
+#define MINIMUM_WIN_MEMORY             0x04000000
+// LordHavoc: raised max to 64mb (was 16mb)
+#define MAXIMUM_WIN_MEMORY             0x04000000
 
 #define CONSOLE_ERROR_TIMEOUT  60.0    // # of seconds to wait on Sys_Error running
                                                                                //  dedicated before exiting
index 5767ca2..d28c8d2 100644 (file)
--- a/vid_wgl.c
+++ b/vid_wgl.c
@@ -567,7 +567,6 @@ void GL_Init (void)
 
        // LordHavoc: report supported extensions
        Con_Printf ("\nQSG extensions: %s\n", QSG_EXTENSIONS);
-
        // LordHavoc: set up state
 //     glEnable(GL_DEPTH_TEST);
 //     glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
diff --git a/view.c b/view.c
index 7d907cd..0638f86 100644 (file)
--- a/view.c
+++ b/view.c
@@ -706,6 +706,7 @@ V_CalcRefdef
 
 ==================
 */
+extern qboolean intimerefresh;
 void V_CalcRefdef (void)
 {
        entity_t        *ent, *view;
@@ -742,7 +743,10 @@ void V_CalcRefdef (void)
        r_refdef.vieworg[1] += 1.0/32;
        r_refdef.vieworg[2] += 1.0/32;
 
-       VectorCopy (cl.viewangles, r_refdef.viewangles);
+       if (!intimerefresh)
+       {
+               VectorCopy (cl.viewangles, r_refdef.viewangles);
+       }
        V_CalcViewRoll ();
        V_AddIdle ();
 
@@ -795,7 +799,10 @@ void V_CalcRefdef (void)
        view->colormap = 0; //vid.colormap;
 
 // set up the refresh position
-       VectorAdd (r_refdef.viewangles, cl.punchangle, r_refdef.viewangles);
+       if (!intimerefresh)
+       {
+               VectorAdd (r_refdef.viewangles, cl.punchangle, r_refdef.viewangles);
+       }
 
 // smooth out stair step ups
 if (cl.onground && ent->origin[2] - oldz > 0)
@@ -845,8 +852,6 @@ void V_RenderView (void)
                        V_CalcRefdef ();
        }
 
-       R_PushDlights ();
-
        R_RenderView ();
 }
 
diff --git a/world.c b/world.c
index 4bb4b54..a83dd21 100644 (file)
--- a/world.c
+++ b/world.c
@@ -586,16 +586,8 @@ loc0:
        node = hull->clipnodes + num;
        plane = hull->planes + node->planenum;
 
-       if (plane->type < 3)
-       {
-               t1 = p1[plane->type] - plane->dist;
-               t2 = p2[plane->type] - plane->dist;
-       }
-       else
-       {
-               t1 = DotProduct (plane->normal, p1) - plane->dist;
-               t2 = DotProduct (plane->normal, p2) - plane->dist;
-       }
+       t1 = PlaneDiff(p1, plane);
+       t2 = PlaneDiff(p2, plane);
        
 #if 1
        if (t1 >= 0 && t2 >= 0)
@@ -620,17 +612,14 @@ loc0:
 
 // put the crosspoint DIST_EPSILON pixels on the near side
        if (t1 < 0)
-               frac = (t1 + DIST_EPSILON)/(t1-t2);
+               frac = bound(0, (t1 + DIST_EPSILON)/(t1-t2), 1);
        else
-               frac = (t1 - DIST_EPSILON)/(t1-t2);
-       if (frac < 0)
-               frac = 0;
-       if (frac > 1)
-               frac = 1;
+               frac = bound(0, (t1 - DIST_EPSILON)/(t1-t2), 1);
                
        midf = p1f + (p2f - p1f)*frac;
-       for (i=0 ; i<3 ; i++)
-               mid[i] = p1[i] + frac*(p2[i] - p1[i]);
+       mid[0] = p1[0] + frac*(p2[0] - p1[0]);
+       mid[1] = p1[1] + frac*(p2[1] - p1[1]);
+       mid[2] = p1[2] + frac*(p2[2] - p1[2]);
 
        side = (t1 < 0);
 
@@ -701,6 +690,74 @@ loc0:
        return false;
 }
 
+qboolean SV_TestLine (hull_t *hull, int num, vec3_t p1, vec3_t p2)
+{
+       dclipnode_t     *node;
+       mplane_t        *plane;
+       float           t1, t2, frac;
+       vec3_t          mid;
+       int                     side;
+
+loc0:
+// check for empty
+       if (num < 0)
+               return num != CONTENTS_SOLID;
+
+       if (num < hull->firstclipnode || num > hull->lastclipnode)
+               Sys_Error ("SV_RecursiveHullCheck: bad node number");
+
+//
+// find the point distances
+//
+       node = hull->clipnodes + num;
+       plane = hull->planes + node->planenum;
+
+       t1 = PlaneDiff(p1, plane);
+       t2 = PlaneDiff(p2, plane);
+       
+       if (t1 >= 0 && t2 >= 0)
+       {
+               num = node->children[0];
+               goto loc0;
+       }
+       if (t1 < 0 && t2 < 0)
+       {
+               num = node->children[1];
+               goto loc0;
+       }
+
+// put the crosspoint DIST_EPSILON pixels on the near side
+       side = (t1 < 0);
+
+       if (side)
+               frac = bound(0, (t1 + DIST_EPSILON)/(t1-t2), 1);
+       else
+               frac = bound(0, (t1 - DIST_EPSILON)/(t1-t2), 1);
+               
+       mid[0] = p1[0] + frac*(p2[0] - p1[0]);
+       mid[1] = p1[1] + frac*(p2[1] - p1[1]);
+       mid[2] = p1[2] + frac*(p2[2] - p1[2]);
+
+       if (node->children[side] < 0)
+       {
+               if (node->children[side] == CONTENTS_SOLID)
+                       return false;
+               return SV_TestLine(hull, node->children[!side], mid, p2);
+//             num = node->children[!side];
+//             VectorCopy(mid, p1);
+//             goto loc0;
+       }
+       else if (SV_TestLine(hull, node->children[side], p1, mid))
+       {
+               return SV_TestLine(hull, node->children[!side], mid, p2);
+//             num = node->children[!side];
+//             VectorCopy(mid, p1);
+//             goto loc0;
+       }
+       else
+               return false;
+}
+
 
 /*
 ==================