source: libcaca/trunk/examples/cacaball.c @ 319

Last change on this file since 319 was 319, checked in by Sam Hocevar, 18 years ago
  • examples/cacaball.c: + Huge coding style overhaul. + Display 5 metaballs instead of 3. + Generate the palette instead of having a static one. + Use a 256x256 back buffer for more smoothness.
  • Property svn:keywords set to Id
File size: 4.2 KB
Line 
1/*
2 *  cacaball      metaballs effect for libcaca
3 *  Copyright (c) 2003-2004 Jean-Yves Lamoureux <jylam@lnxscene.org>
4 *                All Rights Reserved
5 *
6 *  $Id: cacaball.c 319 2004-01-06 12:46:25Z sam $
7 *
8 *  This program is free software; you can redistribute it and/or
9 *  modify it under the terms of the GNU Lesser General Public
10 *  License as published by the Free Software Foundation; either
11 *  version 2 of the License, or (at your option) any later version.
12 *
13 *  This program is distributed in the hope that it will be useful,
14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 *  Lesser General Public License for more details.
17 *
18 *  You should have received a copy of the GNU Lesser General Public
19 *  License along with this program; if not, write to the Free Software
20 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 *  02111-1307  USA
22 */
23
24#include "config.h"
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <math.h>
30
31#include "caca.h"
32
33/* Virtual buffer size */
34#define XSIZ 256
35#define YSIZ 256
36
37#define METASIZE 128
38
39static void draw_ball(unsigned int, unsigned int);
40static void generate_ball(void);
41
42static unsigned char pixels[XSIZ * YSIZ];
43static unsigned char metaball[METASIZE * METASIZE];
44
45int main(int argc, char **argv)
46{
47    struct caca_bitmap *caca_bitmap;
48    float i = 0, j = 0, k = 0;
49    int p;
50    unsigned int x[5], y[5];
51    int r[256], g[256], b[256], a[256];
52
53    if(caca_init())
54        return 1;
55
56    caca_set_delay(0);
57
58    /* Make the palette eatable by libcaca */
59    for(p = 0; p < 256; p++)
60    {
61        r[p] = p < 0xc0 ? 0 : (p - 0xc0) * 0x40;
62        g[p] = p < 0x40 ? 0 : p < 0xc0 ? (p - 0x40) * 0x20 : 0xfff;
63        b[p] = p < 0x40 ? p * 0x40 : 0xfff;
64        a[p] = 0x0;
65    }
66
67    /* Create the bitmap */
68    caca_bitmap = caca_create_bitmap(8, XSIZ, YSIZ, XSIZ, 0, 0, 0, 0);
69
70    /* Set the palette */
71    caca_set_bitmap_palette(caca_bitmap, r, g, b, a);
72
73    /* Generate ball sprite */
74    generate_ball();
75
76    /* Go ! */
77    while(!caca_get_event(CACA_EVENT_KEY_PRESS))
78    {
79        /* Silly paths for our balls */
80        x[0] = (1 + sin(i + k)) * (XSIZ-METASIZE) / 2;
81        y[0] = (1 + cos(1 + j)) * (YSIZ-METASIZE) / 2;
82        x[1] = (1 + cos(2 + j * 2 + k)) * (XSIZ-METASIZE) / 2;
83        y[1] = (1 + cos(3 + i / 2 + j)) * (YSIZ-METASIZE) / 2;
84        x[2] = (1 + cos(4 + k * 2)) * (XSIZ-METASIZE) / 2;
85        y[2] = (1 + cos(i + j / 2)) * (YSIZ-METASIZE) / 2;
86        x[3] = (1 + sin(6 + j * 2)) * (XSIZ-METASIZE) / 2;
87        y[3] = (1 + cos(7 + i / 2)) * (YSIZ-METASIZE) / 2;
88        x[4] = (1 + cos(i - k / 2)) * (XSIZ-METASIZE) / 2;
89        y[4] = (1 + sin(i + k / 2)) * (YSIZ-METASIZE) / 2;
90
91        i += 0.011;
92        j += 0.021;
93        k += 0.029;
94
95        memset(pixels, 0, XSIZ * YSIZ);
96
97        /* Here is all the trick. Maybe if you're that
98         * clever you'll understand. */
99        for(p = 0; p < 5; p++)
100            draw_ball(x[p], y[p]);
101
102        /* Draw our virtual buffer to screen, letting libcaca resize it */
103        caca_draw_bitmap(-10, -10, caca_get_width() + 9, caca_get_height() + 9,
104                         caca_bitmap, pixels);
105        caca_refresh();
106    }
107
108    /* End, bye folks */
109    caca_end();
110
111    return 0;
112}
113
114/* Generate ball sprite
115 * You should read the comments, I already wrote that before ... */
116static void generate_ball(void)
117{
118    int x, y;
119    float distance;
120
121    for(y = 0; y < METASIZE; y++)
122        for(x = 0; x < METASIZE; x++)
123    {
124        distance = ((METASIZE/2) - x) * ((METASIZE/2) - x)
125                 + ((METASIZE/2) - y) * ((METASIZE/2) - y);
126        distance = sqrt(distance) * 64 / METASIZE;
127        metaball[x + y * METASIZE] = distance > 15 ? 0 : (255 - distance) * 15;
128    }
129}
130
131/* You missed the trick ? */
132static void draw_ball(unsigned int bx, unsigned int by)
133{
134    unsigned int color;
135    unsigned int i, e = 0;
136    unsigned int b = (by * XSIZ) + bx;
137
138    for( i = 0; i < METASIZE * METASIZE; i++)
139    {
140        color = pixels[b] + metaball[i];
141
142        if(color > 255)
143            color = 255;
144
145        pixels[b] = color;
146        if(e == METASIZE)
147        {
148            e = 0;
149            b += XSIZ - METASIZE;
150        }
151        b++;
152        e++;
153    }
154}
Note: See TracBrowser for help on using the repository browser.