Fix pdbox makefile to actually take part in dependency generation
[kugel-rb.git] / apps / plugins / pdbox / PDa / src / x_qlist.c
blob63825c7dc6d9d09686d8fc6e1ede06070fe09633
1 /* Copyright (c) 1997-1999 Miller Puckette and others.
2 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
3 * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
5 #ifdef ROCKBOX
6 #include "plugin.h"
7 #include "../../pdbox.h"
8 #endif
10 #include "m_pd.h"
12 #ifndef ROCKBOX
13 #include <string.h>
14 #ifdef UNIX
15 #include <unistd.h>
16 #endif
17 #ifdef MSW
18 #include <io.h>
19 #endif
20 #endif /* ROCKBOX */
22 typedef struct _qlist
24 t_object x_ob;
25 t_outlet *x_bangout;
26 void *x_binbuf;
27 int x_onset; /* playback position */
28 t_clock *x_clock;
29 float x_tempo;
30 double x_whenclockset;
31 float x_clockdelay;
32 t_symbol *x_dir;
33 t_canvas *x_canvas;
34 int x_reentered;
35 } t_qlist;
37 static void qlist_tick(t_qlist *x);
39 static t_class *qlist_class;
41 static void *qlist_new( void)
43 #ifndef ROCKBOX
44 t_symbol *name, *filename = 0;
45 #endif
46 t_qlist *x = (t_qlist *)pd_new(qlist_class);
47 x->x_binbuf = binbuf_new();
48 x->x_clock = clock_new(x, (t_method)qlist_tick);
49 outlet_new(&x->x_ob, &s_list);
50 x->x_bangout = outlet_new(&x->x_ob, &s_bang);
51 x->x_onset = 0x7fffffff;
52 x->x_tempo = 1;
53 x->x_whenclockset = 0;
54 x->x_clockdelay = 0;
55 x->x_canvas = canvas_getcurrent();
56 x->x_reentered = 0;
57 return (x);
60 static void qlist_rewind(t_qlist *x)
62 x->x_onset = 0;
63 if (x->x_clock) clock_unset(x->x_clock);
64 x->x_whenclockset = 0;
65 x->x_reentered = 1;
68 static void qlist_donext(t_qlist *x, int drop, int automatic)
70 t_pd *target = 0;
71 while (1)
73 int argc = binbuf_getnatom(x->x_binbuf),
74 count, onset = x->x_onset, onset2, wasreentered;
75 t_atom *argv = binbuf_getvec(x->x_binbuf);
76 t_atom *ap = argv + onset, *ap2;
77 if (onset >= argc) goto end;
78 while (ap->a_type == A_SEMI || ap->a_type == A_COMMA)
80 if (ap->a_type == A_SEMI) target = 0;
81 onset++, ap++;
82 if (onset >= argc) goto end;
85 if (!target && ap->a_type == A_FLOAT)
87 ap2 = ap + 1;
88 onset2 = onset + 1;
89 while (onset2 < argc && ap2->a_type == A_FLOAT)
90 onset2++, ap2++;
91 x->x_onset = onset2;
92 if (automatic)
94 clock_delay(x->x_clock,
95 x->x_clockdelay = ap->a_w.w_float * x->x_tempo);
96 x->x_whenclockset = clock_getsystime();
98 else outlet_list(x->x_ob.ob_outlet, 0, onset2-onset, ap);
99 return;
101 ap2 = ap + 1;
102 onset2 = onset + 1;
103 while (onset2 < argc &&
104 (ap2->a_type == A_FLOAT || ap2->a_type == A_SYMBOL))
105 onset2++, ap2++;
106 x->x_onset = onset2;
107 count = onset2 - onset;
108 if (!target)
110 if (ap->a_type != A_SYMBOL) continue;
111 else if (!(target = ap->a_w.w_symbol->s_thing))
113 error("qlist: %s: no such object", ap->a_w.w_symbol->s_name);
114 continue;
116 ap++;
117 onset++;
118 count--;
119 if (!count)
121 x->x_onset = onset2;
122 continue;
125 wasreentered = x->x_reentered;
126 x->x_reentered = 0;
127 if (!drop)
129 if (ap->a_type == A_FLOAT)
130 typedmess(target, &s_list, count, ap);
131 else if (ap->a_type == A_SYMBOL)
132 typedmess(target, ap->a_w.w_symbol, count-1, ap+1);
134 if (x->x_reentered)
135 return;
136 x->x_reentered = wasreentered;
137 } /* while (1); never falls through */
139 end:
140 x->x_onset = 0x7fffffff;
141 outlet_bang(x->x_bangout);
142 x->x_whenclockset = 0;
145 static void qlist_next(t_qlist *x, t_floatarg drop)
147 qlist_donext(x, drop != 0, 0);
150 static void qlist_bang(t_qlist *x)
152 qlist_rewind(x);
153 qlist_donext(x, 0, 1);
156 static void qlist_tick(t_qlist *x)
158 x->x_whenclockset = 0;
159 qlist_donext(x, 0, 1);
162 static void qlist_add(t_qlist *x, t_symbol *s, int ac, t_atom *av)
164 #ifdef ROCKBOX
165 (void) s;
166 #endif
167 t_atom a;
168 SETSEMI(&a);
169 binbuf_add(x->x_binbuf, ac, av);
170 binbuf_add(x->x_binbuf, 1, &a);
173 static void qlist_add2(t_qlist *x, t_symbol *s, int ac, t_atom *av)
175 #ifdef ROCKBOX
176 (void) s;
177 #endif
178 binbuf_add(x->x_binbuf, ac, av);
181 static void qlist_clear(t_qlist *x)
183 qlist_rewind(x);
184 binbuf_clear(x->x_binbuf);
187 static void qlist_set(t_qlist *x, t_symbol *s, int ac, t_atom *av)
189 qlist_clear(x);
190 qlist_add(x, s, ac, av);
193 static void qlist_read(t_qlist *x, t_symbol *filename, t_symbol *format)
195 int cr = 0;
196 if (!strcmp(format->s_name, "cr"))
197 cr = 1;
198 else if (*format->s_name)
199 error("qlist_read: unknown flag: %s", format->s_name);
201 if (binbuf_read_via_path(x->x_binbuf, filename->s_name,
202 canvas_getdir(x->x_canvas)->s_name, cr))
203 error("%s: read failed", filename->s_name);
204 x->x_onset = 0x7fffffff;
205 x->x_reentered = 1;
208 static void qlist_write(t_qlist *x, t_symbol *filename, t_symbol *format)
210 int cr = 0;
211 char buf[MAXPDSTRING];
212 canvas_makefilename(x->x_canvas, filename->s_name,
213 buf, MAXPDSTRING);
214 if (!strcmp(format->s_name, "cr"))
215 cr = 1;
216 else if (*format->s_name)
217 error("qlist_read: unknown flag: %s", format->s_name);
218 if (binbuf_write(x->x_binbuf, buf, "", cr))
219 error("%s: write failed", filename->s_name);
222 static void qlist_print(t_qlist *x)
224 post("--------- textfile or qlist contents: -----------");
225 binbuf_print(x->x_binbuf);
228 static void qlist_tempo(t_qlist *x, t_float f)
230 float newtempo;
231 if (f < 1e-20) f = 1e-20;
232 else if (f > 1e20) f = 1e20;
233 newtempo = 1./f;
234 if (x->x_whenclockset != 0)
236 float elapsed = clock_gettimesince(x->x_whenclockset);
237 float left = x->x_clockdelay - elapsed;
238 if (left < 0) left = 0;
239 left *= newtempo / x->x_tempo;
240 clock_delay(x->x_clock, left);
242 x->x_tempo = newtempo;
245 static void qlist_free(t_qlist *x)
247 binbuf_free(x->x_binbuf);
248 if (x->x_clock) clock_free(x->x_clock);
251 /* -------------------- textfile ------------------------------- */
253 static t_class *textfile_class;
254 typedef t_qlist t_textfile;
256 static void *textfile_new( void)
258 #ifndef ROCKBOX
259 t_symbol *name, *filename = 0;
260 #endif
261 t_textfile *x = (t_textfile *)pd_new(textfile_class);
262 x->x_binbuf = binbuf_new();
263 outlet_new(&x->x_ob, &s_list);
264 x->x_bangout = outlet_new(&x->x_ob, &s_bang);
265 x->x_onset = 0x7fffffff;
266 x->x_reentered = 0;
267 x->x_tempo = 1;
268 x->x_whenclockset = 0;
269 x->x_clockdelay = 0;
270 x->x_clock = NULL;
271 x->x_canvas = canvas_getcurrent();
272 return (x);
275 static void textfile_bang(t_textfile *x)
277 int argc = binbuf_getnatom(x->x_binbuf),
278 #ifdef ROCKBOX
279 onset = x->x_onset, onset2;
280 #else
281 count, onset = x->x_onset, onset2;
282 #endif
283 t_atom *argv = binbuf_getvec(x->x_binbuf);
284 t_atom *ap = argv + onset, *ap2;
285 while (onset < argc &&
286 (ap->a_type == A_SEMI || ap->a_type == A_COMMA))
287 onset++, ap++;
288 onset2 = onset;
289 ap2 = ap;
290 while (onset2 < argc &&
291 (ap2->a_type != A_SEMI && ap2->a_type != A_COMMA))
292 onset2++, ap2++;
293 if (onset2 > onset)
295 x->x_onset = onset2;
296 if (ap->a_type == A_SYMBOL)
297 outlet_anything(x->x_ob.ob_outlet, ap->a_w.w_symbol,
298 onset2-onset-1, ap+1);
299 else outlet_list(x->x_ob.ob_outlet, 0, onset2-onset, ap);
301 else
303 x->x_onset = 0x7fffffff;
304 outlet_bang(x->x_bangout);
308 static void textfile_rewind(t_qlist *x)
310 x->x_onset = 0;
313 static void textfile_free(t_textfile *x)
315 binbuf_free(x->x_binbuf);
318 /* ---------------- global setup function -------------------- */
320 void x_qlist_setup(void )
322 qlist_class = class_new(gensym("qlist"), (t_newmethod)qlist_new,
323 (t_method)qlist_free, sizeof(t_qlist), 0, 0);
324 class_addmethod(qlist_class, (t_method)qlist_rewind, gensym("rewind"), 0);
325 class_addmethod(qlist_class, (t_method)qlist_next,
326 gensym("next"), A_DEFFLOAT, 0);
327 class_addmethod(qlist_class, (t_method)qlist_set, gensym("set"),
328 A_GIMME, 0);
329 class_addmethod(qlist_class, (t_method)qlist_clear, gensym("clear"), 0);
330 class_addmethod(qlist_class, (t_method)qlist_add, gensym("add"),
331 A_GIMME, 0);
332 class_addmethod(qlist_class, (t_method)qlist_add2, gensym("add2"),
333 A_GIMME, 0);
334 class_addmethod(qlist_class, (t_method)qlist_add, gensym("append"),
335 A_GIMME, 0);
336 class_addmethod(qlist_class, (t_method)qlist_read, gensym("read"),
337 A_SYMBOL, A_DEFSYM, 0);
338 class_addmethod(qlist_class, (t_method)qlist_write, gensym("write"),
339 A_SYMBOL, A_DEFSYM, 0);
340 class_addmethod(qlist_class, (t_method)qlist_print, gensym("print"),
341 A_DEFSYM, 0);
342 class_addmethod(qlist_class, (t_method)qlist_tempo,
343 gensym("tempo"), A_FLOAT, 0);
344 class_addbang(qlist_class, qlist_bang);
346 textfile_class = class_new(gensym("textfile"), (t_newmethod)textfile_new,
347 (t_method)textfile_free, sizeof(t_textfile), 0, 0);
348 class_addmethod(textfile_class, (t_method)textfile_rewind, gensym("rewind"),
350 class_addmethod(textfile_class, (t_method)qlist_set, gensym("set"),
351 A_GIMME, 0);
352 class_addmethod(textfile_class, (t_method)qlist_clear, gensym("clear"), 0);
353 class_addmethod(textfile_class, (t_method)qlist_add, gensym("add"),
354 A_GIMME, 0);
355 class_addmethod(textfile_class, (t_method)qlist_add2, gensym("add2"),
356 A_GIMME, 0);
357 class_addmethod(textfile_class, (t_method)qlist_add, gensym("append"),
358 A_GIMME, 0);
359 class_addmethod(textfile_class, (t_method)qlist_read, gensym("read"),
360 A_SYMBOL, A_DEFSYM, 0);
361 class_addmethod(textfile_class, (t_method)qlist_write, gensym("write"),
362 A_SYMBOL, A_DEFSYM, 0);
363 class_addmethod(textfile_class, (t_method)qlist_print, gensym("print"),
364 A_DEFSYM, 0);
365 class_addbang(textfile_class, textfile_bang);