From ecf50890203ef00531713a6afcba607d7274cc52 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sat, 11 Jan 2020 01:06:45 +0100 Subject: First version for show --- glitchyclock.c | 190 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 152 insertions(+), 38 deletions(-) (limited to 'glitchyclock.c') diff --git a/glitchyclock.c b/glitchyclock.c index 90e2aaa..4fd8aea 100644 --- a/glitchyclock.c +++ b/glitchyclock.c @@ -27,15 +27,65 @@ struct glitchyclock { GtkWidget *da; PangoFontDescription *fontdesc; - int nglitch; - double glitch_base; + int cue; + double real_time_last_cue; + double real_time_last_reset; + double brightness; + int base_hours; + int base_minutes; + int base_seconds; + int flag; }; -const int glitch_times[] = { - 4, 15, - 23, 58, - -1, -1 +enum glitch_type +{ + BLACKOUT, /* Fade to black, parameter is fade time in seconds */ + FADE_IN, /* Fade from black to running clock, parameter is fade time in seconds */ + FADE_IN_FROZEN, /* Fade from black to running clock, parameter is fade time in seconds */ + BLACKOUT_FROZEN, + GLITCH_BACK, /* Glitch and then jump back, parameter is number of minutes */ + GLITCH_STOP, /* Glitch and then stop, parameter is number of minutes */ + GLITCH, /* Glitch for the number of seconds */ + EOL /* End of list */ +}; + + +struct glitch_cue +{ + int type; + int parameter; + int hours; + int minutes; + int seconds; +}; + + +struct glitch_cue cues[] = { + { FADE_IN, 3, 4, 25, 12 }, + { BLACKOUT, 3, 0,0,0}, + { FADE_IN, 3, 4, 59, 32 }, + { BLACKOUT, 3, 0,0,0 }, + { FADE_IN, 3, 6, 12, 6 }, + { BLACKOUT, 3, 0,0,0}, + { FADE_IN, 3, 6, 39, 58 }, + { BLACKOUT, 3, 0,0,0}, + { FADE_IN, 3, 8, 25, 37 }, + { GLITCH_BACK, 103, 0,0,0}, + { GLITCH, 2, 0, 0, 12 }, + { BLACKOUT, 3, 0, 0, 12 }, + { FADE_IN, 3, 4, 25, 12 }, + { BLACKOUT, 3, 0, 0, 12 }, + { FADE_IN, 3, 4, 25, 12 }, /* Act I sc VII */ + { GLITCH, 1, 0, 0, 12 }, + { GLITCH, 3, 0, 0, 12 }, + { GLITCH_STOP, 2, 0, 0, 12}, + { BLACKOUT_FROZEN, 3, 0, 0, 12 }, + { FADE_IN_FROZEN, 3, 0, 0, 12 }, + { BLACKOUT_FROZEN, 3 , 0, 0, 12}, + { FADE_IN_FROZEN, 3, 0, 0, 12 }, + { BLACKOUT_FROZEN, 8 , 0, 0, 12}, + { EOL, 0, 0, 0, 0 } }; @@ -47,11 +97,18 @@ static double get_monotonic_seconds() } -static void do_glitch(struct glitchyclock *gc) +static void run_cue(struct glitchyclock *gc) { - //if ( glitch_times[2*(gc->nglitch+1)] == -1 ) return; - //gc->nglitch++; - gc->glitch_base = get_monotonic_seconds(); + if ( cues[gc->cue].type == EOL ) return; + gc->cue++; + gc->real_time_last_cue = get_monotonic_seconds(); + gc->flag = 0; + if ( cues[gc->cue].type == FADE_IN ) { + gc->real_time_last_reset = get_monotonic_seconds(); + gc->base_hours = cues[gc->cue].hours; + gc->base_minutes = cues[gc->cue].minutes; + gc->base_seconds = cues[gc->cue].seconds; + } } @@ -61,13 +118,14 @@ static gboolean draw_sig(GtkWidget *widget, cairo_t *cr, struct glitchyclock *gc int lw, lh; double sf; PangoLayout *layout; - const double screen_w_frac = 0.6; - int glitch_hours, glitch_minutes; + const double screen_w_frac = 0.4; char timestr[64]; - double seconds_f; + double seconds_elapsed, seconds_rounded; + double real_seconds_elapsed, real_seconds_rounded; char col; - double seconds_if; - int hours, minutes, seconds; + int clock_hours, clock_minutes, clock_seconds; + int glitch = 0; + double duty; w = gtk_widget_get_allocated_width(widget); h = gtk_widget_get_allocated_height(widget); @@ -80,26 +138,77 @@ static gboolean draw_sig(GtkWidget *widget, cairo_t *cr, struct glitchyclock *gc pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); pango_layout_set_font_description(layout, gc->fontdesc); - seconds_f = get_monotonic_seconds() - gc->glitch_base; - col = (modf(seconds_f, &seconds_if) < 0.5) ? ':' : ' '; - seconds = seconds_if; - if ( seconds > 16 ) seconds = 16; + seconds_elapsed = get_monotonic_seconds() - gc->real_time_last_cue; + col = (modf(seconds_elapsed, &seconds_rounded) < 0.5) ? ':' : ' '; - hours = (seconds/3600 + 4) % 24; - minutes = (seconds/60 + 48) % 60; - seconds += 15; - snprintf(timestr, 63, "%02i%c%02i%c%02i", hours, col, minutes, col, seconds); + real_seconds_elapsed = get_monotonic_seconds() - gc->real_time_last_reset; + modf(real_seconds_elapsed, &real_seconds_rounded); + clock_hours = gc->base_hours; + clock_minutes = gc->base_minutes; + clock_seconds = gc->base_seconds + real_seconds_rounded; - double duty = 0.5; - if ( seconds_f > 17.0 ) { - duty = 0.5 + (seconds_f - 17.0)/10.0; - if ( duty > 1.0 ) duty = 1.0; + clock_minutes += clock_seconds / 60; + clock_seconds = clock_seconds % 60; + clock_hours += clock_minutes / 60; + clock_minutes = clock_minutes % 60; + clock_hours = clock_hours % 24; + + snprintf(timestr, 63, "%02i%c%02i%c%02i", clock_hours, col, clock_minutes, col, clock_seconds); + + if ( cues[gc->cue].type == FADE_IN ) { + gc->brightness = seconds_elapsed / cues[gc->cue].parameter; + if ( gc->brightness > 1.0 ) gc->brightness = 1.0; + } + + if ( cues[gc->cue].type == FADE_IN_FROZEN ) { + gc->brightness = seconds_elapsed / cues[gc->cue].parameter; + if ( gc->brightness > 1.0 ) gc->brightness = 1.0; + strcpy(timestr, "88:v8:68"); } - if ( ((seconds_f > 7.1) && (seconds_f < 7.9)) - || ((seconds_f > 12.2) && (seconds_f < 13.1)) - || ((seconds_f > 17.0)) ) + + if ( cues[gc->cue].type == BLACKOUT ) { + gc->brightness = 1.0 - (seconds_elapsed / cues[gc->cue].parameter); + if ( gc->brightness < 0.0 ) gc->brightness = 0.0; + } + + if ( cues[gc->cue].type == BLACKOUT_FROZEN ) { + gc->brightness = 1.0 - (seconds_elapsed / cues[gc->cue].parameter); + if ( gc->brightness < 0.0 ) gc->brightness = 0.0; + strcpy(timestr, "88:v8:68"); + } + + if ( (cues[gc->cue].type == GLITCH) + && (seconds_elapsed < cues[gc->cue].parameter) ) { - if ( fmod(seconds_f, 0.05) > duty*0.05 ) { + duty = 0.5; + glitch = 1; + } + + if ( cues[gc->cue].type == GLITCH_STOP ) { + glitch = 1; + duty = 0.5 + seconds_elapsed / cues[gc->cue].parameter; + if ( duty > 1.0 ) duty = 1.0; + } + + if ( cues[gc->cue].type == GLITCH_BACK ) { + glitch = 1; + duty = 0.5 + seconds_elapsed / 4; + if ( duty > 1.0 ) { + duty = 1.0; + if ( !gc->flag ) { + gc->base_minutes += cues[gc->cue].parameter; + gc->base_hours += gc->base_minutes / 60; + gc->base_minutes = gc->base_minutes % 60; + gc->base_hours = gc->base_hours % 24; + gc->flag = 1; + } else { + glitch = 0; + } + } + } + + if ( glitch ) { + if ( fmod(seconds_elapsed, 0.05) > duty*0.05 ) { strcpy(timestr, "00:rK:c1"); } else { strcpy(timestr, "88:v8:68"); @@ -118,14 +227,14 @@ static gboolean draw_sig(GtkWidget *widget, cairo_t *cr, struct glitchyclock *gc pango_layout_get_size(layout, &lw, &lh); lw /= PANGO_SCALE; lh /= PANGO_SCALE; w /= sf; h /= sf; - cairo_translate(cr, (w-lw)/2.0, h-lh-20.0); + cairo_translate(cr, (w-lw)/2.0, h-lh-2.0); pango_cairo_update_layout(cr, layout); - cairo_set_source_rgb(cr, 0.10, 0.0, 0.0); + cairo_set_source_rgb(cr, gc->brightness*0.10, 0.0, 0.0); pango_cairo_show_layout(cr, layout); pango_layout_set_text(layout, timestr, -1); - cairo_set_source_rgb(cr, 0.95, 0.0, 0.05); + cairo_set_source_rgb(cr, gc->brightness*0.95, gc->brightness*0.0, gc->brightness*0.05); pango_cairo_show_layout(cr, layout); return FALSE; @@ -145,8 +254,8 @@ static gboolean redraw_cb(gpointer data) static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event, struct glitchyclock *gc) { - if ( event->keyval == GDK_KEY_KP_Enter ) { - do_glitch(gc); + if ( event->keyval == GDK_KEY_space ) { + run_cue(gc); redraw_cb(gc); return TRUE; } @@ -174,8 +283,13 @@ int main(int argc, char *argv[]) struct glitchyclock gc; GtkWidget *mainwindow; - gc.nglitch = 0; - gc.glitch_base = get_monotonic_seconds(); + gc.cue = 0; + gc.brightness = 0.0; + gc.real_time_last_cue = get_monotonic_seconds(); + gc.real_time_last_reset = get_monotonic_seconds(); + gc.base_hours = cues[gc.cue].hours; + gc.base_minutes = cues[gc.cue].minutes; + gc.base_seconds = cues[gc.cue].seconds; gtk_init(&argc, &argv); mainwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); -- cgit v1.2.3