2 #include "goom_plugin_info.h"
4 #include "goom_config.h"
10 //#define CONV_MOTIF_W 32
11 //#define CONV_MOTIF_WMASK 0x1f
13 #define CONV_MOTIF_W 128
14 #define CONV_MOTIF_WMASK 0x7f
16 typedef char Motif[CONV_MOTIF_W][CONV_MOTIF_W];
18 #include "motif_goom1.h"
19 #include "motif_goom2.h"
25 typedef struct _CONV_DATA
28 PluginParam factor_adj_p;
30 PluginParameters params;
46 /* init rotozoom tables */
48 compute_tables (VisualFX * _this, PluginInfo * info)
50 ConvData *data = (ConvData *) _this->fx_data;
56 if (data->h_height == info->screen.height)
59 screen_coef = 2.0 * 300.0 / (double) info->screen.height;
60 data->h_height = info->screen.height;
62 for (i = 0; i < NB_THETA; i++) {
63 radian = 2 * i * M_PI / NB_THETA;
64 h = (0.2 + cos (radian) / 15.0 * sin (radian * 2.0 + 12.123)) * screen_coef;
65 data->h_cos[i] = 0x10000 * (-h * cos (radian) * cos (radian));
66 data->h_sin[i] = 0x10000 * (h * sin (radian + 1.57) * sin (radian));
71 set_motif (ConvData * data, Motif motif)
75 for (i = 0; i < CONV_MOTIF_W; ++i)
76 for (j = 0; j < CONV_MOTIF_W; ++j)
77 data->conv_motif[i][j] =
78 motif[CONV_MOTIF_W - i - 1][CONV_MOTIF_W - j - 1];
82 convolve_init (VisualFX * _this, PluginInfo * info)
86 data = (ConvData *) malloc (sizeof (ConvData));
87 _this->fx_data = (void *) data;
89 data->light = secure_f_param ("Screen Brightness");
90 data->light.param.fval.max = 300.0f;
91 data->light.param.fval.step = 1.0f;
92 data->light.param.fval.value = 100.0f;
94 data->factor_adj_p = secure_f_param ("Flash Intensity");
95 data->factor_adj_p.param.fval.max = 200.0f;
96 data->factor_adj_p.param.fval.step = 1.0f;
97 data->factor_adj_p.param.fval.value = 70.0f;
99 data->factor_p = secure_f_feedback ("Factor");
101 data->params = plugin_parameters ("Bright Flash", 5);
102 data->params.params[0] = &data->light;
103 data->params.params[1] = &data->factor_adj_p;
104 data->params.params[2] = 0;
105 data->params.params[3] = &data->factor_p;
106 data->params.params[4] = 0;
108 /* init rotozoom tables */
109 compute_tables (_this, info);
112 data->visibility = 1.0;
113 set_motif (data, CONV_MOTIF2);
114 data->inverse_motif = 0;
116 _this->params = &data->params;
120 convolve_free (VisualFX * _this)
122 free (_this->fx_data);
126 create_output_with_brightness (VisualFX * _this, Pixel * src, Pixel * dest,
127 PluginInfo * info, int iff)
129 ConvData *data = (ConvData *) _this->fx_data;
132 int i = 0; //info->screen.height * info->screen.width - 1;
134 const int c = data->h_cos[data->theta];
135 const int s = data->h_sin[data->theta];
137 const int xi = -(info->screen.width / 2) * c;
138 const int yi = (info->screen.width / 2) * s;
140 const int xj = -(info->screen.height / 2) * s;
141 const int yj = -(info->screen.height / 2) * c;
148 if (data->inverse_motif) {
151 for (i = 0; i < 16; ++i)
152 ifftab[i] = (double) iff *(1.0 + data->visibility * (15.0 - i) / 15.0);
156 for (i = 0; i < 16; ++i)
157 ifftab[i] = (double) iff / (1.0 + data->visibility * (15.0 - i) / 15.0);
160 for (y = info->screen.height; y--;) {
163 xtex = xprime + xi + CONV_MOTIF_W * 0x10000 / 2;
166 ytex = yprime + yi + CONV_MOTIF_W * 0x10000 / 2;
170 __asm__ __volatile__ ("\n\t pxor %%mm7, %%mm7" /* mm7 = 0 */
171 "\n\t movd %[xtex], %%mm2" "\n\t movd %[ytex], %%mm3" "\n\t punpckldq %%mm3, %%mm2" /* mm2 = [ ytex | xtex ] */
172 "\n\t movd %[c], %%mm4" "\n\t movd %[s], %%mm6" "\n\t pxor %%mm5, %%mm5" "\n\t psubd %%mm6, %%mm5" "\n\t punpckldq %%mm5, %%mm4" /* mm4 = [ -s | c ] */
173 "\n\t movd %[motif], %%mm6" /* mm6 = motif */
174 ::[xtex] "g" (xtex),[ytex] "g" (ytex)
175 ,[c] "g" (c),[s] "g" (s)
176 ,[motif] "g" (&data->conv_motif[0][0]));
178 for (x = info->screen.width; x--;) {
179 __asm__ __volatile__ ("\n\t movd %[src], %%mm0" /* mm0 = src */
180 "\n\t paddd %%mm4, %%mm2" /* [ ytex | xtex ] += [ -s | s ] */
181 "\n\t movd %%esi, %%mm5" /* save esi into mm5 */
182 "\n\t movq %%mm2, %%mm3" "\n\t psrld $16, %%mm3" /* mm3 = [ (ytex>>16) | (xtex>>16) ] */
183 "\n\t movd %%mm3, %%eax" /* eax = xtex' */
184 "\n\t psrlq $25, %%mm3" "\n\t movd %%mm3, %%ecx" /* ecx = ytex' << 7 */
185 "\n\t andl $127, %%eax" "\n\t andl $16256, %%ecx" "\n\t addl %%ecx, %%eax" "\n\t movd %%mm6, %%esi" /* esi = motif */
186 "\n\t xorl %%ecx, %%ecx" "\n\t movb (%%eax,%%esi), %%cl" "\n\t movl %[ifftab], %%eax" "\n\t movd %%mm5, %%esi" /* restore esi from mm5 */
187 "\n\t movd (%%eax,%%ecx,4), %%mm1" /* mm1 = [0|0|0|iff2] */
188 "\n\t punpcklwd %%mm1, %%mm1"
189 "\n\t punpcklbw %%mm7, %%mm0"
190 "\n\t punpckldq %%mm1, %%mm1"
191 "\n\t psrlw $1, %%mm0"
192 "\n\t psrlw $2, %%mm1"
193 "\n\t pmullw %%mm1, %%mm0"
194 "\n\t psrlw $5, %%mm0"
195 "\n\t packuswb %%mm7, %%mm0"
196 "\n\t movd %%mm0, %[dest]":[dest] "=g" (dest[i].val)
197 :[src] "g" (src[i].val)
198 ,[ifftab] "g" (&ifftab[0])
204 for (x = info->screen.width; x--;) {
207 unsigned int f0, f1, f2, f3;
214 conv_motif[(ytex >> 16) & CONV_MOTIF_WMASK][(xtex >> 16) &
217 #define sat(a) ((a)>0xFF?0xFF:(a))
219 f1 = ((f0 >> R_OFFSET) & 0xFF) * iff2 >> 8;
220 f2 = ((f0 >> G_OFFSET) & 0xFF) * iff2 >> 8;
221 f3 = ((f0 >> B_OFFSET) & 0xFF) * iff2 >> 8;
223 (sat (f1) << R_OFFSET) | (sat (f2) << G_OFFSET) | (sat (f3) <<
226 f0 = (src[i].cop[0] * iff2) >> 8;
227 f1 = (src[i].cop[1] * iff2) >> 8;
228 f2 = (src[i].cop[2] * iff2) >> 8;
229 f3 = (src[i].cop[3] * iff2) >> 8;
231 dest[i].cop[0] = (f0 & 0xffffff00) ? 0xff : (unsigned char)f0;
232 dest[i].cop[1] = (f1 & 0xffffff00) ? 0xff : (unsigned char)f1;
233 dest[i].cop[2] = (f2 & 0xffffff00) ? 0xff : (unsigned char)f2;
234 dest[i].cop[3] = (f3 & 0xffffff00) ? 0xff : (unsigned char)f3;
241 __asm__ __volatile__ ("\n\t emms");
244 compute_tables (_this, info);
248 /*#include <stdint.h>
250 static uint64_t GetTick()
253 asm volatile ("RDTSC" : "=A" (x));
259 convolve_apply (VisualFX * _this, Pixel * src, Pixel * dest, PluginInfo * info)
262 ConvData *data = (ConvData *) _this->fx_data;
266 ff = (FVAL (data->factor_p) * FVAL (data->factor_adj_p) +
267 FVAL (data->light)) / 100.0f;
268 iff = (unsigned int) (ff * 256);
271 double fcycle = (double) info->cycle;
272 double rotate_param, rotate_coef;
273 float INCREASE_RATE = 1.5;
274 float DECAY_RATE = 0.955;
276 if (FVAL (info->sound.last_goom_p) > 0.8)
277 FVAL (data->factor_p) += FVAL (info->sound.goom_power_p) * INCREASE_RATE;
278 FVAL (data->factor_p) *= DECAY_RATE;
280 rotate_param = FVAL (info->sound.last_goom_p);
281 if (rotate_param < 0.0)
283 rotate_param += FVAL (info->sound.goom_power_p);
285 rotate_coef = 4.0 + FVAL (info->sound.goom_power_p) * 6.0;
286 data->ftheta = (data->ftheta + rotate_coef * sin (rotate_param * 6.3));
287 data->theta = ((unsigned int) data->ftheta) % NB_THETA;
289 (cos (fcycle * 0.001 + 1.5) * sin (fcycle * 0.008) +
290 cos (fcycle * 0.011 + 5.0) - 0.8 + info->sound.speedvar) * 1.5;
291 if (data->visibility < 0.0)
292 data->visibility = 0.0;
293 data->factor_p.change_listener (&data->factor_p);
296 if (data->visibility < 0.01) {
297 switch (goom_irand (info->gRandom, 300)) {
299 set_motif (data, CONV_MOTIF1);
300 data->inverse_motif = 1;
303 set_motif (data, CONV_MOTIF2);
304 data->inverse_motif = 0;
309 if ((ff > 0.98f) && (ff < 1.02f))
310 memcpy (dest, src, info->screen.size * sizeof (Pixel));
312 create_output_with_brightness (_this, src, dest, info, iff);
316 uint64_t before, after;
318 static double stimed = 10000.0;
320 data->visibility = 1.0;
321 create_output_with_brightness(_this,src,dest,info,iff);
323 timed = (double)((after-before) / info->screen.size);
324 if (timed < stimed) {
326 printf ("CLK = %3.0f CPP\n", stimed);
333 convolve_create (void)
338 apply:convolve_apply,