Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 7 commits
  • 11 files changed
  • 0 comments
  • 1 contributor
12  src/compiler/compiler.c
@@ -188,6 +188,7 @@ static void pfv_bind_callback(void *_sc, struct fpvm_sym *sym, int reg)
188 188
 {
189 189
 	struct compiler_sc *sc = _sc;
190 190
 	struct sym *s = FPVM2SYM(sym);
  191
+	struct sym_stim *r;
191 192
 	int pfv;
192 193
 
193 194
 	pfv = pfv_from_sym(s);
@@ -195,8 +196,8 @@ static void pfv_bind_callback(void *_sc, struct fpvm_sym *sym, int reg)
195 196
 		pfv_update_patch_requires(sc, pfv);
196 197
 		sc->p->pfv_allocation[pfv] = reg;
197 198
 	}
198  
-	if(s->stim_regs)
199  
-		s->stim_regs->pfv = sc->p->perframe_regs+reg;
  199
+	for(r = s->stim; r; r = r->next)
  200
+		r->regs->pfv = sc->p->perframe_regs+reg;
200 201
 }
201 202
 
202 203
 static bool init_pfv(struct compiler_sc *sc)
@@ -269,6 +270,7 @@ static void pvv_bind_callback(void *_sc, struct fpvm_sym *sym, int reg)
269 270
 {
270 271
 	struct compiler_sc *sc = _sc;
271 272
 	struct sym *s = FPVM2SYM(sym);
  273
+	struct sym_stim *r;
272 274
 	int pvv;
273 275
 
274 276
 	pvv = pvv_from_sym(s);
@@ -276,8 +278,8 @@ static void pvv_bind_callback(void *_sc, struct fpvm_sym *sym, int reg)
276 278
 		pvv_update_patch_requires(sc, pvv);
277 279
 		sc->p->pvv_allocation[pvv] = reg;
278 280
 	}
279  
-	if(s->stim_regs)
280  
-		s->stim_regs->pvv = sc->p->pervertex_regs+reg;
  281
+	for(r = s->stim; r; r = r->next)
  282
+		r->regs->pvv = sc->p->pervertex_regs+reg;
281 283
 }
282 284
 
283 285
 static bool init_pvv(struct compiler_sc *sc)
