transitions
[fbgfx] / src / conscr.c
index 4c56fb0..51c50f2 100644 (file)
@@ -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<NBLOCKS; i++) {
+               delay[i] = (float)rand() / (float)RAND_MAX * MAX_DELAY;
+       }
+
        return 0;
 }
 
@@ -63,16 +77,19 @@ static void draw(void)
        unsigned char *dptr = fb_pixels;
        unsigned char *sptr = saved_fb;
 
-       if(!trans_start) {
+       if(trans_start < 0) {
                return;
        }
-       printf("console draw\n");
 
        elapsed = time_msec - trans_start;
-       offs = fb_width * elapsed / trans_dur;
-       rem = fb_width - offs;
 
        for(i=0; i<fb_height; i++) {
+               int bidx = i / blksz;
+               float t = (float)elapsed / (float)trans_dur;
+               offs = fb_width * smoothstep(0, 1.0 - delay[bidx], t - delay[bidx]);
+               if(offs < 0) offs = 0;
+               rem = fb_width - offs;
+
                if(offs > 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);
+}