From c98b091c10dc46797648b3ade88ec24076eb092c Mon Sep 17 00:00:00 2001 From: lordhavoc Date: Thu, 31 Aug 2000 14:09:05 +0000 Subject: [PATCH] misc. cleanup, bubble trails fixed, improved lightmap compatibility. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@15 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_input.c | 3 +- cl_main.c | 21 ++++ cl_parse.c | 47 ++------ cl_tent.c | 3 +- client.h | 3 +- gl_poly.c | 85 +++++++++++++-- gl_rmain.c | 39 ++----- gl_rsurf.c | 283 ++++++++++++++++++++++++++++++------------------ gl_warp.c | 10 +- glquake.h | 1 + host_cmd.c | 5 +- mathlib.h | 4 +- model_alias.c | 20 ++-- r_part.c | 294 ++++++++++++++++++++------------------------------ 14 files changed, 437 insertions(+), 381 deletions(-) diff --git a/cl_input.c b/cl_input.c index a4a7e4d2..a43a9d9a 100644 --- a/cl_input.c +++ b/cl_input.c @@ -351,7 +351,7 @@ void CL_SendMove (usercmd_t *cmd) upmove += cmd->upmove; total++; // LordHavoc: cap outgoing movement messages to sys_ticrate - if (cl.maxclients > 1 && realtime - lastmovetime < sys_ticrate.value) + if ((cl.maxclients > 1) && (realtime - lastmovetime < sys_ticrate.value)) return; lastmovetime = realtime; // average what has happened during this time @@ -381,6 +381,7 @@ void CL_SendMove (usercmd_t *cmd) MSG_WriteShort (&buf, sidemove); MSG_WriteShort (&buf, upmove); + forwardmove = sidemove = upmove = 0; // // send button bits // diff --git a/cl_main.c b/cl_main.c index af1b4a04..0a42a264 100644 --- a/cl_main.c +++ b/cl_main.c @@ -812,6 +812,25 @@ void CL_PModel_f (void) val->_float = i; } +/* +====================== +CL_Fog_f +====================== +*/ +extern float fog_density, fog_red, fog_green, fog_blue; +void CL_Fog_f (void) +{ + if (Cmd_Argc () == 1) + { + Con_Printf ("\"fog\" is \"%f %f %f %f\"\n", fog_density, fog_red, fog_green, fog_blue); + return; + } + fog_density = atof(Cmd_Argv(1)); + fog_red = atof(Cmd_Argv(2)); + fog_green = atof(Cmd_Argv(3)); + fog_blue = atof(Cmd_Argv(4)); +} + cvar_t demo_nehahra = {"demo_nehahra", "0"}; /* @@ -860,6 +879,8 @@ void CL_Init (void) Cmd_AddCommand ("playdemo", CL_PlayDemo_f); Cmd_AddCommand ("timedemo", CL_TimeDemo_f); + Cmd_AddCommand ("fog", CL_Fog_f); + // LordHavoc: added pausedemo Cmd_AddCommand ("pausedemo", CL_PauseDemo_f); // LordHavoc: added pmodel command (like name, etc, only intended for Nehahra) diff --git a/cl_parse.c b/cl_parse.c index b389312f..b1f240b0 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -267,6 +267,11 @@ void CL_ParseEntityLump(char *entdata) // if (r_skyboxsize.value < 64) // r_skyboxsize.value = 64; // } + else if (!strcmp("fog", key)) + { + scanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue); + j = 0; + } else if (!strcmp("fog_density", key)) fog_density = atof(value); else if (!strcmp("fog_red", key)) @@ -521,7 +526,7 @@ void CL_ParseUpdate (int bits) { if (i > cl.maxclients) Host_Error ("i >= cl.maxclients"); - ent->colormap = cl.scores[i-1].translations; + ent->colormap = vid.colormap; // cl.scores[i-1].translations; } skin = bits & U_SKIN ? MSG_ReadByte() : baseline->skin; @@ -740,44 +745,6 @@ void CL_ParseClientdata (int bits) } } -/* -===================== -CL_NewTranslation -===================== -*/ -void CL_NewTranslation (int slot) -{ - int i, j; - int top, bottom; - byte *dest, *source; - - if (slot > cl.maxclients) - Host_Error ("CL_NewTranslation: slot > cl.maxclients"); - dest = cl.scores[slot].translations; - source = vid.colormap; - memcpy (dest, vid.colormap, sizeof(cl.scores[slot].translations)); - top = cl.scores[slot].colors & 0xf0; - bottom = (cl.scores[slot].colors &15)<<4; - R_TranslatePlayerSkin (slot); - - for (i=0 ; i= 224 && top < 240)) // the artists made some backwards ranges. sigh. - memcpy (dest + TOP_RANGE, source + top, 16); - else - for (j=0 ; j<16 ; j++) - dest[TOP_RANGE+j] = source[top+15-j]; - - // LordHavoc: corrected color ranges - if (bottom < 128 || (bottom >= 224 && bottom < 240)) - memcpy (dest + BOTTOM_RANGE, source + bottom, 16); - else - for (j=0 ; j<16 ; j++) - dest[BOTTOM_RANGE+j] = source[bottom+15-j]; - } -} - /* ===================== CL_ParseStatic @@ -992,7 +959,7 @@ void CL_ParseServerMessage (void) if (i >= cl.maxclients) Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD"); cl.scores[i].colors = MSG_ReadByte (); - CL_NewTranslation (i); + R_TranslatePlayerSkin (i); break; case svc_particle: diff --git a/cl_tent.c b/cl_tent.c index 573dc593..a3795adf 100644 --- a/cl_tent.c +++ b/cl_tent.c @@ -576,8 +576,7 @@ void CL_UpdateTEnts (void) dl->die = cl.time + 0.001; dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 1; - for (i=0 ; i<3 ; i++) - org[i] += dist[i]*30; + VectorMA(org, 30, dist, org); d -= 30; } } diff --git a/client.h b/client.h index ca030ddc..45ae787e 100644 --- a/client.h +++ b/client.h @@ -41,7 +41,7 @@ typedef struct float entertime; int frags; int colors; // two 4 bit fields - byte translations[VID_GRADES*256]; + byte translations[256]; // LordHavoc: major memory reduction (was VID_GRADES*256, and VID_GRADES is 64), and weirdness cleanup } scoreboard_t; typedef struct @@ -346,7 +346,6 @@ void CL_TimeDemo_f (void); // cl_parse.c // void CL_ParseServerMessage (void); -void CL_NewTranslation (int slot); // // view diff --git a/gl_poly.c b/gl_poly.c index 9dad35b3..fdc8a896 100644 --- a/gl_poly.c +++ b/gl_poly.c @@ -639,31 +639,94 @@ void skypolyclear() } extern qboolean isATI; + +extern char skyname[]; +extern int solidskytexture, alphaskytexture; void skypolyrender() { int i, j; skypoly_t *p; skyvert_t *vert; + float length, speedscale; + vec3_t dir; if (currentskypoly < 1) return; // testing // Con_DPrintf("skypolyrender: %i polys %i vertices\n", currentskypoly, currentskyvert); - glDisable(GL_TEXTURE_2D); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_ALPHA_TEST); glDisable(GL_BLEND); // make sure zbuffer is enabled glEnable(GL_DEPTH_TEST); glDepthMask(1); - glColor3fv(fogcolor); // note: gets rendered over by sky if fog is not enabled - for (i = 0,p = &skypoly[0];i < currentskypoly;i++, p++) + if (!fogenabled && !skyname[0]) // normal quake sky { - vert = &skyvert[p->firstvert]; - glBegin(GL_POLYGON); - for (j=0 ; jverts ; j++, vert++) - glVertex3fv (vert->v); - glEnd (); + glColor3f(0.5f, 0.5f, 0.5f); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindTexture(GL_TEXTURE_2D, solidskytexture); // upper clouds + speedscale = realtime*8; + speedscale -= (int)speedscale & ~127 ; + for (i = 0,p = &skypoly[0];i < currentskypoly;i++, p++) + { + vert = &skyvert[p->firstvert]; + glBegin(GL_POLYGON); + for (j=0 ; jverts ; j++, vert++) + { + VectorSubtract (vert->v, r_origin, dir); + dir[2] *= 3; // flatten the sphere + + length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]; + length = sqrt (length); + length = 6*63/length; + + glTexCoord2f ((speedscale + dir[0] * length) * (1.0/128), (speedscale + dir[1] * length) * (1.0/128)); + glVertex3fv (vert->v); + } + glEnd (); + } + glEnable(GL_BLEND); + glDepthMask(0); + glBindTexture(GL_TEXTURE_2D, alphaskytexture); // lower clouds + speedscale = realtime*16; + speedscale -= (int)speedscale & ~127 ; + for (i = 0,p = &skypoly[0];i < currentskypoly;i++, p++) + { + vert = &skyvert[p->firstvert]; + glBegin(GL_POLYGON); + for (j=0 ; jverts ; j++, vert++) + { + VectorSubtract (vert->v, r_origin, dir); + dir[2] *= 3; // flatten the sphere + + length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]; + length = sqrt (length); + length = 6*63/length; + + glTexCoord2f ((speedscale + dir[0] * length) * (1.0/128), (speedscale + dir[1] * length) * (1.0/128)); + glVertex3fv (vert->v); + } + glEnd (); + } + glDisable(GL_BLEND); + glColor3f(1,1,1); + glDepthMask(1); + } + else + { + glDisable(GL_TEXTURE_2D); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor3fv(fogcolor); // note: gets rendered over by skybox if fog is not enabled + for (i = 0,p = &skypoly[0];i < currentskypoly;i++, p++) + { + vert = &skyvert[p->firstvert]; + glBegin(GL_POLYGON); + for (j=0 ; jverts ; j++, vert++) + glVertex3fv (vert->v); + glEnd (); + } + glColor3f(1,1,1); + glEnable(GL_TEXTURE_2D); } - glColor3f(1,1,1); - glEnable(GL_TEXTURE_2D); } diff --git a/gl_rmain.c b/gl_rmain.c index f90e467a..fd784385 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -93,9 +93,7 @@ cvar_t gl_playermip = {"gl_playermip","0"}; cvar_t contrast = {"contrast", "1.0", TRUE}; // LordHavoc: a method of operating system independent color correction cvar_t brightness = {"brightness", "1.0", TRUE}; // LordHavoc: a method of operating system independent color correction cvar_t gl_lightmode = {"gl_lightmode", "1", TRUE}; // LordHavoc: overbright lighting -//cvar_t r_particles = {"r_particles", "1"}; //cvar_t r_dynamicwater = {"r_dynamicwater", "1"}; -//cvar_t r_smokealpha = {"r_smokealpha", "0.25"}; //cvar_t r_dynamicbothsides = {"r_dynamicbothsides", "1"}; // LordHavoc: can disable dynamic lighting of backfaces, but quake maps are weird so it doesn't always work right... cvar_t gl_fogenable = {"gl_fogenable", "0"}; @@ -238,7 +236,7 @@ void FOG_framebegin() if (fog_density) { fogenabled = true; - fogdensity = -4096.0f / (fog_density * fog_density); + fogdensity = -4000.0f / (fog_density * fog_density); fogcolor[0] = fog_red = bound(0.0f, fog_red , 1.0f); fogcolor[1] = fog_green = bound(0.0f, fog_green, 1.0f); fogcolor[2] = fog_blue = bound(0.0f, fog_blue , 1.0f); @@ -310,8 +308,6 @@ void rmain_registercvars() Cvar_RegisterVariable (&brightness); Cvar_RegisterVariable (&gl_lightmode); // Cvar_RegisterVariable (&r_dynamicwater); -// Cvar_RegisterVariable (&r_particles); -// Cvar_RegisterVariable (&r_smokealpha); // Cvar_RegisterVariable (&r_dynamicbothsides); Cvar_RegisterVariable (&r_fullbrights); if (nehahra) @@ -1558,7 +1554,7 @@ r_refdef must be set before the first call */ void R_RenderView (void) { - double currtime, temptime; +// double currtime, temptime; // if (r_norefresh.value) // return; @@ -1569,47 +1565,34 @@ void R_RenderView (void) FOG_framebegin(); transpolyclear(); - wallpolyclear(); - if (r_speeds2.value) - { - currtime = Sys_FloatTime(); - Con_Printf("render time: "); - } +// if (r_speeds2.value) +// { +// currtime = Sys_FloatTime(); +// Con_Printf("render time: "); +// } R_Clear(); - TIMEREPORT("R_Clear") +// TIMEREPORT("R_Clear") // render normal view R_SetupFrame (); - TIMEREPORT("R_SetupFrame") R_SetFrustum (); - TIMEREPORT("R_SetFrustum") R_SetupGL (); - TIMEREPORT("R_SetupGL") R_MarkLeaves (); // done here so we know if we're in water - TIMEREPORT("R_MarkLeaves") R_DrawWorld (); // adds static entities to the list - TIMEREPORT("R_DrawWorld") S_ExtraUpdate (); // don't let sound get messed up if going slow - TIMEREPORT("S_ExtraUpdate") + wallpolyclear(); R_DrawEntitiesOnList1 (); // BSP models - TIMEREPORT("R_DrawEntitiesOnList1") wallpolyrender(); - TIMEREPORT("wallpolyrender") R_DrawEntitiesOnList2 (); // other models - TIMEREPORT("R_DrawEntitiesOnList2") // R_RenderDlights (); R_DrawViewModel (); - TIMEREPORT("R_DrawViewModel") R_DrawParticles (); - TIMEREPORT("R_DrawParticles") transpolyrender(); - TIMEREPORT("transpolyrender") FOG_frameend(); GL_BlendView(); - TIMEREPORT("GL_BlendView") - if (r_speeds2.value) - Con_Printf("\n"); +// if (r_speeds2.value) +// Con_Printf("\n"); } diff --git a/gl_rsurf.c b/gl_rsurf.c index 56197663..514d83d4 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -39,13 +39,15 @@ int active_lightmaps; short allocated[MAX_LIGHTMAPS][BLOCK_WIDTH]; byte *lightmaps[MAX_LIGHTMAPS]; +short lightmapupdate[MAX_LIGHTMAPS][2]; int lightmapalign, lightmapalignmask; // LordHavoc: NVIDIA's broken subimage fix, see BuildLightmaps for notes cvar_t gl_lightmapalign = {"gl_lightmapalign", "4"}; cvar_t gl_lightmaprgba = {"gl_lightmaprgba", "1"}; cvar_t gl_nosubimagefragments = {"gl_nosubimagefragments", "0"}; +cvar_t gl_nosubimage = {"gl_nosubimage", "0"}; -qboolean lightmaprgba, nosubimagefragments; +qboolean lightmaprgba, nosubimagefragments, nosubimage; int lightmapbytes; qboolean skyisvisible; @@ -55,15 +57,17 @@ void glrsurf_init() { int i; for (i = 0;i < MAX_LIGHTMAPS;i++) - lightmaps[i] = (byte *) NULL; + lightmaps[i] = NULL; Cvar_RegisterVariable(&gl_lightmapalign); Cvar_RegisterVariable(&gl_lightmaprgba); Cvar_RegisterVariable(&gl_nosubimagefragments); + Cvar_RegisterVariable(&gl_nosubimage); // check if it's the glquake minigl driver if (strnicmp(gl_vendor,"3Dfx",4)==0) if (!gl_arrays) { Cvar_SetValue("gl_nosubimagefragments", 1); +// Cvar_SetValue("gl_nosubimage", 1); Cvar_SetValue("gl_lightmode", 0); } } @@ -300,20 +304,16 @@ void R_UpdateLightmap(msurface_t *s, int lnum) int smax, tmax; // upload the new lightmap texture fragment glBindTexture(GL_TEXTURE_2D, lightmap_textures + lnum); - if (nosubimagefragments) + if (nosubimage || nosubimagefragments) { - smax = (s->extents[0]>>4)+1; - tmax = (s->extents[1]>>4)+1; + if (lightmapupdate[lnum][0] > s->light_t) + lightmapupdate[lnum][0] = s->light_t; + if (lightmapupdate[lnum][1] < (s->light_t + ((s->extents[1]>>4)+1))) + lightmapupdate[lnum][1] = (s->light_t + ((s->extents[1]>>4)+1)); if (lightmaprgba) - { R_BuildLightMap (s, lightmaps[s->lightmaptexturenum] + (s->light_t * BLOCK_WIDTH + s->light_s) * 4, BLOCK_WIDTH * 4); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, s->light_t, BLOCK_WIDTH, tmax, GL_RGBA, GL_UNSIGNED_BYTE, lightmaps[s->lightmaptexturenum] + s->light_t * (BLOCK_WIDTH * 4)); - } else - { R_BuildLightMap (s, lightmaps[s->lightmaptexturenum] + (s->light_t * BLOCK_WIDTH + s->light_s) * 3, BLOCK_WIDTH * 3); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, s->light_t, BLOCK_WIDTH, tmax, GL_RGB , GL_UNSIGNED_BYTE, lightmaps[s->lightmaptexturenum] + s->light_t * (BLOCK_WIDTH * 3)); - } } else { @@ -406,12 +406,45 @@ float turbsin[256] = #define TURBSCALE (256.0 / (2 * M_PI)) +void UploadLightmaps() +{ + int i; + if (nosubimage || nosubimagefragments) + { + for (i = 0;i < MAX_LIGHTMAPS;i++) + { + if (lightmapupdate[i][0] < lightmapupdate[i][1]) + { + glBindTexture(GL_TEXTURE_2D, lightmap_textures + i); + if (nosubimage) + { + if (lightmaprgba) + glTexImage2D(GL_TEXTURE_2D, 0, 4, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, lightmaps[i]); + else + glTexImage2D(GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, lightmaps[i]); + } + else + { + if (lightmaprgba) + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, lightmapupdate[i][0], BLOCK_WIDTH, lightmapupdate[i][1] - lightmapupdate[i][0], GL_RGBA, GL_UNSIGNED_BYTE, lightmaps[i] + (BLOCK_WIDTH * 4 * lightmapupdate[i][0])); + else + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, lightmapupdate[i][0], BLOCK_WIDTH, lightmapupdate[i][1] - lightmapupdate[i][0], GL_RGB, GL_UNSIGNED_BYTE, lightmaps[i] + (BLOCK_WIDTH * 3 * lightmapupdate[i][0])); + } + } + lightmapupdate[i][0] = BLOCK_HEIGHT; + lightmapupdate[i][1] = 0; + } + } +} + /* ================ DrawTextureChains ================ */ extern qboolean hlbsp; +extern void R_Sky(); +extern char skyname[]; void DrawTextureChains (void) { int i, j, maps; @@ -421,6 +454,97 @@ void DrawTextureChains (void) float *v; float os = turbsin[(int)(realtime * TURBSCALE) & 255], ot = turbsin[(int)(realtime * TURBSCALE + 96.0) & 255]; + // first the sky + skypolyclear(); + for (j = 0;j < cl.worldmodel->numtextures;j++) + { + 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; + t = R_TextureAnimation (cl.worldmodel->textures[j]); + skyisvisible = true; + if (!hlbsp) // LordHavoc: HalfLife maps have freaky skypolys... + { + for (;s;s = s->texturechain) + { + for (p=s->polys ; p ; p=p->next) + { + if (currentskypoly < MAX_SKYPOLYS && currentskyvert + p->numverts <= MAX_SKYVERTS) + { + skypoly[currentskypoly].firstvert = currentskyvert; + skypoly[currentskypoly++].verts = p->numverts; + for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) + { + skyvert[currentskyvert].v[0] = v[0]; + skyvert[currentskyvert].v[1] = v[1]; + skyvert[currentskyvert++].v[2] = v[2]; + } + } + } + } + } + } + } + skypolyrender(); // fogged sky polys, affects depth + + if (skyname[0] && skyisvisible && !fogenabled) + R_Sky(); // does not affect depth, draws over the sky polys + + // then walls + wallpolyclear(); + for (j = 0;j < cl.worldmodel->numtextures;j++) + { + if (!cl.worldmodel->textures[j] || !(s = cl.worldmodel->textures[j]->texturechain)) + continue; + if (!(s->flags & SURF_DRAWTURB)) + { + cl.worldmodel->textures[j]->texturechain = NULL; + t = R_TextureAnimation (cl.worldmodel->textures[j]); + c_brush_polys++; + 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) +// { + if (s->dlightframe == r_framecount || s->cached_dlight || lighthalf != s->cached_lighthalf) // dynamic this frame or previously, or lighthalf 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; + } +// } + 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) + { + 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]; + } + } + } + } + } + UploadLightmaps(); + wallpolyrender(); + + // then water (water gets diverted to transpoly list) for (j = 0;j < cl.worldmodel->numtextures;j++) { if (!cl.worldmodel->textures[j] || !(s = cl.worldmodel->textures[j]->texturechain)) @@ -608,68 +732,6 @@ void DrawTextureChains (void) } } } - else if (s->flags & SURF_DRAWSKY) - { - skyisvisible = true; - if (!hlbsp) // LordHavoc: HalfLife maps have freaky skypolys... - { - for (;s;s = s->texturechain) - { - for (p=s->polys ; p ; p=p->next) - { - if (currentskypoly < MAX_SKYPOLYS && currentskyvert + p->numverts <= MAX_SKYVERTS) - { - skypoly[currentskypoly].firstvert = currentskyvert; - skypoly[currentskypoly++].verts = p->numverts; - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) - { - skyvert[currentskyvert].v[0] = v[0]; - skyvert[currentskyvert].v[1] = v[1]; - skyvert[currentskyvert++].v[2] = v[2]; - } - } - } - } - } - } - else // normal wall - { - c_brush_polys++; - 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) -// { - if (s->dlightframe == r_framecount || s->cached_dlight || lighthalf != s->cached_lighthalf) // dynamic this frame or previously, or lighthalf 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; - } -// } - 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) - { - 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]; - } - } - } - } } } @@ -932,6 +994,7 @@ e->angles[0] = -e->angles[0]; // stupid quake bug } } } + UploadLightmaps(); } /* @@ -1179,7 +1242,6 @@ loc0: R_DrawWorld ============= */ -extern void R_Sky(); void R_DrawWorld (void) { entity_t ent; @@ -1195,20 +1257,14 @@ void R_DrawWorld (void) currententity = &ent; softwaretransformidentity(); // LordHavoc: clear transform - skypolyclear(); skyisvisible = false; if (cl.worldmodel) R_WorldNode (); - DrawTextureChains (); - glClear (GL_DEPTH_BUFFER_BIT); - skypolyrender(); // fogged sky polys, affects depth - - if (skyisvisible && !fogenabled) - R_Sky(); // does not affect depth, draws over the sky polys + DrawTextureChains (); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -1309,11 +1365,13 @@ int AllocBlock (int w, int h, int *x, int *y) if (best + h > BLOCK_HEIGHT) continue; - if (gl_nosubimagefragments.value) + if (nosubimagefragments || nosubimage) + { if (!lightmaps[texnum]) lightmaps[texnum] = calloc(BLOCK_WIDTH*BLOCK_HEIGHT*4, 1); + } // LordHavoc: clear texture to blank image, fragments are uploaded using subimage - if (!allocated[texnum][0]) + else if (!allocated[texnum][0]) { byte blank[BLOCK_WIDTH*BLOCK_HEIGHT*3]; memset(blank, 0, sizeof(blank)); @@ -1475,33 +1533,19 @@ void GL_CreateSurfaceLightmap (msurface_t *surf) tmax = (surf->extents[1]>>4)+1; surf->lightmaptexturenum = AllocBlock (smax, tmax, &surf->light_s, &surf->light_t); + if (nosubimage || nosubimagefragments) + return; glBindTexture(GL_TEXTURE_2D, lightmap_textures + surf->lightmaptexturenum); - if (nosubimagefragments) + smax = ((surf->extents[0]>>4)+lightmapalign) & lightmapalignmask; + if (lightmaprgba) { - if (lightmaprgba) - { - R_BuildLightMap (surf, lightmaps[surf->lightmaptexturenum] + (surf->light_t * BLOCK_WIDTH + surf->light_s) * 4, BLOCK_WIDTH * 4); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, surf->light_t, BLOCK_WIDTH, tmax, GL_RGBA, GL_UNSIGNED_BYTE, lightmaps[surf->lightmaptexturenum] + surf->light_t * (BLOCK_WIDTH * 4)); - } - else - { - R_BuildLightMap (surf, lightmaps[surf->lightmaptexturenum] + (surf->light_t * BLOCK_WIDTH + surf->light_s) * 3, BLOCK_WIDTH * 3); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, surf->light_t, BLOCK_WIDTH, tmax, GL_RGB , GL_UNSIGNED_BYTE, lightmaps[surf->lightmaptexturenum] + surf->light_t * (BLOCK_WIDTH * 3)); - } + R_BuildLightMap (surf, templight, smax * 4); + glTexSubImage2D(GL_TEXTURE_2D, 0, surf->light_s, surf->light_t, smax, tmax, GL_RGBA, GL_UNSIGNED_BYTE, templight); } else { - smax = ((surf->extents[0]>>4)+lightmapalign) & lightmapalignmask; - if (lightmaprgba) - { - R_BuildLightMap (surf, templight, smax * 4); - glTexSubImage2D(GL_TEXTURE_2D, 0, surf->light_s, surf->light_t, smax, tmax, GL_RGBA, GL_UNSIGNED_BYTE, templight); - } - else - { - R_BuildLightMap (surf, templight, smax * 3); - glTexSubImage2D(GL_TEXTURE_2D, 0, surf->light_s, surf->light_t, smax, tmax, GL_RGB , GL_UNSIGNED_BYTE, templight); - } + R_BuildLightMap (surf, templight, smax * 3); + glTexSubImage2D(GL_TEXTURE_2D, 0, surf->light_s, surf->light_t, smax, tmax, GL_RGB , GL_UNSIGNED_BYTE, templight); } } @@ -1528,6 +1572,11 @@ void GL_BuildLightmaps (void) else nosubimagefragments = 0; + if (gl_nosubimage.value) + nosubimage = 1; + else + nosubimage = 0; + if (gl_lightmaprgba.value) { lightmaprgba = true; @@ -1551,7 +1600,7 @@ void GL_BuildLightmaps (void) lightmapalign <<= 1; gl_lightmapalign.value = lightmapalign; lightmapalignmask = ~(lightmapalign - 1); - if (nosubimagefragments) + if (nosubimagefragments || nosubimage) { lightmapalign = 1; lightmapalignmask = ~0; @@ -1582,5 +1631,27 @@ void GL_BuildLightmaps (void) BuildSurfaceDisplayList (m->surfaces + i); } } + + if (nosubimage || nosubimagefragments) + { + if (gl_mtexable) + qglSelectTexture(gl_mtex_enum+1); + for (i = 0;i < MAX_LIGHTMAPS;i++) + { + if (!allocated[i][0]) + break; + lightmapupdate[i][0] = BLOCK_HEIGHT; + lightmapupdate[i][1] = 0; + glBindTexture(GL_TEXTURE_2D, lightmap_textures + i); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if (lightmaprgba) + glTexImage2D(GL_TEXTURE_2D, 0, 4, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, lightmaps[i]); + else + glTexImage2D(GL_TEXTURE_2D, 0, 3, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, lightmaps[i]); + } + if (gl_mtexable) + qglSelectTexture(gl_mtex_enum+0); + } } diff --git a/gl_warp.c b/gl_warp.c index 1dd2b28b..79100183 100644 --- a/gl_warp.c +++ b/gl_warp.c @@ -304,6 +304,7 @@ void R_SkyBox() glEnd(); } +/* float skydomeouter[33*33*3]; float skydomeinner[33*33*3]; unsigned short skydomeindices[32*66]; @@ -403,15 +404,18 @@ void R_SkyDome() skydome(skydomeinner, speedscale, 1.0 / 128.0); glDisable (GL_BLEND); } +*/ void R_Sky() { + if (!skyname[0]) + return; glDisable(GL_DEPTH_TEST); glDepthMask(0); - if (skyname[0]) +// if (skyname[0]) R_SkyBox(); - else // classic quake sky - R_SkyDome(); +// else // classic quake sky +// R_SkyDome(); glDepthMask(1); glEnable (GL_DEPTH_TEST); glColor3f (1,1,1); diff --git a/glquake.h b/glquake.h index d77b3580..237c6caa 100644 --- a/glquake.h +++ b/glquake.h @@ -142,6 +142,7 @@ typedef struct particle_s int texnum; 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) } particle_t; diff --git a/host_cmd.c b/host_cmd.c index 97372b39..841ca3e8 100644 --- a/host_cmd.c +++ b/host_cmd.c @@ -32,15 +32,18 @@ Host_Quit_f ================== */ -extern void M_Menu_Quit_f (void); +// LordHavoc: didn't like it asking me if I wanted to quit +//extern void M_Menu_Quit_f (void); void Host_Quit_f (void) { + /* if (key_dest != key_console && cls.state != ca_dedicated) { M_Menu_Quit_f (); return; } + */ CL_Disconnect (); Host_ShutdownServer(false); diff --git a/mathlib.h b/mathlib.h index 19d9a808..0fb1067e 100644 --- a/mathlib.h +++ b/mathlib.h @@ -99,4 +99,6 @@ void BoxOnPlaneSideClassify(struct mplane_s *p); // BoxOnPlaneSide( (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) \ No newline at end of file +#define PlaneDiff(point,plane) ((plane)->type < 3 ? (point)[(plane)->type] - (plane)->dist : DotProduct((point), (plane)->normal) - (plane)->dist) + +#define lhrandom(MIN,MAX) ((rand() & 32767) * (((MAX)-(MIN)) * (1.0f / 32767.0f)) + (MIN)) diff --git a/model_alias.c b/model_alias.c index 4ea3403b..523c5a8d 100644 --- a/model_alias.c +++ b/model_alias.c @@ -34,7 +34,7 @@ aliashdr_t *pheader; typedef struct { int v[3]; - vec3_t n; + vec3_t normal; } temptris_t; temptris_t *temptris; //stvert_t stverts[MAXALIASVERTS]; @@ -57,7 +57,7 @@ void Mod_ConvertAliasVerts (int numverts, int numtris, vec3_t scale, vec3_t tran struct { vec3_t v; - vec3_t n; + vec3_t normal; int count; } tempvert[MD2MAX_VERTS]; temptris_t *tris; @@ -68,7 +68,7 @@ void Mod_ConvertAliasVerts (int numverts, int numtris, vec3_t scale, vec3_t tran tempvert[i].v[0] = v[i].v[0] * scale[0] + translate[0]; tempvert[i].v[1] = v[i].v[1] * scale[1] + translate[1]; tempvert[i].v[2] = v[i].v[2] * scale[2] + translate[2]; - tempvert[i].n[0] = tempvert[i].n[1] = tempvert[i].n[2] = 0; + tempvert[i].normal[0] = tempvert[i].normal[1] = tempvert[i].normal[2] = 0; tempvert[i].count = 0; // update bounding box if (tempvert[i].v[0] < aliasbboxmin[0]) aliasbboxmin[0] = tempvert[i].v[0]; @@ -84,12 +84,12 @@ void Mod_ConvertAliasVerts (int numverts, int numtris, vec3_t scale, vec3_t tran { VectorSubtract(tempvert[tris->v[0]].v, tempvert[tris->v[1]].v, t1); VectorSubtract(tempvert[tris->v[2]].v, tempvert[tris->v[1]].v, t2); - CrossProduct(t1, t2, tris->n); - VectorNormalize(tris->n); + CrossProduct(t1, t2, tris->normal); + VectorNormalize(tris->normal); // add surface normal to vertices for (j = 0;j < 3;j++) { - VectorAdd(tris->n, tempvert[tris->v[j]].n, tempvert[tris->v[j]].n); + VectorAdd(tris->normal, tempvert[tris->v[j]].normal, tempvert[tris->v[j]].normal); tempvert[tris->v[j]].count++; } tris++; @@ -97,10 +97,10 @@ void Mod_ConvertAliasVerts (int numverts, int numtris, vec3_t scale, vec3_t tran // average normals and write out 1.7bit format for (i = 0;i < pheader->numtris;i++) { - VectorNormalize(tempvert[i].n); - out[i].n[0] = (signed char) (tempvert[i].n[0] * 127.0); - out[i].n[1] = (signed char) (tempvert[i].n[1] * 127.0); - out[i].n[2] = (signed char) (tempvert[i].n[2] * 127.0); + VectorNormalize(tempvert[i].normal); + out[i].n[0] = (signed char) (tempvert[i].normal[0] * 127.0); + out[i].n[1] = (signed char) (tempvert[i].normal[1] * 127.0); + out[i].n[2] = (signed char) (tempvert[i].normal[2] * 127.0); } } diff --git a/r_part.c b/r_part.c index 5c822d9b..540494a8 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 2048 // default max # of particles at one +#define MAX_PARTICLES 4096 // default max # of particles at one // time #define ABSOLUTE_MIN_PARTICLES 512 // no fewer than this no matter what's // on the command line @@ -43,8 +43,7 @@ int r_numparticles; vec3_t r_pright, r_pup, r_ppn; -//extern cvar_t r_particles/*, r_smoke*/, r_smokealpha; -//cvar_t r_smokecolor = {"r_smokecolor", "0"}; +cvar_t r_particles = {"r_particles", "1", true}; void fractalnoise(char *noise, int size); void fractalnoise_zeroedge(char *noise, int size); @@ -53,15 +52,15 @@ void R_InitParticleTexture (void) { int x,y,d; float dx, dy, dz, f, dot; - byte data[64][64][4], noise1[64][64], noise2[64][64]; + byte data[32][32][4], noise1[32][32], noise2[32][32]; vec3_t normal, light; particletexture = texture_extension_number++; glBindTexture(GL_TEXTURE_2D, particletexture); - for (x=0 ; x<64 ; x++) + for (x=0 ; x<32 ; x++) { - for (y=0 ; y<64 ; y++) + for (y=0 ; y<32 ; y++) { data[y][x][0] = data[y][x][1] = data[y][x][2] = 255; dx = x - 16; @@ -71,7 +70,7 @@ void R_InitParticleTexture (void) data[y][x][3] = (byte) d; } } - glTexImage2D (GL_TEXTURE_2D, 0, 4, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + glTexImage2D (GL_TEXTURE_2D, 0, 4, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); @@ -79,10 +78,10 @@ void R_InitParticleTexture (void) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - fractalnoise(&noise1[0][0], 64); - fractalnoise(&noise2[0][0], 64); - for (y = 0;y < 64;y++) - for (x = 0;x < 64;x++) + fractalnoise(&noise1[0][0], 32); + fractalnoise(&noise2[0][0], 32); + for (y = 0;y < 32;y++) + for (x = 0;x < 32;x++) { data[y][x][0] = data[y][x][1] = data[y][x][2] = (noise1[y][x] >> 1) + 128; dx = x - 16; @@ -96,7 +95,7 @@ void R_InitParticleTexture (void) /* for (x=0 ; x<34 ; x+=2) for (y=0 ; y<34 ; y+=2) - data[y][x][0] = data[y][x][1] = data[y][x][2] = (rand()%64)+192; + data[y][x][0] = data[y][x][1] = data[y][x][2] = (rand()%32)+192; for (x=0 ; x<32 ; x+=2) for (y=0 ; y<32 ; y+=2) { @@ -104,11 +103,11 @@ void R_InitParticleTexture (void) data[y+1][x ][0] = data[y+1][x ][1] = data[y+1][x ][2] = (int) (data[y ][x ][0] + data[y+2][x ][0]) >> 1; data[y+1][x+1][0] = data[y+1][x+1][1] = data[y+1][x+1][2] = (int) (data[y ][x ][0] + data[y ][x+2][0] + data[y+2][x ][0] + data[y+2][x+2][0]) >> 2; } - for (x=0 ; x<64 ; x++) + for (x=0 ; x<32 ; x++) { - for (y=0 ; y<64 ; y++) + for (y=0 ; y<32 ; y++) { - //data[y][x][0] = data[y][x][1] = data[y][x][2] = (rand()%192)+64; + //data[y][x][0] = data[y][x][1] = data[y][x][2] = (rand()%192)+32; dx = x - 16; dy = y - 16; d = (255 - (dx*dx+dy*dy)); @@ -119,15 +118,15 @@ void R_InitParticleTexture (void) */ smokeparticletexture = texture_extension_number++; glBindTexture(GL_TEXTURE_2D, smokeparticletexture); - glTexImage2D (GL_TEXTURE_2D, 0, 4, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + glTexImage2D (GL_TEXTURE_2D, 0, 4, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - fractalnoise(&noise1[0][0], 64); - fractalnoise(&noise2[0][0], 64); - for (y = 0;y < 64;y++) - for (x = 0;x < 64;x++) + fractalnoise(&noise1[0][0], 32); + fractalnoise(&noise2[0][0], 32); + for (y = 0;y < 32;y++) + for (x = 0;x < 32;x++) { data[y][x][0] = data[y][x][1] = data[y][x][2] = (noise1[y][x] >> 1) + 128; dx = x - 16; @@ -140,7 +139,7 @@ void R_InitParticleTexture (void) bloodcloudparticletexture = texture_extension_number++; glBindTexture(GL_TEXTURE_2D, bloodcloudparticletexture); - glTexImage2D (GL_TEXTURE_2D, 0, 4, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + glTexImage2D (GL_TEXTURE_2D, 0, 4, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -148,9 +147,9 @@ void R_InitParticleTexture (void) flareparticletexture = texture_extension_number++; glBindTexture(GL_TEXTURE_2D, flareparticletexture); - for (x=0 ; x<64 ; x++) + for (x=0 ; x<32 ; x++) { - for (y=0 ; y<64 ; y++) + for (y=0 ; y<32 ; y++) { data[y][x][0] = data[y][x][1] = data[y][x][2] = 255; dx = x - 16; @@ -160,7 +159,7 @@ void R_InitParticleTexture (void) data[y][x][3] = (byte) d; } } - glTexImage2D (GL_TEXTURE_2D, 0, 4, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + glTexImage2D (GL_TEXTURE_2D, 0, 4, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); @@ -170,9 +169,9 @@ void R_InitParticleTexture (void) rainparticletexture = texture_extension_number++; glBindTexture(GL_TEXTURE_2D, rainparticletexture); - for (x=0 ; x<64 ; x++) + for (x=0 ; x<32 ; x++) { - for (y=0 ; y<64 ; y++) + for (y=0 ; y<32 ; y++) { data[y][x][0] = data[y][x][1] = data[y][x][2] = 255; if (y < 24) // stretch the upper half to make a raindrop @@ -191,7 +190,7 @@ void R_InitParticleTexture (void) data[y][x][3] = (byte) d; } } - glTexImage2D (GL_TEXTURE_2D, 0, 4, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + glTexImage2D (GL_TEXTURE_2D, 0, 4, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); @@ -203,9 +202,9 @@ void R_InitParticleTexture (void) light[0] = 1;light[1] = 1;light[2] = 1; VectorNormalize(light); - for (x=0 ; x<64 ; x++) + for (x=0 ; x<32 ; x++) { - for (y=0 ; y<64 ; y++) + for (y=0 ; y<32 ; y++) { data[y][x][0] = data[y][x][1] = data[y][x][2] = 255; dx = x * (1.0 / 16.0) - 1.0; @@ -230,15 +229,15 @@ void R_InitParticleTexture (void) f += ((dot * 2) - 1); else if (dot < -0.5) // exterior reflection f += ((dot * -2) - 1); - f *= 255; + f *= 64; f = bound(0, f, 255); - data[y][x][3] = (byte) d; + data[y][x][3] = (byte) f; } else data[y][x][3] = 0; } } - glTexImage2D (GL_TEXTURE_2D, 0, 4, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + glTexImage2D (GL_TEXTURE_2D, 0, 4, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); @@ -270,7 +269,7 @@ void R_InitParticles (void) particles = (particle_t *) Hunk_AllocName (r_numparticles * sizeof(particle_t), "particles"); -// Cvar_RegisterVariable (&r_smokecolor); + Cvar_RegisterVariable (&r_particles); R_InitParticleTexture (); } @@ -297,7 +296,7 @@ void R_EntityParticles (entity_t *ent) float sr, sp, sy, cr, cp, cy; vec3_t forward; float dist; -// if (!r_particles.value) return; // LordHavoc: particles are optional + if (!r_particles.value) return; // LordHavoc: particles are optional dist = 64; count = 50; @@ -452,7 +451,7 @@ void R_ParticleExplosion (vec3_t org, int smoke) { int i, j; particle_t *p; -// if (!r_particles.value) return; // LordHavoc: particles are optional + if (!r_particles.value) return; // LordHavoc: particles are optional for (i=0 ; i<1024 ; i++) { @@ -464,7 +463,7 @@ void R_ParticleExplosion (vec3_t org, int smoke) active_particles = p; p->texnum = flareparticletexture; - p->scale = 4+(rand()&7); + p->scale = lhrandom(2,5); p->alpha = rand()&255; p->die = cl.time + 5; p->color = ramp1[0]; @@ -497,7 +496,7 @@ void R_ParticleExplosion (vec3_t org, int smoke) active_particles = p; p->texnum = smokeparticletexture; - p->scale = 24; + p->scale = 12; p->alpha = 80; p->die = cl.time + 2; p->type = pt_smoke; @@ -522,7 +521,7 @@ void R_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength) int i, j; particle_t *p; int colorMod = 0; -// if (!r_particles.value) return; // LordHavoc: particles are optional + if (!r_particles.value) return; // LordHavoc: particles are optional for (i=0; i<512; i++) { @@ -534,7 +533,7 @@ void R_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength) active_particles = p; p->texnum = flareparticletexture; - p->scale = 8; + p->scale = 4; p->alpha = 255; p->die = cl.time + 0.3; p->color = colorStart + (colorMod % colorLength); @@ -559,7 +558,7 @@ void R_BlobExplosion (vec3_t org) { int i, j; particle_t *p; -// if (!r_particles.value) return; // LordHavoc: particles are optional + if (!r_particles.value) return; // LordHavoc: particles are optional for (i=0 ; i<1024 ; i++) { @@ -571,7 +570,7 @@ void R_BlobExplosion (vec3_t org) active_particles = p; p->texnum = flareparticletexture; - p->scale = 8; + p->scale = 4; p->alpha = 255; p->die = cl.time + 1 + (rand()&8)*0.05; @@ -608,7 +607,7 @@ void R_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count) { int i, j; particle_t *p; -// if (!r_particles.value) return; // LordHavoc: particles are optional + if (!r_particles.value) return; // LordHavoc: particles are optional for (i=0 ; itexnum = flareparticletexture; - p->scale = 8; + p->scale = 4; p->alpha = 255; p->die = cl.time + 5; p->color = ramp1[0]; @@ -649,7 +648,7 @@ void R_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count) else { p->texnum = flareparticletexture; - p->scale = 8; + p->scale = 4; p->alpha = 255; p->die = cl.time + 0.1*(rand()%5); p->color = (color&~7) + (rand()&7); @@ -674,7 +673,7 @@ void R_SparkShower (vec3_t org, vec3_t dir, int count, int type) { int i, j; particle_t *p; -// if (!r_particles.value) return; // LordHavoc: particles are optional + if (!r_particles.value) return; // LordHavoc: particles are optional if (!free_particles) return; @@ -685,7 +684,7 @@ void R_SparkShower (vec3_t org, vec3_t dir, int count, int type) if (type == 0) // sparks { p->texnum = smokeparticletexture; - p->scale = 20; + p->scale = 10; p->alpha = 64; p->color = (rand()&3)+12; p->type = pt_bulletpuff; @@ -696,7 +695,7 @@ void R_SparkShower (vec3_t org, vec3_t dir, int count, int type) else // blood { p->texnum = bloodcloudparticletexture; - p->scale = 24; + p->scale = 12; p->alpha = 128; p->color = (rand()&3)+68; p->type = pt_bloodcloud; @@ -715,7 +714,7 @@ void R_SparkShower (vec3_t org, vec3_t dir, int count, int type) active_particles = p; p->texnum = flareparticletexture; - p->scale = 5; + p->scale = 2; p->alpha = 255; p->die = cl.time + 0.0625 * (rand()&15); /* @@ -753,7 +752,7 @@ void R_BloodShower (vec3_t mins, vec3_t maxs, float velspeed, int count) vec3_t diff; vec3_t center; vec3_t velscale; -// if (!r_particles.value) return; // LordHavoc: particles are optional + if (!r_particles.value) return; // LordHavoc: particles are optional VectorSubtract(maxs, mins, diff); center[0] = (mins[0] + maxs[0]) * 0.5; @@ -773,7 +772,7 @@ void R_BloodShower (vec3_t mins, vec3_t maxs, float velspeed, int count) active_particles = p; p->texnum = bloodcloudparticletexture; - p->scale = 24; + p->scale = 12; p->alpha = 96 + (rand()&63); p->die = cl.time + 2; //0.015625 * (rand()%128); p->type = pt_fadespark; @@ -793,7 +792,7 @@ void R_ParticleCube (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int colorb particle_t *p; vec3_t diff; float t; -// if (!r_particles.value) return; // LordHavoc: particles are optional + if (!r_particles.value) return; // LordHavoc: particles are optional if (maxs[0] <= mins[0]) {t = mins[0];mins[0] = maxs[0];maxs[0] = t;} if (maxs[1] <= mins[1]) {t = mins[1];mins[1] = maxs[1];maxs[1] = t;} if (maxs[2] <= mins[2]) {t = mins[2];mins[2] = maxs[2];maxs[2] = t;} @@ -810,7 +809,7 @@ void R_ParticleCube (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int colorb active_particles = p; p->texnum = flareparticletexture; - p->scale = 12; + p->scale = 6; p->alpha = 255; p->die = cl.time + 1 + (rand()&15)*0.0625; if (gravity) @@ -837,7 +836,7 @@ void R_ParticleRain (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int colorb vec3_t org; vec3_t vel; float t, z; -// if (!r_particles.value) return; // LordHavoc: particles are optional + if (!r_particles.value) return; // LordHavoc: particles are optional if (maxs[0] <= mins[0]) {t = mins[0];mins[0] = maxs[0];maxs[0] = t;} if (maxs[1] <= mins[1]) {t = mins[1];mins[1] = maxs[1];maxs[1] = t;} if (maxs[2] <= mins[2]) {t = mins[2];mins[2] = maxs[2];maxs[2] = t;} @@ -873,7 +872,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->scale = 6; + p->scale = 1.5; p->alpha = 255; p->die = t; if (type == 1) @@ -889,6 +888,7 @@ void R_ParticleRain (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int colorb p->color = colorbase + (rand()&3); VectorCopy(org, p->org); VectorCopy(vel, p->vel); + VectorCopy(vel, p->vel2); } } @@ -905,7 +905,7 @@ void R_LavaSplash (vec3_t org) particle_t *p; float vel; vec3_t dir; -// if (!r_particles.value) return; // LordHavoc: particles are optional + if (!r_particles.value) return; // LordHavoc: particles are optional for (i=-16 ; i<16 ; i+=2) for (j=-16 ; j<16 ; j+=2) @@ -919,8 +919,8 @@ void R_LavaSplash (vec3_t org) active_particles = p; p->texnum = flareparticletexture; - p->scale = 24; - p->alpha = 255; + p->scale = 10; + p->alpha = 128; p->die = cl.time + 2 + (rand()&31) * 0.02; p->color = 224 + (rand()&7); p->type = pt_slowgrav; @@ -950,7 +950,7 @@ void R_TeleportSplash (vec3_t org) int i, j, k; particle_t *p; // vec3_t dir; -// if (!r_particles.value) return; // LordHavoc: particles are optional + if (!r_particles.value) return; // LordHavoc: particles are optional /* for (i=-16 ; i<16 ; i+=4) @@ -997,7 +997,7 @@ void R_TeleportSplash (vec3_t org) active_particles = p; p->texnum = flareparticletexture; - p->scale = 8; + p->scale = 4; p->alpha = (1 + rand()&7) * 32; p->die = cl.time + 5; p->color = 254; //8 + (rand()&7); @@ -1020,7 +1020,7 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) int j, contents, bubbles; particle_t *p; static int tracercount; -// if (!r_particles.value) return; // LordHavoc: particles are optional + if (!r_particles.value) return; // LordHavoc: particles are optional t = cl.oldtime; nt = cl.time; @@ -1061,14 +1061,11 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) case 1: // grenade trail if (bubbles) { - dec = 0.01f; + dec = 0.005f; p->texnum = bubbleparticletexture; - p->scale = 6+(rand()&3); + p->scale = lhrandom(1,2); p->alpha = 255; -// if (r_smokecolor.value) -// p->color = r_smokecolor.value; -// else - p->color = (rand()&3)+12; + p->color = (rand()&3)+12; p->type = pt_bubble; p->die = cl.time + 2; for (j=0 ; j<3 ; j++) @@ -1079,16 +1076,13 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) } else { - dec = 0.03f; + dec = 0.02f; p->texnum = smokeparticletexture; - p->scale = 12+(rand()&7); + p->scale = lhrandom(4, 7); p->alpha = 64 + (rand()&31); -// if (r_smokecolor.value) -// p->color = r_smokecolor.value; -// else - p->color = (rand()&3)+12; + p->color = (rand()&3)+12; p->type = pt_smoke; - p->die = cl.time + 2; + p->die = cl.time + 10000; VectorCopy(start, p->org); } break; @@ -1097,7 +1091,7 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) case 1: // smoke smoke dec = 0.016f; p->texnum = smokeparticletexture; - p->scale = 12+rand()&7; + p->scale = lhrandom(6,9); p->alpha = 64; if (r_smokecolor.value) p->color = r_smokecolor.value; @@ -1112,7 +1106,7 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) case 2: // blood dec = 0.03f; p->texnum = bloodcloudparticletexture; - p->scale = 20+(rand()&7); + p->scale = lhrandom(8, 12); p->alpha = 255; p->color = (rand()&3)+68; p->type = pt_bloodcloud; @@ -1128,7 +1122,7 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) case 5: // tracer dec = 0.01f; p->texnum = flareparticletexture; - p->scale = 4; + p->scale = 2; p->alpha = 255; p->die = cl.time + 0.2; //5; p->type = pt_static; @@ -1155,7 +1149,7 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) case 4: // slight blood dec = 0.03f; // sparse trail p->texnum = bloodcloudparticletexture; - p->scale = 20+(rand()&7); + p->scale = lhrandom(8,12); p->alpha = 255; p->color = (rand()&3)+68; p->type = pt_fadespark2; @@ -1170,7 +1164,7 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) case 6: // voor trail dec = 0.05f; // sparse trail p->texnum = flareparticletexture; - p->scale = 20+(rand()&7); + p->scale = lhrandom(4, 8); p->alpha = 255; p->color = 9*16 + 8 + (rand()&3); p->type = pt_fadespark2; @@ -1185,11 +1179,11 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) case 7: // Nehahra smoke tracer dec = 0.14f; p->texnum = smokeparticletexture; - p->scale = 12+(rand()&7); + p->scale = lhrandom(6, 10); p->alpha = 64; p->color = (rand()&3)+12; p->type = pt_smoke; - p->die = cl.time + 1; + p->die = cl.time + 10000; for (j=0 ; j<3 ; j++) p->org[j] = start[j] + ((rand()&3)-2); break; @@ -1208,7 +1202,7 @@ void R_RocketTrail2 (vec3_t start, vec3_t end, int color, entity_t *ent) float len; particle_t *p; static int tracercount; -// if (!r_particles.value) return; // LordHavoc: particles are optional + if (!r_particles.value) return; // LordHavoc: particles are optional VectorSubtract (end, start, vec); len = VectorNormalizeLength (vec); @@ -1226,7 +1220,7 @@ void R_RocketTrail2 (vec3_t start, vec3_t end, int color, entity_t *ent) VectorCopy (vec3_origin, p->vel); p->texnum = flareparticletexture; - p->scale = 16; + p->scale = 8; p->alpha = 192; p->color = color; p->type = pt_smoke; @@ -1240,7 +1234,6 @@ void R_RocketTrail2 (vec3_t start, vec3_t end, int color, entity_t *ent) } -//extern qboolean isG200, isATI, isRagePro; extern qboolean lighthalf; /* @@ -1253,7 +1246,7 @@ extern cvar_t sv_gravity; void R_DrawParticles (void) { particle_t *p, *kill; - int i, /*texnum, */r,g,b,a; + int i, r,g,b,a; float grav, grav1, time1, time2, time3, dvel, frametime, scale, scale2; byte *color24; vec3_t up, right, uprightangles, forward2, up2, right2, v; @@ -1262,23 +1255,6 @@ void R_DrawParticles (void) if (!active_particles) return; - /* - texnum = particletexture; - glBindTexture(GL_TEXTURE_2D, texnum); - glEnable (GL_BLEND); - // LordHavoc: Matrox G200 cards can't handle per pixel alpha at all... - // and ATI Rage Pro can't modulate a per pixel alpha texture - if (isG200 || isRagePro) - glEnable(GL_ALPHA_TEST); - else - glDisable(GL_ALPHA_TEST); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDepthMask(0); // disable zbuffer updates - glShadeModel(GL_FLAT); - glBegin (GL_TRIANGLES); - */ - VectorScale (vup, 1.5, up); VectorScale (vright, 1.5, right); @@ -1328,51 +1304,7 @@ void R_DrawParticles (void) VectorSubtract(p->org, r_refdef.vieworg, v); if (DotProduct(v, v) >= 256.0f) { - scale = p->scale * -0.25;scale2 = p->scale * 0.75; - /* - if (p->texnum != texnum) - { - texnum = p->texnum; - glEnd(); - glBindTexture(GL_TEXTURE_2D, texnum); - glBegin(GL_TRIANGLES); - } - if (lighthalf) - { - color24 = (byte *)&d_8to24table[(int)p->color]; - if (p->texnum == smokeparticletexture) - glColor4ub((byte) (color24[0] >> 1), (byte) (color24[1] >> 1), (byte) (color24[2] >> 1), (byte) (p->alpha*r_smokealpha.value)); - else - glColor4ub((byte) (color24[0] >> 1), (byte) (color24[1] >> 1), (byte) (color24[2] >> 1), (byte) p->alpha); - } - else - { - color24 = (byte *) &d_8to24table[(int)p->color]; - if (p->texnum == smokeparticletexture) - glColor4ub(color24[0], color24[1], color24[2], (byte) (p->alpha*r_smokealpha.value)); - else - glColor4ub(color24[0], color24[1], color24[2], (byte) p->alpha); - } - if (p->texnum == rainparticletexture) // rain streak - { - glTexCoord2f (0,0); - glVertex3f (p->org[0] + right2[0]*scale , p->org[1] + right2[1]*scale , p->org[2] + right2[2]*scale ); - glTexCoord2f (1,0); - glVertex3f (p->org[0] + right2[0]*scale , p->org[1] + right2[1]*scale , p->org[2] + right2[2]*scale ); - glTexCoord2f (0,1); - glVertex3f (p->org[0] + right2[0]*scale2, p->org[1] + right2[1]*scale2, p->org[2] + right2[2]*scale2); - } - else - { - glTexCoord2f (0,0); - // LordHavoc: centered particle sprites - glVertex3f (p->org[0] + up[0]*scale + right[0]*scale , p->org[1] + up[1]*scale + right[1]*scale , p->org[2] + up[2]*scale + right[2]*scale ); - glTexCoord2f (1,0); - glVertex3f (p->org[0] + up[0]*scale2 + right[0]*scale , p->org[1] + up[1]*scale2 + right[1]*scale , p->org[2] + up[2]*scale2 + right[2]*scale ); - glTexCoord2f (0,1); - glVertex3f (p->org[0] + up[0]*scale + right[0]*scale2, p->org[1] + up[1]*scale + right[1]*scale2, p->org[2] + up[2]*scale + right[2]*scale2); - } - */ + scale = p->scale * -0.5;scale2 = p->scale * 0.5; color24 = (byte *) &d_8to24table[(int)p->color]; r = color24[0]; g = color24[1]; @@ -1387,15 +1319,17 @@ void R_DrawParticles (void) transpolybegin(p->texnum, 0, p->texnum, TPOLYTYPE_ALPHA); if (p->texnum == rainparticletexture) // rain streak { - transpolyvert(p->org[0] + right2[0]*scale , p->org[1] + right2[1]*scale , p->org[2] + right2[2]*scale , 0,0,r,g,b,a); - transpolyvert(p->org[0] + right2[0]*scale , p->org[1] + right2[1]*scale , p->org[2] + right2[2]*scale , 1,0,r,g,b,a); - transpolyvert(p->org[0] + right2[0]*scale2, p->org[1] + right2[1]*scale2, p->org[2] + right2[2]*scale2, 0,1,r,g,b,a); + transpolyvert(p->org[0] + up2[0]*scale + right2[0]*scale , p->org[1] + up2[1]*scale + right2[1]*scale , p->org[2] + up2[2]*scale + right2[2]*scale , 0,1,r,g,b,a); + transpolyvert(p->org[0] + up2[0]*scale2 + right2[0]*scale , p->org[1] + up2[1]*scale2 + right2[1]*scale , p->org[2] + up2[2]*scale2 + right2[2]*scale , 0,0,r,g,b,a); + transpolyvert(p->org[0] + up2[0]*scale2 + right2[0]*scale2, p->org[1] + up2[1]*scale2 + right2[1]*scale2, p->org[2] + up2[2]*scale2 + right2[2]*scale2, 1,0,r,g,b,a); + transpolyvert(p->org[0] + up2[0]*scale + right2[0]*scale2, p->org[1] + up2[1]*scale + right2[1]*scale2, p->org[2] + up2[2]*scale + right2[2]*scale2, 1,1,r,g,b,a); } else { - transpolyvert(p->org[0] + up[0]*scale + right[0]*scale , p->org[1] + up[1]*scale + right[1]*scale , p->org[2] + up[2]*scale + right[2]*scale , 0,0,r,g,b,a); - transpolyvert(p->org[0] + up[0]*scale2 + right[0]*scale , p->org[1] + up[1]*scale2 + right[1]*scale , p->org[2] + up[2]*scale2 + right[2]*scale , 1,0,r,g,b,a); - transpolyvert(p->org[0] + up[0]*scale + right[0]*scale2, p->org[1] + up[1]*scale + right[1]*scale2, p->org[2] + up[2]*scale + right[2]*scale2, 0,1,r,g,b,a); + transpolyvert(p->org[0] + up[0]*scale + right[0]*scale , p->org[1] + up[1]*scale + right[1]*scale , p->org[2] + up[2]*scale + right[2]*scale , 0,1,r,g,b,a); + transpolyvert(p->org[0] + up[0]*scale2 + right[0]*scale , p->org[1] + up[1]*scale2 + right[1]*scale , p->org[2] + up[2]*scale2 + right[2]*scale , 0,0,r,g,b,a); + transpolyvert(p->org[0] + up[0]*scale2 + right[0]*scale2, p->org[1] + up[1]*scale2 + right[1]*scale2, p->org[2] + up[2]*scale2 + right[2]*scale2, 1,0,r,g,b,a); + transpolyvert(p->org[0] + up[0]*scale + right[0]*scale2, p->org[1] + up[1]*scale + right[1]*scale2, p->org[2] + up[2]*scale + right[2]*scale2, 1,1,r,g,b,a); } transpolyend(); } @@ -1407,6 +1341,8 @@ void R_DrawParticles (void) switch (p->type) { case pt_static: + if (Mod_PointInLeaf(p->org, cl.worldmodel)->contents == CONTENTS_SOLID) + p->die = -1; break; case pt_fire: p->ramp += time1; @@ -1415,6 +1351,8 @@ void R_DrawParticles (void) else p->color = ramp3[(int)p->ramp]; p->vel[2] += grav; + if (Mod_PointInLeaf(p->org, cl.worldmodel)->contents == CONTENTS_SOLID) + p->die = -1; break; case pt_explode: @@ -1431,7 +1369,7 @@ void R_DrawParticles (void) case pt_explode2: p->ramp += time3; - if (p->ramp >=8) + if (p->ramp >= 8 || Mod_PointInLeaf(p->org, cl.worldmodel)->contents == CONTENTS_SOLID) p->die = -1; else p->color = ramp2[(int)p->ramp]; @@ -1445,25 +1383,33 @@ void R_DrawParticles (void) for (i=0 ; i<3 ; i++) p->vel[i] += p->vel[i]*dvel; p->vel[2] -= grav; + if (Mod_PointInLeaf(p->org, cl.worldmodel)->contents == CONTENTS_SOLID) + p->die = -1; break; case pt_blob2: for (i=0 ; i<2 ; i++) p->vel[i] -= p->vel[i]*dvel; p->vel[2] -= grav; + if (Mod_PointInLeaf(p->org, cl.worldmodel)->contents == CONTENTS_SOLID) + p->die = -1; break; case pt_grav: p->vel[2] -= grav1; + if (Mod_PointInLeaf(p->org, cl.worldmodel)->contents == CONTENTS_SOLID) + p->die = -1; break; case pt_slowgrav: p->vel[2] -= grav; + if (Mod_PointInLeaf(p->org, cl.worldmodel)->contents == CONTENTS_SOLID) + p->die = -1; break; // LordHavoc: gunshot spark showers case pt_dust: p->ramp += time1; p->scale -= frametime * 4; - if (p->ramp >= 8 || p->scale <= 0) + if (p->ramp >= 8 || p->scale <= 0 || Mod_PointInLeaf(p->org, cl.worldmodel)->contents == CONTENTS_SOLID) p->die = -1; else p->color = ramp3[(int)p->ramp]; @@ -1471,18 +1417,21 @@ void R_DrawParticles (void) break; // LordHavoc: for smoke trails case pt_smoke: - p->scale += frametime * 16; - p->alpha -= frametime * 64; - p->vel[2] += grav; + p->scale += frametime * 4; + p->alpha -= frametime * 48; +// p->vel[2] += grav; if (p->alpha < 1) p->die = -1; break; case pt_snow: if (cl.time > p->time2) { - p->time2 = cl.time + 0.4; - p->vel[0] = (rand()&63)-32; - p->vel[1] = (rand()&63)-32; + p->time2 = cl.time + (rand() & 3) * 0.1; + p->vel[0] = (rand()&63)-32 + p->vel2[0]; + p->vel[1] = (rand()&63)-32 + p->vel2[1]; + p->vel[2] = (rand()&63)-32 + p->vel2[2]; + if (Mod_PointInLeaf(p->org, cl.worldmodel)->contents != CONTENTS_EMPTY) + p->die = -1; } break; case pt_bulletpuff: @@ -1502,49 +1451,42 @@ void R_DrawParticles (void) case pt_fadespark: p->alpha -= frametime * 256; p->vel[2] -= grav; - if (p->alpha < 1) + if (p->alpha < 1 || Mod_PointInLeaf(p->org, cl.worldmodel)->contents == CONTENTS_SOLID) p->die = -1; break; case pt_fadespark2: p->alpha -= frametime * 512; p->vel[2] -= grav; - if (p->alpha < 1) + if (p->alpha < 1 || Mod_PointInLeaf(p->org, cl.worldmodel)->contents == CONTENTS_SOLID) p->die = -1; break; case pt_fallfadespark: p->alpha -= frametime * 256; p->vel[2] -= grav1; - if (p->alpha < 1) + if (p->alpha < 1 || Mod_PointInLeaf(p->org, cl.worldmodel)->contents == CONTENTS_SOLID) p->die = -1; break; case pt_fallfadespark2: p->alpha -= frametime * 512; p->vel[2] -= grav1; - if (p->alpha < 1) + if (p->alpha < 1 || Mod_PointInLeaf(p->org, cl.worldmodel)->contents == CONTENTS_SOLID) p->die = -1; break; case pt_bubble: - p->vel[2] += grav1; - if (p->vel[2] >= 100) - p->vel[2] = 68+rand()&31; + p->vel[2] += grav1 * 2; + if (p->vel[2] >= 200) + p->vel[2] = 136+rand()&63; if (cl.time > p->time2) { p->time2 = cl.time + (rand()&7)*0.0625; p->vel[0] = (rand()&63)-32; p->vel[1] = (rand()&63)-32; } - p->alpha -= frametime * 32; - if (p->alpha < 1) + p->alpha -= frametime * 64; + if (p->alpha < 1 || Mod_PointInLeaf(p->org, cl.worldmodel)->contents == CONTENTS_EMPTY) p->die = -1; break; } } - - /* - glEnd (); - glShadeModel(GL_SMOOTH); - glDepthMask(1); // enable zbuffer updates - glDisable (GL_BLEND); - */ } -- 2.39.2