2 * Copyright (C) <2003> iOS-Software
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.
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.
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.
20 #include "goom_plugin_info.h"
21 #include "goom_tools.h"
23 #include "mathtools.h"
25 /* TODO:-- FAIRE PROPREMENT... BOAH... */
28 /*static const int colval[] = {
47 static const int colval[] = {
66 /* The different modes of the visual FX.
67 * Put this values on fx_mode */
68 #define FIREWORKS_FX 0
73 typedef struct _FS_STAR
81 typedef struct _FS_DATA
93 PluginParam min_age_p;
94 PluginParam max_age_p;
95 PluginParam nbStars_p;
96 PluginParam nbStars_limit_p;
97 PluginParam fx_mode_p;
99 PluginParameters params;
103 fs_init (VisualFX * _this, PluginInfo * info)
108 data = (FSData *) malloc (sizeof (FSData));
110 data->fx_mode = FIREWORKS_FX;
111 data->maxStars = 4096;
112 data->stars = (Star *) malloc (data->maxStars * sizeof (Star));
115 secure_i_param (&data->max_age_p, "Fireworks Smallest Bombs");
116 IVAL (data->max_age_p) = 80;
117 IMIN (data->max_age_p) = 0;
118 IMAX (data->max_age_p) = 100;
119 ISTEP (data->max_age_p) = 1;
121 secure_i_param (&data->min_age_p, "Fireworks Largest Bombs");
122 IVAL (data->min_age_p) = 99;
123 IMIN (data->min_age_p) = 0;
124 IMAX (data->min_age_p) = 100;
125 ISTEP (data->min_age_p) = 1;
127 secure_i_param (&data->nbStars_limit_p, "Max Number of Particules");
128 IVAL (data->nbStars_limit_p) = 512;
129 IMIN (data->nbStars_limit_p) = 0;
130 IMAX (data->nbStars_limit_p) = data->maxStars;
131 ISTEP (data->nbStars_limit_p) = 64;
133 secure_i_param (&data->fx_mode_p, "FX Mode");
134 IVAL (data->fx_mode_p) = data->fx_mode;
135 IMIN (data->fx_mode_p) = 1;
136 IMAX (data->fx_mode_p) = 3;
137 ISTEP (data->fx_mode_p) = 1;
139 secure_f_feedback (&data->nbStars_p, "Number of Particules (% of Max)");
141 plugin_parameters (&data->params, "Particule System", 7);
142 data->params.params[0] = &data->fx_mode_p;
143 data->params.params[1] = &data->nbStars_limit_p;
144 data->params.params[2] = 0;
145 data->params.params[3] = &data->min_age_p;
146 data->params.params[4] = &data->max_age_p;
147 data->params.params[5] = 0;
148 data->params.params[6] = &data->nbStars_p;
150 _this->params = &data->params;
151 _this->fx_data = (void *) data;
155 fs_free (VisualFX * _this)
157 FSData *data = (FSData *) _this->fx_data;
159 goom_plugin_parameters_free (&data->params);
162 free (_this->fx_data);
167 * Cree une nouvelle 'bombe', c'est a dire une particule appartenant a une fusee d'artifice.
170 addABomb (FSData * fs, int mx, int my, float radius, float vage, float gravity,
178 if (fs->nbStars >= fs->maxStars)
185 ro = radius * (float) goom_irand (info->gRandom, 100) / 100.0f;
186 ro *= (float) goom_irand (info->gRandom, 100) / 100.0f + 1.0f;
187 theta = goom_irand (info->gRandom, 256);
189 fs->stars[i].vx = ro * cos256[theta];
190 fs->stars[i].vy = -0.2f + ro * sin256[theta];
193 fs->stars[i].ay = gravity;
195 fs->stars[i].age = 0;
196 if (vage < fs->min_age)
198 fs->stars[i].vage = vage;
203 * Met a jour la position et vitesse d'une particule.
206 updateStar (Star * s)
217 * Ajoute de nouvelles particules au moment d'un evenement sonore.
220 fs_sound_event_occured (VisualFX * _this, PluginInfo * info)
223 FSData *data = (FSData *) _this->fx_data;
226 int max = (int) ((1.0f + info->sound.goomPower) * goom_irand (info->gRandom,
229 (1.0f + info->sound.goomPower) * (float) (goom_irand (info->gRandom,
233 float vage, gravity = 0.02f;
235 switch (data->fx_mode) {
241 mx = goom_irand (info->gRandom, info->screen.width);
242 my = goom_irand (info->gRandom, info->screen.height);
243 dx = (mx - info->screen.width / 2);
244 dy = (my - info->screen.height / 2);
245 } while (dx * dx + dy * dy <
246 (info->screen.height / 2) * (info->screen.height / 2));
247 vage = data->max_age * (1.0f - info->sound.goomPower);
251 mx = goom_irand (info->gRandom, info->screen.width);
252 if (mx > info->screen.width / 2)
253 mx = info->screen.width;
256 my = -(info->screen.height / 3) - goom_irand (info->gRandom,
257 info->screen.width / 3);
262 my = info->screen.height + 2;
265 mx = info->screen.width / 2;
270 /* my = i R A N D (info->screen.height); vage = 0.01f; */
273 radius *= info->screen.height / 200.0f; /* why 200 ? because the FX was developped on 320x200 */
274 max *= info->screen.height / 200.0f;
276 if (info->sound.timeSinceLastBigGoom < 1) {
280 for (i = 0; i < max; ++i)
281 addABomb (data, mx, my, radius, vage, gravity, info);
286 * Main methode of the FX.
289 fs_apply (VisualFX * _this, Pixel * src, Pixel * dest, PluginInfo * info)
294 FSData *data = (FSData *) _this->fx_data;
296 /* Get the new parameters values */
297 data->min_age = 1.0f - (float) IVAL (data->min_age_p) / 100.0f;
298 data->max_age = 1.0f - (float) IVAL (data->max_age_p) / 100.0f;
299 FVAL (data->nbStars_p) = (float) data->nbStars / (float) data->maxStars;
300 data->nbStars_p.change_listener (&data->nbStars_p);
301 data->maxStars = IVAL (data->nbStars_limit_p);
302 data->fx_mode = IVAL (data->fx_mode_p);
304 /* look for events */
305 if (info->sound.timeSinceLastGoom < 1) {
306 fs_sound_event_occured (_this, info);
307 if (goom_irand (info->gRandom, 20) == 1) {
308 IVAL (data->fx_mode_p) = goom_irand (info->gRandom, (LAST_FX * 3));
309 data->fx_mode_p.change_listener (&data->fx_mode_p);
313 /* update particules */
314 for (i = 0; i < data->nbStars; ++i) {
315 updateStar (&data->stars[i]);
318 if (data->stars[i].age >= NCOL)
321 /* choose the color of the particule */
322 col = colval[(int) data->stars[i].age];
324 /* draws the particule */
325 info->methods.draw_line (dest, (int) data->stars[i].x,
326 (int) data->stars[i].y,
327 (int) (data->stars[i].x - data->stars[i].vx * 6),
328 (int) (data->stars[i].y - data->stars[i].vy * 6), col,
329 (int) info->screen.width, (int) info->screen.height);
330 info->methods.draw_line (dest, (int) data->stars[i].x,
331 (int) data->stars[i].y,
332 (int) (data->stars[i].x - data->stars[i].vx * 2),
333 (int) (data->stars[i].y - data->stars[i].vy * 2), col,
334 (int) info->screen.width, (int) info->screen.height);
337 /* look for dead particules */
338 for (i = 0; i < data->nbStars;) {
340 if ((data->stars[i].x > info->screen.width + 64)
341 || ((data->stars[i].vy >= 0)
342 && (data->stars[i].y - 16 * data->stars[i].vy >
343 info->screen.height))
344 || (data->stars[i].x < -64)
345 || (data->stars[i].age >= NCOL)) {
346 data->stars[i] = data->stars[data->nbStars - 1];
354 flying_star_create (VisualFX * vfx)
358 vfx->apply = fs_apply;