summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2019-06-26 09:18:22 +0200
committerThomas White <taw@physics.org>2019-06-27 23:02:59 +0200
commite07e0540e7b599e09fa009a4e2c165b01a7a34e3 (patch)
treeb1d2f1e3d4ce812a4eac4493f051eae09c16a465
parentc269b1fa9eaa247ef2b863367c249b996b4a01be (diff)
New way of doing attributes
The program now has its own view of what it wants ("this position", "this gobo" etc), and the fixture class contains instructions on how to turn that view into DMX values.
-rw-r--r--src/command.c44
-rw-r--r--src/display.c208
-rw-r--r--src/nanolight.c153
-rw-r--r--src/nanolight.h111
-rw-r--r--src/scanout.c94
5 files changed, 283 insertions, 327 deletions
diff --git a/src/command.c b/src/command.c
index 53d9d9c..e60a75a 100644
--- a/src/command.c
+++ b/src/command.c
@@ -45,7 +45,7 @@ struct token
{
enum token_type type;
int fixture_index;
- enum attr_class attribute;
+ int attribute;
int val;
};
@@ -54,17 +54,13 @@ struct token
const char *attr_class_names[] = {
"int",
- "pan",
- "tilt"
};
-enum attr_class attr_classes[] = {
- ATT_INTENSITY,
- ATT_PAN,
- ATT_TILT
+int attr_classes[] = {
+ INTENSITY,
};
-int n_attr_classes = 3;
+int n_attr_classes = 1;
/* (end of attribute tables) */
@@ -156,21 +152,10 @@ static int find_tokens(const char *cmd, struct token *tokens, struct nanolight *
}
-static const char *str_attr(enum attr_class att)
+static const char *str_attr(int att)
{
switch ( att ) {
- case ATT_INTENSITY : return "intensity";
- case ATT_PAN : return "pan";
- case ATT_TILT : return "tilt";
- case ATT_STROBE : return "strobe";
- case ATT_CYAN : return "cyan";
- case ATT_MAGENTA : return "magenta";
- case ATT_YELLOW : return "yellow";
- case ATT_RGOBO : return "rgobo";
- case ATT_GOBO : return "gobo";
- case ATT_PRISM : return "prism";
- case ATT_FOCUS : return "focus";
- case ATT_ZOOM : return "zoom";
+ case INTENSITY : return "intensity";
}
return "???";
}
@@ -214,24 +199,13 @@ static void show_tokens(struct token *tokens, int n, struct nanolight *nl)
}
-static void set_level(struct nanolight *nl, int val, enum attr_class cls)
+static void set_level(struct nanolight *nl, int val)
{
int i;
- if ( cls == ATT_INTENSITY ) {
- val *= 255;
- val /= 100;
- }
-
for ( i=0; i<nl->n_sel; i++ ) {
- int j;
struct fixture *fix = &nl->fixtures[nl->selection[i]];
- for ( j=0; j<fix->cls->n_attrs; j++ ) {
- if ( fix->cls->attrs[j].cls == cls ) {
- fix->attr_vals[j] = val;
- break;
- }
- }
+ fix->intensity = (float)val/100.0;
}
}
@@ -260,7 +234,7 @@ int command_run(const char *cmd, struct nanolight *nl)
if ( tokens[i].type == TK_AT ) {
if ( tokens[i+1].type == TK_LEVEL ) {
- set_level(nl, tokens[i+1].val, ATT_INTENSITY);
+ set_level(nl, tokens[i+1].val);
}
}
diff --git a/src/display.c b/src/display.c
index ed10330..cd1f0f4 100644
--- a/src/display.c
+++ b/src/display.c
@@ -39,35 +39,22 @@
#define OVERALL_SPLIT (0.5)
#define FIXTURE_BORDER (5.0)
-enum attr_class key_attrs[] = {
+int key_attrs[] = {
0,
- ATT_INTENSITY, /* F1 */
- ATT_TILT, /* F2 */
- ATT_STROBE, /* F3 */
- ATT_CYAN, /* F4 */
- ATT_MAGENTA, /* F5 */
- ATT_YELLOW, /* F6 */
- ATT_GOBO, /* F7 */
- ATT_RGOBO, /* F8 */
- ATT_PRISM, /* F9 */
- ATT_FOCUS, /* F10 */
- ATT_ZOOM, /* F11 */
- ATT_ZOOM, /* F12 */
+ INTENSITY, /* F1 */
+ PANTILT, /* F2 */
+ COL_CMY, /* F3 */
+ GOBO, /* F4 */
+ PRISM, /* F5 */
+ FOCUS, /* F6 */
+ ZOOM, /* F7 */
+ IRIS, /* F8 */
+ FROST, /* F9 */
+ GOBO_ROTATE, /* F10 */
+ PRISM_ROTATE, /* F11 */
+ IRIS, /* F12 */
};
-static double get_attr_val(struct fixture *fix, enum attr_class acls)
-{
- int i;
- for ( i=0; i<fix->cls->n_attrs; i++ ) {
- if ( fix->cls->attrs[i].cls == acls ) {
- int max = 255;
- if ( fix->cls->attrs[i].props & ATTR_16BIT ) max = 65535;
- return (double)fix->attr_vals[i] / max;
- }
- }
- return 0.0;
-}
-
static int fixture_selected(struct nanolight *nl, struct fixture *fix)
{
@@ -79,19 +66,6 @@ static int fixture_selected(struct nanolight *nl, struct fixture *fix)
}
-static int find_attribute(struct fixture *fix, enum attr_class cls, int *n)
-{
- int j;
- for ( j=0; j<fix->cls->n_attrs; j++ ) {
- if ( fix->cls->attrs[j].cls == cls ) {
- *n = j;
- return 1;
- }
- }
- return 0;
-}
-
-
static void draw_fixture(cairo_t *cr, PangoContext *pc, PangoFontDescription *fontdesc,
struct nanolight *nl, struct fixture *fix)
{
@@ -99,24 +73,25 @@ static void draw_fixture(cairo_t *cr, PangoContext *pc, PangoFontDescription *fo
const double w = 40.0;
const double h = 3.0/2.0*w;
char tmp[32];
- int n;
/* Pan/tilt (underneath rectangle) */
- if ( find_attribute(fix, ATT_PAN, &n) ) {
- double x = w*fix->attr_vals[n] / 65535;
+ if ( fix->cls->attributes & PANTILT ) {
+
+ double x = w*(1.0 + fix->pan)/2.0;
+ double y = h*(1.0 + fix->tilt)/2.0;
+
cairo_move_to(cr, x, -1.0);
cairo_line_to(cr, x, h+1.0);
cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
cairo_set_line_width(cr, 1.0);
cairo_stroke(cr);
- }
- if ( find_attribute(fix, ATT_TILT, &n) ) {
- double y = h*(1.0 - (double)fix->attr_vals[n] / 65535);
+
cairo_move_to(cr, -1.0, y);
cairo_line_to(cr, w+1.0, y);
cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
cairo_set_line_width(cr, 1.0);
cairo_stroke(cr);
+
}
cairo_rectangle(cr, 0.0, 0.0, w, h);
@@ -142,7 +117,7 @@ static void draw_fixture(cairo_t *cr, PangoContext *pc, PangoFontDescription *fo
g_object_unref(layout);
/* Intensity */
- snprintf(tmp, 32, "%.0f %%", get_attr_val(fix, ATT_INTENSITY)*100.0);
+ snprintf(tmp, 32, "%.0f %%", fix->intensity*100.0);
layout = pango_layout_new(pc);
pango_layout_set_text(layout, tmp, -1);
pango_layout_set_width(layout, (w*PANGO_SCALE)-4.0);
@@ -155,21 +130,19 @@ static void draw_fixture(cairo_t *cr, PangoContext *pc, PangoFontDescription *fo
}
-static const char *attr_text(enum attr_class cls)
+static const char *attr_text(int cls)
{
switch ( cls ) {
- case ATT_INTENSITY : return "Intensity";
- case ATT_PAN : return "(pan)";
- case ATT_TILT : return "Pan/tilt";
- case ATT_STROBE : return "Strobe";
- case ATT_CYAN : return "Cyan";
- case ATT_MAGENTA : return "Magenta";
- case ATT_YELLOW : return "Yellow";
- case ATT_RGOBO : return "RGobo";
- case ATT_GOBO : return "Gobo";
- case ATT_PRISM : return "Prism";
- case ATT_FOCUS : return "Focus";
- case ATT_ZOOM : return "Zoom";
+ case INTENSITY : return "Intensity";
+ case PANTILT : return "Pan/tilt";
+ case COL_CMY : return "CMY colour";
+ case COL_RGB : return "RGB colour";
+ case GOBO : return "Gobo";
+ case PRISM : return "Prism";
+ case FOCUS : return "Focus";
+ case ZOOM : return "Zoom";
+ case IRIS : return "Iris";
+ case FROST : return "Frost";
}
return "(unknown)";
}
@@ -285,31 +258,13 @@ static size_t delete_char(char *str)
}
-static void cap_value(struct fixture *fix, int n, signed int *v)
-{
- if ( *v < 0 ) *v = 0;
- if ( fix->cls->attrs[n].props & ATTR_16BIT ) {
- if ( *v > 65535 ) *v = 65535;
- } else {
- if ( *v > 255 ) *v = 255;
- }
-}
-
-
-static void set_start_attrs(struct nanolight *nl, enum attr_class cls)
+static void set_start_pantilt(struct nanolight *nl)
{
int i;
for ( i=0; i<nl->n_sel; i++ ) {
- int n;
struct fixture *fix = &nl->fixtures[nl->selection[i]];
- if ( find_attribute(fix, cls, &n) ) {
- fix->attr_vals_start[n] = fix->attr_vals[n];
- }
- }
-
- /* If altering tilt, also change pan */
- if ( cls == ATT_TILT ) {
- set_start_attrs(nl, ATT_PAN);
+ fix->pan_start = fix->pan;
+ fix->tilt_start = fix->tilt;
}
}
@@ -324,8 +279,7 @@ static gboolean button_press_sig(GtkWidget *da, GdkEventButton *event, struct na
nl->pointer = gdk_seat_get_pointer(seat);
#endif
- set_start_attrs(nl, nl->sel_attr);
-
+ set_start_pantilt(nl);
nl->x_orig = event->x;
nl->y_orig = event->y;
nl->dragging = 1;
@@ -341,105 +295,55 @@ static gboolean button_release_sig(GtkWidget *da, GdkEventButton *event, struct
}
-static double maybe_fine(struct fixture *fix, int n, double inc, int shift)
-{
- if ( !(fix->cls->attrs[n].props & ATTR_16BIT) ) return inc;
- if ( shift ) return inc;
- return inc * 100.0;
-}
-
-
static gboolean motion_sig(GtkWidget *da, GdkEventMotion *event, struct nanolight *nl)
{
int i;
double x_inc, y_inc;
int shift;
+ double speed;
if ( !nl->dragging ) return FALSE;
+ if ( nl->sel_attr != PANTILT ) return FALSE;
- x_inc = (event->x - nl->x_orig)/3;
- y_inc = (nl->y_orig - event->y)/3; /* Mouse up means increase */
+ x_inc = event->x - nl->x_orig;
+ y_inc = nl->y_orig - event->y; /* Mouse up means increase */
shift = event->state & GDK_SHIFT_MASK;
if ( shift != nl->fine ) {
nl->fine = shift;
- set_start_attrs(nl, nl->sel_attr);
+ set_start_pantilt(nl);
nl->x_orig = event->x;
nl->y_orig = event->y;
return FALSE;
}
- if ( nl->sel_attr == ATT_TILT ) {
- for ( i=0; i<nl->n_sel; i++ ) {
- int n;
- struct fixture *fix = &nl->fixtures[nl->selection[i]];
- if ( find_attribute(fix, ATT_PAN, &n) ) {
- double inc = maybe_fine(fix, n, x_inc,
- event->state & GDK_SHIFT_MASK);
- signed int nv = fix->attr_vals_start[n] + inc;
- cap_value(fix, n, &nv);
- fix->attr_vals[n] = nv;
- }
- if ( find_attribute(fix, ATT_TILT, &n) ) {
- double inc = maybe_fine(fix, n, y_inc,
- event->state & GDK_SHIFT_MASK);
- signed int nv = fix->attr_vals_start[n] + inc;
- cap_value(fix, n, &nv);
- fix->attr_vals[n] = nv;
- }
- }
- } else {
- for ( i=0; i<nl->n_sel; i++ ) {
- int n;
- struct fixture *fix = &nl->fixtures[nl->selection[i]];
- if ( find_attribute(fix, nl->sel_attr, &n) ) {
- double inc = maybe_fine(fix, n, y_inc,
- event->state & GDK_SHIFT_MASK);
- signed int nv = fix->attr_vals_start[n] + inc;
- cap_value(fix, n, &nv);
- if ( !(fix->cls->attrs[n].props & ATTR_STOP) ) {
- fix->attr_vals[n] = nv;
- } else {
- printf("Can't change step attr with mouse\n");
- }
- }
- }
- }
-
- redraw(nl);
- return FALSE;
-}
-
+ speed = shift ? (1.0/(256.0*500.0)) : (1.0/500.0);
-static void change_stop_attr(struct nanolight *nl, signed int inc)
-{
- int i;
for ( i=0; i<nl->n_sel; i++ ) {
struct fixture *fix = &nl->fixtures[nl->selection[i]];
- int n;
+ if ( !(fix->cls->attributes & PANTILT) ) continue;
- if ( find_attribute(fix, nl->sel_attr, &n) ) {
- signed int nv;
- if ( !(fix->cls->attrs[n].props & ATTR_STOP) ) {
- printf("Can't change continuous attr with keys\n");
- continue;
- }
- nv = fix->attr_vals[n] + inc;
- if ( (nv>=0) && (nv<fix->cls->attrs[n].n_stops) ) {
- fix->attr_vals[n] = nv;
- }
- }
+ fix->pan = fix->pan_start + x_inc*speed;
+ fix->tilt = fix->tilt_start + y_inc*speed;
+ if ( fix->pan > 1.0 ) fix->pan = 1.0;
+ if ( fix->pan < -1.0 ) fix->pan = -1.0;
+ if ( fix->tilt > 1.0 ) fix->tilt = 1.0;
+ if ( fix->tilt < -1.0 ) fix->tilt = -1.0;
}
+
redraw(nl);
+ return FALSE;
}
+
static void home_value(struct nanolight *nl)
{
int i;
for ( i=0; i<nl->n_sel; i++ ) {
+#if 0
struct fixture *fix = &nl->fixtures[nl->selection[i]];
int n;
@@ -456,6 +360,8 @@ static void home_value(struct nanolight *nl)
fix->attr_vals[n] = fix->cls->attrs[n].home;
}
}
+#endif
+
}
redraw(nl);
@@ -503,11 +409,11 @@ static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event, struct nanoligh
break;
case GDK_KEY_Up :
- change_stop_attr(nl, +1);
+ //change_stop_attr(nl, +1);
break;
case GDK_KEY_Down :
- change_stop_attr(nl, -1);
+ //change_stop_attr(nl, -1);
break;
case GDK_KEY_Return :
diff --git a/src/nanolight.c b/src/nanolight.c
index 4751feb..cf6114c 100644
--- a/src/nanolight.c
+++ b/src/nanolight.c
@@ -48,7 +48,6 @@ static struct fixture *create_fixture(struct nanolight *nl, struct fixture_class
const char *label, int universe, int base_addr)
{
struct fixture *fix;
- int i;
if ( nl->n_fixtures == nl->max_fixtures ) {
struct fixture *fixtures_new;
@@ -63,18 +62,25 @@ static struct fixture *create_fixture(struct nanolight *nl, struct fixture_class
fix->universe = universe;
fix->base_addr = base_addr;
fix->cls = cls;
- fix->attr_vals = calloc(cls->n_attrs, sizeof(int));
- fix->attr_vals_start = calloc(cls->n_attrs, sizeof(int));
- if ( (fix->attr_vals == NULL)
- || (fix->attr_vals_start == NULL) )
- {
- nl->n_fixtures--;
- return NULL;
- }
- for ( i=0; i<cls->n_attrs; i++ ) {
- fix->attr_vals[i] = cls->attrs[i].home;
- }
+ fix->intensity = 0.0;
+ fix->cyan = 0.0;
+ fix->magenta = 0.0;
+ fix->yellow = 0.0;
+ fix->red = 0.0;
+ fix->green = 0.0;
+ fix->blue = 0.0;
+ fix->pan = 0.0;
+ fix->tilt = 0.0;
+ fix->gobo = 0;
+ fix->gobo_rotation = 0.5;
+ fix->gobo_spin = 0.0;
+ fix->prism = 0;
+ fix->prism_rotation = 0.5;
+ fix->prism_spin = 0.5;
+ fix->focus = 0.5;
+ fix->zoom = 0.5;
+ fix->frost = 0.0;
return fix;
}
@@ -91,7 +97,6 @@ int main(int argc, char *argv[])
{
struct nanolight nl;
struct fixture_class cls;
- struct attribute attrs[128];
int c;
gtk_init(&argc, &argv);
@@ -126,78 +131,54 @@ int main(int argc, char *argv[])
textdomain("nanolight");
/* Set up data structures */
- cls.name = "Dummy fixture";
- cls.n_attrs = 12;
- cls.attrs = attrs;
-
- cls.attrs[0].cls = ATT_INTENSITY;
- cls.attrs[0].props = 0;
- cls.attrs[0].addr_offset = 49;
- cls.attrs[0].home = 0;
-
- cls.attrs[1].cls = ATT_PAN;
- cls.attrs[1].props = ATTR_16BIT;
- cls.attrs[1].addr_offset = 0;
- cls.attrs[1].home = 32768;
-
- cls.attrs[2].cls = ATT_TILT;
- cls.attrs[2].props = ATTR_16BIT;
- cls.attrs[2].addr_offset = 2;
- cls.attrs[2].home = 32768;
-
- cls.attrs[3].cls = ATT_STROBE;
- cls.attrs[3].props = 0;
- cls.attrs[3].addr_offset = 48;
- cls.attrs[3].home = 32;
-
- cls.attrs[4].cls = ATT_CYAN;
- cls.attrs[4].props = ATTR_16BIT;
- cls.attrs[4].addr_offset = 8;
- cls.attrs[4].home = 0;
-
- cls.attrs[5].cls = ATT_MAGENTA;
- cls.attrs[5].props = ATTR_16BIT;
- cls.attrs[5].addr_offset = 10;
- cls.attrs[5].home = 0;
-
- cls.attrs[6].cls = ATT_YELLOW;
- cls.attrs[6].props = ATTR_16BIT;
- cls.attrs[6].addr_offset = 12;
- cls.attrs[6].home = 0;
-
- int rgobo_stops[] = {0, 6, 10, 15, 19, 24, 28};
- cls.attrs[7].cls = ATT_RGOBO;
- cls.attrs[7].props = ATTR_STOP;
- cls.attrs[7].addr_offset = 24;
- cls.attrs[7].home = 0;
- cls.attrs[7].stops = rgobo_stops;
- cls.attrs[7].n_stops = 7;
-
- cls.attrs[8].cls = ATT_ZOOM;
- cls.attrs[8].props = ATTR_16BIT;
- cls.attrs[8].addr_offset = 32;
- cls.attrs[8].home = 0;
-
- cls.attrs[9].cls = ATT_FOCUS;
- cls.attrs[9].props = ATTR_16BIT;
- cls.attrs[9].addr_offset = 34;
- cls.attrs[9].home = 0;
-
- int gobo_stops[] = {0, 67, 73, 78, 84, 89, 95, 100, 106};
- cls.attrs[10].cls = ATT_GOBO;
- cls.attrs[10].props = ATTR_STOP;
- cls.attrs[10].addr_offset = 22;
- cls.attrs[10].home = 0;
- cls.attrs[10].stops = gobo_stops;
- cls.attrs[10].n_stops = 9;
-
- int prism_stops[] = {0, 50};
- cls.attrs[11].cls = ATT_PRISM;
- cls.attrs[11].props = ATTR_STOP;
- cls.attrs[11].addr_offset = 27;
- cls.attrs[11].home = 0;
- cls.attrs[11].stops = prism_stops;
- cls.attrs[11].n_stops = 2;
+ cls.name = "Robe Robin DL7S Profile Mode 1";
+ cls.attributes = INTENSITY | COL_CMY | PANTILT | FOCUS | ZOOM
+ | FROST | IRIS;
+ cls.attributes16 = INTENSITY | COL_CMY | PANTILT | FOCUS | ZOOM
+ | FROST | IRIS;
+
+ cls.intensity_offset = 49;
+ cls.pan_offset = 0;
+ cls.tilt_offset = 2;
+ cls.cyan_offset = 8;
+ cls.magenta_offset = 10;
+ cls.yellow_offset = 12;
+ cls.focus_offset = 34;
+ cls.zoom_offset = 32;
+
+ int magic_chans[] = {48};
+ int magic_vals[] = {32};
+ cls.magic_chans = magic_chans;
+ cls.magic_vals = magic_vals;
+ cls.n_magic = 1;
+
+ int gobo_chans[] = {24, 22};
+ int gobo_vals[] = { 0, 0,
+ 6, 0,
+ 10, 0,
+ 15, 0,
+ 19, 0,
+ 24, 0,
+ 28, 0,
+ 0, 67,
+ 0, 73,
+ 0, 78,
+ 0, 84,
+ 0, 89,
+ 0, 95,
+ 0, 100,
+ 0, 106 };
+ cls.n_gobos = 15;
+ cls.n_gobo_chans = 2;
+ cls.gobo_chans = gobo_chans;
+ cls.gobo_vals = gobo_vals;
+
+ int prism_chans[] = {27};
+ int prism_vals[] = {0, 50};
+ cls.n_prisms = 15;
+ cls.n_prism_chans = 1;
+ cls.prism_chans = prism_chans;
+ cls.prism_vals = prism_vals;
nl.fixture_width = 80.0;
nl.fixtures = NULL;
@@ -206,7 +187,7 @@ int main(int argc, char *argv[])
nl.cmdline[0] = '\0';
nl.cursor_idx = 0;
nl.n_sel = 0;
- nl.sel_attr = ATT_INTENSITY;
+ nl.sel_attr = INTENSITY;
nl.dragging = 0;
nl.go_lock = 0;
nl.sb_lock = 0;
diff --git a/src/nanolight.h b/src/nanolight.h
index dec9f52..b896a57 100644
--- a/src/nanolight.h
+++ b/src/nanolight.h
@@ -25,44 +25,59 @@
#include <gtk/gtk.h>
-/* Attribute flags */
-#define ATTR_NONE (0)
-#define ATTR_16BIT (1)
-#define ATTR_STOP (2)
-
-enum attr_class
-{
- ATT_INTENSITY,
- ATT_PAN,
- ATT_TILT,
- ATT_STROBE,
- ATT_CYAN,
- ATT_MAGENTA,
- ATT_YELLOW,
- ATT_RGOBO,
- ATT_GOBO,
- ATT_PRISM,
- ATT_FOCUS,
- ATT_ZOOM,
-};
-
-
-struct attribute
-{
- enum attr_class cls;
- int props;
- int addr_offset;
- int home;
- int *stops;
- int n_stops;
-};
-
+/* Fixture attributes */
+#define INTENSITY (1)
+#define COL_RGB (2)
+#define COL_CMY (4)
+#define PANTILT (8)
+#define FOCUS (16)
+#define ZOOM (32)
+#define FROST (64)
+#define IRIS (128)
+#define SHUTTERS (256)
+#define GOBO (512)
+#define GOBO_ROTATE (1024)
+#define PRISM (2048)
+#define PRISM_ROTATE (4096)
struct fixture_class
{
char *name;
- int n_attrs;
- struct attribute *attrs;
+ int attributes;
+ int attributes16;
+
+ int n_magic;
+ int *magic_chans;
+ int *magic_vals;
+
+ int intensity_offset;
+ int pan_offset;
+ int tilt_offset;
+
+ /* For CMY colour */
+ int cyan_offset;
+ int magenta_offset;
+ int yellow_offset;
+
+ /* For RGB colour */
+ int red_offset;
+ int green_offset;
+ int blue_offset;
+
+ int focus_offset;
+ int zoom_offset;
+ int frost_offset;
+ int iris_offset;
+
+ int n_gobos; /* Number of gobos including "no gobo" */
+ int n_gobo_chans;
+ int *gobo_chans;
+ int *gobo_vals;
+
+ int n_prisms;
+ int n_prism_chans;
+ int *prism_chans;
+ int *prism_vals;
};
@@ -72,8 +87,30 @@ struct fixture
int universe;
int base_addr;
struct fixture_class *cls;
- int *attr_vals;
- int *attr_vals_start;
+
+ float intensity; /* 0 (off) to 1 (full) */
+ float cyan; /* 0 (no filter) to 1 (full colour) */
+ float magenta; /* 0 (no filter) to 1 (full colour) */
+ float yellow; /* 0 (no filter) to 1 (full colour) */
+ float red; /* 0 (no red) to 1 (full on) */
+ float green; /* 0 (no green) to 1 (full on) */
+ float blue; /* 0 (no blue) to 1 (full on) */
+ float pan; /* -1 (fully stage left) to +1 (fully stage right) */
+ float tilt; /* -1 (fully downstage) to +1 (fully upstage) */
+ int gobo; /* Gobo number: 0 to cls->n_gobos-1 inclusive */
+ float gobo_rotation; /* -1 (fully anticlockwise) to +1 (fully clockwise) */
+ float gobo_spin; /* -1 (fastest anticlockwise) to +1 (fastest clockwise) */
+ int prism; /* Exactly like gobo */
+ float prism_rotation; /* Exactly like gobo_rotation */
+ float prism_spin; /* Exactly like gobo_spin */
+ float focus; /* 0 (nearest) to 1 (farthest) */
+ float zoom; /* 0 (narrowest) to 1 (widest) */
+ float frost; /* 0 (hardest) to 1 (softest) */
+ float iris; /* 0 (fully open) to 1 (fully closed) */
+
+ /* Values at start of mouse movement */
+ float pan_start;
+ float tilt_start;
};
@@ -95,7 +132,7 @@ struct nanolight
int selection[1024];
int n_sel;
- enum attr_class sel_attr;
+ int sel_attr;
int dragging;
int fine;
int go_lock;
diff --git a/src/scanout.c b/src/scanout.c
index 53d78c9..53e5948 100644
--- a/src/scanout.c
+++ b/src/scanout.c
@@ -28,6 +28,21 @@
#include "nanolight.h"
+static void set_val(int *dmx, int base_addr, int attr_offset, float value, int sixteenbit)
+{
+ /* Minus one to convert DMX address to indexing in 'dmx' array */
+ int pos = base_addr + attr_offset - 1;
+
+ if ( sixteenbit ) {
+ int val = value * 65535;
+ dmx[pos] = (val & 0xff00) >> 8;
+ dmx[pos+1] = val & 0xff;
+ } else {
+ dmx[pos] = value * 255;
+ }
+}
+
+
int scanout_all(struct nanolight *nl)
{
SoupSession *sess;
@@ -42,32 +57,75 @@ int scanout_all(struct nanolight *nl)
/* Loop over fixtures and set values */
for ( i=0; i<nl->n_fixtures; i++ ) {
+
int j;
struct fixture *fix = &nl->fixtures[i];
- for ( j=0; j<fix->cls->n_attrs; j++ ) {
+ struct fixture_class *cls = fix->cls;
- /* Minus one to convert DMX address to indexing in 'dmx' array */
- int pos = fix->base_addr + fix->cls->attrs[j].addr_offset - 1;
+ if ( universe < 0 ) universe = fix->universe;
+ if ( fix->universe != universe ) {
+ fprintf(stderr, "Sorry, only one universe for now!\n");
+ abort();
+ }
- if ( universe < 0 ) universe = fix->universe;
- if ( fix->universe != universe ) {
- fprintf(stderr, "Sorry, only one universe for now!\n");
- abort();
- }
+ for ( j=0; j<cls->n_magic; j++ ) {
+ dmx[fix->base_addr + cls->magic_chans[j] - 1] = cls->magic_vals[j];
+ }
- if ( fix->cls->attrs[j].props & ATTR_STOP ) {
+ if ( cls->attributes & INTENSITY ) {
+ set_val(dmx, fix->base_addr, cls->intensity_offset, fix->intensity,
+ cls->attributes16 & INTENSITY);
+ }
- int v = fix->attr_vals[j];
- assert(!(fix->cls->attrs[j].props & ATTR_16BIT));
- dmx[pos] = fix->cls->attrs[j].stops[v];
+ if ( cls->attributes & PANTILT ) {
+ float pan_val, tilt_val;
+ pan_val = (fix->pan + 1.0)/2.0;
+ tilt_val = (fix->tilt + 1.0)/2.0;
+ set_val(dmx, fix->base_addr, cls->pan_offset, pan_val,
+ cls->attributes16 & PANTILT);
+ set_val(dmx, fix->base_addr, cls->tilt_offset, tilt_val,
+ cls->attributes16 & PANTILT);
+ }
- } else if ( fix->cls->attrs[j].props & ATTR_16BIT ) {
- dmx[pos] = (fix->attr_vals[j] & 0xff00) >> 8;
- dmx[pos+1] = fix->attr_vals[j] & 0xff;
- } else {
- dmx[pos] = fix->attr_vals[j];
- }
+ if ( cls->attributes & COL_CMY ) {
+ set_val(dmx, fix->base_addr, cls->cyan_offset, fix->cyan,
+ cls->attributes16 & COL_CMY);
+ set_val(dmx, fix->base_addr, cls->magenta_offset, fix->magenta,
+ cls->attributes16 & COL_CMY);
+ set_val(dmx, fix->base_addr, cls->yellow_offset, fix->yellow,
+ cls->attributes16 & COL_CMY);
}
+
+ if ( cls->attributes & COL_RGB ) {
+ set_val(dmx, fix->base_addr, cls->red_offset, fix->red,
+ cls->attributes16 & COL_RGB);
+ set_val(dmx, fix->base_addr, cls->green_offset, fix->green,
+ cls->attributes16 & COL_RGB);
+ set_val(dmx, fix->base_addr, cls->blue_offset, fix->blue,
+ cls->attributes16 & COL_RGB);
+ }
+
+ if ( cls->attributes & FOCUS ) {
+ set_val(dmx, fix->base_addr, cls->focus_offset, fix->focus,
+ cls->attributes16 & FOCUS);
+ }
+
+ if ( cls->attributes & ZOOM ) {
+ set_val(dmx, fix->base_addr, cls->zoom_offset, fix->zoom,
+ cls->attributes16 & ZOOM);
+ }
+
+ if ( cls->attributes & FROST ) {
+ set_val(dmx, fix->base_addr, cls->frost_offset, fix->frost,
+ cls->attributes16 & FROST);
+ }
+
+ if ( cls->attributes & IRIS ) {
+ set_val(dmx, fix->base_addr, cls->iris_offset, fix->iris,
+ cls->attributes16 & IRIS);
+ }
+
+
}
if ( universe == -1 ) return 0; /* Nothing to do! */