source: libcaca/trunk/examples/demo0.c @ 3514

Last change on this file since 3514 was 3493, checked in by Sam Hocevar, 11 years ago

Fix the old demo examples so that they don't refresh the screen twice
every frame, causing the mouse to flicker.

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