source: libcaca/trunk/test/demo.c @ 524

Last change on this file since 524 was 524, checked in by Sam Hocevar, 16 years ago

A new low-level text management library (canvas for ultrafast compositing

of unicode letters) is now separated from the higher level rendering and I/O
(that is, libcaca). This commit totally breaks the API, but once everything
is polished I will think about source-level backward compatibility. Most
drivers are broken, but X11 still sorta works.

The new design is much more object-oriented and allows having several

active renderers at the same time, changing renderers on the fly, and more
important, having no renderer at all (useful for converters, or when you
want to do your own renderer).

And in case you are still wondering, the libcucul acronym has "Unicode"

because I want to support at least a subset of Unicode. There are awesome
glyphs in it, including the ones inherited from Codepage 437 such as
"gray 25%" that are used in DOS and Win32 ANSI art.

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