Ignore:
Timestamp:
Sep 16, 2006, 6:01:48 PM (13 years ago)
Author:
Sam Hocevar
Message:
  • Smooth transitions between effects in cacademo. Press 'n' to switch immediately to the next transition.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcaca/trunk/src/cacademo.c

    r1030 r1032  
    22 *  cacademo      various demo effects for libcaca
    33 *  Copyright (c) 1998 Michele Bini <mibin@tin.it>
    4  *                2003-2004 Jean-Yves Lamoureux <jylam@lnxscene.org>
    5  *                2004 Sam Hocevar <sam@zoy.org>
     4 *                2003-2006 Jean-Yves Lamoureux <jylam@lnxscene.org>
     5 *                2004-2006 Sam Hocevar <sam@zoy.org>
    66 *                All Rights Reserved
    77 *
     
    3030#include "caca.h"
    3131
    32 enum action { INIT, UPDATE, DRAW, FREE };
     32enum action { PREPARE, INIT, UPDATE, RENDER, FREE };
    3333
    3434void plasma(enum action, cucul_canvas_t *);
     
    3838void matrix(enum action, cucul_canvas_t *);
    3939
    40 void (*demo_list[])(enum action, cucul_canvas_t *) =
     40void (*fn[])(enum action, cucul_canvas_t *) =
    4141{
    4242    plasma,
     
    4646    matrix,
    4747};
    48 #define DEMOS (sizeof(demo_list)/sizeof(*demo_list))
     48#define DEMOS (sizeof(fn)/sizeof(*fn))
     49
     50#define DEMO_FRAMES 1000
     51#define TRANSITION_FRAMES 40
    4952
    5053/* Common macros for dither-based demos */
     
    5962    static caca_display_t *dp;
    6063    static cucul_canvas_t *frontcv, *backcv, *mask;
    61     int demo = 0, pause = 0;
     64
     65    int demo, next = -1, pause = 0, next_transition = DEMO_FRAMES;
     66    unsigned int i;
    6267
    6368    /* Set up two canvases, a mask, and attach a display to the front one */
     
    7782    caca_set_display_time(dp, 20000);
    7883
     84    /* Initialise all demos' lookup tables */
     85    for(i = 0; i < DEMOS; i++)
     86        fn[i](PREPARE, frontcv);
     87
     88    /* Choose a demo at random */
    7989    demo = cucul_rand(0, DEMOS);
    80 
    81     demo_list[demo](INIT, frontcv);
     90    fn[demo](INIT, frontcv);
    8291
    8392    for(;;)
    8493    {
     94        /* Handle events */
    8595        caca_event_t ev;
    86         if(caca_get_event(dp, CACA_EVENT_KEY_PRESS, &ev, 0))
    87         {
     96        while(caca_get_event(dp, CACA_EVENT_KEY_PRESS
     97                                  | CACA_EVENT_QUIT, &ev, 0))
     98        {
     99            if(ev.type == CACA_EVENT_QUIT)
     100                goto end;
     101
    88102            switch(ev.data.key.ch)
    89103            {
    90                 case CACA_KEY_ESCAPE: goto end;
    91                 case ' ': pause = !pause;
     104                case CACA_KEY_ESCAPE:
     105                    goto end;
     106                case ' ':
     107                    pause = !pause;
     108                    break;
     109                case 'n':
     110                    if(next == -1)
     111                        next_transition = frame;
     112                    break;
    92113            }
    93114        }
     115
     116        /* Resize the spare canvas, just in case the main one changed */
     117        cucul_set_canvas_size(backcv, cucul_get_canvas_width(frontcv),
     118                                      cucul_get_canvas_height(frontcv));
     119        cucul_set_canvas_size(mask, cucul_get_canvas_width(frontcv),
     120                                    cucul_get_canvas_height(frontcv));
    94121
    95122        if(pause)
    96123            goto paused;
    97124
    98         demo_list[demo](UPDATE, frontcv);
     125        /* Update demo's data */
     126        fn[demo](UPDATE, frontcv);
     127
     128        /* Handle transitions */
     129        if(frame == next_transition)
     130        {
     131            next = cucul_rand(0, DEMOS);
     132            if(next == demo)
     133                next = (next + 1) % DEMOS;
     134            fn[next](INIT, backcv);
     135        }
     136        else if(frame == next_transition + TRANSITION_FRAMES)
     137        {
     138            fn[demo](FREE, frontcv);
     139            demo = next;
     140            next = -1;
     141            next_transition = frame + DEMO_FRAMES;
     142        }
     143
     144        if(next != -1)
     145            fn[next](UPDATE, backcv);
     146
    99147        frame++;
    100148paused:
    101         demo_list[demo](DRAW, frontcv);
     149        /* Render main demo's canvas */
     150        fn[demo](RENDER, frontcv);
     151
     152        /* If a transition is on its way, render it */
     153        if(next != -1)
     154        {
     155            fn[next](RENDER, backcv);
     156            cucul_set_color(mask, CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLACK);
     157            cucul_clear_canvas(mask);
     158            cucul_set_color(mask, CUCUL_COLOR_WHITE, CUCUL_COLOR_WHITE);
     159            cucul_fill_ellipse(mask,
     160                cucul_get_canvas_width(mask) / 2,
     161                cucul_get_canvas_height(mask) / 2,
     162                cucul_get_canvas_width(mask) *
     163                    (frame - next_transition) / TRANSITION_FRAMES * 3 / 4,
     164                cucul_get_canvas_height(mask) *
     165                    (frame - next_transition) / TRANSITION_FRAMES * 3 / 4,
     166                "#");
     167            cucul_blit(frontcv, 0, 0, backcv, mask);
     168        }
     169
    102170        cucul_set_color(frontcv, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE);
    103171        cucul_putstr(frontcv, cucul_get_canvas_width(frontcv) - 30,
     
    107175    }
    108176end:
    109     demo_list[demo](FREE, frontcv);
     177    if(next != -1)
     178        fn[next](FREE, frontcv);
     179    fn[demo](FREE, frontcv);
    110180
    111181    caca_free_display(dp);
     
    136206    switch(action)
    137207    {
    138     case INIT:
    139         screen = malloc(XSIZ * YSIZ * sizeof(uint8_t));
    140 
     208    case PREPARE:
    141209        /* Fill various tables */
    142210        for(i = 0 ; i < 256; i++)
     
    158226            table[x + y * TABLEX] = (1.0 + sin(12.0 * sqrt(tmp))) * 256 / 6;
    159227        }
    160 
    161         /* Create a libcucul dither */
     228        break;
     229
     230    case INIT:
     231        screen = malloc(XSIZ * YSIZ * sizeof(uint8_t));
    162232        dither = cucul_create_dither(8, XSIZ, YSIZ, XSIZ, 0, 0, 0, 0);
    163233        break;
     
    185255        break;
    186256
    187     case DRAW:
     257    case RENDER:
    188258        cucul_dither_bitmap(cv, 0, 0,
    189259                            cucul_get_canvas_width(cv),
     
    246316    switch(action)
    247317    {
    248     case INIT:
    249         screen = malloc(XSIZ * YSIZ * sizeof(uint8_t));
    250 
     318    case PREPARE:
    251319        /* Make the palette eatable by libcaca */
    252320        for(p = 0; p < 256; p++)
     
    254322        r[255] = g[255] = b[255] = 0xfff;
    255323
     324        /* Generate ball sprite */
     325        create_ball();
     326
     327        for(p = 0; p < METABALLS; p++)
     328        {
     329            dd[p] = cucul_rand(0, 100);
     330            di[p] = (float)cucul_rand(500, 4000) / 6000.0;
     331            dj[p] = (float)cucul_rand(500, 4000) / 6000.0;
     332            dk[p] = (float)cucul_rand(500, 4000) / 6000.0;
     333        }
     334
     335        for(p = 0; p < 360 + 80; p++)
     336            offset[p] = 1.0 + sin((double)(p * M_PI / 60));
     337        break;
     338
     339    case INIT:
     340        screen = malloc(XSIZ * YSIZ * sizeof(uint8_t));
    256341        /* Create a libcucul dither smaller than our pixel buffer, so that we
    257342         * display only the interesting part of it */
    258343        cucul_dither = cucul_create_dither(8, XSIZ - METASIZE, YSIZ - METASIZE,
    259344                                           XSIZ, 0, 0, 0, 0);
    260         /* Generate ball sprite */
    261         create_ball();
    262 
    263         for(p = 0; p < METABALLS; p++)
    264         {
    265             dd[p] = cucul_rand(0, 100);
    266             di[p] = (float)cucul_rand(500, 4000) / 6000.0;
    267             dj[p] = (float)cucul_rand(500, 4000) / 6000.0;
    268             dk[p] = (float)cucul_rand(500, 4000) / 6000.0;
    269         }
    270 
    271         for(p = 0; p < 360 + 80; p++)
    272             offset[p] = 1.0 + sin((double)(p * M_PI / 60));
    273345        break;
    274346
     
    319391        break;
    320392
    321     case DRAW:
     393    case RENDER:
    322394        cucul_dither_bitmap(cv, 0, 0,
    323395                          cucul_get_canvas_width(cv),
     
    394466    switch(action)
    395467    {
    396     case INIT:
    397         screen = malloc(XSIZ * YSIZ * sizeof(uint8_t));
    398 
     468    case PREPARE:
    399469        /* Fill various tables */
    400470        for(i = 0 ; i < 256; i++)
     
    408478            draw_disc(i, (i / DISCTHICKNESS) % 2);
    409479
    410         /* Create a libcucul dither */
     480        break;
     481
     482    case INIT:
     483        screen = malloc(XSIZ * YSIZ * sizeof(uint8_t));
    411484        dither = cucul_create_dither(8, XSIZ, YSIZ, XSIZ, 0, 0, 0, 0);
    412485        break;
     
    436509        break;
    437510
    438     case DRAW:
     511    case RENDER:
    439512        cucul_dither_bitmap(cv, 0, 0,
    440513                            cucul_get_canvas_width(cv),
     
    509582    switch(action)
    510583    {
    511     case INIT:
     584    case PREPARE:
    512585        width = cucul_get_canvas_width(cv);
    513586        height = cucul_get_canvas_height(cv);
    514         screen = malloc(width * height);
    515         memset(screen, 0, width * height);
    516587        for(i = 0; i < ANTS; i++)
    517588        {
     
    520591            dir[i] = cucul_rand(0, 4);
    521592        }
     593        break;
     594
     595    case INIT:
     596        screen = malloc(width * height);
     597        memset(screen, 0, width * height);
    522598        break;
    523599
     
    552628        break;
    553629
    554     case DRAW:
     630    case RENDER:
    555631        for(y = 0; y < height; y++)
    556632        {
     
    594670    switch(action)
    595671    {
    596     case INIT:
     672    case PREPARE:
    597673        for(i = 0; i < MAXDROPS; i++)
    598674        {
     
    606682        break;
    607683
     684    case INIT:
     685        break;
     686
    608687    case UPDATE:
    609688        w = cucul_get_canvas_width(cv);
     
    621700        break;
    622701
    623     case DRAW:
     702    case RENDER:
    624703        cucul_set_color(cv, CUCUL_COLOR_BLACK, CUCUL_COLOR_BLACK);
    625704        cucul_clear_canvas(cv);
Note: See TracChangeset for help on using the changeset viewer.