@@ -509,7 +511,9 @@ struct patch *patch_compile(const char *basedir, const char *patch_code,
509 511
 	if(!finalize_pvv(sc)) goto fail;
510 512
 	if(!schedule_pvv(sc)) goto fail;
511 513
 
  514
+#ifndef STANDALONE
512 515
 	symtab_free();
  516
+#endif
513 517
 	stim_db_free(); /* @@@ */
514 518
 
515 519
 	free(sc);
2  src/compiler/idgen
@@ -56,7 +56,7 @@ sed 's/#.*//;/^ *$/d' $1 | LANG=C sort | {
56 56
 	.pfv_idx = $2,
57 57
 	.pvv_idx = $3,
58 58
 	.flags = $flags,
59  
-	.stim_regs = NULL,
  59
+	.stim = NULL,
60 60
 },
61 61
 EOF
62 62
 		i=`expr $i + 1`
14  src/compiler/parser.y
@@ -379,6 +379,7 @@ assignment ::= ident(I) TOK_ASSIGN midi_fn_type(T) TOK_LPAREN ident(D)
379 379
     TOK_RPAREN opt_semi.  {
380 380
 	struct sym *sym = I->sym;
381 381
 	struct stimuli *stim = compiler_get_stimulus(state->comm->u.sc);
  382
+	struct sym_stim *ref;
382 383
 
383 384
 	free(I);
384 385
 	if(sym->flags & SF_LIVE) {
@@ -387,19 +388,22 @@ assignment ::= ident(I) TOK_ASSIGN midi_fn_type(T) TOK_LPAREN ident(D)
387 388
 		free(D);
388 389
 		return;
389 390
 	}
390  
-	if(sym->stim_regs) {
391  
-		FAIL("\"%s\" is already used as control variable",
392  
-		    sym->fpvm_sym.name);
  391
+	ref = malloc(sizeof(struct sym_stim));
  392
+	if(!ref) {
  393
+		FAIL("out of memory");
393 394
 		free(D);
394 395
 		return;
395 396
 	}
396  
-	sym->stim_regs = stim_bind(stim, D->sym, T);
  397
+	ref->regs = stim_bind(stim, D->sym, T);
397 398
 	free(D);
398  
-	if(!sym->stim_regs) {
  399
+	if(!ref->regs) {
399 400
 		FAIL("cannot add stimulus for MIDI input \"%s\"",
400 401
 		    sym->fpvm_sym.name);
401 402
 		return;
402 403
 	}
  404
+	ref->next = sym->stim;
  405
+	sym->stim = ref;
  406
+	sym->flags |= SF_ASSIGNED;
403 407
 }
404 408
 
405 409
 midi_fn_type(T) ::= TOK_RANGE.		{ T = ft_range; }
11  src/compiler/ptest/ptest.c
@@ -366,6 +366,7 @@ static void add_midi(const char *s)
366 366
 static void play_midi(struct patch *patch)
367 367
 {
368 368
 	struct sym *sym;
  369
+	struct sym_stim *r;
369 370
 	float f = 0;
370 371
 
371 372
 	sym = unique(trace_var);
@@ -374,12 +375,13 @@ static void play_midi(struct patch *patch)
374 375
 		    trace_var);
375 376
 		exit(1);
376 377
 	}
377  
-	if (!sym->stim_regs) {
  378
+	if (!sym->stim) {
378 379
 		fprintf(stderr, "\"%s\" is not a control variable\n",
379 380
 		    trace_var);
380 381
 		exit(1);
381 382
 	}
382  
-	sym->stim_regs->pfv = &f;
  383
+	for (r = sym->stim; r; r = r->next)
  384
+		r->regs->pfv = &f;
383 385
 
384 386
 	while (midi) {
385 387
 		stim_midi_ctrl(patch->stim,
@@ -395,12 +397,15 @@ static void compile(const char *pgm)
395 397
 	struct patch *patch;
396 398
 
397 399
 	patch = patch_compile("/", pgm, report);
398  
-	if (!patch)
  400
+	if (!patch) {
  401
+		symtab_free();
399 402
 		exit(1);
  403
+	}
400 404
 	if (!quiet)
401 405
 		show_patch(patch);
402 406
 	if (trace_var)
403 407
 		play_midi(patch);
  408
+	symtab_free();
404 409
 	/*
405 410
 	 * We can't use patch_free here because that function also accesses
406 411
 	 * image data, which isn't available in standalone builds. A simple
22  src/compiler/symtab.c
@@ -107,7 +107,7 @@ struct sym *unique(const char *s)
107 107
 	new->fpvm_sym.name = strdup(s);
108 108
 	new->pfv_idx = new->pvv_idx = -1;
109 109
 	new->flags = 0;
110  
-	new->stim_regs = NULL;
  110
+	new->stim = NULL;
111 111
 	return new;
112 112
 }
113 113
 
@@ -133,7 +133,7 @@ struct sym *unique_n(const char *s, int n)
133 133
 	new->fpvm_sym.name = strdup_n(s, n);
134 134
 	new->pfv_idx = new->pvv_idx = -1;
135 135
 	new->flags = 0;
136  
-	new->stim_regs = NULL;
  136
+	new->stim = NULL;
137 137
 	return new;
138 138
 }
139 139
 
@@ -148,12 +148,28 @@ void symtab_init(void)
148 148
 }
149 149
 
150 150
 
  151
+static void free_stim(struct sym *sym)
  152
+{
  153
+	struct sym_stim *next;
  154
+
  155
+	while(sym->stim) {
  156
+		next = sym->stim->next;
  157
+		free(sym->stim);
  158
+		sym->stim = next;
  159
+	}
  160
+}
  161
+
  162
+
151 163
 void symtab_free(void)
152 164
 {
153 165
 	int i;
154 166
 
155  
-	for(i = 0; i != num_user_syms; i++)
  167
+	for(i = 0; i != num_well_known; i++)
  168
+		free_stim(well_known+i);
  169
+	for(i = 0; i != num_user_syms; i++) {
156 170
 		free((void *) user_syms[i].fpvm_sym.name);
  171
+		free_stim(user_syms+i);
  172
+	}
157 173
 	free(user_syms);
158 174
 	user_syms = NULL;
159 175
 	num_user_syms = allocated = 0;
8  src/compiler/symtab.h
@@ -20,11 +20,15 @@
20 20
 #define	SF_LIVE		(1 << 2)	/* variable is written to by FN */
21 21
 #define	SF_FIXED	(SF_SYSTEM | SF_LIVE)
22 22
 
  23
+struct sym_stim {
  24
+	struct stim_regs *regs;
  25
+	struct sym_stim *next;
  26
+};
  27
+
23 28
 struct sym {
24 29
 	struct fpvm_sym fpvm_sym;
25 30
 	int pfv_idx, pvv_idx;	/* index; -1 if not a variable known to FN */
26  
-	struct stim_regs *stim_regs;
27  
-				/* NULL if not a control variable */
  31
+	struct sym_stim *stim;	/* NULL if not a control variable */
28 32
 	int flags;
29 33
 };
30 34
 
15  src/compiler/test/stimerr
@@ -26,19 +26,4 @@ expect <<EOF
26 26
 line 4: cannot add MIDI input "bar" near '}'
27 27
 EOF
28 28
 
29  
-
30  
-#------------------------------------------------------------------------------
31  
-
32  
-ptest_fail "stimuli, errors: bind control variable twice" -c -q << EOF
33  
-midi "foo" {
34  
-	bar = pot(0);
35  
-}
36  
-
37  
-foo = range(bar);
38  
-foo = range(bar);
39  
-EOF
40  
-expect <<EOF
41  
-line 7: "foo" is already used as control variable near 'EOF'
42  
-EOF
43  
-
44 29
 ###############################################################################
10  src/compiler/test/stimin
@@ -197,5 +197,15 @@ expect <<EOF
197 197
 0
198 198
 EOF
199 199
 
  200
+#------------------------------------------------------------------------------
  201
+
  202
+ptest "stimuli, input, MIDI: test -Wundefined" -c -q -Wundefined <<EOF
  203
+midi "foo" { bar = switch(1, 0); }
  204
+foo = button(bar);
  205
+per_frame:
  206
+	sx = foo;
  207
+EOF
  208
+expect <<EOF
  209
+EOF
200 210
 
201 211
 ###############################################################################
106  src/compiler/test/stimmulti
... ...
@@ -0,0 +1,106 @@
  1
+#!/bin/sh
  2
+. ./Common
  3
+
  4
+###############################################################################
  5
+
  6
+ptest "stimuli, multi: bind control variable twice (same device)" -c -q \
  7
+  -v sx -m 0=0 -m 0=127 -m 1=0 -m 1=127 -m 0=0 << EOF
  8
+midi "foo" {
  9
+	foo = pot(0);
  10
+	bar = pot(1);
  11
+}
  12
+
  13
+sx = range(foo);
  14
+sx = range(bar);
  15
+EOF
  16
+expect <<EOF
  17
+0
  18
+1
  19
+0
  20
+1
  21
+0
  22
+EOF
  23
+
  24
+#------------------------------------------------------------------------------
  25
+
  26
+ptest "stimuli, multi: bind control variable twice (2 devs, same addr)" -c -q \
  27
+  -v sx -m 0=0 -m 0=127 -m 0=0 -m 0=127 -m 0=0 << EOF
  28
+midi "foo" {
  29
+	foo_pot = pot(0);
  30
+}
  31
+
  32
+midi "bar" {
  33
+	bar_pot = pot(0);
  34
+}
  35
+
  36
+sx = range(foo_pot);
  37
+sx = range(bar_pot);
  38
+EOF
  39
+expect <<EOF
  40
+0
  41
+1
  42
+0
  43
+1
  44
+0
  45
+EOF
  46
+
  47
+#------------------------------------------------------------------------------
  48
+
  49
+ptest "stimuli, multi: bind control variable twice (2 devs, diff addr)" -c -q \
  50
+  -v sx -m 0=0 -m 0=127 -m 1=0 -m 1=127 -m 0=0 << EOF
  51
+midi "foo" {
  52
+	foo_pot = pot(0);
  53
+}
  54
+
  55
+midi "bar" {
  56
+	bar_pot = pot(1);
  57
+}
  58
+
  59
+sx = range(foo_pot);
  60
+sx = range(bar_pot);
  61
+EOF
  62
+expect <<EOF
  63
+0
  64
+1
  65
+0
  66
+1
  67
+0
  68
+EOF
  69
+
  70
+#------------------------------------------------------------------------------
  71
+
  72
+ptest "stimuli, multi: bind control element twice (1)" -c -q \
  73
+  -v foo -m 0=0 -m 0=63 -m 0=127 -m 0=0 << EOF
  74
+midi "foo" {
  75
+	bar = pot(0);
  76
+}
  77
+
  78
+foo = range(bar);
  79
+bar = button(bar);
  80
+EOF
  81
+expect <<EOF
  82
+0
  83
+0.496063
  84
+1
  85
+0
  86
+EOF
  87
+
  88
+#------------------------------------------------------------------------------
  89
+
  90
+ptest "stimuli, multi: bind control element twice (2)" -c -q \
  91
+  -v bar -m 0=0 -m 0=63 -m 0=127 -m 0=0 << EOF
  92
+midi "foo" {
  93
+	bar = pot(0);
  94
+}
  95
+
  96
+foo = range(bar);
  97
+bar = button(bar);
  98
+EOF
  99
+expect <<EOF
  100
+0
  101
+0
  102
+1
  103
+0
  104
+EOF
  105
+
  106
+###############################################################################
60  src/renderer/stimuli.c
@@ -101,25 +101,21 @@ static void midi_proc_button_switch(struct s_midi_ctrl *ct, int value)
101 101
 
102 102
 void stim_midi_ctrl(struct stimuli *s, int chan, int ctrl, int value)
103 103
 {
104  
-	struct s_midi_ctrl *ct;
  104
+	struct s_midi_ctrl *ct = NULL;
105 105
 
106 106
 	midi_last[chan][ctrl] = value;
107 107
 
108 108
 	if(!s)
109 109
 		return;
110 110
 
111  
-	if(s->midi[chan]) {
  111
+	if(s->midi[chan])
112 112
 		ct = s->midi[chan]->ctrl[ctrl];
113  
-		if(ct) {
114  
-			ct->proc(ct, value);
115  
-			return;
116  
-		}
117  
-	}
118  
-
119  
-	if(s->midi[0]) {
  113
+	if(!ct && s->midi[0])
120 114
 		ct = s->midi[0]->ctrl[ctrl];
121  
-		if(ct)
122  
-			ct->proc(ct, value);
  115
+
  116
+	while(ct) {
  117
+		ct->proc(ct, value);
  118
+		ct = ct->next;
123 119
 	}
124 120
 }
125 121
 
@@ -142,15 +138,14 @@ static struct stim_regs *stim_add_midi_ctrl(struct stimuli *s, int chan,
142 138
 	}
143 139
 	ch = s->midi[chan];
144 140
 
145  
-	if(!ch->ctrl[ctrl]) {
146  
-		ch->ctrl[ctrl] = calloc(1, sizeof(struct s_midi_ctrl));
147  
-		if(!ch->ctrl[ctrl])
148  
-			return NULL;
149  
-	}
150  
-	ct = ch->ctrl[ctrl];
  141
+	ct = calloc(1, sizeof(struct s_midi_ctrl));
  142
+	if(!ct)
  143
+		return NULL;
151 144
 
152 145
 	ct->proc = proc;
153 146
 	ct->regs.pfv = ct->regs.pvv = NULL;
  147
+	ct->next = ch->ctrl[ctrl];
  148
+	ch->ctrl[ctrl] = ct;
154 149
 
155 150
 	return &ct->regs;
156 151
 }
@@ -176,6 +171,7 @@ struct stimuli *stim_get(struct stimuli *s)
176 171
 
177 172
 void stim_put(struct stimuli *s)
178 173
 {
  174
+	struct s_midi_ctrl **ct, *next;
179 175
 	int i, j;
180 176
 
181 177
 	if(!s)
@@ -184,8 +180,14 @@ void stim_put(struct stimuli *s)
184 180
 		return;
185 181
 	for(i = 0; i != MIDI_CHANS+1; i++)
186 182
 		if(s->midi[i]) {
187  
-			for(j = 0; j != MIDI_CTRLS; j++)
188  
-				free(s->midi[i]->ctrl[j]);
  183
+			for(j = 0; j != MIDI_CTRLS; j++) {
  184
+				ct = s->midi[i]->ctrl+j;
  185
+				while(*ct) {
  186
+					next = (*ct)->next;
  187
+					free(*ct);
  188
+					*ct = next;
  189
+				}
  190
+			}
189 191
 			free(s->midi[i]);
190 192
 		}
191 193
 	free(s);
@@ -216,16 +218,14 @@ void stim_redirect(struct stimuli *s, void *new)
216 218
 	for(i = 0; i != MIDI_CHANS+1; i++) {
217 219
 		if(!s->midi[i])
218 220
 			continue;
219  
-		for(j = 0; j != MIDI_CTRLS; j++) {
220  
-			ct = s->midi[i]->ctrl[j];
221  
-			if (!ct)
222  
-				continue;
223  
-			if(ct->regs.pfv)
224  
-				ct->regs.pfv = (void *) ct->regs.pfv+d;
225  
-			if(ct->regs.pvv)
226  
-				ct->regs.pvv = (void *) ct->regs.pvv+d;
227  
-			reset_control(ct, i, j);
228  
-		}
  221
+		for(j = 0; j != MIDI_CTRLS; j++)
  222
+			for(ct = s->midi[i]->ctrl[j]; ct; ct = ct->next) {
  223
+				if(ct->regs.pfv)
  224
+					ct->regs.pfv = (void *) ct->regs.pfv+d;
  225
+				if(ct->regs.pvv)
  226
+					ct->regs.pvv = (void *) ct->regs.pvv+d;
  227
+				reset_control(ct, i, j);
  228
+			}
229 229
 	}
230 230
 	s->target = new;
231 231
 }
@@ -348,7 +348,7 @@ struct stim_regs *stim_bind(struct stimuli *s, const void *handle,
348 348
 	const struct stim_db_midi_ctrl *ctrl;
349 349
 
350 350
 	for(dev = db; dev; dev = dev->next)
351  
-		for(ctrl = db->ctrls; ctrl; ctrl = ctrl->next)
  351
+		for(ctrl = dev->ctrls; ctrl; ctrl = ctrl->next)
352 352
 			if(ctrl->handle == handle)
353 353
 				return do_bind(s, ctrl, fn);
354 354
 	return NULL;
1  src/renderer/stimuli.h
@@ -43,6 +43,7 @@ struct s_midi_ctrl {
43 43
 	void (*proc)(struct s_midi_ctrl *sct, int value);
44 44
 	struct stim_regs regs;
45 45
 	long last;		/* for midi_proc_diff_* */
  46
+	struct s_midi_ctrl *next;
46 47
 };
47 48
 
48 49
 struct s_midi_chan {

No commit comments for this range

Something went wrong with that request. Please try again.