---
src/Makefile | 6 +-
src/compiler/compiler.c | 793 +++++++++++++++++++++++++++++++++++++++++++++++
src/compiler/compiler.h | 238 ++++++++++++++
src/gui/guirender.c | 2 +-
src/gui/guirender.h | 2 +-
src/gui/patcheditor.c | 2 +-
src/gui/performance.c | 2 +-
src/renderer/compiler.c | 793 -----------------------------------------------
src/renderer/compiler.h | 238 --------------
src/renderer/eval.c | 2 +-
src/renderer/renderer.c | 2 +-
src/renderer/renderer.h | 2 +-
12 files changed, 1041 insertions(+), 1041 deletions(-)
create mode 100644 src/compiler/compiler.c
create mode 100644 src/compiler/compiler.h
delete mode 100644 src/renderer/compiler.c
delete mode 100644 src/renderer/compiler.h
diff --git a/src/Makefile b/src/Makefile
index c34a254..d96d028 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -53,10 +53,10 @@ ifeq ($(WITH_PDF),1)
endif
OBJS += $(addprefix translations/,french.o german.o)
OBJS += $(addprefix renderer/,framedescriptor.o analyzer.o sampler.o \
- compiler.o eval.o line.o wave.o font.o osd.o raster.o renderer.o \
+ eval.o line.o wave.o font.o osd.o raster.o renderer.o \
videoinreconf.o)
-OBJS += $(addprefix compiler/,fpvm.o parser_helper.o scanner.o parser.o \
- unique.o)
+OBJS += $(addprefix compiler/,compiler.o fpvm.o parser_helper.o scanner.o \
+ parser.o unique.o)
POBJS=$(addprefix $(OBJDIR)/,$(OBJS))
diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c
new file mode 100644
index 0000000..d745d63
--- /dev/null
+++ b/src/compiler/compiler.c
@@ -0,0 +1,793 @@
+/*
+ * Flickernoise
+ * Copyright (C) 2010, 2011 Sebastien Bourdeauducq
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <fpvm/fpvm.h>
+#include <fpvm/schedulers.h>
+#include <fpvm/pfpu.h>
+
+#include "../pixbuf/pixbuf.h"
+#include "compiler.h"
+
+struct compiler_sc {
+ struct patch *p;
+
+ const char *basedir;
+ report_message rmc;
+ int linenr;
+
+ struct fpvm_fragment pfv_fragment;
+ struct fpvm_fragment pvv_fragment;
+};
+
+static void comp_report(struct compiler_sc *sc, const char *format, ...)
+{
+ va_list args;
+ int len;
+ char outbuf[512];
+
+ va_start(args, format);
+ len = vsnprintf(outbuf, sizeof(outbuf), format, args);
+ va_end(args);
+ sc->rmc(outbuf);
+}
+
+/****************************************************************/
+/* PER-FRAME VARIABLES */
+/****************************************************************/
+
+static const char pfv_names[COMP_PFV_COUNT][FPVM_MAXSYMLEN] = {
+ "sx",
+ "sy",
+ "cx",
+ "cy",
+ "rot",
+ "dx",
+ "dy",
+ "zoom",
+ "decay",
+ "wave_mode",
+ "wave_scale",
+ "wave_additive",
+ "wave_usedots",
+ "wave_brighten",
+ "wave_thick",
+ "wave_x",
+ "wave_y",
+ "wave_r",
+ "wave_g",
+ "wave_b",
+ "wave_a",
+
+ "ob_size",
+ "ob_r",
+ "ob_g",
+ "ob_b",
+ "ob_a",
+ "ib_size",
+ "ib_r",
+ "ib_g",
+ "ib_b",
+ "ib_a",
+
+ "nMotionVectorsX",
+ "nMotionVectorsY",
+ "mv_dx",
+ "mv_dy",
+ "mv_l",
+ "mv_r",
+ "mv_g",
+ "mv_b",
+ "mv_a",
+
+ "bTexWrap",
+
+ "time",
+ "bass",
+ "mid",
+ "treb",
+ "bass_att",
+ "mid_att",
+ "treb_att",
+
+ "warp",
+ "fWarpAnimSpeed",
+ "fWarpScale",
+
+ "q1",
+ "q2",
+ "q3",
+ "q4",
+ "q5",
+ "q6",
+ "q7",
+ "q8",
+
+ "fVideoEchoAlpha",
+ "fVideoEchoZoom",
+ "nVideoEchoOrientation",
+
+ "dmx1",
+ "dmx2",
+ "dmx3",
+ "dmx4",
+ "dmx5",
+ "dmx6",
+ "dmx7",
+ "dmx8",
+
+ "idmx1",
+ "idmx2",
+ "idmx3",
+ "idmx4",
+ "idmx5",
+ "idmx6",
+ "idmx7",
+ "idmx8",
+
+ "osc1",
+ "osc2",
+ "osc3",
+ "osc4",
+
+ "midi1",
+ "midi2",
+ "midi3",
+ "midi4",
+ "midi5",
+ "midi6",
+ "midi7",
+ "midi8",
+
+ "video_a",
+
+ "image1_a",
+ "image1_x",
+ "image1_y",
+ "image1_zoom",
+ "image2_a",
+ "image2_x",
+ "image2_y",
+ "image2_zoom"
+};
+
+static int pfv_from_name(const char *name)
+{
+ int i;
+
+ for(i=0;i<COMP_PFV_COUNT;i++) {
+ if(strcmp(pfv_names[i], name) == 0)
+ return i;
+ }
+
+ if(strcmp(name, "fDecay") == 0) return pfv_decay;
+ if(strcmp(name, "nWaveMode") == 0) return pfv_wave_mode;
+ if(strcmp(name, "fWaveScale") == 0) return pfv_wave_scale;
+ if(strcmp(name, "bAdditiveWaves") == 0) return pfv_wave_additive;
+ if(strcmp(name, "bWaveDots") == 0) return pfv_wave_usedots;
+ if(strcmp(name, "bMaximizeWaveColor") == 0) return pfv_wave_brighten;
+ if(strcmp(name, "bWaveThick") == 0) return pfv_wave_thick;
+ if(strcmp(name, "fWaveAlpha") == 0) return pfv_wave_a;
+ return -1;
+}
+
+static void pfv_update_patch_requires(struct compiler_sc *sc, int pfv)
+{
+ if(pfv >= pfv_dmx1 && pfv <= pfv_idmx8) sc->p->require |=
REQUIRE_DMX;
+ if(pfv >= pfv_osc1 && pfv <= pfv_osc4) sc->p->require |=
REQUIRE_OSC;
+ if(pfv >= pfv_midi1 && pfv <= pfv_midi8) sc->p->require |=
REQUIRE_MIDI;
+ if(pfv == pfv_video_a) sc->p->require |=
REQUIRE_VIDEO;
+}
+
+static void load_defaults(struct compiler_sc *sc)
+{
+ int i;
+
+ for(i=0;i<COMP_PFV_COUNT;i++)
+ sc->p->pfv_initial[i] = 0.0;
+ sc->p->pfv_initial[pfv_sx] = 1.0;
+ sc->p->pfv_initial[pfv_sy] = 1.0;
+ sc->p->pfv_initial[pfv_cx] = 0.5;
+ sc->p->pfv_initial[pfv_cy] = 0.5;
+ sc->p->pfv_initial[pfv_zoom] = 1.0;
+ sc->p->pfv_initial[pfv_decay] = 1.0;
+ sc->p->pfv_initial[pfv_wave_mode] = 1.0;
+ sc->p->pfv_initial[pfv_wave_scale] = 1.0;
+ sc->p->pfv_initial[pfv_wave_r] = 1.0;
+ sc->p->pfv_initial[pfv_wave_g] = 1.0;
+ sc->p->pfv_initial[pfv_wave_b] = 1.0;
+ sc->p->pfv_initial[pfv_wave_a] = 1.0;
+ sc->p->pfv_initial[pfv_wave_x] = 0.5;
+ sc->p->pfv_initial[pfv_wave_y] = 0.5;
+
+ sc->p->pfv_initial[pfv_mv_x] = 16.0;
+ sc->p->pfv_initial[pfv_mv_y] = 12.0;
+ sc->p->pfv_initial[pfv_mv_dx] = 0.02;
+ sc->p->pfv_initial[pfv_mv_dy] = 0.02;
+ sc->p->pfv_initial[pfv_mv_l] = 1.0;
+
+ sc->p->pfv_initial[pfv_warp_scale] = 1.0;
+
+ sc->p->pfv_initial[pfv_video_echo_zoom] = 1.0;
+
+ sc->p->pfv_initial[pfv_image1_x] = 0.5;
+ sc->p->pfv_initial[pfv_image1_y] = 0.5;
+ sc->p->pfv_initial[pfv_image1_zoom] = 1.0;
+ sc->p->pfv_initial[pfv_image2_x] = 0.5;
+ sc->p->pfv_initial[pfv_image2_y] = 0.5;
+ sc->p->pfv_initial[pfv_image2_zoom] = 1.0;
+}
+
+static void set_initial(struct compiler_sc *sc, int pfv, float x)
+{
+ sc->p->pfv_initial[pfv] = x;
+}
+
+static void initial_to_pfv(struct compiler_sc *sc, int pfv)
+{
+ int r;
+
+ r = sc->p->pfv_allocation[pfv];
+ if(r < 0) return;
+ sc->p->perframe_regs[r] = sc->p->pfv_initial[pfv];
+}
+
+static void all_initials_to_pfv(struct compiler_sc *sc)
+{
+ int i;
+ for(i=0;i<COMP_PFV_COUNT;i++)
+ initial_to_pfv(sc, i);
+}
+
+static void pfv_bind_callback(void *_sc, const char *sym, int reg)
+{
+ struct compiler_sc *sc = _sc;
+ int pfv;
+
+ pfv = pfv_from_name(sym);
+ if(pfv >= 0) {
+ pfv_update_patch_requires(sc, pfv);
+ sc->p->pfv_allocation[pfv] = reg;
+ }
+}
+
+static bool init_pfv(struct compiler_sc *sc)
+{
+ int i;
+
+ fpvm_init(&sc->pfv_fragment, 0);
+ fpvm_set_bind_mode(&sc->pfv_fragment, FPVM_BIND_ALL);
+ for(i=0;i<COMP_PFV_COUNT;i++)
+ sc->p->pfv_allocation[i] = -1;
+ fpvm_set_bind_callback(&sc->pfv_fragment, pfv_bind_callback, sc);
+ return true;
+}
+
+static bool finalize_pfv(struct compiler_sc *sc)
+{
+ /* assign dummy values for output */
+ if(!fpvm_assign(&sc->pfv_fragment, "_Xo", "_Xi")) goto fail_fpvm;
+ if(!fpvm_assign(&sc->pfv_fragment, "_Yo", "_Yi")) goto fail_fpvm;
+ if(!fpvm_finalize(&sc->pfv_fragment)) goto fail_fpvm;
+ #ifdef COMP_DEBUG
+ printf("per-frame FPVM fragment:\n");
+ fpvm_dump(&sc->pfv_fragment);
+ #endif
+
+ return true;
+fail_fpvm:
+ comp_report(sc, "failed to finalize per-frame variables: %s",
fpvm_get_last_error(&sc->pfv_fragment));
+ return false;
+}
+
+static bool schedule_pfv(struct compiler_sc *sc)
+{
+ sc->p->perframe_prog_length = fpvm_default_schedule(&sc->pfv_fragment,
+ (unsigned int *)sc->p->perframe_prog, (unsigned int
*)sc->p->perframe_regs);
+ if(sc->p->perframe_prog_length < 0) {
+ comp_report(sc, "per-frame VLIW scheduling failed");
+ return false;
+ }
+ all_initials_to_pfv(sc);
+ #ifdef COMP_DEBUG
+ printf("per-frame PFPU fragment:\n");
+ pfpu_dump(sc->p->perframe_prog, sc->p->perframe_prog_length);
+ #endif
+
+ return true;
+}
+
+static bool add_per_frame(struct compiler_sc *sc, char *dest, char *val)
+{
+ if(!fpvm_assign(&sc->pfv_fragment, dest, val)) {
+ comp_report(sc, "failed to add per-frame equation l. %d: %s",
sc->linenr, fpvm_get_last_error(&sc->pfv_fragment));
+ return false;
+ }
+ return true;
+}
+
+/****************************************************************/
+/* PER-VERTEX VARIABLES */
+/****************************************************************/
+
+static const char pvv_names[COMP_PVV_COUNT][FPVM_MAXSYMLEN] = {
+ /* System */
+ "_texsize",
+ "_hmeshsize",
+ "_vmeshsize",
+
+ /* MilkDrop */
+ "sx",
+ "sy",
+ "cx",
+ "cy",
+ "rot",
+ "dx",
+ "dy",
+ "zoom",
+
+ "time",
+ "bass",
+ "mid",
+ "treb",
+ "bass_att",
+ "mid_att",
+ "treb_att",
+
+ "warp",
+ "fWarpAnimSpeed",
+ "fWarpScale",
+
+ "q1",
+ "q2",
+ "q3",
+ "q4",
+ "q5",
+ "q6",
+ "q7",
+ "q8",
+
+ "idmx1",
+ "idmx2",
+ "idmx3",
+ "idmx4",
+ "idmx5",
+ "idmx6",
+ "idmx7",
+ "idmx8",
+
+ "osc1",
+ "osc2",
+ "osc3",
+ "osc4",
+
+ "midi1",
+ "midi2",
+ "midi3",
+ "midi4",
+ "midi5",
+ "midi6",
+ "midi7",
+ "midi8",
+};
+
+static int pvv_from_name(const char *name)
+{
+ int i;
+
+ for(i=0;i<COMP_PVV_COUNT;i++) {
+ if(strcmp(pvv_names[i], name) == 0)
+ return i;
+ }
+ return -1;
+}
+
+static void pvv_update_patch_requires(struct compiler_sc *sc, int pvv)
+{
+ if(pvv >= pvv_idmx1 && pvv <= pvv_idmx8) sc->p->require |=
REQUIRE_DMX;
+ if(pvv >= pvv_osc1 && pvv <= pvv_osc4) sc->p->require |=
REQUIRE_OSC;
+ if(pvv >= pvv_midi1 && pvv <= pvv_midi8) sc->p->require |=
REQUIRE_MIDI;
+}
+
+static void pvv_bind_callback(void *_sc, const char *sym, int reg)
+{
+ struct compiler_sc *sc = _sc;
+ int pvv;
+
+ pvv = pvv_from_name(sym);
+ if(pvv >= 0) {
+ pvv_update_patch_requires(sc, pvv);
+ sc->p->pvv_allocation[pvv] = reg;
+ }
+}
+
+static bool init_pvv(struct compiler_sc *sc)
+{
+ int i;
+
+ fpvm_init(&sc->pvv_fragment, 1);
+ for(i=0;i<COMP_PVV_COUNT;i++)
+ sc->p->pvv_allocation[i] = -1;
+ fpvm_set_bind_callback(&sc->pvv_fragment, pvv_bind_callback, sc);
+
+ fpvm_set_bind_mode(&sc->pvv_fragment, FPVM_BIND_SOURCE);
+ #define A(dest, val) if(!fpvm_assign(&sc->pvv_fragment, dest, val))
goto fail_assign
+ A("x", "i2f(_Xi)*_hmeshsize");
+ A("y", "i2f(_Yi)*_vmeshsize");
+ A("rad", "sqrt(sqr(x-0.5)+sqr(y-0.5))");
+ /* TODO: generate ang */
+ #undef A
+ fpvm_set_bind_mode(&sc->pvv_fragment, FPVM_BIND_ALL);
+
+ return true;
+
+fail_assign:
+ comp_report(sc, "failed to add equation to per-vertex header: %s",
fpvm_get_last_error(&sc->pvv_fragment));
+ return false;
+}
+
+static int finalize_pvv(struct compiler_sc *sc)
+{
+ fpvm_set_bind_mode(&sc->pvv_fragment, FPVM_BIND_SOURCE);
+
+ #define A(dest, val) if(!fpvm_assign(&sc->pvv_fragment, dest, val))
goto fail_assign
+
+ /* Zoom */
+ A("_invzoom", "1/zoom");
+ A("_xz", "_invzoom*(x-0.5)+0.5");
+ A("_yz", "_invzoom*(y-0.5)+0.5");
+
+ /* Scale */
+ A("_xs", "(_xz-cx)/sx+cx");
+ A("_ys", "(_yz-cy)/sy+cy");
+
+ /* Warp */
+ A("_warptime", "time*fWarpAnimSpeed");
+ A("_invwarpscale", "1/fWarpScale");
+ A("_f0", "11.68 + 4.0*cos(_warptime*1.413 + 10)");
+ A("_f1", "8.77 + 3.0*cos(_warptime*1.113 + 7)");
+ A("_f2", "10.54 + 3.0*cos(_warptime*1.233 + 3)");
+ A("_f3", "11.49 + 4.0*cos(_warptime*0.933 + 5)");
+ A("_ox2", "2*x-1");
+ A("_oy2", "2*y-1");
+ A("_xw", "_xs+warp*0.0035*("
+ "sin(_warptime*0.333+_invwarpscale*(_ox2*_f0-_oy2*_f3))"
+ "+cos(_warptime*0.753-_invwarpscale*(_ox2*_f1-_oy2*_f2)))");
+ A("_yw", "_ys+warp*0.0035*("
+ "cos(_warptime*0.375-_invwarpscale*(_ox2*_f2+_oy2*_f1))"
+ "+sin(_warptime*0.825+_invwarpscale*(_ox2*_f0+_oy2*_f3)))");
+
+ /* Rotate */
+ A("_cosr", "cos(rot)");
+ A("_sinr", "sin(0-rot)");
+ A("_u", "_xw-cx");
+ A("_v", "_yw-cy");
+ A("_xr", "_u*_cosr-_v*_sinr+cx");
+ A("_yr", "_u*_sinr+_v*_cosr+cy");
+
+ /* Translate */
+ A("_xd", "_xr-dx");
+ A("_yd", "_yr-dy");
+
+ /* Convert to framebuffer coordinates */
+ A("_Xo", "f2i(_xd*_texsize)");
+ A("_Yo", "f2i(_yd*_texsize)");
+
+ #undef A
+
+ if(!fpvm_finalize(&sc->pvv_fragment)) goto fail_finalize;
+ #ifdef COMP_DEBUG
+ printf("per-vertex FPVM fragment:\n");
+ fpvm_dump(&sc->pvv_fragment);
+ #endif
+
+ return true;
+fail_assign:
+ comp_report(sc, "failed to add equation to per-vertex footer: %s",
fpvm_get_last_error(&sc->pvv_fragment));
+ return false;
+fail_finalize:
+ comp_report(sc, "failed to finalize per-vertex variables: %s",
fpvm_get_last_error(&sc->pvv_fragment));
+ return false;
+}
+
+static bool schedule_pvv(struct compiler_sc *sc)
+{
+ sc->p->pervertex_prog_length = fpvm_default_schedule(&sc->pvv_fragment,
+ (unsigned int *)sc->p->pervertex_prog, (unsigned int
*)sc->p->pervertex_regs);
+ if(sc->p->pervertex_prog_length < 0) {
+ comp_report(sc, "per-vertex VLIW scheduling failed");
+ return false;
+ }
+ #ifdef COMP_DEBUG
+ printf("per-vertex PFPU fragment:\n");
+ pfpu_dump(sc->p->pervertex_prog, sc->p->pervertex_prog_length);
+ #endif
+
+ return true;
+}
+
+static bool add_per_vertex(struct compiler_sc *sc, char *dest, char *val)
+{
+ if(!fpvm_assign(&sc->pvv_fragment, dest, val)) {
+ comp_report(sc, "failed to add per-vertex equation l. %d:
%s\n", sc->linenr, fpvm_get_last_error(&sc->pvv_fragment));
+ return false;
+ }
+ return true;
+}
+
+/****************************************************************/
+/* PARSING */
+/****************************************************************/
+
+static bool process_equation(struct compiler_sc *sc, char *equation, bool
per_vertex)
+{
+ char *c, *c2;
+
+ c = strchr(equation, '=');
+ if(!c) {
+ comp_report(sc, "error l.%d: malformed equation (%s)",
sc->linenr, equation);
+ return false;
+ }
+ *c = 0;
+
+ if(*equation == 0) {
+ comp_report(sc, "error l.%d: missing lvalue", sc->linenr);
+ return false;
+ }
+ c2 = c - 1;
+ while((c2 > equation) && (*c2 == ' ')) *c2-- = 0;
+
+ c++;
+ while(*c == ' ') c++;
+
+ if(*equation == 0) {
+ comp_report(sc, "error l.%d: missing lvalue", sc->linenr);
+ return false;
+ }
+ if(*c == 0) {
+ comp_report(sc, "error l.%d: missing rvalue", sc->linenr);
+ return false;
+ }
+
+ if(per_vertex)
+ return add_per_vertex(sc, equation, c);
+ else
+ return add_per_frame(sc, equation, c);
+}
+
+static bool process_equations(struct compiler_sc *sc, char *equations, bool
per_vertex)
+{
+ char *c;
+
+ while(*equations) {
+ c = strchr(equations, ';');
+ if(!c)
+ return process_equation(sc, equations, per_vertex);
+ *c = 0;
+ if(!process_equation(sc, equations, per_vertex)) return false;
+ equations = c + 1;
+ }
+ return true;
+}
+
+static bool process_top_assign(struct compiler_sc *sc, char *left, char *right)
+{
+ int pfv;
+
+ while(*right == ' ') right++;
+ if(*right == 0) return true;
+
+ if(strncmp(left, "imagefile", 9) == 0) {
+ int image_n;
+ char *totalname;
+
+ image_n = atoi(left+9);
+ if((image_n < 1) || (image_n > IMAGE_COUNT)) {
+ comp_report(sc, "warning l.%d: ignoring image with out
of bounds number %d", sc->linenr, image_n);
+ return true;
+ }
+ image_n--;
+ if(right[0] == '/')
+ totalname = strdup(right);
+ else {
+ totalname = malloc(strlen(sc->basedir) + strlen(right)
+ 0);
+ if(totalname == NULL) return true;
+ strcpy(totalname, sc->basedir);
+ strcat(totalname, right);
+ }
+ pixbuf_dec_ref(sc->p->images[image_n]);
+ sc->p->images[image_n] = pixbuf_get(totalname);
+ free(totalname);
+ return true;
+ }
+
+ pfv = pfv_from_name(left);
+ if(pfv >= 0) {
+ /* patch initial condition or global parameter */
+ pfv_update_patch_requires(sc, pfv);
+ set_initial(sc, pfv, atof(right));
+ return true;
+ }
+
+ if(strncmp(left, "per_frame", 9) == 0)
+ /* per-frame equation */
+ return process_equations(sc, right, false);
+
+ if((strncmp(left, "per_vertex", 10) == 0) || (strncmp(left,
"per_pixel", 9) == 0))
+ /* per-vertex equation */
+ return process_equations(sc, right, true);
+
+ comp_report(sc, "warning l.%d: ignoring unknown parameter %s",
sc->linenr, left);
+
+ return true;
+}
+
+static bool process_line(struct compiler_sc *sc, char *line)
+{
+ char *c;
+
+ while(*line == ' ') line++;
+ if(*line == 0) return true;
+ if(*line == '[') return true;
+
+ c = strstr(line, "//");
+ if(c) *c = 0;
+
+ c = line + strlen(line) - 1;
+ while((c >= line) && (*c == ' ')) *c-- = 0;
+ if(*line == 0) return true;
+
+ c = strchr(line, '=');
+ if(!c) {
+ comp_report(sc, "error l.%d: '=' expected", sc->linenr);
+ return false;
+ }
+ *c = 0;
+ return process_top_assign(sc, line, c+1);
+}
+
+static bool parse_patch(struct compiler_sc *sc, char *patch_code)
+{
+ char *eol;
+
+ while(*patch_code) {
+ sc->linenr++;
+ eol = strchr(patch_code, '\n');
+ if(!eol) {
+ if(!process_line(sc, patch_code))
+ return false;
+ else
+ return true;
+ }
+ *eol = 0;
+ if(*patch_code == 0) {
+ patch_code = eol + 1;
+ continue;
+ }
+ if(*(eol - 1) == '\r') *(eol - 1) = 0;
+ if(!process_line(sc, patch_code))
+ return false;
+ patch_code = eol + 1;
+ }
+
+ return true;
+}
+
+struct patch *patch_compile(const char *basedir, const char *patch_code,
report_message rmc)
+{
+ struct compiler_sc *sc;
+ struct patch *p;
+ char *patch_code_copy;
+ int i;
+
+ sc = malloc(sizeof(struct compiler_sc));
+ if(sc == NULL) {
+ rmc("Failed to allocate memory for compiler internal data");
+ return NULL;
+ }
+ p = sc->p = malloc(sizeof(struct patch));
+ if(sc->p == NULL) {
+ rmc("Failed to allocate memory for patch");
+ free(sc);
+ return NULL;
+ }
+ for(i=0;i<IMAGE_COUNT;i++)
+ sc->p->images[i] = NULL;
+ sc->p->require = 0;
+ sc->p->original = NULL;
+ sc->p->next = NULL;
+
+ sc->basedir = basedir;
+ sc->rmc = rmc;
+ sc->linenr = 0;
+
+ load_defaults(sc);
+ if(!init_pfv(sc)) goto fail;
+ if(!init_pvv(sc)) goto fail;
+
+ patch_code_copy = strdup(patch_code);
+ if(patch_code_copy == NULL) {
+ rmc("Failed to allocate memory for patch code");
+ goto fail;
+ }
+ if(!parse_patch(sc, patch_code_copy)) {
+ free(patch_code_copy);
+ goto fail;
+ }
+ free(patch_code_copy);
+
+ if(!finalize_pfv(sc)) goto fail;
+ if(!schedule_pfv(sc)) goto fail;
+ if(!finalize_pvv(sc)) goto fail;
+ if(!schedule_pvv(sc)) goto fail;
+
+ free(sc);
+ return p;
+fail:
+ free(sc->p);
+ free(sc);
+ return NULL;
+}
+
+struct patch *patch_compile_filename(const char *filename, const char
*patch_code, report_message rmc)
+{
+ char *basedir;
+ char *c;
+ struct patch *p;
+
+ basedir = strdup(filename);
+ if(basedir == NULL) return NULL;
+ c = strrchr(basedir, '/');
+ if(c != NULL) {
+ c++;
+ *c = 0;
+ p = patch_compile(basedir, patch_code, rmc);
+ } else
+ p = patch_compile("/", patch_code, rmc);
+ free(basedir);
+ return p;
+}
+
+struct patch *patch_copy(struct patch *p)
+{
+ struct patch *new_patch;
+ int i;
+
+ new_patch = malloc(sizeof(struct patch));
+ assert(new_patch != NULL);
+ memcpy(new_patch, p, sizeof(struct patch));
+ new_patch->original = p;
+ new_patch->next = NULL;
+ for(i=0;i<IMAGE_COUNT;i++)
+ pixbuf_inc_ref(new_patch->images[i]);
+ return new_patch;
+}
+
+void patch_free(struct patch *p)
+{
+ int i;
+
+ for(i=0;i<IMAGE_COUNT;i++)
+ pixbuf_dec_ref(p->images[i]);
+ free(p);
+}
diff --git a/src/compiler/compiler.h b/src/compiler/compiler.h
new file mode 100644
index 0000000..46e62a1
--- /dev/null
+++ b/src/compiler/compiler.h
@@ -0,0 +1,238 @@
+/*
+ * Flickernoise
+ * Copyright (C) 2010, 2011 Sebastien Bourdeauducq
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __COMPILER_H
+#define __COMPILER_H
+
+#include <rtems.h>
+#include <bsp/milkymist_pfpu.h>
+
+#include "../renderer/framedescriptor.h"
+#include "../pixbuf/pixbuf.h"
+
+enum {
+ pfv_sx = 0,
+ pfv_sy,
+ pfv_cx,
+ pfv_cy,
+ pfv_rot,
+ pfv_dx,
+ pfv_dy,
+ pfv_zoom,
+ pfv_decay,
+ pfv_wave_mode,
+ pfv_wave_scale,
+ pfv_wave_additive,
+ pfv_wave_usedots,
+ pfv_wave_brighten,
+ pfv_wave_thick,
+ pfv_wave_x,
+ pfv_wave_y,
+ pfv_wave_r,
+ pfv_wave_g,
+ pfv_wave_b,
+ pfv_wave_a,
+
+ pfv_ob_size,
+ pfv_ob_r,
+ pfv_ob_g,
+ pfv_ob_b,
+ pfv_ob_a,
+ pfv_ib_size,
+ pfv_ib_r,
+ pfv_ib_g,
+ pfv_ib_b,
+ pfv_ib_a,
+
+ pfv_mv_x,
+ pfv_mv_y,
+ pfv_mv_dx,
+ pfv_mv_dy,
+ pfv_mv_l,
+ pfv_mv_r,
+ pfv_mv_g,
+ pfv_mv_b,
+ pfv_mv_a,
+
+ pfv_tex_wrap,
+
+ pfv_time,
+ pfv_bass,
+ pfv_mid,
+ pfv_treb,
+ pfv_bass_att,
+ pfv_mid_att,
+ pfv_treb_att,
+
+ pfv_warp,
+ pfv_warp_anim_speed,
+ pfv_warp_scale,
+
+ pfv_q1,
+ pfv_q2,
+ pfv_q3,
+ pfv_q4,
+ pfv_q5,
+ pfv_q6,
+ pfv_q7,
+ pfv_q8,
+
+ pfv_video_echo_alpha,
+ pfv_video_echo_zoom,
+ pfv_video_echo_orientation,
+
+ pfv_dmx1,
+ pfv_dmx2,
+ pfv_dmx3,
+ pfv_dmx4,
+ pfv_dmx5,
+ pfv_dmx6,
+ pfv_dmx7,
+ pfv_dmx8,
+
+ pfv_idmx1,
+ pfv_idmx2,
+ pfv_idmx3,
+ pfv_idmx4,
+ pfv_idmx5,
+ pfv_idmx6,
+ pfv_idmx7,
+ pfv_idmx8,
+
+ pfv_osc1,
+ pfv_osc2,
+ pfv_osc3,
+ pfv_osc4,
+
+ pfv_midi1,
+ pfv_midi2,
+ pfv_midi3,
+ pfv_midi4,
+ pfv_midi5,
+ pfv_midi6,
+ pfv_midi7,
+ pfv_midi8,
+
+ pfv_video_a,
+
+ pfv_image1_a,
+ pfv_image1_x,
+ pfv_image1_y,
+ pfv_image1_zoom,
+ pfv_image2_a,
+ pfv_image2_x,
+ pfv_image2_y,
+ pfv_image2_zoom,
+
+ COMP_PFV_COUNT /* must be last */
+};
+
+enum {
+ /* System */
+ pvv_texsize,
+ pvv_hmeshsize,
+ pvv_vmeshsize,
+
+ /* MilkDrop */
+ pvv_sx,
+ pvv_sy,
+ pvv_cx,
+ pvv_cy,
+ pvv_rot,
+ pvv_dx,
+ pvv_dy,
+ pvv_zoom,
+
+ pvv_time,
+ pvv_bass,
+ pvv_mid,
+ pvv_treb,
+ pvv_bass_att,
+ pvv_mid_att,
+ pvv_treb_att,
+
+ pvv_warp,
+ pvv_warp_anim_speed,
+ pvv_warp_scale,
+
+ pvv_q1,
+ pvv_q2,
+ pvv_q3,
+ pvv_q4,
+ pvv_q5,
+ pvv_q6,
+ pvv_q7,
+ pvv_q8,
+
+ pvv_idmx1,
+ pvv_idmx2,
+ pvv_idmx3,
+ pvv_idmx4,
+ pvv_idmx5,
+ pvv_idmx6,
+ pvv_idmx7,
+ pvv_idmx8,
+
+ pvv_osc1,
+ pvv_osc2,
+ pvv_osc3,
+ pvv_osc4,
+
+ pvv_midi1,
+ pvv_midi2,
+ pvv_midi3,
+ pvv_midi4,
+ pvv_midi5,
+ pvv_midi6,
+ pvv_midi7,
+ pvv_midi8,
+
+ COMP_PVV_COUNT /* must be last */
+};
+
+#define REQUIRE_DMX (1 << 0)
+#define REQUIRE_OSC (1 << 1)
+#define REQUIRE_MIDI (1 << 2)
+#define REQUIRE_VIDEO (1 << 3)
+
+struct patch {
+ /* per-frame */
+ struct pixbuf *images[IMAGE_COUNT]; /* < images used in
this patch */
+ float pfv_initial[COMP_PFV_COUNT]; /* < patch initial
conditions */
+ int pfv_allocation[COMP_PFV_COUNT]; /* < where per-frame
variables are mapped in PFPU regf, -1 if unmapped */
+ int perframe_prog_length; /* < how many
instructions in perframe_prog */
+ unsigned int perframe_prog[PFPU_PROGSIZE]; /* < PFPU per-frame
microcode */
+ float perframe_regs[PFPU_REG_COUNT]; /* < PFPU initial
per-frame regf */
+ /* per-vertex */
+ int pvv_allocation[COMP_PVV_COUNT]; /* < where per-vertex
variables are mapped in PFPU regf, -1 if unmapped */
+ int pervertex_prog_length; /* < how many
instructions in pervertex_prog */
+ unsigned int pervertex_prog[PFPU_PROGSIZE]; /* < PFPU per-vertex
microcode */
+ float pervertex_regs[PFPU_REG_COUNT]; /* < PFPU initial
per-vertex regf */
+ /* meta */
+ unsigned int require; /* < bitmask: dmx, osc,
midi, video */
+ void *original; /* < original patch
(with initial register values) */
+ struct patch *next; /* < used when chaining
patches in mashups */
+};
+
+typedef void (*report_message)(const char *);
+
+struct patch *patch_compile(const char *basedir, const char *patch_code,
report_message rmc);
+struct patch *patch_compile_filename(const char *filename, const char
*patch_code, report_message rmc);
+struct patch *patch_copy(struct patch *p);
+void patch_free(struct patch *p);
+
+#endif /* __COMPILER_H */
diff --git a/src/gui/guirender.c b/src/gui/guirender.c
index 0f1d63a..e91982a 100644
--- a/src/gui/guirender.c
+++ b/src/gui/guirender.c
@@ -25,7 +25,7 @@
#include <mtkeycodes.h>
#include <bsp/milkymist_video.h>
-#include "../renderer/compiler.h"
+#include "../compiler/compiler.h"
#include "../renderer/renderer.h"
#include "resmgr.h"
#include "../fb.h"
diff --git a/src/gui/guirender.h b/src/gui/guirender.h
index f6f4b1f..13f5483 100644
--- a/src/gui/guirender.h
+++ b/src/gui/guirender.h
@@ -18,7 +18,7 @@
#ifndef __GUIRENDER_H
#define __GUIRENDER_H
-#include "../renderer/compiler.h"
+#include "../compiler/compiler.h"
typedef void (*guirender_stop_callback)();
diff --git a/src/gui/patcheditor.c b/src/gui/patcheditor.c
index 049486f..7f232cc 100644
--- a/src/gui/patcheditor.c
+++ b/src/gui/patcheditor.c
@@ -27,7 +27,7 @@
#include "filedialog.h"
#include "patcheditor.h"
#include "../renderer/framedescriptor.h"
-#include "../renderer/compiler.h"
+#include "../compiler/compiler.h"
#include "../input.h"
#include "guirender.h"
diff --git a/src/gui/performance.c b/src/gui/performance.c
index 8813d3a..da751d0 100644
--- a/src/gui/performance.c
+++ b/src/gui/performance.c
@@ -33,7 +33,7 @@
#include "../fb.h"
#include "messagebox.h"
#include "../config.h"
-#include "../renderer/compiler.h"
+#include "../compiler/compiler.h"
#include "../renderer/renderer.h"
#include "guirender.h"
#include "performance.h"
diff --git a/src/renderer/compiler.c b/src/renderer/compiler.c
deleted file mode 100644
index d745d63..0000000
--- a/src/renderer/compiler.c
+++ /dev/null
@@ -1,793 +0,0 @@
-/*
- * Flickernoise
- * Copyright (C) 2010, 2011 Sebastien Bourdeauducq
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <assert.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-
-#include <fpvm/fpvm.h>
-#include <fpvm/schedulers.h>
-#include <fpvm/pfpu.h>
-
-#include "../pixbuf/pixbuf.h"
-#include "compiler.h"
-
-struct compiler_sc {
- struct patch *p;
-
- const char *basedir;
- report_message rmc;
- int linenr;
-
- struct fpvm_fragment pfv_fragment;
- struct fpvm_fragment pvv_fragment;
-};
-
-static void comp_report(struct compiler_sc *sc, const char *format, ...)
-{
- va_list args;
- int len;
- char outbuf[512];
-
- va_start(args, format);
- len = vsnprintf(outbuf, sizeof(outbuf), format, args);
- va_end(args);
- sc->rmc(outbuf);
-}
-
-/****************************************************************/
-/* PER-FRAME VARIABLES */
-/****************************************************************/
-
-static const char pfv_names[COMP_PFV_COUNT][FPVM_MAXSYMLEN] = {
- "sx",
- "sy",
- "cx",
- "cy",
- "rot",
- "dx",
- "dy",
- "zoom",
- "decay",
- "wave_mode",
- "wave_scale",
- "wave_additive",
- "wave_usedots",
- "wave_brighten",
- "wave_thick",
- "wave_x",
- "wave_y",
- "wave_r",
- "wave_g",
- "wave_b",
- "wave_a",
-
- "ob_size",
- "ob_r",
- "ob_g",
- "ob_b",
- "ob_a",
- "ib_size",
- "ib_r",
- "ib_g",
- "ib_b",
- "ib_a",
-
- "nMotionVectorsX",
- "nMotionVectorsY",
- "mv_dx",
- "mv_dy",
- "mv_l",
- "mv_r",
- "mv_g",
- "mv_b",
- "mv_a",
-
- "bTexWrap",
-
- "time",
- "bass",
- "mid",
- "treb",
- "bass_att",
- "mid_att",
- "treb_att",
-
- "warp",
- "fWarpAnimSpeed",
- "fWarpScale",
-
- "q1",
- "q2",
- "q3",
- "q4",
- "q5",
- "q6",
- "q7",
- "q8",
-
- "fVideoEchoAlpha",
- "fVideoEchoZoom",
- "nVideoEchoOrientation",
-
- "dmx1",
- "dmx2",
- "dmx3",
- "dmx4",
- "dmx5",
- "dmx6",
- "dmx7",
- "dmx8",
-
- "idmx1",
- "idmx2",
- "idmx3",
- "idmx4",
- "idmx5",
- "idmx6",
- "idmx7",
- "idmx8",
-
- "osc1",
- "osc2",
- "osc3",
- "osc4",
-
- "midi1",
- "midi2",
- "midi3",
- "midi4",
- "midi5",
- "midi6",
- "midi7",
- "midi8",
-
- "video_a",
-
- "image1_a",
- "image1_x",
- "image1_y",
- "image1_zoom",
- "image2_a",
- "image2_x",
- "image2_y",
- "image2_zoom"
-};
-
-static int pfv_from_name(const char *name)
-{
- int i;
-
- for(i=0;i<COMP_PFV_COUNT;i++) {
- if(strcmp(pfv_names[i], name) == 0)
- return i;
- }
-
- if(strcmp(name, "fDecay") == 0) return pfv_decay;
- if(strcmp(name, "nWaveMode") == 0) return pfv_wave_mode;
- if(strcmp(name, "fWaveScale") == 0) return pfv_wave_scale;
- if(strcmp(name, "bAdditiveWaves") == 0) return pfv_wave_additive;
- if(strcmp(name, "bWaveDots") == 0) return pfv_wave_usedots;
- if(strcmp(name, "bMaximizeWaveColor") == 0) return pfv_wave_brighten;
- if(strcmp(name, "bWaveThick") == 0) return pfv_wave_thick;
- if(strcmp(name, "fWaveAlpha") == 0) return pfv_wave_a;
- return -1;
-}
-
-static void pfv_update_patch_requires(struct compiler_sc *sc, int pfv)
-{
- if(pfv >= pfv_dmx1 && pfv <= pfv_idmx8) sc->p->require |=
REQUIRE_DMX;
- if(pfv >= pfv_osc1 && pfv <= pfv_osc4) sc->p->require |=
REQUIRE_OSC;
- if(pfv >= pfv_midi1 && pfv <= pfv_midi8) sc->p->require |=
REQUIRE_MIDI;
- if(pfv == pfv_video_a) sc->p->require |=
REQUIRE_VIDEO;
-}
-
-static void load_defaults(struct compiler_sc *sc)
-{
- int i;
-
- for(i=0;i<COMP_PFV_COUNT;i++)
- sc->p->pfv_initial[i] = 0.0;
- sc->p->pfv_initial[pfv_sx] = 1.0;
- sc->p->pfv_initial[pfv_sy] = 1.0;
- sc->p->pfv_initial[pfv_cx] = 0.5;
- sc->p->pfv_initial[pfv_cy] = 0.5;
- sc->p->pfv_initial[pfv_zoom] = 1.0;
- sc->p->pfv_initial[pfv_decay] = 1.0;
- sc->p->pfv_initial[pfv_wave_mode] = 1.0;
- sc->p->pfv_initial[pfv_wave_scale] = 1.0;
- sc->p->pfv_initial[pfv_wave_r] = 1.0;
- sc->p->pfv_initial[pfv_wave_g] = 1.0;
- sc->p->pfv_initial[pfv_wave_b] = 1.0;
- sc->p->pfv_initial[pfv_wave_a] = 1.0;
- sc->p->pfv_initial[pfv_wave_x] = 0.5;
- sc->p->pfv_initial[pfv_wave_y] = 0.5;
-
- sc->p->pfv_initial[pfv_mv_x] = 16.0;
- sc->p->pfv_initial[pfv_mv_y] = 12.0;
- sc->p->pfv_initial[pfv_mv_dx] = 0.02;
- sc->p->pfv_initial[pfv_mv_dy] = 0.02;
- sc->p->pfv_initial[pfv_mv_l] = 1.0;
-
- sc->p->pfv_initial[pfv_warp_scale] = 1.0;
-
- sc->p->pfv_initial[pfv_video_echo_zoom] = 1.0;
-
- sc->p->pfv_initial[pfv_image1_x] = 0.5;
- sc->p->pfv_initial[pfv_image1_y] = 0.5;
- sc->p->pfv_initial[pfv_image1_zoom] = 1.0;
- sc->p->pfv_initial[pfv_image2_x] = 0.5;
- sc->p->pfv_initial[pfv_image2_y] = 0.5;
- sc->p->pfv_initial[pfv_image2_zoom] = 1.0;
-}
-
-static void set_initial(struct compiler_sc *sc, int pfv, float x)
-{
- sc->p->pfv_initial[pfv] = x;
-}
-
-static void initial_to_pfv(struct compiler_sc *sc, int pfv)
-{
- int r;
-
- r = sc->p->pfv_allocation[pfv];
- if(r < 0) return;
- sc->p->perframe_regs[r] = sc->p->pfv_initial[pfv];
-}
-
-static void all_initials_to_pfv(struct compiler_sc *sc)
-{
- int i;
- for(i=0;i<COMP_PFV_COUNT;i++)
- initial_to_pfv(sc, i);
-}
-
-static void pfv_bind_callback(void *_sc, const char *sym, int reg)
-{
- struct compiler_sc *sc = _sc;
- int pfv;
-
- pfv = pfv_from_name(sym);
- if(pfv >= 0) {
- pfv_update_patch_requires(sc, pfv);
- sc->p->pfv_allocation[pfv] = reg;
- }
-}
-
-static bool init_pfv(struct compiler_sc *sc)
-{
- int i;
-
- fpvm_init(&sc->pfv_fragment, 0);
- fpvm_set_bind_mode(&sc->pfv_fragment, FPVM_BIND_ALL);
- for(i=0;i<COMP_PFV_COUNT;i++)
- sc->p->pfv_allocation[i] = -1;
- fpvm_set_bind_callback(&sc->pfv_fragment, pfv_bind_callback, sc);
- return true;
-}
-
-static bool finalize_pfv(struct compiler_sc *sc)
-{
- /* assign dummy values for output */
- if(!fpvm_assign(&sc->pfv_fragment, "_Xo", "_Xi")) goto fail_fpvm;
- if(!fpvm_assign(&sc->pfv_fragment, "_Yo", "_Yi")) goto fail_fpvm;
- if(!fpvm_finalize(&sc->pfv_fragment)) goto fail_fpvm;
- #ifdef COMP_DEBUG
- printf("per-frame FPVM fragment:\n");
- fpvm_dump(&sc->pfv_fragment);
- #endif
-
- return true;
-fail_fpvm:
- comp_report(sc, "failed to finalize per-frame variables: %s",
fpvm_get_last_error(&sc->pfv_fragment));
- return false;
-}
-
-static bool schedule_pfv(struct compiler_sc *sc)
-{
- sc->p->perframe_prog_length = fpvm_default_schedule(&sc->pfv_fragment,
- (unsigned int *)sc->p->perframe_prog, (unsigned int
*)sc->p->perframe_regs);
- if(sc->p->perframe_prog_length < 0) {
- comp_report(sc, "per-frame VLIW scheduling failed");
- return false;
- }
- all_initials_to_pfv(sc);
- #ifdef COMP_DEBUG
- printf("per-frame PFPU fragment:\n");
- pfpu_dump(sc->p->perframe_prog, sc->p->perframe_prog_length);
- #endif
-
- return true;
-}
-
-static bool add_per_frame(struct compiler_sc *sc, char *dest, char *val)
-{
- if(!fpvm_assign(&sc->pfv_fragment, dest, val)) {
- comp_report(sc, "failed to add per-frame equation l. %d: %s",
sc->linenr, fpvm_get_last_error(&sc->pfv_fragment));
- return false;
- }
- return true;
-}
-
-/****************************************************************/
-/* PER-VERTEX VARIABLES */
-/****************************************************************/
-
-static const char pvv_names[COMP_PVV_COUNT][FPVM_MAXSYMLEN] = {
- /* System */
- "_texsize",
- "_hmeshsize",
- "_vmeshsize",
-
- /* MilkDrop */
- "sx",
- "sy",
- "cx",
- "cy",
- "rot",
- "dx",
- "dy",
- "zoom",
-
- "time",
- "bass",
- "mid",
- "treb",
- "bass_att",
- "mid_att",
- "treb_att",
-
- "warp",
- "fWarpAnimSpeed",
- "fWarpScale",
-
- "q1",
- "q2",
- "q3",
- "q4",
- "q5",
- "q6",
- "q7",
- "q8",
-
- "idmx1",
- "idmx2",
- "idmx3",
- "idmx4",
- "idmx5",
- "idmx6",
- "idmx7",
- "idmx8",
-
- "osc1",
- "osc2",
- "osc3",
- "osc4",
-
- "midi1",
- "midi2",
- "midi3",
- "midi4",
- "midi5",
- "midi6",
- "midi7",
- "midi8",
-};
-
-static int pvv_from_name(const char *name)
-{
- int i;
-
- for(i=0;i<COMP_PVV_COUNT;i++) {
- if(strcmp(pvv_names[i], name) == 0)
- return i;
- }
- return -1;
-}
-
-static void pvv_update_patch_requires(struct compiler_sc *sc, int pvv)
-{
- if(pvv >= pvv_idmx1 && pvv <= pvv_idmx8) sc->p->require |=
REQUIRE_DMX;
- if(pvv >= pvv_osc1 && pvv <= pvv_osc4) sc->p->require |=
REQUIRE_OSC;
- if(pvv >= pvv_midi1 && pvv <= pvv_midi8) sc->p->require |=
REQUIRE_MIDI;
-}
-
-static void pvv_bind_callback(void *_sc, const char *sym, int reg)
-{
- struct compiler_sc *sc = _sc;
- int pvv;
-
- pvv = pvv_from_name(sym);
- if(pvv >= 0) {
- pvv_update_patch_requires(sc, pvv);
- sc->p->pvv_allocation[pvv] = reg;
- }
-}
-
-static bool init_pvv(struct compiler_sc *sc)
-{
- int i;
-
- fpvm_init(&sc->pvv_fragment, 1);
- for(i=0;i<COMP_PVV_COUNT;i++)
- sc->p->pvv_allocation[i] = -1;
- fpvm_set_bind_callback(&sc->pvv_fragment, pvv_bind_callback, sc);
-
- fpvm_set_bind_mode(&sc->pvv_fragment, FPVM_BIND_SOURCE);
- #define A(dest, val) if(!fpvm_assign(&sc->pvv_fragment, dest, val))
goto fail_assign
- A("x", "i2f(_Xi)*_hmeshsize");
- A("y", "i2f(_Yi)*_vmeshsize");
- A("rad", "sqrt(sqr(x-0.5)+sqr(y-0.5))");
- /* TODO: generate ang */
- #undef A
- fpvm_set_bind_mode(&sc->pvv_fragment, FPVM_BIND_ALL);
-
- return true;
-
-fail_assign:
- comp_report(sc, "failed to add equation to per-vertex header: %s",
fpvm_get_last_error(&sc->pvv_fragment));
- return false;
-}
-
-static int finalize_pvv(struct compiler_sc *sc)
-{
- fpvm_set_bind_mode(&sc->pvv_fragment, FPVM_BIND_SOURCE);
-
- #define A(dest, val) if(!fpvm_assign(&sc->pvv_fragment, dest, val))
goto fail_assign
-
- /* Zoom */
- A("_invzoom", "1/zoom");
- A("_xz", "_invzoom*(x-0.5)+0.5");
- A("_yz", "_invzoom*(y-0.5)+0.5");
-
- /* Scale */
- A("_xs", "(_xz-cx)/sx+cx");
- A("_ys", "(_yz-cy)/sy+cy");
-
- /* Warp */
- A("_warptime", "time*fWarpAnimSpeed");
- A("_invwarpscale", "1/fWarpScale");
- A("_f0", "11.68 + 4.0*cos(_warptime*1.413 + 10)");
- A("_f1", "8.77 + 3.0*cos(_warptime*1.113 + 7)");
- A("_f2", "10.54 + 3.0*cos(_warptime*1.233 + 3)");
- A("_f3", "11.49 + 4.0*cos(_warptime*0.933 + 5)");
- A("_ox2", "2*x-1");
- A("_oy2", "2*y-1");
- A("_xw", "_xs+warp*0.0035*("
- "sin(_warptime*0.333+_invwarpscale*(_ox2*_f0-_oy2*_f3))"
- "+cos(_warptime*0.753-_invwarpscale*(_ox2*_f1-_oy2*_f2)))");
- A("_yw", "_ys+warp*0.0035*("
- "cos(_warptime*0.375-_invwarpscale*(_ox2*_f2+_oy2*_f1))"
- "+sin(_warptime*0.825+_invwarpscale*(_ox2*_f0+_oy2*_f3)))");
-
- /* Rotate */
- A("_cosr", "cos(rot)");
- A("_sinr", "sin(0-rot)");
- A("_u", "_xw-cx");
- A("_v", "_yw-cy");
- A("_xr", "_u*_cosr-_v*_sinr+cx");
- A("_yr", "_u*_sinr+_v*_cosr+cy");
-
- /* Translate */
- A("_xd", "_xr-dx");
- A("_yd", "_yr-dy");
-
- /* Convert to framebuffer coordinates */
- A("_Xo", "f2i(_xd*_texsize)");
- A("_Yo", "f2i(_yd*_texsize)");
-
- #undef A
-
- if(!fpvm_finalize(&sc->pvv_fragment)) goto fail_finalize;
- #ifdef COMP_DEBUG
- printf("per-vertex FPVM fragment:\n");
- fpvm_dump(&sc->pvv_fragment);
- #endif
-
- return true;
-fail_assign:
- comp_report(sc, "failed to add equation to per-vertex footer: %s",
fpvm_get_last_error(&sc->pvv_fragment));
- return false;
-fail_finalize:
- comp_report(sc, "failed to finalize per-vertex variables: %s",
fpvm_get_last_error(&sc->pvv_fragment));
- return false;
-}
-
-static bool schedule_pvv(struct compiler_sc *sc)
-{
- sc->p->pervertex_prog_length = fpvm_default_schedule(&sc->pvv_fragment,
- (unsigned int *)sc->p->pervertex_prog, (unsigned int
*)sc->p->pervertex_regs);
- if(sc->p->pervertex_prog_length < 0) {
- comp_report(sc, "per-vertex VLIW scheduling failed");
- return false;
- }
- #ifdef COMP_DEBUG
- printf("per-vertex PFPU fragment:\n");
- pfpu_dump(sc->p->pervertex_prog, sc->p->pervertex_prog_length);
- #endif
-
- return true;
-}
-
-static bool add_per_vertex(struct compiler_sc *sc, char *dest, char *val)
-{
- if(!fpvm_assign(&sc->pvv_fragment, dest, val)) {
- comp_report(sc, "failed to add per-vertex equation l. %d:
%s\n", sc->linenr, fpvm_get_last_error(&sc->pvv_fragment));
- return false;
- }
- return true;
-}
-
-/****************************************************************/
-/* PARSING */
-/****************************************************************/
-
-static bool process_equation(struct compiler_sc *sc, char *equation, bool
per_vertex)
-{
- char *c, *c2;
-
- c = strchr(equation, '=');
- if(!c) {
- comp_report(sc, "error l.%d: malformed equation (%s)",
sc->linenr, equation);
- return false;
- }
- *c = 0;
-
- if(*equation == 0) {
- comp_report(sc, "error l.%d: missing lvalue", sc->linenr);
- return false;
- }
- c2 = c - 1;
- while((c2 > equation) && (*c2 == ' ')) *c2-- = 0;
-
- c++;
- while(*c == ' ') c++;
-
- if(*equation == 0) {
- comp_report(sc, "error l.%d: missing lvalue", sc->linenr);
- return false;
- }
- if(*c == 0) {
- comp_report(sc, "error l.%d: missing rvalue", sc->linenr);
- return false;
- }
-
- if(per_vertex)
- return add_per_vertex(sc, equation, c);
- else
- return add_per_frame(sc, equation, c);
-}
-
-static bool process_equations(struct compiler_sc *sc, char *equations, bool
per_vertex)
-{
- char *c;
-
- while(*equations) {
- c = strchr(equations, ';');
- if(!c)
- return process_equation(sc, equations, per_vertex);
- *c = 0;
- if(!process_equation(sc, equations, per_vertex)) return false;
- equations = c + 1;
- }
- return true;
-}
-
-static bool process_top_assign(struct compiler_sc *sc, char *left, char *right)
-{
- int pfv;
-
- while(*right == ' ') right++;
- if(*right == 0) return true;
-
- if(strncmp(left, "imagefile", 9) == 0) {
- int image_n;
- char *totalname;
-
- image_n = atoi(left+9);
- if((image_n < 1) || (image_n > IMAGE_COUNT)) {
- comp_report(sc, "warning l.%d: ignoring image with out
of bounds number %d", sc->linenr, image_n);
- return true;
- }
- image_n--;
- if(right[0] == '/')
- totalname = strdup(right);
- else {
- totalname = malloc(strlen(sc->basedir) + strlen(right)
+ 0);
- if(totalname == NULL) return true;
- strcpy(totalname, sc->basedir);
- strcat(totalname, right);
- }
- pixbuf_dec_ref(sc->p->images[image_n]);
- sc->p->images[image_n] = pixbuf_get(totalname);
- free(totalname);
- return true;
- }
-
- pfv = pfv_from_name(left);
- if(pfv >= 0) {
- /* patch initial condition or global parameter */
- pfv_update_patch_requires(sc, pfv);
- set_initial(sc, pfv, atof(right));
- return true;
- }
-
- if(strncmp(left, "per_frame", 9) == 0)
- /* per-frame equation */
- return process_equations(sc, right, false);
-
- if((strncmp(left, "per_vertex", 10) == 0) || (strncmp(left,
"per_pixel", 9) == 0))
- /* per-vertex equation */
- return process_equations(sc, right, true);
-
- comp_report(sc, "warning l.%d: ignoring unknown parameter %s",
sc->linenr, left);
-
- return true;
-}
-
-static bool process_line(struct compiler_sc *sc, char *line)
-{
- char *c;
-
- while(*line == ' ') line++;
- if(*line == 0) return true;
- if(*line == '[') return true;
-
- c = strstr(line, "//");
- if(c) *c = 0;
-
- c = line + strlen(line) - 1;
- while((c >= line) && (*c == ' ')) *c-- = 0;
- if(*line == 0) return true;
-
- c = strchr(line, '=');
- if(!c) {
- comp_report(sc, "error l.%d: '=' expected", sc->linenr);
- return false;
- }
- *c = 0;
- return process_top_assign(sc, line, c+1);
-}
-
-static bool parse_patch(struct compiler_sc *sc, char *patch_code)
-{
- char *eol;
-
- while(*patch_code) {
- sc->linenr++;
- eol = strchr(patch_code, '\n');
- if(!eol) {
- if(!process_line(sc, patch_code))
- return false;
- else
- return true;
- }
- *eol = 0;
- if(*patch_code == 0) {
- patch_code = eol + 1;
- continue;
- }
- if(*(eol - 1) == '\r') *(eol - 1) = 0;
- if(!process_line(sc, patch_code))
- return false;
- patch_code = eol + 1;
- }
-
- return true;
-}
-
-struct patch *patch_compile(const char *basedir, const char *patch_code,
report_message rmc)
-{
- struct compiler_sc *sc;
- struct patch *p;
- char *patch_code_copy;
- int i;
-
- sc = malloc(sizeof(struct compiler_sc));
- if(sc == NULL) {
- rmc("Failed to allocate memory for compiler internal data");
- return NULL;
- }
- p = sc->p = malloc(sizeof(struct patch));
- if(sc->p == NULL) {
- rmc("Failed to allocate memory for patch");
- free(sc);
- return NULL;
- }
- for(i=0;i<IMAGE_COUNT;i++)
- sc->p->images[i] = NULL;
- sc->p->require = 0;
- sc->p->original = NULL;
- sc->p->next = NULL;
-
- sc->basedir = basedir;
- sc->rmc = rmc;
- sc->linenr = 0;
-
- load_defaults(sc);
- if(!init_pfv(sc)) goto fail;
- if(!init_pvv(sc)) goto fail;
-
- patch_code_copy = strdup(patch_code);
- if(patch_code_copy == NULL) {
- rmc("Failed to allocate memory for patch code");
- goto fail;
- }
- if(!parse_patch(sc, patch_code_copy)) {
- free(patch_code_copy);
- goto fail;
- }
- free(patch_code_copy);
-
- if(!finalize_pfv(sc)) goto fail;
- if(!schedule_pfv(sc)) goto fail;
- if(!finalize_pvv(sc)) goto fail;
- if(!schedule_pvv(sc)) goto fail;
-
- free(sc);
- return p;
-fail:
- free(sc->p);
- free(sc);
- return NULL;
-}
-
-struct patch *patch_compile_filename(const char *filename, const char
*patch_code, report_message rmc)
-{
- char *basedir;
- char *c;
- struct patch *p;
-
- basedir = strdup(filename);
- if(basedir == NULL) return NULL;
- c = strrchr(basedir, '/');
- if(c != NULL) {
- c++;
- *c = 0;
- p = patch_compile(basedir, patch_code, rmc);
- } else
- p = patch_compile("/", patch_code, rmc);
- free(basedir);
- return p;
-}
-
-struct patch *patch_copy(struct patch *p)
-{
- struct patch *new_patch;
- int i;
-
- new_patch = malloc(sizeof(struct patch));
- assert(new_patch != NULL);
- memcpy(new_patch, p, sizeof(struct patch));
- new_patch->original = p;
- new_patch->next = NULL;
- for(i=0;i<IMAGE_COUNT;i++)
- pixbuf_inc_ref(new_patch->images[i]);
- return new_patch;
-}
-
-void patch_free(struct patch *p)
-{
- int i;
-
- for(i=0;i<IMAGE_COUNT;i++)
- pixbuf_dec_ref(p->images[i]);
- free(p);
-}
diff --git a/src/renderer/compiler.h b/src/renderer/compiler.h
deleted file mode 100644
index 2f1169f..0000000
--- a/src/renderer/compiler.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Flickernoise
- * Copyright (C) 2010, 2011 Sebastien Bourdeauducq
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __COMPILER_H
-#define __COMPILER_H
-
-#include <rtems.h>
-#include <bsp/milkymist_pfpu.h>
-
-#include "framedescriptor.h"
-#include "../pixbuf/pixbuf.h"
-
-enum {
- pfv_sx = 0,
- pfv_sy,
- pfv_cx,
- pfv_cy,
- pfv_rot,
- pfv_dx,
- pfv_dy,
- pfv_zoom,
- pfv_decay,
- pfv_wave_mode,
- pfv_wave_scale,
- pfv_wave_additive,
- pfv_wave_usedots,
- pfv_wave_brighten,
- pfv_wave_thick,
- pfv_wave_x,
- pfv_wave_y,
- pfv_wave_r,
- pfv_wave_g,
- pfv_wave_b,
- pfv_wave_a,
-
- pfv_ob_size,
- pfv_ob_r,
- pfv_ob_g,
- pfv_ob_b,
- pfv_ob_a,
- pfv_ib_size,
- pfv_ib_r,
- pfv_ib_g,
- pfv_ib_b,
- pfv_ib_a,
-
- pfv_mv_x,
- pfv_mv_y,
- pfv_mv_dx,
- pfv_mv_dy,
- pfv_mv_l,
- pfv_mv_r,
- pfv_mv_g,
- pfv_mv_b,
- pfv_mv_a,
-
- pfv_tex_wrap,
-
- pfv_time,
- pfv_bass,
- pfv_mid,
- pfv_treb,
- pfv_bass_att,
- pfv_mid_att,
- pfv_treb_att,
-
- pfv_warp,
- pfv_warp_anim_speed,
- pfv_warp_scale,
-
- pfv_q1,
- pfv_q2,
- pfv_q3,
- pfv_q4,
- pfv_q5,
- pfv_q6,
- pfv_q7,
- pfv_q8,
-
- pfv_video_echo_alpha,
- pfv_video_echo_zoom,
- pfv_video_echo_orientation,
-
- pfv_dmx1,
- pfv_dmx2,
- pfv_dmx3,
- pfv_dmx4,
- pfv_dmx5,
- pfv_dmx6,
- pfv_dmx7,
- pfv_dmx8,
-
- pfv_idmx1,
- pfv_idmx2,
- pfv_idmx3,
- pfv_idmx4,
- pfv_idmx5,
- pfv_idmx6,
- pfv_idmx7,
- pfv_idmx8,
-
- pfv_osc1,
- pfv_osc2,
- pfv_osc3,
- pfv_osc4,
-
- pfv_midi1,
- pfv_midi2,
- pfv_midi3,
- pfv_midi4,
- pfv_midi5,
- pfv_midi6,
- pfv_midi7,
- pfv_midi8,
-
- pfv_video_a,
-
- pfv_image1_a,
- pfv_image1_x,
- pfv_image1_y,
- pfv_image1_zoom,
- pfv_image2_a,
- pfv_image2_x,
- pfv_image2_y,
- pfv_image2_zoom,
-
- COMP_PFV_COUNT /* must be last */
-};
-
-enum {
- /* System */
- pvv_texsize,
- pvv_hmeshsize,
- pvv_vmeshsize,
-
- /* MilkDrop */
- pvv_sx,
- pvv_sy,
- pvv_cx,
- pvv_cy,
- pvv_rot,
- pvv_dx,
- pvv_dy,
- pvv_zoom,
-
- pvv_time,
- pvv_bass,
- pvv_mid,
- pvv_treb,
- pvv_bass_att,
- pvv_mid_att,
- pvv_treb_att,
-
- pvv_warp,
- pvv_warp_anim_speed,
- pvv_warp_scale,
-
- pvv_q1,
- pvv_q2,
- pvv_q3,
- pvv_q4,
- pvv_q5,
- pvv_q6,
- pvv_q7,
- pvv_q8,
-
- pvv_idmx1,
- pvv_idmx2,
- pvv_idmx3,
- pvv_idmx4,
- pvv_idmx5,
- pvv_idmx6,
- pvv_idmx7,
- pvv_idmx8,
-
- pvv_osc1,
- pvv_osc2,
- pvv_osc3,
- pvv_osc4,
-
- pvv_midi1,
- pvv_midi2,
- pvv_midi3,
- pvv_midi4,
- pvv_midi5,
- pvv_midi6,
- pvv_midi7,
- pvv_midi8,
-
- COMP_PVV_COUNT /* must be last */
-};
-
-#define REQUIRE_DMX (1 << 0)
-#define REQUIRE_OSC (1 << 1)
-#define REQUIRE_MIDI (1 << 2)
-#define REQUIRE_VIDEO (1 << 3)
-
-struct patch {
- /* per-frame */
- struct pixbuf *images[IMAGE_COUNT]; /* < images used in
this patch */
- float pfv_initial[COMP_PFV_COUNT]; /* < patch initial
conditions */
- int pfv_allocation[COMP_PFV_COUNT]; /* < where per-frame
variables are mapped in PFPU regf, -1 if unmapped */
- int perframe_prog_length; /* < how many
instructions in perframe_prog */
- unsigned int perframe_prog[PFPU_PROGSIZE]; /* < PFPU per-frame
microcode */
- float perframe_regs[PFPU_REG_COUNT]; /* < PFPU initial
per-frame regf */
- /* per-vertex */
- int pvv_allocation[COMP_PVV_COUNT]; /* < where per-vertex
variables are mapped in PFPU regf, -1 if unmapped */
- int pervertex_prog_length; /* < how many
instructions in pervertex_prog */
- unsigned int pervertex_prog[PFPU_PROGSIZE]; /* < PFPU per-vertex
microcode */
- float pervertex_regs[PFPU_REG_COUNT]; /* < PFPU initial
per-vertex regf */
- /* meta */
- unsigned int require; /* < bitmask: dmx, osc,
midi, video */
- void *original; /* < original patch
(with initial register values) */
- struct patch *next; /* < used when chaining
patches in mashups */
-};
-
-typedef void (*report_message)(const char *);
-
-struct patch *patch_compile(const char *basedir, const char *patch_code,
report_message rmc);
-struct patch *patch_compile_filename(const char *filename, const char
*patch_code, report_message rmc);
-struct patch *patch_copy(struct patch *p);
-void patch_free(struct patch *p);
-
-#endif /* __COMPILER_H */
diff --git a/src/renderer/eval.c b/src/renderer/eval.c
index 380a7ea..e41c641 100644
--- a/src/renderer/eval.c
+++ b/src/renderer/eval.c
@@ -28,7 +28,7 @@
#include <bsp/milkymist_tmu.h>
#include "../pixbuf/pixbuf.h"
-#include "compiler.h"
+#include "../compiler/compiler.h"
#include "framedescriptor.h"
#include "renderer.h"
diff --git a/src/renderer/renderer.c b/src/renderer/renderer.c
index b8388ba..5bad9a4 100644
--- a/src/renderer/renderer.c
+++ b/src/renderer/renderer.c
@@ -21,7 +21,7 @@
#include <stdlib.h>
#include "sampler.h"
-#include "compiler.h"
+#include "../compiler/compiler.h"
#include "eval.h"
#include "raster.h"
#include "osd.h"
diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h
index 41ac5df..fc50f32 100644
--- a/src/renderer/renderer.h
+++ b/src/renderer/renderer.h
@@ -18,7 +18,7 @@
#ifndef __RENDERER_H
#define __RENDERER_H
-#include "compiler.h"
+#include "../compiler/compiler.h"
extern int renderer_texsize;
extern int renderer_hmeshlast;
--
1.7.1
_______________________________________________
http://lists.milkymist.org/listinfo.cgi/devel-milkymist.org
IRC: #milkymist@Freenode