X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=cl_particles.c;h=e33bba65f3461ce52f5758c252c03a705ea1e533;hb=1e60f704831678c9e7d27de1fbedb5adedb69e38;hp=2e0d968488fc3cf03faf8a9b017e0243ce00abf7;hpb=818efa72622675162e7760da0c8423f215031abb;p=xonotic%2Fdarkplaces.git diff --git a/cl_particles.c b/cl_particles.c index 2e0d9684..e33bba65 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -40,7 +40,6 @@ void R_Stain (vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, i #define CL_BlobExplosion R_BlobExplosion #define CL_RunParticleEffect R_RunParticleEffect #define CL_LavaSplash R_LavaSplash -#define CL_RocketTrail2 R_RocketTrail2 void R_CalcBeam_Vertex3f (float *vert, vec3_t org1, vec3_t org2, float width) { vec3_t right1, right2, diff, normal; @@ -294,6 +293,10 @@ cvar_t cl_particles_blood = {CVAR_SAVE, "cl_particles_blood", "1"}; cvar_t cl_particles_blood_alpha = {CVAR_SAVE, "cl_particles_blood_alpha", "0.5"}; cvar_t cl_particles_blood_bloodhack = {CVAR_SAVE, "cl_particles_blood_bloodhack", "1"}; cvar_t cl_particles_bulletimpacts = {CVAR_SAVE, "cl_particles_bulletimpacts", "1"}; +cvar_t cl_particles_explosions_bubbles = {CVAR_SAVE, "cl_particles_explosions_bubbles", "1"}; +cvar_t cl_particles_explosions_smoke = {CVAR_SAVE, "cl_particles_explosions_smokes", "0"}; +cvar_t cl_particles_explosions_sparks = {CVAR_SAVE, "cl_particles_explosions_sparks", "1"}; +cvar_t cl_particles_explosions_shell = {CVAR_SAVE, "cl_particles_explosions_shell", "0"}; cvar_t cl_particles_smoke = {CVAR_SAVE, "cl_particles_smoke", "1"}; cvar_t cl_particles_smoke_alpha = {CVAR_SAVE, "cl_particles_smoke_alpha", "0.5"}; cvar_t cl_particles_smoke_alphafade = {CVAR_SAVE, "cl_particles_smoke_alphafade", "0.55"}; @@ -311,6 +314,7 @@ void CL_Particles_Clear(void) { cl_numparticles = 0; cl_freeparticle = 0; + memset(particles, 0, sizeof(particle_t) * cl_maxparticles); } /* @@ -323,6 +327,7 @@ void CL_Particles_Init (void) { int i; +// COMMANDLINEOPTION: Client: -particles changes maximum number of particles at once, default 32768 i = COM_CheckParm ("-particles"); if (i && i < com_argc - 1) @@ -343,6 +348,10 @@ void CL_Particles_Init (void) Cvar_RegisterVariable (&cl_particles_blood); Cvar_RegisterVariable (&cl_particles_blood_alpha); Cvar_RegisterVariable (&cl_particles_blood_bloodhack); + Cvar_RegisterVariable (&cl_particles_explosions_bubbles); + Cvar_RegisterVariable (&cl_particles_explosions_smoke); + Cvar_RegisterVariable (&cl_particles_explosions_sparks); + Cvar_RegisterVariable (&cl_particles_explosions_shell); Cvar_RegisterVariable (&cl_particles_bulletimpacts); Cvar_RegisterVariable (&cl_particles_smoke); Cvar_RegisterVariable (&cl_particles_smoke_alpha); @@ -359,8 +368,7 @@ void CL_Particles_Init (void) cl_part_mempool = Mem_AllocPool("CL_Part", 0, NULL); particles = (particle_t *) Mem_Alloc(cl_part_mempool, cl_maxparticles * sizeof(particle_t)); #endif - cl_numparticles = 0; - cl_freeparticle = 0; + CL_Particles_Clear(); } // list of all 26 parameters: @@ -605,7 +613,7 @@ void CL_ParseParticleEffect (void) vec3_t org, dir; int i, count, msgcount, color; - MSG_ReadVector(org); + MSG_ReadVector(org, cl.protocol); for (i=0 ; i<3 ; i++) dir[i] = MSG_ReadChar () * (1.0/16); msgcount = MSG_ReadByte (); @@ -650,66 +658,59 @@ void CL_ParticleExplosion (vec3_t org) CL_SpawnDecalParticleForPoint(org, 40, 48, 255, tex_bulletdecal[rand()&7], 0xFFFFFF, 0xFFFFFF); i = CL_PointQ1Contents(org); - if ((i == CONTENTS_SLIME || i == CONTENTS_WATER) && cl_particles.integer && cl_particles_bubbles.integer) + if (i == CONTENTS_SLIME || i == CONTENTS_WATER) { - for (i = 0;i < 128 * cl_particles_quality.value;i++) - particle(pt_bubble, PARTICLE_BILLBOARD, 0x404040, 0x808080, tex_bubble, false, PBLEND_ADD, 2, 2, (1.0f / cl_particles_quality.value) * lhrandom(128, 255), (1.0f / cl_particles_quality.value) * 256, 9999, -0.25, 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), 0, 0, 0, 0, (1.0 / 16.0), 0); + if (cl_particles.integer && cl_particles_bubbles.integer && cl_particles_explosions_bubbles.integer) + for (i = 0;i < 128 * cl_particles_quality.value;i++) + particle(pt_bubble, PARTICLE_BILLBOARD, 0x404040, 0x808080, tex_bubble, false, PBLEND_ADD, 2, 2, (1.0f / cl_particles_quality.value) * lhrandom(128, 255), (1.0f / cl_particles_quality.value) * 256, 9999, -0.25, 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), 0, 0, 0, 0, (1.0 / 16.0), 0); } else { - /* // LordHavoc: smoke effect similar to UT2003, chews fillrate too badly up close // smoke puff - if (cl_particles.integer && cl_particles_smoke.integer) + if (cl_particles.integer && cl_particles_smoke.integer && cl_particles_explosions_smoke.integer) { - for (i = 0;i < 64;i++) + for (i = 0;i < 32;i++) { + int k; + vec3_t v, v2; #ifdef WORKINGLQUAKE - v2[0] = lhrandom(-64, 64); - v2[1] = lhrandom(-64, 64); - v2[2] = lhrandom(-8, 24); + v2[0] = lhrandom(-48, 48); + v2[1] = lhrandom(-48, 48); + v2[2] = lhrandom(-48, 48); #else for (k = 0;k < 16;k++) { - v[0] = org[0] + lhrandom(-64, 64); - v[1] = org[1] + lhrandom(-64, 64); - v[2] = org[2] + lhrandom(-8, 24); + v[0] = org[0] + lhrandom(-48, 48); + v[1] = org[1] + lhrandom(-48, 48); + v[2] = org[2] + lhrandom(-48, 48); if (CL_TraceLine(org, v, v2, NULL, true, NULL, SUPERCONTENTS_SOLID) >= 0.1) break; } VectorSubtract(v2, org, v2); #endif VectorScale(v2, 2.0f, v2); - particle(pt_static, PARTICLE_BILLBOARD, 0x101010, 0x202020, tex_smoke[rand()&7], true, PBLEND_ADD, 12, 12, 255, 512, 9999, 0, 0, org[0], org[1], org[2], v2[0], v2[1], v2[2], 0, 0, 0, 0, 0, 0); + particle(pt_static, PARTICLE_BILLBOARD, 0xFFFFFF, 0xFFFFFF, tex_smoke[rand()&7], true, PBLEND_ADD, 12, 12, 32, 64, 9999, 0, 0, org[0], org[1], org[2], v2[0], v2[1], v2[2], 0, 0, 0, 0, 0, 0); } } - */ #if 1 - if (cl_particles.integer && cl_particles_sparks.integer) + if (cl_particles.integer && cl_particles_sparks.integer && cl_particles_explosions_sparks.integer) for (i = 0;i < 128 * cl_particles_quality.value;i++) particle(pt_static, PARTICLE_SPARK, 0x903010, 0xFFD030, tex_particle, false, PBLEND_ADD, 1.0f, 0.02f, (1.0f / cl_particles_quality.value) * lhrandom(0, 255), (1.0f / cl_particles_quality.value) * 512, 9999, 1, 0, org[0], org[1], org[2], lhrandom(-256, 256), lhrandom(-256, 256), lhrandom(-256, 256) + 80, 0, 0, 0, 0, 0.2, 0); - } - - //if (cl_explosions.integer) - // R_NewExplosion(org); #elif 1 - if (cl_particles.integer && cl_particles_sparks.integer) + if (cl_particles.integer && cl_particles_sparks.integer && cl_particles_explosions_sparks.integer) for (i = 0;i < 64 * cl_particles_quality.value;i++) particle(pt_ember, PARTICLE_SPARK, 0x903010, 0xFFD030, tex_particle, false, PBLEND_ADD, 1.0f, 0.01f, (1.0f / cl_particles_quality.value) * lhrandom(0, 255), (1.0f / cl_particles_quality.value) * 256, 9999, 0.7, 0, org[0], org[1], org[2], lhrandom(-256, 256), lhrandom(-256, 256), lhrandom(-256, 256) + 80, cl.time, 0, 0, 0, 0, 0); - } - - //if (cl_explosions.integer) - // R_NewExplosion(org); #else - if (cl_particles.integer && cl_particles_sparks.integer) + if (cl_particles.integer && cl_particles_sparks.integer && cl_particles_explosions_sparks.integer) for (i = 0;i < 256 * cl_particles_quality.value;i++) particle(pt_static, PARTICLE_SPARK, 0x903010, 0xFFD030, tex_particle, false, PBLEND_ADD, 1.5f, 0.05f, (1.0f / cl_particles_quality.value) * lhrandom(0, 255), (1.0f / cl_particles_quality.value) * 512, 9999, 1, 0, org[0], org[1], org[2], lhrandom(-192, 192), lhrandom(-192, 192), lhrandom(-192, 192) + 160, 0, 0, 0, 0, 0.2, 0); +#endif } - if (cl_explosions.integer) + if (cl_particles_explosions_shell.integer) R_NewExplosion(org); -#endif } /* @@ -745,12 +746,7 @@ CL_BlobExplosion */ void CL_BlobExplosion (vec3_t org) { - if (cl_stainmaps.integer) - R_Stain(org, 96, 80, 80, 80, 64, 176, 176, 176, 64); - CL_SpawnDecalParticleForPoint(org, 40, 48, 255, tex_bulletdecal[rand()&7], 0xFFFFFF, 0xFFFFFF); - - if (cl_explosions.integer) - R_NewExplosion(org); + CL_ParticleExplosion(org); } /* @@ -1096,7 +1092,7 @@ void R_TeleportSplash (vec3_t org) #ifdef WORKINGLQUAKE void R_RocketTrail (vec3_t start, vec3_t end, int type) #else -void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) +void CL_RocketTrail (vec3_t start, vec3_t end, int type, int color, entity_t *ent) #endif { vec3_t vec, dir, vel, pos; @@ -1129,6 +1125,7 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) if (speed) speed = 1.0f / speed; VectorSubtract(ent->state_current.origin, ent->state_previous.origin, vel); + color = particlepalette[color]; #endif VectorScale(vel, speed, vel); @@ -1204,7 +1201,7 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) particle(pt_static, PARTICLE_BILLBOARD, 0x502030, 0x502030, tex_particle, false, PBLEND_ADD, 6, 6, qd*128, qd*384, 9999, 0, 0, pos[0], pos[1], pos[2], lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(-8, 8), 0, 0, 0, 0, 0, 0); } break; - +#ifndef WORKINGLQUAKE case 7: // Nehahra smoke tracer dec = qd*7; if (smoke) @@ -1215,6 +1212,12 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) if (smoke) particle(pt_static, PARTICLE_BILLBOARD, 0x283880, 0x283880, tex_particle, false, PBLEND_ADD, 4, 4, qd*255, qd*1024, 9999, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); break; + case 9: // glow trail + dec = qd*3; + if (smoke) + particle(pt_static, PARTICLE_BILLBOARD, color, color, tex_particle, false, PBLEND_ALPHA, 5, 5, qd*128, qd*320, 9999, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + break; +#endif } // advance to next time and position @@ -1226,30 +1229,6 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) #endif } -void CL_RocketTrail2 (vec3_t start, vec3_t end, int color, entity_t *ent) -{ - float dec, len; - vec3_t vec, pos; - if (!cl_particles.integer) return; - if (!cl_particles_smoke.integer) return; - - VectorCopy(start, pos); - VectorSubtract(end, start, vec); -#ifdef WORKINGLQUAKE - len = VectorNormalize(vec); -#else - len = VectorNormalizeLength(vec); -#endif - color = particlepalette[color]; - dec = 3.0f / cl_particles_quality.value; - while (len > 0) - { - particle(pt_static, PARTICLE_BILLBOARD, color, color, tex_particle, false, PBLEND_ALPHA, 5, 5, 128 / cl_particles_quality.value, 320 / cl_particles_quality.value, 9999, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); - len -= dec; - VectorMA(pos, dec, vec, pos); - } -} - void CL_BeamParticle (const vec3_t start, const vec3_t end, vec_t radius, float red, float green, float blue, float alpha, float lifetime) { int tempcolor2, cr, cg, cb; @@ -1372,8 +1351,8 @@ void CL_MoveParticles (void) p->bounce = 0; p->friction = 0; p->gravity = 0; - p->scalex *= 1.25f; - p->scaley *= 1.25f; + p->scalex *= 2.0f; + p->scaley *= 2.0f; } else { @@ -1520,6 +1499,9 @@ static particletexture_t particletexture[MAX_PARTICLETEXTURES]; static cvar_t r_drawparticles = {0, "r_drawparticles", "1"}; +#define PARTICLETEXTURESIZE 32 +#define PARTICLEFONTSIZE (PARTICLETEXTURESIZE*8) + static qbyte shadebubble(float dx, float dy, vec3_t light) { float dz, f, dot; @@ -1556,14 +1538,14 @@ static qbyte shadebubble(float dx, float dy, vec3_t light) static void setuptex(int texnum, qbyte *data, qbyte *particletexturedata) { int basex, basey, y; - basex = ((texnum >> 0) & 7) * 32; - basey = ((texnum >> 3) & 7) * 32; - particletexture[texnum].s1 = (basex + 1) / 256.0f; - particletexture[texnum].t1 = (basey + 1) / 256.0f; - particletexture[texnum].s2 = (basex + 31) / 256.0f; - particletexture[texnum].t2 = (basey + 31) / 256.0f; - for (y = 0;y < 32;y++) - memcpy(particletexturedata + ((basey + y) * 256 + basex) * 4, data + y * 32 * 4, 32 * 4); + basex = ((texnum >> 0) & 7) * PARTICLETEXTURESIZE; + basey = ((texnum >> 3) & 7) * PARTICLETEXTURESIZE; + particletexture[texnum].s1 = (basex + 1) / (float)PARTICLEFONTSIZE; + particletexture[texnum].t1 = (basey + 1) / (float)PARTICLEFONTSIZE; + particletexture[texnum].s2 = (basex + PARTICLETEXTURESIZE - 1) / (float)PARTICLEFONTSIZE; + particletexture[texnum].t2 = (basey + PARTICLETEXTURESIZE - 1) / (float)PARTICLEFONTSIZE; + for (y = 0;y < PARTICLETEXTURESIZE;y++) + memcpy(particletexturedata + ((basey + y) * PARTICLEFONTSIZE + basex) * 4, data + y * PARTICLETEXTURESIZE * 4, PARTICLETEXTURESIZE * 4); } void particletextureblotch(qbyte *data, float radius, float red, float green, float blue, float alpha) @@ -1571,20 +1553,20 @@ void particletextureblotch(qbyte *data, float radius, float red, float green, fl int x, y; float cx, cy, dx, dy, f, iradius; qbyte *d; - cx = lhrandom(radius + 1, 30 - radius); - cy = lhrandom(radius + 1, 30 - radius); + cx = (lhrandom(radius + 1, PARTICLETEXTURESIZE - 2 - radius) + lhrandom(radius + 1, PARTICLETEXTURESIZE - 2 - radius)) * 0.5f; + cy = (lhrandom(radius + 1, PARTICLETEXTURESIZE - 2 - radius) + lhrandom(radius + 1, PARTICLETEXTURESIZE - 2 - radius)) * 0.5f; iradius = 1.0f / radius; alpha *= (1.0f / 255.0f); - for (y = 0;y < 32;y++) + for (y = 0;y < PARTICLETEXTURESIZE;y++) { - for (x = 0;x < 32;x++) + for (x = 0;x < PARTICLETEXTURESIZE;x++) { dx = (x - cx); dy = (y - cy); f = (1.0f - sqrt(dx * dx + dy * dy) * iradius) * alpha; if (f > 0) { - d = data + (y * 32 + x) * 4; + d = data + (y * PARTICLETEXTURESIZE + x) * 4; d[0] += f * (red - d[0]); d[1] += f * (green - d[1]); d[2] += f * (blue - d[2]); @@ -1596,7 +1578,7 @@ void particletextureblotch(qbyte *data, float radius, float red, float green, fl void particletextureclamp(qbyte *data, int minr, int ming, int minb, int maxr, int maxg, int maxb) { int i; - for (i = 0;i < 32*32;i++, data += 4) + for (i = 0;i < PARTICLETEXTURESIZE*PARTICLETEXTURESIZE;i++, data += 4) { data[0] = bound(minr, data[0], maxr); data[1] = bound(ming, data[1], maxg); @@ -1607,7 +1589,7 @@ void particletextureclamp(qbyte *data, int minr, int ming, int minb, int maxr, i void particletextureinvert(qbyte *data) { int i; - for (i = 0;i < 32*32;i++, data += 4) + for (i = 0;i < PARTICLETEXTURESIZE*PARTICLETEXTURESIZE;i++, data += 4) { data[0] = 255 - data[0]; data[1] = 255 - data[1]; @@ -1619,9 +1601,9 @@ static void R_InitParticleTexture (void) { int x, y, d, i, j, k, m; float dx, dy, radius, f, f2; - qbyte data[32][32][4], noise1[64][64], noise2[64][64], data2[64][16][4]; + qbyte data[PARTICLETEXTURESIZE][PARTICLETEXTURESIZE][4], noise1[PARTICLETEXTURESIZE*2][PARTICLETEXTURESIZE*2], noise2[PARTICLETEXTURESIZE*2][PARTICLETEXTURESIZE*2], noise3[64][64], data2[64][16][4]; vec3_t light; - qbyte particletexturedata[256*256*4]; + qbyte *particletexturedata; // a note: decals need to modulate (multiply) the background color to // properly darken it (stain), and they need to be able to alpha fade, @@ -1632,7 +1614,8 @@ static void R_InitParticleTexture (void) // and white on black background) so we can alpha fade it to black, then // we invert it again during the blendfunc to make it work... - memset(particletexturedata, 255, sizeof(particletexturedata)); + particletexturedata = Mem_Alloc(tempmempool, PARTICLEFONTSIZE*PARTICLEFONTSIZE*4); + memset(particletexturedata, 255, PARTICLEFONTSIZE*PARTICLEFONTSIZE*4); // smoke for (i = 0;i < 8;i++) @@ -1640,18 +1623,18 @@ static void R_InitParticleTexture (void) memset(&data[0][0][0], 255, sizeof(data)); do { - fractalnoise(&noise1[0][0], 64, 4); - fractalnoise(&noise2[0][0], 64, 8); + fractalnoise(&noise1[0][0], PARTICLETEXTURESIZE*2, PARTICLETEXTURESIZE/8); + fractalnoise(&noise2[0][0], PARTICLETEXTURESIZE*2, PARTICLETEXTURESIZE/4); m = 0; - for (y = 0;y < 32;y++) + for (y = 0;y < PARTICLETEXTURESIZE;y++) { - dy = y - 16; - for (x = 0;x < 32;x++) + dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + for (x = 0;x < PARTICLETEXTURESIZE;x++) { - dx = x - 16; + dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); d = (noise2[y][x] - 128) * 3 + 192; if (d > 0) - d = d * (256 - (int) (dx*dx+dy*dy)) / 256; + d = d * (1-(dx*dx+dy*dy)); d = (d * noise1[y][x]) >> 7; d = bound(0, d, 255); data[y][x][3] = (qbyte) d; @@ -1668,15 +1651,15 @@ static void R_InitParticleTexture (void) for (i = 0;i < 16;i++) { memset(&data[0][0][0], 255, sizeof(data)); - radius = i * 3.0f / 16.0f; + radius = i * 3.0f / 4.0f / 16.0f; f2 = 255.0f * ((15.0f - i) / 15.0f); - for (y = 0;y < 32;y++) + for (y = 0;y < PARTICLETEXTURESIZE;y++) { - dy = (y - 16) * 0.25f; - for (x = 0;x < 32;x++) + dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + for (x = 0;x < PARTICLETEXTURESIZE;x++) { - dx = (x - 16) * 0.25f; - f = (1.0 - fabs(radius - sqrt(dx*dx+dy*dy))) * f2; + dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + f = f2 * (1.0 - 4.0f * fabs(radius - sqrt(dx*dx+dy*dy))); data[y][x][3] = (int) (bound(0.0f, f, 255.0f)); } } @@ -1685,13 +1668,13 @@ static void R_InitParticleTexture (void) // normal particle memset(&data[0][0][0], 255, sizeof(data)); - for (y = 0;y < 32;y++) + for (y = 0;y < PARTICLETEXTURESIZE;y++) { - dy = y - 16; - for (x = 0;x < 32;x++) + dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + for (x = 0;x < PARTICLETEXTURESIZE;x++) { - dx = x - 16; - d = (256 - (dx*dx+dy*dy)); + dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + d = 256 * (1 - (dx*dx+dy*dy)); d = bound(0, d, 255); data[y][x][3] = (qbyte) d; } @@ -1702,18 +1685,38 @@ static void R_InitParticleTexture (void) memset(&data[0][0][0], 255, sizeof(data)); light[0] = 1;light[1] = 1;light[2] = 1; VectorNormalize(light); - for (y = 0;y < 32;y++) - for (x = 0;x < 32;x++) - 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); + for (y = 0;y < PARTICLETEXTURESIZE;y++) + { + dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + // stretch upper half of bubble by +50% and shrink lower half by -50% + // (this gives an elongated teardrop shape) + if (dy > 0.5f) + dy = (dy - 0.5f) * 2.0f; + else + dy = (dy - 0.5f) / 1.5f; + for (x = 0;x < PARTICLETEXTURESIZE;x++) + { + dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + // shrink bubble width to half + dx *= 2.0f; + data[y][x][3] = shadebubble(dx, dy, light); + } + } setuptex(tex_raindrop, &data[0][0][0], particletexturedata); // bubble memset(&data[0][0][0], 255, sizeof(data)); light[0] = 1;light[1] = 1;light[2] = 1; VectorNormalize(light); - for (y = 0;y < 32;y++) - for (x = 0;x < 32;x++) - data[y][x][3] = shadebubble((x - 16) * (1.0 / 16.0), (y - 16) * (1.0 / 16.0), light); + for (y = 0;y < PARTICLETEXTURESIZE;y++) + { + dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + for (x = 0;x < PARTICLETEXTURESIZE;x++) + { + dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + data[y][x][3] = shadebubble(dx, dy, light); + } + } setuptex(tex_bubble, &data[0][0][0], particletexturedata); // blood particles @@ -1721,7 +1724,7 @@ static void R_InitParticleTexture (void) { memset(&data[0][0][0], 255, sizeof(data)); for (k = 0;k < 24;k++) - particletextureblotch(&data[0][0][0], 2, 96, 0, 0, 160); + particletextureblotch(&data[0][0][0], PARTICLETEXTURESIZE/16, 96, 0, 0, 160); //particletextureclamp(&data[0][0][0], 32, 32, 32, 255, 255, 255); particletextureinvert(&data[0][0][0]); setuptex(tex_bloodparticle[i], &data[0][0][0], particletexturedata); @@ -1731,11 +1734,10 @@ static void R_InitParticleTexture (void) for (i = 0;i < 8;i++) { memset(&data[0][0][0], 255, sizeof(data)); - for (k = 0;k < 24;k++) - particletextureblotch(&data[0][0][0], 2, 96, 0, 0, 96); - for (j = 3;j < 7;j++) - for (k = 0, m = rand() % 12;k < m;k++) - particletextureblotch(&data[0][0][0], j, 96, 0, 0, 192); + m = 8; + for (j = 1;j < 10;j++) + for (k = min(j, m - 1);k < m;k++) + particletextureblotch(&data[0][0][0], (float)j*PARTICLETEXTURESIZE/64.0f, 96, 0, 0, 192 - j * 8); //particletextureclamp(&data[0][0][0], 32, 32, 32, 255, 255, 255); particletextureinvert(&data[0][0][0]); setuptex(tex_blooddecal[i], &data[0][0][0], particletexturedata); @@ -1746,9 +1748,9 @@ static void R_InitParticleTexture (void) { memset(&data[0][0][0], 255, sizeof(data)); for (k = 0;k < 12;k++) - particletextureblotch(&data[0][0][0], 2, 0, 0, 0, 128); + particletextureblotch(&data[0][0][0], PARTICLETEXTURESIZE/16, 0, 0, 0, 128); for (k = 0;k < 3;k++) - particletextureblotch(&data[0][0][0], 14, 0, 0, 0, 160); + particletextureblotch(&data[0][0][0], PARTICLETEXTURESIZE/2, 0, 0, 0, 160); //particletextureclamp(&data[0][0][0], 64, 64, 64, 255, 255, 255); particletextureinvert(&data[0][0][0]); setuptex(tex_bulletdecal[i], &data[0][0][0], particletexturedata); @@ -1761,22 +1763,20 @@ static void R_InitParticleTexture (void) #else particlefonttexture = loadtextureimage(particletexturepool, "particles/particlefont.tga", 0, 0, false, TEXF_ALPHA | TEXF_PRECACHE); if (!particlefonttexture) - particlefonttexture = R_LoadTexture2D(particletexturepool, "particlefont", 256, 256, particletexturedata, TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL); + particlefonttexture = R_LoadTexture2D(particletexturepool, "particlefont", PARTICLEFONTSIZE, PARTICLEFONTSIZE, particletexturedata, TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL); for (i = 0;i < MAX_PARTICLETEXTURES;i++) particletexture[i].texture = particlefonttexture; // nexbeam - fractalnoise(&noise1[0][0], 64, 4); + fractalnoise(&noise3[0][0], 64, 4); m = 0; for (y = 0;y < 64;y++) { + dy = (y - 0.5f*64) / (64*0.5f+1); for (x = 0;x < 16;x++) { - if (x < 8) - d = x; - else - d = (15 - x); - d = d * d * noise1[y][x] / (7 * 7); + dx = (x - 0.5f*16) / (16*0.5f+1); + d = (1 - (dx*dx)) * noise3[y][x]; data2[y][x][0] = data2[y][x][1] = data2[y][x][2] = (qbyte) bound(0, d, 255); data2[y][x][3] = 255; } @@ -1790,6 +1790,7 @@ static void R_InitParticleTexture (void) particletexture[tex_beam].s2 = 1; particletexture[tex_beam].t2 = 1; #endif + Mem_Free(particletexturedata); } static void r_part_start(void)