summaryrefslogtreecommitdiffstats
path: root/gst/goom/tentacle3d.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/goom/tentacle3d.c')
-rw-r--r--gst/goom/tentacle3d.c333
1 files changed, 333 insertions, 0 deletions
diff --git a/gst/goom/tentacle3d.c b/gst/goom/tentacle3d.c
new file mode 100644
index 00000000..44503934
--- /dev/null
+++ b/gst/goom/tentacle3d.c
@@ -0,0 +1,333 @@
+#include <stdlib.h>
+
+#include "v3d.h"
+#include "surf3d.h"
+#include "goom_tools.h"
+#include "goom_config.h"
+#include "goom_plugin_info.h"
+#include "tentacle3d.h"
+
+#define D 256.0f
+
+#define nbgrid 6
+#define definitionx 15
+#define definitionz 45
+
+typedef struct _TENTACLE_FX_DATA
+{
+ PluginParam enabled_bp;
+ PluginParameters params;
+
+ float cycle;
+ grid3d *grille[nbgrid];
+ float *vals;
+
+#define NB_TENTACLE_COLORS 4
+ int colors[NB_TENTACLE_COLORS];
+
+ int col;
+ int dstcol;
+ float lig;
+ float ligs;
+
+ /* statics from pretty_move */
+ float distt;
+ float distt2;
+ float rot; /* entre 0 et 2 * M_PI */
+ int happens;
+ int rotation;
+ int lock;
+} TentacleFXData;
+
+static void tentacle_new (TentacleFXData * data);
+static void tentacle_update (PluginInfo * goomInfo, Pixel * buf, Pixel * back,
+ int W, int H, short[2][512], float, int drawit, TentacleFXData * data);
+static void tentacle_free (TentacleFXData * data);
+
+/*
+ * VisualFX wrapper for the tentacles
+ */
+
+static void
+tentacle_fx_init (VisualFX * _this, PluginInfo * info)
+{
+
+ TentacleFXData *data = (TentacleFXData *) malloc (sizeof (TentacleFXData));
+
+ data->enabled_bp = secure_b_param ("Enabled", 1);
+ data->params = plugin_parameters ("3D Tentacles", 1);
+ data->params.params[0] = &data->enabled_bp;
+
+ data->cycle = 0.0f;
+ data->col =
+ (0x28 << (ROUGE * 8)) | (0x2c << (VERT * 8)) | (0x5f << (BLEU * 8));
+ data->dstcol = 0;
+ data->lig = 1.15f;
+ data->ligs = 0.1f;
+
+ data->distt = 10.0f;
+ data->distt2 = 0.0f;
+ data->rot = 0.0f; /* entre 0 et 2 * M_PI */
+ data->happens = 0;
+
+ data->rotation = 0;
+ data->lock = 0;
+ data->colors[0] =
+ (0x18 << (ROUGE * 8)) | (0x4c << (VERT * 8)) | (0x2f << (BLEU * 8));
+ data->colors[1] =
+ (0x48 << (ROUGE * 8)) | (0x2c << (VERT * 8)) | (0x6f << (BLEU * 8));
+ data->colors[2] =
+ (0x58 << (ROUGE * 8)) | (0x3c << (VERT * 8)) | (0x0f << (BLEU * 8));
+ data->colors[3] =
+ (0x87 << (ROUGE * 8)) | (0x55 << (VERT * 8)) | (0x74 << (BLEU * 8));
+ tentacle_new (data);
+
+ _this->params = &data->params;
+ _this->fx_data = (void *) data;
+}
+
+static void
+tentacle_fx_apply (VisualFX * _this, Pixel * src, Pixel * dest,
+ PluginInfo * goomInfo)
+{
+ TentacleFXData *data = (TentacleFXData *) _this->fx_data;
+
+ if (BVAL (data->enabled_bp)) {
+ tentacle_update (goomInfo, dest, src, goomInfo->screen.width,
+ goomInfo->screen.height, goomInfo->sound.samples,
+ (float) goomInfo->sound.accelvar,
+ goomInfo->curGState->drawTentacle, data);
+ }
+}
+
+static void
+tentacle_fx_free (VisualFX * _this)
+{
+ tentacle_free ((TentacleFXData *) _this->fx_data);
+ free (_this->fx_data);
+}
+
+VisualFX
+tentacle_fx_create (void)
+{
+ VisualFX fx;
+
+ fx.init = tentacle_fx_init;
+ fx.apply = tentacle_fx_apply;
+ fx.free = tentacle_fx_free;
+ return fx;
+}
+
+/* ----- */
+
+static void
+tentacle_free (TentacleFXData * data)
+{
+ /* TODO : un vrai FREE GRID!! */
+ free (data->vals);
+}
+
+static void
+tentacle_new (TentacleFXData * data)
+{
+ int tmp;
+
+ v3d center = { 0, -17.0, 0 };
+ data->vals = (float *) malloc ((definitionx + 20) * sizeof (float));
+
+ for (tmp = 0; tmp < nbgrid; tmp++) {
+ int x, z;
+
+ z = 45 + rand () % 30;
+ x = 85 + rand () % 5;
+ center.z = z;
+ data->grille[tmp] =
+ grid3d_new (x, definitionx, z, definitionz + rand () % 10, center);
+ center.y += 8;
+ }
+}
+
+static inline unsigned char
+lighten (unsigned char value, float power)
+{
+ int val = value;
+ float t = (float) val * log10 (power) / 2.0;
+
+ if (t > 0) {
+ val = (int) t; /* (32.0f * log (t)); */
+ if (val > 255)
+ val = 255;
+ if (val < 0)
+ val = 0;
+ return val;
+ } else {
+ return 0;
+ }
+}
+
+static void
+lightencolor (int *col, float power)
+{
+ unsigned char *color;
+
+ color = (unsigned char *) col;
+ *color = lighten (*color, power);
+ color++;
+ *color = lighten (*color, power);
+ color++;
+ *color = lighten (*color, power);
+ color++;
+ *color = lighten (*color, power);
+}
+
+/* retourne x>>s , en testant le signe de x */
+#define ShiftRight(_x,_s) ((_x<0) ? -(-_x>>_s) : (_x>>_s))
+
+static int
+evolutecolor (unsigned int src, unsigned int dest,
+ unsigned int mask, unsigned int incr)
+{
+
+ int color = src & (~mask);
+
+ src &= mask;
+ dest &= mask;
+
+ if ((src != mask)
+ && (src < dest))
+ src += incr;
+
+ if (src > dest)
+ src -= incr;
+ return (src & mask) | color;
+}
+
+static void
+pretty_move (PluginInfo * goomInfo, float cycle, float *dist, float *dist2,
+ float *rotangle, TentacleFXData * fx_data)
+{
+
+ float tmp;
+
+ /* many magic numbers here... I don't really like that. */
+ if (fx_data->happens)
+ fx_data->happens -= 1;
+ else if (fx_data->lock == 0) {
+ fx_data->happens =
+ goom_irand (goomInfo->gRandom,
+ 200) ? 0 : 100 + goom_irand (goomInfo->gRandom, 60);
+ fx_data->lock = fx_data->happens * 3 / 2;
+ } else
+ fx_data->lock--;
+
+ tmp = fx_data->happens ? 8.0f : 0;
+ *dist2 = fx_data->distt2 = (tmp + 15.0f * fx_data->distt2) / 16.0f;
+
+ tmp = 30 + D - 90.0f * (1.0f + sin (cycle * 19 / 20));
+ if (fx_data->happens)
+ tmp *= 0.6f;
+
+ *dist = fx_data->distt = (tmp + 3.0f * fx_data->distt) / 4.0f;
+
+ if (!fx_data->happens) {
+ tmp = M_PI * sin (cycle) / 32 + 3 * M_PI / 2;
+ } else {
+ fx_data->rotation =
+ goom_irand (goomInfo->gRandom,
+ 500) ? fx_data->rotation : goom_irand (goomInfo->gRandom, 2);
+ if (fx_data->rotation)
+ cycle *= 2.0f * M_PI;
+ else
+ cycle *= -1.0f * M_PI;
+ tmp = cycle - (M_PI * 2.0) * floor (cycle / (M_PI * 2.0));
+ }
+
+ if (abs (tmp - fx_data->rot) > abs (tmp - (fx_data->rot + 2.0 * M_PI))) {
+ fx_data->rot = (tmp + 15.0f * (fx_data->rot + 2 * M_PI)) / 16.0f;
+ if (fx_data->rot > 2.0 * M_PI)
+ fx_data->rot -= 2.0 * M_PI;
+ *rotangle = fx_data->rot;
+ } else if (abs (tmp - fx_data->rot) > abs (tmp - (fx_data->rot - 2.0 * M_PI))) {
+ fx_data->rot = (tmp + 15.0f * (fx_data->rot - 2.0 * M_PI)) / 16.0f;
+ if (fx_data->rot < 0.0f)
+ fx_data->rot += 2.0 * M_PI;
+ *rotangle = fx_data->rot;
+ } else
+ *rotangle = fx_data->rot = (tmp + 15.0f * fx_data->rot) / 16.0f;
+}
+
+static void
+tentacle_update (PluginInfo * goomInfo, Pixel * buf, Pixel * back, int W, int H,
+ short data[2][512], float rapport, int drawit, TentacleFXData * fx_data)
+{
+
+ int tmp;
+ int tmp2;
+
+ int color;
+ int colorlow;
+
+ float dist, dist2, rotangle;
+
+ if ((!drawit) && (fx_data->ligs > 0.0f))
+ fx_data->ligs = -fx_data->ligs;
+
+ fx_data->lig += fx_data->ligs;
+
+ if (fx_data->lig > 1.01f) {
+ if ((fx_data->lig > 10.0f) | (fx_data->lig < 1.1f))
+ fx_data->ligs = -fx_data->ligs;
+
+ if ((fx_data->lig < 6.3f) && (goom_irand (goomInfo->gRandom, 30) == 0))
+ fx_data->dstcol = goom_irand (goomInfo->gRandom, NB_TENTACLE_COLORS);
+
+ fx_data->col =
+ evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff,
+ 0x01);
+ fx_data->col =
+ evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff00,
+ 0x0100);
+ fx_data->col =
+ evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff0000,
+ 0x010000);
+ fx_data->col =
+ evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol],
+ 0xff000000, 0x01000000);
+
+ color = fx_data->col;
+ colorlow = fx_data->col;
+
+ lightencolor (&color, fx_data->lig * 2.0f + 2.0f);
+ lightencolor (&colorlow, (fx_data->lig / 3.0f) + 0.67f);
+
+ rapport = 1.0f + 2.0f * (rapport - 1.0f);
+ rapport *= 1.2f;
+ if (rapport > 1.12f)
+ rapport = 1.12f;
+
+ pretty_move (goomInfo, fx_data->cycle, &dist, &dist2, &rotangle, fx_data);
+
+ for (tmp = 0; tmp < nbgrid; tmp++) {
+ for (tmp2 = 0; tmp2 < definitionx; tmp2++) {
+ float val =
+ (float) (ShiftRight (data[0][goom_irand (goomInfo->gRandom, 511)],
+ 10)) * rapport;
+ fx_data->vals[tmp2] = val;
+ }
+
+ grid3d_update (fx_data->grille[tmp], rotangle, fx_data->vals, dist2);
+ }
+ fx_data->cycle += 0.01f;
+ for (tmp = 0; tmp < nbgrid; tmp++)
+ grid3d_draw (goomInfo, fx_data->grille[tmp], color, colorlow, dist, buf,
+ back, W, H);
+ } else {
+ fx_data->lig = 1.05f;
+ if (fx_data->ligs < 0.0f)
+ fx_data->ligs = -fx_data->ligs;
+ pretty_move (goomInfo, fx_data->cycle, &dist, &dist2, &rotangle, fx_data);
+ fx_data->cycle += 0.1f;
+ if (fx_data->cycle > 1000)
+ fx_data->cycle = 0;
+ }
+}