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