1 /* Goom Project
2 * Copyright (C) <2003> iOS-Software
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19 #include <stdlib.h>
20
21 #include "v3d.h"
22 #include "surf3d.h"
23 #include "goom_tools.h"
24 #include "goom_config.h"
25 #include "goom_plugin_info.h"
26 #include "tentacle3d.h"
27
28 #define D 256.0f
29
30 #define nbgrid 6
31 #define definitionx 15
32 #define definitionz 45
33
34 typedef struct _TENTACLE_FX_DATA
35 {
36 PluginParam enabled_bp;
37 PluginParameters params;
38
39 float cycle;
40 grid3d *grille[nbgrid];
41 float *vals;
42
43 #define NB_TENTACLE_COLORS 4
44 int colors[NB_TENTACLE_COLORS];
45
46 int col;
47 int dstcol;
48 float lig;
49 float ligs;
50
51 /* statics from pretty_move */
52 float distt;
53 float distt2;
54 float rot; /* entre 0 et 2 * G_PI */
55 int happens;
56 int rotation;
57 int lock;
58 } TentacleFXData;
59
60 static void tentacle_new (TentacleFXData * data);
61 static void tentacle_update (PluginInfo * goomInfo, Pixel * buf, Pixel * back,
62 int W, int H, short[2][512], float, int drawit, TentacleFXData * data);
63 static void tentacle_free (TentacleFXData * data);
64
65 /*
66 * VisualFX wrapper for the tentacles
67 */
68
69 static void
tentacle_fx_init(VisualFX * _this,PluginInfo * info)70 tentacle_fx_init (VisualFX * _this, PluginInfo * info)
71 {
72
73 TentacleFXData *data = (TentacleFXData *) malloc (sizeof (TentacleFXData));
74
75 secure_b_param (&data->enabled_bp, "Enabled", 1);
76 plugin_parameters (&data->params, "3D Tentacles", 1);
77 data->params.params[0] = &data->enabled_bp;
78
79 data->cycle = 0.0f;
80 data->col =
81 (0x28 << (ROUGE * 8)) | (0x2c << (VERT * 8)) | (0x5f << (BLEU * 8));
82 data->dstcol = 0;
83 data->lig = 1.15f;
84 data->ligs = 0.1f;
85
86 data->distt = 10.0f;
87 data->distt2 = 0.0f;
88 data->rot = 0.0f; /* entre 0 et 2 * G_PI */
89 data->happens = 0;
90
91 data->rotation = 0;
92 data->lock = 0;
93 data->colors[0] =
94 (0x18 << (ROUGE * 8)) | (0x4c << (VERT * 8)) | (0x2f << (BLEU * 8));
95 data->colors[1] =
96 (0x48 << (ROUGE * 8)) | (0x2c << (VERT * 8)) | (0x6f << (BLEU * 8));
97 data->colors[2] =
98 (0x58 << (ROUGE * 8)) | (0x3c << (VERT * 8)) | (0x0f << (BLEU * 8));
99 data->colors[3] =
100 (0x87 << (ROUGE * 8)) | (0x55 << (VERT * 8)) | (0x74 << (BLEU * 8));
101 tentacle_new (data);
102
103 _this->params = &data->params;
104 _this->fx_data = (void *) data;
105 }
106
107 static void
tentacle_fx_apply(VisualFX * _this,Pixel * src,Pixel * dest,PluginInfo * goomInfo)108 tentacle_fx_apply (VisualFX * _this, Pixel * src, Pixel * dest,
109 PluginInfo * goomInfo)
110 {
111 TentacleFXData *data = (TentacleFXData *) _this->fx_data;
112
113 if (BVAL (data->enabled_bp)) {
114 tentacle_update (goomInfo, dest, src, goomInfo->screen.width,
115 goomInfo->screen.height, goomInfo->sound.samples,
116 (float) goomInfo->sound.accelvar,
117 goomInfo->curGState->drawTentacle, data);
118 }
119 }
120
121 static void
tentacle_fx_free(VisualFX * _this)122 tentacle_fx_free (VisualFX * _this)
123 {
124 tentacle_free ((TentacleFXData *) _this->fx_data);
125 free (_this->fx_data);
126 }
127
128 void
tentacle_fx_create(VisualFX * fx)129 tentacle_fx_create (VisualFX * fx)
130 {
131 fx->init = tentacle_fx_init;
132 fx->apply = tentacle_fx_apply;
133 fx->free = tentacle_fx_free;
134 fx->fx_data = NULL;
135 fx->params = NULL;
136 }
137
138 /* ----- */
139
140 static void
tentacle_free(TentacleFXData * data)141 tentacle_free (TentacleFXData * data)
142 {
143 int tmp;
144
145 /* FREE GRID */
146 for (tmp = 0; tmp < nbgrid; tmp++)
147 grid3d_free (data->grille[tmp]);
148 free (data->vals);
149
150 goom_plugin_parameters_free (&data->params);
151 }
152
153 static void
tentacle_new(TentacleFXData * data)154 tentacle_new (TentacleFXData * data)
155 {
156 int tmp;
157
158 v3d center = { 0, -17.0, 0 };
159 data->vals = (float *) malloc ((definitionx + 20) * sizeof (float));
160
161 for (tmp = 0; tmp < nbgrid; tmp++) {
162 int x, z;
163
164 z = 45 + rand () % 30;
165 x = 85 + rand () % 5;
166 center.z = z;
167 data->grille[tmp] =
168 grid3d_new (x, definitionx, z, definitionz + rand () % 10, center);
169 center.y += 8;
170 }
171 }
172
173 static inline unsigned char
lighten(unsigned char value,float power)174 lighten (unsigned char value, float power)
175 {
176 int val = value;
177 float t = (float) val * log10 (power) / 2.0;
178
179 if (t > 0) {
180 val = (int) t; /* (32.0f * log (t)); */
181 if (val > 255)
182 val = 255;
183 if (val < 0)
184 val = 0;
185 return val;
186 } else {
187 return 0;
188 }
189 }
190
191 static void
lightencolor(int * col,float power)192 lightencolor (int *col, float power)
193 {
194 unsigned char *color;
195
196 color = (unsigned char *) col;
197 *color = lighten (*color, power);
198 color++;
199 *color = lighten (*color, power);
200 color++;
201 *color = lighten (*color, power);
202 color++;
203 *color = lighten (*color, power);
204 }
205
206 /* retourne x>>s , en testant le signe de x */
207 #define ShiftRight(_x,_s) ((_x<0) ? -(-_x>>_s) : (_x>>_s))
208
209 static int
evolutecolor(unsigned int src,unsigned int dest,unsigned int mask,unsigned int incr)210 evolutecolor (unsigned int src, unsigned int dest,
211 unsigned int mask, unsigned int incr)
212 {
213
214 int color = src & (~mask);
215
216 src &= mask;
217 dest &= mask;
218
219 if ((src != mask)
220 && (src < dest))
221 src += incr;
222
223 if (src > dest)
224 src -= incr;
225 return (src & mask) | color;
226 }
227
228 static void
pretty_move(PluginInfo * goomInfo,float cycle,float * dist,float * dist2,float * rotangle,TentacleFXData * fx_data)229 pretty_move (PluginInfo * goomInfo, float cycle, float *dist, float *dist2,
230 float *rotangle, TentacleFXData * fx_data)
231 {
232
233 float tmp;
234
235 /* many magic numbers here... I don't really like that. */
236 if (fx_data->happens)
237 fx_data->happens -= 1;
238 else if (fx_data->lock == 0) {
239 fx_data->happens =
240 goom_irand (goomInfo->gRandom,
241 200) ? 0 : 100 + goom_irand (goomInfo->gRandom, 60);
242 fx_data->lock = fx_data->happens * 3 / 2;
243 } else
244 fx_data->lock--;
245
246 tmp = fx_data->happens ? 8.0f : 0;
247 *dist2 = fx_data->distt2 = (tmp + 15.0f * fx_data->distt2) / 16.0f;
248
249 tmp = 30 + D - 90.0f * (1.0f + sin (cycle * 19 / 20));
250 if (fx_data->happens)
251 tmp *= 0.6f;
252
253 *dist = fx_data->distt = (tmp + 3.0f * fx_data->distt) / 4.0f;
254
255 if (!fx_data->happens) {
256 tmp = G_PI * sin (cycle) / 32 + 3 * G_PI / 2;
257 } else {
258 fx_data->rotation =
259 goom_irand (goomInfo->gRandom,
260 500) ? fx_data->rotation : goom_irand (goomInfo->gRandom, 2);
261 if (fx_data->rotation)
262 cycle *= 2.0f * G_PI;
263 else
264 cycle *= -1.0f * G_PI;
265 tmp = cycle - (G_PI * 2.0) * floor (cycle / (G_PI * 2.0));
266 }
267
268 if (fabs (tmp - fx_data->rot) > fabs (tmp - (fx_data->rot + 2.0 * G_PI))) {
269 fx_data->rot = (tmp + 15.0f * (fx_data->rot + 2 * G_PI)) / 16.0f;
270 if (fx_data->rot > 2.0 * G_PI)
271 fx_data->rot -= 2.0 * G_PI;
272 *rotangle = fx_data->rot;
273 } else if (fabs (tmp - fx_data->rot) >
274 fabs (tmp - (fx_data->rot - 2.0 * G_PI))) {
275 fx_data->rot = (tmp + 15.0f * (fx_data->rot - 2.0 * G_PI)) / 16.0f;
276 if (fx_data->rot < 0.0f)
277 fx_data->rot += 2.0 * G_PI;
278 *rotangle = fx_data->rot;
279 } else
280 *rotangle = fx_data->rot = (tmp + 15.0f * fx_data->rot) / 16.0f;
281 }
282
283 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)284 tentacle_update (PluginInfo * goomInfo, Pixel * buf, Pixel * back, int W, int H,
285 short data[2][512], float rapport, int drawit, TentacleFXData * fx_data)
286 {
287
288 int tmp;
289 int tmp2;
290
291 int color;
292 int colorlow;
293
294 float dist, dist2, rotangle;
295
296 if ((!drawit) && (fx_data->ligs > 0.0f))
297 fx_data->ligs = -fx_data->ligs;
298
299 fx_data->lig += fx_data->ligs;
300
301 if (fx_data->lig > 1.01f) {
302 if ((fx_data->lig > 10.0f) | (fx_data->lig < 1.1f))
303 fx_data->ligs = -fx_data->ligs;
304
305 if ((fx_data->lig < 6.3f) && (goom_irand (goomInfo->gRandom, 30) == 0))
306 fx_data->dstcol = goom_irand (goomInfo->gRandom, NB_TENTACLE_COLORS);
307
308 fx_data->col =
309 evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff,
310 0x01);
311 fx_data->col =
312 evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff00,
313 0x0100);
314 fx_data->col =
315 evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff0000,
316 0x010000);
317 fx_data->col =
318 evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol],
319 0xff000000, 0x01000000);
320
321 color = fx_data->col;
322 colorlow = fx_data->col;
323
324 lightencolor (&color, fx_data->lig * 2.0f + 2.0f);
325 lightencolor (&colorlow, (fx_data->lig / 3.0f) + 0.67f);
326
327 rapport = 1.0f + 2.0f * (rapport - 1.0f);
328 rapport *= 1.2f;
329 if (rapport > 1.12f)
330 rapport = 1.12f;
331
332 pretty_move (goomInfo, fx_data->cycle, &dist, &dist2, &rotangle, fx_data);
333
334 for (tmp = 0; tmp < nbgrid; tmp++) {
335 for (tmp2 = 0; tmp2 < definitionx; tmp2++) {
336 float val =
337 (float) (ShiftRight (data[0][goom_irand (goomInfo->gRandom, 511)],
338 10)) * rapport;
339
340 fx_data->vals[tmp2] = val;
341 }
342
343 grid3d_update (fx_data->grille[tmp], rotangle, fx_data->vals, dist2);
344 }
345 fx_data->cycle += 0.01f;
346 for (tmp = 0; tmp < nbgrid; tmp++)
347 grid3d_draw (goomInfo, fx_data->grille[tmp], color, colorlow, dist, buf,
348 back, W, H);
349 } else {
350 fx_data->lig = 1.05f;
351 if (fx_data->ligs < 0.0f)
352 fx_data->ligs = -fx_data->ligs;
353 pretty_move (goomInfo, fx_data->cycle, &dist, &dist2, &rotangle, fx_data);
354 fx_data->cycle += 0.1f;
355 if (fx_data->cycle > 1000)
356 fx_data->cycle = 0;
357 }
358 }
359