PageRenderTime 37ms CodeModel.GetById 15ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://github.com/xbmc/xbmc
C | 299 lines | 234 code | 57 blank | 8 comment | 35 complexity | c1995cf2457f93525d31af127b99486a MD5 | raw file
  1#include <stdlib.h>
  2
  3#include "v3d.h"
  4#include "surf3d.h"
  5#include "goom_tools.h"
  6#include "goom_config.h"
  7#include "goom_plugin_info.h"
  8#include "tentacle3d.h"
  9
 10#define D 256.0f
 11
 12#define nbgrid 6
 13#define definitionx 15
 14#define definitionz 45
 15
 16typedef struct _TENTACLE_FX_DATA {
 17	PluginParam enabled_bp;
 18	PluginParameters params;
 19
 20	float cycle;
 21	grid3d *grille[nbgrid];
 22	float *vals;
 23
 24#define NB_TENTACLE_COLORS 4
 25	int colors[NB_TENTACLE_COLORS];
 26
 27	int col;
 28	int dstcol;
 29	float lig;
 30	float ligs;
 31
 32	/* statics from pretty_move */
 33	float distt;
 34	float distt2;
 35	float rot; /* entre 0 et 2 * M_PI */
 36	int happens;
 37	int rotation;
 38	int lock;
 39} TentacleFXData;
 40
 41static void tentacle_new (TentacleFXData *data);
 42static void tentacle_update(PluginInfo *goomInfo, Pixel *buf, Pixel *back, int W, int H,
 43                     short[2][512], float, int drawit, TentacleFXData *data);
 44static void tentacle_free (TentacleFXData *data);
 45
 46/* 
 47 * VisualFX wrapper for the tentacles
 48 */
 49
 50static void tentacle_fx_init(VisualFX *_this, PluginInfo *info) {
 51	
 52	TentacleFXData *data = (TentacleFXData*)malloc(sizeof(TentacleFXData));
 53	
 54	data->enabled_bp = secure_b_param("Enabled", 1);
 55	data->params = plugin_parameters ("3D Tentacles", 1);
 56	data->params.params[0] = &data->enabled_bp;
 57
 58	data->cycle = 0.0f;
 59	data->col = (0x28<<(ROUGE*8))|(0x2c<<(VERT*8))|(0x5f<<(BLEU*8));
 60	data->dstcol = 0;
 61	data->lig = 1.15f;
 62	data->ligs = 0.1f;
 63	
 64	data->distt = 10.0f;
 65	data->distt2 = 0.0f;
 66	data->rot = 0.0f; /* entre 0 et 2 * M_PI */
 67	data->happens = 0;
 68	
 69	data->rotation = 0;
 70	data->lock = 0;
 71	data->colors[0] = (0x18<<(ROUGE*8))|(0x4c<<(VERT*8))|(0x2f<<(BLEU*8));
 72	data->colors[1] = (0x48<<(ROUGE*8))|(0x2c<<(VERT*8))|(0x6f<<(BLEU*8));
 73	data->colors[2] = (0x58<<(ROUGE*8))|(0x3c<<(VERT*8))|(0x0f<<(BLEU*8));
 74	data->colors[3] = (0x87<<(ROUGE*8))|(0x55<<(VERT*8))|(0x74<<(BLEU*8));
 75	tentacle_new(data);
 76
 77	_this->params = &data->params;
 78	_this->fx_data = (void*)data;
 79}
 80
 81static void tentacle_fx_apply(VisualFX *_this, Pixel *src, Pixel *dest, PluginInfo *goomInfo)
 82{
 83  TentacleFXData *data = (TentacleFXData*)_this->fx_data;
 84  if (BVAL(data->enabled_bp)) {
 85    tentacle_update(goomInfo, dest, src, goomInfo->screen.width,
 86                    goomInfo->screen.height, goomInfo->sound.samples,
 87                    (float)goomInfo->sound.accelvar,
 88                    goomInfo->curGState->drawTentacle, data);
 89  }
 90}
 91
 92static void tentacle_fx_free(VisualFX *_this) {
 93       TentacleFXData *data = (TentacleFXData*)_this->fx_data;
 94       free(data->params.params);
 95	tentacle_free(data);
 96	free(_this->fx_data);
 97}
 98
 99VisualFX tentacle_fx_create(void) {
100	VisualFX fx;
101	fx.init = tentacle_fx_init;
102	fx.apply = tentacle_fx_apply;
103	fx.free = tentacle_fx_free;
104	return fx;
105}
106
107/* ----- */
108
109static void tentacle_free (TentacleFXData *data) {
110	/* TODO : un vrai FREE GRID!! */
111        int tmp;
112        for (tmp=0;tmp<nbgrid;tmp++){
113            grid3d *g = data->grille[tmp];
114            free (g->surf.vertex);
115            free (g->surf.svertex);
116            free (g);
117        }
118	free (data->vals);
119}
120
121static void tentacle_new (TentacleFXData *data) {
122	int tmp;
123
124	v3d center = {0,-17.0,0};
125	data->vals = (float*)malloc ((definitionx+20)*sizeof(float));
126
127	for (tmp=0;tmp<nbgrid;tmp++) {
128		int x,z;
129		z = 45 + rand() % 30;
130		x = 85 + rand() % 5;
131		center.z = z;
132		data->grille[tmp] = grid3d_new (x, definitionx, z, definitionz + rand() % 10, center);
133		center.y += 8;
134	}
135}
136
137static inline unsigned char lighten (unsigned char value, float power)
138{
139	int val = value;
140	float t = (float) val * log10(power) / 2.0;
141
142	if (t > 0) {
143		val = (int) t; /* (32.0f * log (t)); */
144		if (val > 255)
145			val = 255;
146		if (val < 0)
147			val = 0;
148		return val;
149	}
150	else {
151		return 0;
152	}
153}
154
155static void lightencolor (int *col, float power)
156{
157	unsigned char *color;
158
159	color = (unsigned char *) col;
160	*color = lighten (*color, power);
161	color++;
162	*color = lighten (*color, power);
163	color++;
164	*color = lighten (*color, power);
165	color++;
166	*color = lighten (*color, power);
167}
168
169/* retourne x>>s , en testant le signe de x */
170#define ShiftRight(_x,_s) ((_x<0) ? -(-_x>>_s) : (_x>>_s))
171
172static int evolutecolor (unsigned int src,unsigned int dest,
173                         unsigned int mask, unsigned int incr) {
174	
175	int color = src & (~mask);
176	src &= mask;
177	dest &= mask;
178
179	if ((src!=mask)
180			&&(src<dest))
181		src += incr;
182
183	if (src>dest)
184		src -= incr;
185	return (src&mask)|color;
186}
187
188static void pretty_move (PluginInfo *goomInfo, float cycle, float *dist, float *dist2, float *rotangle, TentacleFXData *fx_data) {
189
190	float tmp;
191
192	/* many magic numbers here... I don't really like that. */
193	if (fx_data->happens)
194		fx_data->happens -= 1;
195	else if (fx_data->lock == 0) {
196		fx_data->happens = goom_irand(goomInfo->gRandom,200)?0:100+goom_irand(goomInfo->gRandom,60);
197		fx_data->lock = fx_data->happens * 3 / 2;
198	}
199	else fx_data->lock --;
200
201	tmp = fx_data->happens?8.0f:0;
202	*dist2 = fx_data->distt2 = (tmp + 15.0f*fx_data->distt2)/16.0f;
203
204	tmp = 30+D-90.0f*(1.0f+sin(cycle*19/20));
205	if (fx_data->happens)
206		tmp *= 0.6f;
207
208	*dist = fx_data->distt = (tmp + 3.0f*fx_data->distt)/4.0f;
209
210	if (!fx_data->happens){
211		tmp = M_PI*sin(cycle)/32+3*M_PI/2;
212	}
213	else {
214		fx_data->rotation = goom_irand(goomInfo->gRandom,500)?fx_data->rotation:goom_irand(goomInfo->gRandom,2);
215		if (fx_data->rotation)
216			cycle *= 2.0f*M_PI;
217		else
218			cycle *= -1.0f*M_PI;
219		tmp = cycle - (M_PI*2.0) * floor(cycle/(M_PI*2.0));
220	}
221
222	if (abs(tmp-fx_data->rot) > abs(tmp-(fx_data->rot+2.0*M_PI))) {
223		fx_data->rot = (tmp + 15.0f*(fx_data->rot+2*M_PI)) / 16.0f;
224		if (fx_data->rot>2.0*M_PI)
225			fx_data->rot -= 2.0*M_PI;
226		*rotangle = fx_data->rot;
227	}
228	else if (abs(tmp-fx_data->rot) > abs(tmp-(fx_data->rot-2.0*M_PI))) {
229		fx_data->rot = (tmp + 15.0f*(fx_data->rot-2.0*M_PI)) / 16.0f;
230		if (fx_data->rot<0.0f)
231			fx_data->rot += 2.0*M_PI;
232		*rotangle = fx_data->rot;
233	}
234	else
235		*rotangle = fx_data->rot = (tmp + 15.0f*fx_data->rot) / 16.0f;
236}
237
238static void tentacle_update(PluginInfo *goomInfo, Pixel *buf, Pixel *back, int W, int H,
239                     short data[2][512], float rapport, int drawit, TentacleFXData *fx_data) {
240	
241	int tmp;
242	int tmp2;
243
244	int color;
245	int colorlow;
246
247	float dist,dist2,rotangle;
248
249	if ((!drawit) && (fx_data->ligs>0.0f))
250		fx_data->ligs = -fx_data->ligs;
251
252	fx_data->lig += fx_data->ligs;
253
254	if (fx_data->lig > 1.01f) {
255		if ((fx_data->lig>10.0f) | (fx_data->lig<1.1f)) fx_data->ligs = -fx_data->ligs;
256
257		if ((fx_data->lig<6.3f)&&(goom_irand(goomInfo->gRandom,30)==0))
258			fx_data->dstcol=goom_irand(goomInfo->gRandom,NB_TENTACLE_COLORS);
259
260		fx_data->col = evolutecolor(fx_data->col,fx_data->colors[fx_data->dstcol],0xff,0x01);
261		fx_data->col = evolutecolor(fx_data->col,fx_data->colors[fx_data->dstcol],0xff00,0x0100);
262		fx_data->col = evolutecolor(fx_data->col,fx_data->colors[fx_data->dstcol],0xff0000,0x010000);
263		fx_data->col = evolutecolor(fx_data->col,fx_data->colors[fx_data->dstcol],0xff000000,0x01000000);
264
265		color = fx_data->col;
266		colorlow = fx_data->col;
267
268		lightencolor(&color,fx_data->lig * 2.0f + 2.0f);
269		lightencolor(&colorlow,(fx_data->lig/3.0f)+0.67f);
270
271		rapport = 1.0f + 2.0f * (rapport - 1.0f);
272		rapport *= 1.2f;
273		if (rapport > 1.12f)
274			rapport = 1.12f;
275
276		pretty_move (goomInfo, fx_data->cycle, &dist, &dist2, &rotangle, fx_data);
277
278		for (tmp=0;tmp<nbgrid;tmp++) {
279			for (tmp2=0;tmp2<definitionx;tmp2++) {
280				float val = (float)(ShiftRight(data[0][goom_irand(goomInfo->gRandom,511)],10)) * rapport;
281				fx_data->vals[tmp2] = val;
282			}
283
284			grid3d_update (fx_data->grille[tmp], rotangle, fx_data->vals, dist2);
285		}
286		fx_data->cycle+=0.01f;
287		for (tmp=0;tmp<nbgrid;tmp++)
288			grid3d_draw (goomInfo, fx_data->grille[tmp],color,colorlow,dist,buf,back,W,H);
289	}
290	else {
291		fx_data->lig = 1.05f;
292		if (fx_data->ligs < 0.0f)
293			fx_data->ligs = -fx_data->ligs;
294		pretty_move (goomInfo, fx_data->cycle, &dist, &dist2, &rotangle, fx_data);
295		fx_data->cycle+=0.1f;
296		if (fx_data->cycle > 1000)
297			fx_data->cycle = 0;
298	}
299}