Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 8 commits
  • 10 files changed
  • 0 comments
  • 1 contributor
14  patches/demo/pacman/Makefile
... ...
@@ -0,0 +1,14 @@
  1
+.PHONY:		all clean
  2
+
  3
+all:		pacman.jpg ghost.jpg
  4
+
  5
+pacman.jpg:	pacman.xbm
  6
+		xbmtopbm $< | pbmtopgm 1 1 | pgmtoppm yellow-black | \
  7
+		    convert - $@
  8
+
  9
+ghost.jpg:	ghost.xbm
  10
+		xbmtopbm $< | pbmtopgm 1 1 | pgmtoppm magenta-black | \
  11
+		    convert - $@
  12
+
  13
+clean:
  14
+		rm -f pacnman.jpg ghost.jpg
31  patches/demo/pacman/README
... ...
@@ -0,0 +1,31 @@
  1
+The "pacman" patch illustrates the use of images with MIDI controls.
  2
+It also demonstrates the use of image tags.
  3
+
  4
+To install the patch, run "make" (needs netpbm and ImageMagick).
  5
+
  6
+Then upload pacman.fnp and the images with ftp:
  7
+
  8
+ftp milkymist
  9
+ftp> put pacman.fnp
  10
+ftp> put pacman.jpg
  11
+ftp> put ghost.jpg
  12
+ftp> put ../../pleiades.jpg pleiades.jpg
  13
+
  14
+The patch comes with MIDI bindings for the Faderfox LV3:
  15
+
  16
+- left joystick: pacman position
  17
+- right joystick: ghost position
  18
+- fader 1 (leftmost): pacman size
  19
+- fader 2 (rightmost): ghost size
  20
+- green button 1: change pacman to ghost image
  21
+- green button 2: change pacman to Pleiades image
  22
+- green button 8: change ghost to pacman image
  23
+
  24
+The result of an earlier version can be seen here:
  25
+http://www.youtube.com/watch?v=JuSjp_zKarI
  26
+
  27
+The background music in the video is "Over the Edge / Stephanie RMX"
  28
+by BOCrew, licensed under CC-BY:
  29
+
  30
+http://ccmixter.org/content/BOCrew/BOCrew_-_Over_the_Edge_Stephanie_RMX.mp3
  31
+http://ccmixter.org/files/BOCrew/23932
9  patches/demo/pacman/ghost.xbm
... ...
@@ -0,0 +1,9 @@
  1
+#define ghost_width 24
  2
+#define ghost_height 24
  3
+static unsigned char ghost_bits[] = {
  4
+   0xe0, 0xff, 0x07, 0xf8, 0xff, 0x1f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f,
  5
+   0x3e, 0xff, 0x7c, 0x1e, 0x7e, 0x78, 0x0e, 0x3c, 0x70, 0x0f, 0x3c, 0xf0,
  6
+   0x0f, 0x3c, 0xf0, 0x8f, 0x3d, 0xf6, 0x8f, 0x3d, 0xf6, 0x1f, 0x7e, 0xf8,
  7
+   0x3f, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  8
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  9
+   0xcf, 0xcf, 0xe7, 0x87, 0x87, 0xc3, 0x83, 0x83, 0xc1, 0x83, 0x83, 0xc1};
30  experimental/N.fnp → patches/demo/pacman/pacman.fnp
... ...
@@ -1,7 +1,11 @@
1  
-imagefiles=pacman.jpg, ghost.jpg, pleiades.jpg
2  
-decay=0.6
3  
-image1_a=0.6
4  
-image2_a=0.6
  1
+imagefiles =
  2
+   pacman:	pacman.jpg,
  3
+   ghost:	ghost.jpg,
  4
+   pleiades:	pleiades.jpg;
  5
+
  6
+decay = 0.6;
  7
+image1_a = 0.6;
  8
+image2_a = 0.6;
5 9
 
