source: libcaca/trunk/examples/demo.c @ 298

Last change on this file since 298 was 287, checked in by Sam Hocevar, 17 years ago
  • src/io.c: + Mouse support under X11. + Split the mouse motion and mouse click events.
  • examples/demo.c: + Mouse motion support.
  • Property svn:keywords set to Id
File size: 15.5 KB
Line 
1/*
2 *  demo          demo for libcaca
3 *  Copyright (c) 2003 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: demo.c 287 2003-12-31 01:16:47Z 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 <math.h>
27#include <string.h>
28#include <stdio.h>
29
30#include "caca.h"
31
32static void display_menu(void);
33
34static void demo_all(void);
35
36static void demo_color(void);
37static void demo_dots(void);
38static void demo_lines(void);
39static void demo_boxes(void);
40static void demo_ellipses(void);
41static void demo_triangles(void);
42static void demo_sprites(void);
43static void demo_render(void);
44
45int bounds = 0;
46int outline = 0;
47int dithering = 0;
48struct caca_sprite *sprite = NULL;
49
50int main(int argc, char **argv)
51{
52    void (*demo)(void) = NULL;
53    int quit = 0;
54
55    if(caca_init())
56        return 1;
57
58    caca_set_delay(40000);
59
60    /* Initialize data */
61    sprite = caca_load_sprite(DATADIR "/caca.txt");
62    if(!sprite)
63        sprite = caca_load_sprite("caca.txt");
64    if(!sprite)
65        sprite = caca_load_sprite("examples/caca.txt");
66
67    /* Main menu */
68    display_menu();
69    caca_refresh();
70
71    /* Go ! */
72    while(!quit)
73    {
74        int menu = 0, mouse = 0, xmouse = 0, ymouse = 0;
75        int event;
76
77        while((event = caca_get_event()))
78        {
79            if(demo && (event & CACA_EVENT_KEY_PRESS))
80            {
81                menu = 1;
82                demo = NULL;
83            }
84            else if(event & CACA_EVENT_KEY_PRESS)
85            {
86                switch(event & 0xffff)
87                {
88                case 'q':
89                case 'Q':
90                    demo = NULL;
91                    quit = 1;
92                    break;
93                case 'o':
94                case 'O':
95                    outline = (outline + 1) % 3;
96                    display_menu();
97                    break;
98                case 'b':
99                case 'B':
100                    bounds = (bounds + 1) % 2;
101                    display_menu();
102                    break;
103                case 'd':
104                case 'D':
105                    dithering = (dithering + 1) % 5;
106                    caca_set_dithering(dithering);
107                    display_menu();
108                    break;
109                case 'c':
110                    demo = demo_color;
111                    break;
112                case 'f':
113                case 'F':
114                    demo = demo_all;
115                    break;
116                case '1':
117                    demo = demo_dots;
118                    break;
119                case '2':
120                    demo = demo_lines;
121                    break;
122                case '3':
123                    demo = demo_boxes;
124                    break;
125                case '4':
126                    demo = demo_triangles;
127                    break;
128                case '5':
129                    demo = demo_ellipses;
130                    break;
131                case 's':
132                case 'S':
133                    if(sprite)
134                        demo = demo_sprites;
135                    break;
136                case 'r':
137                case 'R':
138                    demo = demo_render;
139                    break;
140                }
141
142                if(demo)
143                    caca_clear();
144            }
145            else if(event & CACA_EVENT_MOUSE_MOTION)
146            {
147                mouse = 1;
148                xmouse = (event & 0xfff000) >> 12;
149                ymouse = event & 0xfff;
150            }
151        }
152
153        if(menu || (mouse && !demo))
154        {
155            display_menu();
156            if(mouse && !demo)
157            {
158                caca_set_color(CACA_COLOR_RED, CACA_COLOR_BLACK);
159                caca_putstr(xmouse, ymouse, "|\\");
160            }
161            caca_refresh();
162            mouse = menu = 0;
163        }
164
165        if(demo)
166        {
167            demo();
168
169            caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_BLACK);
170            caca_draw_thin_box(1, 1, caca_get_width() - 2, caca_get_height() - 2);
171            caca_printf(4, 1, "[%i.%i fps]----",
172                            1000000 / caca_get_rendertime(),
173                            (10000000 / caca_get_rendertime()) % 10);
174            caca_refresh();
175        }
176    }
177
178    /* Clean up */
179    caca_free_sprite(sprite);
180    caca_end();
181
182    return 0;
183}
184
185static void display_menu(void)
186{
187    int xo = caca_get_width() - 2;
188    int yo = caca_get_height() - 2;
189
190    caca_clear();
191    caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_BLACK);
192    caca_draw_thin_box(1, 1, xo, yo);
193
194    caca_putstr((xo - strlen("libcaca demo")) / 2, 3, "libcaca demo");
195    caca_putstr((xo - strlen("==============")) / 2, 4, "==============");
196
197    caca_putstr(4, 6, "demos:");
198    caca_putstr(4, 7, "'f': full");
199    caca_putstr(4, 8, "'1': dots");
200    caca_putstr(4, 9, "'2': lines");
201    caca_putstr(4, 10, "'3': boxes");
202    caca_putstr(4, 11, "'4': triangles");
203    caca_putstr(4, 12, "'5': ellipses");
204    caca_putstr(4, 13, "'c': colour");
205    caca_putstr(4, 14, "'r': render");
206    if(sprite)
207        caca_putstr(4, 15, "'s': sprites");
208
209    caca_putstr(4, 16, "settings:");
210    caca_printf(4, 17, "'o': outline: %s",
211              outline == 0 ? "none" : outline == 1 ? "solid" : "thin");
212    caca_printf(4, 18, "'b': drawing boundaries: %s",
213              bounds == 0 ? "screen" : "infinite");
214    caca_printf(4, 19, "'d': dithering (%s)",
215                caca_get_dithering_name(dithering));
216
217    caca_putstr(4, yo - 2, "'q': quit");
218}
219
220static void demo_all(void)
221{
222    static int i = 0;
223
224    int j, xo, yo, xa, ya, xb, yb, xc, yc;
225
226    i++;
227
228    caca_clear();
229
230    /* Draw the sun */
231    caca_set_color(CACA_COLOR_YELLOW, CACA_COLOR_BLACK);
232    xo = caca_get_width() / 4;
233    yo = caca_get_height() / 4 + 5 * sin(0.03*i);
234
235    for(j = 0; j < 16; j++)
236    {
237        xa = xo - (30 + sin(0.03*i) * 8) * sin(0.03*i + M_PI*j/8);
238        ya = yo + (15 + sin(0.03*i) * 4) * cos(0.03*i + M_PI*j/8);
239        caca_draw_thin_line(xo, yo, xa, ya);
240    }
241
242    j = 15 + sin(0.03*i) * 8;
243    caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLACK);
244    caca_fill_ellipse(xo, yo, j, j / 2, '#');
245    caca_set_color(CACA_COLOR_YELLOW, CACA_COLOR_BLACK);
246    caca_draw_ellipse(xo, yo, j, j / 2, '#');
247
248    /* Draw the pyramid */
249    xo = caca_get_width() * 5 / 8;
250    yo = 2;
251
252    xa = caca_get_width() / 8 + sin(0.03*i) * 5;
253    ya = caca_get_height() / 2 + cos(0.03*i) * 5;
254
255    xb = caca_get_width() - 10 - cos(0.02*i) * 10;
256    yb = caca_get_height() * 3 / 4 - 5 + sin(0.02*i) * 5;
257
258    xc = caca_get_width() / 4 - sin(0.02*i) * 5;
259    yc = caca_get_height() * 3 / 4 + cos(0.02*i) * 5;
260
261    caca_set_color(CACA_COLOR_GREEN, CACA_COLOR_BLACK);
262    caca_fill_triangle(xo, yo, xb, yb, xa, ya, '%');
263    caca_set_color(CACA_COLOR_YELLOW, CACA_COLOR_BLACK);
264    caca_draw_thin_triangle(xo, yo, xb, yb, xa, ya);
265
266    caca_set_color(CACA_COLOR_RED, CACA_COLOR_BLACK);
267    caca_fill_triangle(xa, ya, xb, yb, xc, yc, '#');
268    caca_set_color(CACA_COLOR_YELLOW, CACA_COLOR_BLACK);
269    caca_draw_thin_triangle(xa, ya, xb, yb, xc, yc);
270
271    caca_set_color(CACA_COLOR_BLUE, CACA_COLOR_BLACK);
272    caca_fill_triangle(xo, yo, xb, yb, xc, yc, '%');
273    caca_set_color(CACA_COLOR_YELLOW, CACA_COLOR_BLACK);
274    caca_draw_thin_triangle(xo, yo, xb, yb, xc, yc);
275
276    /* Draw a background triangle */
277    xa = 2;
278    ya = 2;
279
280    xb = caca_get_width() - 3;
281    yb = caca_get_height() / 2;
282
283    xc = caca_get_width() / 3;
284    yc = caca_get_height() - 3;
285
286    caca_set_color(CACA_COLOR_CYAN, CACA_COLOR_BLACK);
287    caca_draw_thin_triangle(xa, ya, xb, yb, xc, yc);
288
289    xo = caca_get_width() / 2 + cos(0.027*i) * caca_get_width() / 3;
290    yo = caca_get_height() / 2 - sin(0.027*i) * caca_get_height() / 2;
291
292    caca_draw_thin_line(xa, ya, xo, yo);
293    caca_draw_thin_line(xb, yb, xo, yo);
294    caca_draw_thin_line(xc, yc, xo, yo);
295
296    /* Draw a sprite on the pyramid */
297    caca_draw_sprite(xo, yo, sprite, 0);
298
299    /* Draw a trail behind the foreground sprite */
300    for(j = i - 60; j < i; j++)
301    {
302        int delta = caca_rand(-5, 5);
303        caca_set_color(caca_rand(0, 15), caca_rand(0, 15));
304        caca_putchar(caca_get_width() / 2
305                    + cos(0.02*j) * (delta + caca_get_width() / 4),
306                   caca_get_height() / 2
307                    + sin(0.02*j) * (delta + caca_get_height() / 3),
308                   '#');
309    }
310
311    /* Draw foreground sprite */
312    caca_draw_sprite(caca_get_width() / 2 + cos(0.02*i) * caca_get_width() / 4,
313                   caca_get_height() / 2 + sin(0.02*i) * caca_get_height() / 3,
314                   sprite, 0);
315}
316
317static void demo_dots(void)
318{
319    int xmax = caca_get_width() - 1;
320    int ymax = caca_get_height() - 1;
321    int i;
322    static char chars[10] =
323    {
324        '+', '-', '*', '#', 'X', '@', '%', '$', 'M', 'W'
325    };
326
327    for(i = 1000; i--;)
328    {
329        /* Putpixel */
330        caca_set_color(caca_rand(0, 15), caca_rand(0, 15));
331        caca_putchar(caca_rand(0, xmax), caca_rand(0, ymax),
332                     chars[caca_rand(0, 9)]);
333    }
334}
335
336static void demo_color(void)
337{
338    int i, j;
339    char buf[BUFSIZ];
340
341    caca_clear();
342    for(i = 0; i < 16; i++)
343    {
344        sprintf(buf, "'%c': %i (%s)", 'a' + i, i, caca_get_color_name(i));
345        caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_BLACK);
346        caca_putstr(4, i + (i >= 8 ? 4 : 3), buf);
347        for(j = 0; j < 16; j++)
348        {
349            caca_set_color(i, j);
350            caca_putstr((j >= 8 ? 41 : 40) + j * 2, i + (i >= 8 ? 4 : 3), "# ");
351        }
352    }
353}
354
355static void demo_lines(void)
356{
357    int w = caca_get_width();
358    int h = caca_get_height();
359    int xa, ya, xb, yb;
360
361    if(bounds)
362    {
363        xa = caca_rand(- w, 2 * w); ya = caca_rand(- h, 2 * h);
364        xb = caca_rand(- w, 2 * w); yb = caca_rand(- h, 2 * h);
365    }
366    else
367    {
368        xa = caca_rand(0, w - 1); ya = caca_rand(0, h - 1);
369        xb = caca_rand(0, w - 1); yb = caca_rand(0, h - 1);
370    }
371
372    caca_set_color(caca_rand(0, 15), CACA_COLOR_BLACK);
373    if(outline > 1)
374        caca_draw_thin_line(xa, ya, xb, yb);
375    else
376        caca_draw_line(xa, ya, xb, yb, '#');
377}
378
379static void demo_boxes(void)
380{
381    int w = caca_get_width();
382    int h = caca_get_height();
383    int xa, ya, xb, yb;
384
385    if(bounds)
386    {
387        xa = caca_rand(- w, 2 * w); ya = caca_rand(- h, 2 * h);
388        xb = caca_rand(- w, 2 * w); yb = caca_rand(- h, 2 * h);
389    }
390    else
391    {
392        xa = caca_rand(0, w - 1); ya = caca_rand(0, h - 1);
393        xb = caca_rand(0, w - 1); yb = caca_rand(0, h - 1);
394    }
395
396    caca_set_color(caca_rand(0, 15), caca_rand(0, 15));
397    caca_fill_box(xa, ya, xb, yb, '#');
398
399    caca_set_color(caca_rand(0, 15), CACA_COLOR_BLACK);
400    if(outline == 2)
401        caca_draw_thin_box(xa, ya, xb, yb);
402    else if(outline == 1)
403        caca_draw_box(xa, ya, xb, yb, '#');
404}
405
406static void demo_ellipses(void)
407{
408    int w = caca_get_width();
409    int h = caca_get_height();
410    int x, y, a, b;
411
412    if(bounds)
413    {
414        x = caca_rand(- w, 2 * w); y = caca_rand(- h, 2 * h);
415        a = caca_rand(0, w); b = caca_rand(0, h);
416    }
417    else
418    {
419        do
420        {
421            x = caca_rand(0, w); y = caca_rand(0, h);
422            a = caca_rand(0, w); b = caca_rand(0, h);
423
424        } while(x - a < 0 || x + a >= w || y - b < 0 || y + b >= h);
425    }
426
427    caca_set_color(caca_rand(0, 15), caca_rand(0, 15));
428    caca_fill_ellipse(x, y, a, b, '#');
429
430    caca_set_color(caca_rand(0, 15), CACA_COLOR_BLACK);
431    if(outline == 2)
432        caca_draw_thin_ellipse(x, y, a, b);
433    else if(outline == 1)
434        caca_draw_ellipse(x, y, a, b, '#');
435}
436
437static void demo_triangles(void)
438{
439    int w = caca_get_width();
440    int h = caca_get_height();
441    int xa, ya, xb, yb, xc, yc;
442
443    if(bounds)
444    {
445        xa = caca_rand(- w, 2 * w); ya = caca_rand(- h, 2 * h);
446        xb = caca_rand(- w, 2 * w); yb = caca_rand(- h, 2 * h);
447        xc = caca_rand(- w, 2 * w); yc = caca_rand(- h, 2 * h);
448    }
449    else
450    {
451
452        xa = caca_rand(0, w - 1); ya = caca_rand(0, h - 1);
453        xb = caca_rand(0, w - 1); yb = caca_rand(0, h - 1);
454        xc = caca_rand(0, w - 1); yc = caca_rand(0, h - 1);
455    }
456
457    caca_set_color(caca_rand(0, 15), caca_rand(0, 15));
458    caca_fill_triangle(xa, ya, xb, yb, xc, yc, '#');
459
460    caca_set_color(caca_rand(0, 15), CACA_COLOR_BLACK);
461    if(outline == 2)
462        caca_draw_thin_triangle(xa, ya, xb, yb, xc, yc);
463    else if(outline == 1)
464        caca_draw_triangle(xa, ya, xb, yb, xc, yc, '#');
465}
466
467static void demo_sprites(void)
468{
469    caca_draw_sprite(caca_rand(0, caca_get_width() - 1),
470                   caca_rand(0, caca_get_height() - 1), sprite, 0);
471}
472
473#if 0
474static void demo_render(void)
475{
476    struct caca_bitmap *bitmap;
477    //short buffer[256*256];
478    //short *dest = buffer;
479    int buffer[256*256];
480    int *dest = buffer;
481    int x, y, z;
482    static int i = 0;
483
484    i = (i + 1) % 512;
485    z = i < 256 ? i : 511 - i;
486
487    for(x = 0; x < 256; x++)
488        for(y = 0; y < 256; y++)
489    {
490        //*dest++ = ((x >> 3) << 11) | ((y >> 2) << 5) | ((z >> 3));
491        *dest++ = (x << 16) | (y << 8) | (z);
492    }
493
494    //bitmap = caca_create_bitmap(16, 256, 256, 2 * 256, 0xf800, 0x07e0, 0x001f, 0x0000);
495    bitmap = caca_create_bitmap(32, 256, 256, 4 * 256, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
496    caca_draw_bitmap(0, 0, caca_get_width() - 1, caca_get_height() - 1,
497                     bitmap, buffer);
498    caca_free_bitmap(bitmap);
499}
500#endif
501
502static void draw_circle(int *buffer, int xo, int yo, int r, int mask, int val);
503
504static void demo_render(void)
505{
506    struct caca_bitmap *bitmap;
507    int buffer[256*256];
508    int *dest;
509    int x, y, z, xo, yo;
510    static int i = 0;
511
512    i++;
513
514    dest = buffer;
515    for(x = 0; x < 256; x++)
516        for(y = 0; y < 256; y++)
517    {
518        *dest++ = 0xff000000;
519    }
520
521    /* red */
522    xo = 128 + 48 * sin(0.02 * i);
523    yo = 128 + 48 * cos(0.03 * i);
524    for(z = 0; z < 240; z++)
525        draw_circle(buffer, xo, yo, z, 0x00ff0000, 200 << 16);
526
527    /* green */
528    xo = 128 + 48 * sin(2 + 0.06 * i);
529    yo = 128 + 48 * cos(2 + 0.05 * i);
530    for(z = 0; z < 240; z++)
531        draw_circle(buffer, xo, yo, z, 0x0000ff00, 200 << 8);
532
533    /* blue */
534    xo = 128 + 48 * sin(1 + 0.04 * i);
535    yo = 128 + 48 * cos(1 + 0.03 * i);
536    for(z = 0; z < 240; z++)
537        draw_circle(buffer, xo, yo, z, 0x000000ff, 200);
538
539    bitmap = caca_create_bitmap(32, 256, 256, 4 * 256, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
540    caca_draw_bitmap(0, 0, caca_get_width() - 1, caca_get_height() - 1,
541                     bitmap, (char *)buffer);
542    caca_free_bitmap(bitmap);
543}
544
545static void draw_circle(int *buffer, int x, int y, int r, int mask, int val)
546{
547    int t, dx, dy;
548
549#define POINT(X,Y) \
550    buffer[(X) + 256 * (Y)] = 0xff000000 | (buffer[(X) + 256 * (Y)] & ~mask) | val;
551
552    for(t = 0, dx = 0, dy = r; dx <= dy; dx++)
553    {
554        POINT(x - dx / 3, y - dy / 3);
555        POINT(x + dx / 3, y - dy / 3);
556        POINT(x - dx / 3, y + dy / 3);
557        POINT(x + dx / 3, y + dy / 3);
558
559        POINT(x - dy / 3, y - dx / 3);
560        POINT(x + dy / 3, y - dx / 3);
561        POINT(x - dy / 3, y + dx / 3);
562        POINT(x + dy / 3, y + dx / 3);
563
564        t += t > 0 ? dx - dy-- : dx;
565    }
566}
567
Note: See TracBrowser for help on using the repository browser.