From 3a148d92224a9ab88a9c602b072d85d4b1b1eddd Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Mon, 22 Aug 2016 05:42:57 +0300 Subject: [PATCH] transitions --- src/conscr.c | 38 ++++++++++++++++++++++++++++++++------ src/main.c | 2 +- src/screen.c | 8 ++++++++ src/tunnel.c | 44 +++++++++++++++++++++++++++++++++++--------- 4 files changed, 76 insertions(+), 16 deletions(-) diff --git a/src/conscr.c b/src/conscr.c index 4c56fb0..51c50f2 100644 --- a/src/conscr.c +++ b/src/conscr.c @@ -9,6 +9,7 @@ static void destroy(void); static void start(long trans_time); static void stop(long trans_time); static void draw(void); +static float smoothstep(float a, float b, float x); static struct screen scr = { "console", @@ -21,7 +22,12 @@ static struct screen scr = { static void *saved_fb; static int fbsize; -static long trans_start, trans_dur; +static long trans_start = -1, trans_dur; + +#define NBLOCKS 32 +#define MAX_DELAY 0.5 +static float delay[NBLOCKS]; +static int blksz; struct screen *console_screen(void) { @@ -30,13 +36,21 @@ struct screen *console_screen(void) static int init(void) { + int i; fbsize = fb_width * fb_height * fb_depth / 8; if(!(saved_fb = malloc(fbsize))) { - perror("failed to allocate memory"); + perror("failed to allocate console framebuffer"); return -1; } memcpy(saved_fb, fb_pixels, fbsize); + + blksz = fb_height / NBLOCKS; + + for(i=0; i 0) { memset(dptr, 0, offs * pixsz); } @@ -84,3 +101,12 @@ static void draw(void) sptr += fb_width * pixsz; } } + +static float smoothstep(float a, float b, float x) +{ + if(x < a) return 0.0; + if(x >= b) return 1.0; + + x = (x - a) / (b - a); + return x * x * (3.0 - 2.0 * x); +} diff --git a/src/main.c b/src/main.c index 1cd4950..f18563e 100644 --- a/src/main.c +++ b/src/main.c @@ -50,7 +50,7 @@ int main(void) goto end; } scr_change(scr_lookup("console"), 0); - scr_change(scr_lookup("tunnel"), 2000); + scr_change(scr_lookup("tunnel"), 4000); start_msec = get_time_msec(); for(;;) { diff --git a/src/screen.c b/src/screen.c index 1f1dfbe..ff88268 100644 --- a/src/screen.c +++ b/src/screen.c @@ -45,6 +45,7 @@ void scr_update(void) if(prev) { /* we're in the middle of a transition */ long interval = time_msec - trans_start; if(interval >= trans_dur) { + next->start(trans_dur); prev = 0; cur = next; next = 0; @@ -70,16 +71,23 @@ struct screen *scr_lookup(const char *name) int scr_change(struct screen *s, long trans_time) { + if(!s) return -1; if(s == cur) return 0; if(trans_time && cur) { trans_dur = trans_time / 2; /* half for each part transition out then in */ trans_start = time_msec; + if(cur) cur->stop(trans_dur); + prev = cur; next = s; } else { + if(cur) cur->stop(0); + s->start(0); + cur = s; + prev = 0; } return 0; } diff --git a/src/tunnel.c b/src/tunnel.c index 4707d81..8dec902 100644 --- a/src/tunnel.c +++ b/src/tunnel.c @@ -20,10 +20,10 @@ static void start(long trans_time); static void stop(long trans_time); static void draw(void); -static void (*draw_tunnel_range)(void*, int, int); +static void (*draw_tunnel_range)(void*, int, int, long); -static void draw_tunnel_range16(void *pixels, int starty, int num_lines); -static void draw_tunnel_range32(void *pixels, int starty, int num_lines); +static void draw_tunnel_range16(void *pixels, int starty, int num_lines, long tm); +static void draw_tunnel_range32(void *pixels, int starty, int num_lines, long tm); static int count_bits(unsigned int x); static int count_zeros(unsigned int x); @@ -47,6 +47,9 @@ static unsigned int tex_xmask, tex_ymask; static struct thread_pool *tpool; +static long trans_start, trans_dur; +static int trans_dir; + struct screen *tunnel_screen(void) { @@ -146,10 +149,16 @@ static void destroy(void) static void start(long trans_time) { + trans_start = time_msec; + trans_dur = trans_time; + trans_dir = 1; } static void stop(long trans_time) { + trans_start = time_msec; + trans_dur = trans_time; + trans_dir = -1; } #define NUM_WORK_ITEMS 32 @@ -157,21 +166,38 @@ static void stop(long trans_time) static struct work { void *pixels; int starty, num_lines; + long tm; } work[NUM_WORK_ITEMS]; static void work_func(void *cls) { struct work *w = (struct work*)cls; - draw_tunnel_range(w->pixels, w->starty, w->num_lines); + draw_tunnel_range(w->pixels, w->starty, w->num_lines, w->tm); } static void draw(void) { int i, num_lines = vysz / NUM_WORK_ITEMS; + int draw_lines = num_lines; + + if(trans_dir) { + long interval = time_msec - trans_start; + int progr = num_lines * interval / trans_dur; + if(trans_dir < 0) { + draw_lines = num_lines - progr - 1; + } else { + draw_lines = progr; + } + if(progr >= num_lines) { + trans_dir = 0; + } + } + for(i=0; i> 1); for(i=0; i