--- /dev/null
+
+#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
--- /dev/null
+
+#define BUILDNUMBER 68
+
+int buildnumber = BUILDNUMBER;
// 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)
}
-/*
-===============
-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
{
if (frac < -0.01)
{
-SetPal(1);
cl.time = cl.mtime[1];
// Con_Printf ("low frac\n");
}
{
if (frac > 1.01)
{
-SetPal(2);
cl.time = cl.mtime[0];
// Con_Printf ("high frac\n");
}
frac = 1;
}
- else
- SetPal(0);
return frac;
}
{
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;
"?", // 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
/*
===============
Nehahrademcompatibility = true;
if (cls.demoplayback && demo_nehahra.value)
Nehahrademcompatibility = true;
+ dpprotocol = i == DPPROTOCOL_VERSION;
// parse maxclients
cl.maxclients = MSG_ReadByte ();
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);
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);
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;
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;
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;
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;
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);
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;
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)
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)
{
}
*/
+float MSG_ReadPreciseAngle (void)
+{
+ return MSG_ReadShort() * (360.0f/65536);
+}
//===========================================================================
//#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;
//============================================================================
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);
; 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;
; 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)
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)
===============
*/
void rmain_registercvars();
+extern int buildnumber;
void Draw_Init (void)
{
int i;
// 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);
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));
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)
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++;
}
}
*/
+/*
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;
}
qsort(&transpolyindex[0], transpolyindices, sizeof(unsigned short), transpolyqsort);
}
+*/
/*
int i, j, a;
a = true;
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)
*/
{
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);
}
}
}
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;
{
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)
{
}
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);
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
// 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)
{
}
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);
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)
{
}
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);
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;
}
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);
{
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)));
}
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);
}
#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)
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;
{
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
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
//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"};
glDepthMask(1);
}
+int modeldlightbits[8];
+extern int r_dlightframecount;
+
/*
=================
R_DrawAliasModel
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)
c_brush_polys = 0;
c_alias_polys = 0;
+ c_light_polys = 0;
+ c_nodes = 0;
+ c_leafs = 0;
}
r_refdef must be set before the first call
================
*/
+extern qboolean intimerefresh;
void R_RenderView (void)
{
// double currtime, temptime;
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();
// Cvar_RegisterVariable (&gl_cull);
// Cvar_RegisterVariable (&gl_affinemodels);
// Cvar_RegisterVariable (&gl_polyblend);
-// Cvar_RegisterVariable (&gl_flashblend);
Cvar_RegisterVariable (&gl_playermip);
// Cvar_RegisterVariable (&gl_nocolors);
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++)
{
}
stop = Sys_FloatTime ();
+ intimerefresh = 0;
time = stop-start;
Con_Printf ("%f seconds (%f fps)\n", time, 128/time);
}
-void D_FlushCaches (void)
-{
-}
-
#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;
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;
qboolean skyisvisible;
extern qboolean gl_arrays;
+extern int r_dlightframecount;
+
void glrsurf_init()
{
int i;
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)
}
}
-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;
/*
===============
int maps;
int *bl;
- surf->cached_dlight = (surf->dlightframe == r_framecount);
surf->cached_lighthalf = lighthalf;
surf->cached_ambient = r_ambient.value;
*bl++ += *lightmap++ * scale;
}
}
-
-// add all the dynamic lights
- if (surf->dlightframe == r_framecount)
- R_AddDynamicLights (surf);
}
stride -= (smax*lightmapbytes);
bl = blocklights;
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"
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();
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;
{
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];
+ }
}
}
}
// 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;
}
}
}
+ */
}
}
}
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);
/*
=================
*/
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;
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;
// 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;
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;
}
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
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];
+ }
}
}
}
/*
================
-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))
while(1)
{
// if a leaf node, draw stuff
- c_nodes++;
if (node->contents < 0)
{
if (node->contents != CONTENTS_SOLID)
mleaf_t *pleaf;
pleaf = (mleaf_t *)node;
+ c_leafs++;
if ((c = pleaf->nummarksurfaces))
{
msurface_t **mark;
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
// 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;
}
// 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;
glClear (GL_DEPTH_BUFFER_BIT);
+ R_PushDlights (); // now mark the lit surfaces
+
DrawTextureChains ();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
*/
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));
+ */
}
/*
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;
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)
//
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 ();
}
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 !!!
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;
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;
//
//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;
// 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;
double oldrealtime; // last frame run
int host_framecount;
+double sv_frametime;
+
int host_hunklevel;
int minimum_memory;
void Host_ClearMemory (void)
{
Con_DPrintf ("Clearing memory\n");
- D_FlushCaches ();
Mod_ClearAll ();
if (host_hunklevel)
Hunk_FreeToLowMark (host_hunklevel);
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;
#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);
: \
(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))
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;
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
{
// 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];
// 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;
extern char m_return_reason[32];
-#ifdef DEBUG
+//#ifdef DEBUG
char *StrAddr (struct qsockaddr *addr)
{
static char buf[34];
sprintf (buf + n * 2, "%02x", *p++);
return buf;
}
-#endif
+//#endif
#ifdef BAN_TEST
// 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;
}
// protocol.h -- communications protocols
#define PROTOCOL_VERSION 15
+#define DPPROTOCOL_VERSION 96
// model effects
#define EF_ROCKET 1 // leave a trail
#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
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);
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)
{
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
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++)
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;
}
}
}
+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++;
+ }
+ }
+}
+
/*
=============
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;
{
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);
}
}
// 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];
+ }
+ }
}
}
}
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++)
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];
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;
{
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;
{
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;
#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
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;
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);
}
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;
p = p->next;
}
}
+*/
/*
===============
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;
}
p->vel[2] += 160;
}
+ */
i = Mod_PointInLeaf(org, cl.worldmodel)->contents;
if (i == CONTENTS_SLIME || i == CONTENTS_WATER)
{
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;
}
}
}
- 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;
}
}
- }
+// }
}
/*
{
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;
{
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;
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);
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;
{
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
{
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);
{
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;
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;
{
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;
{
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;
{
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);
{
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)
{
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;
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;
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;
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;
{
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)
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;
for (p=active_particles ; p ; p=p->next)
{
+ // remove dead particles following this one
for ( ;; )
{
kill = p->next;
}
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];
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);
transpolyend();
}
+ /*
if (p->pushvel[0] || p->pushvel[1] || p->pushvel[2])
{
p->org[0] += (p->vel[0]+p->pushvel[0])*frametime;
}
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)
{
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];
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)
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;
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;
}
}
}
//
// refresh
//
-extern int reinit_surfcache;
extern refdef_t r_refdef;
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);
-
if (sb_showscores)
return;
sb_showscores = true;
-// sb_updates = 0;
}
/*
void Sbar_DontShowScores (void)
{
sb_showscores = false;
-// sb_updates = 0;
}
-/*
-===============
-Sbar_Changed
-===============
-*/
-//void Sbar_Changed (void)
-//{
-// sb_updates = 0; // update next frame
-//}
-
/*
===============
Sbar_Init
}
}
-int Sbar_ColorForMap (int m)
-{
- return m < 128 ? m + 8 : m + 8;
-}
-
/*
===============
Sbar_UpdateScoreboard
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;
}
}
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
}
//=============================================================================
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) )
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] );
}
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;
}
}
}
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);
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;
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);
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);
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];
// 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
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;
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
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]);
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++)
#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
// 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);
==================
*/
+extern qboolean intimerefresh;
void V_CalcRefdef (void)
{
entity_t *ent, *view;
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 ();
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)
V_CalcRefdef ();
}
- R_PushDlights ();
-
R_RenderView ();
}
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)
// 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);
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;
+}
+
/*
==================