/* * nanolight.c * * Copyright © 2019 Thomas White * * This file is part of NanoLight. * * NanoLight 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, either version 3 of the License, or * (at your option) any later version. * * 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 . * */ #include #include #include #include #include #include #include #include #define _(x) gettext(x) #include "nanolight.h" #include "scanout.h" #include "display.h" static void show_help(const char *s) { printf(_("Syntax: %s [options]\n\n"), s); printf(_("Theatrical lighting control program.\n\n" " -h, --help Display this help message.\n")); } static struct fixture *create_fixture(struct nanolight *nl, struct fixture_class *cls, const char *label, int universe, int base_addr) { struct fixture *fix; if ( nl->n_fixtures == nl->max_fixtures ) { struct fixture *fixtures_new; fixtures_new = realloc(nl->fixtures, (64+nl->max_fixtures)*sizeof(struct fixture)); if ( fixtures_new == NULL ) return NULL; nl->fixtures = fixtures_new; nl->max_fixtures += 64; } fix = &nl->fixtures[nl->n_fixtures++]; fix->label = strdup(label); fix->universe = universe; fix->base_addr = base_addr; fix->cls = cls; 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_rotate = 0.0; fix->gobo_spin = 0.0; fix->prism = 0; fix->prism_rotate = 0.0; fix->prism_spin = 0.0; fix->focus = 0.5; fix->zoom = 0.5; fix->frost = 0.0; return fix; } static gboolean scanout_cb(gpointer data) { scanout_all((struct nanolight *)data); return G_SOURCE_CONTINUE; } static void cap_value(float *val, float min, float max) { if ( *val > max ) *val = max; if ( *val < min ) *val = min; } void attr_movex(struct nanolight *nl, signed int d, int fine) { int i; float chg = fine ? d/60000.0 : d/10.0; if ( nl->sel_attr != PANTILT ) return; for ( i=0; in_sel; i++ ) { struct fixture *fix = &nl->fixtures[nl->selection[i]]; if ( !(fix->cls->attributes & PANTILT) ) continue; fix->pan += chg; cap_value(&fix->pan, -1.0, 1.0); } } void attr_movey(struct nanolight *nl, signed int d, int fine) { int i; float chg = fine ? d/60000.0 : d/10.0; for ( i=0; in_sel; i++ ) { struct fixture *fix = &nl->fixtures[nl->selection[i]]; switch ( nl->sel_attr ) { case PANTILT : fix->tilt += chg; cap_value(&fix->tilt, -1.0, 1.0); break; case FOCUS : fix->focus += chg; cap_value(&fix->focus, 0.0, 1.0); break; case ZOOM : fix->zoom += chg; cap_value(&fix->zoom, 0.0, 1.0); break; case FROST : fix->frost += chg; cap_value(&fix->frost, 0.0, 1.0); break; case IRIS : fix->iris += chg; cap_value(&fix->iris, 0.0, 1.0); break; case GOBO : if ( (fix->gobo == 0) && (d<0) ) continue; if ( (fix->gobo == fix->cls->n_gobos-1) && (d>0) ) continue; fix->gobo += d; break; case GOBO_ROTATE : fix->gobo_rotate += chg; cap_value(&fix->gobo_rotate, -1.0, 1.0); break; case GOBO_SPIN : fix->gobo_spin += chg; cap_value(&fix->gobo_spin, -1.0, 1.0); break; case PRISM : if ( (fix->prism == 0) && (d<0) ) continue; if ( (fix->prism == fix->cls->n_prisms-1) && (d>0) ) continue; fix->prism += d; break; case PRISM_ROTATE : fix->prism_rotate += chg; cap_value(&fix->prism_rotate, -1.0, 1.0); break; case PRISM_SPIN : fix->prism_spin += chg; cap_value(&fix->prism_spin, -1.0, 1.0); break; } } } int main(int argc, char *argv[]) { struct nanolight nl; struct fixture_class cls; int c; gtk_init(&argc, &argv); const struct option longopts[] = { {"help", 0, NULL, 'h'}, {0, 0, NULL, 0} }; while ((c = getopt_long(argc, argv, "h", longopts, NULL)) != -1) { switch (c) { case 'h' : show_help(argv[0]); return 0; case 0 : break; default : return 1; } } #if !GLIB_CHECK_VERSION(2,36,0) g_type_init(); #endif bindtextdomain("nanolight", LOCALEDIR); textdomain("nanolight"); /* Set up data structures */ cls.name = "Robe Robin DL7S Profile Mode 1"; cls.properties = COL_CMY; cls.attributes = INTENSITY | COLOUR | PANTILT | FOCUS | ZOOM | FROST | IRIS | GOBO | PRISM; cls.attributes16 = INTENSITY | COLOUR | PANTILT | FOCUS | ZOOM | 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; cls.frost_offset = 29; /* FIXME 0..179 only */ cls.iris_offset = 30; /* FIXME: 0..179 only, but also fine @ offset 32 */ cls.gobo_rotate_offset = 25; cls.gobo_spin_offset = 25; cls.prism_rotate_offset = 0; cls.prism_spin_offset = 28; 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, 33, 0, 38, 0, 42, 0, 47, 0, 52, 0, 57, 0, 0, 67, 0, 73, 0, 78, 0, 84, 0, 89, 0, 95, 0, 100, 0, 106 }; int gobo_flags[] = { 0, GOBO_ROTATE, GOBO_ROTATE, GOBO_ROTATE, GOBO_ROTATE, GOBO_ROTATE, GOBO_ROTATE, GOBO_SPIN, GOBO_SPIN, GOBO_SPIN, GOBO_SPIN, GOBO_SPIN, GOBO_SPIN, 0, 0, 0, 0, 0, 0, 0, 0 }; cls.n_gobos = 21; cls.n_gobo_chans = 2; cls.gobo_chans = gobo_chans; cls.gobo_vals = gobo_vals; cls.gobo_flags = gobo_flags; int prism_chans[] = {27}; int prism_vals[] = {0, 50}; int prism_flags [] = {0, PRISM_SPIN}; cls.n_prisms = 2; cls.n_prism_chans = 1; cls.prism_chans = prism_chans; cls.prism_vals = prism_vals; cls.prism_flags = prism_flags; nl.fixture_width = 80.0; nl.fixtures = NULL; nl.n_fixtures = 0; nl.max_fixtures = 0; nl.cmdline[0] = '\0'; nl.cursor_idx = 0; nl.n_sel = 0; nl.sel_attr = INTENSITY; nl.dragging = 0; nl.go_lock = 0; nl.sb_lock = 0; create_fixture(&nl, &cls, "mh1", 0, 1); create_fixture(&nl, &cls, "mh2", 0, 52); create_fixture(&nl, &cls, "mh3", 0, 103); create_fixture(&nl, &cls, "mh4", 0, 154); /* Set up output */ g_timeout_add(100, scanout_cb, &nl); create_main_window(&nl); gtk_main(); return 0; }