flying_stars_fx.c

来自「linux下的MPEG1」· C语言 代码 · 共 315 行

C
315
字号
#include "goom_fx.h"#include "goom_plugin_info.h"#include "goom_tools.h"#include "mathtools.h"/* TODO:-- FAIRE PROPREMENT... BOAH... */#define NCOL 15/*static const int colval[] = {0xfdf6f5,0xfae4e4,0xf7d1d1,0xf3b6b5,0xefa2a2,0xec9190,0xea8282,0xe87575,0xe46060,0xe14b4c,0xde3b3b,0xdc2d2f,0xd92726,0xd81619,0xd50c09,0};*/static const int colval[] = {	0x1416181a,	0x1419181a,	0x141f181a,	0x1426181a,	0x142a181a,	0x142f181a,	0x1436181a,	0x142f1819,	0x14261615,	0x13201411,	0x111a100a,	0x0c180508,	0x08100304,	0x00050101,	0x0};/* The different modes of the visual FX. * Put this values on fx_mode */#define FIREWORKS_FX 0#define RAIN_FX 1#define FOUNTAIN_FX 2#define LAST_FX 3typedef struct _FS_STAR {	float x,y;	float vx,vy;	float ax,ay;	float age,vage;} Star;typedef struct _FS_DATA{	int fx_mode;	int nbStars;	int maxStars;	Star *stars;	float min_age;	float max_age;	PluginParam min_age_p;	PluginParam max_age_p;	PluginParam nbStars_p;	PluginParam nbStars_limit_p;	PluginParam fx_mode_p;	PluginParameters params;} FSData;static void fs_init(VisualFX *_this, PluginInfo *info) {		FSData *data;	data = (FSData*)malloc(sizeof(FSData));	data->fx_mode = FIREWORKS_FX;	data->maxStars = 4096;	data->stars = (Star*)malloc(data->maxStars * sizeof(Star));	data->nbStars = 0;	data->max_age_p = secure_i_param ("Fireworks Smallest Bombs");	IVAL(data->max_age_p) = 80;	IMIN(data->max_age_p) = 0;	IMAX(data->max_age_p) = 100;	ISTEP(data->max_age_p) = 1;	data->min_age_p = secure_i_param ("Fireworks Largest Bombs");	IVAL(data->min_age_p) = 99;	IMIN(data->min_age_p) = 0;	IMAX(data->min_age_p) = 100;	ISTEP(data->min_age_p) = 1;	data->nbStars_limit_p = secure_i_param ("Max Number of Particules");	IVAL(data->nbStars_limit_p) = 512;	IMIN(data->nbStars_limit_p) = 0;	IMAX(data->nbStars_limit_p) = data->maxStars;	ISTEP(data->nbStars_limit_p) = 64;	data->fx_mode_p = secure_i_param ("FX Mode");	IVAL(data->fx_mode_p) = data->fx_mode;	IMIN(data->fx_mode_p) = 1;	IMAX(data->fx_mode_p) = 3;	ISTEP(data->fx_mode_p) = 1;	data->nbStars_p = secure_f_feedback ("Number of Particules (% of Max)");	data->params = plugin_parameters ("Particule System", 7);	data->params.params[0] = &data->fx_mode_p;	data->params.params[1] = &data->nbStars_limit_p;	data->params.params[2] = 0;	data->params.params[3] = &data->min_age_p;	data->params.params[4] = &data->max_age_p;	data->params.params[5] = 0;	data->params.params[6] = &data->nbStars_p;	_this->params = &data->params;	_this->fx_data = (void*)data;}static void fs_free(VisualFX *_this) {	free (_this->fx_data);}/** * Cree une nouvelle 'bombe', c'est a dire une particule appartenant a une fusee d'artifice. */static void addABomb (FSData *fs, int mx, int my, float radius, float vage, float gravity, PluginInfo *info) {	int i = fs->nbStars;	float ro;	int theta;	if (fs->nbStars >= fs->maxStars)		return;	fs->nbStars++;	fs->stars[i].x = mx;	fs->stars[i].y = my;	ro = radius * (float)goom_irand(info->gRandom,100) / 100.0f;	ro *= (float)goom_irand(info->gRandom,100)/100.0f + 1.0f;	theta = goom_irand(info->gRandom,256);	fs->stars[i].vx = ro * cos256[theta];	fs->stars[i].vy = -0.2f + ro * sin256[theta];	fs->stars[i].ax = 0;	fs->stars[i].ay = gravity;	fs->stars[i].age = 0;	if (vage < fs->min_age)		vage=fs->min_age;	fs->stars[i].vage = vage;}/** * Met a jour la position et vitesse d'une particule. */static void updateStar (Star *s) {	s->x+=s->vx;	s->y+=s->vy;	s->vx+=s->ax;	s->vy+=s->ay;	s->age+=s->vage;}/** * Ajoute de nouvelles particules au moment d'un evenement sonore. */static void fs_sound_event_occured(VisualFX *_this, PluginInfo *info) {	FSData *data = (FSData*)_this->fx_data;	int i;	int max = (int)((1.0f+info->sound.goomPower)*goom_irand(info->gRandom,150)) + 100;	float radius = (1.0f+info->sound.goomPower) * (float)(goom_irand(info->gRandom,150)+50)/300;	int mx;	int my;	float vage, gravity = 0.02f;	switch (data->fx_mode) {		case FIREWORKS_FX:      {        double dx,dy;      do {        mx = goom_irand(info->gRandom,info->screen.width);	  		my = goom_irand(info->gRandom,info->screen.height);        dx = (mx - info->screen.width/2);        dy = (my - info->screen.height/2);      } while (dx*dx + dy*dy < (info->screen.height/2)*(info->screen.height/2));			vage = data->max_age * (1.0f - info->sound.goomPower);      }			break;		case RAIN_FX:      mx = goom_irand(info->gRandom,info->screen.width);      if (mx > info->screen.width/2)        mx = info->screen.width;      else        mx = 0;			my = -(info->screen.height/3)-goom_irand(info->gRandom,info->screen.width/3);			radius *= 1.5;			vage = 0.002f;			break;		case FOUNTAIN_FX:			my = info->screen.height+2;			vage = 0.001f;			radius += 1.0f;			mx = info->screen.width / 2;			gravity = 0.04f;			break;		default:			return;			/* my = i R A N D (info->screen.height); vage = 0.01f; */	}	radius *= info->screen.height / 200.0f; /* why 200 ? because the FX was developped on 320x200 */	max *= info->screen.height / 200.0f;	if (info->sound.timeSinceLastBigGoom < 1) {		radius *= 1.5;		max *= 2;	}	for (i=0;i<max;++i)		addABomb (data,mx,my,radius,vage,gravity,info);}/** * Main methode of the FX. */static void fs_apply(VisualFX *_this, Pixel *src, Pixel *dest, PluginInfo *info) {	int i;	int col;	FSData *data = (FSData*)_this->fx_data;	/* Get the new parameters values */	data->min_age = 1.0f - (float)IVAL(data->min_age_p)/100.0f;	data->max_age = 1.0f - (float)IVAL(data->max_age_p)/100.0f;	FVAL(data->nbStars_p) = (float)data->nbStars / (float)data->maxStars;	data->nbStars_p.change_listener(&data->nbStars_p);	data->maxStars = IVAL(data->nbStars_limit_p);	data->fx_mode = IVAL(data->fx_mode_p);	/* look for events */	if (info->sound.timeSinceLastGoom < 1) {		fs_sound_event_occured(_this, info);		if (goom_irand(info->gRandom,20)==1) {			IVAL(data->fx_mode_p) = goom_irand(info->gRandom,(LAST_FX*3));			data->fx_mode_p.change_listener(&data->fx_mode_p);		}	}	/* update particules */	for (i=0;i<data->nbStars;++i) {		updateStar(&data->stars[i]);		/* dead particule */		if (data->stars[i].age>=NCOL)			continue;		/* choose the color of the particule */		col = colval[(int)data->stars[i].age];		/* draws the particule */		info->methods.draw_line(dest,(int)data->stars[i].x,(int)data->stars[i].y,				(int)(data->stars[i].x-data->stars[i].vx*6),				(int)(data->stars[i].y-data->stars[i].vy*6),				col,				(int)info->screen.width, (int)info->screen.height);		info->methods.draw_line(dest,(int)data->stars[i].x,(int)data->stars[i].y,				(int)(data->stars[i].x-data->stars[i].vx*2),				(int)(data->stars[i].y-data->stars[i].vy*2),				col,				(int)info->screen.width, (int)info->screen.height);	}	/* look for dead particules */	for (i=0;i<data->nbStars;) {		if ((data->stars[i].x > info->screen.width + 64)				||((data->stars[i].vy>=0)&&(data->stars[i].y - 16*data->stars[i].vy > info->screen.height))				||(data->stars[i].x < -64)				||(data->stars[i].age>=NCOL)) {			data->stars[i] = data->stars[data->nbStars-1];			data->nbStars--;		}		else ++i;	}}VisualFX flying_star_create(void) {	VisualFX vfx = {		init: fs_init,		free: fs_free,		apply: fs_apply,		fx_data: 0	};	return vfx;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?