|
116
|
1 /* Iris - visualization plugin for XMMS
|
|
|
2 * Copyright (C) 2000-2002 Cédric DELFOSSE (cdelfosse@free.fr)
|
|
|
3 *
|
|
|
4 * This program is free software; you can redistribute it and/or modify
|
|
|
5 * it under the terms of the GNU General Public License as published by
|
|
|
6 * the Free Software Foundation; either version 2 of the License, or
|
|
|
7 * (at your option) any later version.
|
|
|
8 *
|
|
|
9 * This program 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
|
|
|
12 * GNU General Public License for more details.
|
|
|
13 *
|
|
|
14 * You should have received a copy of the GNU General Public License
|
|
|
15 * along with this program; if not, write to the Free Software
|
|
|
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
17 */
|
|
|
18
|
|
|
19 #include <stdlib.h>
|
|
|
20 #include <math.h>
|
|
|
21 #include <GL/gl.h>
|
|
|
22 #include <audacious/configdb.h>
|
|
|
23 #include "iris.h"
|
|
|
24
|
|
|
25 GLfloat jump[16] =
|
|
|
26 { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
|
|
27 0.0
|
|
|
28 };
|
|
|
29
|
|
|
30 xz xz1, xz2, xz3, xz4;
|
|
|
31
|
|
|
32 static int draw_mode = 0; // the drawing mode
|
|
|
33
|
|
|
34 static struct
|
|
|
35 {
|
|
|
36 int draw_mode;
|
|
|
37 int angle_step;
|
|
|
38 gboolean wave_on_beat;
|
|
|
39 GLfloat wave_height;
|
|
|
40 int wave_timer;
|
|
|
41 GLfloat radius;
|
|
|
42 GLfloat interband;
|
|
|
43 GLfloat linelength;
|
|
|
44 }
|
|
|
45 conf_private, conf_private_new;
|
|
|
46
|
|
|
47 static config_theme conf = {
|
|
|
48 (config_global *) NULL,
|
|
|
49 &conf_private
|
|
|
50 };
|
|
|
51
|
|
|
52 static config_theme conf_new = {
|
|
|
53 (config_global *) NULL,
|
|
|
54 &conf_private_new
|
|
|
55 };
|
|
|
56
|
|
|
57 static char original_draw_mode[] = "original_draw_mode";
|
|
|
58 static char original_angle_step[] = "original_angle_step";
|
|
|
59 static char original_wave_on_beat[] = "original_wave_on_beat";
|
|
|
60 static char original_wave_height[] = "original_wave_height";
|
|
|
61 static char original_wave_timer[] = "original_wave_timer";
|
|
|
62 static char original_radius[] = "original_radius";
|
|
|
63 static char original_interband[] = "original_interband";
|
|
|
64 static char original_linelength[] = "original_linelength";
|
|
|
65
|
|
|
66 static void config_read (ConfigDb *, char *);
|
|
|
67 static void config_write (ConfigDb *, char *);
|
|
|
68 static void config_default (void);
|
|
|
69 static void config_create (GtkWidget *);
|
|
|
70 static void init_draw_mode (void);
|
|
|
71 static GLfloat get_x_angle (void);
|
|
|
72 static void draw_one_frame (gboolean);
|
|
|
73
|
|
|
74 iris_theme theme_original = {
|
|
|
75 "Original",
|
|
|
76 "A 360 degrees spectrum analyzer",
|
|
|
77 "Cédric Delfosse (cdelfosse@free.fr)",
|
|
|
78 "original",
|
|
|
79 &conf,
|
|
|
80 &conf_new,
|
|
|
81 sizeof (conf_private),
|
|
|
82 config_read,
|
|
|
83 config_write,
|
|
|
84 config_default,
|
|
|
85 config_create,
|
|
|
86 NULL,
|
|
|
87 NULL,
|
|
|
88 init_draw_mode,
|
|
|
89 get_x_angle,
|
|
|
90 draw_one_frame
|
|
|
91 };
|
|
|
92
|
|
|
93
|
|
|
94 static void
|
|
|
95 shift_jump ()
|
|
|
96 {
|
|
|
97 int i;
|
|
|
98
|
|
|
99 for (i = 15; i > 0; i--)
|
|
|
100 jump[i] = jump[i - 1];
|
|
|
101 jump[0] = 0.0;
|
|
|
102 }
|
|
|
103
|
|
|
104
|
|
|
105 static void
|
|
|
106 init_draw_mode ()
|
|
|
107 {
|
|
|
108 draw_mode = 1 + (int) (3.0 * rand () / (RAND_MAX + 1.0));
|
|
|
109 }
|
|
|
110
|
|
|
111
|
|
|
112 static GLfloat
|
|
|
113 get_x_angle ()
|
|
|
114 {
|
|
|
115 if (draw_mode == 3)
|
|
|
116 return (45.0 + (int) (30.0 * rand () / (RAND_MAX + 1.0)));
|
|
|
117 else
|
|
|
118 return (55.0 + (int) (35.0 * rand () / (RAND_MAX + 1.0)));
|
|
|
119 }
|
|
|
120
|
|
|
121
|
|
|
122 static void
|
|
|
123 draw_one_frame (gboolean beat)
|
|
|
124 {
|
|
|
125 static unsigned int cpt = 0;
|
|
|
126 static float a = 1.0;
|
|
|
127 static float b = 1.0;
|
|
|
128 int d = 0;
|
|
|
129 float step;
|
|
|
130 float rad = (float) ((2 * M_PI * d) / 360);
|
|
|
131 float cosv = a * (float) cos (rad);
|
|
|
132 float sinv = b * (float) sin (rad);
|
|
|
133
|
|
|
134 if ((conf_private.wave_on_beat) && (beat))
|
|
|
135 jump[0] = conf_private.wave_height;
|
|
|
136
|
|
|
137
|
|
|
138 glBegin (GL_QUADS);
|
|
|
139 for (d = 0, step = 0; d < 360; d = d + conf_private.angle_step)
|
|
|
140 {
|
|
|
141 int l;
|
|
|
142 float rad2 = (float) ((2 * M_PI * (d + conf_private.angle_step)) / 360);
|
|
|
143 float cosv2 = a * (float) cos (rad2);
|
|
|
144 float sinv2 = b * (float) sin (rad2);
|
|
|
145
|
|
|
146 for (l = 0; l < 16; l++)
|
|
|
147 {
|
|
|
148 int i;
|
|
|
149 GLfloat red, green, blue;
|
|
|
150 xz xz1, xz2, xz3, xz4;
|
|
|
151
|
|
|
152 GLfloat y;
|
|
|
153 GLfloat u = (float) (l * conf_private.interband * cosv);
|
|
|
154 GLfloat v = (float) (l * conf_private.interband * sinv);
|
|
|
155 GLfloat u2 = (float) (l * conf_private.interband * cosv2);
|
|
|
156 GLfloat v2 = (float) (l * conf_private.interband * sinv2);
|
|
|
157
|
|
|
158 xz1.x = u + (conf_private.radius + conf_private.linelength) * cosv;
|
|
|
159 xz1.z = v + (conf_private.radius + conf_private.linelength) * sinv;
|
|
|
160 xz2.x = u + conf_private.radius * cosv;
|
|
|
161 xz2.z = v + conf_private.radius * sinv;
|
|
|
162 xz3.x =
|
|
|
163 u2 + (conf_private.radius + conf_private.linelength) * cosv2;
|
|
|
164 xz3.z =
|
|
|
165 v2 + (conf_private.radius + conf_private.linelength) * sinv2;
|
|
|
166 xz4.x = u2 + conf_private.radius * cosv2;
|
|
|
167 xz4.z = v2 + conf_private.radius * sinv2;
|
|
|
168
|
|
|
169 // calculate the height of the bar
|
|
|
170 // this makes a fade with the past drawn values
|
|
|
171 for (i = 0, y = 0; i < conf_private.angle_step; i++)
|
|
|
172 y += datas.data360[d + i][l];
|
|
|
173 y /= (float) conf_private.angle_step;
|
|
|
174
|
|
|
175 // get the color associated with the height of the bar
|
|
|
176 if (y != 0.0)
|
|
|
177 get_color (&red, &green, &blue, &y);
|
|
|
178 else
|
|
|
179 break; // we draw nothing if the signal is null
|
|
|
180
|
|
|
181 y *= 4; // should be in the config ?
|
|
|
182
|
|
|
183 if (conf_private.wave_on_beat)
|
|
|
184 y += jump[l];
|
|
|
185
|
|
|
186 switch (draw_mode)
|
|
|
187 {
|
|
|
188 case 1:
|
|
|
189 // draw a bar
|
|
|
190 {
|
|
|
191 glColor4f (red / 2, green / 2, blue / 2, 0.3);
|
|
|
192 bar_side (y, &xz1, &xz2);
|
|
|
193 bar_side (y, &xz3, &xz4);
|
|
|
194 bar_side (y, &xz1, &xz3);
|
|
|
195 bar_side (y, &xz2, &xz4);
|
|
|
196 if (jump[l])
|
|
|
197 glColor4f (config.color_flash_red, config.color_flash_green,
|
|
|
198 config.color_flash_blue, 0.3);
|
|
|
199 else
|
|
|
200 glColor4f (red, green, blue, 0.3);
|
|
|
201 bar_top_or_bottom (y, &xz1, &xz2, &xz3, &xz4);
|
|
|
202
|
|
|
203 break;
|
|
|
204 }
|
|
|
205 case 2:
|
|
|
206 // draw only the top of a bar
|
|
|
207 {
|
|
|
208 if (jump[l])
|
|
|
209 glColor4f (config.color_flash_red, config.color_flash_green,
|
|
|
210 config.color_flash_blue, 0.3);
|
|
|
211 else
|
|
|
212 glColor4f (red, green, blue, 0.3);
|
|
|
213 bar_top_or_bottom (y, &xz1, &xz2, &xz3, &xz4);
|
|
|
214
|
|
|
215 break;
|
|
|
216 }
|
|
|
217 case 3:
|
|
|
218 // draw only a side of a bar
|
|
|
219 {
|
|
|
220 if (jump[l])
|
|
|
221 glColor4f (config.color_flash_red, config.color_flash_green,
|
|
|
222 config.color_flash_blue, 0.3);
|
|
|
223 else
|
|
|
224 glColor4f (red, green, blue, 0.3);
|
|
|
225 bar_side (y, &xz3, &xz4);
|
|
|
226
|
|
|
227 break;
|
|
|
228 }
|
|
|
229 case 4:
|
|
|
230 //draw only another side of a bar
|
|
|
231 {
|
|
|
232 if (jump[l])
|
|
|
233 glColor4f (config.color_flash_red, config.color_flash_green,
|
|
|
234 config.color_flash_blue, 0.3);
|
|
|
235 else
|
|
|
236 glColor4f (red, green, blue, 0.3);
|
|
|
237 bar_side (y, &xz1, &xz3);
|
|
|
238
|
|
|
239 break;
|
|
|
240 }
|
|
|
241
|
|
|
242 } // switch
|
|
|
243
|
|
|
244 } // for(l=0
|
|
|
245
|
|
|
246 rad = rad2;
|
|
|
247 cosv = cosv2;
|
|
|
248 sinv = sinv2;
|
|
|
249
|
|
|
250 } // for(d=0
|
|
|
251
|
|
|
252 if (!cpt)
|
|
|
253 {
|
|
|
254 shift_jump ();
|
|
|
255 cpt = conf_private.wave_timer;
|
|
|
256 }
|
|
|
257 cpt--;
|
|
|
258
|
|
|
259 glEnd ();
|
|
|
260
|
|
|
261 }
|
|
|
262
|
|
|
263
|
|
|
264 static void
|
|
|
265 config_read (ConfigDb * db, char *section_name)
|
|
|
266 {
|
|
|
267 bmp_cfg_db_get_int (db, section_name, original_draw_mode, &conf_private.draw_mode);
|
|
|
268 bmp_cfg_db_get_int (db, section_name, original_angle_step, &conf_private.angle_step);
|
|
|
269 bmp_cfg_db_get_bool (db, section_name, original_wave_on_beat, &conf_private.wave_on_beat);
|
|
|
270 bmp_cfg_db_get_float (db, section_name, original_wave_height, &conf_private.wave_height);
|
|
|
271 bmp_cfg_db_get_int (db, section_name, original_wave_timer, &conf_private.wave_timer);
|
|
|
272 bmp_cfg_db_get_float (db, section_name, original_radius, &conf_private.radius);
|
|
|
273 bmp_cfg_db_get_float (db, section_name, original_interband, &conf_private.interband);
|
|
|
274 bmp_cfg_db_get_float (db, section_name, original_linelength, &conf_private.linelength);
|
|
|
275 }
|
|
|
276
|
|
|
277
|
|
|
278 static void
|
|
|
279 config_write (ConfigDb * db, char *section_name)
|
|
|
280 {
|
|
|
281 bmp_cfg_db_set_int (db, section_name, original_draw_mode, conf_private.draw_mode);
|
|
|
282 bmp_cfg_db_set_int (db, section_name, original_angle_step, conf_private.angle_step);
|
|
|
283 bmp_cfg_db_set_bool (db, section_name, original_wave_on_beat, conf_private.wave_on_beat);
|
|
|
284 bmp_cfg_db_set_float (db, section_name, original_wave_height, conf_private.wave_height);
|
|
|
285 bmp_cfg_db_set_int (db, section_name, original_wave_timer, conf_private.wave_timer);
|
|
|
286 bmp_cfg_db_set_float (db, section_name, original_radius, conf_private.radius);
|
|
|
287 bmp_cfg_db_set_float (db, section_name, original_interband, conf_private.interband);
|
|
|
288 bmp_cfg_db_set_float (db, section_name, original_linelength, conf_private.linelength);
|
|
|
289 }
|
|
|
290
|
|
|
291
|
|
|
292 static void
|
|
|
293 config_default ()
|
|
|
294 {
|
|
|
295 conf_private.draw_mode = 2;
|
|
|
296 conf_private.angle_step = 8;
|
|
|
297 conf_private.wave_on_beat = TRUE;
|
|
|
298 conf_private.wave_height = 0.5;
|
|
|
299 conf_private.wave_timer = 5;
|
|
|
300 conf_private.radius = 0.4;
|
|
|
301 conf_private.interband = 0.25;
|
|
|
302 conf_private.linelength = 0.11;
|
|
|
303 }
|
|
|
304
|
|
|
305
|
|
|
306 void
|
|
|
307 jumpbeat_toggled (GtkWidget * widget, gpointer data)
|
|
|
308 {
|
|
|
309 conf_private_new.wave_on_beat = !conf_private_new.wave_on_beat;
|
|
|
310 }
|
|
|
311
|
|
|
312
|
|
|
313 static void
|
|
|
314 value_jump_speed (GtkAdjustment * adj)
|
|
|
315 {
|
|
|
316 conf_private_new.wave_timer = (int) adj->value;
|
|
|
317 }
|
|
|
318
|
|
|
319
|
|
|
320 static void
|
|
|
321 config_create (GtkWidget * vbox)
|
|
|
322 {
|
|
|
323 GtkWidget *hbox;
|
|
|
324 GtkWidget *button;
|
|
|
325 GtkWidget *label;
|
|
|
326 GtkObject *adjustment;
|
|
|
327 GtkWidget *hscale;
|
|
|
328
|
|
|
329 memcpy (&conf_private_new, &conf_private, sizeof (conf_private_new));
|
|
|
330
|
|
|
331 /* wave on beat */
|
|
|
332 hbox = gtk_hbox_new (FALSE, 2);
|
|
|
333 gtk_widget_show (hbox);
|
|
|
334 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 4);
|
|
|
335
|
|
|
336 button = gtk_check_button_new_with_label ("Wave on beats");
|
|
|
337 gtk_widget_show (button);
|
|
|
338 gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 4);
|
|
|
339 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
|
|
|
340 conf_private_new.wave_on_beat);
|
|
|
341 gtk_signal_connect (GTK_OBJECT (button), "toggled",
|
|
|
342 GTK_SIGNAL_FUNC (jumpbeat_toggled), NULL);
|
|
|
343
|
|
|
344 /* number of frame for the wave to propagate */
|
|
|
345 hbox = gtk_hbox_new (FALSE, 2);
|
|
|
346 gtk_widget_show (hbox);
|
|
|
347 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 4);
|
|
|
348
|
|
|
349 label = gtk_label_new ("Wave propagation timer (in frames)");
|
|
|
350 gtk_widget_show (label);
|
|
|
351 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 4);
|
|
|
352
|
|
|
353 hbox = gtk_hbox_new (FALSE, 2);
|
|
|
354 gtk_widget_show (hbox);
|
|
|
355 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 4);
|
|
|
356
|
|
|
357 adjustment =
|
|
|
358 gtk_adjustment_new (conf_private_new.wave_timer, 1, 50, 1, 5, 0);
|
|
|
359 hscale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
|
|
|
360 gtk_scale_set_digits (GTK_SCALE (hscale), 0);
|
|
|
361 gtk_widget_set_usize (GTK_WIDGET (hscale), 200, 25);
|
|
|
362 gtk_box_pack_start (GTK_BOX (hbox), hscale, FALSE, FALSE, 4);
|
|
|
363 gtk_widget_show (hscale);
|
|
|
364 gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
|
|
|
365 GTK_SIGNAL_FUNC (value_jump_speed), NULL);
|
|
|
366 }
|