summaryrefslogtreecommitdiffstats
path: root/gst/goom/flying_stars_fx.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/goom/flying_stars_fx.c')
-rw-r--r--gst/goom/flying_stars_fx.c341
1 files changed, 341 insertions, 0 deletions
diff --git a/gst/goom/flying_stars_fx.c b/gst/goom/flying_stars_fx.c
new file mode 100644
index 00000000..c323c7c9
--- /dev/null
+++ b/gst/goom/flying_stars_fx.c
@@ -0,0 +1,341 @@
+#include "goom_fx.h"
+#include "goom_plugin_info.h"
+#include "goom_tools.h"
+
+#include "mathtools.h"
+
+/* TODO:-- FAIRE PROPREMENT... BOAH... */
+#define NCOL 15
+
+/*static const int colval[] = {
+0xfdf6f5,
+0xfae4e4,
+0xf7d1d1,
+0xf3b6b5,
+0xefa2a2,
+0xec9190,
+0xea8282,
+0xe87575,
+0xe46060,
+0xe14b4c,
+0xde3b3b,
+0xdc2d2f,
+0xd92726,
+0xd81619,
+0xd50c09,
+0
+};
+*/
+static const int colval[] = {
+ 0x1416181a,
+ 0x1419181a,
+ 0x141f181a,
+ 0x1426181a,
+ 0x142a181a,
+ 0x142f181a,
+ 0x1436181a,
+ 0x142f1819,
+ 0x14261615,
+ 0x13201411,
+ 0x111a100a,
+ 0x0c180508,
+ 0x08100304,
+ 0x00050101,
+ 0x0
+};
+
+
+/* The different modes of the visual FX.
+ * Put this values on fx_mode */
+#define FIREWORKS_FX 0
+#define RAIN_FX 1
+#define FOUNTAIN_FX 2
+#define LAST_FX 3
+
+typedef struct _FS_STAR
+{
+ float x, y;
+ float vx, vy;
+ float ax, ay;
+ float age, vage;
+} Star;
+
+typedef struct _FS_DATA
+{
+
+ int fx_mode;
+ int nbStars;
+
+ int maxStars;
+ Star *stars;
+
+ float min_age;
+ float max_age;
+
+ PluginParam min_age_p;
+ PluginParam max_age_p;
+ PluginParam nbStars_p;
+ PluginParam nbStars_limit_p;
+ PluginParam fx_mode_p;
+
+ PluginParameters params;
+} FSData;
+
+static void
+fs_init (VisualFX * _this, PluginInfo * info)
+{
+
+ FSData *data;
+
+ data = (FSData *) malloc (sizeof (FSData));
+
+ data->fx_mode = FIREWORKS_FX;
+ data->maxStars = 4096;
+ data->stars = (Star *) malloc (data->maxStars * sizeof (Star));
+ data->nbStars = 0;
+
+ data->max_age_p = secure_i_param ("Fireworks Smallest Bombs");
+ IVAL (data->max_age_p) = 80;
+ IMIN (data->max_age_p) = 0;
+ IMAX (data->max_age_p) = 100;
+ ISTEP (data->max_age_p) = 1;
+
+ data->min_age_p = secure_i_param ("Fireworks Largest Bombs");
+ IVAL (data->min_age_p) = 99;
+ IMIN (data->min_age_p) = 0;
+ IMAX (data->min_age_p) = 100;
+ ISTEP (data->min_age_p) = 1;
+
+ data->nbStars_limit_p = secure_i_param ("Max Number of Particules");
+ IVAL (data->nbStars_limit_p) = 512;
+ IMIN (data->nbStars_limit_p) = 0;
+ IMAX (data->nbStars_limit_p) = data->maxStars;
+ ISTEP (data->nbStars_limit_p) = 64;
+
+ data->fx_mode_p = secure_i_param ("FX Mode");
+ IVAL (data->fx_mode_p) = data->fx_mode;
+ IMIN (data->fx_mode_p) = 1;
+ IMAX (data->fx_mode_p) = 3;
+ ISTEP (data->fx_mode_p) = 1;
+
+ data->nbStars_p = secure_f_feedback ("Number of Particules (% of Max)");
+
+ data->params = plugin_parameters ("Particule System", 7);
+ data->params.params[0] = &data->fx_mode_p;
+ data->params.params[1] = &data->nbStars_limit_p;
+ data->params.params[2] = 0;
+ data->params.params[3] = &data->min_age_p;
+ data->params.params[4] = &data->max_age_p;
+ data->params.params[5] = 0;
+ data->params.params[6] = &data->nbStars_p;
+
+ _this->params = &data->params;
+ _this->fx_data = (void *) data;
+}
+
+static void
+fs_free (VisualFX * _this)
+{
+ free (_this->fx_data);
+}
+
+
+/**
+ * Cree une nouvelle 'bombe', c'est a dire une particule appartenant a une fusee d'artifice.
+ */
+static void
+addABomb (FSData * fs, int mx, int my, float radius, float vage, float gravity,
+ PluginInfo * info)
+{
+
+ int i = fs->nbStars;
+ float ro;
+ int theta;
+
+ if (fs->nbStars >= fs->maxStars)
+ return;
+ fs->nbStars++;
+
+ fs->stars[i].x = mx;
+ fs->stars[i].y = my;
+
+ ro = radius * (float) goom_irand (info->gRandom, 100) / 100.0f;
+ ro *= (float) goom_irand (info->gRandom, 100) / 100.0f + 1.0f;
+ theta = goom_irand (info->gRandom, 256);
+
+ fs->stars[i].vx = ro * cos256[theta];
+ fs->stars[i].vy = -0.2f + ro * sin256[theta];
+
+ fs->stars[i].ax = 0;
+ fs->stars[i].ay = gravity;
+
+ fs->stars[i].age = 0;
+ if (vage < fs->min_age)
+ vage = fs->min_age;
+ fs->stars[i].vage = vage;
+}
+
+
+/**
+ * Met a jour la position et vitesse d'une particule.
+ */
+static void
+updateStar (Star * s)
+{
+ s->x += s->vx;
+ s->y += s->vy;
+ s->vx += s->ax;
+ s->vy += s->ay;
+ s->age += s->vage;
+}
+
+
+/**
+ * Ajoute de nouvelles particules au moment d'un evenement sonore.
+ */
+static void
+fs_sound_event_occured (VisualFX * _this, PluginInfo * info)
+{
+
+ FSData *data = (FSData *) _this->fx_data;
+ int i;
+
+ int max =
+ (int) ((1.0f + info->sound.goomPower) * goom_irand (info->gRandom,
+ 150)) + 100;
+ float radius =
+ (1.0f + info->sound.goomPower) * (float) (goom_irand (info->gRandom,
+ 150) + 50) / 300;
+ int mx;
+ int my;
+ float vage, gravity = 0.02f;
+
+ switch (data->fx_mode) {
+ case FIREWORKS_FX:
+ {
+ double dx, dy;
+
+ do {
+ mx = goom_irand (info->gRandom, info->screen.width);
+ my = goom_irand (info->gRandom, info->screen.height);
+ dx = (mx - info->screen.width / 2);
+ dy = (my - info->screen.height / 2);
+ } while (dx * dx + dy * dy <
+ (info->screen.height / 2) * (info->screen.height / 2));
+ vage = data->max_age * (1.0f - info->sound.goomPower);
+ }
+ break;
+ case RAIN_FX:
+ mx = goom_irand (info->gRandom, info->screen.width);
+ if (mx > info->screen.width / 2)
+ mx = info->screen.width;
+ else
+ mx = 0;
+ my = -(info->screen.height / 3) - goom_irand (info->gRandom,
+ info->screen.width / 3);
+ radius *= 1.5;
+ vage = 0.002f;
+ break;
+ case FOUNTAIN_FX:
+ my = info->screen.height + 2;
+ vage = 0.001f;
+ radius += 1.0f;
+ mx = info->screen.width / 2;
+ gravity = 0.04f;
+ break;
+ default:
+ return;
+ /* my = i R A N D (info->screen.height); vage = 0.01f; */
+ }
+
+ radius *= info->screen.height / 200.0f; /* why 200 ? because the FX was developped on 320x200 */
+ max *= info->screen.height / 200.0f;
+
+ if (info->sound.timeSinceLastBigGoom < 1) {
+ radius *= 1.5;
+ max *= 2;
+ }
+ for (i = 0; i < max; ++i)
+ addABomb (data, mx, my, radius, vage, gravity, info);
+}
+
+
+/**
+ * Main methode of the FX.
+ */
+static void
+fs_apply (VisualFX * _this, Pixel * src, Pixel * dest, PluginInfo * info)
+{
+
+ int i;
+ int col;
+ FSData *data = (FSData *) _this->fx_data;
+
+ /* Get the new parameters values */
+ data->min_age = 1.0f - (float) IVAL (data->min_age_p) / 100.0f;
+ data->max_age = 1.0f - (float) IVAL (data->max_age_p) / 100.0f;
+ FVAL (data->nbStars_p) = (float) data->nbStars / (float) data->maxStars;
+ data->nbStars_p.change_listener (&data->nbStars_p);
+ data->maxStars = IVAL (data->nbStars_limit_p);
+ data->fx_mode = IVAL (data->fx_mode_p);
+
+ /* look for events */
+ if (info->sound.timeSinceLastGoom < 1) {
+ fs_sound_event_occured (_this, info);
+ if (goom_irand (info->gRandom, 20) == 1) {
+ IVAL (data->fx_mode_p) = goom_irand (info->gRandom, (LAST_FX * 3));
+ data->fx_mode_p.change_listener (&data->fx_mode_p);
+ }
+ }
+
+ /* update particules */
+ for (i = 0; i < data->nbStars; ++i) {
+ updateStar (&data->stars[i]);
+
+ /* dead particule */
+ if (data->stars[i].age >= NCOL)
+ continue;
+
+ /* choose the color of the particule */
+ col = colval[(int) data->stars[i].age];
+
+ /* draws the particule */
+ info->methods.draw_line (dest, (int) data->stars[i].x,
+ (int) data->stars[i].y,
+ (int) (data->stars[i].x - data->stars[i].vx * 6),
+ (int) (data->stars[i].y - data->stars[i].vy * 6), col,
+ (int) info->screen.width, (int) info->screen.height);
+ info->methods.draw_line (dest, (int) data->stars[i].x,
+ (int) data->stars[i].y,
+ (int) (data->stars[i].x - data->stars[i].vx * 2),
+ (int) (data->stars[i].y - data->stars[i].vy * 2), col,
+ (int) info->screen.width, (int) info->screen.height);
+ }
+
+ /* look for dead particules */
+ for (i = 0; i < data->nbStars;) {
+
+ if ((data->stars[i].x > info->screen.width + 64)
+ || ((data->stars[i].vy >= 0)
+ && (data->stars[i].y - 16 * data->stars[i].vy >
+ info->screen.height))
+ || (data->stars[i].x < -64)
+ || (data->stars[i].age >= NCOL)) {
+ data->stars[i] = data->stars[data->nbStars - 1];
+ data->nbStars--;
+ } else
+ ++i;
+ }
+}
+
+VisualFX
+flying_star_create (void)
+{
+ VisualFX vfx = {
+ init:fs_init,
+ free:fs_free,
+ apply:fs_apply,
+ fx_data:0
+ };
+ return vfx;
+}