PageRenderTime 78ms CodeModel.GetById 24ms app.highlight 50ms RepoModel.GetById 1ms app.codeStats 0ms

/xbmc/visualizations/Goom/goom2k4-0/src/flying_stars_fx.c

http://github.com/xbmc/xbmc
C | 316 lines | 221 code | 53 blank | 42 comment | 14 complexity | 5e455c1fe0523f940fd6e69a839f4fbf MD5 | raw file
  1#include "goom_fx.h"
  2#include "goom_plugin_info.h"
  3#include "goom_tools.h"
  4
  5#include "mathtools.h"
  6
  7/* TODO:-- FAIRE PROPREMENT... BOAH... */
  8#define NCOL 15
  9
 10/*static const int colval[] = {
 110xfdf6f5,
 120xfae4e4,
 130xf7d1d1,
 140xf3b6b5,
 150xefa2a2,
 160xec9190,
 170xea8282,
 180xe87575,
 190xe46060,
 200xe14b4c,
 210xde3b3b,
 220xdc2d2f,
 230xd92726,
 240xd81619,
 250xd50c09,
 260
 27};
 28*/
 29static const int colval[] = {
 30	0x1416181a,
 31	0x1419181a,
 32	0x141f181a,
 33	0x1426181a,
 34	0x142a181a,
 35	0x142f181a,
 36	0x1436181a,
 37	0x142f1819,
 38	0x14261615,
 39	0x13201411,
 40	0x111a100a,
 41	0x0c180508,
 42	0x08100304,
 43	0x00050101,
 44	0x0
 45};
 46
 47
 48/* The different modes of the visual FX.
 49 * Put this values on fx_mode */
 50#define FIREWORKS_FX 0
 51#define RAIN_FX 1
 52#define FOUNTAIN_FX 2
 53#define LAST_FX 3
 54
 55typedef struct _FS_STAR {
 56	float x,y;
 57	float vx,vy;
 58	float ax,ay;
 59	float age,vage;
 60} Star;
 61
 62typedef struct _FS_DATA{
 63
 64	int fx_mode;
 65	int nbStars;
 66
 67	int maxStars;
 68	Star *stars;
 69
 70	float min_age;
 71	float max_age;
 72
 73	PluginParam min_age_p;
 74	PluginParam max_age_p;
 75	PluginParam nbStars_p;
 76	PluginParam nbStars_limit_p;
 77	PluginParam fx_mode_p;
 78
 79	PluginParameters params;
 80} FSData;
 81
 82static void fs_init(VisualFX *_this, PluginInfo *info) {
 83	
 84	FSData *data;
 85	data = (FSData*)malloc(sizeof(FSData));
 86
 87	data->fx_mode = FIREWORKS_FX;
 88	data->maxStars = 4096;
 89	data->stars = (Star*)malloc(data->maxStars * sizeof(Star));
 90	data->nbStars = 0;
 91
 92	data->max_age_p = secure_i_param ("Fireworks Smallest Bombs");
 93	IVAL(data->max_age_p) = 80;
 94	IMIN(data->max_age_p) = 0;
 95	IMAX(data->max_age_p) = 100;
 96	ISTEP(data->max_age_p) = 1;
 97
 98	data->min_age_p = secure_i_param ("Fireworks Largest Bombs");
 99	IVAL(data->min_age_p) = 99;
100	IMIN(data->min_age_p) = 0;
101	IMAX(data->min_age_p) = 100;
102	ISTEP(data->min_age_p) = 1;
103
104	data->nbStars_limit_p = secure_i_param ("Max Number of Particules");
105	IVAL(data->nbStars_limit_p) = 512;
106	IMIN(data->nbStars_limit_p) = 0;
107	IMAX(data->nbStars_limit_p) = data->maxStars;
108	ISTEP(data->nbStars_limit_p) = 64;
109
110	data->fx_mode_p = secure_i_param ("FX Mode");
111	IVAL(data->fx_mode_p) = data->fx_mode;
112	IMIN(data->fx_mode_p) = 1;
113	IMAX(data->fx_mode_p) = 3;
114	ISTEP(data->fx_mode_p) = 1;
115
116	data->nbStars_p = secure_f_feedback ("Number of Particules (% of Max)");
117
118	data->params = plugin_parameters ("Particule System", 7);
119	data->params.params[0] = &data->fx_mode_p;
120	data->params.params[1] = &data->nbStars_limit_p;
121	data->params.params[2] = 0;
122	data->params.params[3] = &data->min_age_p;
123	data->params.params[4] = &data->max_age_p;
124	data->params.params[5] = 0;
125	data->params.params[6] = &data->nbStars_p;
126
127	_this->params = &data->params;
128	_this->fx_data = (void*)data;
129}
130
131static void fs_free(VisualFX *_this) {
132       FSData *data = (FSData*)_this->fx_data;
133       free (data->stars);
134       free (data->params.params);
135	free (data);
136}
137
138
139/**
140 * Cree une nouvelle 'bombe', c'est a dire une particule appartenant a une fusee d'artifice.
141 */
142static void addABomb (FSData *fs, int mx, int my, float radius, float vage, float gravity, PluginInfo *info) {
143
144	int i = fs->nbStars;
145	float ro;
146	int theta;
147
148	if (fs->nbStars >= fs->maxStars)
149		return;
150	fs->nbStars++;
151
152	fs->stars[i].x = mx;
153	fs->stars[i].y = my;
154
155	ro = radius * (float)goom_irand(info->gRandom,100) / 100.0f;
156	ro *= (float)goom_irand(info->gRandom,100)/100.0f + 1.0f;
157	theta = goom_irand(info->gRandom,256);
158
159	fs->stars[i].vx = ro * cos256[theta];
160	fs->stars[i].vy = -0.2f + ro * sin256[theta];
161
162	fs->stars[i].ax = 0;
163	fs->stars[i].ay = gravity;
164
165	fs->stars[i].age = 0;
166	if (vage < fs->min_age)
167		vage=fs->min_age;
168	fs->stars[i].vage = vage;
169}
170
171
172/**
173 * Met a jour la position et vitesse d'une particule.
174 */
175static void updateStar (Star *s) {
176	s->x+=s->vx;
177	s->y+=s->vy;
178	s->vx+=s->ax;
179	s->vy+=s->ay;
180	s->age+=s->vage;
181}
182
183
184/**
185 * Ajoute de nouvelles particules au moment d'un evenement sonore.
186 */
187static void fs_sound_event_occured(VisualFX *_this, PluginInfo *info) {
188
189	FSData *data = (FSData*)_this->fx_data;
190	int i;
191
192	int max = (int)((1.0f+info->sound.goomPower)*goom_irand(info->gRandom,150)) + 100;
193	float radius = (1.0f+info->sound.goomPower) * (float)(goom_irand(info->gRandom,150)+50)/300;
194	int mx;
195	int my;
196	float vage, gravity = 0.02f;
197
198	switch (data->fx_mode) {
199		case FIREWORKS_FX:
200      {  
201      double dx,dy;
202      do {
203        mx = goom_irand(info->gRandom,info->screen.width);
204	  		my = goom_irand(info->gRandom,info->screen.height);
205        dx = (mx - info->screen.width/2);
206        dy = (my - info->screen.height/2);
207      } while (dx*dx + dy*dy < (info->screen.height/2)*(info->screen.height/2));
208			vage = data->max_age * (1.0f - info->sound.goomPower);
209      }
210			break;
211		case RAIN_FX:
212      mx = goom_irand(info->gRandom,info->screen.width);
213      if (mx > info->screen.width/2)
214        mx = info->screen.width;
215      else
216        mx = 0;
217			my = -(info->screen.height/3)-goom_irand(info->gRandom,info->screen.width/3);
218			radius *= 1.5;
219			vage = 0.002f;
220			break;
221		case FOUNTAIN_FX:
222			my = info->screen.height+2;
223			vage = 0.001f;
224			radius += 1.0f;
225			mx = info->screen.width / 2;
226			gravity = 0.04f;
227			break;
228		default:
229			return;
230			/* my = i R A N D (info->screen.height); vage = 0.01f; */
231	}
232
233	radius *= info->screen.height / 200.0f; /* why 200 ? because the FX was developped on 320x200 */
234	max *= info->screen.height / 200.0f;
235
236	if (info->sound.timeSinceLastBigGoom < 1) {
237		radius *= 1.5;
238		max *= 2;
239	}
240	for (i=0;i<max;++i)
241		addABomb (data,mx,my,radius,vage,gravity,info);
242}
243
244
245/**
246 * Main methode of the FX.
247 */
248static void fs_apply(VisualFX *_this, Pixel *src, Pixel *dest, PluginInfo *info) {
249
250	int i;
251	int col;
252	FSData *data = (FSData*)_this->fx_data;
253
254	/* Get the new parameters values */
255	data->min_age = 1.0f - (float)IVAL(data->min_age_p)/100.0f;
256	data->max_age = 1.0f - (float)IVAL(data->max_age_p)/100.0f;
257	FVAL(data->nbStars_p) = (float)data->nbStars / (float)data->maxStars;
258	data->nbStars_p.change_listener(&data->nbStars_p);
259	data->maxStars = IVAL(data->nbStars_limit_p);
260	data->fx_mode = IVAL(data->fx_mode_p);
261
262	/* look for events */
263	if (info->sound.timeSinceLastGoom < 1) {
264		fs_sound_event_occured(_this, info);
265		if (goom_irand(info->gRandom,20)==1) {
266			IVAL(data->fx_mode_p) = goom_irand(info->gRandom,(LAST_FX*3));
267			data->fx_mode_p.change_listener(&data->fx_mode_p);
268		}
269	}
270
271	/* update particules */
272	for (i=0;i<data->nbStars;++i) {
273		updateStar(&data->stars[i]);
274
275		/* dead particule */
276		if (data->stars[i].age>=NCOL)
277			continue;
278
279		/* choose the color of the particule */
280		col = colval[(int)data->stars[i].age];
281
282		/* draws the particule */
283		info->methods.draw_line(dest,(int)data->stars[i].x,(int)data->stars[i].y,
284				(int)(data->stars[i].x-data->stars[i].vx*6),
285				(int)(data->stars[i].y-data->stars[i].vy*6),
286				col,
287				(int)info->screen.width, (int)info->screen.height);
288		info->methods.draw_line(dest,(int)data->stars[i].x,(int)data->stars[i].y,
289				(int)(data->stars[i].x-data->stars[i].vx*2),
290				(int)(data->stars[i].y-data->stars[i].vy*2),
291				col,
292				(int)info->screen.width, (int)info->screen.height);
293	}
294
295	/* look for dead particules */
296	for (i=0;i<data->nbStars;) {
297
298		if ((data->stars[i].x > info->screen.width + 64)
299				||((data->stars[i].vy>=0)&&(data->stars[i].y - 16*data->stars[i].vy > info->screen.height))
300				||(data->stars[i].x < -64)
301				||(data->stars[i].age>=NCOL)) {
302			data->stars[i] = data->stars[data->nbStars-1];
303			data->nbStars--;
304		}
305		else ++i;
306	}
307}
308
309VisualFX flying_star_create(void) {
310  VisualFX vfx;
311  vfx.init = fs_init;
312  vfx.free = fs_free;
313  vfx.apply = fs_apply;
314  vfx.fx_data = 0;
315  return vfx;
316}