[PATCH] Separate particle logic and rendering

Separate out the particle update code from the rendering code.

diff -urN -X exclude a/NQ/client.h head/NQ/client.h
--- a/NQ/client.h	2006-02-19 12:19:11.000000000 +1030
+++ head/NQ/client.h	2006-05-20 14:33:18.000000000 +0930
@@ -286,6 +286,7 @@
 const float dl_colors[4][4]; /* Use enums to reference the colors */
 
 void CL_DecayLights(void);
+void CL_RunParticles(void);
 
 void CL_Init(void);
 
diff -urN -X exclude a/NQ/host.c head/NQ/host.c
--- a/NQ/host.c	2005-12-28 13:18:27.000000000 +1030
+++ head/NQ/host.c	2006-05-20 14:31:10.000000000 +0930
@@ -728,6 +728,7 @@
 	time1 = Sys_DoubleTime();
 
     SCR_UpdateScreen();
+    CL_RunParticles();
 
     if (host_speeds.value)
 	time2 = Sys_DoubleTime();
diff -urN -X exclude a/NQ/r_part.c head/NQ/r_part.c
--- a/NQ/r_part.c	2006-05-13 20:10:38.000000000 +0930
+++ head/NQ/r_part.c	2006-05-20 14:25:12.000000000 +0930
@@ -579,50 +579,21 @@
     }
 }
 
-
 /*
 ===============
-R_DrawParticles
+CL_RunParticles
 ===============
 */
-
 void
-R_DrawParticles(void)
+CL_RunParticles(void)
 {
     particle_t *p, *kill;
     float grav;
-    int i;
-    float time2, time3;
-    float time1;
-    float dvel;
+    float time1, time2, time3;
     float frametime;
+    float dvel;
+    int i;
 
-#ifdef GLQUAKE
-    vec3_t up, right;
-    float scale;
-
-    /*
-     * FIXME - shouldn't need to do this, just get the caller to make sure
-     *         multitexture is not enabled.
-     */
-    GL_DisableMultitexture();
-
-    GL_Bind(particletexture);
-    glEnable(GL_BLEND);
-    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-    glDepthMask(GL_FALSE);
-
-    glBegin(GL_TRIANGLES);
-
-    VectorScale(vup, 1.5, up);
-    VectorScale(vright, 1.5, right);
-#else
-    D_StartParticles();
-
-    VectorScale(vright, xscaleshrink, r_pright);
-    VectorScale(vup, yscaleshrink, r_pup);
-    VectorCopy(vpn, r_ppn);
-#endif
     frametime = cl.time - cl.oldtime;
     time3 = frametime * 15;
     time2 = frametime * 10;	// 15;
@@ -653,29 +624,6 @@
 	    break;
 	}
 
-#ifdef GLQUAKE
-	// hack a scale up to keep particles from disapearing
-	scale =
-	    (p->org[0] - r_origin[0]) * vpn[0] + (p->org[1] -
-						  r_origin[1]) * vpn[1]
-	    + (p->org[2] - r_origin[2]) * vpn[2];
-	if (scale < 20)
-	    scale = 1;
-	else
-	    scale = 1 + scale * 0.004;
-	glColor3ubv((byte *)&d_8to24table[(int)p->color]);
-	glTexCoord2f(0, 0);
-	glVertex3fv(p->org);
-	glTexCoord2f(1, 0);
-	glVertex3f(p->org[0] + up[0] * scale, p->org[1] + up[1] * scale,
-		   p->org[2] + up[2] * scale);
-	glTexCoord2f(0, 1);
-	glVertex3f(p->org[0] + right[0] * scale,
-		   p->org[1] + right[1] * scale,
-		   p->org[2] + right[2] * scale);
-#else
-	D_DrawParticle(p);
-#endif
 	p->org[0] += p->vel[0] * frametime;
 	p->org[1] += p->vel[1] * frametime;
 	p->org[2] += p->vel[2] * frametime;
@@ -733,6 +681,72 @@
 	    break;
 	}
     }
