From: lordhavoc Date: Fri, 20 Apr 2001 15:38:28 +0000 (+0000) Subject: added newmap function to render modules (so explosions and other things are reset... X-Git-Tag: RELEASE_0_2_0_RC1~839 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=4d162c39ec059b7f3191fbb4fb18304bc9b1db59;p=xonotic%2Fdarkplaces.git added newmap function to render modules (so explosions and other things are reset on map load) CL_AllocDlight redesigned (takes all settings for dlight on parameter line) dlights now use a pointer to their owner entity instead of a key number light emitting entities now glow properly (directional lighting disabled on the entity that owns the dlight) cl_shownet no longer spews empty lines when recieving less updates from server than client framerate some whitespace cleanup fixed some missing parentheses on a condition in R_BuildLightmap (mixed &&, &, and ||, eek) fixed vertex array problems with fog sky increased MAX_TRANSPOLYS from 8192 to 65536 added a general purpose decal engine, superior to the decal particles (lower CPU use, better lighting) added bullet hole decals and bullet hole texture generator added r_speeds2 time reporting for moveexplosions, drawexplosions, and drawdecals cleaned up dlight logic, all code now relies on radius, which is cleared when the dlight dies, this removed all potential flickering problems and offers a minor speedup optimized R_ResampleTexture further to improve load times moved heap size commandline parameter stuff from platform specific startup code to Host_Init, now all platforms understand -mem, -winmem, and -heapsize WAD3 texture transparency now supported again r_explosionclip cvar is now saved to config r_drawexplosions cvar added r_particles cvar is now saved to config r_dynamicparticles cvar renamed to r_particles_lighting r_particles_bloodshowers cvar added to disable blood shower effects r_particles_blood cvar added to disable blood effects r_particles_smoke cvar added to disable smoke effects r_particles_sparks cvar added to disable spark effects r_particles_bubbles cvar added to disable bubble effects fixed smoke texture problem (0 alpha-noise portions were not written to texture, leaving portions of previous texture in buffer) changed nearly every particle effect to look better and use less particles and fillrate, major speed gains resulted blood particles no longer fade inflight as it made the effects less impressive and resulted in a lot of mostly transparent decals major particle size bug fixed, all view aligned particles (everything but rain and decals) were 50% larger than they were supposed to be particles now use transpolyvertub (unsigned byte colors) instead of transpolyvert for a speedup git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@189 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cl_effects.c b/cl_effects.c index 61630a22..01bea5c9 100644 --- a/cl_effects.c +++ b/cl_effects.c @@ -51,11 +51,16 @@ void r_effects_shutdown() { } +void r_effects_newmap() +{ + memset(effect, 0, sizeof(effect)); +} + void CL_Effects_Init() { Cvar_RegisterVariable(&r_draweffects); - R_RegisterModule("R_Effects", r_effects_start, r_effects_shutdown); + R_RegisterModule("R_Effects", r_effects_start, r_effects_shutdown, r_effects_newmap); } void CL_Effect(vec3_t org, int modelindex, int startframe, int framecount, float framerate) diff --git a/cl_main.c b/cl_main.c index 7a6623a1..40b42ebb 100644 --- a/cl_main.c +++ b/cl_main.c @@ -286,42 +286,39 @@ CL_AllocDlight =============== */ -dlight_t *CL_AllocDlight (int key) +void CL_AllocDlight (entity_t *ent, vec3_t org, float radius, float red, float green, float blue, float decay, float lifetime) { int i; dlight_t *dl; // first look for an exact key match - if (key) + if (ent) { dl = cl_dlights; - for (i=0 ; ikey == key) - { - memset (dl, 0, sizeof(*dl)); - dl->key = key; - return dl; - } - } + for (i = 0;i < MAX_DLIGHTS;i++, dl++) + if (dl->ent == ent) + goto dlightsetup; } // then look for anything else dl = cl_dlights; - for (i=0 ; idie < cl.time) - { - memset (dl, 0, sizeof(*dl)); - dl->key = key; - return dl; - } - } + for (i = 0;i < MAX_DLIGHTS;i++, dl++) + if (!dl->radius) + goto dlightsetup; - dl = &cl_dlights[0]; + // unable to find one + return; + +dlightsetup: memset (dl, 0, sizeof(*dl)); - dl->key = key; - return dl; + dl->ent = ent; + VectorCopy(org, dl->origin); + dl->radius = radius; + dl->color[0] = red; + dl->color[1] = green; + dl->color[2] = blue; + dl->decay = decay; + dl->die = cl.time + lifetime; } @@ -343,8 +340,13 @@ void CL_DecayLights (void) dl = cl_dlights; for (i=0 ; idie < cl.time || !dl->radius) + if (!dl->radius) + continue; + if (dl->die < cl.time) + { + dl->radius = 0; continue; + } c_dlights++; // count every dlight in use @@ -420,8 +422,6 @@ void CL_RelinkEntities (void) vec3_t delta; float bobjrotate; vec3_t oldorg; - dlight_t *dl; - byte *tempcolor; // determine partial update time frac = CL_LerpPoint (); @@ -481,7 +481,7 @@ void CL_RelinkEntities (void) else { // if the delta is large, assume a teleport and don't lerp f = frac; - for (j=0 ; j<3 ; j++) + for (j = 0;j < 3;j++) { delta[j] = ent->msg_origins[0][j] - ent->msg_origins[1][j]; // LordHavoc: increased lerp tolerance from 100 to 200 @@ -490,7 +490,7 @@ void CL_RelinkEntities (void) } // interpolate the origin and angles - for (j=0 ; j<3 ; j++) + for (j = 0;j < 3;j++) { ent->origin[j] = ent->msg_origins[1][j] + f*delta[j]; @@ -508,63 +508,30 @@ void CL_RelinkEntities (void) R_EntityParticles (ent); if (ent->effects & EF_MUZZLEFLASH) { - vec3_t fv; - - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->origin[2] += 16; - AngleVectors (ent->angles, fv, NULL, NULL); - - VectorMA (dl->origin, 18, fv, dl->origin); - dl->radius = 100 + (rand()&31); - dl->die = cl.time + 0.1; - dl->color[0] = 1.0;dl->color[1] = 1.0;dl->color[2] = 1.0; + vec3_t v; + + AngleVectors (ent->angles, v, NULL, NULL); + + v[0] = v[0] * 18 + ent->origin[0]; + v[1] = v[1] * 18 + ent->origin[1]; + v[2] = v[2] * 18 + ent->origin[2] + 16; + + CL_AllocDlight (ent, v, 100, 1, 1, 1, 0, 0.1); } if (ent->effects & EF_BRIGHTLIGHT) - { - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->origin[2] += 16; - dl->radius = 400 + (rand()&31); - dl->die = cl.time + 0.001; - dl->color[0] = 1.0;dl->color[1] = 1.0;dl->color[2] = 1.0; - } + CL_AllocDlight (ent, ent->origin, 400, 1, 1, 1, 0, 0); if (ent->effects & EF_DIMLIGHT) - { - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->radius = 200 + (rand()&31); - dl->die = cl.time + 0.001; - dl->color[0] = 1.0;dl->color[1] = 1.0;dl->color[2] = 1.0; - } + CL_AllocDlight (ent, ent->origin, 200, 1, 1, 1, 0, 0); // LordHavoc: added EF_RED and EF_BLUE if (ent->effects & EF_RED) // red { if (ent->effects & EF_BLUE) // magenta - { - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->radius = 200 + (rand()&31); - dl->die = cl.time + 0.001; - dl->color[0] = 0.7;dl->color[1] = 0.07;dl->color[2] = 0.7; - } + CL_AllocDlight (ent, ent->origin, 200, 1.0f, 0.2f, 1.0f, 0, 0); else // red - { - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->radius = 200 + (rand()&31); - dl->die = cl.time + 0.001; - dl->color[0] = 0.8;dl->color[1] = 0.05;dl->color[2] = 0.05; - } + CL_AllocDlight (ent, ent->origin, 200, 1.0f, 0.1f, 0.1f, 0, 0); } else if (ent->effects & EF_BLUE) // blue - { - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->radius = 200 + (rand()&31); - dl->die = cl.time + 0.001; - dl->color[0] = 0.05;dl->color[1] = 0.05;dl->color[2] = 0.8; - } + CL_AllocDlight (ent, ent->origin, 200, 0.1f, 0.1f, 1.0f, 0, 0); else if (ent->effects & EF_FLAME) { if (ent->model) @@ -574,15 +541,10 @@ void CL_RelinkEntities (void) VectorAdd(ent->origin, ent->model->mins, mins); VectorAdd(ent->origin, ent->model->maxs, maxs); // how many flames to make - temp = (int) (cl.time * 30) - (int) (cl.oldtime * 30); + temp = (int) (cl.time * 300) - (int) (cl.oldtime * 300); R_FlameCube(mins, maxs, temp); } - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->radius = 200 + (rand()&31); - dl->die = cl.time + 0.25; - dl->decay = dl->radius * 4; - dl->color[0] = 1.0;dl->color[1] = 0.7;dl->color[2] = 0.3; + CL_AllocDlight (ent, ent->origin, lhrandom(200, 250), 1.0f, 0.7f, 0.3f, 0, 0); } if (ent->model->flags) // LordHavoc: if the model has no flags, don't check each @@ -601,11 +563,7 @@ void CL_RelinkEntities (void) else if (ent->model->flags & EF_ROCKET) { R_RocketTrail (oldorg, ent->origin, 0, ent); - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->radius = 200; - dl->die = cl.time + 0.001; - dl->color[0] = 1.0;dl->color[1] = 0.8;dl->color[2] = 0.4; + CL_AllocDlight (ent, ent->origin, 200, 1.0f, 0.8f, 0.4f, 0, 0); } else if (ent->model->flags & EF_GRENADE) { @@ -619,12 +577,8 @@ void CL_RelinkEntities (void) } if (ent->glowsize) // LordHavoc: customizable glow { - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->radius = ent->glowsize; - 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); + byte *tempcolor = (byte *)&d_8to24table[ent->glowcolor]; + CL_AllocDlight (ent, ent->origin, ent->glowsize, tempcolor[0]*(1.0/255.0), tempcolor[1]*(1.0/255.0), tempcolor[2]*(1.0/255.0), 0, 0); } if (ent->glowtrail) // LordHavoc: customizable glow and trail R_RocketTrail2 (oldorg, ent->origin, ent->glowcolor, ent); @@ -640,10 +594,12 @@ void CL_RelinkEntities (void) if (cl_numvisedicts < MAX_VISEDICTS) cl_visedicts[cl_numvisedicts++] = ent; } - } +// used by cl_shownet +int netshown; + /* =============== CL_ReadFromServer @@ -658,6 +614,7 @@ int CL_ReadFromServer (void) cl.oldtime = cl.time; cl.time += cl.frametime; + netshown = false; do { ret = CL_GetMessage (); @@ -670,7 +627,7 @@ int CL_ReadFromServer (void) CL_ParseServerMessage (); } while (ret && cls.state == ca_connected); - if (cl_shownet.value) + if (netshown) Con_Printf ("\n"); CL_RelinkEntities (); diff --git a/cl_parse.c b/cl_parse.c index 368bf3da..d856ce11 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -822,6 +822,7 @@ void CL_ParseEffect2 (void) extern void SHOWLMP_decodehide(); extern void SHOWLMP_decodeshow(); extern void R_SetSkyBox(char* sky); +extern int netshown; /* ===================== @@ -840,9 +841,15 @@ void CL_ParseServerMessage (void) // if recording demos, copy the message out // if (cl_shownet.value == 1) + { Con_Printf ("%i ",net_message.cursize); + netshown = true; + } else if (cl_shownet.value == 2) + { Con_Printf ("------------------\n"); + netshown = true; + } cl.onground = false; // unless the server says otherwise // diff --git a/cl_tent.c b/cl_tent.c index 1046cbc6..363ca591 100644 --- a/cl_tent.c +++ b/cl_tent.c @@ -127,10 +127,9 @@ void CL_ParseTEnt (void) vec3_t pos; vec3_t dir; vec3_t pos2; - dlight_t *dl; int rnd; int colorStart, colorLength, count; - float velspeed; + float velspeed, radius; byte *tempcolor; type = MSG_ReadByte (); @@ -171,12 +170,7 @@ void CL_ParseTEnt (void) // LordHavoc: changed to spark shower R_SparkShower(pos, vec3_origin, 15); //R_RunParticleEffect (pos, vec3_origin, 0, 10); - dl = CL_AllocDlight (0); - VectorCopy (pos, dl->origin); - dl->radius = 200; - dl->die = cl.time + 0.2; - dl->decay = 1000; - dl->color[0] = 0.05;dl->color[1] = 0.05;dl->color[2] = 0.8; + CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2); S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); if ( rand() % 5 ) S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1); @@ -214,12 +208,7 @@ void CL_ParseTEnt (void) // LordHavoc: changed to dust shower R_SparkShower(pos, vec3_origin, 30); //R_RunParticleEffect (pos, vec3_origin, 0, 20); - dl = CL_AllocDlight (0); - VectorCopy (pos, dl->origin); - dl->radius = 200; - dl->die = cl.time + 0.2; - dl->decay = 1000; - dl->color[0] = 0.05;dl->color[1] = 0.05;dl->color[2] = 0.8; + CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2); if ( rand() % 5 ) S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1); else @@ -301,12 +290,7 @@ void CL_ParseTEnt (void) case TE_GUNSHOTQUAD: // quad bullet hitting wall MSG_ReadVector(pos); R_SparkShower(pos, vec3_origin, 15); - dl = CL_AllocDlight (0); - VectorCopy (pos, dl->origin); - dl->radius = 200; - dl->die = cl.time + 0.2; - dl->decay = 1000; - dl->color[0] = 0.05;dl->color[1] = 0.05;dl->color[2] = 0.8; + CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2); break; case TE_EXPLOSION: // rocket explosion @@ -314,12 +298,7 @@ void CL_ParseTEnt (void) FindNonSolidLocation(pos); R_ParticleExplosion (pos, false); // R_BlastParticles (pos, 120, 120); - dl = CL_AllocDlight (0); - VectorCopy (pos, dl->origin); - dl->radius = 350; - dl->die = cl.time + 0.5; - dl->decay = 700; - dl->color[0] = 1.0;dl->color[1] = 0.8;dl->color[2] = 0.4; + CL_AllocDlight (NULL, pos, 350, 1.0f, 0.8f, 0.4f, 700, 0.5); S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; @@ -328,12 +307,7 @@ void CL_ParseTEnt (void) FindNonSolidLocation(pos); R_ParticleExplosion (pos, false); // R_BlastParticles (pos, 120, 480); - dl = CL_AllocDlight (0); - VectorCopy (pos, dl->origin); - dl->radius = 600; - dl->die = cl.time + 0.5; - dl->decay = 1200; - dl->color[0] = 0.5;dl->color[1] = 0.4;dl->color[2] = 1.0; + CL_AllocDlight (NULL, pos, 600, 0.5f, 0.4f, 1.0f, 1200, 0.5); S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; @@ -342,12 +316,7 @@ void CL_ParseTEnt (void) MSG_ReadVector(pos); FindNonSolidLocation(pos); R_ParticleExplosion (pos, true); - dl = CL_AllocDlight (0); - VectorCopy (pos, dl->origin); - dl->radius = 350; - dl->die = cl.time + 0.5; - dl->decay = 300; - dl->color[0] = 1.0;dl->color[1] = 0.8;dl->color[2] = 0.4; + CL_AllocDlight (NULL, pos, 350, 1.0f, 0.8f, 0.4f, 700, 0.5); S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; */ @@ -357,12 +326,7 @@ void CL_ParseTEnt (void) FindNonSolidLocation(pos); R_ParticleExplosion (pos, false); // R_BlastParticles (pos, 120, 120); - dl = CL_AllocDlight (0); - VectorCopy (pos, dl->origin); - dl->radius = 350; - dl->die = cl.time + 0.5; - dl->decay = 700; - dl->color[0] = MSG_ReadCoord();dl->color[1] = MSG_ReadCoord();dl->color[2] = MSG_ReadCoord(); + CL_AllocDlight (NULL, pos, 350, MSG_ReadCoord(), MSG_ReadCoord(), MSG_ReadCoord(), 700, 0.5); S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; @@ -371,12 +335,7 @@ void CL_ParseTEnt (void) FindNonSolidLocation(pos); R_ParticleExplosion (pos, false); // R_BlastParticles (pos, 120, 120); - dl = CL_AllocDlight (0); - VectorCopy (pos, dl->origin); - dl->radius = 350; - dl->die = cl.time + 0.5; - dl->decay = 700; - dl->color[0] = MSG_ReadByte() * (1.0 / 255.0);dl->color[1] = MSG_ReadByte() * (1.0 / 255.0);dl->color[2] = MSG_ReadByte() * (1.0 / 255.0); + CL_AllocDlight (NULL, pos, 350, MSG_ReadByte() * (1.0 / 255.0), MSG_ReadByte() * (1.0 / 255.0), MSG_ReadByte() * (1.0 / 255.0), 700, 0.5); S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; @@ -387,36 +346,22 @@ void CL_ParseTEnt (void) // R_BlastParticles (pos, 120, 120); S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); - dl = CL_AllocDlight (0); - VectorCopy (pos, dl->origin); - dl->radius = 600; - dl->die = cl.time + 0.5; - dl->decay = 1200; - dl->color[0] = 0.8;dl->color[1] = 0.4;dl->color[2] = 1.0; + CL_AllocDlight (NULL, pos, 600, 0.8f, 0.4f, 1.0f, 1200, 0.5); S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; case TE_SMALLFLASH: MSG_ReadVector(pos); FindNonSolidLocation(pos); - dl = CL_AllocDlight (0); - VectorCopy (pos, dl->origin); - dl->radius = 200; - dl->die = cl.time + 0.2; - dl->decay = 1000; - dl->color[0] = dl->color[1] = dl->color[2] = 1; + CL_AllocDlight (NULL, pos, 200, 1, 1, 1, 1000, 0.2); break; case TE_CUSTOMFLASH: MSG_ReadVector(pos); FindNonSolidLocation(pos); - dl = CL_AllocDlight (0); - VectorCopy (pos, dl->origin); - dl->radius = MSG_ReadByte() * 8; + radius = MSG_ReadByte() * 8; velspeed = (MSG_ReadByte() + 1) * (1.0 / 256.0); - dl->die = cl.time + velspeed; - dl->decay = dl->radius / velspeed; - dl->color[0] = MSG_ReadByte() * (1.0 / 255.0);dl->color[1] = MSG_ReadByte() * (1.0 / 255.0);dl->color[2] = MSG_ReadByte() * (1.0 / 255.0); + CL_AllocDlight (NULL, pos, radius, MSG_ReadByte() * (1.0 / 255.0), MSG_ReadByte() * (1.0 / 255.0), MSG_ReadByte() * (1.0 / 255.0), radius / velspeed, velspeed); break; case TE_FLAMEJET: @@ -470,13 +415,8 @@ void CL_ParseTEnt (void) colorLength = MSG_ReadByte (); R_ParticleExplosion2 (pos, colorStart, colorLength); // R_BlastParticles (pos, 80, 80); - dl = CL_AllocDlight (0); - VectorCopy (pos, dl->origin); - dl->radius = 350; - dl->die = cl.time + 0.5; - dl->decay = 700; tempcolor = (byte *)&d_8to24table[(rand()%colorLength) + colorStart]; - dl->color[0] = tempcolor[0] * (1.0f / 255.0f);dl->color[1] = tempcolor[1] * (1.0f / 255.0f);dl->color[2] = tempcolor[2] * (1.0f / 255.0f); + CL_AllocDlight (NULL, pos, 350, tempcolor[0] * (1.0f / 255.0f), tempcolor[1] * (1.0f / 255.0f), tempcolor[2] * (1.0f / 255.0f), 700, 0.5); S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; @@ -525,7 +465,6 @@ void CL_UpdateTEnts (void) entity_t *ent; float yaw, pitch; float forward; - dlight_t *dl; num_temp_entities = 0; @@ -579,20 +518,14 @@ void CL_UpdateTEnts (void) ent->angles[1] = yaw; ent->angles[2] = rand()%360; - if (r_glowinglightning.value) - { - dl = CL_AllocDlight (0); - VectorCopy (ent->origin, dl->origin); - dl->radius = 100 + (rand()&31); - dl->die = cl.time + 0.001; - dl->color[0] = dl->color[1] = dl->color[2] = r_glowinglightning.value * 0.25f; - } + if (r_glowinglightning.value > 0) + CL_AllocDlight(ent, ent->origin, lhrandom(100, 120), r_glowinglightning.value * 0.25f, r_glowinglightning.value * 0.25f, r_glowinglightning.value * 0.25f, 0, 0); VectorMA(org, 30, dist, org); d -= 30; } } - + } diff --git a/client.h b/client.h index 9abe25e2..f7aa2af0 100644 --- a/client.h +++ b/client.h @@ -40,8 +40,7 @@ typedef struct char name[MAX_SCOREBOARDNAME]; float entertime; int frags; - int colors; // two 4 bit fields -// byte translations[256]; // LordHavoc: major memory reduction (was VID_GRADES*256, and VID_GRADES is 64), and weirdness cleanup + int colors; // two 4 bit fields } scoreboard_t; typedef struct @@ -74,7 +73,8 @@ typedef struct struct model_s *model; float endtime; vec3_t start, end; -} beam_t; +} +beam_t; // LordHavoc: increased MAX_EFRAGS from 640 to 2048 #define MAX_EFRAGS 2048 @@ -83,11 +83,13 @@ typedef struct #define MAX_DEMOS 8 #define MAX_DEMONAME 16 -typedef enum { -ca_dedicated, // a dedicated server with no ability to start a client -ca_disconnected, // full screen console with no connection -ca_connected // valid netcon, talking to a server -} cactive_t; +typedef enum +{ + ca_dedicated, // a dedicated server with no ability to start a client + ca_disconnected, // full screen console with no connection + ca_connected // valid netcon, talking to a server +} +cactive_t; // // the client_static_t structure is persistant through an arbitrary number @@ -122,8 +124,8 @@ typedef struct int signon; // 0 to SIGNONS struct qsocket_s *netcon; sizebuf_t message; // writing buffer to send to server - -} client_static_t; +} +client_static_t; extern client_static_t cls; @@ -162,7 +164,7 @@ typedef struct vec3_t punchangle; // temporary offset vec3_t punchvector; // LordHavoc: origin view kick - + // pitch drifting vars float idealpitch; float pitchvel; @@ -176,10 +178,10 @@ typedef struct qboolean paused; // send over by server qboolean onground; qboolean inwater; - + int intermission; // don't change view angle, full screen, etc int completed_time; // latched at intermission start - + double mtime[2]; // the timestamp of last two messages double time; // clients view of time, should be between // servertime and oldservertime to generate @@ -188,7 +190,7 @@ typedef struct // to decay light values and smooth step ups double frametime; - + float last_received_message; // (realtime) for net trouble icon @@ -214,7 +216,8 @@ typedef struct // frag scoreboard scoreboard_t *scores; // [cl.maxclients] -} client_state_t; +} +client_state_t; // @@ -272,8 +275,8 @@ extern beam_t cl_beams[MAX_BEAMS]; // // cl_main // -dlight_t *CL_AllocDlight (int key); -void CL_DecayLights (void); +void CL_AllocDlight (entity_t *ent, vec3_t org, float radius, float red, float green, float blue, float decay, float lifetime); +void CL_DecayLights (void); void CL_Init (void); @@ -288,9 +291,9 @@ void CL_Disconnect_f (void); void CL_NextDemo (void); // LordHavoc: raised this from 256 to the maximum possible number of entities visible -#define MAX_VISEDICTS (MAX_EDICTS + MAX_STATIC_ENTITIES + MAX_TEMP_ENTITIES) -extern int cl_numvisedicts; -extern entity_t *cl_visedicts[MAX_VISEDICTS]; +#define MAX_VISEDICTS (MAX_EDICTS + MAX_STATIC_ENTITIES + MAX_TEMP_ENTITIES) +extern int cl_numvisedicts; +extern entity_t *cl_visedicts[MAX_VISEDICTS]; // // cl_input @@ -299,7 +302,8 @@ typedef struct { int down[2]; // key nums holding it down int state; // low bit is down state -} kbutton_t; +} +kbutton_t; extern kbutton_t in_mlook, in_klook; extern kbutton_t in_strafe; diff --git a/fractalnoise.c b/fractalnoise.c index 93622b14..3425daf8 100644 --- a/fractalnoise.c +++ b/fractalnoise.c @@ -17,7 +17,7 @@ void fractalnoise(byte *noise, int size, int startgrid) startgrid = bound(0, startgrid, size); - amplitude = 32767; + amplitude = 0xFFFF; // this gets halved before use noisebuf = qmalloc(size*size*sizeof(int)); memset(noisebuf, 0, size*size*sizeof(int)); @@ -55,10 +55,11 @@ void fractalnoise(byte *noise, int size, int startgrid) if (n(x,y) > max) max = n(x,y); } max -= min; + max++; // normalize noise and copy to output for (y = 0;y < size;y++) for (x = 0;x < size;x++) - *noise++ = (n(x,y) - min) * 255 / max; + *noise++ = (byte) (((n(x,y) - min) * 256) / max); qfree(noisebuf); #undef n } diff --git a/gl_draw.c b/gl_draw.c index f2c94651..5a348d3e 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -154,6 +154,10 @@ void gl_draw_shutdown() { } +void gl_draw_newmap() +{ +} + char engineversion[40]; int engineversionx, engineversiony; @@ -178,7 +182,7 @@ void GL_Draw_Init (void) engineversiony = vid.height - 8; R_Textures_Init(); - R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown); + R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown, gl_draw_newmap); } /* diff --git a/gl_models.c b/gl_models.c index 99e71140..6065452e 100644 --- a/gl_models.c +++ b/gl_models.c @@ -92,12 +92,16 @@ void gl_models_shutdown() qfree(aliasvertusage); } +void gl_models_newmap() +{ +} + void GL_Models_Init() { Cvar_RegisterVariable(&gl_transform); Cvar_RegisterVariable(&gl_lockarrays); - R_RegisterModule("GL_Models", gl_models_start, gl_models_shutdown); + R_RegisterModule("GL_Models", gl_models_start, gl_models_shutdown, gl_models_newmap); } extern vec3_t softwaretransform_x; @@ -318,7 +322,7 @@ R_DrawAliasFrame ================= */ extern vec3_t lightspot; -void R_LightModel(int numverts, vec3_t center, vec3_t basecolor); +void R_LightModel(entity_t *ent, int numverts, vec3_t center, vec3_t basecolor); void R_DrawAliasFrame (maliashdr_t *maliashdr, float alpha, vec3_t color, entity_t *ent, int shadow, vec3_t org, vec3_t angles, vec_t scale, frameblend_t *blend, rtexture_t **skin, int colormap, int effects, int flags) { if (gl_transform.value) @@ -350,7 +354,7 @@ void R_DrawAliasFrame (maliashdr_t *maliashdr, float alpha, vec3_t color, entity GL_LockArray(0, maliashdr->numverts); } - R_LightModel(maliashdr->numverts, org, color); + R_LightModel(ent, maliashdr->numverts, org, color); if (!r_render.value) return; @@ -473,7 +477,7 @@ void R_DrawQ2AliasFrame (md2mem_t *pheader, float alpha, vec3_t color, entity_t if (!gl_transform.value) R_AliasTransformVerts(pheader->num_xyz); - R_LightModel(pheader->num_xyz, org, color); + R_LightModel(ent, pheader->num_xyz, org, color); if (!r_render.value) return; @@ -895,7 +899,7 @@ void R_DrawZymoticFrame (zymtype1header_t *m, float alpha, vec3_t color, entity_ ZymoticTransformVerts(m->numverts, (int *)(m->lump_vertbonecounts.start + (int) m), (zymvertex_t *)(m->lump_verts.start + (int) m)); ZymoticCalcNormals(m->numverts, m->numshaders, (int *)(m->lump_render.start + (int) m)); - R_LightModel(m->numverts, org, color); + R_LightModel(ent, m->numverts, org, color); if (!r_render.value) return; @@ -929,8 +933,6 @@ void R_DrawZymoticFrame (zymtype1header_t *m, float alpha, vec3_t color, entity_ glDepthMask(1); } -extern int r_dlightframecount; - /* ================= R_DrawAliasModel diff --git a/gl_poly.c b/gl_poly.c index 4eb8bafe..d2114ab6 100644 --- a/gl_poly.c +++ b/gl_poly.c @@ -49,6 +49,7 @@ void gl_poly_start() for (i = 1;i < 256;i++) transreciptable[i] = 1.0f / i; } + void gl_poly_shutdown() { qfree(transvert); @@ -61,10 +62,14 @@ void gl_poly_shutdown() qfree(skypoly); } +void gl_poly_newmap() +{ +} + void GL_Poly_Init() { Cvar_RegisterVariable (&gl_multitexture); - R_RegisterModule("GL_Poly", gl_poly_start, gl_poly_shutdown); + R_RegisterModule("GL_Poly", gl_poly_start, gl_poly_shutdown, gl_poly_newmap); } void transpolyclear() @@ -786,7 +791,7 @@ extern char skyname[]; extern rtexture_t *solidskytexture, *alphaskytexture; void skypolyrender() { - int i, j, numskyverts; + int i, j; skypoly_t *p; skyvert_t *vert; float length, speedscale; @@ -805,9 +810,9 @@ void skypolyrender() if (!fogenabled && !skyname[0]) // normal quake sky { glInterleavedArrays(GL_T2F_V3F, 0, skyvert); -// glTexCoordPointer(2, GL_FLOAT, sizeof(skyvert_t) - sizeof(float) * 2, &skyvert[0].tex[0]); +// glTexCoordPointer(2, GL_FLOAT, sizeof(skyvert_t), &skyvert[0].tex[0]); // glEnableClientState(GL_TEXTURE_COORD_ARRAY); -// glVertexPointer(3, GL_FLOAT, sizeof(skyvert_t) - sizeof(float) * 3, &skyvert[0].v[0]); +// glVertexPointer(3, GL_FLOAT, sizeof(skyvert_t), &skyvert[0].v[0]); // glEnableClientState(GL_VERTEX_ARRAY); if(lighthalf) glColor3f(0.5f, 0.5f, 0.5f); @@ -820,7 +825,6 @@ void skypolyrender() glBindTexture(GL_TEXTURE_2D, R_GetTexture(solidskytexture)); // upper clouds speedscale = cl.time*8; speedscale -= (int)speedscale & ~127 ; - numskyverts = 0; for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++) { vert = skyvert + p->firstvert; @@ -836,9 +840,8 @@ void skypolyrender() vert->tex[0] = (speedscale + dir[0] * length) * (1.0/128); vert->tex[1] = (speedscale + dir[1] * length) * (1.0/128); } - numskyverts += p->verts; } - GL_LockArray(0, numskyverts); + GL_LockArray(0, currentskyvert); for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++) glDrawArrays(GL_POLYGON, p->firstvert, p->verts); GL_UnlockArray(); @@ -863,7 +866,7 @@ void skypolyrender() vert->tex[1] = (speedscale + dir[1] * length) * (1.0/128); } } - GL_LockArray(0, numskyverts); + GL_LockArray(0, currentskyvert); for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++) glDrawArrays(GL_POLYGON, p->firstvert, p->verts); GL_UnlockArray(); @@ -875,15 +878,12 @@ void skypolyrender() } else { - glVertexPointer(3, GL_FLOAT, sizeof(skyvert_t) - sizeof(float) * 3, &skyvert[0].v[0]); + glVertexPointer(3, GL_FLOAT, sizeof(skyvert_t), &skyvert[0].v[0]); glEnableClientState(GL_VERTEX_ARRAY); 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 - numskyverts = 0; - for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++) - numskyverts += p->verts; - GL_LockArray(0, numskyverts); + GL_LockArray(0, currentskyvert); for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++) glDrawArrays(GL_POLYGON, p->firstvert, p->verts); GL_UnlockArray(); diff --git a/gl_poly.h b/gl_poly.h index 24ece5f5..25747e9a 100644 --- a/gl_poly.h +++ b/gl_poly.h @@ -18,7 +18,7 @@ extern void skypolybegin(); extern void skypolyvert(float x, float y, float z); extern void skypolyend(); -#define MAX_TRANSPOLYS 8192 +#define MAX_TRANSPOLYS 65536 #define MAX_TRANSVERTS (MAX_TRANSPOLYS*4) #define MAX_WALLPOLYS 65536 #define MAX_WALLVERTS (MAX_WALLPOLYS*3) diff --git a/gl_rmain.c b/gl_rmain.c index c4a257d2..f3806a33 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -211,11 +211,15 @@ void FOG_registercvars() } } -void glmain_start() +void gl_main_start() { } -void glmain_shutdown() +void gl_main_shutdown() +{ +} + +void gl_main_newmap() { } @@ -241,7 +245,7 @@ void GL_Main_Init() // if (gl_vendor && strstr(gl_vendor, "3Dfx")) // gl_lightmode.value = 0; Cvar_RegisterVariable (&r_fullbright); - R_RegisterModule("GL_Main", glmain_start, glmain_shutdown); + R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap); } extern void GL_Draw_Init(); @@ -259,7 +263,7 @@ extern void CL_Effects_Init(); void Render_Init() { - R_ShutdownModules(); + R_Modules_Shutdown(); GL_Draw_Init(); GL_Main_Init(); GL_Models_Init(); @@ -272,7 +276,8 @@ void Render_Init() R_Particles_Init(); R_Explosion_Init(); CL_Effects_Init(); - R_StartModules(); + R_Decals_Init(); + R_Modules_Start(); } /* @@ -739,16 +744,6 @@ void GL_BlendView() glEnable(GL_TEXTURE_2D); } -/* -#define TIMEREPORT(DESC) \ - if (r_speeds2.value)\ - {\ - temptime = -currtime;\ - currtime = Sys_FloatTime();\ - temptime += currtime;\ - Con_Printf(DESC " %.4fms ", temptime * 1000.0);\ - } -*/ #define TIMEREPORT(VAR) \ if (r_speeds2.value)\ {\ @@ -770,12 +765,11 @@ extern qboolean intimerefresh; extern qboolean skyisvisible; extern void R_Sky(); extern void UploadLightmaps(); -char r_speeds2_string1[81], r_speeds2_string2[81], r_speeds2_string3[81], r_speeds2_string4[81], r_speeds2_string5[81], r_speeds2_string6[81]; +char r_speeds2_string1[81], r_speeds2_string2[81], r_speeds2_string3[81], r_speeds2_string4[81], r_speeds2_string5[81], r_speeds2_string6[81], r_speeds2_string7[81]; void R_RenderView (void) { double starttime, currtime, temptime; - int time_clear, time_setup, time_world, time_bmodels, time_upload, time_sky, time_wall, time_models, time_moveparticles, time_drawparticles, time_moveexplosions, time_drawexplosions, time_transpoly, time_blend, time_total; -// double currtime, temptime; + int time_clear, time_setup, time_world, time_bmodels, time_upload, time_sky, time_wall, time_models, time_moveparticles, time_drawparticles, time_moveexplosions, time_drawexplosions, time_drawdecals, time_transpoly, time_blend, time_total; // if (r_norefresh.value) // return; @@ -789,7 +783,6 @@ void R_RenderView (void) if (r_speeds2.value) { starttime = currtime = Sys_FloatTime(); -// Con_Printf("render time: "); } else starttime = currtime = 0; @@ -842,6 +835,8 @@ void R_RenderView (void) TIMEREPORT(time_moveexplosions) R_DrawExplosions(); TIMEREPORT(time_drawexplosions) + R_DrawDecals(); + TIMEREPORT(time_drawdecals) transpolyrender(); TIMEREPORT(time_transpoly) @@ -853,12 +848,12 @@ void R_RenderView (void) if (r_speeds2.value) { time_total = (int) ((Sys_FloatTime() - starttime) * 1000000.0); -// Con_Printf("\n"); sprintf(r_speeds2_string1, "%6i walls %6i dlitwalls %7i modeltris %7i transpoly\n", c_brush_polys, c_light_polys, c_alias_polys, currenttranspoly); sprintf(r_speeds2_string2, "BSP: %6i faces %6i nodes %6i leafs\n", c_faces, c_nodes, c_leafs); sprintf(r_speeds2_string3, "%4i models %4i bmodels %4i sprites %5i particles %3i dlights\n", c_models, c_bmodels, c_sprites, c_particles, c_dlights); sprintf(r_speeds2_string4, "%6ius clear %6ius setup %6ius world %6ius bmodel %6ius upload", time_clear, time_setup, time_world, time_bmodels, time_upload); sprintf(r_speeds2_string5, "%6ius sky %6ius wall %6ius models %6ius mpart %6ius dpart ", time_sky, time_wall, time_models, time_moveparticles, time_drawparticles); - sprintf(r_speeds2_string6, "%6ius trans %6ius blend %6ius total %6ius permdl", time_transpoly, time_blend, time_total, time_models / max(c_models, 1)); + sprintf(r_speeds2_string6, "%6ius mexplo %6ius dexplo %6ius decals %6ius trans %6ius blend ", time_moveexplosions, time_drawexplosions, time_drawdecals, time_transpoly, time_blend); + sprintf(r_speeds2_string7, "%6ius permdl %6ius total ", time_models / max(c_models, 1), time_total); } } diff --git a/gl_rmisc.c b/gl_rmisc.c index c5c367d6..72dc5e43 100644 --- a/gl_rmisc.c +++ b/gl_rmisc.c @@ -136,6 +136,10 @@ void gl_misc_shutdown() { } +void gl_misc_newmap() +{ +} + /* =============== R_Init @@ -146,7 +150,7 @@ void GL_Misc_Init (void) Cmd_AddCommand ("envmap", R_Envmap_f); Cmd_AddCommand ("timerefresh", R_TimeRefresh_f); - R_RegisterModule("GL_Misc", gl_misc_start, gl_misc_shutdown); + R_RegisterModule("GL_Misc", gl_misc_start, gl_misc_shutdown, gl_misc_newmap); } void R_ClearParticles (void); @@ -175,7 +179,7 @@ void R_NewMap (void) cl.worldmodel->leafs[i].efrags = NULL; r_viewleaf = NULL; - R_ClearParticles (); + R_Modules_NewMap(); GL_BuildLightmaps (); diff --git a/gl_screen.c b/gl_screen.c index 026861df..b19aa685 100644 --- a/gl_screen.c +++ b/gl_screen.c @@ -378,6 +378,10 @@ void gl_screen_shutdown() { } +void gl_screen_newmap() +{ +} + /* ================== SCR_Init @@ -409,7 +413,7 @@ void GL_Screen_Init (void) scr_initialized = true; - R_RegisterModule("GL_Screen", gl_screen_start, gl_screen_shutdown); + R_RegisterModule("GL_Screen", gl_screen_start, gl_screen_shutdown, gl_screen_newmap); } @@ -940,13 +944,14 @@ void SCR_UpdateScreen (void) if (r_speeds2.value) { - extern char r_speeds2_string1[81], r_speeds2_string2[81], r_speeds2_string3[81], r_speeds2_string4[81], r_speeds2_string5[81], r_speeds2_string6[81]; - Draw_String(0, vid.height - sb_lines - 48, r_speeds2_string1, 80); - Draw_String(0, vid.height - sb_lines - 40, r_speeds2_string2, 80); - Draw_String(0, vid.height - sb_lines - 32, r_speeds2_string3, 80); - Draw_String(0, vid.height - sb_lines - 24, r_speeds2_string4, 80); - Draw_String(0, vid.height - sb_lines - 16, r_speeds2_string5, 80); - Draw_String(0, vid.height - sb_lines - 8, r_speeds2_string6, 80); + extern char r_speeds2_string1[81], r_speeds2_string2[81], r_speeds2_string3[81], r_speeds2_string4[81], r_speeds2_string5[81], r_speeds2_string6[81], r_speeds2_string7[81]; + Draw_String(0, vid.height - sb_lines - 56, r_speeds2_string1, 80); + Draw_String(0, vid.height - sb_lines - 48, r_speeds2_string2, 80); + Draw_String(0, vid.height - sb_lines - 40, r_speeds2_string3, 80); + Draw_String(0, vid.height - sb_lines - 32, r_speeds2_string4, 80); + Draw_String(0, vid.height - sb_lines - 24, r_speeds2_string5, 80); + Draw_String(0, vid.height - sb_lines - 16, r_speeds2_string6, 80); + Draw_String(0, vid.height - sb_lines - 8, r_speeds2_string7, 80); } V_UpdateBlends (); diff --git a/gl_textures.c b/gl_textures.c index a5644a3d..6248f5bc 100644 --- a/gl_textures.c +++ b/gl_textures.c @@ -169,6 +169,10 @@ void r_textures_shutdown() { } +void r_textures_newmap() +{ +} + void R_Textures_Init (void) { Cmd_AddCommand("r_texturestats", GL_TextureStats_f); @@ -189,7 +193,7 @@ void R_Textures_Init (void) memset(gltextures, 0, sizeof(gltexture_t) * MAX_GLTEXTURES); Cmd_AddCommand ("gl_texturemode", &Draw_TextureMode_f); - R_RegisterModule("R_Textures", r_textures_start, r_textures_shutdown); + R_RegisterModule("R_Textures", r_textures_start, r_textures_shutdown, r_textures_newmap); } /* @@ -213,7 +217,7 @@ int R_FindTexture (char *identifier) void R_ResampleTextureLerpLine (byte *in, byte *out, int inwidth, int outwidth) { - int j, xi, oldx = 0, f, fstep, l1, l2, endx; + int j, xi, oldx = 0, f, fstep, endx; fstep = (int) (inwidth*65536.0f/outwidth); endx = (inwidth-1); for (j = 0,f = 0;j < outwidth;j++, f += fstep) @@ -226,12 +230,11 @@ void R_ResampleTextureLerpLine (byte *in, byte *out, int inwidth, int outwidth) } if (xi < endx) { - l2 = f & 0xFFFF; - l1 = 0x10000 - l2; - *out++ = (byte) ((in[0] * l1 + in[4] * l2) >> 16); - *out++ = (byte) ((in[1] * l1 + in[5] * l2) >> 16); - *out++ = (byte) ((in[2] * l1 + in[6] * l2) >> 16); - *out++ = (byte) ((in[3] * l1 + in[7] * l2) >> 16); + int lerp = f & 0xFFFF; + *out++ = (byte) ((((in[4] - in[0]) * lerp) >> 16) + in[0]); + *out++ = (byte) ((((in[5] - in[1]) * lerp) >> 16) + in[1]); + *out++ = (byte) ((((in[6] - in[2]) * lerp) >> 16) + in[2]); + *out++ = (byte) ((((in[7] - in[3]) * lerp) >> 16) + in[3]); } else // last pixel of the line has no pixel to lerp to { @@ -250,9 +253,12 @@ R_ResampleTexture */ void R_ResampleTexture (void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight) { + if (outwidth & 3) + Sys_Error("R_ResampleTexture: output width must be a multiple of 4"); + if (r_lerpimages.value) { - int i, j, yi, oldy, f, fstep, l1, l2, endy = (inheight-1); + int i, j, yi, oldy, f, fstep, endy = (inheight-1); byte *inrow, *out, *row1, *row2; out = outdata; fstep = (int) (inheight*65536.0f/outheight); @@ -266,43 +272,56 @@ void R_ResampleTexture (void *indata, int inwidth, int inheight, void *outdata, for (i = 0, f = 0;i < outheight;i++,f += fstep) { yi = f >> 16; - if (yi != oldy) - { - inrow = (byte *)indata + inwidth*4*yi; - if (yi == oldy+1) - memcpy(row1, row2, outwidth*4); - else - R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth); - if (yi < endy) - R_ResampleTextureLerpLine (inrow + inwidth*4, row2, inwidth, outwidth); - else - memcpy(row2, row1, outwidth*4); - oldy = yi; - } if (yi < endy) { - l2 = f & 0xFFFF; - l1 = 0x10000 - l2; - for (j = 0;j < outwidth;j++) + int lerp = f & 0xFFFF; + if (yi != oldy) { - *out++ = (byte) ((*row1++ * l1 + *row2++ * l2) >> 16); - *out++ = (byte) ((*row1++ * l1 + *row2++ * l2) >> 16); - *out++ = (byte) ((*row1++ * l1 + *row2++ * l2) >> 16); - *out++ = (byte) ((*row1++ * l1 + *row2++ * l2) >> 16); + inrow = (byte *)indata + inwidth*4*yi; + if (yi == oldy+1) + memcpy(row1, row2, outwidth*4); + else + R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth); + R_ResampleTextureLerpLine (inrow + inwidth*4, row2, inwidth, outwidth); + oldy = yi; + } + for (j = 0;j < outwidth;j += 4) + { + out[ 0] = (byte) ((((row2[ 0] - row1[ 0]) * lerp) >> 16) + row1[ 0]); + out[ 1] = (byte) ((((row2[ 1] - row1[ 1]) * lerp) >> 16) + row1[ 1]); + out[ 2] = (byte) ((((row2[ 2] - row1[ 2]) * lerp) >> 16) + row1[ 2]); + out[ 3] = (byte) ((((row2[ 3] - row1[ 3]) * lerp) >> 16) + row1[ 3]); + out[ 4] = (byte) ((((row2[ 4] - row1[ 4]) * lerp) >> 16) + row1[ 4]); + out[ 5] = (byte) ((((row2[ 5] - row1[ 5]) * lerp) >> 16) + row1[ 5]); + out[ 6] = (byte) ((((row2[ 6] - row1[ 6]) * lerp) >> 16) + row1[ 6]); + out[ 7] = (byte) ((((row2[ 7] - row1[ 7]) * lerp) >> 16) + row1[ 7]); + out[ 8] = (byte) ((((row2[ 8] - row1[ 8]) * lerp) >> 16) + row1[ 8]); + out[ 9] = (byte) ((((row2[ 9] - row1[ 9]) * lerp) >> 16) + row1[ 9]); + out[10] = (byte) ((((row2[10] - row1[10]) * lerp) >> 16) + row1[10]); + out[11] = (byte) ((((row2[11] - row1[11]) * lerp) >> 16) + row1[11]); + out[12] = (byte) ((((row2[12] - row1[12]) * lerp) >> 16) + row1[12]); + out[13] = (byte) ((((row2[13] - row1[13]) * lerp) >> 16) + row1[13]); + out[14] = (byte) ((((row2[14] - row1[14]) * lerp) >> 16) + row1[14]); + out[15] = (byte) ((((row2[15] - row1[15]) * lerp) >> 16) + row1[15]); + out += 16; + row1 += 16; + row2 += 16; } row1 -= outwidth*4; row2 -= outwidth*4; } - else // last line has no pixels to lerp to + else { - for (j = 0;j < outwidth;j++) + if (yi != oldy) { - *out++ = *row1++; - *out++ = *row1++; - *out++ = *row1++; - *out++ = *row1++; + inrow = (byte *)indata + inwidth*4*yi; + if (yi == oldy+1) + memcpy(row1, row2, outwidth*4); + else + R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth); + oldy = yi; } - row1 -= outwidth*4; + memcpy(out, row1, outwidth * 4); } } qfree(row1); @@ -310,22 +329,24 @@ void R_ResampleTexture (void *indata, int inwidth, int inheight, void *outdata, } else { - int i, j; - unsigned frac, fracstep; - byte *inrow, *out, *inpix; + int i, j; + unsigned frac, fracstep; + // relies on int being 4 bytes + int *inrow, *out; out = outdata; fracstep = inwidth*0x10000/outwidth; - for (i=0 ; i> 1; - for (j=0 ; j> 14) & ~3);*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = *inpix++ ;frac += fracstep; - inpix = inrow + ((frac >> 14) & ~3);*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = *inpix++ ;frac += fracstep; - inpix = inrow + ((frac >> 14) & ~3);*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = *inpix++ ;frac += fracstep; - inpix = inrow + ((frac >> 14) & ~3);*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = *inpix++ ;frac += fracstep; + out[0] = inrow[frac >> 16];frac += fracstep; + out[1] = inrow[frac >> 16];frac += fracstep; + out[2] = inrow[frac >> 16];frac += fracstep; + out[3] = inrow[frac >> 16];frac += fracstep; + out += 4; } } } diff --git a/host.c b/host.c index 3d687b6d..7c165adb 100644 --- a/host.c +++ b/host.c @@ -827,6 +827,7 @@ Host_Init */ void Host_Init () { + int i; /* if (standard_quake) minimum_memory = MINIMUM_MEMORY; @@ -840,6 +841,24 @@ void Host_Init () Sys_Error ("Only %4.1f megs of memory available, can't execute game", host_parms.memsize / (float)0x100000); */ + host_parms.memsize = DEFAULTMEM * 1024 * 1024; + + i = COM_CheckParm("-mem"); + if (i) + host_parms.memsize = (int) (atof(com_argv[i+1]) * 1024 * 1024); + + i = COM_CheckParm("-winmem"); + if (i) + host_parms.memsize = (int) (atof(com_argv[i+1]) * 1024 * 1024); + + i = COM_CheckParm("-heapsize"); + if (i) + host_parms.memsize = (int) (atof(com_argv[i+1]) * 1024); + + host_parms.membase = qmalloc(host_parms.memsize); + if (!host_parms.membase) + Sys_Error("Not enough memory free, close some programs and try again, or free disk space\n"); + com_argc = host_parms.argc; com_argv = host_parms.argv; @@ -926,7 +945,7 @@ void Host_Shutdown(void) if (cls.state != ca_dedicated) { - R_ShutdownModules(); + R_Modules_Shutdown(); VID_Shutdown(); } } diff --git a/image.c b/image.c index 7b05a23f..a26b78fc 100644 --- a/image.c +++ b/image.c @@ -630,3 +630,23 @@ void Image_WriteTGARGBA (char *filename, int width, int height, byte *data) qfree(buffer); } + +qboolean Image_CheckAlpha(byte *data, int size, qboolean rgba) +{ + byte *end; + if (rgba) + { + // check alpha bytes + for (end = data + size * 4, data += 3;data < end;data += 4) + if (*data < 255) + return 1; + } + else + { + // color 255 is transparent + for (end = data + size;data < end;data++) + if (*data == 255) + return 1; + } + return 0; +} diff --git a/image.h b/image.h index 60a9759c..9fc65f0d 100644 --- a/image.h +++ b/image.h @@ -1,13 +1,14 @@ -extern void Image_Copy8bitRGBA(byte *in, byte *out, int pixels, int *pal); -extern void Image_CopyRGBAGamma(byte *in, byte *out, int pixels); -extern int image_makemask (byte *in, byte *out, int size); -extern byte* loadimagepixels (char* filename, qboolean complain, int matchwidth, int matchheight); -extern rtexture_t *loadtextureimage (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache); -extern byte* loadimagepixelsmask (char* filename, qboolean complain, int matchwidth, int matchheight); -extern rtexture_t *loadtextureimagemask (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache); -extern rtexture_t *image_masktex; -extern rtexture_t *loadtextureimagewithmask (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache); -extern void Image_WriteTGARGB_preflipped (char *filename, int width, int height, byte *data); -extern void Image_WriteTGARGB (char *filename, int width, int height, byte *data); -extern void Image_WriteTGARGBA (char *filename, int width, int height, byte *data); +void Image_Copy8bitRGBA(byte *in, byte *out, int pixels, int *pal); +void Image_CopyRGBAGamma(byte *in, byte *out, int pixels); +int image_makemask (byte *in, byte *out, int size); +byte* loadimagepixels (char* filename, qboolean complain, int matchwidth, int matchheight); +rtexture_t *loadtextureimage (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache); +byte* loadimagepixelsmask (char* filename, qboolean complain, int matchwidth, int matchheight); +rtexture_t *loadtextureimagemask (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache); +rtexture_t *image_masktex; +rtexture_t *loadtextureimagewithmask (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache); +void Image_WriteTGARGB_preflipped (char *filename, int width, int height, byte *data); +void Image_WriteTGARGB (char *filename, int width, int height, byte *data); +void Image_WriteTGARGBA (char *filename, int width, int height, byte *data); +qboolean Image_CheckAlpha(byte *data, int size, qboolean rgba); diff --git a/makefile b/makefile index ea8fb191..7cbbad77 100644 --- a/makefile +++ b/makefile @@ -7,7 +7,7 @@ SND=snd_alsa_0_9.o #if you use the kernel sound driver or OSS #SND=snd_oss.o -OBJECTS= buildnumber.o cd_linux.o chase.o cl_demo.o cl_input.o cl_main.o cl_parse.o cl_tent.o cmd.o common.o console.o crc.o cvar.o fractalnoise.o gl_draw.o gl_poly.o gl_refrag.o gl_rmain.o gl_rmisc.o gl_rsurf.o gl_screen.o gl_warp.o host.o host_cmd.o image.o keys.o mathlib.o menu.o model_alias.o model_brush.o model_shared.o model_sprite.o net_bsd.o net_udp.o net_dgrm.o net_loop.o net_main.o net_vcr.o pr_cmds.o pr_edict.o pr_exec.o r_light.o r_part.o r_explosion.o sbar.o snd_dma.o snd_mem.o snd_mix.o $(SND) sv_main.o sv_move.o sv_phys.o sv_user.o sv_light.o sys_linux.o transform.o view.o wad.o world.o zone.o vid_shared.o palette.o r_crosshairs.o gl_textures.o gl_models.o r_sprites.o r_modules.o r_explosion.o r_lerpanim.o cl_effects.o +OBJECTS= buildnumber.o cd_linux.o chase.o cl_demo.o cl_input.o cl_main.o cl_parse.o cl_tent.o cmd.o common.o console.o crc.o cvar.o fractalnoise.o gl_draw.o gl_poly.o gl_refrag.o gl_rmain.o gl_rmisc.o gl_rsurf.o gl_screen.o gl_warp.o host.o host_cmd.o image.o keys.o mathlib.o menu.o model_alias.o model_brush.o model_shared.o model_sprite.o net_bsd.o net_udp.o net_dgrm.o net_loop.o net_main.o net_vcr.o pr_cmds.o pr_edict.o pr_exec.o r_light.o r_part.o r_explosion.o sbar.o snd_dma.o snd_mem.o snd_mix.o $(SND) sv_main.o sv_move.o sv_phys.o sv_user.o sv_light.o sys_linux.o transform.o view.o wad.o world.o zone.o vid_shared.o palette.o r_crosshairs.o gl_textures.o gl_models.o r_sprites.o r_modules.o r_explosion.o r_lerpanim.o cl_effects.o r_decals.o OPTIMIZATIONS= -O6 -ffast-math -funroll-loops -fomit-frame-pointer -fexpensive-optimizations diff --git a/model_brush.c b/model_brush.c index 33350406..8604c43b 100644 --- a/model_brush.c +++ b/model_brush.c @@ -224,8 +224,8 @@ void Mod_LoadTextures (lump_t *l) { tx->width = mt->width; tx->height = mt->height; - tx->transparent = true; - tx->texture = R_LoadTexture (tx->name, image_width, image_height, data, TEXF_MIPMAP | TEXF_ALPHA | TEXF_RGBA | TEXF_PRECACHE); + tx->transparent = Image_CheckAlpha(data, image_width * image_height, true); + tx->texture = R_LoadTexture (tx->name, image_width, image_height, data, TEXF_MIPMAP | (tx->transparent ? TEXF_ALPHA : 0) | TEXF_RGBA | TEXF_PRECACHE); tx->glowtexture = NULL; } qfree(data); @@ -252,8 +252,8 @@ void Mod_LoadTextures (lump_t *l) { tx->width = mt->width; tx->height = mt->height; - tx->transparent = true; - tx->texture = R_LoadTexture (tx->name, mt->width, mt->height, data, TEXF_MIPMAP | TEXF_ALPHA | TEXF_RGBA | TEXF_PRECACHE); + tx->transparent = Image_CheckAlpha(data, mt->width * mt->height, true); + tx->texture = R_LoadTexture (tx->name, mt->width, mt->height, data, TEXF_MIPMAP | (tx->transparent ? TEXF_ALPHA : 0) | TEXF_RGBA | TEXF_PRECACHE); tx->glowtexture = NULL; qfree(data); } @@ -266,8 +266,8 @@ void Mod_LoadTextures (lump_t *l) { tx->width = image_width; tx->height = image_height; - tx->transparent = true; - tx->texture = R_LoadTexture (tx->name, image_width, image_height, data, TEXF_MIPMAP | TEXF_ALPHA | TEXF_RGBA | TEXF_PRECACHE); + tx->transparent = Image_CheckAlpha(data, image_width * image_height, true); + tx->texture = R_LoadTexture (tx->name, image_width, image_height, data, TEXF_MIPMAP | (tx->transparent ? TEXF_ALPHA : 0) | TEXF_RGBA | TEXF_PRECACHE); tx->glowtexture = NULL; qfree(data); } diff --git a/quakedef.h b/quakedef.h index 0232c8f3..db706ec7 100644 --- a/quakedef.h +++ b/quakedef.h @@ -47,7 +47,7 @@ extern int buildnumber; #define UNUSED(x) (x = x) // for pesky compiler / lint warnings -// LordHavoc: default heap size (unless -heapsize (win32 only) or -mem is used), in megabytes +// LordHavoc: default heap size (unless -heapsize, -mem, or -winmem is used), in megabytes #define DEFAULTMEM 24 //#define MINIMUM_MEMORY 0x550000 //#define MINIMUM_MEMORY_LEVELPAK (MINIMUM_MEMORY + 0x100000) diff --git a/r_crosshairs.c b/r_crosshairs.c index c6a2b81c..ef7e5c64 100644 --- a/r_crosshairs.c +++ b/r_crosshairs.c @@ -121,13 +121,17 @@ void r_crosshairs_shutdown() { } +void r_crosshairs_newmap() +{ +} + void R_Crosshairs_Init() { Cvar_RegisterVariable(&crosshair_brightness); Cvar_RegisterVariable(&crosshair_alpha); Cvar_RegisterVariable(&crosshair_flashspeed); Cvar_RegisterVariable(&crosshair_flashrange); - R_RegisterModule("R_Crosshairs", r_crosshairs_start, r_crosshairs_shutdown); + R_RegisterModule("R_Crosshairs", r_crosshairs_start, r_crosshairs_shutdown, r_crosshairs_newmap); } void DrawCrosshair(int num) diff --git a/r_decals.c b/r_decals.c new file mode 100644 index 00000000..cea29fdb --- /dev/null +++ b/r_decals.c @@ -0,0 +1,280 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "quakedef.h" + +#define MAX_DECALS 2048 + +typedef struct decal_s +{ + vec3_t org; + vec3_t direction; + vec3_t vert[4]; + byte color[4]; + rtexture_t *tex; + msurface_t *surface; + byte *lightmapaddress; + int lightmapstep; +} +decal_t; + +decal_t *decals; +int currentdecal; // wraps around in decal array, replacing old ones when a new one is needed + +cvar_t r_drawdecals = {"r_drawdecals", "1"}; +cvar_t r_decals_lighting = {"r_decals_lighting", "1"}; + +void r_decals_start() +{ + decals = (decal_t *) qmalloc(MAX_DECALS * sizeof(decal_t)); + memset(decals, 0, MAX_DECALS * sizeof(decal_t)); + currentdecal = 0; +} + +void r_decals_shutdown() +{ + qfree(decals); +} + +void r_decals_newmap() +{ + memset(decals, 0, MAX_DECALS * sizeof(decal_t)); + currentdecal = 0; +} + +void R_Decals_Init() +{ + Cvar_RegisterVariable (&r_drawdecals); + Cvar_RegisterVariable (&r_decals_lighting); + + R_RegisterModule("R_Decals", r_decals_start, r_decals_shutdown, r_decals_newmap); +} + +void R_Decal(vec3_t org, rtexture_t *tex, float scale, int cred, int cgreen, int cblue, int alpha) +{ + int i, ds, dt, bestlightmapofs; + float bestdist, dist; + vec3_t impact, right, up; + decal_t *decal; +// mleaf_t *leaf; + msurface_t *surf/*, **mark, **endmark*/, *bestsurf; + + if (alpha < 1) + return; + +// leaf = Mod_PointInLeaf(org, cl.worldmodel); +// if (!leaf->nummarksurfaces) +// return; + +// mark = leaf->firstmarksurface; +// endmark = mark + leaf->nummarksurfaces; + + // find the best surface to place the decal on + bestsurf = NULL; + bestdist = 16; + bestlightmapofs = 0; +// while(mark < endmark) +// { +// surf = *mark++; + surf = &cl.worldmodel->surfaces[cl.worldmodel->firstmodelsurface]; + for (i = 0;i < cl.worldmodel->nummodelsurfaces;i++, surf++) + { + if (surf->flags & SURF_DRAWTILED) + continue; // no lightmaps + + dist = PlaneDiff(org, surf->plane); + if (surf->flags & SURF_PLANEBACK) + dist = -dist; + if (dist < 0) + continue; + if (dist >= bestdist) + continue; + + impact[0] = org[0] - surf->plane->normal[0] * dist; + impact[1] = org[1] - surf->plane->normal[1] * dist; + impact[2] = org[2] - surf->plane->normal[2] * dist; + + ds = (int) (DotProduct(impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]); + dt = (int) (DotProduct(impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]); + + if (ds < surf->texturemins[0] || dt < surf->texturemins[1]) + continue; + + ds -= surf->texturemins[0]; + dt -= surf->texturemins[1]; + + if (ds > surf->extents[0] || dt > surf->extents[1]) + continue; + + bestsurf = surf; + bestdist = dist; + bestlightmapofs = (dt >> 4) * ((surf->extents[0] >> 4) + 1) + (ds >> 4); + } + // abort if no suitable surface was found + if (bestsurf == NULL) + return; + + // grab a decal from the array and advance to the next decal to replace, wrapping to replace an old decal if necessary + decal = decals + currentdecal; + currentdecal++; + if (currentdecal >= MAX_DECALS) + currentdecal = 0; + decal->tex = tex; + // reverse direction + if (bestsurf->flags & SURF_PLANEBACK) + { + VectorCopy(bestsurf->plane->normal, decal->direction); + } + else + { + VectorNegate(bestsurf->plane->normal, decal->direction); + } + // - 0.25 to push it off the surface a bit + decal->org[0] = impact[0] = org[0] + decal->direction[0] * (bestdist - 0.25f); + decal->org[1] = impact[1] = org[1] + decal->direction[1] * (bestdist - 0.25f); + decal->org[2] = impact[2] = org[2] + decal->direction[2] * (bestdist - 0.25f); + // set up the 4 corners + scale *= 0.5f; + VectorVectors(decal->direction, right, up); + decal->vert[0][0] = impact[0] - up[0] * scale - right[0] * scale; + decal->vert[0][1] = impact[1] - up[1] * scale - right[1] * scale; + decal->vert[0][2] = impact[2] - up[2] * scale - right[2] * scale; + decal->vert[1][0] = impact[0] + up[0] * scale - right[0] * scale; + decal->vert[1][1] = impact[1] + up[1] * scale - right[1] * scale; + decal->vert[1][2] = impact[2] + up[2] * scale - right[2] * scale; + decal->vert[2][0] = impact[0] + up[0] * scale + right[0] * scale; + decal->vert[2][1] = impact[1] + up[1] * scale + right[1] * scale; + decal->vert[2][2] = impact[2] + up[2] * scale + right[2] * scale; + decal->vert[3][0] = impact[0] - up[0] * scale + right[0] * scale; + decal->vert[3][1] = impact[1] - up[1] * scale + right[1] * scale; + decal->vert[3][2] = impact[2] - up[2] * scale + right[2] * scale; + // store the color + decal->color[0] = (byte) bound(0, cred, 255); + decal->color[1] = (byte) bound(0, cgreen, 255); + decal->color[2] = (byte) bound(0, cblue, 255); + decal->color[3] = (byte) bound(0, alpha, 255); + // store the surface information for lighting + decal->surface = bestsurf; + decal->lightmapstep = ((bestsurf->extents[0]>>4)+1) * ((bestsurf->extents[1]>>4)+1)*3; // LordHavoc: *3 for colored lighting + if (bestsurf->samples) + decal->lightmapaddress = bestsurf->samples + bestlightmapofs * 3; // LordHavoc: *3 for colored lighitng + else + decal->lightmapaddress = NULL; +} + +void R_DrawDecals (void) +{ + decal_t *p; + int i, j, k, dynamiclight, ir, ig, ib, maps, bits; + byte br, bg, bb, ba; + float scale, fr, fg, fb, dist, rad, mindist; + byte *lightmap; + vec3_t v; + msurface_t *surf; + dlight_t *dl; + + if (!r_drawdecals.value) + return; + + dynamiclight = (int) r_dynamic.value != 0 && (int) r_decals_lighting.value != 0; + + mindist = DotProduct(r_refdef.vieworg, vpn) + 4.0f; + + for (i = 0, p = decals;i < MAX_DECALS;i++, p++) + { + if (p->tex == NULL) + break; + + // do not render if the decal is behind the view + if (DotProduct(p->org, vpn) < mindist) + continue; + + // do not render if the view origin is behind the decal + VectorSubtract(p->org, r_refdef.vieworg, v); + if (DotProduct(p->direction, v) < 0) + continue; + + // get the surface lighting + surf = p->surface; + lightmap = p->lightmapaddress; + fr = fg = fb = 0.0f; + if (lightmap) + { + for (maps = 0;maps < MAXLIGHTMAPS && surf->styles[maps] != 255;maps++) + { + scale = d_lightstylevalue[surf->styles[maps]]; + fr += lightmap[0] * scale; + fg += lightmap[1] * scale; + fb += lightmap[2] * scale; + lightmap += p->lightmapstep; + } + } + fr *= (1.0f / 256.0f); + fg *= (1.0f / 256.0f); + fb *= (1.0f / 256.0f); + // dynamic lighting + if (dynamiclight) + { + if (surf->dlightframe == r_dlightframecount) + { + for (j = 0;j < 8;j++) + { + bits = surf->dlightbits[j]; + if (bits) + { + for (k = 0, dl = cl_dlights + j * 32;bits;k++, dl++) + { + if (bits & (1 << k)) + { + bits -= 1 << k; + VectorSubtract(p->org, dl->origin, v); + dist = DotProduct(v, v) + LIGHTOFFSET; + rad = dl->radius * dl->radius; + if (dist < rad) + { + rad *= 128.0f / dist; + fr += rad * dl->color[0]; + fg += rad * dl->color[1]; + fb += rad * dl->color[2]; + } + } + } + } + } + } + } + // apply color to lighting + ir = (int) (fr * p->color[0] * (1.0f / 128.0f)); + ig = (int) (fg * p->color[1] * (1.0f / 128.0f)); + ib = (int) (fb * p->color[2] * (1.0f / 128.0f)); + // compute byte color + br = (byte) min(ir, 255); + bg = (byte) min(ig, 255); + bb = (byte) min(ib, 255); + ba = p->color[3]; + // put into transpoly system for sorted drawing later + transpolybegin(R_GetTexture(p->tex), 0, R_GetTexture(p->tex), TPOLYTYPE_ALPHA); + transpolyvertub(p->vert[0][0], p->vert[0][1], p->vert[0][2], 0,1,br,bg,bb,ba); + transpolyvertub(p->vert[1][0], p->vert[1][1], p->vert[1][2], 0,0,br,bg,bb,ba); + transpolyvertub(p->vert[2][0], p->vert[2][1], p->vert[2][2], 1,0,br,bg,bb,ba); + transpolyvertub(p->vert[3][0], p->vert[3][1], p->vert[3][2], 1,1,br,bg,bb,ba); + transpolyend(); + } +} diff --git a/r_decals.h b/r_decals.h new file mode 100644 index 00000000..d0aedc5b --- /dev/null +++ b/r_decals.h @@ -0,0 +1,6 @@ + +void R_Decals_Init(); + +void R_DrawDecals(); + +void R_Decal(vec3_t org, rtexture_t *tex, float scale, int cred, int cgreen, int cblue, int alpha); diff --git a/r_explosion.c b/r_explosion.c index a69d4fe2..0350ac72 100644 --- a/r_explosion.c +++ b/r_explosion.c @@ -52,7 +52,8 @@ explosion_t explosion[128]; rtexture_t *explosiontexture; rtexture_t *explosiontexturefog; -cvar_t r_explosionclip = {"r_explosionclip", "0"}; +cvar_t r_explosionclip = {"r_explosionclip", "0", true}; +cvar_t r_drawexplosions = {"r_drawexplosions", "1"}; int R_ExplosionVert(int column, int row) { @@ -104,6 +105,11 @@ void r_explosion_shutdown() { } +void r_explosion_newmap() +{ + memset(explosion, 0, sizeof(explosion)); +} + void R_Explosion_Init() { int i, x, y; @@ -133,8 +139,9 @@ void R_Explosion_Init() } Cvar_RegisterVariable(&r_explosionclip); + Cvar_RegisterVariable(&r_drawexplosions); - R_RegisterModule("R_Explosions", r_explosion_start, r_explosion_shutdown); + R_RegisterModule("R_Explosions", r_explosion_start, r_explosion_shutdown, r_explosion_newmap); } void R_NewExplosion(vec3_t org) @@ -255,6 +262,8 @@ void R_MoveExplosions() void R_DrawExplosions() { int i; + if (!r_drawexplosions.value) + return; for (i = 0;i < MAX_EXPLOSIONS;i++) { if (explosion[i].alpha > 0.0f) diff --git a/r_light.c b/r_light.c index 39cde86d..37a2a0fd 100644 --- a/r_light.c +++ b/r_light.c @@ -33,10 +33,14 @@ void r_light_shutdown() { } +void r_light_newmap() +{ +} + void R_Light_Init() { Cvar_RegisterVariable(&r_lightmodels); - R_RegisterModule("R_Light", r_light_start, r_light_shutdown); + R_RegisterModule("R_Light", r_light_start, r_light_shutdown, r_light_newmap); } int r_dlightframecount; @@ -403,7 +407,7 @@ void R_PushDlights (void) for (i=0 ; idie < cl.time || !l->radius) + if (!l->radius) continue; // 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); @@ -685,7 +689,7 @@ void R_DynamicLightPoint(vec3_t color, vec3_t org, int *dlightbits) if (!((1 << i) & dlightbits[j])) continue; k = (j<<5)+i; - if (cl_dlights[k].die < cl.time || !cl_dlights[k].radius) + if (!cl_dlights[k].radius) continue; VectorSubtract (org, cl_dlights[k].origin, dist); f = DotProduct(dist, dist) + LIGHTOFFSET; @@ -702,7 +706,7 @@ void R_DynamicLightPoint(vec3_t color, vec3_t org, int *dlightbits) } } -void R_CompleteLightPoint (vec3_t color, vec3_t p) +void R_CompleteLightPoint (vec3_t color, vec3_t p, int dynamic) { mleaf_t *leaf; leaf = Mod_PointInLeaf(p, cl.worldmodel); @@ -721,7 +725,8 @@ void R_CompleteLightPoint (vec3_t color, vec3_t p) color[0] = color[1] = color[2] = r_ambient.value * 2.0f; RecursiveLightPoint (color, cl.worldmodel->nodes, p[0], p[1], p[2], p[2] - 65536); - R_DynamicLightPoint(color, p, leaf->dlightbits); + if (dynamic) + R_DynamicLightPoint(color, p, leaf->dlightbits); } void R_ModelLightPoint (vec3_t color, vec3_t p, int *dlightbits) @@ -772,7 +777,7 @@ void R_DynamicLightPointNoMask(vec3_t color, vec3_t org) for (i=0 ; icolormod[0] * 0.5f; - mod[1] = currententity->colormod[1] * 0.5f; - mod[2] = currententity->colormod[2] * 0.5f; + mod[0] = ent->colormod[0] * 0.5f; + mod[1] = ent->colormod[1] * 0.5f; + mod[2] = ent->colormod[2] * 0.5f; } else { - mod[0] = currententity->colormod[0]; - mod[1] = currententity->colormod[1]; - mod[2] = currententity->colormod[2]; + mod[0] = ent->colormod[0]; + mod[1] = ent->colormod[1]; + mod[2] = ent->colormod[2]; } - if (currententity->effects & EF_FULLBRIGHT) + if (ent->effects & EF_FULLBRIGHT) { ((byte *)&color)[0] = (byte) (255.0f * mod[0]); ((byte *)&color)[1] = (byte) (255.0f * mod[1]); @@ -864,7 +869,7 @@ void R_LightModel(int numverts, vec3_t center, vec3_t basecolor) nearlight[nearlights].color[0] = cl_dlights[i].color[0] * t1 * mod[0]; nearlight[nearlights].color[1] = cl_dlights[i].color[1] * t1 * mod[1]; nearlight[nearlights].color[2] = cl_dlights[i].color[2] * t1 * mod[2]; - if (r_lightmodels.value) + if (r_lightmodels.value && (ent == NULL || ent != cl_dlights[i].ent)) nearlights++; else { diff --git a/r_light.h b/r_light.h index 4d7bcb55..df11b53b 100644 --- a/r_light.h +++ b/r_light.h @@ -7,15 +7,16 @@ typedef struct float radius; float die; // stop lighting after this time float decay; // drop this each second - int key; + entity_t *ent; // the entity that spawned this light (can be NULL if it is not to be replaced repeatedly) vec3_t color; // LordHavoc: colored lighting - qboolean dark; // subtracts light instead of adding } dlight_t; // LordHavoc: this affects the lighting scale of the whole game #define LIGHTOFFSET 4096.0f -extern void R_CompleteLightPoint (vec3_t color, vec3_t p); +extern void R_CompleteLightPoint (vec3_t color, vec3_t p, int dynamic); extern void R_DynamicLightPoint(vec3_t color, vec3_t org, int *dlightbits); extern void R_DynamicLightPointNoMask(vec3_t color, vec3_t org); extern void R_LightPoint (vec3_t color, vec3_t p); + +extern int r_dlightframecount; diff --git a/r_modules.c b/r_modules.c index 1c30a4ca..69086f67 100644 --- a/r_modules.c +++ b/r_modules.c @@ -1,46 +1,50 @@ #include "quakedef.h" +#define MAXRENDERMODULES 64 + typedef struct rendermodule_s { int active; // set by start, cleared by shutdown char *name; void(*start)(); void(*shutdown)(); + void(*newmap)(); } rendermodule_t; -rendermodule_t rendermodule[64]; +rendermodule_t rendermodule[MAXRENDERMODULES]; void R_Modules_Init() { int i; - for (i = 0;i < 64;i++) + for (i = 0;i < MAXRENDERMODULES;i++) rendermodule[i].name = NULL; } -void R_RegisterModule(char *name, void(*start)(), void(*shutdown)()) +void R_RegisterModule(char *name, void(*start)(), void(*shutdown)(), void(*newmap)()) { int i; - for (i = 0;i < 64;i++) + for (i = 0;i < MAXRENDERMODULES;i++) { if (rendermodule[i].name == NULL) break; if (!strcmp(name, rendermodule[i].name)) Sys_Error("R_RegisterModule: module \"%s\" registered twice\n", name); } - if (i >= 64) - Sys_Error("R_RegisterModule: ran out of renderer module slots (64)\n"); + if (i >= MAXRENDERMODULES) + Sys_Error("R_RegisterModule: ran out of renderer module slots (%i)\n", MAXRENDERMODULES); rendermodule[i].active = 0; rendermodule[i].name = name; rendermodule[i].start = start; rendermodule[i].shutdown = shutdown; + rendermodule[i].newmap = newmap; } -void R_StartModules () +void R_Modules_Start () { int i; - for (i = 0;i < 64;i++) + for (i = 0;i < MAXRENDERMODULES;i++) { if (rendermodule[i].name == NULL) continue; @@ -51,10 +55,10 @@ void R_StartModules () } } -void R_ShutdownModules () +void R_Modules_Shutdown () { int i; - for (i = 0;i < 64;i++) + for (i = 0;i < MAXRENDERMODULES;i++) { if (rendermodule[i].name == NULL) continue; @@ -65,8 +69,21 @@ void R_ShutdownModules () } } -void R_Restart () +void R_Modules_Restart () +{ + R_Modules_Shutdown(); + R_Modules_Start(); +} + +void R_Modules_NewMap () { - R_ShutdownModules(); - R_StartModules(); + int i; + for (i = 0;i < MAXRENDERMODULES;i++) + { + if (rendermodule[i].name == NULL) + continue; + if (!rendermodule[i].active) + continue; + rendermodule[i].newmap(); + } } diff --git a/r_modules.h b/r_modules.h index 38aa9c62..72f41572 100644 --- a/r_modules.h +++ b/r_modules.h @@ -1,6 +1,7 @@ void R_Modules_Init(); -void R_RegisterModule(char *name, void(*start)(), void(*shutdown)()); -void R_StartModules (); -void R_ShutdownModules (); -void R_Restart (); +void R_RegisterModule(char *name, void(*start)(), void(*shutdown)(), void(*newmap)()); +void R_Modules_Start(); +void R_Modules_Shutdown(); +void R_Modules_NewMap(); +void R_Modules_Restart(); diff --git a/r_part.c b/r_part.c index 6abff27c..2e3f8f36 100644 --- a/r_part.c +++ b/r_part.c @@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // LordHavoc: added dust, smoke, snow, bloodcloud, and many others typedef enum { - pt_static, pt_grav, pt_slowgrav, pt_blob, pt_blob2, pt_bulletsmoke, pt_smoke, pt_snow, pt_rain, pt_bloodcloud, pt_fallfadespark, pt_bubble, pt_fade, pt_smokecloud, pt_splash, pt_flame, pt_glow, pt_decal, pt_blood, pt_bloodsplatter + pt_static, pt_grav, pt_slowgrav, pt_blob, pt_blob2, pt_bulletsmoke, pt_smoke, pt_snow, pt_rain, pt_spark, pt_bubble, pt_fade, pt_steam, pt_splash, pt_splashpuff, pt_flame/*, pt_decal*/, pt_blood, pt_oneframe, pt_lavasplash } ptype_t; @@ -48,7 +48,9 @@ typedef struct particle_s float bounce; // how much bounce-back from a surface the particle hits (0 = no physics, 1 = stop and slide, 2 = keep bouncing forever, 1.5 is typical of bouncing particles) vec3_t oldorg; vec3_t vel2; // used for snow fluttering (base velocity, wind for instance) - vec3_t direction; // used by decals +// vec3_t direction; // used by decals +// vec3_t decalright; // used by decals +// vec3_t decalup; // used by decals } particle_t; @@ -62,6 +64,7 @@ rtexture_t *particletexture; rtexture_t *smokeparticletexture[8]; rtexture_t *rainparticletexture; rtexture_t *bubbleparticletexture; +rtexture_t *bulletholetexture[8]; particle_t *particles; int r_numparticles; @@ -71,17 +74,22 @@ vec3_t r_pright, r_pup, r_ppn; int numparticles; particle_t **freeparticles; // list used only in compacting particles array -cvar_t r_particles = {"r_particles", "1"}; +cvar_t r_particles = {"r_particles", "1", true}; cvar_t r_drawparticles = {"r_drawparticles", "1"}; -cvar_t r_dynamicparticles = {"r_dynamicparticles", "1", true}; +cvar_t r_particles_lighting = {"r_particles_lighting", "1", true}; +cvar_t r_particles_bloodshowers = {"r_particles_bloodshowers", "1", true}; +cvar_t r_particles_blood = {"r_particles_blood", "1", true}; +cvar_t r_particles_smoke = {"r_particles_smoke", "1", true}; +cvar_t r_particles_sparks = {"r_particles_sparks", "1", true}; +cvar_t r_particles_bubbles = {"r_particles_bubbles", "1", true}; byte shadebubble(float dx, float dy, vec3_t light) { float dz, f, dot; vec3_t normal; - if ((dx*dx+dy*dy) < 1) // it does hit the sphere + dz = 1 - (dx*dx+dy*dy); + if (dz > 0) // it does hit the sphere { - dz = 1 - (dx*dx+dy*dy); f = 0; // back side normal[0] = dx;normal[1] = dy;normal[2] = dz; @@ -122,8 +130,8 @@ void R_InitParticleTexture (void) { data[y][x][0] = data[y][x][1] = data[y][x][2] = 255; dx = x - 16; - d = (255 - (dx*dx+dy*dy)); - if (d < 0) d = 0; + d = (256 - (dx*dx+dy*dy)); + d = bound(0, d, 255); data[y][x][3] = (byte) d; } } @@ -141,38 +149,30 @@ void R_InitParticleTexture (void) dy = y - 16; for (x = 0;x < 32;x++) { - int j; - j = (noise1[y][x] - 128) * 2 + 128; - if (j < 0) j = 0; - if (j > 255) j = 255; - data[y][x][0] = data[y][x][1] = data[y][x][2] = j; + d = (noise1[y][x] - 128) * 2 + 128; + d = bound(0, d, 255); + data[y][x][0] = data[y][x][1] = data[y][x][2] = d; dx = x - 16; d = (noise2[y][x] - 128) * 4 + 128; if (d > 0) - { - d = (d * (255 - (int) (dx*dx+dy*dy))) >> 8; - //j = (sqrt(dx*dx+dy*dy) * 2.0f - 16.0f); - //if (j > 0) - // d = (d * (255 - j*j)) >> 8; - if (d < 0) d = 0; - if (d > 255) d = 255; - data[y][x][3] = (byte) d; - if (m < d) - m = d; - } + d = (d * (256 - (int) (dx*dx+dy*dy))) >> 8; + d = bound(0, d, 255); + data[y][x][3] = (byte) d; + if (m < d) + m = d; } } } - while (m < 192); + while (m < 224); smokeparticletexture[i] = R_LoadTexture (va("smokeparticletexture%d", i), 32, 32, &data[0][0][0], TEXF_MIPMAP | TEXF_ALPHA | TEXF_RGBA | TEXF_PRECACHE); } light[0] = 1;light[1] = 1;light[2] = 1; VectorNormalize(light); - for (x=0 ; x<32 ; x++) + for (y = 0;y < 32;y++) { - for (y=0 ; y<32 ; y++) + for (x = 0;x < 32;x++) { data[y][x][0] = data[y][x][1] = data[y][x][2] = 255; data[y][x][3] = shadebubble((x - 16) * (1.0 / 8.0), y < 24 ? (y - 24) * (1.0 / 24.0) : (y - 24) * (1.0 / 8.0), light); @@ -182,15 +182,69 @@ void R_InitParticleTexture (void) light[0] = 1;light[1] = 1;light[2] = 1; VectorNormalize(light); - for (x=0 ; x<32 ; x++) + for (y = 0;y < 32;y++) { - for (y=0 ; y<32 ; y++) + for (x = 0;x < 32;x++) { data[y][x][0] = data[y][x][1] = data[y][x][2] = 255; data[y][x][3] = shadebubble((x - 16) * (1.0 / 16.0), (y - 16) * (1.0 / 16.0), light); } } bubbleparticletexture = R_LoadTexture ("bubbleparticletexture", 32, 32, &data[0][0][0], TEXF_MIPMAP | TEXF_ALPHA | TEXF_RGBA | TEXF_PRECACHE); + + for (i = 0;i < 8;i++) + { + float p[32][32]; + fractalnoise(&noise1[0][0], 64, 8); + for (y = 0;y < 32;y++) + for (x = 0;x < 32;x++) + p[y][x] = (noise1[y][x] / 8.0f) - 64.0f; + for (m = 0;m < 32;m++) + { + int j; + float fx, fy, f; + fx = lhrandom(14, 18); + fy = lhrandom(14, 18); + do + { + dx = lhrandom(-1, 1); + dy = lhrandom(-1, 1); + f = (dx * dx + dy * dy); + } + while(f < 0.125f || f > 1.0f); + f = (m + 1) / 40.0f; //lhrandom(0.0f, 1.0); + dx *= 1.0f / 32.0f; + dy *= 1.0f / 32.0f; + for (j = 0;f > 0 && j < (32 * 14);j++) + { + y = fy; + x = fx; + fx += dx; + fy += dy; + p[y - 1][x - 1] += f * 0.125f; + p[y - 1][x ] += f * 0.25f; + p[y - 1][x + 1] += f * 0.125f; + p[y ][x - 1] += f * 0.25f; + p[y ][x ] += f; + p[y ][x + 1] += f * 0.25f; + p[y + 1][x - 1] += f * 0.125f; + p[y + 1][x ] += f * 0.25f; + p[y + 1][x + 1] += f * 0.125f; +// f -= (0.5f / (32 * 16)); + } + } + for (y = 0;y < 32;y++) + { + for (x = 0;x < 32;x++) + { + m = p[y][x]; + data[y][x][0] = data[y][x][1] = data[y][x][2] = 255; + data[y][x][3] = (byte) bound(0, m, 255); + } + } + + bulletholetexture[i] = R_LoadTexture (va("bulletholetexture%d", i), 32, 32, &data[0][0][0], TEXF_MIPMAP | TEXF_ALPHA | TEXF_RGBA | TEXF_PRECACHE); + } } void r_part_start() @@ -208,6 +262,11 @@ void r_part_shutdown() qfree(freeparticles); } +void r_part_newmap() +{ + numparticles = 0; +} + /* =============== R_InitParticles @@ -235,9 +294,14 @@ void R_Particles_Init (void) Cvar_RegisterVariable (&r_particles); Cvar_RegisterVariable (&r_drawparticles); - Cvar_RegisterVariable (&r_dynamicparticles); - - R_RegisterModule("R_Particles", r_part_start, r_part_shutdown); + Cvar_RegisterVariable (&r_particles_lighting); + Cvar_RegisterVariable (&r_particles_bloodshowers); + Cvar_RegisterVariable (&r_particles_blood); + Cvar_RegisterVariable (&r_particles_smoke); + Cvar_RegisterVariable (&r_particles_sparks); + Cvar_RegisterVariable (&r_particles_bubbles); + + R_RegisterModule("R_Particles", r_part_start, r_part_shutdown, r_part_newmap); } //void particle(int ptype, int pcolor, int ptex, int prendermode, int plight, float pscale, float palpha, float ptime, float pbounce, float px, float py, float pz, float pvx, float pvy, float pvz) @@ -265,6 +329,7 @@ void R_Particles_Init (void) part->time2 = 0;\ part->vel2[0] = part->vel2[1] = part->vel2[2] = 0;\ } +/* #define particle2(ptype, pcolor, ptex, prendermode, plight, pscale, palpha, ptime, pbounce, pbase, poscale, pvscale)\ {\ particle_t *part;\ @@ -289,6 +354,8 @@ void R_Particles_Init (void) part->time2 = 0;\ part->vel2[0] = part->vel2[1] = part->vel2[2] = 0;\ } +*/ +/* #define particle3(ptype, pcolor, ptex, prendermode, plight, pscale, palpha, ptime, pbounce, pbase, pscalex, pscaley, pscalez, pvscalex, pvscaley, pvscalez)\ {\ particle_t *part;\ @@ -313,6 +380,7 @@ void R_Particles_Init (void) part->time2 = 0;\ part->vel2[0] = part->vel2[1] = part->vel2[2] = 0;\ } +*/ #define particle4(ptype, pcolor, ptex, prendermode, plight, pscale, palpha, ptime, pbounce, px, py, pz, pvx, pvy, pvz, ptime2, pvx2, pvy2, pvz2)\ {\ particle_t *part;\ @@ -376,30 +444,11 @@ void R_EntityParticles (entity_t *ent) forward[1] = cp*sy; forward[2] = -sp; - particle(pt_static, 0x6f, particletexture, TPOLYTYPE_ALPHA, false, 2, 255, 0, 0, ent->origin[0] + m_bytenormals[i][0]*dist + forward[0]*beamlength, ent->origin[1] + m_bytenormals[i][1]*dist + forward[1]*beamlength, ent->origin[2] + m_bytenormals[i][2]*dist + forward[2]*beamlength, 0, 0, 0); + particle(pt_oneframe, 0x6f, particletexture, TPOLYTYPE_ALPHA, false, 2, 255, 9999, 0, ent->origin[0] + m_bytenormals[i][0]*dist + forward[0]*beamlength, ent->origin[1] + m_bytenormals[i][1]*dist + forward[1]*beamlength, ent->origin[2] + m_bytenormals[i][2]*dist + forward[2]*beamlength, 0, 0, 0); } } -/* -=============== -R_ClearParticles -=============== -*/ -void R_ClearParticles (void) -{ -// int i; -// free_particles = &particles[0]; -// active_particles = NULL; - -// for (i=0 ;icontents; if (i == CONTENTS_SLIME || i == CONTENTS_WATER) { - for (i=0 ; i<128 ; i++) - particle2(pt_bubble, (rand()&3) + 12, bubbleparticletexture, TPOLYTYPE_ADD, false, lhrandom(1, 2), 255, 2, 1.5, org, 16, 96); + for (i = 0;i < 128;i++) + particle(pt_bubble, 254, bubbleparticletexture, TPOLYTYPE_ADD, false, lhrandom(1, 2), 255, 9999, 1.5, org[0] + lhrandom(-16, 16), org[1] + lhrandom(-16, 16), org[2] + lhrandom(-16, 16), lhrandom(-96, 96), lhrandom(-96, 96), lhrandom(-96, 96)); } else R_NewExplosion(org); @@ -493,9 +542,9 @@ void R_ParticleExplosion (vec3_t org, int smoke) // int color; float f, forg[3], fvel[3], fvel2[3]; // for (i = 0;i < 256;i++) -// particle(pt_fallfadespark, ramp3[rand()%6], particletexture, TPOLYTYPE_ALPHA, false, 1.5, lhrandom(128, 255), 5, lhrandom(-16, 16) + org[0], lhrandom(-16, 16) + org[1], lhrandom(-16, 16) + org[2], lhrandom(-192, 192), lhrandom(-192, 192), lhrandom(-192, 192) + 192); +// particle(pt_fallfadespark, ramp3[rand()%6], particletexture, TPOLYTYPE_ALPHA, false, 1.5, lhrandom(128, 255), 5, org[0] + lhrandom(-16, 16), org[1] + lhrandom(-16, 16), org[2] + lhrandom(-16, 16), lhrandom(-192, 192), lhrandom(-192, 192), lhrandom(0, 384)); // for (i = 0;i < 256;i++) -// particle2(pt_fallfadespark, ramp3[rand()%6], particletexture, TPOLYTYPE_ALPHA, false, 1.5, lhrandom(128, 255), 5, org, 15, 150); +// particle(pt_fallfadespark, ramp3[rand()%6], particletexture, TPOLYTYPE_ALPHA, false, 1.5, lhrandom(128, 255), 5, org[0] + lhrandom(-16, 16), org[1] + lhrandom(-16, 16), org[2] + lhrandom(-16, 16), lhrandom(-150, 150), lhrandom(-150, 150), lhrandom(-150, 150)); for (i = 0;i < 32;i++) { fvel[0] = lhrandom(-150, 150); @@ -518,11 +567,11 @@ void R_ParticleExplosion (vec3_t org, int smoke) } } // for (i = 0;i < 16;i++) -// particle2(pt_smoke, 12+(rand()&3), smokeparticletexture[rand()&7], TPOLYTYPE_ALPHA, true, 20, 192, 99, org, 20, 0); +// particle(pt_smoke, 12+(rand()&3), smokeparticletexture[rand()&7], TPOLYTYPE_ALPHA, true, 20, 192, 99, org[0] + lhrandom(-20, 20), org[1] + lhrandom(-20, 20), org[2] + lhrandom(-20, 20), 0, 0, 0); // for (i = 0;i < 50;i++) -// particle2(pt_flamingdebris, ramp3[rand()%6], particletexture, TPOLYTYPE_ALPHA, false, 3, 255, 99, org, 10, 200); +// particle(pt_flamingdebris, ramp3[rand()%6], particletexture, TPOLYTYPE_ALPHA, false, 3, 255, 99, org[0] + lhrandom(-10, 10), org[1] + lhrandom(-10, 10), org[2] + lhrandom(-10, 10), lhrandom(-200, 200), lhrandom(-200, 200), lhrandom(-200, 200)); // for (i = 0;i < 30;i++) -// particle2(pt_smokingdebris, 10 + (rand()%6), particletexture, TPOLYTYPE_ALPHA, false, 2, 255, 99, org, 10, 100); +// particle(pt_smokingdebris, 10 + (rand()%6), particletexture, TPOLYTYPE_ALPHA, false, 2, 255, 99, org[0] + lhrandom(-10, 10), org[1] + lhrandom(-10, 10), org[2] + lhrandom(-10, 10), lhrandom(-100, 100), lhrandom(-100, 100), lhrandom(-100, 100)); } */ } @@ -539,7 +588,7 @@ void R_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength) if (!r_particles.value) return; // LordHavoc: particles are optional for (i = 0;i < 512;i++) - particle2(pt_fade, colorStart + (i % colorLength), particletexture, TPOLYTYPE_ALPHA, false, 1.5, 255, 0.3, 0, org, 8, 192); + particle(pt_fade, colorStart + (i % colorLength), particletexture, TPOLYTYPE_ALPHA, false, 1.5, 255, 0.3, 0, org[0] + lhrandom(-8, 8), org[1] + lhrandom(-8, 8), org[2] + lhrandom(-8, 8), lhrandom(-192, 192), lhrandom(-192, 192), lhrandom(-192, 192)); } /* @@ -553,10 +602,10 @@ void R_BlobExplosion (vec3_t org) int i; if (!r_particles.value) return; // LordHavoc: particles are optional - for (i=0 ; i<512 ; i++) - particle3(pt_blob, 66+(rand()%6), particletexture, TPOLYTYPE_ALPHA, false, 2, 255, lhrandom(1, 1.4), 0, org, 16, 16, 16, 4, 4, 128); - for (i=0 ; i<512 ; i++) - particle3(pt_blob2, 150+(rand()%6), particletexture, TPOLYTYPE_ALPHA, false, 2, 255, lhrandom(1, 1.4), 0, org, 16, 16, 16, 4, 4, 128); + for (i = 0;i < 256;i++) + particle(pt_blob, 66+(rand()%6), particletexture, TPOLYTYPE_ALPHA, false, 4, 255, 9999, 0, org[0] + lhrandom(-16, 16), org[1] + lhrandom(-16, 16), org[2] + lhrandom(-16, 16), lhrandom(-4, 4), lhrandom(-4, 4), lhrandom(-128, 128)); + for (i = 0;i < 256;i++) + particle(pt_blob2, 150+(rand()%6), particletexture, TPOLYTYPE_ALPHA, false, 4, 255, 9999, 0, org[0] + lhrandom(-16, 16), org[1] + lhrandom(-16, 16), org[2] + lhrandom(-16, 16), lhrandom(-4, 4), lhrandom(-4, 4), lhrandom(-128, 128)); } /* @@ -575,7 +624,7 @@ void R_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count) return; } while (count--) - particle2(pt_fade, color + (rand()&7), particletexture, TPOLYTYPE_ALPHA, false, 1, 128, 1, 0, org, 8, 15); + particle(pt_fade, color + (rand()&7), particletexture, TPOLYTYPE_ALPHA, false, 1, 128, 9999, 0, org[0] + lhrandom(-8, 8), org[1] + lhrandom(-8, 8), org[2] + lhrandom(-8, 8), lhrandom(-15, 15), lhrandom(-15, 15), lhrandom(-15, 15)); } // LordHavoc: added this for spawning sparks/dust (which have strong gravity) @@ -588,23 +637,34 @@ void R_SparkShower (vec3_t org, vec3_t dir, int count) { if (!r_particles.value) return; // LordHavoc: particles are optional + R_Decal(org, bulletholetexture[rand()&7], 16, 0, 0, 0, 255); + // smoke puff - particle(pt_bulletsmoke, 12+(rand()&3), smokeparticletexture[rand()&7], TPOLYTYPE_ALPHA, true, 1, 160, 99, 0, org[0], org[1], org[2], lhrandom(-4, 4), lhrandom(-4, 4), 16); - // sparks - while(count--) - particle(pt_fallfadespark, ramp3[rand()%6], particletexture, TPOLYTYPE_ADD, false, 1, lhrandom(0, 255), 1.5, 1.5, org[0], org[1], org[2], lhrandom(-64, 64), lhrandom(-64, 64), lhrandom(-64, 64) + 128); + if (r_particles_smoke.value) + particle(pt_bulletsmoke, 10, smokeparticletexture[rand()&7], TPOLYTYPE_ALPHA, true, 5, 255, 9999, 0, org[0], org[1], org[2], lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(0, 16)); + + if (r_particles_sparks.value) + { + // sparks + while(count--) + particle(pt_spark, ramp3[rand()%6], particletexture, TPOLYTYPE_ADD, false, 1, lhrandom(0, 255), 9999, 1.5, org[0], org[1], org[2], lhrandom(-64, 64), lhrandom(-64, 64), lhrandom(0, 128)); + } } void R_BloodPuff (vec3_t org, vec3_t vel, int count) { + // bloodcount is used to accumulate counts too small to cause a blood particle + static int bloodcount = 0; if (!r_particles.value) return; // LordHavoc: particles are optional + if (!r_particles_blood.value) return; if (count > 100) count = 100; - while(count > 0) + bloodcount += count; + while(bloodcount >= 10) { - particle(pt_bloodsplatter, 68+(rand()&3), smokeparticletexture[rand()&7], TPOLYTYPE_ALPHA, true, lhrandom(10, 20), min(count, 10) * 25 + 5, 99, -1, org[0], org[1], org[2], vel[0] + lhrandom(-64, 64), vel[1] + lhrandom(-64, 64), vel[2] + lhrandom(-64, 64)); - count -= 10; + particle(pt_blood, 68+(rand()&3), smokeparticletexture[rand()&7], TPOLYTYPE_ALPHA, true, 24, 255, 9999, -1, org[0], org[1], org[2], vel[0] + lhrandom(-64, 64), vel[1] + lhrandom(-64, 64), vel[2] + lhrandom(-64, 64)); + bloodcount -= 10; } } @@ -614,6 +674,8 @@ void R_BloodShower (vec3_t mins, vec3_t maxs, float velspeed, int count) vec3_t center; vec3_t velscale; if (!r_particles.value) return; // LordHavoc: particles are optional + if (!r_particles_bloodshowers.value) return; + if (!r_particles_blood.value) return; VectorSubtract(maxs, mins, diff); center[0] = (mins[0] + maxs[0]) * 0.5; @@ -633,7 +695,7 @@ void R_BloodShower (vec3_t mins, vec3_t maxs, float velspeed, int count) vel[0] = (org[0] - center[0]) * velscale[0]; vel[1] = (org[1] - center[1]) * velscale[1]; vel[2] = (org[2] - center[2]) * velscale[2]; - particle(pt_bloodsplatter, 68+(rand()&3), smokeparticletexture[rand()&7], TPOLYTYPE_ALPHA, true, lhrandom(10, 25), 255, 99, -1, org[0], org[1], org[2], vel[0], vel[1], vel[2]); + particle(pt_blood, 68+(rand()&3), smokeparticletexture[rand()&7], TPOLYTYPE_ALPHA, true, 24, 255, 9999, -1, org[0], org[1], org[2], vel[0], vel[1], vel[2]); } } @@ -704,7 +766,7 @@ void R_FlameCube (vec3_t mins, vec3_t maxs, int count) if (maxs[2] <= mins[2]) {t = mins[2];mins[2] = maxs[2];maxs[2] = t;} while (count--) - particle(pt_flame, 224 + (rand()&15), smokeparticletexture[rand()&7], TPOLYTYPE_ADD, false, 1, lhrandom(64, 255), 5, 0, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(mins[2], maxs[2]), lhrandom(-16, 16), lhrandom(-16, 16), lhrandom(-16, 48)); + particle(pt_flame, 224 + (rand()&15), smokeparticletexture[rand()&7], TPOLYTYPE_ADD, false, 8, 255, 9999, 1.1, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(mins[2], maxs[2]), lhrandom(-32, 32), lhrandom(-32, 32), lhrandom(-32, 64)); } void R_Flames (vec3_t org, vec3_t vel, int count) @@ -712,7 +774,7 @@ void R_Flames (vec3_t org, vec3_t vel, int count) if (!r_particles.value) return; // LordHavoc: particles are optional while (count--) - particle(pt_flame, 224 + (rand()&15), smokeparticletexture[rand()&7], TPOLYTYPE_ADD, false, 1, lhrandom(64, 255), 5, 1.5, org[0], org[1], org[2], vel[0] + lhrandom(-16, 16), vel[1] + lhrandom(-16, 16), vel[2] + lhrandom(-16, 16)); + particle(pt_flame, 224 + (rand()&15), smokeparticletexture[rand()&7], TPOLYTYPE_ADD, false, 8, 255, 9999, 1.1, org[0], org[1], org[2], vel[0] + lhrandom(-128, 128), vel[1] + lhrandom(-128, 128), vel[2] + lhrandom(-128, 128)); } @@ -730,9 +792,9 @@ void R_LavaSplash (vec3_t origin) vec3_t dir, org; if (!r_particles.value) return; // LordHavoc: particles are optional - for (i=-128 ; i<128 ; i+=8) + for (i=-128 ; i<128 ; i+=16) { - for (j=-128 ; j<128 ; j+=8) + for (j=-128 ; j<128 ; j+=16) { dir[0] = j + lhrandom(0, 8); dir[1] = i + lhrandom(0, 8); @@ -741,8 +803,8 @@ void R_LavaSplash (vec3_t origin) org[1] = origin[1] + dir[1]; org[2] = origin[2] + lhrandom(0, 64); vel = lhrandom(50, 120) / VectorLength(dir); // normalize and scale - particle(pt_slowgrav, 224 + (rand()&7), particletexture, TPOLYTYPE_ALPHA, false, 3, 128, lhrandom(2, 2.5), 0, org[0], org[1], org[2], dir[0] * vel, dir[1] * vel, dir[2] * vel); -// particle(pt_slowgrav, 224 + (rand()&7), particletexture, TPOLYTYPE_ALPHA, false, 3, 128, lhrandom(2, 2.5), 0, origin[0] + i, origin[1] + j, origin[2] + lhrandom(0, 63), i * lhrandom(0.125, 0.25), j * lhrandom(0.125, 0.25), lhrandom(64, 128)); + particle(pt_lavasplash, 224 + (rand()&7), particletexture, TPOLYTYPE_ALPHA, false, 7, 255, 9999, 0, org[0], org[1], org[2], dir[0] * vel, dir[1] * vel, dir[2] * vel); +// particle(pt_lavasplash, 224 + (rand()&7), particletexture, TPOLYTYPE_ALPHA, false, 7, 255, 9999, 0, origin[0] + i, origin[1] + j, origin[2] + lhrandom(0, 63), i * lhrandom(0.125, 0.25), j * lhrandom(0.125, 0.25), lhrandom(64, 128)); } } } @@ -761,7 +823,7 @@ void R_TeleportSplash (vec3_t org) for (i=-16 ; i<16 ; i+=8) for (j=-16 ; j<16 ; j+=8) for (k=-24 ; k<32 ; k+=8) - particle(pt_fade, 254, particletexture, TPOLYTYPE_ADD, false, 1, lhrandom(64, 128), 5, 0, org[0] + i + lhrandom(0, 8), org[1] + j + lhrandom(0, 8), org[2] + k + lhrandom(0, 8), i*2 + lhrandom(-12.5, 12.5), j*2 + lhrandom(-12.5, 12.5), k*2 + lhrandom(27.5, 52.5)); + particle(pt_fade, 254, particletexture, TPOLYTYPE_ADD, false, 1, lhrandom(64, 128), 9999, 0, org[0] + i + lhrandom(0, 8), org[1] + j + lhrandom(0, 8), org[2] + k + lhrandom(0, 8), i*2 + lhrandom(-12.5, 12.5), j*2 + lhrandom(-12.5, 12.5), k*2 + lhrandom(27.5, 52.5)); } void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) @@ -777,7 +839,7 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) /* if (type == 0) // rocket glow - particle(pt_glow, 254, particletexture, TPOLYTYPE_ADD, false, 10, 160, 999, 0, start[0] - 12 * dir[0], start[1] - 12 * dir[1], start[2] - 12 * dir[2], 0, 0, 0); + particle(pt_glow, 254, particletexture, TPOLYTYPE_ADD, false, 10, 160, 9999, 0, start[0] - 12 * dir[0], start[1] - 12 * dir[1], start[2] - 12 * dir[2], 0, 0, 0); */ t = ent->trail_time; @@ -822,48 +884,63 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) switch (type) { case 0: // rocket trail - if (bubbles) + if (!r_particles_smoke.value) + dec = cl.time - t; + else if (bubbles && r_particles_bubbles.value) { dec = 0.01f; - particle(pt_bubble, 254, bubbleparticletexture, polytype, false, lhrandom(1, 2), 255, 2, 1.5, start[0], start[1], start[2], lhrandom(-16, 16), lhrandom(-16, 16), lhrandom(-16, 16)); + particle(pt_bubble, 254, bubbleparticletexture, polytype, false, lhrandom(1, 2), 255, 9999, 1.5, start[0], start[1], start[2], lhrandom(-16, 16), lhrandom(-16, 16), lhrandom(-16, 16)); + particle(pt_bubble, 254, bubbleparticletexture, polytype, false, lhrandom(1, 2), 255, 9999, 1.5, start[0], start[1], start[2], lhrandom(-16, 16), lhrandom(-16, 16), lhrandom(-16, 16)); + particle(pt_smoke, 254, smokeparticletexture[rand()&7], polytype, false, 2, 160, 9999, 0, start[0], start[1], start[2], 0, 0, 0); } else { dec = 0.01f; - particle(pt_smoke, 254, smokeparticletexture[rand()&7], polytype, true, 2, 160, 9999, 0, start[0], start[1], start[2], 0, 0, 16); - if (type == 0) - { - particle(pt_fallfadespark, 0x68 + (rand() & 7), particletexture, TPOLYTYPE_ADD, false, 1, lhrandom(128, 255), 5, 0, start[0], start[1], start[2], lhrandom(-64, 64) - vel[0] * 0.25, lhrandom(-64, 64) - vel[1] * 0.25, lhrandom(-64, 64) - vel[2] * 0.25); - particle(pt_fallfadespark, 0x68 + (rand() & 7), particletexture, TPOLYTYPE_ADD, false, 1, lhrandom(128, 255), 5, 0, start[0], start[1], start[2], lhrandom(-64, 64) - vel[0] * 0.25, lhrandom(-64, 64) - vel[1] * 0.25, lhrandom(-64, 64) - vel[2] * 0.25); -// particle(pt_fallfadespark, 0x68 + (rand() & 7), particletexture, TPOLYTYPE_ADD, false, 1, lhrandom(128, 255), 5, 0, start[0], start[1], start[2], lhrandom(-64, 64) - vel[0] * 0.25, lhrandom(-64, 64) - vel[1] * 0.25, lhrandom(-64, 64) - vel[2] * 0.25); -// particle(pt_fallfadespark, 0x68 + (rand() & 7), particletexture, TPOLYTYPE_ADD, false, 1, lhrandom(128, 255), 5, 0, start[0], start[1], start[2], lhrandom(-64, 64) - vel[0] * 0.25, lhrandom(-64, 64) - vel[1] * 0.25, lhrandom(-64, 64) - vel[2] * 0.25); - } + particle(pt_smoke, 12, smokeparticletexture[rand()&7], polytype, true, 2, 160, 9999, 0, start[0], start[1], start[2], 0, 0, 0); +// particle(pt_spark, 0x68 + (rand() & 7), particletexture, TPOLYTYPE_ADD, false, 1, lhrandom(128, 255), 9999, 1.5, start[0], start[1], start[2], lhrandom(-64, 64) - vel[0] * 0.25, lhrandom(-64, 64) - vel[1] * 0.25, lhrandom(-64, 64) - vel[2] * 0.25); +// particle(pt_spark, 0x68 + (rand() & 7), particletexture, TPOLYTYPE_ADD, false, 1, lhrandom(128, 255), 9999, 1.5, start[0], start[1], start[2], lhrandom(-64, 64) - vel[0] * 0.25, lhrandom(-64, 64) - vel[1] * 0.25, lhrandom(-64, 64) - vel[2] * 0.25); +// particle(pt_spark, 0x68 + (rand() & 7), particletexture, TPOLYTYPE_ADD, false, 1, lhrandom(128, 255), 9999, 1.5, start[0], start[1], start[2], lhrandom(-64, 64) - vel[0] * 0.25, lhrandom(-64, 64) - vel[1] * 0.25, lhrandom(-64, 64) - vel[2] * 0.25); +// particle(pt_spark, 0x68 + (rand() & 7), particletexture, TPOLYTYPE_ADD, false, 1, lhrandom(128, 255), 9999, 1.5, start[0], start[1], start[2], lhrandom(-64, 64) - vel[0] * 0.25, lhrandom(-64, 64) - vel[1] * 0.25, lhrandom(-64, 64) - vel[2] * 0.25); } break; case 1: // grenade trail // FIXME: make it gradually stop smoking - if (bubbles) + if (!r_particles_smoke.value) + dec = cl.time - t; + else if (bubbles && r_particles_bubbles.value) { dec = 0.02f; - particle(pt_bubble, 254, bubbleparticletexture, polytype, false, lhrandom(1, 2), 255, 2, 1.5, start[0], start[1], start[2], lhrandom(-16, 16), lhrandom(-16, 16), lhrandom(-16, 16)); + particle(pt_bubble, 254, bubbleparticletexture, polytype, false, lhrandom(1, 2), 255, 9999, 1.5, start[0], start[1], start[2], lhrandom(-16, 16), lhrandom(-16, 16), lhrandom(-16, 16)); + particle(pt_bubble, 254, bubbleparticletexture, polytype, false, lhrandom(1, 2), 255, 9999, 1.5, start[0], start[1], start[2], lhrandom(-16, 16), lhrandom(-16, 16), lhrandom(-16, 16)); + particle(pt_smoke, 254, smokeparticletexture[rand()&7], polytype, false, 2, 160, 9999, 0, start[0], start[1], start[2], 0, 0, 0); } else { dec = 0.02f; - particle(pt_smoke, 6, smokeparticletexture[rand()&7], polytype, true, 2, 160, 9999, 0, start[0], start[1], start[2], 0, 0, 16); + particle(pt_smoke, 8, smokeparticletexture[rand()&7], polytype, true, 2, 160, 9999, 0, start[0], start[1], start[2], 0, 0, 0); } break; case 2: // blood - dec = 0.025f; - particle(pt_bloodsplatter, 67+(rand()&3), smokeparticletexture[rand()&7], polytype, true, lhrandom(5, 20), 255, 9999, -1, start[0], start[1], start[2], vel[0] + lhrandom(-64, 64), vel[1] + lhrandom(-64, 64), vel[2] + lhrandom(-64, 64)); + if (!r_particles_blood.value) + dec = cl.time - t; + else + { + dec = 0.2f; + particle(pt_blood, 67+(rand()&3), smokeparticletexture[rand()&7], polytype, true, 24, 255, 9999, -1, start[0], start[1], start[2], vel[0] + lhrandom(-64, 64), vel[1] + lhrandom(-64, 64), vel[2] + lhrandom(-64, 64)); + } break; case 4: // slight blood - dec = 0.025f; - particle(pt_bloodsplatter, 67+(rand()&3), smokeparticletexture[rand()&7], polytype, true, lhrandom(5, 20), 192, 9999, -1, start[0], start[1], start[2], vel[0] + lhrandom(-64, 64), vel[1] + lhrandom(-64, 64), vel[2] + lhrandom(-64, 64)); + if (!r_particles_blood.value) + dec = cl.time - t; + else + { + dec = 0.3f; + particle(pt_blood, 67+(rand()&3), smokeparticletexture[rand()&7], polytype, true, 24, 255, 9999, -1, start[0], start[1], start[2], vel[0] + lhrandom(-64, 64), vel[1] + lhrandom(-64, 64), vel[2] + lhrandom(-64, 64)); + } break; case 3: // green tracer @@ -882,11 +959,16 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) break; case 7: // Nehahra smoke tracer - dec = 0.14f; - particle(pt_smoke, 12, smokeparticletexture[rand()&7], polytype, true, 10, 64, 9999, 0, start[0], start[1], start[2], 0, 0, 0); + if (!r_particles_smoke.value) + dec = cl.time - t; + else + { + dec = 0.14f; + particle(pt_smoke, 12, smokeparticletexture[rand()&7], polytype, true, 10, 64, 9999, 0, start[0], start[1], start[2], 0, 0, 0); + } break; } - + // advance to next time and position t += dec; dec *= speed; @@ -900,13 +982,14 @@ void R_RocketTrail2 (vec3_t start, vec3_t end, int color, entity_t *ent) vec3_t vec; int len; if (!r_particles.value) return; // LordHavoc: particles are optional + if (!r_particles_smoke.value) return; VectorSubtract (end, start, vec); len = (int) (VectorNormalizeLength (vec) * (1.0f / 3.0f)); VectorScale(vec, 3, vec); while (len--) { - particle(pt_smoke, color, particletexture, TPOLYTYPE_ALPHA, false, 8, 192, 99, 0, start[0], start[1], start[2], 0, 0, 0); + particle(pt_smoke, color, particletexture, TPOLYTYPE_ALPHA, false, 8, 192, 9999, 0, start[0], start[1], start[2], 0, 0, 0); VectorAdd (start, vec, start); } } @@ -931,6 +1014,8 @@ void R_MoveParticles (void) return; frametime = cl.time - cl.oldtime; + if (!frametime) + return; // if absolutely still, don't update particles gravity = frametime * sv_gravity.value; dvel = 1+4*frametime; @@ -958,23 +1043,28 @@ void R_MoveParticles (void) VectorCopy(v, p->org); if (p->bounce < 0) { + byte *color24 = (byte *) &d_8to24table[(int)p->color]; + R_Decal(v, p->tex, p->scale, color24[0], color24[1], color24[2], p->alpha); + p->die = -1; + freeparticles[j++] = p; + continue; + /* VectorClear(p->vel); p->type = pt_decal; // have to negate the direction (why?) VectorNegate(normal, p->direction); + VectorVectors(p->direction, p->decalright, p->decalup); + VectorSubtract(p->org, p->direction, p->org); // push off the surface a bit so it doesn't flicker p->bounce = 0; p->time2 = cl.time + 30; + */ } else { dist = DotProduct(p->vel, normal) * -p->bounce; VectorMAQuick(p->vel, dist, normal, p->vel); if (DotProduct(p->vel, p->vel) < 0.03) - { VectorClear(p->vel); - // hack - world is static, therefore there won't be any moving or disappearing surfaces to worry about - //p->bounce = 0; - } } } } @@ -990,6 +1080,9 @@ void R_MoveParticles (void) case pt_blob2: p->vel[0] *= dvel; p->vel[1] *= dvel; + p->alpha -= frametime * 256; + if (p->alpha < 1) + p->die = -1; break; case pt_grav: @@ -998,6 +1091,12 @@ void R_MoveParticles (void) case pt_slowgrav: p->vel[2] -= gravity * 0.05; break; + case pt_lavasplash: + p->vel[2] -= gravity * 0.05; + p->alpha -= frametime * 192; + if (p->alpha < 1) + p->die = -1; + break; case pt_snow: if (cl.time > p->time2) { @@ -1019,7 +1118,7 @@ void R_MoveParticles (void) case CONTENTS_LAVA: case CONTENTS_SLIME: p->tex = smokeparticletexture[rand()&7]; - p->type = pt_smokecloud; + p->type = pt_steam; p->alpha = 96; p->scale = 5; p->vel[2] = 96; @@ -1041,43 +1140,16 @@ void R_MoveParticles (void) } } break; - case pt_bloodcloud: -// if (Mod_PointInLeaf(p->org, cl.worldmodel)->contents != CONTENTS_EMPTY) -// { -// p->die = -1; -// break; -// } - p->scale += frametime * 16; - p->alpha -= frametime * 256; - p->vel[2] -= gravity * 0.25; - if (p->alpha < 1) - p->die = -1; - break; case pt_blood: -// if (Mod_PointInLeaf(p->org, cl.worldmodel)->contents != CONTENTS_EMPTY) -// { -// p->die = -1; -// break; -// } - p->scale += frametime * 16; - p->alpha -= frametime * 512; - p->vel[2] -= gravity * 0.25; - if (p->alpha < 1) - p->die = -1; - break; - case pt_bloodsplatter: -// if (Mod_PointInLeaf(p->org, cl.worldmodel)->contents != CONTENTS_EMPTY) -// { -// p->die = -1; -// break; -// } - p->alpha -= frametime * 128; - if (p->alpha < 1) + if (Mod_PointInLeaf(p->org, cl.worldmodel)->contents != CONTENTS_EMPTY) + { p->die = -1; + break; + } p->vel[2] -= gravity * 0.5; break; - case pt_fallfadespark: - p->alpha -= frametime * 256; + case pt_spark: + p->alpha -= frametime * 512; p->vel[2] -= gravity; if (p->alpha < 1) p->die = -1; @@ -1092,12 +1164,10 @@ void R_MoveParticles (void) if (a != CONTENTS_WATER && a != CONTENTS_SLIME) { p->tex = smokeparticletexture[rand()&7]; - p->type = pt_splash; - p->alpha = 96; - p->scale = 5; + p->type = pt_splashpuff; + p->scale = 4; p->vel[0] = p->vel[1] = p->vel[2] = 0; - p->die = cl.time + 1000; -// p->die = -1; + break; } p->vel[2] += gravity * 0.25; p->vel[0] *= (1 - (frametime * 0.0625)); @@ -1110,37 +1180,34 @@ void R_MoveParticles (void) p->vel[1] += lhrandom(-32,32); p->vel[2] += lhrandom(-32,32); } - p->alpha -= frametime * 64; - if (p->alpha < 1) - p->die = -1; + p->alpha -= frametime * 256; if (p->alpha < 1) p->die = -1; break; -// LordHavoc: for smoke trails case pt_bulletsmoke: - p->scale += frametime * 60; - p->alpha -= frametime * 512; + p->scale += frametime * 16; + p->alpha -= frametime * 1024; p->vel[2] += gravity * 0.05; if (p->alpha < 1) p->die = -1; break; case pt_smoke: - p->scale += frametime * 20; - p->alpha -= frametime * 256; + p->scale += frametime * 32; + p->alpha -= frametime * 512; p->vel[2] += gravity * 0.05; if (p->alpha < 1) p->die = -1; break; - case pt_smokecloud: - p->scale += frametime * 64; - p->alpha -= frametime * 256; + case pt_steam: + p->scale += frametime * 48; + p->alpha -= frametime * 512; p->vel[2] += gravity * 0.05; if (p->alpha < 1) p->die = -1; break; - case pt_splash: - p->scale += frametime * 24; - p->alpha -= frametime * 512; + case pt_splashpuff: +// p->scale += frametime * 24; + p->alpha -= frametime * 1024; if (p->alpha < 1) p->die = -1; break; @@ -1158,36 +1225,30 @@ void R_MoveParticles (void) case CONTENTS_LAVA: case CONTENTS_SLIME: p->tex = smokeparticletexture[rand()&7]; - p->type = pt_smokecloud; - p->alpha = 96; - p->scale = 5; + p->type = pt_steam; + p->scale = 3; p->vel[2] = 96; break; case CONTENTS_WATER: p->tex = smokeparticletexture[rand()&7]; - p->type = pt_splash; - p->alpha = 96; - p->scale = 5; + p->type = pt_splashpuff; + p->scale = 4; break; default: // CONTENTS_SOLID and any others TraceLine(p->oldorg, p->org, v, normal); VectorCopy(v, p->org); p->tex = smokeparticletexture[rand()&7]; - p->type = pt_splash; - p->alpha = 96; - p->scale = 5; - particle(pt_fallfadespark, 245, particletexture, TPOLYTYPE_ADD, false, 1, 64, 1, 1.3, p->org[0], p->org[1], p->org[2] + 1, lhrandom(-32, 32), lhrandom(-32, 32), lhrandom(-32, 32) + 48); - particle(pt_fallfadespark, 245, particletexture, TPOLYTYPE_ADD, false, 1, 128, 1, 1.3, p->org[0], p->org[1], p->org[2] + 1, lhrandom(-32, 32), lhrandom(-32, 32), lhrandom(-32, 32) + 48); - particle(pt_fallfadespark, 245, particletexture, TPOLYTYPE_ADD, false, 1, 192, 1, 1.3, p->org[0], p->org[1], p->org[2] + 1, lhrandom(-32, 32), lhrandom(-32, 32), lhrandom(-32, 32) + 48); - particle(pt_fallfadespark, 245, particletexture, TPOLYTYPE_ADD, false, 1, 255, 1, 1.3, p->org[0], p->org[1], p->org[2] + 1, lhrandom(-32, 32), lhrandom(-32, 32), lhrandom(-32, 32) + 48); + p->type = pt_splashpuff; + p->scale = 4; break; } } break; case pt_flame: p->alpha -= frametime * 512; - p->vel[2] += gravity * 0.2; - if (p->alpha < 1) + p->vel[2] += gravity; +// p->scale -= frametime * 16; + if (p->alpha < 16) p->die = -1; break; /* @@ -1195,7 +1256,7 @@ void R_MoveParticles (void) if (cl.time >= p->time2) { p->time2 = cl.time + 0.01; - particle2(pt_flame, p->color, particletexture, TPOLYTYPE_ADD, false, 4, p->alpha, 999, 0, p->org, 0, 50); + particle(pt_flame, p->color, particletexture, TPOLYTYPE_ADD, false, 4, p->alpha, 9999, 0, org[0], org[1], org[2], lhrandom(-50, 50), lhrandom(-50, 50), lhrandom(-50, 50)); } p->alpha -= frametime * 512; p->vel[2] -= gravity * 0.5f; @@ -1208,7 +1269,7 @@ void R_MoveParticles (void) if (cl.time >= p->time2) { p->time2 = cl.time + 0.01; - particle2(pt_flame, 15, smokeparticletexture[rand()&7], TPOLYTYPE_ALPHA, false, 4, p->alpha, 999, 0, p->org, 0, 50); + particle2(pt_flame, 15, smokeparticletexture[rand()&7], TPOLYTYPE_ALPHA, false, 4, p->alpha, 9999, 0, org[0], org[1], org[2], lhrandom(-50, 50), lhrandom(-50, 50), lhrandom(-50, 50)); } p->alpha -= frametime * 512; p->vel[2] -= gravity * 0.5f; @@ -1224,11 +1285,7 @@ void R_MoveParticles (void) p->die = -1; break; */ - case pt_glow: - if (p->time2) - p->die = -1; - p->time2 = 1; - break; + /* case pt_decal: if (cl.time > p->time2) { @@ -1239,6 +1296,12 @@ void R_MoveParticles (void) if (p->alpha < 64) p->die = -1; break; + */ + case pt_oneframe: + if (p->time2) + p->die = -1; + p->time2 = 1; + break; default: printf("unknown particle type %i\n", p->type); p->die = -1; @@ -1268,23 +1331,21 @@ void R_MoveParticles (void) void R_DrawParticles (void) { particle_t *p; - int i, r,g,b,a, dynlight; + int i, dynamiclight, staticlight, r, g, b; + byte br, bg, bb, ba; float scale, scale2, minparticledist; byte *color24; - vec3_t up, right, uprightangles, up2, right2, tempcolor, corner, decalright, decalup, v; + vec3_t uprightangles, up2, right2, tempcolor, corner; // LordHavoc: early out condition if ((!numparticles) || (!r_drawparticles.value)) return; - dynlight = r_dynamicparticles.value; + staticlight = dynamiclight = r_particles_lighting.value; if (!r_dynamic.value) - dynlight = 0; + dynamiclight = 0; c_particles += numparticles; - VectorScale (vup, 1.5, up); - VectorScale (vright, 1.5, right); - uprightangles[0] = 0; uprightangles[1] = r_refdef.viewangles[1]; uprightangles[2] = 0; @@ -1298,61 +1359,66 @@ void R_DrawParticles (void) // if (p->die < cl.time) // continue; + // LordHavoc: only render if not too close + if (DotProduct(p->org, vpn) < minparticledist) + continue; + + /* if (p->type == pt_decal) { VectorSubtract(p->org, r_refdef.vieworg, v); if (DotProduct(p->direction, v) < 0) continue; } - - // LordHavoc: only render if not too close - if (DotProduct(p->org, vpn) < minparticledist) - continue; + */ color24 = (byte *) &d_8to24table[(int)p->color]; r = color24[0]; g = color24[1]; b = color24[2]; - a = p->alpha; - if (dynlight && (p->dynlight || dynlight >= 2)) // LordHavoc: only light blood and smoke + if (staticlight && (p->dynlight || staticlight >= 2)) // LordHavoc: only light blood and smoke { - R_CompleteLightPoint(tempcolor, p->org); + R_CompleteLightPoint(tempcolor, p->org, dynamiclight); r = (r * (int) tempcolor[0]) >> 7; g = (g * (int) tempcolor[1]) >> 7; b = (b * (int) tempcolor[2]) >> 7; } + br = (byte) min(r, 255); + bg = (byte) min(g, 255); + bb = (byte) min(b, 255); + ba = (byte) p->alpha; transpolybegin(R_GetTexture(p->tex), 0, R_GetTexture(p->tex), p->rendermode); scale = p->scale * -0.5;scale2 = p->scale; + /* if (p->type == pt_decal) { - VectorVectors(p->direction, decalright, decalup); - corner[0] = p->org[0] + decalup[0]*scale + decalright[0]*scale; - corner[1] = p->org[1] + decalup[1]*scale + decalright[1]*scale; - corner[2] = p->org[2] + decalup[2]*scale + decalright[2]*scale; - transpolyvert(corner[0] , corner[1] , corner[2] , 0,1,r,g,b,a); - transpolyvert(corner[0] + decalup[0]*scale2 , corner[1] + decalup[1]*scale2 , corner[2] + decalup[2]*scale2 , 0,0,r,g,b,a); - transpolyvert(corner[0] + decalup[0]*scale2 + decalright[0]*scale2, corner[1] + decalup[1]*scale2 + decalright[1]*scale2, corner[2] + decalup[2]*scale2 + decalright[2]*scale2, 1,0,r,g,b,a); - transpolyvert(corner[0] + decalright[0]*scale2, corner[1] + decalright[1]*scale2, corner[2] + decalright[2]*scale2, 1,1,r,g,b,a); + corner[0] = p->org[0] + p->decalup[0]*scale + p->decalright[0]*scale; + corner[1] = p->org[1] + p->decalup[1]*scale + p->decalright[1]*scale; + corner[2] = p->org[2] + p->decalup[2]*scale + p->decalright[2]*scale; + transpolyvertub(corner[0] , corner[1] , corner[2] , 0,1,br,bg,bb,ba); + transpolyvertub(corner[0] + p->decalup[0]*scale2 , corner[1] + p->decalup[1]*scale2 , corner[2] + p->decalup[2]*scale2 , 0,0,br,bg,bb,ba); + transpolyvertub(corner[0] + p->decalup[0]*scale2 + p->decalright[0]*scale2, corner[1] + p->decalup[1]*scale2 + p->decalright[1]*scale2, corner[2] + p->decalup[2]*scale2 + p->decalright[2]*scale2, 1,0,br,bg,bb,ba); + transpolyvertub(corner[0] + p->decalright[0]*scale2, corner[1] + p->decalright[1]*scale2, corner[2] + p->decalright[2]*scale2, 1,1,br,bg,bb,ba); } - else if (p->tex == rainparticletexture) // rain streak + else*/ if (p->tex == rainparticletexture) // rain streak { corner[0] = p->org[0] + up2[0]*scale + right2[0]*scale; corner[1] = p->org[1] + up2[1]*scale + right2[1]*scale; corner[2] = p->org[2] + up2[2]*scale + right2[2]*scale; - transpolyvert(corner[0] , corner[1] , corner[2] , 0,1,r,g,b,a); - transpolyvert(corner[0] + up2[0]*scale2 , corner[1] + up2[1]*scale2 , corner[2] + up2[2]*scale2 , 0,0,r,g,b,a); - transpolyvert(corner[0] + up2[0]*scale2 + right2[0]*scale2, corner[1] + up2[1]*scale2 + right2[1]*scale2, corner[2] + up2[2]*scale2 + right2[2]*scale2, 1,0,r,g,b,a); - transpolyvert(corner[0] + right2[0]*scale2, corner[1] + right2[1]*scale2, corner[2] + right2[2]*scale2, 1,1,r,g,b,a); + transpolyvertub(corner[0] , corner[1] , corner[2] , 0,1,br,bg,bb,ba); + transpolyvertub(corner[0] + up2[0]*scale2 , corner[1] + up2[1]*scale2 , corner[2] + up2[2]*scale2 , 0,0,br,bg,bb,ba); + transpolyvertub(corner[0] + up2[0]*scale2 + right2[0]*scale2, corner[1] + up2[1]*scale2 + right2[1]*scale2, corner[2] + up2[2]*scale2 + right2[2]*scale2, 1,0,br,bg,bb,ba); + transpolyvertub(corner[0] + right2[0]*scale2, corner[1] + right2[1]*scale2, corner[2] + right2[2]*scale2, 1,1,br,bg,bb,ba); } else { - corner[0] = p->org[0] + up[0]*scale + right[0]*scale; - corner[1] = p->org[1] + up[1]*scale + right[1]*scale; - corner[2] = p->org[2] + up[2]*scale + right[2]*scale; - transpolyvert(corner[0] , corner[1] , corner[2] , 0,1,r,g,b,a); - transpolyvert(corner[0] + up[0]*scale2 , corner[1] + up[1]*scale2 , corner[2] + up[2]*scale2 , 0,0,r,g,b,a); - transpolyvert(corner[0] + up[0]*scale2 + right[0]*scale2, corner[1] + up[1]*scale2 + right[1]*scale2, corner[2] + up[2]*scale2 + right[2]*scale2, 1,0,r,g,b,a); - transpolyvert(corner[0] + right[0]*scale2, corner[1] + right[1]*scale2, corner[2] + right[2]*scale2, 1,1,r,g,b,a); + corner[0] = p->org[0] + vup[0]*scale + vright[0]*scale; + corner[1] = p->org[1] + vup[1]*scale + vright[1]*scale; + corner[2] = p->org[2] + vup[2]*scale + vright[2]*scale; + transpolyvertub(corner[0] , corner[1] , corner[2] , 0,1,br,bg,bb,ba); + transpolyvertub(corner[0] + vup[0]*scale2 , corner[1] + vup[1]*scale2 , corner[2] + vup[2]*scale2 , 0,0,br,bg,bb,ba); + transpolyvertub(corner[0] + vup[0]*scale2 + vright[0]*scale2, corner[1] + vup[1]*scale2 + vright[1]*scale2, corner[2] + vup[2]*scale2 + vright[2]*scale2, 1,0,br,bg,bb,ba); + transpolyvertub(corner[0] + vright[0]*scale2, corner[1] + vright[1]*scale2, corner[2] + vright[2]*scale2, 1,1,br,bg,bb,ba); } transpolyend(); } diff --git a/r_sprites.c b/r_sprites.c index 13db9a00..db8e90e9 100644 --- a/r_sprites.c +++ b/r_sprites.c @@ -56,7 +56,7 @@ void R_DrawSpriteModel (entity_t *e, frameblend_t *blend) color[2] = e->colormod[2] * 255; } else - R_CompleteLightPoint(color, e->origin); + R_CompleteLightPoint(color, e->origin, true); colorub[0] = bound(0, color[0], 255); colorub[1] = bound(0, color[1], 255); diff --git a/render.h b/render.h index 5cf362e6..e69a5bdd 100644 --- a/render.h +++ b/render.h @@ -147,6 +147,7 @@ void R_RemoveEfrags (entity_t *ent); void R_NewMap (void); +#include "r_decals.h" void R_ParseParticleEffect (void); void R_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count); diff --git a/snd_win.c b/snd_win.c index 1a725ebb..1fb72b99 100644 --- a/snd_win.c +++ b/snd_win.c @@ -207,11 +207,9 @@ sndinitstat SNDDMA_InitDirect (void) format.nChannels = shm->channels; format.wBitsPerSample = shm->samplebits; format.nSamplesPerSec = shm->speed; - format.nBlockAlign = format.nChannels - *format.wBitsPerSample / 8; + format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8; format.cbSize = 0; - format.nAvgBytesPerSec = format.nSamplesPerSec - *format.nBlockAlign; + format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign; if (!hInstDS) { diff --git a/sys_linux.c b/sys_linux.c index da6ae1d7..cc2ef249 100644 --- a/sys_linux.c +++ b/sys_linux.c @@ -399,7 +399,6 @@ int main (int c, char **v) double time, oldtime, newtime; extern int vcrFile; extern int recording; - int j; // static char cwd[1024]; @@ -414,16 +413,6 @@ int main (int c, char **v) host_parms.memsize = DEFAULTMEM * 1024*1024; - j = COM_CheckParm("-mem"); - if (j) - host_parms.memsize = (int) (atof(com_argv[j+1]) * 1024 * 1024); - host_parms.membase = qmalloc(host_parms.memsize); - if (!host_parms.membase) - { - printf("Unable to allocate heap memory\n"); - return 1; - } - host_parms.basedir = basedir; // caching is disabled by default, use -cachedir to enable // host_parms.cachedir = cachedir; diff --git a/sys_win.c b/sys_win.c index 90b04ed8..8452c9ae 100644 --- a/sys_win.c +++ b/sys_win.c @@ -695,25 +695,6 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin if (host_parms.memsize > MAXIMUM_WIN_MEMORY) host_parms.memsize = MAXIMUM_WIN_MEMORY; */ - host_parms.memsize = DEFAULTMEM * 1048576; - - if ((t = COM_CheckParm("-heapsize"))) - { - t++; - if (t < com_argc) - host_parms.memsize = atoi (com_argv[t]) * 1024; - } - else if ((t = COM_CheckParm("-mem")) || (t = COM_CheckParm("-winmem"))) - { - t++; - if (t < com_argc) - host_parms.memsize = atoi (com_argv[t]) * 1048576; - } - - host_parms.membase = qmalloc(host_parms.memsize); - - if (!host_parms.membase) - Sys_Error ("Not enough memory free; check disk space\n"); // Sys_PageIn (parms.membase, parms.memsize);