6 10
 midi "Faderfox LV3" {
7 11
 	fad1 = fader(1, 7);
@@ -17,12 +21,12 @@ midi "Faderfox LV3" {
17 21
 	joy2y = pot(10, 2);
18 22
 };
19 23
 
20  
-fad1 = range(fad1);
21  
-fad8 = range(fad8);
  24
+size_pac = range(fad1);
  25
+size_ghost = range(fad8);
22 26
 
23  
-green1 = button(green1);
24  
-green2 = button(green2);
25  
-green8 = button(green8);
  27
+pac_ghost = button(green1);
  28
+pac_stars = button(green2);
  29
+ghost_pac = button(green8);
26 30
 
27 31
 joy1x = range(joy1x);
28 32
 joy1y = range(joy1y);
@@ -30,10 +34,10 @@ joy2x = range(joy2x);
30 34
 joy2y = range(joy2y);
31 35
 
32 36
 per_frame:
33  
-	image1_zoom = fad1*5+0.1;
34  
-	image2_zoom = fad8*6+0.1;
35  
-	image1_index = green1+2*green2;
36  
-	image2_index = !green8;
  37
+	image1_zoom = size_pac*5+0.1;
  38
+	image2_zoom = size_ghost*6+0.1;
  39
+	image1_index = pac_ghost ? ghost : pac_stars ? pleiades : pacman;
  40
+	image2_index = ghost_pac ? pacman : ghost;
37 41
 
38 42
 	sx = 1.06;
39 43
 	sy = 1.06;
9  patches/demo/pacman/pacman.xbm
... ...
@@ -0,0 +1,9 @@
  1
+#define pacman_width 24
  2
+#define pacman_height 24
  3
+static unsigned char pacman_bits[] = {
  4
+   0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xc0, 0xff, 0x01, 0xe0, 0xff, 0x03,
  5
+   0xf0, 0xff, 0x07, 0xf8, 0xff, 0x07, 0xfc, 0xff, 0x03, 0xfe, 0xff, 0x01,
  6
+   0xfe, 0xff, 0x00, 0xfe, 0x3f, 0x00, 0xff, 0x1f, 0x00, 0xff, 0x0f, 0x00,
  7
+   0xff, 0x07, 0x00, 0xff, 0x0f, 0x00, 0xff, 0x1f, 0x00, 0xfe, 0x3f, 0x00,
  8
+   0xfe, 0x7f, 0x00, 0xfe, 0xff, 0x01, 0xfc, 0xff, 0x03, 0xf8, 0xff, 0x07,
  9
+   0xf0, 0xff, 0x07, 0xe0, 0xff, 0x03, 0xc0, 0xff, 0x01, 0x00, 0x3e, 0x00};
24  src/compiler/parser.y
@@ -318,6 +318,10 @@ assignment ::= ident(I) TOK_ASSIGN expr(N) opt_semi. {
318 318
 	 * - must be in the initial section
319 319
 	 * - must not assign to a per-frame system variable
320 320
 	 */
  321
+	if(I->sym->flags & SF_CONST) {
  322
+		FAIL("\"%s\" is a constant", I->sym->fpvm_sym.name);
  323
+		return;
  324
+	}
321 325
 	if(state->comm->assign_per_frame &&
322 326
 	    state->assign != state->comm->assign_per_frame &&
323 327
 	    state->assign != state->comm->assign_per_vertex &&
@@ -416,6 +420,12 @@ assignment ::= ident(I) TOK_ASSIGN midi_fn_type(T) TOK_LPAREN ident(D)
416 420
 	struct stimuli *stim = compiler_get_stimulus(state->comm->u.sc);
417 421
 	struct sym_stim *ref;
418 422
 
  423
+	if(I->sym->flags & SF_CONST) {
  424
+		FAIL("\"%s\" is a constant", I->sym->fpvm_sym.name);
  425
+		free(I);
  426
+		free(D);
  427
+		return;
  428
+	}
419 429
 	free(I);
420 430
 	if(sym->flags & SF_LIVE) {
421 431
 		FAIL("\"%s\" cannot be used as control variable",
@@ -486,6 +496,15 @@ assignment ::= TOK_IMAGEFILES TOK_ASSIGN file_list(L) opt_semi. {
486 496
 			free((void *) msg);
487 497
 			return;
488 498
 		}
  499
+		if(p->tag) {
  500
+			if(p->tag->flags & (SF_ASSIGNED | SF_SYSTEM)) {
  501
+				FAIL("tag \"%s\" is already in use",
  502
+				    p->tag->fpvm_sym.name);
  503
+				return;
  504
+			}
  505
+			p->tag->flags |= SF_ASSIGNED | SF_CONST;
  506
+			p->tag->f = i;
  507
+		}
489 508
 		i++;
490 509
 	}
491 510
 	free_file_list(L);
@@ -756,7 +775,10 @@ primary_expr(N) ::= ident(I). {
756 775
 	    !(I->sym->flags & (SF_SYSTEM | SF_ASSIGNED)))
757 776
 		warn(state, "reading undefined variable %s",
758 777
 		    I->sym->fpvm_sym.name);
759  
-	N = node(I->token, I->sym, NULL, NULL, NULL);
  778
+	if(I->sym->flags & SF_CONST)
  779
+		N = constant(I->sym->f);
  780
+	else
  781
+		N = node(I->token, I->sym, NULL, NULL, NULL);
760 782
 	free(I);
761 783
 }
762 784
 
17  src/compiler/ptest/ptest.c
@@ -30,6 +30,9 @@ static const char *trace_var = NULL;
30 30
 static const char *buffer;
31 31
 
32 32
 
  33
+/* ----- Parse the patch into the AST -------------------------------------- */
  34
+
  35
+
33 36
 static void dump_ast(const struct ast_node *ast);
34 37
 
35 38
 
@@ -257,7 +260,10 @@ static void parse_only(const char *pgm)
257 260
 				printf("\n");
258 261
 				user = 1;
259 262
 			}
260  
-			printf("%s\n", sym->fpvm_sym.name);
  263
+			if (sym->flags & SF_CONST)
  264
+				printf("%s = %g\n", sym->fpvm_sym.name, sym->f);
  265
+			else
  266
+				printf("%s\n", sym->fpvm_sym.name);
261 267
 		}
262 268
 	}