+}
+
+/*
+===============
+R_DrawParticles
+===============
+*/
+
+void
+R_DrawParticles(void)
+{
+    particle_t *p;
+
+#ifdef GLQUAKE
+    vec3_t up, right;
+    float scale;
+
+    /*
+     * FIXME - shouldn't need to do this, just get the caller to make sure
+     *         multitexture is not enabled.
+     */
+    GL_DisableMultitexture();
+
+    GL_Bind(particletexture);
+    glEnable(GL_BLEND);
+    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+    glDepthMask(GL_FALSE);
+
+    glBegin(GL_TRIANGLES);
+
+    VectorScale(vup, 1.5, up);
+    VectorScale(vright, 1.5, right);
+#else
+    D_StartParticles();
+
+    VectorScale(vright, xscaleshrink, r_pright);
+    VectorScale(vup, yscaleshrink, r_pup);
+    VectorCopy(vpn, r_ppn);
+#endif
+
+    for (p = active_particles; p; p = p->next) {
+
+#ifdef GLQUAKE
+	// hack a scale up to keep particles from disapearing
+	scale =
+	    (p->org[0] - r_origin[0]) * vpn[0] + (p->org[1] -
+						  r_origin[1]) * vpn[1]
+	    + (p->org[2] - r_origin[2]) * vpn[2];
+	if (scale < 20)
+	    scale = 1;
+	else
+	    scale = 1 + scale * 0.004;
+	glColor3ubv((byte *)&d_8to24table[(int)p->color]);
+	glTexCoord2f(0, 0);
+	glVertex3fv(p->org);
+	glTexCoord2f(1, 0);
+	glVertex3f(p->org[0] + up[0] * scale, p->org[1] + up[1] * scale,
+		   p->org[2] + up[2] * scale);
+	glTexCoord2f(0, 1);
+	glVertex3f(p->org[0] + right[0] * scale,
+		   p->org[1] + right[1] * scale,
+		   p->org[2] + right[2] * scale);
+#else
+	D_DrawParticle(p);
+#endif
+    }
 
 #ifdef GLQUAKE
     glEnd();
diff -urN -X exclude a/QW/client/cl_main.c head/QW/client/cl_main.c
--- a/QW/client/cl_main.c	2006-03-12 06:15:47.000000000 +1030
+++ head/QW/client/cl_main.c	2006-05-20 14:41:55.000000000 +0930
@@ -1393,6 +1393,7 @@
 	time1 = Sys_DoubleTime();
 
     SCR_UpdateScreen();
+    CL_RunParticles();
 
     if (host_speeds.value)
 	time2 = Sys_DoubleTime();
diff -urN -X exclude a/QW/client/client.h head/QW/client/client.h
--- a/QW/client/client.h	2006-02-19 12:19:11.000000000 +1030
+++ head/QW/client/client.h	2006-05-20 14:42:51.000000000 +0930
@@ -366,6 +366,7 @@
 const float dl_colors[4][4]; /* Use enums to reference the colors */
 
 void CL_DecayLights(void);
+void CL_RunParticles(void);
 
 void CL_Init(void);
 void Host_WriteConfiguration(void);
diff -urN -X exclude a/QW/client/r_part.c head/QW/client/r_part.c
--- a/QW/client/r_part.c	2006-05-13 20:10:38.000000000 +0930
+++ head/QW/client/r_part.c	2006-05-20 14:50:37.000000000 +0930
@@ -419,50 +419,20 @@
     }
 }
 
-
 /*
 ===============
-R_DrawParticles
+CL_RunParticles
 ===============
 */
 void
-R_DrawParticles(void)
+CL_RunParticles(void)
 {
     particle_t *p, *kill;
     float grav;
-    int i;
-    float time2, time3;
-    float time1;
-    float dvel;
+    float time1, time2, time3;
     float frametime;
-
-#ifdef GLQUAKE
-    unsigned char *at;
-    unsigned char theAlpha;
-    vec3_t up, right;
-    float scale;
-    qboolean alphaTestEnabled;
-
-    GL_Bind(particletexture);
-    alphaTestEnabled = glIsEnabled(GL_ALPHA_TEST);
-
-    if (alphaTestEnabled)
-	glDisable(GL_ALPHA_TEST);
-    glEnable(GL_BLEND);
-    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-    glDepthMask(GL_FALSE);
-
-    glBegin(GL_TRIANGLES);
-
-    VectorScale(vup, 1.5, up);
-    VectorScale(vright, 1.5, right);
-#else
-    D_StartParticles();
-
-    VectorScale(vright, xscaleshrink, r_pright);
-    VectorScale(vup, yscaleshrink, r_pup);
-    VectorCopy(vpn, r_ppn);
-#endif
+    float dvel;
+    int i;
 
     frametime = host_frametime;
     time3 = frametime * 15;
@@ -494,41 +464,6 @@
 	    break;
 	}
 
