Mercurial > audlegacy
annotate audacious/vis.c @ 1429:a360afd8df52 trunk
[svn] Make annoying recursion that consistently returns wrong art, optional.
author | nemo |
---|---|
date | Mon, 24 Jul 2006 16:20:05 -0700 |
parents | 0ee0b9b6db7e |
children | f12d7e208b43 |
rev | line source |
---|---|
0 | 1 /* BMP - Cross-platform multimedia player |
2 * Copyright (C) 2003-2004 BMP development team. | |
3 * | |
4 * Based on XMMS: | |
5 * Copyright (C) 1998-2003 XMMS development team. | |
6 * | |
7 * This program is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or | |
10 * (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with this program; if not, write to the Free Software | |
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
20 */ | |
21 | |
22 #include "vis.h" | |
23 | |
24 #include <glib.h> | |
25 #include <gdk/gdk.h> | |
26 #include <string.h> | |
27 | |
28 #include "main.h" | |
29 #include "skin.h" | |
30 #include "widget.h" | |
31 | |
32 static const gfloat vis_afalloff_speeds[] = { 0.34, 0.5, 1.0, 1.3, 1.6 }; | |
33 static const gfloat vis_pfalloff_speeds[] = { 1.2, 1.3, 1.4, 1.5, 1.6 }; | |
34 static const gint vis_redraw_delays[] = { 1, 2, 4, 8 }; | |
35 static const guint8 vis_scope_colors[] = | |
36 { 21, 21, 20, 20, 19, 19, 18, 19, 19, 20, 20, 21, 21 }; | |
37 | |
38 void | |
39 vis_timeout_func(Vis * vis, guchar * data) | |
40 { | |
41 static GTimer *timer = NULL; | |
42 gulong micros = 9999999; | |
43 gboolean falloff = FALSE; | |
44 gint i; | |
45 | |
46 if (!timer) { | |
47 timer = g_timer_new(); | |
48 g_timer_start(timer); | |
49 } | |
50 else { | |
51 g_timer_elapsed(timer, µs); | |
52 if (micros > 14000) | |
53 g_timer_reset(timer); | |
54 | |
55 } | |
56 | |
57 if (cfg.vis_type == VIS_ANALYZER) { | |
58 if (micros > 14000) | |
59 falloff = TRUE; | |
60 if (data || falloff) { | |
61 for (i = 0; i < 75; i++) { | |
62 if (data && data[i] > vis->vs_data[i]) { | |
63 vis->vs_data[i] = data[i]; | |
64 if (vis->vs_data[i] > vis->vs_peak[i]) { | |
65 vis->vs_peak[i] = vis->vs_data[i]; | |
66 vis->vs_peak_speed[i] = 0.01; | |
67 | |
68 } | |
69 else if (vis->vs_peak[i] > 0.0) { | |
70 vis->vs_peak[i] -= vis->vs_peak_speed[i]; | |
71 vis->vs_peak_speed[i] *= | |
72 vis_pfalloff_speeds[cfg.peaks_falloff]; | |
73 if (vis->vs_peak[i] < vis->vs_data[i]) | |
74 vis->vs_peak[i] = vis->vs_data[i]; | |
75 if (vis->vs_peak[i] < 0.0) | |
76 vis->vs_peak[i] = 0.0; | |
77 } | |
78 } | |
79 else if (falloff) { | |
80 if (vis->vs_data[i] > 0.0) { | |
81 vis->vs_data[i] -= | |
82 vis_afalloff_speeds[cfg.analyzer_falloff]; | |
83 if (vis->vs_data[i] < 0.0) | |
84 vis->vs_data[i] = 0.0; | |
85 } | |
86 if (vis->vs_peak[i] > 0.0) { | |
87 vis->vs_peak[i] -= vis->vs_peak_speed[i]; | |
88 vis->vs_peak_speed[i] *= | |
89 vis_pfalloff_speeds[cfg.peaks_falloff]; | |
90 if (vis->vs_peak[i] < vis->vs_data[i]) | |
91 vis->vs_peak[i] = vis->vs_data[i]; | |
92 if (vis->vs_peak[i] < 0.0) | |
93 vis->vs_peak[i] = 0.0; | |
94 } | |
95 } | |
96 } | |
97 } | |
98 } | |
99 else if (data) { | |
100 for (i = 0; i < 75; i++) | |
101 vis->vs_data[i] = data[i]; | |
102 } | |
103 | |
104 if (micros > 14000) { | |
105 if (!vis->vs_refresh_delay) { | |
106 vis_draw((Widget *) vis); | |
107 vis->vs_refresh_delay = vis_redraw_delays[cfg.vis_refresh]; | |
108 | |
109 } | |
110 vis->vs_refresh_delay--; | |
111 } | |
112 } | |
113 | |
114 void | |
115 vis_draw(Widget * w) | |
116 { | |
117 Vis *vis = (Vis *) w; | |
118 gint x, y, h = 0, h2; | |
119 guchar vis_color[24][3]; | |
120 guchar rgb_data[152 * 32], *ptr, c; | |
121 guint32 colors[24]; | |
122 GdkRgbCmap *cmap; | |
123 | |
124 if (!vis->vs_widget.visible) | |
125 return; | |
126 | |
127 skin_get_viscolor(bmp_active_skin, vis_color); | |
128 for (y = 0; y < 24; y++) { | |
129 colors[y] = | |
130 vis_color[y][0] << 16 | vis_color[y][1] << 8 | vis_color[y][2]; | |
131 } | |
132 cmap = gdk_rgb_cmap_new(colors, 24); | |
133 | |
134 memset(rgb_data, 0, 76 * 16); | |
135 for (y = 1; y < 16; y += 2) { | |
136 ptr = rgb_data + (y * 76); | |
137 for (x = 0; x < 76; x += 2, ptr += 2) | |
138 *ptr = 1; | |
139 } | |
140 if (cfg.vis_type == VIS_ANALYZER) { | |
141 for (x = 0; x < 75; x++) { | |
142 if (cfg.analyzer_type == ANALYZER_BARS && (x % 4) == 0) | |
143 h = vis->vs_data[x >> 2]; | |
144 else if (cfg.analyzer_type == ANALYZER_LINES) | |
145 h = vis->vs_data[x]; | |
146 if (h && (cfg.analyzer_type == ANALYZER_LINES || | |
147 (x % 4) != 3)) { | |
148 ptr = rgb_data + ((16 - h) * 76) + x; | |
149 switch (cfg.analyzer_mode) { | |
150 case ANALYZER_NORMAL: | |
151 for (y = 0; y < h; y++, ptr += 76) | |
152 *ptr = 18 - h + y; | |
153 break; | |
154 case ANALYZER_FIRE: | |
155 for (y = 0; y < h; y++, ptr += 76) | |
156 *ptr = y + 2; | |
157 break; | |
158 case ANALYZER_VLINES: | |
159 for (y = 0; y < h; y++, ptr += 76) | |
160 *ptr = 18 - h; | |
161 break; | |
162 } | |
163 } | |
164 } | |
165 if (cfg.analyzer_peaks) { | |
166 for (x = 0; x < 75; x++) { | |
167 if (cfg.analyzer_type == ANALYZER_BARS && (x % 4) == 0) | |
168 h = vis->vs_peak[x >> 2]; | |
169 else if (cfg.analyzer_type == ANALYZER_LINES) | |
170 h = vis->vs_peak[x]; | |
171 if (h | |
172 && (cfg.analyzer_type == ANALYZER_LINES | |
173 || (x % 4) != 3)) | |
174 rgb_data[(16 - h) * 76 + x] = 23; | |
175 } | |
176 } | |
177 } | |
178 else if (cfg.vis_type == VIS_SCOPE) { | |
179 for (x = 0; x < 75; x++) { | |
180 switch (cfg.scope_mode) { | |
181 case SCOPE_DOT: | |
182 h = vis->vs_data[x]; | |
183 ptr = rgb_data + ((15 - h) * 76) + x; | |
184 *ptr = vis_scope_colors[h]; | |
185 break; | |
186 case SCOPE_LINE: | |
187 if (x != 74) { | |
188 h = 15 - vis->vs_data[x]; | |
189 h2 = 15 - vis->vs_data[x + 1]; | |
190 if (h > h2) { | |
191 y = h; | |
192 h = h2; | |
193 h2 = y; | |
194 } | |
195 ptr = rgb_data + (h * 76) + x; | |
196 for (y = h; y <= h2; y++, ptr += 76) | |
197 *ptr = vis_scope_colors[y - 3]; | |
198 | |
199 } | |
200 else { | |
201 h = 15 - vis->vs_data[x]; | |
202 ptr = rgb_data + (h * 76) + x; | |
203 *ptr = vis_scope_colors[h]; | |
204 } | |
205 break; | |
206 case SCOPE_SOLID: | |
207 h = 15 - vis->vs_data[x]; | |
208 h2 = 9; | |
209 c = vis_scope_colors[(gint) vis->vs_data[x]]; | |
210 if (h > h2) { | |
211 y = h; | |
212 h = h2; | |
213 h2 = y; | |
214 } | |
215 ptr = rgb_data + (h * 76) + x; | |
216 for (y = h; y <= h2; y++, ptr += 76) | |
217 *ptr = c; | |
218 break; | |
219 } | |
220 } | |
221 } | |
222 | |
223 /* FIXME: The check "shouldn't" be neccessary? */ | |
224 /* if (GTK_IS_WINDOW(vis->vs_window)) { */ | |
225 GDK_THREADS_ENTER(); | |
226 gdk_draw_indexed_image(vis->vs_window, vis->vs_widget.gc, | |
227 vis->vs_widget.x, vis->vs_widget.y, | |
228 vis->vs_widget.width, vis->vs_widget.height, | |
229 GDK_RGB_DITHER_NORMAL, (guchar *) rgb_data, | |
230 76, cmap); | |
231 GDK_THREADS_LEAVE(); | |
232 /* } else { | |
233 vis->vs_window = mainwin->window; | |
234 GDK_THREADS_ENTER(); | |
235 gdk_draw_indexed_image(vis->vs_window, vis->vs_widget.gc, | |
236 vis->vs_widget.x, vis->vs_widget.y, | |
237 vis->vs_widget.width, vis->vs_widget.height, | |
238 GDK_RGB_DITHER_NORMAL, (guchar *) rgb_data, | |
239 76, cmap); | |
240 GDK_THREADS_LEAVE(); | |
241 } | |
242 */ | |
243 | |
244 gdk_rgb_cmap_free(cmap); | |
245 } | |
246 | |
247 void | |
248 vis_clear_data(Vis * vis) | |
249 { | |
250 gint i; | |
251 | |
192
0ee0b9b6db7e
[svn] headless now working, use --headless if you wish to experiment.
nenolod
parents:
0
diff
changeset
|
252 if (!vis) |
0ee0b9b6db7e
[svn] headless now working, use --headless if you wish to experiment.
nenolod
parents:
0
diff
changeset
|
253 return; |
0ee0b9b6db7e
[svn] headless now working, use --headless if you wish to experiment.
nenolod
parents:
0
diff
changeset
|
254 |
0 | 255 for (i = 0; i < 75; i++) { |
256 vis->vs_data[i] = (cfg.vis_type == VIS_SCOPE) ? 6 : 0; | |
257 vis->vs_peak[i] = 0; | |
258 } | |
259 } | |
260 | |
261 void | |
262 vis_clear(Vis * vis) | |
263 { | |
264 gdk_window_clear_area(vis->vs_window, vis->vs_widget.x, | |
265 vis->vs_widget.y, vis->vs_widget.width, | |
266 vis->vs_widget.height); | |
267 } | |
268 | |
269 void | |
270 vis_set_window(Vis * vis, GdkWindow * window) | |
271 { | |
272 vis->vs_window = window; | |
273 } | |
274 | |
275 Vis * | |
276 create_vis(GList ** wlist, | |
277 GdkPixmap * parent, | |
278 GdkWindow * window, | |
279 GdkGC * gc, | |
280 gint x, gint y, | |
281 gint width) | |
282 { | |
283 Vis *vis; | |
284 | |
285 vis = g_new0(Vis, 1); | |
286 | |
287 widget_init(&vis->vs_widget, parent, gc, x, y, width, 16, 1); | |
288 widget_list_add(wlist, WIDGET(vis)); | |
289 | |
290 return vis; | |
291 } |