263 269
 	symtab_free();
@@ -270,6 +276,9 @@ static void parse_only(const char *pgm)
270 276
 }
271 277
 
272 278
 
  279
+/* ----- Compile the patch into PFPU code ---------------------------------- */
  280
+
  281
+
273 282
 /*
274 283
  * "sym" and "field" are used to access a field chosen by the caller in the
275 284
  * "struct sym". For this, the caller provides a buffer (sym) and a pointer to
@@ -415,6 +424,9 @@ static void compile(const char *pgm)
415 424
 }
416 425
 
417 426
 
  427
+/* ----- Compile the patch into FPVM code ---------------------------------- */
  428
+
  429
+
418 430
 static const char *assign_raw(struct parser_comm *comm,
419 431
     struct sym *sym, struct ast_node *node)
420 432
 {
@@ -473,6 +485,9 @@ static void compile_vm(const char *pgm)
473 485
 }
474 486
 
475 487
 
  488
+/* ----- Command-line processing ------------------------------------------- */
  489
+
  490
+
476 491
 static void free_buffer(void)
477 492
 {
478 493
 	free((void *) buffer);
2  src/compiler/symtab.h
@@ -18,6 +18,7 @@
18 18
 #define	SF_SYSTEM	(1 << 0)	/* variable is predefined */
19 19
 #define	SF_ASSIGNED	(1 << 1)	/* variable has been assigned to */
20 20
 #define	SF_LIVE		(1 << 2)	/* variable is written to by FN */
  21
+#define	SF_CONST	(1 << 3)	/* "variable" is a constant */
21 22
 #define	SF_FIXED	(SF_SYSTEM | SF_LIVE)
22 23
 
23 24
 struct sym_stim {
@@ -29,6 +30,7 @@ struct sym {
29 30
 	struct fpvm_sym fpvm_sym;
30 31
 	int pfv_idx, pvv_idx;	/* index; -1 if not a variable known to FN */
31 32
 	struct sym_stim *stim;	/* NULL if not a control variable */
  33
+	float f;		/* undefined unless SF_CONST */
32 34
 	int flags;
33 35
 };
34 36
 
111  src/compiler/test/imgtag
... ...
@@ -0,0 +1,111 @@
  1
+#!/bin/sh
  2
+. ./Common
  3
+
  4
+###############################################################################
  5
+
  6
+ptest 'image tags: imagefiles=foo:bar' <<EOF
  7
+imagefiles=foo:bar
  8
+EOF
  9
+expect <<EOF
  10
+image 1 = "bar"
  11
+EOF
  12
+
  13
+#------------------------------------------------------------------------------
  14
+
  15
+ptest 'image tags: imagefiles=foo: bar' <<EOF
  16
+imagefiles=foo: bar
  17
+EOF
  18
+expect <<EOF
  19
+image 1 = "bar"
  20
+EOF
  21
+
  22
+#------------------------------------------------------------------------------
  23
+
  24
+ptest 'image tags: imagefiles=foo:<NL> bar' <<EOF
  25
+imagefiles=foo:
  26
+  bar
  27
+EOF
  28
+expect <<EOF
  29
+image 1 = "bar"
  30
+EOF
  31
+
  32
+#------------------------------------------------------------------------------
  33
+
  34
+ptest 'image tags: imagefiles=foo-:bar' <<EOF
  35
+imagefiles=foo-:bar
  36
+EOF
  37
+expect <<EOF
  38
+image 1 = "foo-:bar"
  39
+EOF
  40
+
  41
+#------------------------------------------------------------------------------
  42
+
  43
+ptest 'image tags: imagefiles=0foo:bar' <<EOF
  44
+imagefiles=0foo:bar
  45
+EOF
  46
+expect <<EOF
  47
+image 1 = "0foo:bar"
  48
+EOF
  49
+
  50
+#------------------------------------------------------------------------------
  51
+
  52
+ptest 'image tags: imagefiles=:bar' <<EOF
  53
+imagefiles=:bar
  54
+EOF
  55
+expect <<EOF
  56
+image 1 = ":bar"
  57
+EOF
  58
+
  59
+#------------------------------------------------------------------------------
  60
+
  61
+ptest_fail 'image tags: imagefiles=a:,b:bar' <<EOF
  62
+imagefiles=a:,b:bar
  63
+EOF
  64
+expect <<EOF
  65
+line 1: scan error near ','
  66
+EOF
  67
+
  68
+#------------------------------------------------------------------------------
  69
+
  70
+ptest_fail 'image tags: imagefiles=a:;' <<EOF
  71
+imagefiles=a:;
  72
+EOF
  73
+expect <<EOF
  74
+line 1: scan error near ';'
  75
+EOF
  76
+
  77
+#------------------------------------------------------------------------------
  78
+
  79
+#
  80
+# We could support this syntax, e.g.,
  81
+# 1) scanning it as tag "a" and name "b:bar", or
  82
+# 2) allowing mutiple tags per file
  83
+# but either case seems a bit far-fetched.
  84
+#
  85
+
  86
+ptest_fail 'image tags: imagefiles=a:b:bar' <<EOF
  87
+imagefiles=a:b:bar
  88
+EOF
  89
+expect <<EOF
  90
+line 1: parse error near 'b'
  91
+EOF
  92
+
  93
+#------------------------------------------------------------------------------
  94
+
  95
+ptest 'image tags: imagefiles=foo:"bar"' <<EOF
  96
+imagefiles=foo:"bar"
  97
+EOF
  98
+expect <<EOF
  99
+image 1 = "bar"
  100
+EOF
  101
+
  102
+#------------------------------------------------------------------------------
  103
+
  104
+ptest 'image tags: imagefiles="bar:x"' <<EOF
  105
+imagefiles="bar:x"
  106
+EOF
  107
+expect <<EOF
  108
+image 1 = "bar:x"
  109
+EOF
  110
+
  111
+###############################################################################
113  src/compiler/test/imgtaguse
... ...
@@ -0,0 +1,113 @@
  1
+#!/bin/sh
  2
+. ./Common
  3
+
  4
+###############################################################################
  5
+
  6
+ptest 'image tags: x,bar:y -> bar = 1' -s <<EOF
  7
+imagefiles=x,bar:y
  8
+EOF
  9
+sedit "/=/p;d"
  10
+expect <<EOF
  11
+image 1 = "x"
  12
+image 2 = "y"
  13
+bar = 1
  14
+EOF
  15
+
  16
+#------------------------------------------------------------------------------
  17
+
  18
+ptest 'image tags: use tag in equation' <<EOF
  19
+imagefiles=x,bar:y
  20
+
  21
+per_frame:
  22
+	foo = bar;
  23
+EOF
  24
+expect <<EOF
  25
+image 1 = "x"
  26
+image 2 = "y"
  27
+per_frame = foo = 1
  28
+EOF
  29
+
  30
+#------------------------------------------------------------------------------
  31
+
  32
+ptest_fail 'image tags: try to use system variable as tag' <<EOF
  33
+imagefiles=sx:foo
  34
+EOF
  35
+expect <<EOF
  36
+image 1 = "foo"
  37
+line 2: tag "sx" is already in use near 'EOF'
  38
+EOF
  39
+
  40
+#------------------------------------------------------------------------------
  41
+
  42
+ptest_fail 'image tags: try to use global user variable as tag' <<EOF
  43
+foo = 0;
  44
+imagefiles=foo:bar
  45
+EOF
  46
+expect <<EOF
  47
+image 1 = "bar"
  48
+line 3: tag "foo" is already in use near 'EOF'
  49
+EOF
  50
+
  51
+#------------------------------------------------------------------------------
  52
+
  53
+#
  54
+# @@@ We should probably simply disallow "imagefiles" in non-global sections.
  55
+#
  56
+
  57
+ptest_fail 'image tags: try to use per-frame variable as tag' <<EOF
  58
+per_frame:
  59
+	foo = 1;
  60
+imagefiles=foo:bar
  61
+EOF
  62
+expect <<EOF
  63
+per_frame = foo = 1
  64
+image 1 = "bar"
  65
+line 4: tag "foo" is already in use near 'EOF'
  66
+EOF
  67
+
  68
+#------------------------------------------------------------------------------
  69
+
  70
+ptest_fail 'image tags: try to use control variable as tag' -c <<EOF
  71
+midi "foo" { bar = fader(0); }
  72
+blah = range(bar);
  73
+imagefiles=blah:bar
  74
+EOF
  75
+expect <<EOF
  76
+line 4: tag "blah" is already in use near 'EOF'
  77
+EOF
  78
+
  79
+#------------------------------------------------------------------------------
  80
+
  81
+ptest_fail 'image tags: try to assign to tag (global)' <<EOF
  82
+imagefiles=foo:bar
  83
+foo = 0;
  84
+EOF
  85
+expect <<EOF
  86
+image 1 = "bar"
  87
+line 3: "foo" is a constant near 'EOF'
  88
+EOF
  89
+
  90
+#------------------------------------------------------------------------------
  91
+
  92
+ptest_fail 'image tags: try to assign to tag (per-frame)' <<EOF
  93
+imagefiles=foo:bar
  94
+per_frame:
  95
+	foo = 1;
  96
+EOF
  97
+expect <<EOF
  98
+image 1 = "bar"
  99
+line 4: "foo" is a constant near 'EOF'
  100
+EOF
  101
+
  102
+#------------------------------------------------------------------------------
  103
+
  104
+ptest_fail 'image tags: try to assign to tag (control variable)' -c <<EOF
  105
+midi "foo" { bar = fader(0); }
  106
+imagefiles=blah:bar
  107
+blah = range(bar);
  108
+EOF
  109
+expect <<EOF
  110
+line 4: "blah" is a constant near 'EOF'
  111
+EOF
  112
+
  113
+###############################################################################

No commit comments for this range

Something went wrong with that request. Please try again.