-#ifdef GLQUAKE
-	// hack a scale up to keep particles from disapearing
-	scale =
-	    (p->org[0] - r_origin[0]) * vpn[0] + (p->org[1] -
-						  r_origin[1]) * vpn[1]
-	    + (p->org[2] - r_origin[2]) * vpn[2];
-	if (scale < 20)
-	    scale = 1;
-	else
-	    scale = 1 + scale * 0.004;
-	at = (byte *)&d_8to24table[(int)p->color];
-	if (p->type == pt_fire)
-	    theAlpha = 255 * (6 - p->ramp) / 6;
-//                      theAlpha = 192;
-//              else if (p->type==pt_explode || p->type==pt_explode2)
-//                      theAlpha = 255*(8-p->ramp)/8;
-	else
-	    theAlpha = 255;
-	glColor4ub(*at, *(at + 1), *(at + 2), theAlpha);
-//              glColor3ubv (at);
-//              glColor3ubv ((byte *)&d_8to24table[(int)p->color]);
-	glTexCoord2f(0, 0);
-	glVertex3fv(p->org);
-	glTexCoord2f(1, 0);
-	glVertex3f(p->org[0] + up[0] * scale, p->org[1] + up[1] * scale,
-		   p->org[2] + up[2] * scale);
-	glTexCoord2f(0, 1);
-	glVertex3f(p->org[0] + right[0] * scale,
-		   p->org[1] + right[1] * scale,
-		   p->org[2] + right[2] * scale);
-
-#else
-	D_DrawParticle(p);
-#endif
-
 	p->org[0] += p->vel[0] * frametime;
 	p->org[1] += p->vel[1] * frametime;
 	p->org[2] += p->vel[2] * frametime;
@@ -585,6 +520,84 @@
 	    break;
 	}
     }
+}
+
+/*
+===============
+R_DrawParticles
+===============
+*/
+void
+R_DrawParticles(void)
+{
+    particle_t *p;
+
+#ifdef GLQUAKE
+    unsigned char *at;
+    unsigned char theAlpha;
+    vec3_t up, right;
+    float scale;
+    qboolean alphaTestEnabled;
+
+    GL_Bind(particletexture);
+    alphaTestEnabled = glIsEnabled(GL_ALPHA_TEST);
+
+    if (alphaTestEnabled)
+	glDisable(GL_ALPHA_TEST);
+    glEnable(GL_BLEND);
+    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+    glDepthMask(GL_FALSE);
+
+    glBegin(GL_TRIANGLES);
+
+    VectorScale(vup, 1.5, up);
+    VectorScale(vright, 1.5, right);
+#else
+    D_StartParticles();
+
+    VectorScale(vright, xscaleshrink, r_pright);
+    VectorScale(vup, yscaleshrink, r_pup);
+    VectorCopy(vpn, r_ppn);
+#endif
+
+    for (p = active_particles; p; p = p->next) {
+
+#ifdef GLQUAKE
+	// hack a scale up to keep particles from disapearing
+	scale =
+	    (p->org[0] - r_origin[0]) * vpn[0] + (p->org[1] -
+						  r_origin[1]) * vpn[1]
+	    + (p->org[2] - r_origin[2]) * vpn[2];
+	if (scale < 20)
+	    scale = 1;
+	else
+	    scale = 1 + scale * 0.004;
+	at = (byte *)&d_8to24table[(int)p->color];
+	if (p->type == pt_fire)
+	    theAlpha = 255 * (6 - p->ramp) / 6;
+//                      theAlpha = 192;
+//              else if (p->type==pt_explode || p->type==pt_explode2)
+//                      theAlpha = 255*(8-p->ramp)/8;
+	else
+	    theAlpha = 255;
+	glColor4ub(*at, *(at + 1), *(at + 2), theAlpha);
+//              glColor3ubv (at);
+//              glColor3ubv ((byte *)&d_8to24table[(int)p->color]);
+	glTexCoord2f(0, 0);
+	glVertex3fv(p->org);
+	glTexCoord2f(1, 0);
+	glVertex3f(p->org[0] + up[0] * scale, p->org[1] + up[1] * scale,
+		   p->org[2] + up[2] * scale);
+	glTexCoord2f(0, 1);
+	glVertex3f(p->org[0] + right[0] * scale,
+		   p->org[1] + right[1] * scale,
+		   p->org[2] + right[2] * scale);
+
+#else
+	D_DrawParticle(p);
+#endif
+
+    }
 
 #ifdef GLQUAKE
     glEnd();
