{
}
+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)
===============
*/
-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 ; i<MAX_DLIGHTS ; i++, dl++)
- {
- if (dl->key == 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 ; i<MAX_DLIGHTS ; i++, dl++)
- {
- if (dl->die < 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;
}
dl = cl_dlights;
for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
{
- if (dl->die < cl.time || !dl->radius)
+ if (!dl->radius)
+ continue;
+ if (dl->die < cl.time)
+ {
+ dl->radius = 0;
continue;
+ }
c_dlights++; // count every dlight in use
vec3_t delta;
float bobjrotate;
vec3_t oldorg;
- dlight_t *dl;
- byte *tempcolor;
// determine partial update time
frac = CL_LerpPoint ();
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
}
// 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];
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)
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
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)
{
}
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);
if (cl_numvisedicts < MAX_VISEDICTS)
cl_visedicts[cl_numvisedicts++] = ent;
}
-
}
+// used by cl_shownet
+int netshown;
+
/*
===============
CL_ReadFromServer
cl.oldtime = cl.time;
cl.time += cl.frametime;
+ netshown = false;
do
{
ret = CL_GetMessage ();
CL_ParseServerMessage ();
} while (ret && cls.state == ca_connected);
- if (cl_shownet.value)
+ if (netshown)
Con_Printf ("\n");
CL_RelinkEntities ();
extern void SHOWLMP_decodehide();
extern void SHOWLMP_decodeshow();
extern void R_SetSkyBox(char* sky);
+extern int netshown;
/*
=====================
// 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
//
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 ();
// 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);
// 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
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
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;
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;
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;
*/
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;
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;
// 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:
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;
entity_t *ent;
float yaw, pitch;
float forward;
- dlight_t *dl;
num_temp_entities = 0;
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;
}
}
-
+
}
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
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
#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
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;
vec3_t punchangle; // temporary offset
vec3_t punchvector; // LordHavoc: origin view kick
-
+
// pitch drifting vars
float idealpitch;
float pitchvel;
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
// to decay light values and smooth step ups
double frametime;
-
+
float last_received_message; // (realtime) for net trouble icon
// frag scoreboard
scoreboard_t *scores; // [cl.maxclients]
-} client_state_t;
+}
+client_state_t;
//
//
// 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);
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
{
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;
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));
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
}
{
}
+void gl_draw_newmap()
+{
+}
+
char engineversion[40];
int engineversionx, engineversiony;
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);
}
/*
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;
=================
*/
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)
GL_LockArray(0, maliashdr->numverts);
}
- R_LightModel(maliashdr->numverts, org, color);
+ R_LightModel(ent, maliashdr->numverts, org, color);
if (!r_render.value)
return;
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;
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;
glDepthMask(1);
}
-extern int r_dlightframecount;
-
/*
=================
R_DrawAliasModel
for (i = 1;i < 256;i++)
transreciptable[i] = 1.0f / i;
}
+
void gl_poly_shutdown()
{
qfree(transvert);
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()
extern rtexture_t *solidskytexture, *alphaskytexture;
void skypolyrender()
{
- int i, j, numskyverts;
+ int i, j;
skypoly_t *p;
skyvert_t *vert;
float length, speedscale;
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);
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;
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();
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();
}
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();
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)
}
}
-void glmain_start()
+void gl_main_start()
{
}
-void glmain_shutdown()
+void gl_main_shutdown()
+{
+}
+
+void gl_main_newmap()
{
}
// 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();
void Render_Init()
{
- R_ShutdownModules();
+ R_Modules_Shutdown();
GL_Draw_Init();
GL_Main_Init();
GL_Models_Init();
R_Particles_Init();
R_Explosion_Init();
CL_Effects_Init();
- R_StartModules();
+ R_Decals_Init();
+ R_Modules_Start();
}
/*
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)\
{\
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;
if (r_speeds2.value)
{
starttime = currtime = Sys_FloatTime();
-// Con_Printf("render time: ");
}
else
starttime = currtime = 0;
TIMEREPORT(time_moveexplosions)
R_DrawExplosions();
TIMEREPORT(time_drawexplosions)
+ R_DrawDecals();
+ TIMEREPORT(time_drawdecals)
transpolyrender();
TIMEREPORT(time_transpoly)
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);
}
}
{
}
+void gl_misc_newmap()
+{
+}
+
/*
===============
R_Init
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);
cl.worldmodel->leafs[i].efrags = NULL;
r_viewleaf = NULL;
- R_ClearParticles ();
+ R_Modules_NewMap();
GL_BuildLightmaps ();
{
}
+void gl_screen_newmap()
+{
+}
+
/*
==================
SCR_Init
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);
}
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 ();
{
}
+void r_textures_newmap()
+{
+}
+
void R_Textures_Init (void)
{
Cmd_AddCommand("r_texturestats", GL_TextureStats_f);
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);
}
/*
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)
}
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
{
*/
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);
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);
}
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<outheight ; i++)
+ for (i = 0;i < outheight;i++)
{
- inrow = (byte *)indata + inwidth*(i*inheight/outheight)*4;
+ inrow = (int *)indata + inwidth*(i*inheight/outheight);
frac = fracstep >> 1;
- for (j=0 ; j<outwidth ; j+=4)
+ for (j = 0;j < outwidth;j += 4)
{
- 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;
- 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;
}
}
}
*/
void Host_Init ()
{
+ int i;
/*
if (standard_quake)
minimum_memory = MINIMUM_MEMORY;
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;
if (cls.state != ca_dedicated)
{
- R_ShutdownModules();
+ R_Modules_Shutdown();
VID_Shutdown();
}
}
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;
+}
-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);
#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
{
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);
{
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);
}
{
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);
}
#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)
{
}
+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)
--- /dev/null
+/*
+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();
+ }
+}
--- /dev/null
+
+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);
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)
{
{
}
+void r_explosion_newmap()
+{
+ memset(explosion, 0, sizeof(explosion));
+}
+
void R_Explosion_Init()
{
int i, x, y;
}
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)
void R_DrawExplosions()
{
int i;
+ if (!r_drawexplosions.value)
+ return;
for (i = 0;i < MAX_EXPLOSIONS;i++)
{
if (explosion[i].alpha > 0.0f)
{
}
+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;
for (i=0 ; i<MAX_DLIGHTS ; i++, l++)
{
- if (l->die < 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);
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;
}
}
-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);
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)
for (i=0 ; i<MAX_DLIGHTS ; i++)
{
- if (cl_dlights[i].die < cl.time || !cl_dlights[i].radius)
+ if (!cl_dlights[i].radius)
continue;
VectorSubtract (org, cl_dlights[i].origin, dist);
f = DotProduct(dist, dist) + LIGHTOFFSET;
extern float *aliasvertnorm;
extern byte *aliasvertcolor;
extern float modelalpha;
-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)
{
// LordHavoc: warning: reliance on int being 4 bytes here (of course the d_8to24table relies on that too...)
int i, j, nearlights = 0, color;
a = (byte) bound((int) 0, (int) (modelalpha * 255.0f), (int) 255);
if (lighthalf)
{
- mod[0] = currententity->colormod[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]);
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
{
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;
#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;
}
}
-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;
}
}
-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();
+ }
}
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();
// 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;
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;
rtexture_t *smokeparticletexture[8];
rtexture_t *rainparticletexture;
rtexture_t *bubbleparticletexture;
+rtexture_t *bulletholetexture[8];
particle_t *particles;
int r_numparticles;
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;
{
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;
}
}
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);
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()
qfree(freeparticles);
}
+void r_part_newmap()
+{
+ numparticles = 0;
+}
+
/*
===============
R_InitParticles
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)
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;\
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;\
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;\
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 ;i<r_numparticles ; i++)
-// particles[i].next = &particles[i+1];
-// particles[r_numparticles-1].next = NULL;
-
- numparticles = 0;
-}
-
-
void R_ReadPointFile_f (void)
{
FILE *f;
i = Mod_PointInLeaf(org, cl.worldmodel)->contents;
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);
// 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);
}
}
// 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));
}
*/
}
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));
}
/*
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));
}
/*
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)
{
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;
}
}
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;
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]);
}
}
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)
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));
}
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);
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));
}
}
}
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)
/*
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;
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
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;
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);
}
}
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;
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;
- }
}
}
}
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:
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)
{
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;
}
}
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;
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));
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;
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;
/*
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;
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;
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)
{
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;
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;
// 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();
}
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);
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);
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)
{
double time, oldtime, newtime;
extern int vcrFile;
extern int recording;
- int j;
// static char cwd[1024];
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;
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);