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

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

Starting refactoring to get rid of libcucul. The initial reason for the
split is rendered moot by the plugin system: when enabled, binaries do
not link directly with libX11 or libGL. I hope this is a step towards
more consisteny and clarity.

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