#include <allegro.h>
#include <math.h>
#include <stdlib.h>

int main(void)
{
    BITMAP* buffer;
    float val[2][4][3];
    float div[3] = {33, 35, 37};
    int interval = 140;
    int step = 0;
    int frame = 0;
    int scale = 4;
    int i, j, k;
    int xi, yi;
    float xf, yf;
    float xs, ys;
    float interp;
    float intensity;
    float c[3];

    if (allegro_init() != 0) {
        return EXIT_FAILURE;
    }
    install_keyboard();
    install_timer();

    set_color_depth(32);
    if (set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, 640, 480, 0, 0) != 0) {
        allegro_message("Error setting graphics mode\n%s\n", allegro_error);
        return EXIT_FAILURE;
    }

    buffer = create_bitmap(screen->w / scale, screen->h / scale);
    clear_bitmap(buffer);

    srand(time(NULL));

    for (k = 0; k < 2; ++k) {
        for (j = 0; j < 4; ++j) {
            for (i = 0; i < 3; ++i) {
                val[k][j][i] = rand() / (float)RAND_MAX;
            }
        }
    }

    xs = 1.0 / buffer->w;
    ys = 1.0 / buffer->h;

    while (!keypressed()) {
        if (step >= interval) {
            step = 0;
            for (j = 0; j < 4; ++j) {
                for (i = 0; i < 3; ++i) {
                    val[0][j][i] = val[1][j][i];
                    val[1][j][i] = rand() / (float)RAND_MAX;
                }
            }
        }

        interp = -cos(M_PI * step / interval) / 2 + 0.5;

        for (yi = yf = 0; yi < buffer->h; ++yi, yf += ys) {
            for (xi = xf = 0; xi < buffer->w; ++xi, xf += xs) {
                for (i = 0; i < 3; ++i) {
                    c[i] = val[0][0][i] * (1 - interp) * (1 - xf) * (1 - yf)
                         + val[1][0][i] * (    interp) * (1 - xf) * (1 - yf)
                         + val[0][1][i] * (1 - interp) * (    xf) * (1 - yf)
                         + val[1][1][i] * (    interp) * (    xf) * (1 - yf)
                         + val[0][2][i] * (1 - interp) * (1 - xf) * (    yf)
                         + val[1][2][i] * (    interp) * (1 - xf) * (    yf)
                         + val[0][3][i] * (1 - interp) * (    xf) * (    yf)
                         + val[1][3][i] * (    interp) * (    xf) * (    yf);
                    c[i] = cos(frame / div[i] + c[i] * 7 * M_PI) / 2 + 0.5;
                }
                intensity = cos((c[0] + c[1] + c[2] + frame / 17.)
                              * M_PI) / 2 + 0.5;
                for (i = 0; i < 3; ++i) {
                    c[i] *= intensity;
                }
                _putpixel32(buffer, xi, yi,
                        makecol32(c[0] * 255, c[1] * 255, c[2] * 255));
            }
        }

        vsync();
        stretch_blit(buffer, screen, 0, 0, buffer->w, buffer->h,
                                     0, 0, screen->w, screen->h);

        ++step;
        ++frame;
    }

    return EXIT_SUCCESS;
}
END_OF_MAIN()

/* vim: set ts=4 sts=4 sw=4 tw=80 et ft=c: */

