void CG_EffectParse(const char *effectstr) { // Split the string into it's component parts. float bmin, bmax, cmin, cmax, gmin, gmax, bdrop, gdrop, wsplash, lsplash; int count; char *startptr, *eqptr, *endptr, *type; char workbuff[128]; if (CG_AtmosphericKludge()) return; // Set up some default values cg_atmFx.baseVec[0] = cg_atmFx.baseVec[1] = 0; cg_atmFx.gustVec[0] = cg_atmFx.gustVec[1] = 100; bmin = 5; bmax = 10; cmin = 1; cmax = 1; gmin = 0; gmax = 2; bdrop = gdrop = 300; cg_atmFx.baseWeight = 0.7f; cg_atmFx.gustWeight = 1.5f; wsplash = 1; lsplash = 1; type = NULL; // Parse the parameter string Q_strncpyz(workbuff, effectstr, sizeof(workbuff)); for (startptr = workbuff; *startptr;) { for (eqptr = startptr; *eqptr && *eqptr != '=' && *eqptr != ','; eqptr++); if (!*eqptr) break; // No more string if (*eqptr == ',') { startptr = eqptr + 1; // Bad argument, continue continue; } *eqptr++ = 0; for (endptr = eqptr; *endptr && *endptr != ','; endptr++); if (*endptr) *endptr++ = 0; if (!type) { if (Q_stricmp(startptr, "T")) { cg_atmFx.numDrops = 0; CG_Printf("Atmospheric effect must start with a type.\n"); return; } if (!Q_stricmp(eqptr, "RAIN")) { type = "rain"; cg_atmFx.ParticleCheckVisible = &CG_RainParticleCheckVisible; cg_atmFx.ParticleGenerate = &CG_RainParticleGenerate; cg_atmFx.ParticleRender = &CG_RainParticleRender; cg_atmFx.baseVec[2] = cg_atmFx.gustVec[2] = -ATMOSPHERIC_RAIN_SPEED; } else if (!Q_stricmp(eqptr, "SNOW")) { type = "snow"; cg_atmFx.ParticleCheckVisible = &CG_RainParticleCheckVisible; cg_atmFx.ParticleGenerate = &CG_SnowParticleGenerate; cg_atmFx.ParticleRender = &CG_SnowParticleRender; cg_atmFx.baseVec[2] = cg_atmFx.gustVec[2] = -ATMOSPHERIC_SNOW_SPEED; } else { cg_atmFx.numDrops = 0; CG_Printf("Only effect type 'rain' and 'snow' are supported.\n"); return; } } else { if (!Q_stricmp(startptr, "B")) CG_EP_ParseFloats(eqptr, &bmin, &bmax); else if (!Q_stricmp(startptr, "C")) CG_EP_ParseFloats(eqptr, &cmin, &cmax); else if (!Q_stricmp(startptr, "G")) CG_EP_ParseFloats(eqptr, &gmin, &gmax); else if (!Q_stricmp(startptr, "BV")) CG_EP_ParseFloats(eqptr, &cg_atmFx.baseVec[0], &cg_atmFx.baseVec[1]); else if (!Q_stricmp(startptr, "GV")) CG_EP_ParseFloats(eqptr, &cg_atmFx.gustVec[0], &cg_atmFx.gustVec[1]); else if (!Q_stricmp(startptr, "W")) CG_EP_ParseFloats(eqptr, &cg_atmFx.baseWeight, &cg_atmFx.gustWeight); else if (!Q_stricmp(startptr, "S")) CG_EP_ParseFloats(eqptr, &wsplash, &lsplash); else if (!Q_stricmp(startptr, "D")) CG_EP_ParseFloats(eqptr, &bdrop, &gdrop); else CG_Printf("Unknown effect key '%s'.\n", startptr); } startptr = endptr; } if (!type) { // No effects cg_atmFx.numDrops = -1; return; } cg_atmFx.baseMinTime = 1000 * bmin; cg_atmFx.baseMaxTime = 1000 * bmax; cg_atmFx.changeMinTime = 1000 * cmin; cg_atmFx.changeMaxTime = 1000 * cmax; cg_atmFx.gustMinTime = 1000 * gmin; cg_atmFx.gustMaxTime = 1000 * gmax; cg_atmFx.baseDrops = bdrop; cg_atmFx.gustDrops = gdrop; cg_atmFx.waterSplash = wsplash; cg_atmFx.landSplash = lsplash; cg_atmFx.numDrops = (cg_atmFx.baseDrops > cg_atmFx.gustDrops) ? cg_atmFx.baseDrops : cg_atmFx.gustDrops; if (cg_atmFx.numDrops > MAX_ATMOSPHERIC_PARTICLES) cg_atmFx.numDrops = MAX_ATMOSPHERIC_PARTICLES; // Load graphics // Rain if (!Q_stricmp(type, "rain")) { cg_atmFx.numEffectShaders = 1; if (!(cg_atmFx.effectshaders[0] = trap_R_RegisterShader("gfx/atmosphere/raindrop"))) cg_atmFx.effectshaders[0] = -1; if (cg_atmFx.waterSplash) cg_atmFx.effectwatershader = trap_R_RegisterShader("gfx/atmosphere/raindropwater"); if (cg_atmFx.landSplash) cg_atmFx.effectlandshader = trap_R_RegisterShader("gfx/atmosphere/raindropsolid"); // Snow } else if (!Q_stricmp(type, "snow")) { for (cg_atmFx.numEffectShaders = 0; cg_atmFx.numEffectShaders < 6; cg_atmFx.numEffectShaders++) { if (! (cg_atmFx.effectshaders[cg_atmFx.numEffectShaders] = trap_R_RegisterShader(va("gfx/atmosphere/snowflake0%i", cg_atmFx.numEffectShaders)))) cg_atmFx.effectshaders[cg_atmFx.numEffectShaders] = -1; // we had some kind of a problem } cg_atmFx.waterSplash = 0; cg_atmFx.landSplash = 0; // This really should never happen } else cg_atmFx.numEffectShaders = 0; // Initialise atmospheric effect to prevent all particles falling at the start for (count = 0; count < cg_atmFx.numDrops; count++) cg_atmFx.particles[count].nextDropTime = ATMOSPHERIC_DROPDELAY + (rand() % ATMOSPHERIC_DROPDELAY); CG_EffectGust(); }
/** * @brief Parse effect * @details Split the string into it's component parts. */ void CG_EffectParse(const char *effectstr) { float bmin, bmax, cmin, cmax, gmin, gmax, bdrop, gdrop /*, wsplash, lsplash*/; int bheight; char *startptr, *eqptr, *endptr; char workbuff[128]; atmFXType_t atmFXType = ATM_NONE; if (CG_AtmosphericKludge()) { return; } // set up some default values cg_atmFx.baseVec[0] = cg_atmFx.baseVec[1] = 0; cg_atmFx.gustVec[0] = cg_atmFx.gustVec[1] = 100; bmin = 5; bmax = 10; cmin = 1; cmax = 1; gmin = 0; gmax = 2; bdrop = gdrop = 300; cg_atmFx.baseWeight = 0.7f; cg_atmFx.gustWeight = 1.5f; bheight = 0; // parse the parameter string Q_strncpyz(workbuff, effectstr, sizeof(workbuff)); for (startptr = workbuff; *startptr; ) { for (eqptr = startptr; *eqptr && *eqptr != '=' && *eqptr != ','; eqptr++) ; if (!*eqptr) { break; // No more string } if (*eqptr == ',') { startptr = eqptr + 1; // Bad argument, continue continue; } *eqptr++ = 0; for (endptr = eqptr; *endptr && *endptr != ','; endptr++) ; if (*endptr) { *endptr++ = 0; } if (atmFXType == ATM_NONE) { if (Q_stricmp(startptr, "T")) { cg_atmFx.numDrops = 0; CG_Printf("Atmospheric effect must start with a type.\n"); return; } if (!Q_stricmp(eqptr, "RAIN")) { atmFXType = ATM_RAIN; cg_atmFx.ParticleCheckVisible = &CG_RainParticleCheckVisible; cg_atmFx.ParticleGenerate = &CG_RainParticleGenerate; cg_atmFx.ParticleRender = &CG_RainParticleRender; cg_atmFx.baseVec[2] = cg_atmFx.gustVec[2] = -ATMOSPHERIC_RAIN_SPEED; } else if (!Q_stricmp(eqptr, "SNOW")) { atmFXType = ATM_SNOW; cg_atmFx.ParticleCheckVisible = &CG_SnowParticleCheckVisible; cg_atmFx.ParticleGenerate = &CG_SnowParticleGenerate; cg_atmFx.ParticleRender = &CG_SnowParticleRender; cg_atmFx.baseVec[2] = cg_atmFx.gustVec[2] = -ATMOSPHERIC_SNOW_SPEED; } else { cg_atmFx.numDrops = 0; CG_Printf("Only effect type 'rain' and 'snow' are supported.\n"); return; } } else { if (!Q_stricmp(startptr, "B")) { CG_EP_ParseFloats(eqptr, &bmin, &bmax); } else if (!Q_stricmp(startptr, "C")) { CG_EP_ParseFloats(eqptr, &cmin, &cmax); } else if (!Q_stricmp(startptr, "G")) { CG_EP_ParseFloats(eqptr, &gmin, &gmax); } else if (!Q_stricmp(startptr, "BV")) { CG_EP_ParseFloats(eqptr, &cg_atmFx.baseVec[0], &cg_atmFx.baseVec[1]); } else if (!Q_stricmp(startptr, "GV")) { CG_EP_ParseFloats(eqptr, &cg_atmFx.gustVec[0], &cg_atmFx.gustVec[1]); } else if (!Q_stricmp(startptr, "W")) { CG_EP_ParseFloats(eqptr, &cg_atmFx.baseWeight, &cg_atmFx.gustWeight); } else if (!Q_stricmp(startptr, "D")) { CG_EP_ParseFloats(eqptr, &bdrop, &gdrop); } else if (!Q_stricmp(startptr, "H")) { CG_EP_ParseInts(eqptr, &bheight, &bheight); } else { CG_Printf("Unknown effect key '%s'.\n", startptr); } } startptr = endptr; } if (atmFXType == ATM_NONE || !BG_LoadTraceMap(cgs.rawmapname, cg.mapcoordsMins, cg.mapcoordsMaxs)) { // no effects cg_atmFx.numDrops = -1; return; } cg_atmFx.baseHeightOffset = bheight; if (cg_atmFx.baseHeightOffset < 0) { cg_atmFx.baseHeightOffset = 0; } cg_atmFx.baseMinTime = 1000 * bmin; cg_atmFx.baseMaxTime = 1000 * bmax; cg_atmFx.changeMinTime = 1000 * cmin; cg_atmFx.changeMaxTime = 1000 * cmax; cg_atmFx.gustMinTime = 1000 * gmin; cg_atmFx.gustMaxTime = 1000 * gmax; cg_atmFx.baseDrops = bdrop; cg_atmFx.gustDrops = gdrop; cg_atmFx.numDrops = (cg_atmFx.baseDrops > cg_atmFx.gustDrops) ? cg_atmFx.baseDrops : cg_atmFx.gustDrops; if (cg_atmFx.numDrops > MAX_ATMOSPHERIC_PARTICLES) { cg_atmFx.numDrops = MAX_ATMOSPHERIC_PARTICLES; } // load graphics if (atmFXType == ATM_RAIN) // rain { cg_atmFx.numEffectShaders = 1; cg_atmFx.effectshaders[0] = trap_R_RegisterShader("gfx/misc/raindrop"); if (!(cg_atmFx.effectshaders[0])) { cg_atmFx.effectshaders[0] = -1; cg_atmFx.numEffectShaders = 0; } } else if (atmFXType == ATM_SNOW) // snow { cg_atmFx.numEffectShaders = 1; cg_atmFx.effectshaders[0] = trap_R_RegisterShader("gfx/misc/snow"); } else { // this really should never happen cg_atmFx.numEffectShaders = 0; } CG_EffectGust(); }