Browse Source

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.
tags/v0.99.beta14
Sam Hocevar sam 19 years ago
parent
commit
4c72df99aa
35 changed files with 2921 additions and 2615 deletions
  1. +1
    -1
      configure.ac
  2. +1
    -2
      doc/doxygen.cfg.in
  3. +1
    -5
      examples/Makefile.am
  4. +25
    -14
      examples/aafire.c
  5. +26
    -18
      examples/cacaball.c
  6. +20
    -12
      examples/cacamoir.c
  7. +22
    -14
      examples/cacaplas.c
  8. +92
    -79
      examples/cacaview.c
  9. +0
    -557
      examples/demo.c
  10. +20
    -16
      src/Makefile.am
  11. +52
    -58
      src/bitmap.c
  12. +28
    -22
      src/box.c
  13. +68
    -294
      src/caca.c
  14. +40
    -203
      src/caca.h
  15. +39
    -24
      src/caca_internals.h
  16. +394
    -0
      src/char.c
  17. +30
    -30
      src/conic.c
  18. +322
    -0
      src/cucul.c
  19. +216
    -0
      src/cucul.h
  20. +48
    -0
      src/cucul_internals.h
  21. +60
    -56
      src/event.c
  22. +329
    -0
      src/export.c
  23. +225
    -978
      src/graphics.c
  24. +36
    -36
      src/line.c
  25. +12
    -6
      src/math.c
  26. +33
    -27
      src/sprite.c
  27. +22
    -16
      src/triangle.c
  28. +6
    -2
      test/Makefile.am
  29. +21
    -10
      test/colors.c
  30. +564
    -0
      test/demo.c
  31. +29
    -22
      test/dithering.c
  32. +39
    -30
      test/event.c
  33. +17
    -10
      test/hsv.c
  34. +45
    -45
      test/optipal.c
  35. +38
    -28
      test/spritedit.c

+ 1
- 1
configure.ac View File

@@ -13,7 +13,6 @@ AM_PROG_CC_C_O
AC_PROG_CPP

AC_LIBTOOL_WIN32_DLL
AC_DISABLE_SHARED
AM_PROG_LIBTOOL

AC_C_CONST
@@ -174,6 +173,7 @@ fi

AC_SUBST(MATH_LIBS)
AC_SUBST(CACA_LIBS)
AC_SUBST(CUCUL_LIBS)

# Optimizations
CFLAGS="${CFLAGS} -g -O2 -fno-strength-reduce -fomit-frame-pointer"


+ 1
- 2
doc/doxygen.cfg.in View File

@@ -62,8 +62,7 @@ WARN_LOGFILE =
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = @top_srcdir@/src
FILE_PATTERNS = *.c \
caca.h
FILE_PATTERNS = *.c cucul.h caca.h
RECURSIVE = YES
EXCLUDE = ../src/config.h
EXCLUDE_SYMLINKS = NO


+ 1
- 5
examples/Makefile.am View File

@@ -4,11 +4,7 @@ pkgdata_DATA = caca.txt

EXTRA_DIST = caca.txt

bin_PROGRAMS = cacademo cacafire cacaball cacaplas cacaview cacamoir

cacademo_SOURCES = demo.c
cacademo_LDADD = ../src/libcaca.la @CACA_LIBS@ @MATH_LIBS@
cacademo_CPPFLAGS = -I$(top_srcdir)/src -DDATADIR=\"$(pkgdatadir)\"
bin_PROGRAMS = cacafire cacaball cacaplas cacaview cacamoir

cacafire_SOURCES = aafire.c
cacafire_LDADD = ../src/libcaca.la @CACA_LIBS@


+ 25
- 14
examples/aafire.c View File

@@ -37,8 +37,10 @@
#endif
#define MAXTABLE (256*5)
#ifdef LIBCACA
static cucul_t *qq;
static caca_t *kk;
static int XSIZ, YSIZ;
static struct caca_bitmap *caca_bitmap;
static struct cucul_bitmap *cucul_bitmap;
static char *bitmap;
static int pause = 0;
#else
@@ -96,14 +98,21 @@ initialize (void)
#endif

#ifdef LIBCACA
if (caca_init())
qq = cucul_init();
if (!qq)
{
printf ("Failed to initialize libcucul\n");
exit (1);
}
kk = caca_attach(qq);
if (!kk)
{
printf ("Failed to initialize libcaca\n");
exit (1);
}
caca_set_delay(10000);
XSIZ = caca_get_width() * 2;
YSIZ = caca_get_height() * 2 - 4;
caca_set_delay(kk, 10000);
XSIZ = cucul_get_width(qq) * 2;
YSIZ = cucul_get_height(qq) * 2 - 4;
#else
context = aa_autoinit (&aa_defparams);
if (context == NULL)
@@ -129,10 +138,10 @@ initialize (void)
#endif

#ifdef LIBCACA
caca_bitmap = caca_create_bitmap(8, XSIZ, YSIZ - 2, XSIZ, 0, 0, 0, 0);
caca_set_bitmap_palette(caca_bitmap, r, g, b, a);
bitmap = malloc(4 * caca_get_width() * caca_get_height() * sizeof(char));
memset(bitmap, 0, 4 * caca_get_width() * caca_get_height());
cucul_bitmap = cucul_create_bitmap(qq, 8, XSIZ, YSIZ - 2, XSIZ, 0, 0, 0, 0);
cucul_set_bitmap_palette(qq, cucul_bitmap, r, g, b, a);
bitmap = malloc(4 * cucul_get_width(qq) * cucul_get_height(qq) * sizeof(char));
memset(bitmap, 0, 4 * cucul_get_width(qq) * cucul_get_height(qq));
#else
aa_hidecursor (context);
#endif
@@ -141,7 +150,8 @@ static void
uninitialize (void)
{
#ifdef LIBCACA
caca_end();
caca_detach(kk);
cucul_end(qq);
#else
aa_close (context);
#endif
@@ -223,9 +233,10 @@ drawfire (void)
firemain ();
#ifdef LIBCACA
paused:
caca_draw_bitmap(0, 0, caca_get_width() - 1, caca_get_height() - 1,
caca_bitmap, bitmap);
caca_refresh();
cucul_draw_bitmap(qq, 0, 0,
cucul_get_width(qq) - 1, cucul_get_height(qq) - 1,
cucul_bitmap, bitmap);
caca_refresh(kk);
/*XSIZ = caca_get_width() * 2;
YSIZ = caca_get_height() * 2 - 4;*/
#else
@@ -248,7 +259,7 @@ game (void)
#endif
{
#ifdef LIBCACA
switch (caca_get_event(CACA_EVENT_KEY_PRESS))
switch (caca_get_event(kk, CACA_EVENT_KEY_PRESS))
{
case CACA_EVENT_KEY_PRESS | CACA_KEY_ESCAPE: return;
case CACA_EVENT_KEY_PRESS | ' ': pause = !pause;


+ 26
- 18
examples/cacaball.c View File

@@ -22,6 +22,7 @@
# define M_PI 3.14159265358979323846
#endif

#include "cucul.h"
#include "caca.h"

/* Virtual buffer size */
@@ -42,43 +43,48 @@ static unsigned char metaball[METASIZE * METASIZE];

int main(int argc, char **argv)
{
cucul_t *qq; caca_t *kk;
unsigned int r[256], g[256], b[256], a[256];
float d[METABALLS], di[METABALLS], dj[METABALLS], dk[METABALLS];
unsigned int x[METABALLS], y[METABALLS];
struct caca_bitmap *caca_bitmap;
struct cucul_bitmap *cucul_bitmap;
float i = 10.0, j = 17.0, k = 11.0;
int p, frame = 0, pause = 0;

if(caca_init())
qq = cucul_init();
if(!qq)
return 1;
kk = caca_attach(qq);
if(!kk)
return 1;

caca_set_delay(20000);
caca_set_delay(kk, 20000);

/* Make the palette eatable by libcaca */
for(p = 0; p < 256; p++)
r[p] = g[p] = b[p] = a[p] = 0x0;
r[255] = g[255] = b[255] = 0xfff;

/* Create a libcaca bitmap smaller than our pixel buffer, so that we
/* Create a libcucul bitmap smaller than our pixel buffer, so that we
* display only the interesting part of it */
caca_bitmap = caca_create_bitmap(8, XSIZ - METASIZE, YSIZ - METASIZE,
XSIZ, 0, 0, 0, 0);
cucul_bitmap = cucul_create_bitmap(qq, 8, XSIZ - METASIZE, YSIZ - METASIZE,
XSIZ, 0, 0, 0, 0);

/* Generate ball sprite */
create_ball();

for(p = 0; p < METABALLS; p++)
{
d[p] = caca_rand(0, 100);
di[p] = (float)caca_rand(500, 4000) / 6000.0;
dj[p] = (float)caca_rand(500, 4000) / 6000.0;
dk[p] = (float)caca_rand(500, 4000) / 6000.0;
d[p] = cucul_rand(0, 100);
di[p] = (float)cucul_rand(500, 4000) / 6000.0;
dj[p] = (float)cucul_rand(500, 4000) / 6000.0;
dk[p] = (float)cucul_rand(500, 4000) / 6000.0;
}

/* Go ! */
for(;;)
{
switch(caca_get_event(CACA_EVENT_KEY_PRESS))
switch(caca_get_event(kk, CACA_EVENT_KEY_PRESS))
{
case CACA_EVENT_KEY_PRESS | CACA_KEY_ESCAPE: goto end;
case CACA_EVENT_KEY_PRESS | ' ': pause = !pause;
@@ -109,7 +115,7 @@ int main(int argc, char **argv)
}

/* Set the palette */
caca_set_bitmap_palette(caca_bitmap, r, g, b, a);
cucul_set_bitmap_palette(qq, cucul_bitmap, r, g, b, a);

/* Silly paths for our balls */
for(p = 0; p < METABALLS; p++)
@@ -134,16 +140,18 @@ int main(int argc, char **argv)
draw_ball(x[p], y[p]);

paused:
/* Draw our virtual buffer to screen, letting libcaca resize it */
caca_draw_bitmap(0, 0, caca_get_width() - 1, caca_get_height() - 1,
caca_bitmap, pixels + (METASIZE / 2) * (1 + XSIZ));
caca_refresh();
/* Draw our virtual buffer to screen, letting libcucul resize it */
cucul_draw_bitmap(qq, 0, 0,
cucul_get_width(qq) - 1, cucul_get_height(qq) - 1,
cucul_bitmap, pixels + (METASIZE / 2) * (1 + XSIZ));
caca_refresh(kk);
}

/* End, bye folks */
end:
caca_free_bitmap(caca_bitmap);
caca_end();
cucul_free_bitmap(qq, cucul_bitmap);
caca_detach(kk);
cucul_end(qq);

return 0;
}


+ 20
- 12
examples/cacamoir.c View File

@@ -16,6 +16,7 @@
#include <math.h>
#include <string.h>

#include "cucul.h"
#include "caca.h"

/* Virtual buffer size */
@@ -34,14 +35,19 @@ static void draw_line(int, int, char);

int main (int argc, char **argv)
{
cucul_t *qq; caca_t *kk;
unsigned int red[256], green[256], blue[256], alpha[256];
struct caca_bitmap *bitmap;
struct cucul_bitmap *bitmap;
int i, x, y, frame = 0, pause = 0;

if(caca_init() < 0)
qq = cucul_init();
if(!qq)
return 1;
kk = caca_attach(qq);
if(!kk)
return 1;

caca_set_delay(20000);
caca_set_delay(kk, 20000);

/* Fill various tables */
for(i = 0 ; i < 256; i++)
@@ -54,13 +60,13 @@ int main (int argc, char **argv)
for(i = DISCSIZ * 2; i > 0; i -= DISCTHICKNESS)
draw_disc(i, (i / DISCTHICKNESS) % 2);

/* Create a libcaca bitmap */
bitmap = caca_create_bitmap(8, XSIZ, YSIZ, XSIZ, 0, 0, 0, 0);
/* Create a libcucul bitmap */
bitmap = cucul_create_bitmap(qq, 8, XSIZ, YSIZ, XSIZ, 0, 0, 0, 0);

/* Main loop */
for(;;)
{
switch(caca_get_event(CACA_EVENT_KEY_PRESS))
switch(caca_get_event(kk, CACA_EVENT_KEY_PRESS))
{
case CACA_EVENT_KEY_PRESS | CACA_KEY_ESCAPE: goto end;
case CACA_EVENT_KEY_PRESS | ' ': pause = !pause;
@@ -80,7 +86,7 @@ int main (int argc, char **argv)
green[1] = 0.5 * (1 + cos(0.06 * frame + 5.0)) * 0xfff;
blue[1] = 0.5 * (1 + cos(0.05 * frame + 5.0)) * 0xfff;

caca_set_bitmap_palette(bitmap, red, green, blue, alpha);
cucul_set_bitmap_palette(qq, bitmap, red, green, blue, alpha);

/* Draw circles */
x = cos(0.07 * frame + 5.0) * 128.0 + (XSIZ / 2);
@@ -94,14 +100,16 @@ int main (int argc, char **argv)
frame++;

paused:
caca_draw_bitmap(0, 0, caca_get_width() - 1, caca_get_height() - 1,
bitmap, screen);
caca_refresh();
cucul_draw_bitmap(qq, 0, 0,
cucul_get_width(qq) - 1, cucul_get_height(qq) - 1,
bitmap, screen);
caca_refresh(kk);
}

end:
caca_free_bitmap(bitmap);
caca_end();
cucul_free_bitmap(qq, bitmap);
caca_detach(kk);
cucul_end(qq);

return 0;
}


+ 22
- 14
examples/cacaplas.c View File

@@ -20,6 +20,7 @@
# define M_PI 3.14159265358979323846
#endif

#include "cucul.h"
#include "caca.h"

/* Virtual buffer size */
@@ -37,25 +38,30 @@ static void do_plasma(unsigned char *,

int main (int argc, char **argv)
{
cucul_t *qq; caca_t *kk;
unsigned int red[256], green[256], blue[256], alpha[256];
double r[3], R[6];
struct caca_bitmap *bitmap;
struct cucul_bitmap *bitmap;
int i, x, y, frame = 0, pause = 0;

if(caca_init() < 0)
qq = cucul_init();
if(!qq)
return 1;
kk = caca_attach(qq);
if(!kk)
return 1;

caca_set_delay(20000);
caca_set_delay(kk, 20000);

/* Fill various tables */
for(i = 0 ; i < 256; i++)
red[i] = green[i] = blue[i] = alpha[i] = 0;

for(i = 0; i < 3; i++)
r[i] = (double)(caca_rand(1, 1000)) / 60000 * M_PI;
r[i] = (double)(cucul_rand(1, 1000)) / 60000 * M_PI;

for(i = 0; i < 6; i++)
R[i] = (double)(caca_rand(1, 1000)) / 10000;
R[i] = (double)(cucul_rand(1, 1000)) / 10000;

for(y = 0 ; y < TABLEY ; y++)
for(x = 0 ; x < TABLEX ; x++)
@@ -67,13 +73,13 @@ int main (int argc, char **argv)
table[x + y * TABLEX] = (1.0 + sin(12.0 * sqrt(tmp))) * 256 / 6;
}

/* Create a libcaca bitmap */
bitmap = caca_create_bitmap(8, XSIZ, YSIZ, XSIZ, 0, 0, 0, 0);
/* Create a libcucul bitmap */
bitmap = cucul_create_bitmap(qq, 8, XSIZ, YSIZ, XSIZ, 0, 0, 0, 0);

/* Main loop */
for(;;)
{
switch(caca_get_event(CACA_EVENT_KEY_PRESS))
switch(caca_get_event(kk, CACA_EVENT_KEY_PRESS))
{
case CACA_EVENT_KEY_PRESS | CACA_KEY_ESCAPE: goto end;
case CACA_EVENT_KEY_PRESS | ' ': pause = !pause;
@@ -92,7 +98,7 @@ int main (int argc, char **argv)
}

/* Set the palette */
caca_set_bitmap_palette(bitmap, red, green, blue, alpha);
cucul_set_bitmap_palette(qq, bitmap, red, green, blue, alpha);

do_plasma(screen,
(1.0 + sin(((double)frame) * R[0])) / 2,
@@ -104,14 +110,16 @@ int main (int argc, char **argv)
frame++;

paused:
caca_draw_bitmap(0, 0, caca_get_width() - 1, caca_get_height() - 1,
bitmap, screen);
caca_refresh();
cucul_draw_bitmap(qq, 0, 0,
cucul_get_width(qq) - 1, cucul_get_height(qq) - 1,
bitmap, screen);
caca_refresh(kk);
}

end:
caca_free_bitmap(bitmap);
caca_end();
cucul_free_bitmap(qq, bitmap);
caca_detach(kk);
cucul_end(qq);

return 0;
}


+ 92
- 79
examples/cacaview.c View File

@@ -27,6 +27,7 @@
# include <windows.h>
#endif

#include "cucul.h"
#include "caca.h"

/* Local macros */
@@ -41,6 +42,9 @@
#define ZOOM_MAX 50
#define PAD_STEP 0.15

/* libcucul/libcaca contexts */
cucul_t *qq; caca_t *kk;

/* Local functions */
static void print_status(void);
static void print_help(int, int);
@@ -59,7 +63,7 @@ static int freadchar(FILE *);
Imlib_Image image = NULL;
#endif
char *pixels = NULL;
struct caca_bitmap *bitmap = NULL;
struct cucul_bitmap *bitmap = NULL;
unsigned int w, h, depth, bpp, rmask, gmask, bmask, amask;
#if !defined(HAVE_IMLIB2_H)
unsigned int red[256], green[256], blue[256], alpha[256];
@@ -78,18 +82,26 @@ int main(int argc, char **argv)
int current = 0, items = 0, opts = 1;
int i;

/* Initialise libcaca */
if(caca_init())
/* Initialise libcucul */
qq = cucul_init();
if(!qq)
{
fprintf(stderr, "%s: unable to initialise libcucul\n", argv[0]);
return 1;
}

kk = caca_attach(qq);
if(!kk)
{
fprintf(stderr, "%s: unable to initialise libcaca\n", argv[0]);
return 1;
}

/* Set the window title */
caca_set_window_title("cacaview");
caca_set_window_title(kk, "cacaview");

ww = caca_get_width();
wh = caca_get_height();
ww = cucul_get_width(qq);
wh = cucul_get_height(qq);

/* Fill the zoom table */
zoomtab[0] = 1.0;
@@ -127,9 +139,9 @@ int main(int argc, char **argv)
unsigned int event, new_status = 0, new_help = 0;

if(update)
event = caca_get_event(event_mask);
event = caca_get_event(kk, event_mask);
else
event = caca_wait_event(event_mask);
event = caca_wait_event(kk, event_mask);

while(event)
{
@@ -165,44 +177,44 @@ int main(int argc, char **argv)
set_zoom(zoom);
break;
case 'b':
i = 1 + caca_get_feature(CACA_BACKGROUND);
if(i > CACA_BACKGROUND_MAX) i = CACA_BACKGROUND_MIN;
caca_set_feature(i);
i = 1 + cucul_get_feature(qq, CUCUL_BACKGROUND);
if(i > CUCUL_BACKGROUND_MAX) i = CUCUL_BACKGROUND_MIN;
cucul_set_feature(qq, i);
new_status = STATUS_BACKGROUND;
update = 1;
break;
case 'B':
i = -1 + caca_get_feature(CACA_BACKGROUND);
if(i < CACA_BACKGROUND_MIN) i = CACA_BACKGROUND_MAX;
caca_set_feature(i);
i = -1 + cucul_get_feature(qq, CUCUL_BACKGROUND);
if(i < CUCUL_BACKGROUND_MIN) i = CUCUL_BACKGROUND_MAX;
cucul_set_feature(qq, i);
new_status = STATUS_BACKGROUND;
update = 1;
break;
case 'a':
i = 1 + caca_get_feature(CACA_ANTIALIASING);
if(i > CACA_ANTIALIASING_MAX) i = CACA_ANTIALIASING_MIN;
caca_set_feature(i);
i = 1 + cucul_get_feature(qq, CUCUL_ANTIALIASING);
if(i > CUCUL_ANTIALIASING_MAX) i = CUCUL_ANTIALIASING_MIN;
cucul_set_feature(qq, i);
new_status = STATUS_ANTIALIASING;
update = 1;
break;
case 'A':
i = -1 + caca_get_feature(CACA_ANTIALIASING);
if(i < CACA_ANTIALIASING_MIN) i = CACA_ANTIALIASING_MAX;
caca_set_feature(i);
i = -1 + cucul_get_feature(qq, CUCUL_ANTIALIASING);
if(i < CUCUL_ANTIALIASING_MIN) i = CUCUL_ANTIALIASING_MAX;
cucul_set_feature(qq, i);
new_status = STATUS_ANTIALIASING;
update = 1;
break;
case 'd':
i = 1 + caca_get_feature(CACA_DITHERING);
if(i > CACA_DITHERING_MAX) i = CACA_DITHERING_MIN;
caca_set_feature(i);
i = 1 + cucul_get_feature(qq, CUCUL_DITHERING);
if(i > CUCUL_DITHERING_MAX) i = CUCUL_DITHERING_MIN;
cucul_set_feature(qq, i);
new_status = STATUS_DITHERING;
update = 1;
break;
case 'D':
i = -1 + caca_get_feature(CACA_DITHERING);
if(i < CACA_DITHERING_MIN) i = CACA_DITHERING_MAX;
caca_set_feature(i);
i = -1 + cucul_get_feature(qq, CUCUL_DITHERING);
if(i < CUCUL_DITHERING_MIN) i = CUCUL_DITHERING_MAX;
cucul_set_feature(qq, i);
new_status = STATUS_DITHERING;
update = 1;
break;
@@ -258,9 +270,9 @@ int main(int argc, char **argv)
}
else if(event == CACA_EVENT_RESIZE)
{
caca_refresh();
ww = caca_get_width();
wh = caca_get_height();
caca_refresh(kk);
ww = cucul_get_width(qq);
wh = cucul_get_height(qq);
update = 1;
set_zoom(zoom);
}
@@ -271,7 +283,7 @@ int main(int argc, char **argv)
if(help || new_help)
help = new_help;

event = caca_get_event(CACA_EVENT_KEY_PRESS);
event = caca_get_event(kk, CACA_EVENT_KEY_PRESS);
}

if(items && reload)
@@ -286,11 +298,11 @@ int main(int argc, char **argv)

sprintf(buffer, " Loading `%s'... ", list[current]);
buffer[ww] = '\0';
caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
caca_refresh();
ww = caca_get_width();
wh = caca_get_height();
cucul_set_color(qq, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE);
cucul_putstr(qq, (ww - strlen(buffer)) / 2, wh / 2, buffer);
caca_refresh(kk);
ww = cucul_get_width(qq);
wh = cucul_get_height(qq);

unload_image();
load_image(list[current]);
@@ -304,12 +316,12 @@ int main(int argc, char **argv)
free(buffer);
}

caca_clear();
cucul_clear(qq);

if(!items)
{
caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
caca_printf(ww / 2 - 5, wh / 2, " No image. ");
cucul_set_color(qq, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE);
cucul_printf(qq, ww / 2 - 5, wh / 2, " No image. ");
}
else if(!pixels)
{
@@ -328,8 +340,8 @@ int main(int argc, char **argv)

sprintf(buffer, ERROR_STRING, list[current]);
buffer[ww] = '\0';
caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
cucul_set_color(qq, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE);
cucul_putstr(qq, (ww - strlen(buffer)) / 2, wh / 2, buffer);
free(buffer);
}
else
@@ -348,31 +360,31 @@ int main(int argc, char **argv)
ww * (1.0 + xfactor) / 2,
y + height * (1.0 + yfactor) / 2);

caca_draw_bitmap(ww * (1.0 - xfactor) * xdelta,
y + height * (1.0 - yfactor) * ydelta,
ww * (xdelta + (1.0 - xdelta) * xfactor),
y + height * (ydelta + (1.0 - ydelta) * yfactor),
bitmap, pixels);
cucul_draw_bitmap(qq, ww * (1.0 - xfactor) * xdelta,
y + height * (1.0 - yfactor) * ydelta,
ww * (xdelta + (1.0 - xdelta) * xfactor),
y + height * (ydelta + (1.0 - ydelta) * yfactor),
bitmap, pixels);
}

if(!fullscreen)
{
print_status();

caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_BLACK);
cucul_set_color(qq, CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLACK);
switch(status)
{
case STATUS_ANTIALIASING:
caca_printf(0, wh - 1, "Antialiasing: %s",
caca_get_feature_name(caca_get_feature(CACA_ANTIALIASING)));
cucul_printf(qq, 0, wh - 1, "Antialiasing: %s",
cucul_get_feature_name(cucul_get_feature(qq, CUCUL_ANTIALIASING)));
break;
case STATUS_DITHERING:
caca_printf(0, wh - 1, "Dithering: %s",
caca_get_feature_name(caca_get_feature(CACA_DITHERING)));
cucul_printf(qq, 0, wh - 1, "Dithering: %s",
cucul_get_feature_name(cucul_get_feature(qq, CUCUL_DITHERING)));
break;
case STATUS_BACKGROUND:
caca_printf(0, wh - 1, "Background: %s",
caca_get_feature_name(caca_get_feature(CACA_BACKGROUND)));
cucul_printf(qq, 0, wh - 1, "Background: %s",
cucul_get_feature_name(cucul_get_feature(qq, CUCUL_BACKGROUND)));
break;
}
}
@@ -382,30 +394,31 @@ int main(int argc, char **argv)
print_help(ww - 25, 2);
}

caca_refresh();
caca_refresh(kk);
update = 0;
}

/* Clean up */
unload_image();
caca_end();
caca_detach(kk);
cucul_end(qq);

return 0;
}

static void print_status(void)
{
caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
caca_draw_line(0, 0, ww - 1, 0, ' ');
caca_draw_line(0, wh - 2, ww - 1, wh - 2, '-');
caca_putstr(0, 0, "q:Quit np:Next/Prev +-x:Zoom "
"hjkl:Move d:Dithering a:Antialias");
caca_putstr(ww - strlen("?:Help"), 0, "?:Help");
caca_printf(3, wh - 2, "cacaview %s", VERSION);
caca_printf(ww - 14, wh - 2, "(zoom: %s%i)", zoom > 0 ? "+" : "", zoom);
caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_BLACK);
caca_draw_line(0, wh - 1, ww - 1, wh - 1, ' ');
cucul_set_color(qq, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE);
cucul_draw_line(qq, 0, 0, ww - 1, 0, ' ');
cucul_draw_line(qq, 0, wh - 2, ww - 1, wh - 2, '-');
cucul_putstr(qq, 0, 0, "q:Quit np:Next/Prev +-x:Zoom "
"hjkl:Move d:Dithering a:Antialias");
cucul_putstr(qq, ww - strlen("?:Help"), 0, "?:Help");
cucul_printf(qq, 3, wh - 2, "cacaview %s", VERSION);
cucul_printf(qq, ww - 14, wh - 2, "(zoom: %s%i)", zoom > 0 ? "+" : "", zoom);
cucul_set_color(qq, CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLACK);
cucul_draw_line(qq, 0, wh - 1, ww - 1, wh - 1, ' ');
}

static void print_help(int x, int y)
@@ -430,10 +443,10 @@ static void print_help(int x, int y)

int i;

caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
cucul_set_color(qq, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE);

for(i = 0; help[i]; i++)
caca_putstr(x, y + i, help[i]);
cucul_putstr(qq, x, y + i, help[i]);
}

static void set_zoom(int new_zoom)
@@ -445,13 +458,13 @@ static void set_zoom(int new_zoom)
if(zoom > ZOOM_MAX) zoom = ZOOM_MAX;
if(zoom < -ZOOM_MAX) zoom = -ZOOM_MAX;

ww = caca_get_width();
ww = cucul_get_width(qq);
height = fullscreen ? wh : wh - 3;

xfactor = (zoom < 0) ? 1.0 / zoomtab[-zoom] : zoomtab[zoom];
yfactor = xfactor * ww / height * h / w
* caca_get_height() / caca_get_width()
* caca_get_window_width() / caca_get_window_height();
* cucul_get_height(qq) / cucul_get_width(qq)
* caca_get_window_width(kk) / caca_get_window_height(kk);

if(yfactor > xfactor)
{
@@ -474,7 +487,7 @@ static void unload_image(void)
pixels = NULL;
#endif
if(bitmap)
caca_free_bitmap(bitmap);
cucul_free_bitmap(qq, bitmap);
bitmap = NULL;
}

@@ -498,9 +511,9 @@ static void load_image(char const *name)
bpp = 32;
depth = 4;

/* Create the libcaca bitmap */
bitmap = caca_create_bitmap(bpp, w, h, depth * w,
rmask, gmask, bmask, amask);
/* Create the libcucul bitmap */
bitmap = cucul_create_bitmap(qq, bpp, w, h, depth * w,
rmask, gmask, bmask, amask);
if(!bitmap)
{
imlib_free_image();
@@ -685,17 +698,17 @@ static void draw_checkers(int x1, int y1, int x2, int y2)
{
int xn, yn;

if(x2 + 1 > (int)caca_get_width()) x2 = caca_get_width() - 1;
if(y2 + 1 > (int)caca_get_height()) y2 = caca_get_height() - 1;
if(x2 + 1 > (int)cucul_get_width(qq)) x2 = cucul_get_width(qq) - 1;
if(y2 + 1 > (int)cucul_get_height(qq)) y2 = cucul_get_height(qq) - 1;

for(yn = y1 > 0 ? y1 : 0; yn <= y2; yn++)
for(xn = x1 > 0 ? x1 : 0; xn <= x2; xn++)
{
if((((xn - x1) / 5) ^ ((yn - y1) / 3)) & 1)
caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_DARKGRAY);
cucul_set_color(qq, CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_DARKGRAY);
else
caca_set_color(CACA_COLOR_DARKGRAY, CACA_COLOR_LIGHTGRAY);
caca_putchar(xn, yn, ' ');
cucul_set_color(qq, CUCUL_COLOR_DARKGRAY, CUCUL_COLOR_LIGHTGRAY);
cucul_putchar(qq, xn, yn, ' ');
}
}



+ 0
- 557
examples/demo.c View File

@@ -1,557 +0,0 @@
/*
* demo demo for libcaca
* Copyright (c) 2003 Sam Hocevar <sam@zoy.org>
* All Rights Reserved
*
* $Id$
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the Do What The Fuck You Want To
* Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#include <math.h>
#include <string.h>
#include <stdio.h>

#include "caca.h"

static void display_menu(void);

static void demo_all(void);

static void demo_color(void);
static void demo_dots(void);
static void demo_lines(void);
static void demo_boxes(void);
static void demo_ellipses(void);
static void demo_triangles(void);
static void demo_sprites(void);
static void demo_render(void);

int bounds = 0;
int outline = 0;
int dithering = 0;
struct caca_sprite *sprite = NULL;

int main(int argc, char **argv)
{
void (*demo)(void) = NULL;
int quit = 0;

if(caca_init())
return 1;

caca_set_delay(40000);

/* Initialize data */
sprite = caca_load_sprite(DATADIR "/caca.txt");
if(!sprite)
sprite = caca_load_sprite("caca.txt");
if(!sprite)
sprite = caca_load_sprite("examples/caca.txt");

/* Main menu */
display_menu();
caca_refresh();

/* Go ! */
while(!quit)
{
int menu = 0, mouse = 0, xmouse = 0, ymouse = 0;
int event;

while((event = caca_get_event(CACA_EVENT_ANY)))
{
if(demo && (event & CACA_EVENT_KEY_PRESS))
{
menu = 1;
demo = NULL;
}
else if(event & CACA_EVENT_KEY_PRESS)
{
switch(event & 0xffff)
{
case 'q':
case 'Q':
demo = NULL;
quit = 1;
break;
case 'o':
case 'O':
outline = (outline + 1) % 3;
display_menu();
break;
case 'b':
case 'B':
bounds = (bounds + 1) % 2;
display_menu();
break;
case 'd':
case 'D':
dithering = (dithering + 1) % 5;
caca_set_dithering(dithering);
display_menu();
break;
case 'c':
demo = demo_color;
break;
case 'f':
case 'F':
demo = demo_all;
break;
case '1':
demo = demo_dots;
break;
case '2':
demo = demo_lines;
break;
case '3':
demo = demo_boxes;
break;
case '4':
demo = demo_triangles;
break;
case '5':
demo = demo_ellipses;
break;
case 's':
case 'S':
if(sprite)
demo = demo_sprites;
break;
case 'r':
case 'R':
demo = demo_render;
break;
}

if(demo)
caca_clear();
}
else if(event & CACA_EVENT_MOUSE_MOTION)
{
mouse = 1;
xmouse = (event & 0xfff000) >> 12;
ymouse = event & 0xfff;
}
}

if(menu || (mouse && !demo))
{
display_menu();
if(mouse && !demo)
{
caca_set_color(CACA_COLOR_RED, CACA_COLOR_BLACK);
caca_putstr(xmouse, ymouse, "|\\");
}
caca_refresh();
mouse = menu = 0;
}

if(demo)
{
demo();

caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_BLACK);
caca_draw_thin_box(1, 1, caca_get_width() - 2, caca_get_height() - 2);
caca_printf(4, 1, "[%i.%i fps]----",
1000000 / caca_get_rendertime(),
(10000000 / caca_get_rendertime()) % 10);
caca_refresh();
}
}

/* Clean up */
caca_free_sprite(sprite);
caca_end();

return 0;
}

static void display_menu(void)
{
int xo = caca_get_width() - 2;
int yo = caca_get_height() - 2;

caca_clear();
caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_BLACK);
caca_draw_thin_box(1, 1, xo, yo);

caca_putstr((xo - strlen("libcaca demo")) / 2, 3, "libcaca demo");
caca_putstr((xo - strlen("==============")) / 2, 4, "==============");

caca_putstr(4, 6, "demos:");
caca_putstr(4, 7, "'f': full");
caca_putstr(4, 8, "'1': dots");
caca_putstr(4, 9, "'2': lines");
caca_putstr(4, 10, "'3': boxes");
caca_putstr(4, 11, "'4': triangles");
caca_putstr(4, 12, "'5': ellipses");
caca_putstr(4, 13, "'c': colour");
caca_putstr(4, 14, "'r': render");
if(sprite)
caca_putstr(4, 15, "'s': sprites");

caca_putstr(4, 16, "settings:");
caca_printf(4, 17, "'o': outline: %s",
outline == 0 ? "none" : outline == 1 ? "solid" : "thin");
caca_printf(4, 18, "'b': drawing boundaries: %s",
bounds == 0 ? "screen" : "infinite");
caca_printf(4, 19, "'d': dithering (%s)",
caca_get_dithering_name(dithering));

caca_putstr(4, yo - 2, "'q': quit");
}

static void demo_all(void)
{
static int i = 0;

int j, xo, yo, xa, ya, xb, yb, xc, yc;

i++;

caca_clear();

/* Draw the sun */
caca_set_color(CACA_COLOR_YELLOW, CACA_COLOR_BLACK);
xo = caca_get_width() / 4;
yo = caca_get_height() / 4 + 5 * sin(0.03*i);

for(j = 0; j < 16; j++)
{
xa = xo - (30 + sin(0.03*i) * 8) * sin(0.03*i + M_PI*j/8);
ya = yo + (15 + sin(0.03*i) * 4) * cos(0.03*i + M_PI*j/8);
caca_draw_thin_line(xo, yo, xa, ya);
}

j = 15 + sin(0.03*i) * 8;
caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLACK);
caca_fill_ellipse(xo, yo, j, j / 2, '#');
caca_set_color(CACA_COLOR_YELLOW, CACA_COLOR_BLACK);
caca_draw_ellipse(xo, yo, j, j / 2, '#');

/* Draw the pyramid */
xo = caca_get_width() * 5 / 8;
yo = 2;

xa = caca_get_width() / 8 + sin(0.03*i) * 5;
ya = caca_get_height() / 2 + cos(0.03*i) * 5;

xb = caca_get_width() - 10 - cos(0.02*i) * 10;
yb = caca_get_height() * 3 / 4 - 5 + sin(0.02*i) * 5;

xc = caca_get_width() / 4 - sin(0.02*i) * 5;
yc = caca_get_height() * 3 / 4 + cos(0.02*i) * 5;

caca_set_color(CACA_COLOR_GREEN, CACA_COLOR_BLACK);
caca_fill_triangle(xo, yo, xb, yb, xa, ya, '%');
caca_set_color(CACA_COLOR_YELLOW, CACA_COLOR_BLACK);
caca_draw_thin_triangle(xo, yo, xb, yb, xa, ya);

caca_set_color(CACA_COLOR_RED, CACA_COLOR_BLACK);
caca_fill_triangle(xa, ya, xb, yb, xc, yc, '#');
caca_set_color(CACA_COLOR_YELLOW, CACA_COLOR_BLACK);
caca_draw_thin_triangle(xa, ya, xb, yb, xc, yc);

caca_set_color(CACA_COLOR_BLUE, CACA_COLOR_BLACK);
caca_fill_triangle(xo, yo, xb, yb, xc, yc, '%');
caca_set_color(CACA_COLOR_YELLOW, CACA_COLOR_BLACK);
caca_draw_thin_triangle(xo, yo, xb, yb, xc, yc);

/* Draw a background triangle */
xa = 2;
ya = 2;

xb = caca_get_width() - 3;
yb = caca_get_height() / 2;

xc = caca_get_width() / 3;
yc = caca_get_height() - 3;

caca_set_color(CACA_COLOR_CYAN, CACA_COLOR_BLACK);
caca_draw_thin_triangle(xa, ya, xb, yb, xc, yc);

xo = caca_get_width() / 2 + cos(0.027*i) * caca_get_width() / 3;
yo = caca_get_height() / 2 - sin(0.027*i) * caca_get_height() / 2;

caca_draw_thin_line(xa, ya, xo, yo);
caca_draw_thin_line(xb, yb, xo, yo);
caca_draw_thin_line(xc, yc, xo, yo);

/* Draw a sprite on the pyramid */
caca_draw_sprite(xo, yo, sprite, 0);

/* Draw a trail behind the foreground sprite */
for(j = i - 60; j < i; j++)
{
int delta = caca_rand(-5, 5);
caca_set_color(caca_rand(0, 15), caca_rand(0, 15));
caca_putchar(caca_get_width() / 2
+ cos(0.02*j) * (delta + caca_get_width() / 4),
caca_get_height() / 2
+ sin(0.02*j) * (delta + caca_get_height() / 3),
'#');
}

/* Draw foreground sprite */
caca_draw_sprite(caca_get_width() / 2 + cos(0.02*i) * caca_get_width() / 4,
caca_get_height() / 2 + sin(0.02*i) * caca_get_height() / 3,
sprite, 0);
}

static void demo_dots(void)
{
int xmax = caca_get_width() - 1;
int ymax = caca_get_height() - 1;
int i;
static char chars[10] =
{
'+', '-', '*', '#', 'X', '@', '%', '$', 'M', 'W'
};

for(i = 1000; i--;)
{
/* Putpixel */
caca_set_color(caca_rand(0, 15), caca_rand(0, 15));
caca_putchar(caca_rand(0, xmax), caca_rand(0, ymax),
chars[caca_rand(0, 9)]);
}
}

static void demo_color(void)
{
int i, j;
char buf[BUFSIZ];

caca_clear();
for(i = 0; i < 16; i++)
{
sprintf(buf, "'%c': %i (%s)", 'a' + i, i, caca_get_color_name(i));
caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_BLACK);
caca_putstr(4, i + (i >= 8 ? 4 : 3), buf);
for(j = 0; j < 16; j++)
{
caca_set_color(i, j);
caca_putstr((j >= 8 ? 41 : 40) + j * 2, i + (i >= 8 ? 4 : 3), "# ");
}
}
}

static void demo_lines(void)
{
int w = caca_get_width();
int h = caca_get_height();
int xa, ya, xb, yb;

if(bounds)
{
xa = caca_rand(- w, 2 * w); ya = caca_rand(- h, 2 * h);
xb = caca_rand(- w, 2 * w); yb = caca_rand(- h, 2 * h);
}
else
{
xa = caca_rand(0, w - 1); ya = caca_rand(0, h - 1);
xb = caca_rand(0, w - 1); yb = caca_rand(0, h - 1);
}

caca_set_color(caca_rand(0, 15), CACA_COLOR_BLACK);
if(outline > 1)
caca_draw_thin_line(xa, ya, xb, yb);
else
caca_draw_line(xa, ya, xb, yb, '#');
}

static void demo_boxes(void)
{
int w = caca_get_width();
int h = caca_get_height();
int xa, ya, xb, yb;

if(bounds)
{
xa = caca_rand(- w, 2 * w); ya = caca_rand(- h, 2 * h);
xb = caca_rand(- w, 2 * w); yb = caca_rand(- h, 2 * h);
}
else
{
xa = caca_rand(0, w - 1); ya = caca_rand(0, h - 1);
xb = caca_rand(0, w - 1); yb = caca_rand(0, h - 1);
}

caca_set_color(caca_rand(0, 15), caca_rand(0, 15));
caca_fill_box(xa, ya, xb, yb, '#');

caca_set_color(caca_rand(0, 15), CACA_COLOR_BLACK);
if(outline == 2)
caca_draw_thin_box(xa, ya, xb, yb);
else if(outline == 1)
caca_draw_box(xa, ya, xb, yb, '#');
}

static void demo_ellipses(void)
{
int w = caca_get_width();
int h = caca_get_height();
int x, y, a, b;

if(bounds)
{
x = caca_rand(- w, 2 * w); y = caca_rand(- h, 2 * h);
a = caca_rand(0, w); b = caca_rand(0, h);
}
else
{
do
{
x = caca_rand(0, w); y = caca_rand(0, h);
a = caca_rand(0, w); b = caca_rand(0, h);

} while(x - a < 0 || x + a >= w || y - b < 0 || y + b >= h);
}

caca_set_color(caca_rand(0, 15), caca_rand(0, 15));
caca_fill_ellipse(x, y, a, b, '#');

caca_set_color(caca_rand(0, 15), CACA_COLOR_BLACK);
if(outline == 2)
caca_draw_thin_ellipse(x, y, a, b);
else if(outline == 1)
caca_draw_ellipse(x, y, a, b, '#');
}

static void demo_triangles(void)
{
int w = caca_get_width();
int h = caca_get_height();
int xa, ya, xb, yb, xc, yc;

if(bounds)
{
xa = caca_rand(- w, 2 * w); ya = caca_rand(- h, 2 * h);
xb = caca_rand(- w, 2 * w); yb = caca_rand(- h, 2 * h);
xc = caca_rand(- w, 2 * w); yc = caca_rand(- h, 2 * h);
}
else
{

xa = caca_rand(0, w - 1); ya = caca_rand(0, h - 1);
xb = caca_rand(0, w - 1); yb = caca_rand(0, h - 1);
xc = caca_rand(0, w - 1); yc = caca_rand(0, h - 1);
}

caca_set_color(caca_rand(0, 15), caca_rand(0, 15));
caca_fill_triangle(xa, ya, xb, yb, xc, yc, '#');

caca_set_color(caca_rand(0, 15), CACA_COLOR_BLACK);
if(outline == 2)
caca_draw_thin_triangle(xa, ya, xb, yb, xc, yc);
else if(outline == 1)
caca_draw_triangle(xa, ya, xb, yb, xc, yc, '#');
}

static void demo_sprites(void)
{
caca_draw_sprite(caca_rand(0, caca_get_width() - 1),
caca_rand(0, caca_get_height() - 1), sprite, 0);
}

#if 0
static void demo_render(void)
{
struct caca_bitmap *bitmap;
//short buffer[256*256];
//short *dest = buffer;
int buffer[256*256];
int *dest = buffer;
int x, y, z;
static int i = 0;

i = (i + 1) % 512;
z = i < 256 ? i : 511 - i;

for(x = 0; x < 256; x++)
for(y = 0; y < 256; y++)
{
//*dest++ = ((x >> 3) << 11) | ((y >> 2) << 5) | ((z >> 3));
*dest++ = (x << 16) | (y << 8) | (z);
}

//bitmap = caca_create_bitmap(16, 256, 256, 2 * 256, 0xf800, 0x07e0, 0x001f, 0x0000);
bitmap = caca_create_bitmap(32, 256, 256, 4 * 256, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
caca_draw_bitmap(0, 0, caca_get_width() - 1, caca_get_height() - 1,
bitmap, buffer);
caca_free_bitmap(bitmap);
}
#endif

static void draw_circle(int *buffer, int xo, int yo, int r, int mask, int val);

static void demo_render(void)
{
struct caca_bitmap *bitmap;
int buffer[256*256];
int *dest;
int x, y, z, xo, yo;
static int i = 0;

i++;

dest = buffer;
for(x = 0; x < 256; x++)
for(y = 0; y < 256; y++)
{
*dest++ = 0xff000000;
}

/* red */
xo = 128 + 48 * sin(0.02 * i);
yo = 128 + 48 * cos(0.03 * i);
for(z = 0; z < 240; z++)
draw_circle(buffer, xo, yo, z, 0x00ff0000, 200 << 16);

/* green */
xo = 128 + 48 * sin(2 + 0.06 * i);
yo = 128 + 48 * cos(2 + 0.05 * i);
for(z = 0; z < 240; z++)
draw_circle(buffer, xo, yo, z, 0x0000ff00, 200 << 8);

/* blue */
xo = 128 + 48 * sin(1 + 0.04 * i);
yo = 128 + 48 * cos(1 + 0.03 * i);
for(z = 0; z < 240; z++)
draw_circle(buffer, xo, yo, z, 0x000000ff, 200);

bitmap = caca_create_bitmap(32, 256, 256, 4 * 256, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
caca_draw_bitmap(0, 0, caca_get_width() - 1, caca_get_height() - 1,
bitmap, (char *)buffer);
caca_free_bitmap(bitmap);
}

static void draw_circle(int *buffer, int x, int y, int r, int mask, int val)
{
int t, dx, dy;

#define POINT(X,Y) \
buffer[(X) + 256 * (Y)] = 0xff000000 | (buffer[(X) + 256 * (Y)] & ~mask) | val;

for(t = 0, dx = 0, dy = r; dx <= dy; dx++)
{
POINT(x - dx / 3, y - dy / 3);
POINT(x + dx / 3, y - dy / 3);
POINT(x - dx / 3, y + dy / 3);
POINT(x + dx / 3, y + dy / 3);

POINT(x - dy / 3, y - dx / 3);
POINT(x + dy / 3, y - dx / 3);
POINT(x - dy / 3, y + dx / 3);
POINT(x + dy / 3, y + dx / 3);

t += t > 0 ? dx - dy-- : dx;
}
}


+ 20
- 16
src/Makefile.am View File

@@ -1,14 +1,14 @@
# $Id$

include_HEADERS = caca.h
include_HEADERS = cucul.h caca.h

lib_LTLIBRARIES = libcaca.la
libcaca_la_SOURCES = \
caca.c \
caca.h \
caca_internals.h \
graphics.c \
event.c \
lib_LTLIBRARIES = libcucul.la libcaca.la
libcucul_la_SOURCES = \
cucul.c \
cucul.h \
cucul_internals.h \
char.c \
math.c \
line.c \
box.c \
@@ -16,15 +16,19 @@ libcaca_la_SOURCES = \
triangle.c \
sprite.c \
bitmap.c \
export.c \
time.c \
$(NULL)
libcaca_la_LDFLAGS = -no-undefined
libcaca_la_LIBADD = @CACA_LIBS@
libcucul_la_LDFLAGS = -no-undefined
libcucul_la_LIBADD = @CUCUL_LIBS@

if NEED_PIC
libcaca_pic_a = libcaca_pic.a
endif
lib_LIBRARIES = $(libcaca_pic_a)
libcaca_pic_a_SOURCES = $(libcaca_la_SOURCES)
libcaca_pic_a_CPPFLAGS = -fPIC -DPIC
libcaca_la_SOURCES = \
caca.c \
caca.h \
caca_internals.h \
graphics.c \
event.c \
$(NULL)
libcaca_la_LDFLAGS = -no-undefined
libcaca_la_LIBADD = libcucul.la @CACA_LIBS@


+ 52
- 58
src/bitmap.c View File

@@ -36,18 +36,11 @@ typedef unsigned int uint32_t;
#include <limits.h>
#include <string.h>

#include "cucul.h"
#include "cucul_internals.h"
#include "caca.h"
#include "caca_internals.h"

/*
* Global variables
*/
#if !defined(_DOXYGEN_SKIP_ME)
enum caca_feature _caca_background;
enum caca_feature _caca_dithering;
enum caca_feature _caca_antialiasing;
#endif

/*
* Local variables
*/
@@ -57,7 +50,7 @@ enum caca_feature _caca_antialiasing;
# define LOOKUP_HUE 16
#endif
static unsigned char hsv_distances[LOOKUP_VAL][LOOKUP_SAT][LOOKUP_HUE];
static enum caca_color lookup_colors[8];
static enum cucul_color lookup_colors[8];

static int const hsv_palette[] =
{
@@ -123,7 +116,7 @@ static int rgb_weight[] =
*/
static void mask2shift(unsigned int, int *, int *);

static void get_rgba_default(struct caca_bitmap const *, uint8_t *, int, int,
static void get_rgba_default(struct cucul_bitmap const *, uint8_t *, int, int,
unsigned int *, unsigned int *, unsigned int *,
unsigned int *);
static inline void rgb2hsv_default(int, int, int, int *, int *, int *);
@@ -151,14 +144,14 @@ static unsigned int get_random_dither(void);
static void increment_random_dither(void);

#if !defined(_DOXYGEN_SKIP_ME)
struct caca_bitmap
struct cucul_bitmap
{
int bpp, has_palette, has_alpha;
int w, h, pitch;
int rmask, gmask, bmask, amask;
int rright, gright, bright, aright;
int rleft, gleft, bleft, aleft;
void (*get_hsv)(struct caca_bitmap *, char *, int, int);
void (*get_hsv)(struct cucul_bitmap *, char *, int, int);
int red[256], green[256], blue[256], alpha[256];
float gamma;
int gammatab[4097];
@@ -196,7 +189,7 @@ static void mask2shift(unsigned int mask, int *right, int *left)
* Create a bitmap structure from its coordinates (depth, width, height and
* pitch) and pixel mask values. If the depth is 8 bits per pixel, the mask
* values are ignored and the colour palette should be set using the
* caca_set_bitmap_palette() function. For depths greater than 8 bits per
* cucul_set_bitmap_palette() function. For depths greater than 8 bits per
* pixel, a zero alpha mask causes the alpha values to be ignored.
*
* \param bpp Bitmap depth in bits per pixel.
@@ -209,19 +202,20 @@ static void mask2shift(unsigned int mask, int *right, int *left)
* \param amask Bitmask for alpha values.
* \return Bitmap object, or NULL upon error.
*/
struct caca_bitmap *caca_create_bitmap(unsigned int bpp, unsigned int w,
struct cucul_bitmap *cucul_create_bitmap(cucul_t *qq,
unsigned int bpp, unsigned int w,
unsigned int h, unsigned int pitch,
unsigned int rmask, unsigned int gmask,
unsigned int bmask, unsigned int amask)
{
struct caca_bitmap *bitmap;
struct cucul_bitmap *bitmap;
int i;

/* Minor sanity test */
if(!w || !h || !pitch || bpp > 32 || bpp < 8)
return NULL;

bitmap = malloc(sizeof(struct caca_bitmap));
bitmap = malloc(sizeof(struct cucul_bitmap));
if(!bitmap)
return NULL;

@@ -279,9 +273,9 @@ struct caca_bitmap *caca_create_bitmap(unsigned int bpp, unsigned int w,
* \param blue Array of 256 blue values.
* \param alpha Array of 256 alpha values.
*/
void caca_set_bitmap_palette(struct caca_bitmap *bitmap,
unsigned int red[], unsigned int green[],
unsigned int blue[], unsigned int alpha[])
void cucul_set_bitmap_palette(cucul_t *qq, struct cucul_bitmap *bitmap,
unsigned int red[], unsigned int green[],
unsigned int blue[], unsigned int alpha[])
{
int i, has_alpha = 0;

@@ -317,7 +311,7 @@ void caca_set_bitmap_palette(struct caca_bitmap *bitmap,
* \param bitmap Bitmap object.
* \param gamma Gamma value.
*/
void caca_set_bitmap_gamma(struct caca_bitmap *bitmap, float gamma)
void cucul_set_bitmap_gamma(cucul_t *qq, struct cucul_bitmap *bitmap, float gamma)
{
int i;

@@ -327,17 +321,17 @@ void caca_set_bitmap_gamma(struct caca_bitmap *bitmap, float gamma)
bitmap->gamma = gamma;

for(i = 0; i < 4096; i++)
bitmap->gammatab[i] = 4096.0 * caca_powf((float)i / 4096.0, 1.0 / gamma);
bitmap->gammatab[i] = 4096.0 * cucul_powf((float)i / 4096.0, 1.0 / gamma);
}

/**
* \brief Free the memory associated with a bitmap.
*
* Free the memory allocated by caca_create_bitmap().
* Free the memory allocated by cucul_create_bitmap().
*
* \param bitmap Bitmap object.
*/
void caca_free_bitmap(struct caca_bitmap *bitmap)
void cucul_free_bitmap(cucul_t *qq, struct cucul_bitmap *bitmap)
{
if(!bitmap)
return;
@@ -345,7 +339,7 @@ void caca_free_bitmap(struct caca_bitmap *bitmap)
free(bitmap);
}

static void get_rgba_default(struct caca_bitmap const *bitmap, uint8_t *pixels,
static void get_rgba_default(struct cucul_bitmap const *bitmap, uint8_t *pixels,
int x, int y, unsigned int *r, unsigned int *g,
unsigned int *b, unsigned int *a)
{
@@ -450,8 +444,8 @@ static inline int sq(int x)
* \param bitmap Bitmap object to be drawn.
* \param pixels Bitmap's pixels.
*/
void caca_draw_bitmap(int x1, int y1, int x2, int y2,
struct caca_bitmap const *bitmap, void *pixels)
void cucul_draw_bitmap(cucul_t *qq, int x1, int y1, int x2, int y2,
struct cucul_bitmap const *bitmap, void *pixels)
{
/* Current dithering method */
void (*_init_dither) (int);
@@ -501,39 +495,39 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2,
deltax = x2 - x1 + 1;
deltay = y2 - y1 + 1;

switch(_caca_dithering)
switch(qq->dithering)
{
case CACA_DITHERING_NONE:
case CUCUL_DITHERING_NONE:
_init_dither = init_no_dither;
_get_dither = get_no_dither;
_increment_dither = increment_no_dither;
break;

case CACA_DITHERING_ORDERED2:
case CUCUL_DITHERING_ORDERED2:
_init_dither = init_ordered2_dither;
_get_dither = get_ordered2_dither;
_increment_dither = increment_ordered2_dither;
break;

case CACA_DITHERING_ORDERED4:
case CUCUL_DITHERING_ORDERED4:
_init_dither = init_ordered4_dither;
_get_dither = get_ordered4_dither;
_increment_dither = increment_ordered4_dither;
break;

case CACA_DITHERING_ORDERED8:
case CUCUL_DITHERING_ORDERED8:
_init_dither = init_ordered8_dither;
_get_dither = get_ordered8_dither;
_increment_dither = increment_ordered8_dither;
break;

case CACA_DITHERING_RANDOM:
case CUCUL_DITHERING_RANDOM:
_init_dither = init_random_dither;
_get_dither = get_random_dither;
_increment_dither = increment_random_dither;
break;

case CACA_DITHERING_FSTEIN:
case CUCUL_DITHERING_FSTEIN:
_init_dither = init_no_dither;
_get_dither = get_no_dither;
_increment_dither = increment_no_dither;
@@ -544,19 +538,19 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2,
return;
}

fs_length = ((int)_caca_width <= x2 ? (int)_caca_width : x2) + 1;
fs_length = ((int)qq->width <= x2 ? (int)qq->width : x2) + 1;
floyd_steinberg = malloc(3 * (fs_length + 2) * sizeof(int));
memset(floyd_steinberg, 0, 3 * (fs_length + 2) * sizeof(int));
fs_r = floyd_steinberg + 1;
fs_g = fs_r + fs_length + 2;
fs_b = fs_g + fs_length + 2;

for(y = y1 > 0 ? y1 : 0; y <= y2 && y <= (int)_caca_height; y++)
for(y = y1 > 0 ? y1 : 0; y <= y2 && y <= (int)qq->height; y++)
{
int remain_r = 0, remain_g = 0, remain_b = 0;

for(x = x1 > 0 ? x1 : 0, _init_dither(y);
x <= x2 && x <= (int)_caca_width;
x <= x2 && x <= (int)qq->width;
x++)
{
unsigned int i;
@@ -566,13 +560,13 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2,
int fromx, fromy, tox, toy, myx, myy, dots, dist;
int error[3];

enum caca_color outfg = 0, outbg = 0;
enum cucul_color outfg = 0, outbg = 0;
char outch;

r = g = b = a = 0;

/* First get RGB */
if(_caca_antialiasing == CACA_ANTIALIASING_PREFILTER)
if(qq->antialiasing == CUCUL_ANTIALIASING_PREFILTER)
{
fromx = (x - x1) * w / deltax;
fromy = (y - y1) * h / deltay;
@@ -623,7 +617,7 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2,
continue;
}

if(_caca_dithering == CACA_DITHERING_FSTEIN)
if(qq->dithering == CUCUL_DITHERING_FSTEIN)
{
r += remain_r;
g += remain_g;
@@ -653,7 +647,7 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2,
bg_g = rgb_palette[outbg * 3 + 1];
bg_b = rgb_palette[outbg * 3 + 2];

if(_caca_background == CACA_BACKGROUND_SOLID)
if(qq->background == CUCUL_BACKGROUND_SOLID)
{
distmin = INT_MAX;
for(i = 0; i < 16; i++)
@@ -692,7 +686,7 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2,
}
outch = density_chars[4 * ch];

if(_caca_dithering == CACA_DITHERING_FSTEIN)
if(qq->dithering == CUCUL_DITHERING_FSTEIN)
{
error[0] = r - (fg_r * ch + bg_r * ((2*DCHMAX-1) - ch)) / (2*DCHMAX-1);
error[1] = g - (fg_g * ch + bg_g * ((2*DCHMAX-1) - ch)) / (2*DCHMAX-1);
@@ -703,7 +697,7 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2,
{
unsigned int lum = r; if(g > lum) lum = g; if(b > lum) lum = b;
outfg = outbg;
outbg = CACA_COLOR_BLACK;
outbg = CUCUL_COLOR_BLACK;

ch = lum * DCHMAX / 0x1000;
if(ch < 0)
@@ -712,7 +706,7 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2,
ch = DCHMAX - 1;
outch = density_chars[4 * ch];

if(_caca_dithering == CACA_DITHERING_FSTEIN)
if(qq->dithering == CUCUL_DITHERING_FSTEIN)
{
error[0] = r - bg_r * ch / (DCHMAX-1);
error[1] = g - bg_g * ch / (DCHMAX-1);
@@ -720,7 +714,7 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2,
}
}

if(_caca_dithering == CACA_DITHERING_FSTEIN)
if(qq->dithering == CUCUL_DITHERING_FSTEIN)
{
remain_r = fs_r[x+1] + 7 * error[0] / 16;
remain_g = fs_g[x+1] + 7 * error[1] / 16;
@@ -737,8 +731,8 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2,
}

/* Now output the character */
caca_set_color(outfg, outbg);
caca_putchar(x, y, outch);
cucul_set_color(qq, outfg, outbg);
cucul_putchar(qq, x, y, outch);

_increment_dither();
}
@@ -749,21 +743,21 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2,
}

#if !defined(_DOXYGEN_SKIP_ME)
int _caca_init_bitmap(void)
int _cucul_init_bitmap(void)
{
unsigned int v, s, h;

/* These ones are constant */
lookup_colors[0] = CACA_COLOR_BLACK;
lookup_colors[1] = CACA_COLOR_DARKGRAY;
lookup_colors[2] = CACA_COLOR_LIGHTGRAY;
lookup_colors[3] = CACA_COLOR_WHITE;
lookup_colors[0] = CUCUL_COLOR_BLACK;
lookup_colors[1] = CUCUL_COLOR_DARKGRAY;
lookup_colors[2] = CUCUL_COLOR_LIGHTGRAY;
lookup_colors[3] = CUCUL_COLOR_WHITE;

/* These ones will be overwritten */
lookup_colors[4] = CACA_COLOR_MAGENTA;
lookup_colors[5] = CACA_COLOR_LIGHTMAGENTA;
lookup_colors[6] = CACA_COLOR_RED;
lookup_colors[7] = CACA_COLOR_LIGHTRED;
lookup_colors[4] = CUCUL_COLOR_MAGENTA;
lookup_colors[5] = CUCUL_COLOR_LIGHTMAGENTA;
lookup_colors[6] = CUCUL_COLOR_RED;
lookup_colors[7] = CUCUL_COLOR_LIGHTRED;

for(v = 0; v < LOOKUP_VAL; v++)
for(s = 0; s < LOOKUP_SAT; s++)
@@ -807,7 +801,7 @@ int _caca_init_bitmap(void)
return 0;
}

int _caca_end_bitmap(void)
int _cucul_end_bitmap(void)
{
return 0;
}
@@ -941,7 +935,7 @@ static void init_random_dither(int line)

static unsigned int get_random_dither(void)
{
return caca_rand(0x00, 0xff);
return cucul_rand(0x00, 0xff);
}

static void increment_random_dither(void)


+ 28
- 22
src/box.c View File

@@ -19,10 +19,16 @@

#include "config.h"

#if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME)
# include <inttypes.h>
#else
typedef unsigned char uint8_t;
#endif

#include <stdlib.h>

#include "caca.h"
#include "caca_internals.h"
#include "cucul.h"
#include "cucul_internals.h"

/**
* \brief Draw a box on the screen using the given character.
@@ -34,12 +40,12 @@
* \param c Character to draw the box outline with.
* \return void
*/
void caca_draw_box(int x1, int y1, int x2, int y2, char c)
void cucul_draw_box(cucul_t *qq, int x1, int y1, int x2, int y2, char c)
{
caca_draw_line(x1, y1, x1, y2, c);
caca_draw_line(x1, y2, x2, y2, c);
caca_draw_line(x2, y2, x2, y1, c);
caca_draw_line(x2, y1, x1, y1, c);
cucul_draw_line(qq, x1, y1, x1, y2, c);
cucul_draw_line(qq, x1, y2, x2, y2, c);
cucul_draw_line(qq, x2, y2, x2, y1, c);
cucul_draw_line(qq, x2, y1, x1, y1, c);
}

/**
@@ -51,7 +57,7 @@ void caca_draw_box(int x1, int y1, int x2, int y2, char c)
* \param y2 Y coordinate of the lower-right corner of the box.
* \return void
*/
void caca_draw_thin_box(int x1, int y1, int x2, int y2)
void cucul_draw_thin_box(cucul_t *qq, int x1, int y1, int x2, int y2)
{
int x, y, xmax, ymax;

@@ -67,8 +73,8 @@ void caca_draw_thin_box(int x1, int y1, int x2, int y2)
y1 = y2; y2 = tmp;
}

xmax = _caca_width - 1;
ymax = _caca_height - 1;
xmax = qq->width - 1;
ymax = qq->height - 1;

if(x2 < 0 || y2 < 0 || x1 > xmax || y1 > ymax)
return;
@@ -76,32 +82,32 @@ void caca_draw_thin_box(int x1, int y1, int x2, int y2)
/* Draw edges */
if(y1 >= 0)
for(x = x1 < 0 ? 1 : x1 + 1; x < x2 && x < xmax; x++)
caca_putchar(x, y1, '-');
cucul_putchar(qq, x, y1, '-');

if(y2 <= ymax)
for(x = x1 < 0 ? 1 : x1 + 1; x < x2 && x < xmax; x++)
caca_putchar(x, y2, '-');
cucul_putchar(qq, x, y2, '-');

if(x1 >= 0)
for(y = y1 < 0 ? 1 : y1 + 1; y < y2 && y < ymax; y++)
caca_putchar(x1, y, '|');
cucul_putchar(qq, x1, y, '|');

if(x2 <= xmax)
for(y = y1 < 0 ? 1 : y1 + 1; y < y2 && y < ymax; y++)
caca_putchar(x2, y, '|');
cucul_putchar(qq, x2, y, '|');

/* Draw corners */
if(x1 >= 0 && y1 >= 0)
caca_putchar(x1, y1, ',');
cucul_putchar(qq, x1, y1, ',');

if(x1 >= 0 && y2 <= ymax)
caca_putchar(x1, y2, '`');
cucul_putchar(qq, x1, y2, '`');

if(x2 <= xmax && y1 >= 0)
caca_putchar(x2, y1, '.');
cucul_putchar(qq, x2, y1, '.');

if(x2 <= xmax && y2 <= ymax)
caca_putchar(x2, y2, '\'');
cucul_putchar(qq, x2, y2, '\'');
}

/**
@@ -114,7 +120,7 @@ void caca_draw_thin_box(int x1, int y1, int x2, int y2)
* \param c Character to fill the box with.
* \return void
*/
void caca_fill_box(int x1, int y1, int x2, int y2, char c)
void cucul_fill_box(cucul_t *qq, int x1, int y1, int x2, int y2, char c)
{
int x, y, xmax, ymax;

@@ -130,8 +136,8 @@ void caca_fill_box(int x1, int y1, int x2, int y2, char c)
y1 = y2; y2 = tmp;
}

xmax = _caca_width - 1;
ymax = _caca_height - 1;
xmax = qq->width - 1;
ymax = qq->height - 1;

if(x2 < 0 || y2 < 0 || x1 > xmax || y1 > ymax)
return;
@@ -143,6 +149,6 @@ void caca_fill_box(int x1, int y1, int x2, int y2, char c)

for(y = y1; y <= y2; y++)
for(x = x1; x <= x2; x++)
caca_putchar(x, y, c);
cucul_putchar(qq, x, y, c);
}


+ 68
- 294
src/caca.c View File

@@ -21,6 +21,12 @@

#include "config.h"

#if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME)
# include <inttypes.h>
#else
typedef unsigned char uint8_t;
#endif

#if defined(USE_SLANG)
# if defined(HAVE_SLANG_SLANG_H)
# include <slang/slang.h>
@@ -51,16 +57,13 @@
#include <stdlib.h>
#include <string.h>

#include "cucul.h"
#include "cucul_internals.h"
#include "caca.h"
#include "caca_internals.h"

static void caca_init_driver(void);
static void caca_init_features(void);
static void caca_init_terminal(void);

#if !defined(_DOXYGEN_SKIP_ME)
enum caca_driver _caca_driver;
#endif
static void caca_init_driver(caca_t *kk);
static void caca_init_terminal(caca_t *kk);

#if defined(USE_NCURSES)
static mmask_t oldmask;
@@ -70,31 +73,23 @@ static mmask_t oldmask;
static CONSOLE_CURSOR_INFO cci;
#endif

/** \brief Initialise \e libcaca.
*
* This function initialises internal \e libcaca structures and the backend
* that will be used for subsequent graphical operations. It must be the
* first \e libcaca function to be called in a function. caca_end() should
* be called at the end of the program to free all allocated resources.
*
* \return 0 upon success, a non-zero value if an error occurs.
*/
int caca_init(void)
caca_t * caca_attach(cucul_t * qq)
{
caca_t *kk = malloc(sizeof(caca_t));

#if defined(USE_NCURSES)
mmask_t newmask;
#endif

caca_init_driver();
caca_init_driver(kk);

if(_caca_driver == CACA_DRIVER_NONE)
return -1;
if(kk->driver == CACA_DRIVER_NONE)
return NULL;

caca_init_features();
caca_init_terminal();
caca_init_terminal(kk);

#if defined(USE_SLANG)
if(_caca_driver == CACA_DRIVER_SLANG)
if(kk->driver == CACA_DRIVER_SLANG)
{
/* Initialise slang library */
SLsig_block_signals();
@@ -103,7 +98,7 @@ int caca_init(void)
if(SLkp_init() == -1)
{
SLsig_unblock_signals();
return -1;
return NULL;
}

SLang_init_tty(-1, 0, 1);
@@ -111,7 +106,7 @@ int caca_init(void)
if(SLsmg_init_smg() == -1)
{
SLsig_unblock_signals();
return -1;
return NULL;
}

SLsig_unblock_signals();
@@ -129,7 +124,7 @@ int caca_init(void)
else
#endif
#if defined(USE_NCURSES)
if(_caca_driver == CACA_DRIVER_NCURSES)
if(kk->driver == CACA_DRIVER_NCURSES)
{
initscr();
keypad(stdscr, TRUE);
@@ -150,7 +145,7 @@ int caca_init(void)
else
#endif
#if defined(USE_CONIO)
if(_caca_driver == CACA_DRIVER_CONIO)
if(kk->driver == CACA_DRIVER_CONIO)
{
_wscroll = 0;
_setcursortype(_NOCURSOR);
@@ -159,14 +154,17 @@ int caca_init(void)
else
#endif
#if defined(USE_X11)
if(_caca_driver == CACA_DRIVER_X11)
if(kk->driver == CACA_DRIVER_X11)
{
/* Nothing to do */
kk->x11.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask
| ButtonReleaseMask | PointerMotionMask | StructureNotifyMask
| ExposureMask;
}
else
#endif
#if defined(USE_WIN32)
if(_caca_driver == CACA_DRIVER_WIN32)
if(kk->driver == CACA_DRIVER_WIN32)
{
/* This call is allowed to fail in cas we already have a console */
AllocConsole();
@@ -177,7 +175,7 @@ int caca_init(void)
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if(win32_hout == INVALID_HANDLE_VALUE)
return -1;
return NULL;

GetConsoleCursorInfo(win32_hout, &cci);
cci.bVisible = FALSE;
@@ -188,14 +186,7 @@ int caca_init(void)
else
#endif
#if defined(USE_GL)
if(_caca_driver == CACA_DRIVER_GL)
{
/* Nothing to do */
}
else
#endif
#if defined(USE_NULL)
if(_caca_driver == CACA_DRIVER_NULL)
if(kk->driver == CACA_DRIVER_GL)
{
/* Nothing to do */
}
@@ -205,183 +196,24 @@ int caca_init(void)
/* Dummy */
}

if(_caca_init_graphics())
return -1;

if(_caca_init_bitmap())
return -1;

return 0;
}

/** \brief Get the screen width.
*
* This function returns the current screen width, in character cells.
*
* \return The screen width.
*/
unsigned int caca_get_width(void)
{
return _caca_width;
}

/** \brief Get the screen height.
*
* This function returns the current screen height, in character cells.
*
* \return The screen height.
*/
unsigned int caca_get_height(void)
{
return _caca_height;
}

/** \brief Translate a colour index into the colour's name.
*
* This function translates a caca_color enum into a human-readable
* description string of the associated colour.
*
* \param color The colour value.
* \return A static string containing the colour's name.
*/
char const *caca_get_color_name(enum caca_color color)
{
static char const *color_names[] =
{
"black",
"blue",
"green",
"cyan",
"red",
"magenta",
"brown",
"light gray",
"dark gray",
"light blue",
"light green",
"light cyan",
"light red",
"light magenta",
"yellow",
"white",
};

if(color < 0 || color > 15)
return "unknown";

return color_names[color];
}

/** \brief Get the current value of a feature.
*
* This function retrieves the value of an internal \e libcaca feature. A
* generic feature value is expected, such as CACA_ANTIALIASING.
*
* \param feature The requested feature.
* \return The current value of the feature or CACA_FEATURE_UNKNOWN if an
* error occurred..
*/
enum caca_feature caca_get_feature(enum caca_feature feature)
{
switch(feature)
{
case CACA_BACKGROUND:
return _caca_background;
case CACA_ANTIALIASING:
return _caca_antialiasing;
case CACA_DITHERING:
return _caca_dithering;

default:
return CACA_FEATURE_UNKNOWN;
}
}

/** \brief Set a feature.
*
* This function sets an internal \e libcaca feature such as the antialiasing
* or dithering modes. If a specific feature such as CACA_DITHERING_RANDOM,
* caca_set_feature() will set it immediately. If a generic feature is given
* instead, such as CACA_DITHERING, the default value will be used instead.
*
* \param feature The requested feature.
*/
void caca_set_feature(enum caca_feature feature)
{
switch(feature)
{
case CACA_BACKGROUND:
feature = CACA_BACKGROUND_SOLID;
case CACA_BACKGROUND_BLACK:
case CACA_BACKGROUND_SOLID:
_caca_background = feature;
break;

case CACA_ANTIALIASING:
feature = CACA_ANTIALIASING_PREFILTER;
case CACA_ANTIALIASING_NONE:
case CACA_ANTIALIASING_PREFILTER:
_caca_antialiasing = feature;
break;

case CACA_DITHERING:
feature = CACA_DITHERING_FSTEIN;
case CACA_DITHERING_NONE:
case CACA_DITHERING_ORDERED2:
case CACA_DITHERING_ORDERED4:
case CACA_DITHERING_ORDERED8:
case CACA_DITHERING_RANDOM:
case CACA_DITHERING_FSTEIN:
_caca_dithering = feature;
break;

case CACA_FEATURE_UNKNOWN:
break;
}
}

/** \brief Translate a feature value into the feature's name.
*
* This function translates a caca_feature enum into a human-readable
* description string of the associated feature.
*
* \param feature The feature value.
* \return A static string containing the feature's name.
*/
char const *caca_get_feature_name(enum caca_feature feature)
{
switch(feature)
{
case CACA_BACKGROUND_BLACK: return "black background";
case CACA_BACKGROUND_SOLID: return "solid background";
qq->refcount++;
kk->qq = qq;

case CACA_ANTIALIASING_NONE: return "no antialiasing";
case CACA_ANTIALIASING_PREFILTER: return "prefilter antialiasing";
kk->resize = 0;
kk->resize_event = 0;

case CACA_DITHERING_NONE: return "no dithering";
case CACA_DITHERING_ORDERED2: return "2x2 ordered dithering";
case CACA_DITHERING_ORDERED4: return "4x4 ordered dithering";
case CACA_DITHERING_ORDERED8: return "8x8 ordered dithering";
case CACA_DITHERING_RANDOM: return "random dithering";
case CACA_DITHERING_FSTEIN: return "Floyd-Steinberg dithering";
if(_caca_init_graphics(kk))
return NULL;

default: return "unknown";
}
return kk;
}

/** \brief Uninitialise \e libcaca.
*
* This function frees all resources allocated by caca_init(). After
* caca_end() has been called, no other \e libcaca functions may be used
* unless a new call to caca_init() is done.
*/
void caca_end(void)
void caca_detach(caca_t *kk)
{
_caca_end_bitmap();
_caca_end_graphics();
_caca_end_graphics(kk);

#if defined(USE_SLANG)
if(_caca_driver == CACA_DRIVER_SLANG)
if(kk->driver == CACA_DRIVER_SLANG)
{
SLtt_set_mouse_mode(0, 0);
SLtt_set_cursor_visibility(1);
@@ -391,7 +223,7 @@ void caca_end(void)
else
#endif
#if defined(USE_NCURSES)
if(_caca_driver == CACA_DRIVER_NCURSES)
if(kk->driver == CACA_DRIVER_NCURSES)
{
mousemask(oldmask, NULL);
curs_set(1);
@@ -401,7 +233,7 @@ void caca_end(void)
else
#endif
#if defined(USE_CONIO)
if(_caca_driver == CACA_DRIVER_CONIO)
if(kk->driver == CACA_DRIVER_CONIO)
{
_wscroll = 1;
textcolor((enum COLORS)WHITE);
@@ -413,14 +245,14 @@ void caca_end(void)
else
#endif
#if defined(USE_X11)
if(_caca_driver == CACA_DRIVER_X11)
if(kk->driver == CACA_DRIVER_X11)
{
/* Nothing to do */
}
else
#endif
#if defined(USE_WIN32)
if(_caca_driver == CACA_DRIVER_WIN32)
if(kk->driver == CACA_DRIVER_WIN32)
{
SetConsoleTextAttribute(win32_hout, FOREGROUND_INTENSITY
| FOREGROUND_RED
@@ -433,14 +265,7 @@ void caca_end(void)
else
#endif
#if defined(USE_GL)
if(_caca_driver == CACA_DRIVER_GL)
{
/* Nothing to do */
}
else
#endif
#if defined(USE_NULL)
if(_caca_driver == CACA_DRIVER_NULL)
if(kk->driver == CACA_DRIVER_GL)
{
/* Nothing to do */
}
@@ -449,13 +274,17 @@ void caca_end(void)
{
/* Dummy */
}

kk->qq->refcount--;

free(kk);
}

/*
* XXX: The following functions are local.
*/

static void caca_init_driver(void)
static void caca_init_driver(caca_t *kk)
{
#if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP)
char *var = getenv("CACA_DRIVER");
@@ -465,52 +294,47 @@ static void caca_init_driver(void)
{
#if defined(USE_WIN32)
if(!strcasecmp(var, "win32"))
_caca_driver = CACA_DRIVER_WIN32;
kk->driver = CACA_DRIVER_WIN32;
else
#endif
#if defined(USE_CONIO)
if(!strcasecmp(var, "conio"))
_caca_driver = CACA_DRIVER_CONIO;
kk->driver = CACA_DRIVER_CONIO;
else
#endif
#if defined(USE_X11)
if(!strcasecmp(var, "x11"))
_caca_driver = CACA_DRIVER_X11;
kk->driver = CACA_DRIVER_X11;
else
#endif
#if defined(USE_GL)
if(!strcasecmp(var, "gl"))
_caca_driver = CACA_DRIVER_GL;
kk->driver = CACA_DRIVER_GL;
else
#endif
#if defined(USE_SLANG)
if(!strcasecmp(var, "slang"))
_caca_driver = CACA_DRIVER_SLANG;
kk->driver = CACA_DRIVER_SLANG;
else
#endif
#if defined(USE_NCURSES)
if(!strcasecmp(var, "ncurses"))
_caca_driver = CACA_DRIVER_NCURSES;
else
#endif
#if defined(USE_NULL)
if(!strcasecmp(var, "null"))
_caca_driver = CACA_DRIVER_NULL;
kk->driver = CACA_DRIVER_NCURSES;
else
#endif

_caca_driver = CACA_DRIVER_NONE;
kk->driver = CACA_DRIVER_NONE;

return;
}
#endif

#if defined(USE_WIN32)
_caca_driver = CACA_DRIVER_WIN32;
kk->driver = CACA_DRIVER_WIN32;
return;
#endif
#if defined(USE_CONIO)
_caca_driver = CACA_DRIVER_CONIO;
kk->driver = CACA_DRIVER_CONIO;
return;
#endif
#if defined(USE_X11)
@@ -518,7 +342,7 @@ static void caca_init_driver(void)
if(getenv("DISPLAY") && *(getenv("DISPLAY")))
#endif
{
_caca_driver = CACA_DRIVER_X11;
kk->driver = CACA_DRIVER_X11;
return;
}
#endif
@@ -527,74 +351,24 @@ static void caca_init_driver(void)
if(getenv("DISPLAY") && *(getenv("DISPLAY")))
#endif
{
_caca_driver = CACA_DRIVER_GL;
kk->driver = CACA_DRIVER_GL;
return;
}
#endif
#if defined(USE_SLANG)
_caca_driver = CACA_DRIVER_SLANG;
kk->driver = CACA_DRIVER_SLANG;
return;
#endif
#if defined(USE_NCURSES)
_caca_driver = CACA_DRIVER_NCURSES;
return;
#endif
#if defined(USE_NULL)
_caca_driver = CACA_DRIVER_NULL;
kk->driver = CACA_DRIVER_NCURSES;
return;
#endif

_caca_driver = CACA_DRIVER_NONE;
kk->driver = CACA_DRIVER_NONE;
return;
}

static void caca_init_features(void)
{
/* FIXME: if strcasecmp isn't available, use strcmp */
#if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP)
char *var;
#endif

caca_set_feature(CACA_BACKGROUND);
caca_set_feature(CACA_ANTIALIASING);
caca_set_feature(CACA_DITHERING);

#if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP)
if((var = getenv("CACA_BACKGROUND")) && *var)
{
if(!strcasecmp("black", var))
caca_set_feature(CACA_BACKGROUND_BLACK);
else if(!strcasecmp("solid", var))
caca_set_feature(CACA_BACKGROUND_SOLID);
}

if((var = getenv("CACA_ANTIALIASING")) && *var)
{
if(!strcasecmp("none", var))
caca_set_feature(CACA_ANTIALIASING_NONE);
else if(!strcasecmp("prefilter", var))
caca_set_feature(CACA_ANTIALIASING_PREFILTER);
}

if((var = getenv("CACA_DITHERING")) && *var)
{
if(!strcasecmp("none", var))
caca_set_feature(CACA_DITHERING_NONE);
else if(!strcasecmp("ordered2", var))
caca_set_feature(CACA_DITHERING_ORDERED2);
else if(!strcasecmp("ordered4", var))
caca_set_feature(CACA_DITHERING_ORDERED4);
else if(!strcasecmp("ordered8", var))
caca_set_feature(CACA_DITHERING_ORDERED8);
else if(!strcasecmp("random", var))
caca_set_feature(CACA_DITHERING_RANDOM);
else if(!strcasecmp("fstein", var))
caca_set_feature(CACA_DITHERING_FSTEIN);
}
#endif
}

static void caca_init_terminal(void)
static void caca_init_terminal(caca_t *kk)
{
#if defined(HAVE_GETENV) && defined(HAVE_PUTENV) && \
(defined(USE_SLANG) || defined(USE_NCURSES))
@@ -602,10 +376,10 @@ static void caca_init_terminal(void)
#endif

#if defined(USE_SLANG)
if(_caca_driver != CACA_DRIVER_SLANG)
if(kk->driver != CACA_DRIVER_SLANG)
#endif
#if defined(USE_NCURSES)
if(_caca_driver != CACA_DRIVER_NCURSES)
if(kk->driver != CACA_DRIVER_NCURSES)
#endif
return;

@@ -620,7 +394,7 @@ static void caca_init_terminal(void)
if(colorterm && !strcmp(colorterm, "gnome-terminal"))
{
#if defined(USE_NCURSES)
if(_caca_driver == CACA_DRIVER_NCURSES)
if(kk->driver == CACA_DRIVER_NCURSES)
{
SCREEN *screen;
screen = newterm("xterm-16color", stdout, stdin);
@@ -638,7 +412,7 @@ static void caca_init_terminal(void)
if(other)
{
#if defined(USE_NCURSES)
if(_caca_driver == CACA_DRIVER_NCURSES)
if(kk->driver == CACA_DRIVER_NCURSES)
{
SCREEN *screen;
screen = newterm("xterm-16color", stdout, stdin);


+ 40
- 203
src/caca.h View File

@@ -1,6 +1,6 @@
/*
* libcaca ASCII-Art library
* Copyright (c) 2002, 2003 Sam Hocevar <sam@zoy.org>
* Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
* All Rights Reserved
*
* This library is free software; you can redistribute it and/or
@@ -29,7 +29,7 @@
* Mac OS X) using either the slang library or the ncurses library, on DOS
* using the conio library, and on Windows systems using either slang or
* ncurses (through Cygwin emulation) or conio. There is also a native X11
* driver, and an OpenGL driver (through freeglut) that does not require a
* driver, and an OpenGL driver (through freeglut) that does not require a
* text terminal.
*
* \e libcaca is free software, released under the Do What The Fuck You
@@ -40,14 +40,18 @@
*
* \section api The libcaca API
*
* The complete \e libcaca programming interface is available from the
* caca.h header.
* \e libcaca relies on a low-level, device independent library, called
* \e libcucul. \e libcucul can be used alone as a simple ASCII and/or
* Unicode compositing canvas.
*
* The complete \e libcucul and \e libcaca programming interface is
* available from the cucul.h and caca.h headers.
*
* \section env Environment variables
*
* Some environment variables can be used to change the behaviour of
* \e libcaca without having to modify the program which uses it. These
* variables are:
* \e libcaca or \e libcucul without having to modify the program which
* uses them. These variables are:
*
* \li \b CACA_DRIVER: set the backend video driver. In order of preference:
* - \c conio uses the DOS conio.h interface.
@@ -57,28 +61,20 @@
* - \c gl uses freeglut and opengl libraries.
* - \c null uses nothing at all, and will display nothing as well.
*
* \li \b CACA_GEOMETRY: set the video display size. The format of this
* variable must be XxY, with X and Y being integer values. This option
* currently only works with the X11 and the GL driver.
*
* \li \b CACA_FONT: set the rendered font. The format of this variable is
* implementation dependent, but since it currently only works with the
* X11 driver, an X11 font name such as "fixed" or "5x7" is expected.
*
* \li \b CACA_BACKGROUND: set the background type.
* \li \b CUCUL_BACKGROUND: set the background type.
* - \c solid uses solid coloured backgrounds for all characters. This
* feature does not work with all terminal emulators. This is the
* default choice.
* - \c black uses only black backgrounds to render characters.
*
* \li \b CACA_ANTIALIASING: set the antialiasing mode. Antialiasing
* \li \b CUCUL_ANTIALIASING: set the antialiasing mode. Antialiasing
* smoothens the rendered image and avoids the commonly seen staircase
* effect.
* - \c none disables antialiasing.
* - \c prefilter uses a simple prefilter antialiasing method. This is
* the default choice.
*
* \li \b CACA_DITHERING: set the dithering mode. Dithering is necessary
* \li \b CUCUL_DITHERING: set the dithering mode. Dithering is necessary
* when rendering a picture that has more colours than the usually
* available palette.
* - \c none disables dithering.
@@ -87,84 +83,26 @@
* default choice.
* - \c ordered8 uses a 8x8 Bayer matrix for dithering.
* - \c random uses random dithering.
*
* \li \b CACA_GEOMETRY: set the video display size. The format of this
* variable must be XxY, with X and Y being integer values. This option
* currently only works with the X11 and the GL driver.
*
* \li \b CACA_FONT: set the rendered font. The format of this variable is
* implementation dependent, but since it currently only works with the
* X11 driver, an X11 font name such as "fixed" or "5x7" is expected.
*/

#ifndef __CACA_H__
#define __CACA_H__

#include <cucul.h>

#ifdef __cplusplus
extern "C"
{
#endif

/** \brief Colour definitions.
*
* Colours that can be used with caca_set_color().
*/
enum caca_color
{
CACA_COLOR_BLACK = 0, /**< The colour index for black. */
CACA_COLOR_BLUE = 1, /**< The colour index for blue. */
CACA_COLOR_GREEN = 2, /**< The colour index for green. */
CACA_COLOR_CYAN = 3, /**< The colour index for cyan. */
CACA_COLOR_RED = 4, /**< The colour index for red. */
CACA_COLOR_MAGENTA = 5, /**< The colour index for magenta. */
CACA_COLOR_BROWN = 6, /**< The colour index for brown. */
CACA_COLOR_LIGHTGRAY = 7, /**< The colour index for light gray. */
CACA_COLOR_DARKGRAY = 8, /**< The colour index for dark gray. */
CACA_COLOR_LIGHTBLUE = 9, /**< The colour index for blue. */
CACA_COLOR_LIGHTGREEN = 10, /**< The colour index for light green. */
CACA_COLOR_LIGHTCYAN = 11, /**< The colour index for light cyan. */
CACA_COLOR_LIGHTRED = 12, /**< The colour index for light red. */
CACA_COLOR_LIGHTMAGENTA = 13, /**< The colour index for light magenta. */
CACA_COLOR_YELLOW = 14, /**< The colour index for yellow. */
CACA_COLOR_WHITE = 15 /**< The colour index for white. */
};

/** \brief Internal features.
*
* Internal libcaca features such as the rendering method or the dithering
* mode.
*/
enum caca_feature
{
CACA_BACKGROUND = 0x10, /**< Properties of background characters. */
CACA_BACKGROUND_BLACK = 0x11, /**< Draw only black backgrounds. */
CACA_BACKGROUND_SOLID = 0x12, /**< Draw coloured solid backgorunds. */
#define CACA_BACKGROUND_MIN 0x11 /**< First background property */
#define CACA_BACKGROUND_MAX 0x12 /**< Last background property */

CACA_ANTIALIASING = 0x20, /**< Antialiasing features. */
CACA_ANTIALIASING_NONE = 0x21, /**< No antialiasing. */
CACA_ANTIALIASING_PREFILTER = 0x22, /**< Prefilter antialiasing. */
#define CACA_ANTIALIASING_MIN 0x21 /**< First antialiasing feature. */
#define CACA_ANTIALIASING_MAX 0x22 /**< Last antialiasing feature. */

CACA_DITHERING = 0x30, /**< Dithering methods */
CACA_DITHERING_NONE = 0x31, /**< No dithering. */
CACA_DITHERING_ORDERED2 = 0x32, /**< Ordered 2x2 Bayer dithering. */
CACA_DITHERING_ORDERED4 = 0x33, /**< Ordered 4x4 Bayer dithering. */
CACA_DITHERING_ORDERED8 = 0x34, /**< Ordered 8x8 Bayer dithering. */
CACA_DITHERING_RANDOM = 0x35, /**< Random dithering. */
CACA_DITHERING_FSTEIN = 0x36, /**< Floyd-Steinberg dithering. */
#define CACA_DITHERING_MIN 0x31 /**< First dithering feature. */
#define CACA_DITHERING_MAX 0x36 /**< Last dithering feature. */

CACA_FEATURE_UNKNOWN = 0xffff /**< Unknown feature. */
};

/*
* Backwards compatibility macros
*/
#if !defined(_DOXYGEN_SKIP_ME)
#define caca_dithering caca_feature
#define caca_set_dithering caca_set_feature
#define caca_get_dithering_name caca_get_feature_name
#define CACA_DITHER_NONE CACA_DITHERING_NONE
#define CACA_DITHER_ORDERED CACA_DITHERING_ORDERED8
#define CACA_DITHER_RANDOM CACA_DITHERING_RANDOM
#endif

/** \brief User events.
*
* Event types returned by caca_get_event().
@@ -228,28 +166,25 @@ enum caca_key
CACA_KEY_F15 = 296 /**< The F15 key. */
};

typedef struct caca_context caca_t;

/** \defgroup basic Basic functions
*
* These functions provide the basic \e libcaca routines for library
* initialisation, system information retrieval and configuration.
*
* @{ */
int caca_init(void);
void caca_set_delay(unsigned int);
enum caca_feature caca_get_feature(enum caca_feature);
void caca_set_feature(enum caca_feature);
char const *caca_get_feature_name(enum caca_feature);
unsigned int caca_get_rendertime(void);
unsigned int caca_get_width(void);
unsigned int caca_get_height(void);
void caca_set_size(unsigned int width, unsigned int height);
void caca_set_width(unsigned int width);
void caca_set_height(unsigned int height);
int caca_set_window_title(char const *);
unsigned int caca_get_window_width(void);
unsigned int caca_get_window_height(void);
void caca_refresh(void);
void caca_end(void);
caca_t * caca_attach(cucul_t *qq);
void caca_detach(caca_t *kk);
void caca_set_delay(caca_t *kk, unsigned int);
void caca_refresh(caca_t *kk);
unsigned int caca_get_rendertime(caca_t *kk);
unsigned int caca_get_window_width(caca_t *kk);
unsigned int caca_get_window_height(caca_t *kk);
void caca_set_size(caca_t *kk, unsigned int width, unsigned int height);
void caca_set_width(caca_t *kk, unsigned int width);
void caca_set_height(caca_t *kk, unsigned int height);
int caca_set_window_title(caca_t *kk, char const *);
/* @} */

/** \defgroup event Event handling
@@ -258,108 +193,10 @@ void caca_end(void);
* clicks.
*
* @{ */
unsigned int caca_get_event(unsigned int);
unsigned int caca_wait_event(unsigned int);
unsigned int caca_get_mouse_x(void);
unsigned int caca_get_mouse_y(void);
/* @} */

/** \defgroup char Character printing
*
* These functions provide low-level character printing routines.
*
* @{ */
void caca_set_color(enum caca_color, enum caca_color);
enum caca_color caca_get_fg_color(void);
enum caca_color caca_get_bg_color(void);
char const *caca_get_color_name(enum caca_color);
void caca_putchar(int, int, char);
void caca_putstr(int, int, char const *);
void caca_printf(int, int, char const *, ...);
void caca_get_screen(char *);
void caca_clear(void);
/* @} */

/** \defgroup prim Primitives drawing
*
* These functions provide routines for primitive drawing, such as lines,
* boxes, triangles and ellipses.
*
* @{ */
void caca_draw_line(int, int, int, int, char);
void caca_draw_polyline(int const x[], int const y[], int, char);
void caca_draw_thin_line(int, int, int, int);
void caca_draw_thin_polyline(int const x[], int const y[], int);

void caca_draw_circle(int, int, int, char);
void caca_draw_ellipse(int, int, int, int, char);
void caca_draw_thin_ellipse(int, int, int, int);
void caca_fill_ellipse(int, int, int, int, char);

void caca_draw_box(int, int, int, int, char);
void caca_draw_thin_box(int, int, int, int);
void caca_fill_box(int, int, int, int, char);

void caca_draw_triangle(int, int, int, int, int, int, char);
void caca_draw_thin_triangle(int, int, int, int, int, int);
void caca_fill_triangle(int, int, int, int, int, int, char);
/* @} */

/** \defgroup math Mathematical functions
*
* These functions provide a few useful math-related routines.
*
* @{ */
int caca_rand(int, int);
unsigned int caca_sqrt(unsigned int);
float caca_powf(float x, float y);
/* @} */

/** \defgroup sprite Sprite handling
*
* These functions provide high level routines for sprite loading, animation
* and rendering.
*
* @{ */
struct caca_sprite;
struct caca_sprite * caca_load_sprite(char const *);
int caca_get_sprite_frames(struct caca_sprite const *);
int caca_get_sprite_width(struct caca_sprite const *, int);
int caca_get_sprite_height(struct caca_sprite const *, int);
int caca_get_sprite_dx(struct caca_sprite const *, int);
int caca_get_sprite_dy(struct caca_sprite const *, int);
void caca_draw_sprite(int, int, struct caca_sprite const *, int);
void caca_free_sprite(struct caca_sprite *);
/* @} */

/** \defgroup bitmap Bitmap handling
*
* These functions provide high level routines for bitmap allocation and
* rendering.
*
* @{ */
struct caca_bitmap;
struct caca_bitmap *caca_create_bitmap(unsigned int, unsigned int,
unsigned int, unsigned int,
unsigned int, unsigned int,
unsigned int, unsigned int);
void caca_set_bitmap_palette(struct caca_bitmap *,
unsigned int r[], unsigned int g[],
unsigned int b[], unsigned int a[]);
void caca_set_bitmap_gamma(struct caca_bitmap *, float);
void caca_draw_bitmap(int, int, int, int, struct caca_bitmap const *, void *);
void caca_free_bitmap(struct caca_bitmap *);
/* @} */

/** \defgroup exporter Exporters to various formats
*
* These functions exports current image to various text formats
*
* @{ */
char* caca_get_html(void);
char* caca_get_html3(void);
char* caca_get_irc(void);
char* caca_get_ansi(int trailing);
unsigned int caca_get_event(caca_t *kk, unsigned int);
unsigned int caca_wait_event(caca_t *kk, unsigned int);
unsigned int caca_get_mouse_x(caca_t *kk);
unsigned int caca_get_mouse_y(caca_t *kk);
/* @} */

#ifdef __cplusplus


+ 39
- 24
src/caca_internals.h View File

@@ -20,6 +20,10 @@
#ifndef __CACA_INTERNALS_H__
#define __CACA_INTERNALS_H__

#if defined(USE_X11)
#include <X11/Xlib.h>
#endif

/* Graphics driver */
enum caca_driver
{
@@ -40,9 +44,6 @@ enum caca_driver
#endif
#if defined(USE_GL)
CACA_DRIVER_GL = 6,
#endif
#if defined(USE_NULL)
CACA_DRIVER_NULL = 7,
#endif
CACA_DRIVER_NONE = 0
};
@@ -54,13 +55,43 @@ struct caca_timer
int last_sec, last_usec;
};

extern enum caca_driver _caca_driver;
/* Internal caca context */
struct caca_context
{
cucul_t *qq;

enum caca_driver driver;
unsigned int width, height;

int resize;
int resize_event;

unsigned int delay, rendertime;

#if defined(USE_X11) && !defined(_DOXYGEN_SKIP_ME)
struct x11
{
Display *dpy;
Window window;
Pixmap pixmap;
GC gc;
long int event_mask;
int font_width, font_height;
unsigned int new_width, new_height;
int colors[16];
Font font;
XFontStruct *font_struct;
int font_offset;
#if defined(HAVE_X11_XKBLIB_H)
Bool detect_autorepeat;
#endif
} x11;
#endif
};

/* Initialisation functions */
extern int _caca_init_graphics(void);
extern int _caca_end_graphics(void);
extern int _caca_init_bitmap(void);
extern int _caca_end_bitmap(void);
extern int _caca_init_graphics(caca_t *kk);
extern int _caca_end_graphics(caca_t *kk);

/* Timer functions */
extern void _caca_sleep(unsigned int);
@@ -72,22 +103,6 @@ extern unsigned int _caca_height;
extern int _caca_resize;
extern int _caca_resize_event;

/* Internal libcaca features */
extern enum caca_feature _caca_background;
extern enum caca_feature _caca_dithering;
extern enum caca_feature _caca_antialiasing;

#if defined(USE_X11)
#include <X11/Xlib.h>
extern Display *x11_dpy;
extern Window x11_window;
extern Pixmap x11_pixmap;
extern GC x11_gc;
extern long int x11_event_mask;
extern int x11_font_width, x11_font_height;
extern unsigned int x11_new_width, x11_new_height;
#endif

#if defined(USE_WIN32)
#include <windows.h>
extern HANDLE win32_hin, win32_hout;


+ 394
- 0
src/char.c View File

@@ -0,0 +1,394 @@
/*
* libcaca ASCII-Art library
* Copyright (c) 2002, 2003 Sam Hocevar <sam@zoy.org>
* All Rights Reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Do What The Fuck You Want To
* Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

/** \file char.c
* \version \$Id$
* \author Sam Hocevar <sam@zoy.org>
* \brief Character drawing
*
* This file contains character and string drawing functions.
*/

#include "config.h"

#if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME)
# include <inttypes.h>
#else
typedef unsigned char uint8_t;
#endif

#include <stdio.h> /* BUFSIZ */
#include <string.h>
#include <stdlib.h>
#if defined(HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <stdarg.h>

#if defined(HAVE_SIGNAL_H)
# include <signal.h>
#endif
#if defined(HAVE_SYS_IOCTL_H)
# include <sys/ioctl.h>
#endif

#include "cucul.h"
#include "cucul_internals.h"

/** \brief Set the default colour pair.
*
* This function sets the default colour pair. String functions such as
* caca_printf() and graphical primitive functions such as caca_draw_line()
* will use these colour pairs.
*
* \param fgcolor The requested foreground colour.
* \param bgcolor The requested background colour.
*/
void cucul_set_color(cucul_t *qq, enum cucul_color fgcolor, enum cucul_color bgcolor)
{
if(fgcolor < 0 || fgcolor > 15 || bgcolor < 0 || bgcolor > 15)
return;

qq->fgcolor = fgcolor;
qq->bgcolor = bgcolor;

#if 0
switch(kk->driver)
{
#if defined(USE_SLANG)
case CACA_DRIVER_SLANG:

#if defined(OPTIMISE_SLANG_PALETTE)
/* If foreground == background, discard this colour pair. Functions
* such as cucul_putchar will print spaces instead of characters */
if(fgcolor != bgcolor)
qq->fgisbg = 0;
else
{
qq->fgisbg = 1;
if(fgcolor == CUCUL_COLOR_BLACK)
fgcolor = CUCUL_COLOR_WHITE;
else if(fgcolor == CUCUL_COLOR_WHITE
|| fgcolor <= CUCUL_COLOR_LIGHTGRAY)
fgcolor = CUCUL_COLOR_BLACK;
else
fgcolor = CUCUL_COLOR_WHITE;
}
#endif

#if defined(OPTIMISE_SLANG_PALETTE)
SLsmg_set_color(slang_assoc[fgcolor + 16 * bgcolor]);
#else
SLsmg_set_color(fgcolor + 16 * bgcolor);
#endif
break;
#endif
#if defined(USE_NCURSES)
case CACA_DRIVER_NCURSES:
attrset(ncurses_attr[fgcolor + 16 * bgcolor]);
break;
#endif
#if defined(USE_CONIO)
case CACA_DRIVER_CONIO:
textbackground(bgcolor);
textcolor(fgcolor);
break;
#endif
#if defined(USE_X11)
case CACA_DRIVER_X11:
/* Nothing to do */
break;
#endif
#if defined(USE_WIN32)
case CACA_DRIVER_WIN32:
/* Nothing to do */
break;
#endif
#if defined(USE_GL)
case CACA_DRIVER_GL:
/* Nothing to do */
break;
#endif
default:
break;
}
#endif
}

/** \brief Get the current foreground colour.
*
* This function returns the current foreground colour that was set with
* cucul_set_color().
*
* \return The current foreground colour.
*/
enum cucul_color cucul_get_fg_color(cucul_t *qq)
{
return qq->fgcolor;
}

/** \brief Get the current background colour.
*
* This function returns the current background colour that was set with
* cucul_set_color().
*
* \return The current background colour.
*/
enum cucul_color cucul_get_bg_color(cucul_t *qq)
{
return qq->bgcolor;
}

/** \brief Print a character.
*
* This function prints a character at the given coordinates, using the
* default foreground and background values. If the coordinates are outside
* the screen boundaries, nothing is printed.
*
* \param x X coordinate.
* \param y Y coordinate.
* \param c The character to print.
*/
void cucul_putchar(cucul_t *qq, int x, int y, char c)
{
#if defined(USE_CONIO)
char *data;
#endif
if(x < 0 || x >= (int)qq->width ||
y < 0 || y >= (int)qq->height)
return;

qq->chars[x + y * qq->width] = c;
qq->attr[x + y * qq->width] = (qq->bgcolor << 4) | qq->fgcolor;

#if 0
switch(kk->driver)
{
#if defined(USE_SLANG)
case CACA_DRIVER_SLANG:
SLsmg_gotorc(y, x);
#if defined(OPTIMISE_SLANG_PALETTE)
if(qq->fgisbg)
SLsmg_write_char(' ');
else
#endif
SLsmg_write_char(c);
break;
#endif
#if defined(USE_NCURSES)
case CACA_DRIVER_NCURSES:
move(y, x);
addch(c);
break;
#endif
#if defined(USE_CONIO)
case CACA_DRIVER_CONIO:
data = conio_screen + 2 * (x + y * qq->width);
data[0] = c;
data[1] = (qq->bgcolor << 4) | qq->fgcolor;
break;
#endif
#if defined(USE_X11)
case CACA_DRIVER_X11:
break;
#endif
#if defined(USE_WIN32)
case CACA_DRIVER_WIN32:
break;
#endif
#if defined(USE_GL)
case CACA_DRIVER_GL:
break;
#endif
default:
break;
}
#endif
}

/** \brief Print a string.
*
* This function prints a string at the given coordinates, using the
* default foreground and background values. The coordinates may be outside
* the screen boundaries (eg. a negative Y coordinate) and the string will
* be cropped accordingly if it is too long.
*
* \param x X coordinate.
* \param y Y coordinate.
* \param s The string to print.
*/
void cucul_putstr(cucul_t *qq, int x, int y, char const *s)
{
unsigned char *charbuf;
unsigned char *attrbuf;
char const *t;
unsigned int len;

if(y < 0 || y >= (int)qq->height || x >= (int)qq->width)
return;

len = strlen(s);

if(x < 0)
{
if(len < (unsigned int)-x)
return;
len -= -x;
s += -x;
x = 0;
}

if(x + len >= qq->width)
{
len = qq->width - x;
memcpy(qq->scratch_line, s, len);
qq->scratch_line[len] = '\0';
s = qq->scratch_line;
}

charbuf = qq->chars + x + y * qq->width;
attrbuf = qq->attr + x + y * qq->width;
t = s;
while(*t)
{
*charbuf++ = *t++;
*attrbuf++ = (qq->bgcolor << 4) | qq->fgcolor;
}

#if 0
switch(kk->driver)
{
#if defined(USE_SLANG)
case CACA_DRIVER_SLANG:
SLsmg_gotorc(y, x);
#if defined(OPTIMISE_SLANG_PALETTE)
if(qq->fgisbg)
SLsmg_write_string(qq->empty_line + qq->width - len);
else
#endif
{
union { char *ch; const char *constch; } u;
u.constch = s;
SLsmg_write_string(u.ch);
}
break;
#endif
#if defined(USE_NCURSES)
case CACA_DRIVER_NCURSES:
move(y, x);
addstr(s);
break;
#endif
#if defined(USE_CONIO)
case CACA_DRIVER_CONIO:
charbuf = conio_screen + 2 * (x + y * qq->width);
while(*s)
{
*charbuf++ = *s++;
*charbuf++ = (qq->bgcolor << 4) | qq->fgcolor;
}
break;
#endif
#if defined(USE_X11)
case CACA_DRIVER_X11:
break;
#endif
#if defined(USE_WIN32)
case CACA_DRIVER_WIN32:
break;
#endif
#if defined(USE_GL)
case CACA_DRIVER_GL:
break;
#endif
default:
break;
}
#endif
}

/** \brief Format a string.
*
* This function formats a string at the given coordinates, using the
* default foreground and background values. The coordinates may be outside
* the screen boundaries (eg. a negative Y coordinate) and the string will
* be cropped accordingly if it is too long. The syntax of the format
* string is the same as for the C printf() function.
*
* \param x X coordinate.
* \param y Y coordinate.
* \param format The format string to print.
* \param ... Arguments to the format string.
*/
void cucul_printf(cucul_t *qq, int x, int y, char const *format, ...)
{
char tmp[BUFSIZ];
char *buf = tmp;
va_list args;

if(y < 0 || y >= (int)qq->height || x >= (int)qq->width)
return;

if(qq->width - x + 1 > BUFSIZ)
buf = malloc(qq->width - x + 1);

va_start(args, format);
#if defined(HAVE_VSNPRINTF)
vsnprintf(buf, qq->width - x + 1, format, args);
#else
vsprintf(buf, format, args);
#endif
buf[qq->width - x] = '\0';
va_end(args);

cucul_putstr(qq, x, y, buf);

if(buf != tmp)
free(buf);
}

/** \brief Get the screen.
*
* This function fills a byte array with the character values.
*/
void cucul_get_screen(cucul_t *qq, char *buffer)
{
unsigned int x, y;

for(y = 0; y < qq->height; y++)
{
for(x = 0; x < qq->width; x++)
{
*buffer++ = qq->attr[x + y * qq->width];
*buffer++ = qq->chars[x + y * qq->width];
}
}
}

/** \brief Clear the screen.
*
* This function clears the screen using a black background.
*/
void cucul_clear(cucul_t *qq)
{
enum cucul_color oldfg = cucul_get_fg_color(qq);
enum cucul_color oldbg = cucul_get_bg_color(qq);
int y = qq->height;

cucul_set_color(qq, CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLACK);

/* We could use SLsmg_cls() etc., but drawing empty lines is much faster */
while(y--)
cucul_putstr(qq, 0, y, qq->empty_line);

cucul_set_color(qq, oldfg, oldbg);
}


+ 30
- 30
src/conic.c View File

@@ -28,10 +28,10 @@ typedef unsigned char uint8_t;

#include <stdlib.h>

#include "caca.h"
#include "caca_internals.h"
#include "cucul.h"
#include "cucul_internals.h"

static void ellipsepoints(int, int, int, int, char);
static void ellipsepoints(cucul_t *, int, int, int, int, char);

/**
* \brief Draw a circle on the screen using the given character.
@@ -42,15 +42,15 @@ static void ellipsepoints(int, int, int, int, char);
* \param c Character to draw the circle outline with.
* \return void
*/
void caca_draw_circle(int x, int y, int r, char c)
void cucul_draw_circle(cucul_t *qq, int x, int y, int r, char c)
{
int test, dx, dy;

/* Optimized Bresenham. Kick ass. */
for(test = 0, dx = 0, dy = r ; dx <= dy ; dx++)
{
ellipsepoints(x, y, dx, dy, c);
ellipsepoints(x, y, dy, dx, c);
ellipsepoints(qq, x, y, dx, dy, c);
ellipsepoints(qq, x, y, dy, dx, c);

test += test > 0 ? dx - dy-- : dx;
}
@@ -66,7 +66,7 @@ void caca_draw_circle(int x, int y, int r, char c)
* \param c Character to fill the ellipse with.
* \return void
*/
void caca_fill_ellipse(int xo, int yo, int a, int b, char c)
void cucul_fill_ellipse(cucul_t *qq, int xo, int yo, int a, int b, char c)
{
int d2;
int x = 0;
@@ -82,15 +82,15 @@ void caca_fill_ellipse(int xo, int yo, int a, int b, char c)
else
{
d1 += b*b*(2*x*1) + a*a*(-2*y+2);
caca_draw_line(xo - x, yo - y, xo + x, yo - y, c);
caca_draw_line(xo - x, yo + y, xo + x, yo + y, c);
cucul_draw_line(qq, xo - x, yo - y, xo + x, yo - y, c);
cucul_draw_line(qq, xo - x, yo + y, xo + x, yo + y, c);
y--;
}
x++;
}

caca_draw_line(xo - x, yo - y, xo + x, yo - y, c);
caca_draw_line(xo - x, yo + y, xo + x, yo + y, c);
cucul_draw_line(qq, xo - x, yo - y, xo + x, yo - y, c);
cucul_draw_line(qq, xo - x, yo + y, xo + x, yo + y, c);

d2 = b*b*(x+0.5)*(x+0.5) + a*a*(y-1)*(y-1) - a*a*b*b;
while(y > 0)
@@ -106,8 +106,8 @@ void caca_fill_ellipse(int xo, int yo, int a, int b, char c)
}

y--;
caca_draw_line(xo - x, yo - y, xo + x, yo - y, c);
caca_draw_line(xo - x, yo + y, xo + x, yo + y, c);
cucul_draw_line(qq, xo - x, yo - y, xo + x, yo - y, c);
cucul_draw_line(qq, xo - x, yo + y, xo + x, yo + y, c);
}
}

@@ -121,14 +121,14 @@ void caca_fill_ellipse(int xo, int yo, int a, int b, char c)
* \param c Character to draw the ellipse outline with.
* \return void
*/
void caca_draw_ellipse(int xo, int yo, int a, int b, char c)
void cucul_draw_ellipse(cucul_t *qq, int xo, int yo, int a, int b, char c)
{
int d2;
int x = 0;
int y = b;
int d1 = b*b - (a*a*b) + (a*a/4);

ellipsepoints(xo, yo, x, y, c);
ellipsepoints(qq, xo, yo, x, y, c);

while(a*a*y - a*a/2 > b*b*(x+1))
{
@@ -142,7 +142,7 @@ void caca_draw_ellipse(int xo, int yo, int a, int b, char c)
y--;
}
x++;
ellipsepoints(xo, yo, x, y, c);
ellipsepoints(qq, xo, yo, x, y, c);
}

d2 = b*b*(x+0.5)*(x+0.5) + a*a*(y-1)*(y-1) - a*a*b*b;
@@ -159,7 +159,7 @@ void caca_draw_ellipse(int xo, int yo, int a, int b, char c)
}

y--;
ellipsepoints(xo, yo, x, y, c);
ellipsepoints(qq, xo, yo, x, y, c);
}
}

@@ -172,7 +172,7 @@ void caca_draw_ellipse(int xo, int yo, int a, int b, char c)
* \param b Ellipse Y radius.
* \return void
*/
void caca_draw_thin_ellipse(int xo, int yo, int a, int b)
void cucul_draw_thin_ellipse(cucul_t *qq, int xo, int yo, int a, int b)
{
/* FIXME: this is not correct */
int d2;
@@ -180,7 +180,7 @@ void caca_draw_thin_ellipse(int xo, int yo, int a, int b)
int y = b;
int d1 = b*b - (a*a*b) + (a*a/4);

ellipsepoints(xo, yo, x, y, '-');
ellipsepoints(qq, xo, yo, x, y, '-');

while(a*a*y - a*a/2 > b*b*(x+1))
{
@@ -194,7 +194,7 @@ void caca_draw_thin_ellipse(int xo, int yo, int a, int b)
y--;
}
x++;
ellipsepoints(xo, yo, x, y, '-');
ellipsepoints(qq, xo, yo, x, y, '-');
}

d2 = b*b*(x+0.5)*(x+0.5) + a*a*(y-1)*(y-1) - a*a*b*b;
@@ -211,33 +211,33 @@ void caca_draw_thin_ellipse(int xo, int yo, int a, int b)
}

y--;
ellipsepoints(xo, yo, x, y, '|');
ellipsepoints(qq, xo, yo, x, y, '|');
}
}

static void ellipsepoints(int xo, int yo, int x, int y, char c)
static void ellipsepoints(cucul_t *qq, int xo, int yo, int x, int y, char c)
{
uint8_t b = 0;

if(xo + x >= 0 && xo + x < (int)_caca_width)
if(xo + x >= 0 && xo + x < (int)qq->width)
b |= 0x1;
if(xo - x >= 0 && xo - x < (int)_caca_width)
if(xo - x >= 0 && xo - x < (int)qq->width)
b |= 0x2;
if(yo + y >= 0 && yo + y < (int)_caca_height)
if(yo + y >= 0 && yo + y < (int)qq->height)
b |= 0x4;
if(yo - y >= 0 && yo - y < (int)_caca_height)
if(yo - y >= 0 && yo - y < (int)qq->height)
b |= 0x8;

if((b & (0x1|0x4)) == (0x1|0x4))
caca_putchar(xo + x, yo + y, c);
cucul_putchar(qq, xo + x, yo + y, c);

if((b & (0x2|0x4)) == (0x2|0x4))
caca_putchar(xo - x, yo + y, c);
cucul_putchar(qq, xo - x, yo + y, c);

if((b & (0x1|0x8)) == (0x1|0x8))
caca_putchar(xo + x, yo - y, c);
cucul_putchar(qq, xo + x, yo - y, c);

if((b & (0x2|0x8)) == (0x2|0x8))
caca_putchar(xo - x, yo - y, c);
cucul_putchar(qq, xo - x, yo - y, c);
}


+ 322
- 0
src/cucul.c View File

@@ -0,0 +1,322 @@
/*
* libcucul Unicode canvas library
* Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
* All Rights Reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Do What The Fuck You Want To
* Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

/** \file cucul.c
* \version \$Id$
* \author Sam Hocevar <sam@zoy.org>
* \brief Main \e libcucul functions
*
* This file contains the main functions used by \e libcucul applications
* to initialise a drawing context.
*/

#include "config.h"

#if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME)
# include <inttypes.h>
#else
typedef unsigned char uint8_t;
#endif

#include <stdlib.h>
#include <string.h>

#include "cucul.h"
#include "cucul_internals.h"

static void cucul_init_features(cucul_t *qq);

/** \brief Initialise \e libcucul.
*
* This function initialises internal \e libcucul structures and the backend
* that will be used for subsequent graphical operations. It must be the
* first \e libcucul function to be called in a function. cucul_end() should
* be called at the end of the program to free all allocated resources.
*
* \return 0 upon success, a non-zero value if an error occurs.
*/
cucul_t * cucul_init(void)
{
cucul_t *qq = malloc(sizeof(cucul_t));

cucul_init_features(qq);

qq->fgcolor = CUCUL_COLOR_LIGHTGRAY;
qq->bgcolor = CUCUL_COLOR_BLACK;
#if defined(OPTIMISE_SLANG_PALETTE)
qq->fgisbg = 0;
#endif

/* Initialise to a default size. If a graphic driver attaches to
* us before cucul_set_size is called, we'll adapt. */
qq->width = 80;
qq->height = 32;
qq->size_set = 0;

qq->chars = malloc(qq->width * qq->height * sizeof(uint8_t));
qq->attr = malloc(qq->width * qq->height * sizeof(uint8_t));

memset(qq->chars, 0, qq->width * qq->height * sizeof(uint8_t));
memset(qq->attr, 0, qq->width * qq->height * sizeof(uint8_t));

qq->empty_line = malloc(qq->width + 1);
memset(qq->empty_line, ' ', qq->width);
qq->empty_line[qq->width] = '\0';

qq->scratch_line = malloc(qq->width + 1);

if(_cucul_init_bitmap())
{
free(qq);
return NULL;
}

return qq;
}

/** \brief Set the screen size.
*
* This function sets the screen width and height, in character cells.
*
* \param width The desired screen width
* \param height The desired screen height
*/
void cucul_set_size(cucul_t *qq, unsigned int width, unsigned int height)
{
qq->width = width;
qq->height = height;
qq->size_set = 1;
}

/** \brief Get the screen width.
*
* This function returns the current screen width, in character cells.
*
* \return The screen width.
*/
unsigned int cucul_get_width(cucul_t *qq)
{
return qq->width;
}

/** \brief Get the screen height.
*
* This function returns the current screen height, in character cells.
*
* \return The screen height.
*/
unsigned int cucul_get_height(cucul_t *qq)
{
return qq->width;
}

/** \brief Translate a colour index into the colour's name.
*
* This function translates a caca_color enum into a human-readable
* description string of the associated colour.
*
* \param color The colour value.
* \return A static string containing the colour's name.
*/
char const *cucul_get_color_name(enum cucul_color color)
{
static char const *color_names[] =
{
"black",
"blue",
"green",
"cyan",
"red",
"magenta",
"brown",
"light gray",
"dark gray",
"light blue",
"light green",
"light cyan",
"light red",
"light magenta",
"yellow",
"white",
};

if(color < 0 || color > 15)
return "unknown";

return color_names[color];
}

/** \brief Get the current value of a feature.
*
* This function retrieves the value of an internal \e libcaca feature. A
* generic feature value is expected, such as CUCUL_ANTIALIASING.
*
* \param feature The requested feature.
* \return The current value of the feature or CUCUL_FEATURE_UNKNOWN if an
* error occurred..
*/
enum cucul_feature cucul_get_feature(cucul_t *qq, enum cucul_feature feature)
{
switch(feature)
{
case CUCUL_BACKGROUND:
return qq->background;
case CUCUL_ANTIALIASING:
return qq->antialiasing;
case CUCUL_DITHERING:
return qq->dithering;

default:
return CUCUL_FEATURE_UNKNOWN;
}
}

/** \brief Set a feature.
*
* This function sets an internal \e libcaca feature such as the antialiasing
* or dithering modes. If a specific feature such as CUCUL_DITHERING_RANDOM,
* cucul_set_feature() will set it immediately. If a generic feature is given
* instead, such as CUCUL_DITHERING, the default value will be used instead.
*
* \param feature The requested feature.
*/
void cucul_set_feature(cucul_t *qq, enum cucul_feature feature)
{
switch(feature)
{
case CUCUL_BACKGROUND:
feature = CUCUL_BACKGROUND_SOLID;
case CUCUL_BACKGROUND_BLACK:
case CUCUL_BACKGROUND_SOLID:
qq->background = feature;
break;

case CUCUL_ANTIALIASING:
feature = CUCUL_ANTIALIASING_PREFILTER;
case CUCUL_ANTIALIASING_NONE:
case CUCUL_ANTIALIASING_PREFILTER:
qq->antialiasing = feature;
break;

case CUCUL_DITHERING:
feature = CUCUL_DITHERING_FSTEIN;
case CUCUL_DITHERING_NONE:
case CUCUL_DITHERING_ORDERED2:
case CUCUL_DITHERING_ORDERED4:
case CUCUL_DITHERING_ORDERED8:
case CUCUL_DITHERING_RANDOM:
case CUCUL_DITHERING_FSTEIN:
qq->dithering = feature;
break;

case CUCUL_FEATURE_UNKNOWN:
break;
}
}

/** \brief Translate a feature value into the feature's name.
*
* This function translates a cucul_feature enum into a human-readable
* description string of the associated feature.
*
* \param feature The feature value.
* \return A static string containing the feature's name.
*/
char const *cucul_get_feature_name(enum cucul_feature feature)
{
switch(feature)
{
case CUCUL_BACKGROUND_BLACK: return "black background";
case CUCUL_BACKGROUND_SOLID: return "solid background";

case CUCUL_ANTIALIASING_NONE: return "no antialiasing";
case CUCUL_ANTIALIASING_PREFILTER: return "prefilter antialiasing";

case CUCUL_DITHERING_NONE: return "no dithering";
case CUCUL_DITHERING_ORDERED2: return "2x2 ordered dithering";
case CUCUL_DITHERING_ORDERED4: return "4x4 ordered dithering";
case CUCUL_DITHERING_ORDERED8: return "8x8 ordered dithering";
case CUCUL_DITHERING_RANDOM: return "random dithering";
case CUCUL_DITHERING_FSTEIN: return "Floyd-Steinberg dithering";

default: return "unknown";
}
}

/** \brief Uninitialise \e libcucul.
*
* This function frees all resources allocated by cucul_init(). After
* cucul_end() has been called, no other \e libcucul functions may be used
* unless a new call to cucul_init() is done.
*/
void cucul_end(cucul_t *qq)
{
_cucul_end_bitmap();

free(qq->empty_line);
free(qq->scratch_line);

free(qq->chars);
free(qq->attr);

free(qq);
}

/*
* XXX: The following functions are local.
*/

static void cucul_init_features(cucul_t * qq)
{
/* FIXME: if strcasecmp isn't available, use strcmp */
#if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP)
char *var;
#endif

cucul_set_feature(qq, CUCUL_BACKGROUND);
cucul_set_feature(qq, CUCUL_ANTIALIASING);
cucul_set_feature(qq, CUCUL_DITHERING);

#if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP)
if((var = getenv("CUCUL_BACKGROUND")) && *var)
{
if(!strcasecmp("black", var))
cucul_set_feature(qq, CUCUL_BACKGROUND_BLACK);
else if(!strcasecmp("solid", var))
cucul_set_feature(qq, CUCUL_BACKGROUND_SOLID);
}

if((var = getenv("CUCUL_ANTIALIASING")) && *var)
{
if(!strcasecmp("none", var))
cucul_set_feature(qq, CUCUL_ANTIALIASING_NONE);
else if(!strcasecmp("prefilter", var))
cucul_set_feature(qq, CUCUL_ANTIALIASING_PREFILTER);
}

if((var = getenv("CUCUL_DITHERING")) && *var)
{
if(!strcasecmp("none", var))
cucul_set_feature(qq, CUCUL_DITHERING_NONE);
else if(!strcasecmp("ordered2", var))
cucul_set_feature(qq, CUCUL_DITHERING_ORDERED2);
else if(!strcasecmp("ordered4", var))
cucul_set_feature(qq, CUCUL_DITHERING_ORDERED4);
else if(!strcasecmp("ordered8", var))
cucul_set_feature(qq, CUCUL_DITHERING_ORDERED8);
else if(!strcasecmp("random", var))
cucul_set_feature(qq, CUCUL_DITHERING_RANDOM);
else if(!strcasecmp("fstein", var))
cucul_set_feature(qq, CUCUL_DITHERING_FSTEIN);
}
#endif
}


+ 216
- 0
src/cucul.h View File

@@ -0,0 +1,216 @@
/*
* libcucul Unicode canvas library
* Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
* All Rights Reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Do What The Fuck You Want To
* Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

/** \file cucul.h
* \version \$Id$
* \author Sam Hocevar <sam@zoy.org>
* \brief The \e libcucul public header.
*
* This header contains the public types and functions that applications
* using \e libcucul may use.
*/

#ifndef __CUCUL_H__
#define __CUCUL_H__

#ifdef __cplusplus
extern "C"
{
#endif

/** \brief Colour definitions.
*
* Colours that can be used with caca_set_color().
*/
enum cucul_color
{
CUCUL_COLOR_BLACK = 0, /**< The colour index for black. */
CUCUL_COLOR_BLUE = 1, /**< The colour index for blue. */
CUCUL_COLOR_GREEN = 2, /**< The colour index for green. */
CUCUL_COLOR_CYAN = 3, /**< The colour index for cyan. */
CUCUL_COLOR_RED = 4, /**< The colour index for red. */
CUCUL_COLOR_MAGENTA = 5, /**< The colour index for magenta. */
CUCUL_COLOR_BROWN = 6, /**< The colour index for brown. */
CUCUL_COLOR_LIGHTGRAY = 7, /**< The colour index for light gray. */
CUCUL_COLOR_DARKGRAY = 8, /**< The colour index for dark gray. */
CUCUL_COLOR_LIGHTBLUE = 9, /**< The colour index for blue. */
CUCUL_COLOR_LIGHTGREEN = 10, /**< The colour index for light green. */
CUCUL_COLOR_LIGHTCYAN = 11, /**< The colour index for light cyan. */
CUCUL_COLOR_LIGHTRED = 12, /**< The colour index for light red. */
CUCUL_COLOR_LIGHTMAGENTA = 13, /**< The colour index for light magenta. */
CUCUL_COLOR_YELLOW = 14, /**< The colour index for yellow. */
CUCUL_COLOR_WHITE = 15 /**< The colour index for white. */
};

/** \brief Internal features.
*
* Internal libcaca features such as the rendering method or the dithering
* mode.
*/
enum cucul_feature
{
CUCUL_BACKGROUND = 0x10, /**< Properties of background characters. */
CUCUL_BACKGROUND_BLACK = 0x11, /**< Draw only black backgrounds. */
CUCUL_BACKGROUND_SOLID = 0x12, /**< Draw coloured solid backgorunds. */
#define CUCUL_BACKGROUND_MIN 0x11 /**< First background property */
#define CUCUL_BACKGROUND_MAX 0x12 /**< Last background property */

CUCUL_ANTIALIASING = 0x20, /**< Antialiasing features. */
CUCUL_ANTIALIASING_NONE = 0x21, /**< No antialiasing. */
CUCUL_ANTIALIASING_PREFILTER = 0x22, /**< Prefilter antialiasing. */
#define CUCUL_ANTIALIASING_MIN 0x21 /**< First antialiasing feature. */
#define CUCUL_ANTIALIASING_MAX 0x22 /**< Last antialiasing feature. */

CUCUL_DITHERING = 0x30, /**< Dithering methods */
CUCUL_DITHERING_NONE = 0x31, /**< No dithering. */
CUCUL_DITHERING_ORDERED2 = 0x32, /**< Ordered 2x2 Bayer dithering. */
CUCUL_DITHERING_ORDERED4 = 0x33, /**< Ordered 4x4 Bayer dithering. */
CUCUL_DITHERING_ORDERED8 = 0x34, /**< Ordered 8x8 Bayer dithering. */
CUCUL_DITHERING_RANDOM = 0x35, /**< Random dithering. */
CUCUL_DITHERING_FSTEIN = 0x36, /**< Floyd-Steinberg dithering. */
#define CUCUL_DITHERING_MIN 0x31 /**< First dithering feature. */
#define CUCUL_DITHERING_MAX 0x36 /**< Last dithering feature. */

CUCUL_FEATURE_UNKNOWN = 0xffff /**< Unknown feature. */
};

/*
* Backwards compatibility macros
*/
#if !defined(_DOXYGEN_SKIP_ME)
#define caca_dithering cucul_feature
#define caca_set_dithering caca_set_feature
#define caca_get_dithering_name caca_get_feature_name
#define CACA_DITHER_NONE CUCUL_DITHERING_NONE
#define CACA_DITHER_ORDERED CUCUL_DITHERING_ORDERED8
#define CACA_DITHER_RANDOM CUCUL_DITHERING_RANDOM
#endif

typedef struct cucul_context cucul_t;

/** \defgroup basic Basic functions
*
* These functions provide the basic \e libcaca routines for library
* initialisation, system information retrieval and configuration.
*
* @{ */
cucul_t * cucul_init(void);
void cucul_set_size(cucul_t *, unsigned int, unsigned int);
unsigned int cucul_get_width(cucul_t *);
unsigned int cucul_get_height(cucul_t *);
enum cucul_feature cucul_get_feature(cucul_t *, enum cucul_feature);
void cucul_set_feature(cucul_t *, enum cucul_feature);
char const *cucul_get_feature_name(enum cucul_feature);
void cucul_end(cucul_t *);
/* @} */

/** \defgroup char Character printing
*
* These functions provide low-level character printing routines.
*
* @{ */
void cucul_set_color(cucul_t *, enum cucul_color, enum cucul_color);
enum cucul_color cucul_get_fg_color(cucul_t *);
enum cucul_color cucul_get_bg_color(cucul_t *);
char const *cucul_get_color_name(enum cucul_color);
void cucul_putchar(cucul_t *, int, int, char);
void cucul_putstr(cucul_t *, int, int, char const *);
void cucul_printf(cucul_t *, int, int, char const *, ...);
void cucul_get_screen(cucul_t *, char *);
void cucul_clear(cucul_t *);
/* @} */

/** \defgroup prim Primitives drawing
*
* These functions provide routines for primitive drawing, such as lines,
* boxes, triangles and ellipses.
*
* @{ */
void cucul_draw_line(cucul_t *, int, int, int, int, char);
void cucul_draw_polyline(cucul_t *, int const x[], int const y[], int, char);
void cucul_draw_thin_line(cucul_t *, int, int, int, int);
void cucul_draw_thin_polyline(cucul_t *, int const x[], int const y[], int);

void cucul_draw_circle(cucul_t *, int, int, int, char);
void cucul_draw_ellipse(cucul_t *, int, int, int, int, char);
void cucul_draw_thin_ellipse(cucul_t *, int, int, int, int);
void cucul_fill_ellipse(cucul_t *, int, int, int, int, char);

void cucul_draw_box(cucul_t *, int, int, int, int, char);
void cucul_draw_thin_box(cucul_t *, int, int, int, int);
void cucul_fill_box(cucul_t *, int, int, int, int, char);

void cucul_draw_triangle(cucul_t *, int, int, int, int, int, int, char);
void cucul_draw_thin_triangle(cucul_t *, int, int, int, int, int, int);
void cucul_fill_triangle(cucul_t *, int, int, int, int, int, int, char);
/* @} */

/** \defgroup math Mathematical functions
*
* These functions provide a few useful math-related routines.
*
* @{ */
int cucul_rand(int, int);
unsigned int cucul_sqrt(unsigned int);
float cucul_powf(float x, float y);
/* @} */

/** \defgroup sprite Sprite handling
*
* These functions provide high level routines for sprite loading, animation
* and rendering.
*
* @{ */
struct cucul_sprite;
struct cucul_sprite * cucul_load_sprite(cucul_t *, char const *);
int cucul_get_sprite_frames(cucul_t *, struct cucul_sprite const *);
int cucul_get_sprite_width(cucul_t *, struct cucul_sprite const *, int);
int cucul_get_sprite_height(cucul_t *, struct cucul_sprite const *, int);
int cucul_get_sprite_dx(cucul_t *, struct cucul_sprite const *, int);
int cucul_get_sprite_dy(cucul_t *, struct cucul_sprite const *, int);
void cucul_draw_sprite(cucul_t *, int, int, struct cucul_sprite const *, int);void cucul_free_sprite(cucul_t *, struct cucul_sprite *);
/* @} */

/** \defgroup bitmap Bitmap handling
*
* These functions provide high level routines for bitmap allocation and
* rendering.
*
* @{ */
struct cucul_bitmap;
struct cucul_bitmap *cucul_create_bitmap(cucul_t *, unsigned int, unsigned int,
unsigned int, unsigned int,
unsigned int, unsigned int,
unsigned int, unsigned int);
void cucul_set_bitmap_palette(cucul_t *, struct cucul_bitmap *,
unsigned int r[], unsigned int g[],
unsigned int b[], unsigned int a[]);
void cucul_set_bitmap_gamma(cucul_t *, struct cucul_bitmap *, float);
void cucul_draw_bitmap(cucul_t *, int, int, int, int, struct cucul_bitmap const *, void *);
void cucul_free_bitmap(cucul_t *, struct cucul_bitmap *);
/* @} */

/** \defgroup exporter Exporters to various formats
*
* These functions exports current image to various text formats
*
* @{ */
char* cucul_get_html(cucul_t *);
char* cucul_get_html3(cucul_t *);
char* cucul_get_irc(cucul_t *);
char* cucul_get_ansi(cucul_t *, int trailing);
/* @} */

#ifdef __cplusplus
}
#endif

#endif /* __CUCUL_H__ */

+ 48
- 0
src/cucul_internals.h View File

@@ -0,0 +1,48 @@
/*
* libcucul Unicode canvas library
* Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
* All Rights Reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Do What The Fuck You Want To
* Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

/** \file cucul_internals.h
* \version \$Id$
* \author Sam Hocevar <sam@zoy.org>
* \brief The \e libcucul private header.
*
* This header contains the private types and functions used by \e libcucul.
*/

#ifndef __CUCUL_INTERNALS_H__
#define __CUCUL_INTERNALS_H__

struct cucul_context
{
/* Context size */
unsigned int width, height;
int size_set;

uint8_t *chars, *attr;
uint8_t *empty_line, *scratch_line;

enum cucul_color fgcolor;
enum cucul_color bgcolor;
#if defined(OPTIMISE_SLANG_PALETTE)
int fgisbg;
#endif

/* Internal libcucul features */
enum cucul_feature background, antialiasing, dithering;

unsigned int refcount;
};

/* Initialisation functions */
extern int _cucul_init_bitmap(void);
extern int _cucul_end_bitmap(void);

#endif /* __CUCUL_INTERNALS_H__ */

+ 60
- 56
src/event.c View File

@@ -19,6 +19,12 @@

#include "config.h"

#if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME)
# include <inttypes.h>
#else
typedef unsigned char uint8_t;
#endif

#if defined(USE_SLANG)
# if defined(HAVE_SLANG_SLANG_H)
# include <slang/slang.h>
@@ -59,11 +65,13 @@ extern unsigned char gl_mouse_changed, gl_mouse_clicked;
extern unsigned int gl_mouse_x, gl_mouse_y;
extern unsigned int gl_mouse_button, gl_mouse_state;
#endif
#include "cucul.h"
#include "cucul_internals.h"
#include "caca.h"
#include "caca_internals.h"

static unsigned int _get_next_event(void);
static unsigned int _lowlevel_event(void);
static unsigned int _get_next_event(caca_t *kk);
static unsigned int _lowlevel_event(caca_t *kk);
#if defined(USE_SLANG) || defined(USE_NCURSES) || defined(USE_CONIO)
static void _push_event(unsigned int);
static unsigned int _pop_event(void);
@@ -100,14 +108,14 @@ static unsigned int mouse_x = 0, mouse_y = 0;
* \param event_mask Bitmask of requested events.
* \return The next matching event in the queue, or 0 if no event is pending.
*/
unsigned int caca_get_event(unsigned int event_mask)
unsigned int caca_get_event(caca_t *kk, unsigned int event_mask)
{
if(!event_mask)
return CACA_EVENT_NONE;

for( ; ; )
{
unsigned int event = _get_next_event();
unsigned int event = _get_next_event(kk);

if(!event || event & event_mask)
return event;
@@ -124,14 +132,14 @@ unsigned int caca_get_event(unsigned int event_mask)
* \param event_mask Bitmask of requested events.
* \return The next event in the queue.
*/
unsigned int caca_wait_event(unsigned int event_mask)
unsigned int caca_wait_event(caca_t *kk, unsigned int event_mask)
{
if(!event_mask)
return CACA_EVENT_NONE;

for( ; ; )
{
unsigned int event = _get_next_event();
unsigned int event = _get_next_event(kk);

if(event & event_mask)
return event;
@@ -149,10 +157,10 @@ unsigned int caca_wait_event(unsigned int event_mask)
*
* \return The X mouse coordinate.
*/
unsigned int caca_get_mouse_x(void)
unsigned int caca_get_mouse_x(caca_t *kk)
{
if(mouse_x >= _caca_width)
mouse_x = _caca_width - 1;
if(mouse_x >= kk->qq->width)
mouse_x = kk->qq->width - 1;

return mouse_x;
}
@@ -166,10 +174,10 @@ unsigned int caca_get_mouse_x(void)
*
* \return The Y mouse coordinate.
*/
unsigned int caca_get_mouse_y(void)
unsigned int caca_get_mouse_y(caca_t *kk)
{
if(mouse_y >= _caca_height)
mouse_y = _caca_height - 1;
if(mouse_y >= kk->qq->height)
mouse_y = kk->qq->height - 1;

return mouse_y;
}
@@ -178,7 +186,7 @@ unsigned int caca_get_mouse_y(void)
* XXX: The following functions are local.
*/

static unsigned int _get_next_event(void)
static unsigned int _get_next_event(caca_t *kk)
{
#if defined(USE_SLANG) || defined(USE_NCURSES)
static struct caca_timer key_timer = CACA_TIMER_INITIALIZER;
@@ -188,18 +196,14 @@ static unsigned int _get_next_event(void)
unsigned int ticks;
#endif
unsigned int event;
#if defined(USE_NULL)
if(_caca_driver == CACA_DRIVER_NULL)
return CACA_EVENT_NONE;
#endif

event = _lowlevel_event();
event = _lowlevel_event(kk);

#if defined(USE_SLANG)
if(_caca_driver != CACA_DRIVER_SLANG)
if(kk->driver != CACA_DRIVER_SLANG)
#endif
#if defined(USE_NCURSES)
if(_caca_driver != CACA_DRIVER_NCURSES)
if(kk->driver != CACA_DRIVER_NCURSES)
#endif
return event;

@@ -224,7 +228,7 @@ static unsigned int _get_next_event(void)
if(event == (CACA_EVENT_KEY_PRESS | last_key))
{
last_key_ticks = 0;
return _get_next_event();
return _get_next_event(kk);
}

/* We are in autorepeat mode, but key has expired or a new key was
@@ -250,7 +254,7 @@ static unsigned int _get_next_event(void)
#endif
}

static unsigned int _lowlevel_event(void)
static unsigned int _lowlevel_event(caca_t *kk)
{
unsigned int event;

@@ -263,12 +267,12 @@ static unsigned int _lowlevel_event(void)

#if defined(USE_X11)
/* The X11 event check routine */
if(_caca_driver == CACA_DRIVER_X11)
if(kk->driver == CACA_DRIVER_X11)
{
XEvent xevent;
char key;

while(XCheckWindowEvent(x11_dpy, x11_window, x11_event_mask, &xevent)
while(XCheckWindowEvent(kk->x11.dpy, kk->x11.window, kk->x11.event_mask, &xevent)
== True)
{
KeySym keysym;
@@ -276,9 +280,9 @@ static unsigned int _lowlevel_event(void)
/* Expose event */
if(xevent.type == Expose)
{
XCopyArea(x11_dpy, x11_pixmap, x11_window, x11_gc, 0, 0,
_caca_width * x11_font_width,
_caca_height * x11_font_height, 0, 0);
XCopyArea(kk->x11.dpy, kk->x11.pixmap, kk->x11.window, kk->x11.gc, 0, 0,
kk->qq->width * kk->x11.font_width,
kk->qq->height * kk->x11.font_height, 0, 0);
continue;
}

@@ -287,21 +291,21 @@ static unsigned int _lowlevel_event(void)
{
unsigned int w, h;

w = (xevent.xconfigure.width + x11_font_width / 3)
/ x11_font_width;
h = (xevent.xconfigure.height + x11_font_height / 3)
/ x11_font_height;
w = (xevent.xconfigure.width + kk->x11.font_width / 3)
/ kk->x11.font_width;
h = (xevent.xconfigure.height + kk->x11.font_height / 3)
/ kk->x11.font_height;

if(!w || !h || (w == _caca_width && h == _caca_height))
if(!w || !h || (w == kk->qq->width && h == kk->qq->height))
continue;

x11_new_width = w;
x11_new_height = h;
kk->x11.new_width = w;
kk->x11.new_height = h;

if(_caca_resize)
if(kk->resize)
continue;

_caca_resize = 1;
kk->resize = 1;

return CACA_EVENT_RESIZE;
}
@@ -309,13 +313,13 @@ static unsigned int _lowlevel_event(void)
/* Check for mouse motion events */
if(xevent.type == MotionNotify)
{
unsigned int newx = xevent.xmotion.x / x11_font_width;
unsigned int newy = xevent.xmotion.y / x11_font_height;
unsigned int newx = xevent.xmotion.x / kk->x11.font_width;
unsigned int newy = xevent.xmotion.y / kk->x11.font_height;

if(newx >= _caca_width)
newx = _caca_width - 1;
if(newy >= _caca_height)
newy = _caca_height - 1;
if(newx >= kk->qq->width)
newx = kk->qq->width - 1;
if(newy >= kk->qq->height)
newy = kk->qq->height - 1;

if(mouse_x == newx && mouse_y == newy)
continue;
@@ -346,7 +350,7 @@ static unsigned int _lowlevel_event(void)
if(XLookupString(&xevent.xkey, &key, 1, NULL, NULL))
return event | key;

keysym = XKeycodeToKeysym(x11_dpy, xevent.xkey.keycode, 0);
keysym = XKeycodeToKeysym(kk->x11.dpy, xevent.xkey.keycode, 0);
switch(keysym)
{
case XK_F1: return event | CACA_KEY_F1;
@@ -377,14 +381,14 @@ static unsigned int _lowlevel_event(void)
else
#endif
#if defined(USE_NCURSES)
if(_caca_driver == CACA_DRIVER_NCURSES)
if(kk->driver == CACA_DRIVER_NCURSES)
{
int intkey;

if(_caca_resize_event)
if(kk->resize_event)
{
_caca_resize_event = 0;
_caca_resize = 1;
kk->resize_event = 0;
kk->resize = 1;
return CACA_EVENT_RESIZE;
}

@@ -561,14 +565,14 @@ static unsigned int _lowlevel_event(void)
else
#endif
#if defined(USE_SLANG)
if(_caca_driver == CACA_DRIVER_SLANG)
if(kk->driver == CACA_DRIVER_SLANG)
{
int intkey;

if(_caca_resize_event)
if(kk->resize_event)
{
_caca_resize_event = 0;
_caca_resize = 1;
kk->resize_event = 0;
kk->resize = 1;
return CACA_EVENT_RESIZE;
}

@@ -644,7 +648,7 @@ static unsigned int _lowlevel_event(void)
else
#endif
#if defined(USE_CONIO)
if(_caca_driver == CACA_DRIVER_CONIO)
if(kk->driver == CACA_DRIVER_CONIO)
{
if(!_conio_kbhit())
return CACA_EVENT_NONE;
@@ -656,7 +660,7 @@ static unsigned int _lowlevel_event(void)
else
#endif
#if defined(USE_WIN32)
if(_caca_driver == CACA_DRIVER_WIN32)
if(kk->driver == CACA_DRIVER_WIN32)
{
INPUT_RECORD rec;
DWORD num;
@@ -730,13 +734,13 @@ static unsigned int _lowlevel_event(void)
else
#endif
#if defined(USE_GL)
if(_caca_driver == CACA_DRIVER_GL)
if(kk->driver == CACA_DRIVER_GL)
{
glutMainLoopEvent();

if(gl_resized && !_caca_resize)
if(gl_resized && !kk->resize)
{
_caca_resize = 1;
kk->resize = 1;
gl_resized = 0;
return CACA_EVENT_RESIZE;
}


+ 329
- 0
src/export.c View File

@@ -0,0 +1,329 @@
/*
* libcaca ASCII-Art library
* Copyright (c) 2002, 2003 Sam Hocevar <sam@zoy.org>
* All Rights Reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Do What The Fuck You Want To
* Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

/** \file char.c
* \version \$Id$
* \author Sam Hocevar <sam@zoy.org>
* \brief Character drawing
*
* This file contains character and string drawing functions.
*/

#include "config.h"

#if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME)
# include <inttypes.h>
#else
typedef unsigned char uint8_t;
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "cucul.h"
#include "cucul_internals.h"

/* HTML */

/** \brief Generate HTML representation of current image.
*
* This function generates and returns the HTML representation of
* the current image.
*/
char* cucul_get_html(cucul_t *qq)
{
static int const palette[] =
{
0x000, 0x008, 0x080, 0x088, 0x800, 0x808, 0x880, 0x888,
0x444, 0x44f, 0x4f4, 0x4ff, 0xf44, 0xf4f, 0xff4, 0xfff,
};
char *buffer, *cur;
unsigned int x, y, len;

/* 13000 -> css palette
* 40 -> max size used for a pixel (plus 10, never know)*/
/* FIXME: Check this value */
buffer = malloc((13000 + ((qq->width*qq->height) * 40)) * sizeof(char));
cur = buffer;

/* HTML header */
cur += sprintf(cur, "<html>\n<head>\n<title>Generated by libcaca %s</title>\n", VERSION);

/* CSS */
cur += sprintf(cur, "<style>\n");
cur += sprintf(cur, ".caca { font-family: monospace, fixed; font-weight: bold; }");
for(x = 0; x < 0x100; x++)
{
cur += sprintf(cur, ".b%02x { color:#%03x; background-color:#%03x; }\n",
x, palette[x & 0xf ], palette[x >> 4]);
}
cur += sprintf(cur, "</style>\n</head>\n<body>\n");

cur += sprintf(cur, "<div cellpadding='0' cellspacing='0' style='%s'>\n",
"font-family: monospace, fixed; font-weight: bold;");

for(y = 0; y < qq->height; y++)
{
uint8_t *lineattr = qq->attr + y * qq->width;
uint8_t *linechar = qq->chars + y * qq->width;

for(x = 0; x < qq->width; x += len)
{
cur += sprintf(cur, "<span class='b%02x'>", lineattr[x]);

for(len = 0;
x + len < qq->width && lineattr[x + len] == lineattr[x];
len++)
{
if(linechar[x + len] == ' ')
cur += sprintf(cur, "&nbsp;");
else
cur += sprintf(cur, "%c", linechar[x + len]);
}
cur += sprintf(cur, "</span>");
}
/* New line */
cur += sprintf(cur, "<br />\n");
}

cur += sprintf(cur, "</div></body></html>\n");

/* Crop to really used size */
buffer = realloc(buffer, (strlen(buffer) + 1) * sizeof(char));

return buffer;
}

/** \brief Generate HTML3 representation of current image.
*
* This function generates and returns the HTML3 representation of
* the current image. It is way bigger than cucul_get_html(), but
* permits viewing in old browsers (or limited ones such as links)
* Won't work under gecko (mozilla rendering engine) unless you set
* a correct header.
*/
char* cucul_get_html3(cucul_t *qq)
{
static int const palette[] =
{
0x000000, 0x000088, 0x008800, 0x008888,
0x880000, 0x880088, 0x888800, 0x888888,
0x444444, 0x4444ff, 0x44ff44, 0x44ffff,
0xff4444, 0xff44ff, 0xffff44, 0xffffff,
};
char *buffer, *cur;
unsigned int x, y, len;

/* 13000 -> css palette
* 40 -> max size used for a pixel (plus 10, never know) */
buffer = malloc((13000 + ((qq->width*qq->height)*40))*sizeof(char));
cur = buffer;

/* Table */
cur += sprintf(cur, "<table cols='%d' cellpadding='0' cellspacing='0'>\n",
qq->height);

for(y = 0; y < qq->height; y++)
{
uint8_t *lineattr = qq->attr + y * qq->width;
uint8_t *linechar = qq->chars + y * qq->width;

cur += sprintf(cur, "<tr>");

for(x = 0; x < qq->width; x += len)
{
unsigned int i;

/* Use colspan option to factorize cells with same attributes
* (see below) */
len = 1;
while(x + len < qq->width && lineattr[x + len] == lineattr[x])
len++;

cur += sprintf(cur, "<td bgcolor=#%06x", palette[lineattr[x] >> 4]);

if(len > 1)
cur += sprintf(cur, " colspan=%d", len);

cur += sprintf(cur, "><font color=#%06x>",
palette[lineattr[x] & 0x0f]);

for(i = 0; i < len; i++)
{
if(linechar[x + i] == ' ')
cur += sprintf(cur, "&nbsp;");
else
cur += sprintf(cur, "%c", linechar[x + i]);
}

cur += sprintf(cur, "</font></td>");
}
cur += sprintf(cur, "</tr>\n");
}

/* Footer */
cur += sprintf(cur, "</table>\n");

/* Crop to really used size */
buffer = realloc(buffer, (strlen(buffer) + 1) * sizeof(char));

return buffer;
}

/** \brief Generate IRC representation of current image.
*
* This function generates and returns an IRC representation of
* the current image.
*/
char* cucul_get_irc(cucul_t *qq)
{
static int const palette[] =
{
1, 2, 3, 10, 5, 6, 7, 15, /* Dark */
14, 12, 9, 11, 4, 13, 8, 0, /* Light */
};

char *buffer, *cur;
unsigned int x, y;

/* 11 bytes assumed for max length per pixel. Worst case scenario:
* ^Cxx,yy 6 bytes
* ^B^B 2 bytes
* c 1 byte
* \r\n 2 bytes
* In real life, the average bytes per pixel value will be around 5.
*/
buffer = malloc((2 + (qq->width * qq->height * 11)) * sizeof(char));
cur = buffer;

*cur++ = '\x0f';

for(y = 0; y < qq->height; y++)
{
uint8_t *lineattr = qq->attr + y * qq->width;
uint8_t *linechar = qq->chars + y * qq->width;

uint8_t prevfg = -1;
uint8_t prevbg = -1;

for(x = 0; x < qq->width; x++)
{
uint8_t fg = palette[lineattr[x] & 0x0f];
uint8_t bg = palette[lineattr[x] >> 4];
uint8_t c = linechar[x];

if(bg == prevbg)
{
if(fg == prevfg)
; /* Same fg/bg, do nothing */
else if(c == ' ')
fg = prevfg; /* Hackety hack */
else
{
cur += sprintf(cur, "\x03%d", fg);
if(c >= '0' && c <= '9')
cur += sprintf(cur, "\x02\x02");
}
}
else
{
if(fg == prevfg)
cur += sprintf(cur, "\x03,%d", bg);
else
cur += sprintf(cur, "\x03%d,%d", fg, bg);

if(c >= '0' && c <= '9')
cur += sprintf(cur, "\x02\x02");
}
*cur++ = c;
prevfg = fg;
prevbg = bg;
}
*cur++ = '\r';
*cur++ = '\n';
}

*cur++ = '\x0f';

/* Crop to really used size */
buffer = realloc(buffer, (strlen(buffer) + 1) * sizeof(char));

return buffer;
}

/** \brief Generate ANSI representation of current image.
*
* This function generates and returns an ANSI representation of
* the current image.
* \param trailing if 0, raw ANSI will be generated. Otherwise, you'll be
* able to cut/paste the result to a function like printf
* \return buffer containing generated ANSI codes as a big string
*/
char * cucul_get_ansi(cucul_t *qq, int trailing)
{
static int const palette[] =
{
30, 34, 32, 36, 31, 35, 33, 37, /* Both lines (light and dark) are the same, */
30, 34, 32, 36, 31, 35, 33, 37, /* light colors handling is done later */
};

char *buffer, *cur;
unsigned int x, y;

/* 20 bytes assumed for max length per pixel.
* Add height*9 to that (zeroes color at the end and jump to next line) */
buffer = malloc(((qq->height*9) + (qq->width * qq->height * 20)) * sizeof(char));
cur = buffer;

// *cur++ = '';

for(y = 0; y < qq->height; y++)
{
uint8_t *lineattr = qq->attr + y * qq->width;
uint8_t *linechar = qq->chars + y * qq->width;

uint8_t prevfg = -1;
uint8_t prevbg = -1;

for(x = 0; x < qq->width; x++)
{
uint8_t fg = palette[lineattr[x] & 0x0f];
uint8_t bg = (palette[lineattr[x] >> 4])+10;
uint8_t c = linechar[x];

if(!trailing)
cur += sprintf(cur, "\033[");
else
cur += sprintf(cur, "\\033[");

if(fg > 7)
cur += sprintf(cur, "1;%d;%dm",fg,bg);
else
cur += sprintf(cur, "0;%d;%dm",fg,bg);
*cur++ = c;
if((c == '%') && trailing)
*cur++ = c;
prevfg = fg;
prevbg = bg;
}
if(!trailing)
cur += sprintf(cur, "\033[0m\n\r");
else
cur += sprintf(cur, "\\033[0m\\n\n");
}

/* Crop to really used size */
buffer = realloc(buffer, (strlen(buffer) + 1) * sizeof(char));

return buffer;
}


+ 225
- 978
src/graphics.c
File diff suppressed because it is too large
View File


+ 36
- 36
src/line.c View File

@@ -28,8 +28,8 @@ typedef unsigned char uint8_t;

#include <stdlib.h>

#include "caca.h"
#include "caca_internals.h"
#include "cucul.h"
#include "cucul_internals.h"

#if !defined(_DOXYGEN_SKIP_ME)
struct line
@@ -37,14 +37,14 @@ struct line
int x1, y1;
int x2, y2;
char c;
void (*draw) (struct line*);
void (*draw) (cucul_t *, struct line*);
};
#endif

static void clip_line(struct line*);
static uint8_t clip_bits(int, int);
static void draw_solid_line(struct line*);
static void draw_thin_line(struct line*);
static void clip_line(cucul_t*, struct line*);
static uint8_t clip_bits(cucul_t*, int, int);
static void draw_solid_line(cucul_t*, struct line*);
static void draw_thin_line(cucul_t*, struct line*);

/**
* \brief Draw a line on the screen using the given character.
@@ -56,7 +56,7 @@ static void draw_thin_line(struct line*);
* \param c Character to draw the line with.
* \return void
*/
void caca_draw_line(int x1, int y1, int x2, int y2, char c)
void cucul_draw_line(cucul_t *qq, int x1, int y1, int x2, int y2, char c)
{
struct line s;
s.x1 = x1;
@@ -65,7 +65,7 @@ void caca_draw_line(int x1, int y1, int x2, int y2, char c)
s.y2 = y2;
s.c = c;
s.draw = draw_solid_line;
clip_line(&s);
clip_line(qq, &s);
}

/**
@@ -80,7 +80,7 @@ void caca_draw_line(int x1, int y1, int x2, int y2, char c)
* \param c Character to draw the lines with.
* \return void
*/
void caca_draw_polyline(int const x[], int const y[], int n, char c)
void cucul_draw_polyline(cucul_t *qq, int const x[], int const y[], int n, char c)
{
int i;
struct line s;
@@ -93,7 +93,7 @@ void caca_draw_polyline(int const x[], int const y[], int n, char c)
s.y1 = y[i];
s.x2 = x[i+1];
s.y2 = y[i+1];
clip_line(&s);
clip_line(qq, &s);
}
}

@@ -106,7 +106,7 @@ void caca_draw_polyline(int const x[], int const y[], int n, char c)
* \param y2 Y coordinate of the second point.
* \return void
*/
void caca_draw_thin_line(int x1, int y1, int x2, int y2)
void cucul_draw_thin_line(cucul_t *qq, int x1, int y1, int x2, int y2)
{
struct line s;
s.x1 = x1;
@@ -114,7 +114,7 @@ void caca_draw_thin_line(int x1, int y1, int x2, int y2)
s.x2 = x2;
s.y2 = y2;
s.draw = draw_thin_line;
clip_line(&s);
clip_line(qq, &s);
}

/**
@@ -128,7 +128,7 @@ void caca_draw_thin_line(int x1, int y1, int x2, int y2)
* \param n Number of lines to draw.
* \return void
*/
void caca_draw_thin_polyline(int const x[], int const y[], int n)
void cucul_draw_thin_polyline(cucul_t *qq, int const x[], int const y[], int n)
{
int i;
struct line s;
@@ -140,7 +140,7 @@ void caca_draw_thin_polyline(int const x[], int const y[], int n)
s.y1 = y[i];
s.x2 = x[i+1];
s.y2 = y[i+1];
clip_line(&s);
clip_line(qq, &s);
}
}

@@ -154,12 +154,12 @@ void caca_draw_thin_polyline(int const x[], int const y[], int n)
* \param s a line structure
* \return void
*/
static void clip_line(struct line* s)
static void clip_line(cucul_t *qq, struct line* s)
{
uint8_t bits1, bits2;

bits1 = clip_bits(s->x1, s->y1);
bits2 = clip_bits(s->x2, s->y2);
bits1 = clip_bits(qq, s->x1, s->y1);
bits2 = clip_bits(qq, s->x2, s->y2);

if(bits1 & bits2)
return;
@@ -167,13 +167,13 @@ static void clip_line(struct line* s)
if(bits1 == 0)
{
if(bits2 == 0)
s->draw(s);
s->draw(qq, s);
else
{
int tmp;
tmp = s->x1; s->x1 = s->x2; s->x2 = tmp;
tmp = s->y1; s->y1 = s->y2; s->y2 = tmp;
clip_line(s);
clip_line(qq, s);
}

return;
@@ -186,7 +186,7 @@ static void clip_line(struct line* s)
}
else if(bits1 & (1<<1))
{
int xmax = _caca_width - 1;
int xmax = qq->width - 1;
s->y1 = s->y2 - (s->x2 - xmax) * (s->y2 - s->y1) / (s->x2 - s->x1);
s->x1 = xmax;
}
@@ -197,12 +197,12 @@ static void clip_line(struct line* s)
}
else if(bits1 & (1<<3))
{
int ymax = _caca_height - 1;
int ymax = qq->height - 1;
s->x1 = s->x2 - (s->y2 - ymax) * (s->x2 - s->x1) / (s->y2 - s->y1);
s->y1 = ymax;
}

clip_line(s);
clip_line(qq, s);
}

/**
@@ -212,18 +212,18 @@ static void clip_line(struct line* s)
* \param y Y coordinate of the point.
* \return The clipping bits for the given point.
*/
static uint8_t clip_bits(int x, int y)
static uint8_t clip_bits(cucul_t *qq, int x, int y)
{
uint8_t b = 0;

if(x < 0)
b |= (1<<0);
else if(x >= (int)_caca_width)
else if(x >= (int)qq->width)
b |= (1<<1);

if(y < 0)
b |= (1<<2);
else if(y >= (int)_caca_height)
else if(y >= (int)qq->height)
b |= (1<<3);

return b;
@@ -236,7 +236,7 @@ static uint8_t clip_bits(int x, int y)
* \param s a line structure
* \return void
*/
static void draw_solid_line(struct line* s)
static void draw_solid_line(cucul_t *qq, struct line* s)
{
int x1, y1, x2, y2;
int dx, dy;
@@ -258,7 +258,7 @@ static void draw_solid_line(struct line* s)

for(; dx>=0; dx--)
{
caca_putchar(x1, y1, s->c);
cucul_putchar(qq, x1, y1, s->c);
if(delta > 0)
{
x1 += xinc;
@@ -280,7 +280,7 @@ static void draw_solid_line(struct line* s)

for(; dy >= 0; dy--)
{
caca_putchar(x1, y1, s->c);
cucul_putchar(qq, x1, y1, s->c);
if(delta > 0)
{
x1 += xinc;
@@ -303,7 +303,7 @@ static void draw_solid_line(struct line* s)
* \param s a line structure
* \return void
*/
static void draw_thin_line(struct line* s)
static void draw_thin_line(cucul_t *qq, struct line* s)
{
char *charmapx, *charmapy;
int x1, y1, x2, y2;
@@ -352,7 +352,7 @@ static void draw_thin_line(struct line* s)
{
if(delta > 0)
{
caca_putchar(x1, y1, charmapy[1]);
cucul_putchar(qq, x1, y1, charmapy[1]);
x1++;
y1 += yinc;
delta += dpru;
@@ -361,9 +361,9 @@ static void draw_thin_line(struct line* s)
else
{
if(prev)
caca_putchar(x1, y1, charmapy[0]);
cucul_putchar(qq, x1, y1, charmapy[0]);
else
caca_putchar(x1, y1, '-');
cucul_putchar(qq, x1, y1, '-');
x1++;
delta += dpr;
prev = 0;
@@ -380,15 +380,15 @@ static void draw_thin_line(struct line* s)
{
if(delta > 0)
{
caca_putchar(x1, y1, charmapx[0]);
caca_putchar(x1 + 1, y1, charmapx[1]);
cucul_putchar(qq, x1, y1, charmapx[0]);
cucul_putchar(qq, x1 + 1, y1, charmapx[1]);
x1++;
y1 += yinc;
delta += dpru;
}
else
{
caca_putchar(x1, y1, '|');
cucul_putchar(qq, x1, y1, '|');
y1 += yinc;
delta += dpr;
}


+ 12
- 6
src/math.c View File

@@ -19,10 +19,16 @@

#include "config.h"

#if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME)
# include <inttypes.h>
#else
typedef unsigned char uint8_t;
#endif

#include <stdlib.h>

#include "caca.h"
#include "caca_internals.h"
#include "cucul.h"
#include "cucul_internals.h"

/**
* \brief Generate a random integer within a range.
@@ -31,7 +37,7 @@
* \param max The upper bound of the integer range.
* \return A random integer comprised between \p min and \p max, inclusive.
*/
int caca_rand(int min, int max)
int cucul_rand(int min, int max)
{
return min + (int)((1.0*(max-min+1)) * rand() / (RAND_MAX+1.0));
}
@@ -43,7 +49,7 @@ int caca_rand(int min, int max)
* \param a A positive integer.
* \return The approximate square root of \p a.
*/
unsigned int caca_sqrt(unsigned int a)
unsigned int cucul_sqrt(unsigned int a)
{
if(a == 0)
return 0;
@@ -65,7 +71,7 @@ unsigned int caca_sqrt(unsigned int a)
return x;
}

return 2 * caca_sqrt(a / 4);
return 2 * cucul_sqrt(a / 4);
}


@@ -76,7 +82,7 @@ unsigned int caca_sqrt(unsigned int a)
* \return \p x raised to the power of \p y
*/

float caca_powf(float x, float y)
float cucul_powf(float x, float y)
{
int i=((int)y);
float r=x;


+ 33
- 27
src/sprite.c View File

@@ -19,15 +19,21 @@

#include "config.h"

#if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME)
# include <inttypes.h>
#else
typedef unsigned char uint8_t;
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "caca.h"
#include "caca_internals.h"
#include "cucul.h"
#include "cucul_internals.h"

#if !defined(_DOXYGEN_SKIP_ME)
struct caca_frame
struct cucul_frame
{
int w, h;
int dx, dy;
@@ -35,10 +41,10 @@ struct caca_frame
int *color;
};

struct caca_sprite
struct cucul_sprite
{
int nf;
struct caca_frame *frames;
struct cucul_frame *frames;
};
#endif

@@ -48,17 +54,17 @@ struct caca_sprite
* \param file The filename.
* \return The sprite, or NULL if an error occured.
*/
struct caca_sprite *caca_load_sprite(char const *file)
struct cucul_sprite *cucul_load_sprite(cucul_t *qq, char const *file)
{
char buf[BUFSIZ];
struct caca_sprite *sprite;
struct cucul_sprite *sprite;
FILE *fd;

fd = fopen(file, "r");
if(fd == NULL)
return NULL;

sprite = malloc(sizeof(struct caca_sprite));
sprite = malloc(sizeof(struct cucul_sprite));
if(sprite == NULL)
goto sprite_alloc_failed;

@@ -69,7 +75,7 @@ struct caca_sprite *caca_load_sprite(char const *file)
{
int x, y;
int w = 0, h = 0, dx = 0, dy = 0;
struct caca_frame *frame;
struct cucul_frame *frame;

/* Get width and height */
if(!fgets(buf, BUFSIZ, fd))
@@ -82,7 +88,7 @@ struct caca_sprite *caca_load_sprite(char const *file)
if(sprite->nf)
{
void *tmp = realloc(sprite->frames,
(sprite->nf + 1) * sizeof(struct caca_frame));
(sprite->nf + 1) * sizeof(struct cucul_frame));
if(tmp == NULL)
goto frame_failed;
sprite->frames = tmp;
@@ -90,7 +96,7 @@ struct caca_sprite *caca_load_sprite(char const *file)
}
else
{
sprite->frames = malloc((sprite->nf + 1) * sizeof(struct caca_frame));
sprite->frames = malloc((sprite->nf + 1) * sizeof(struct cucul_frame));
if(sprite->frames == NULL)
goto sprite_failed;
sprite->nf++;
@@ -169,7 +175,7 @@ sprite_alloc_failed:
* \param sprite The sprite.
* \return The number of frames.
*/
int caca_get_sprite_frames(struct caca_sprite const *sprite)
int cucul_get_sprite_frames(cucul_t *qq, struct cucul_sprite const *sprite)
{
if(sprite == NULL)
return 0;
@@ -184,7 +190,7 @@ int caca_get_sprite_frames(struct caca_sprite const *sprite)
* \param f The frame index.
* \return The width of the given frame of the sprite.
*/
int caca_get_sprite_width(struct caca_sprite const *sprite, int f)
int cucul_get_sprite_width(cucul_t *qq, struct cucul_sprite const *sprite, int f)
{
if(sprite == NULL)
return 0;
@@ -202,7 +208,7 @@ int caca_get_sprite_width(struct caca_sprite const *sprite, int f)
* \param f The frame index.
* \return The height of the given frame of the sprite.
*/
int caca_get_sprite_height(struct caca_sprite const *sprite, int f)
int cucul_get_sprite_height(cucul_t *qq, struct cucul_sprite const *sprite, int f)
{
if(sprite == NULL)
return 0;
@@ -220,7 +226,7 @@ int caca_get_sprite_height(struct caca_sprite const *sprite, int f)
* \param f The frame index.
* \return The X coordinate of the given frame's handle.
*/
int caca_get_sprite_dx(struct caca_sprite const *sprite, int f)
int cucul_get_sprite_dx(cucul_t *qq, struct cucul_sprite const *sprite, int f)
{
if(sprite == NULL)
return 0;
@@ -238,7 +244,7 @@ int caca_get_sprite_dx(struct caca_sprite const *sprite, int f)
* \param f The frame index.
* \return The Y coordinate of the given frame's handle.
*/
int caca_get_sprite_dy(struct caca_sprite const *sprite, int f)
int cucul_get_sprite_dy(cucul_t *qq, struct cucul_sprite const *sprite, int f)
{
if(sprite == NULL)
return 0;
@@ -259,11 +265,11 @@ int caca_get_sprite_dy(struct caca_sprite const *sprite, int f)
* \param f The frame index.
* \return void
*/
void caca_draw_sprite(int x, int y, struct caca_sprite const *sprite, int f)
void cucul_draw_sprite(cucul_t *qq, int x, int y, struct cucul_sprite const *sprite, int f)
{
int i, j;
enum caca_color oldfg, oldbg;
struct caca_frame *frame;
enum cucul_color oldfg, oldbg;
struct cucul_frame *frame;

if(sprite == NULL)
return;
@@ -273,8 +279,8 @@ void caca_draw_sprite(int x, int y, struct caca_sprite const *sprite, int f)

frame = &sprite->frames[f];

oldfg = caca_get_fg_color();
oldbg = caca_get_bg_color();
oldfg = cucul_get_fg_color(qq);
oldbg = cucul_get_bg_color(qq);

for(j = 0; j < frame->h; j++)
{
@@ -283,14 +289,14 @@ void caca_draw_sprite(int x, int y, struct caca_sprite const *sprite, int f)
int col = frame->color[frame->w * j + i];
if(col >= 0)
{
caca_set_color(col, CACA_COLOR_BLACK);
caca_putchar(x + i - frame->dx, y + j - frame->dy,
frame->chars[frame->w * j + i]);
cucul_set_color(qq, col, CUCUL_COLOR_BLACK);
cucul_putchar(qq, x + i - frame->dx, y + j - frame->dy,
frame->chars[frame->w * j + i]);
}
}
}

caca_set_color(oldfg, oldbg);
cucul_set_color(qq, oldfg, oldbg);
}

/**
@@ -299,7 +305,7 @@ void caca_draw_sprite(int x, int y, struct caca_sprite const *sprite, int f)
* \param sprite The sprite to be freed.
* \return void
*/
void caca_free_sprite(struct caca_sprite *sprite)
void cucul_free_sprite(cucul_t *qq, struct cucul_sprite *sprite)
{
int i;

@@ -308,7 +314,7 @@ void caca_free_sprite(struct caca_sprite *sprite)

for(i = sprite->nf; i--;)
{
struct caca_frame *frame = &sprite->frames[i];
struct cucul_frame *frame = &sprite->frames[i];
free(frame->chars);
free(frame->color);
}


+ 22
- 16
src/triangle.c View File

@@ -19,10 +19,16 @@

#include "config.h"

#if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME)
# include <inttypes.h>
#else
typedef unsigned char uint8_t;
#endif

#include <stdlib.h>

#include "caca.h"
#include "caca_internals.h"
#include "cucul.h"
#include "cucul_internals.h"

/**
* \brief Draw a triangle on the screen using the given character.
@@ -36,11 +42,11 @@
* \param c Character to draw the triangle outline with.
* \return void
*/
void caca_draw_triangle(int x1, int y1, int x2, int y2, int x3, int y3, char c)
void cucul_draw_triangle(cucul_t *qq, int x1, int y1, int x2, int y2, int x3, int y3, char c)
{
caca_draw_line(x1, y1, x2, y2, c);
caca_draw_line(x2, y2, x3, y3, c);
caca_draw_line(x3, y3, x1, y1, c);
cucul_draw_line(qq, x1, y1, x2, y2, c);
cucul_draw_line(qq, x2, y2, x3, y3, c);
cucul_draw_line(qq, x3, y3, x1, y1, c);
}

/**
@@ -54,11 +60,11 @@ void caca_draw_triangle(int x1, int y1, int x2, int y2, int x3, int y3, char c)
* \param y3 Y coordinate of the third point.
* \return void
*/
void caca_draw_thin_triangle(int x1, int y1, int x2, int y2, int x3, int y3)
void cucul_draw_thin_triangle(cucul_t *qq, int x1, int y1, int x2, int y2, int x3, int y3)
{
caca_draw_thin_line(x1, y1, x2, y2);
caca_draw_thin_line(x2, y2, x3, y3);
caca_draw_thin_line(x3, y3, x1, y1);
cucul_draw_thin_line(qq, x1, y1, x2, y2);
cucul_draw_thin_line(qq, x2, y2, x3, y3);
cucul_draw_thin_line(qq, x3, y3, x1, y1);
}

/**
@@ -73,20 +79,20 @@ void caca_draw_thin_triangle(int x1, int y1, int x2, int y2, int x3, int y3)
* \param c Character to fill the triangle with.
* \return void
*/
void caca_fill_triangle(int x1, int y1, int x2, int y2, int x3, int y3, char c)
void cucul_fill_triangle(cucul_t *qq, int x1, int y1, int x2, int y2, int x3, int y3, char c)
{
int x, y, xa, xb, xmax, ymax;

/* Bubble-sort y1 <= y2 <= y3 */
if(y1 > y2)
{
caca_fill_triangle(x2, y2, x1, y1, x3, y3, c);
cucul_fill_triangle(qq, x2, y2, x1, y1, x3, y3, c);
return;
}

if(y2 > y3)
{
caca_fill_triangle(x1, y1, x3, y3, x2, y2, c);
cucul_fill_triangle(qq, x1, y1, x3, y3, x2, y2, c);
return;
}

@@ -95,8 +101,8 @@ void caca_fill_triangle(int x1, int y1, int x2, int y2, int x3, int y3, char c)
x2 *= 4;
x3 *= 4;

xmax = _caca_width - 1;
ymax = _caca_height - 1;
xmax = qq->width - 1;
ymax = qq->height - 1;

/* Rasterize our triangle */
for(y = y1 < 0 ? 0 : y1; y <= y3 && y <= ymax; y++)
@@ -128,7 +134,7 @@ void caca_fill_triangle(int x1, int y1, int x2, int y2, int x3, int y3, char c)
if(xb > xmax) xb = xmax;

for(x = xa; x <= xb; x++)
caca_putchar(x, y, c);
cucul_putchar(qq, x, y, c);
}
}


+ 6
- 2
test/Makefile.am View File

@@ -1,11 +1,15 @@
# $Id$

noinst_PROGRAMS = colors dithering event hsv optipal spritedit
noinst_PROGRAMS = colors demo dithering event hsv optipal spritedit

colors_SOURCES = colors.c
colors_LDADD = ../src/libcaca.la @CACA_LIBS@
colors_CPPFLAGS = -I$(top_srcdir)/src

demo_SOURCES = demo.c
demo_LDADD = ../src/libcaca.la @CACA_LIBS@ @MATH_LIBS@
demo_CPPFLAGS = -I$(top_srcdir)/src -DDATADIR=\"$(pkgdatadir)\"

dithering_SOURCES = dithering.c
dithering_LDADD = ../src/libcaca.la @CACA_LIBS@
dithering_CPPFLAGS = -I$(top_srcdir)/src
@@ -19,7 +23,7 @@ hsv_LDADD = ../src/libcaca.la @CACA_LIBS@
hsv_CPPFLAGS = -I$(top_srcdir)/src

optipal_SOURCES = optipal.c
optipal_LDADD = ../src/libcaca.la @CACA_LIBS@
optipal_LDADD = ../src/libcucul.la @CUCUL_LIBS@
optipal_CPPFLAGS = -I$(top_srcdir)/src

spritedit_SOURCES = spritedit.c


+ 21
- 10
test/colors.c View File

@@ -15,31 +15,42 @@

#include <stdio.h>

#include "cucul.h"
#include "caca.h"

int main(int argc, char **argv)
{
cucul_t *qq;
caca_t *kk;
int i, j;

if(caca_init())
qq = cucul_init();
if(!qq)
return 1;

caca_clear();
kk = caca_attach(qq);
if(!kk)
return 1;

cucul_clear(qq);
for(i = 0; i < 16; i++)
{
caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_BLACK);
caca_printf(4, i + (i >= 8 ? 4 : 3), "'%c': %i (%s)",
'a' + i, i, caca_get_color_name(i));
cucul_set_color(qq, CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLACK);
cucul_printf(qq, 4, i + (i >= 8 ? 4 : 3), "'%c': %i (%s)",
'a' + i, i, cucul_get_color_name(i));
for(j = 0; j < 16; j++)
{
caca_set_color(i, j);
caca_putstr((j >= 8 ? 41 : 40) + j * 2, i + (i >= 8 ? 4 : 3), "# ");
cucul_set_color(qq, i, j);
cucul_putstr(qq, (j >= 8 ? 41 : 40) + j * 2, i + (i >= 8 ? 4 : 3),
"# ");
}
}

caca_refresh();
caca_wait_event(CACA_EVENT_KEY_PRESS);
caca_end();
caca_refresh(kk);
caca_wait_event(kk, CACA_EVENT_KEY_PRESS);

caca_detach(kk);
cucul_end(qq);

return 0;
}


+ 564
- 0
test/demo.c View File

@@ -0,0 +1,564 @@
/*
* demo demo for libcaca
* Copyright (c) 2003 Sam Hocevar <sam@zoy.org>
* All Rights Reserved
*
* $Id$
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the Do What The Fuck You Want To
* Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#include <math.h>
#include <string.h>
#include <stdio.h>

#include "caca.h"

static void display_menu(void);

static void demo_all(void);

static void demo_color(void);
static void demo_dots(void);
static void demo_lines(void);
static void demo_boxes(void);
static void demo_ellipses(void);
static void demo_triangles(void);
static void demo_sprites(void);
static void demo_render(void);

int bounds = 0;
int outline = 0;
int dithering = 0;
struct cucul_sprite *sprite = NULL;

cucul_t *qq;
caca_t *kk;

int main(int argc, char **argv)
{
void (*demo)(void) = NULL;
int quit = 0;

qq = cucul_init();
if(!qq)
return 1;
kk = caca_attach(qq);
if(!kk)
return 1;

caca_set_delay(kk, 40000);

/* Initialize data */
sprite = cucul_load_sprite(qq, DATADIR "/caca.txt");
if(!sprite)
sprite = cucul_load_sprite(qq, "caca.txt");
if(!sprite)
sprite = cucul_load_sprite(qq, "examples/caca.txt");

/* Main menu */
display_menu();
caca_refresh(kk);

/* Go ! */
while(!quit)
{
int menu = 0, mouse = 0, xmouse = 0, ymouse = 0;
int event;

while((event = caca_get_event(kk, CACA_EVENT_ANY)))
{
if(demo && (event & CACA_EVENT_KEY_PRESS))
{
menu = 1;
demo = NULL;
}
else if(event & CACA_EVENT_KEY_PRESS)
{
switch(event & 0xffff)
{
case 'q':
case 'Q':
demo = NULL;
quit = 1;
break;
case 'o':
case 'O':
outline = (outline + 1) % 3;
display_menu();
break;
case 'b':
case 'B':
bounds = (bounds + 1) % 2;
display_menu();
break;
case 'd':
case 'D':
dithering = (dithering + 1) % 5;
cucul_set_feature(qq, dithering);
display_menu();
break;
case 'c':
demo = demo_color;
break;
case 'f':
case 'F':
demo = demo_all;
break;
case '1':
demo = demo_dots;
break;
case '2':
demo = demo_lines;
break;
case '3':
demo = demo_boxes;
break;
case '4':
demo = demo_triangles;
break;
case '5':
demo = demo_ellipses;
break;
case 's':
case 'S':
if(sprite)
demo = demo_sprites;
break;
case 'r':
case 'R':
demo = demo_render;
break;
}

if(demo)
cucul_clear(qq);
}
else if(event & CACA_EVENT_MOUSE_MOTION)
{
mouse = 1;
xmouse = (event & 0xfff000) >> 12;
ymouse = event & 0xfff;
}
}

if(menu || (mouse && !demo))
{
display_menu();
if(mouse && !demo)
{
cucul_set_color(qq, CUCUL_COLOR_RED, CUCUL_COLOR_BLACK);
cucul_putstr(qq, xmouse, ymouse, "|\\");
}
caca_refresh(kk);
mouse = menu = 0;
}

if(demo)
{
demo();

cucul_set_color(qq, CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLACK);
cucul_draw_thin_box(qq, 1, 1, cucul_get_width(qq) - 2, cucul_get_height(qq) - 2);
cucul_printf(qq, 4, 1, "[%i.%i fps]----",
1000000 / caca_get_rendertime(kk),
(10000000 / caca_get_rendertime(kk)) % 10);
caca_refresh(kk);
}
}

/* Clean up */
cucul_free_sprite(qq, sprite);
caca_detach(kk);
cucul_end(qq);

return 0;
}

static void display_menu(void)
{
int xo = cucul_get_width(qq) - 2;
int yo = cucul_get_height(qq) - 2;

cucul_clear(qq);
cucul_set_color(qq, CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLACK);
cucul_draw_thin_box(qq, 1, 1, xo, yo);

cucul_putstr(qq, (xo - strlen("libcaca demo")) / 2, 3, "libcaca demo");
cucul_putstr(qq, (xo - strlen("==============")) / 2, 4, "==============");

cucul_putstr(qq, 4, 6, "demos:");
cucul_putstr(qq, 4, 7, "'f': full");
cucul_putstr(qq, 4, 8, "'1': dots");
cucul_putstr(qq, 4, 9, "'2': lines");
cucul_putstr(qq, 4, 10, "'3': boxes");
cucul_putstr(qq, 4, 11, "'4': triangles");
cucul_putstr(qq, 4, 12, "'5': ellipses");
cucul_putstr(qq, 4, 13, "'c': colour");
cucul_putstr(qq, 4, 14, "'r': render");
if(sprite)
cucul_putstr(qq, 4, 15, "'s': sprites");

cucul_putstr(qq, 4, 16, "settings:");
cucul_printf(qq, 4, 17, "'o': outline: %s",
outline == 0 ? "none" : outline == 1 ? "solid" : "thin");
cucul_printf(qq, 4, 18, "'b': drawing boundaries: %s",
bounds == 0 ? "screen" : "infinite");
cucul_printf(qq, 4, 19, "'d': dithering (%s)",
cucul_get_feature_name(dithering));

cucul_putstr(qq, 4, yo - 2, "'q': quit");
}

static void demo_all(void)
{
static int i = 0;

int j, xo, yo, xa, ya, xb, yb, xc, yc;

i++;

cucul_clear(qq);

/* Draw the sun */
cucul_set_color(qq, CUCUL_COLOR_YELLOW, CUCUL_COLOR_BLACK);
xo = cucul_get_width(qq) / 4;
yo = cucul_get_height(qq) / 4 + 5 * sin(0.03*i);

for(j = 0; j < 16; j++)
{
xa = xo - (30 + sin(0.03*i) * 8) * sin(0.03*i + M_PI*j/8);
ya = yo + (15 + sin(0.03*i) * 4) * cos(0.03*i + M_PI*j/8);
cucul_draw_thin_line(qq, xo, yo, xa, ya);
}

j = 15 + sin(0.03*i) * 8;
cucul_set_color(qq, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLACK);
cucul_fill_ellipse(qq, xo, yo, j, j / 2, '#');
cucul_set_color(qq, CUCUL_COLOR_YELLOW, CUCUL_COLOR_BLACK);
cucul_draw_ellipse(qq, xo, yo, j, j / 2, '#');

/* Draw the pyramid */
xo = cucul_get_width(qq) * 5 / 8;
yo = 2;

xa = cucul_get_width(qq) / 8 + sin(0.03*i) * 5;
ya = cucul_get_height(qq) / 2 + cos(0.03*i) * 5;

xb = cucul_get_width(qq) - 10 - cos(0.02*i) * 10;
yb = cucul_get_height(qq) * 3 / 4 - 5 + sin(0.02*i) * 5;

xc = cucul_get_width(qq) / 4 - sin(0.02*i) * 5;
yc = cucul_get_height(qq) * 3 / 4 + cos(0.02*i) * 5;

cucul_set_color(qq, CUCUL_COLOR_GREEN, CUCUL_COLOR_BLACK);
cucul_fill_triangle(qq, xo, yo, xb, yb, xa, ya, '%');
cucul_set_color(qq, CUCUL_COLOR_YELLOW, CUCUL_COLOR_BLACK);
cucul_draw_thin_triangle(qq, xo, yo, xb, yb, xa, ya);

cucul_set_color(qq, CUCUL_COLOR_RED, CUCUL_COLOR_BLACK);
cucul_fill_triangle(qq, xa, ya, xb, yb, xc, yc, '#');
cucul_set_color(qq, CUCUL_COLOR_YELLOW, CUCUL_COLOR_BLACK);
cucul_draw_thin_triangle(qq, xa, ya, xb, yb, xc, yc);

cucul_set_color(qq, CUCUL_COLOR_BLUE, CUCUL_COLOR_BLACK);
cucul_fill_triangle(qq, xo, yo, xb, yb, xc, yc, '%');
cucul_set_color(qq, CUCUL_COLOR_YELLOW, CUCUL_COLOR_BLACK);
cucul_draw_thin_triangle(qq, xo, yo, xb, yb, xc, yc);

/* Draw a background triangle */
xa = 2;
ya = 2;

xb = cucul_get_width(qq) - 3;
yb = cucul_get_height(qq) / 2;

xc = cucul_get_width(qq) / 3;
yc = cucul_get_height(qq) - 3;

cucul_set_color(qq, CUCUL_COLOR_CYAN, CUCUL_COLOR_BLACK);
cucul_draw_thin_triangle(qq, xa, ya, xb, yb, xc, yc);

xo = cucul_get_width(qq) / 2 + cos(0.027*i) * cucul_get_width(qq) / 3;
yo = cucul_get_height(qq) / 2 - sin(0.027*i) * cucul_get_height(qq) / 2;

cucul_draw_thin_line(qq, xa, ya, xo, yo);
cucul_draw_thin_line(qq, xb, yb, xo, yo);
cucul_draw_thin_line(qq, xc, yc, xo, yo);

/* Draw a sprite on the pyramid */
cucul_draw_sprite(qq, xo, yo, sprite, 0);

/* Draw a trail behind the foreground sprite */
for(j = i - 60; j < i; j++)
{
int delta = cucul_rand(-5, 5);
cucul_set_color(qq, cucul_rand(0, 15), cucul_rand(0, 15));
cucul_putchar(qq, cucul_get_width(qq) / 2
+ cos(0.02*j) * (delta + cucul_get_width(qq) / 4),
cucul_get_height(qq) / 2
+ sin(0.02*j) * (delta + cucul_get_height(qq) / 3),
'#');
}

/* Draw foreground sprite */
cucul_draw_sprite(qq, cucul_get_width(qq) / 2 + cos(0.02*i) * cucul_get_width(qq) / 4,
cucul_get_height(qq) / 2 + sin(0.02*i) * cucul_get_height(qq) / 3,
sprite, 0);
}

static void demo_dots(void)
{
int xmax = cucul_get_width(qq) - 1;
int ymax = cucul_get_height(qq) - 1;
int i;
static char chars[10] =
{
'+', '-', '*', '#', 'X', '@', '%', '$', 'M', 'W'
};

for(i = 1000; i--;)
{
/* Putpixel */
cucul_set_color(qq, cucul_rand(0, 15), cucul_rand(0, 15));
cucul_putchar(qq, cucul_rand(0, xmax), cucul_rand(0, ymax),
chars[cucul_rand(0, 9)]);
}
}

static void demo_color(void)
{
int i, j;
char buf[BUFSIZ];

cucul_clear(qq);
for(i = 0; i < 16; i++)
{
sprintf(buf, "'%c': %i (%s)", 'a' + i, i, cucul_get_color_name(i));
cucul_set_color(qq, CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLACK);
cucul_putstr(qq, 4, i + (i >= 8 ? 4 : 3), buf);
for(j = 0; j < 16; j++)
{
cucul_set_color(qq, i, j);
cucul_putstr(qq, (j >= 8 ? 41 : 40) + j * 2, i + (i >= 8 ? 4 : 3), "# ");
}
}
}

static void demo_lines(void)
{
int w = cucul_get_width(qq);
int h = cucul_get_height(qq);
int xa, ya, xb, yb;

if(bounds)
{
xa = cucul_rand(- w, 2 * w); ya = cucul_rand(- h, 2 * h);
xb = cucul_rand(- w, 2 * w); yb = cucul_rand(- h, 2 * h);
}
else
{
xa = cucul_rand(0, w - 1); ya = cucul_rand(0, h - 1);
xb = cucul_rand(0, w - 1); yb = cucul_rand(0, h - 1);
}

cucul_set_color(qq, cucul_rand(0, 15), CUCUL_COLOR_BLACK);
if(outline > 1)
cucul_draw_thin_line(qq, xa, ya, xb, yb);
else
cucul_draw_line(qq, xa, ya, xb, yb, '#');
}

static void demo_boxes(void)
{
int w = cucul_get_width(qq);
int h = cucul_get_height(qq);
int xa, ya, xb, yb;

if(bounds)
{
xa = cucul_rand(- w, 2 * w); ya = cucul_rand(- h, 2 * h);
xb = cucul_rand(- w, 2 * w); yb = cucul_rand(- h, 2 * h);
}
else
{
xa = cucul_rand(0, w - 1); ya = cucul_rand(0, h - 1);
xb = cucul_rand(0, w - 1); yb = cucul_rand(0, h - 1);
}

cucul_set_color(qq, cucul_rand(0, 15), cucul_rand(0, 15));
cucul_fill_box(qq, xa, ya, xb, yb, '#');

cucul_set_color(qq, cucul_rand(0, 15), CUCUL_COLOR_BLACK);
if(outline == 2)
cucul_draw_thin_box(qq, xa, ya, xb, yb);
else if(outline == 1)
cucul_draw_box(qq, xa, ya, xb, yb, '#');
}

static void demo_ellipses(void)
{
int w = cucul_get_width(qq);
int h = cucul_get_height(qq);
int x, y, a, b;

if(bounds)
{
x = cucul_rand(- w, 2 * w); y = cucul_rand(- h, 2 * h);
a = cucul_rand(0, w); b = cucul_rand(0, h);
}
else
{
do
{
x = cucul_rand(0, w); y = cucul_rand(0, h);
a = cucul_rand(0, w); b = cucul_rand(0, h);

} while(x - a < 0 || x + a >= w || y - b < 0 || y + b >= h);
}

cucul_set_color(qq, cucul_rand(0, 15), cucul_rand(0, 15));
cucul_fill_ellipse(qq, x, y, a, b, '#');

cucul_set_color(qq, cucul_rand(0, 15), CUCUL_COLOR_BLACK);
if(outline == 2)
cucul_draw_thin_ellipse(qq, x, y, a, b);
else if(outline == 1)
cucul_draw_ellipse(qq, x, y, a, b, '#');
}

static void demo_triangles(void)
{
int w = cucul_get_width(qq);
int h = cucul_get_height(qq);
int xa, ya, xb, yb, xc, yc;

if(bounds)
{
xa = cucul_rand(- w, 2 * w); ya = cucul_rand(- h, 2 * h);
xb = cucul_rand(- w, 2 * w); yb = cucul_rand(- h, 2 * h);
xc = cucul_rand(- w, 2 * w); yc = cucul_rand(- h, 2 * h);
}
else
{

xa = cucul_rand(0, w - 1); ya = cucul_rand(0, h - 1);
xb = cucul_rand(0, w - 1); yb = cucul_rand(0, h - 1);
xc = cucul_rand(0, w - 1); yc = cucul_rand(0, h - 1);
}

cucul_set_color(qq, cucul_rand(0, 15), cucul_rand(0, 15));
cucul_fill_triangle(qq, xa, ya, xb, yb, xc, yc, '#');

cucul_set_color(qq, cucul_rand(0, 15), CUCUL_COLOR_BLACK);
if(outline == 2)
cucul_draw_thin_triangle(qq, xa, ya, xb, yb, xc, yc);
else if(outline == 1)
cucul_draw_triangle(qq, xa, ya, xb, yb, xc, yc, '#');
}

static void demo_sprites(void)
{
cucul_draw_sprite(qq, cucul_rand(0, cucul_get_width(qq) - 1),
cucul_rand(0, cucul_get_height(qq) - 1), sprite, 0);
}

#if 0
static void demo_render(void)
{
struct cucul_bitmap *bitmap;
//short buffer[256*256];
//short *dest = buffer;
int buffer[256*256];
int *dest = buffer;
int x, y, z;
static int i = 0;

i = (i + 1) % 512;
z = i < 256 ? i : 511 - i;

for(x = 0; x < 256; x++)
for(y = 0; y < 256; y++)
{
//*dest++ = ((x >> 3) << 11) | ((y >> 2) << 5) | ((z >> 3));
*dest++ = (x << 16) | (y << 8) | (z);
}

//bitmap = cucul_create_bitmap(16, 256, 256, 2 * 256, 0xf800, 0x07e0, 0x001f, 0x0000);
bitmap = cucul_create_bitmap(32, 256, 256, 4 * 256, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
cucul_draw_bitmap(qq, 0, 0, cucul_get_width(qq) - 1, cucul_get_height(qq) - 1,
bitmap, buffer);
cucul_free_bitmap(qq, bitmap);
}
#endif

static void draw_circle(int *buffer, int xo, int yo, int r, int mask, int val);

static void demo_render(void)
{
struct cucul_bitmap *bitmap;
int buffer[256*256];
int *dest;
int x, y, z, xo, yo;
static int i = 0;

i++;

dest = buffer;
for(x = 0; x < 256; x++)
for(y = 0; y < 256; y++)
{
*dest++ = 0xff000000;
}

/* red */
xo = 128 + 48 * sin(0.02 * i);
yo = 128 + 48 * cos(0.03 * i);
for(z = 0; z < 240; z++)
draw_circle(buffer, xo, yo, z, 0x00ff0000, 200 << 16);

/* green */
xo = 128 + 48 * sin(2 + 0.06 * i);
yo = 128 + 48 * cos(2 + 0.05 * i);
for(z = 0; z < 240; z++)
draw_circle(buffer, xo, yo, z, 0x0000ff00, 200 << 8);

/* blue */
xo = 128 + 48 * sin(1 + 0.04 * i);
yo = 128 + 48 * cos(1 + 0.03 * i);
for(z = 0; z < 240; z++)
draw_circle(buffer, xo, yo, z, 0x000000ff, 200);

bitmap = cucul_create_bitmap(qq, 32, 256, 256, 4 * 256, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
cucul_draw_bitmap(qq, 0, 0, cucul_get_width(qq) - 1, cucul_get_height(qq) - 1, bitmap, (char *)buffer);
cucul_free_bitmap(qq, bitmap);
}

static void draw_circle(int *buffer, int x, int y, int r, int mask, int val)
{
int t, dx, dy;

#define POINT(X,Y) \
buffer[(X) + 256 * (Y)] = 0xff000000 | (buffer[(X) + 256 * (Y)] & ~mask) | val;

for(t = 0, dx = 0, dy = r; dx <= dy; dx++)
{
POINT(x - dx / 3, y - dy / 3);
POINT(x + dx / 3, y - dy / 3);
POINT(x - dx / 3, y + dy / 3);
POINT(x + dx / 3, y + dy / 3);

POINT(x - dy / 3, y - dx / 3);
POINT(x + dy / 3, y - dx / 3);
POINT(x - dy / 3, y + dx / 3);
POINT(x + dy / 3, y + dx / 3);

t += t > 0 ? dx - dy-- : dx;
}
}


+ 29
- 22
test/dithering.c View File

@@ -13,30 +13,34 @@

#include "config.h"

#include "cucul.h"
#include "caca.h"

#define XRATIO 100*100
#define YRATIO 70*70
#define FUZZY 5000000

enum caca_color points[] =
enum cucul_color points[] =
{
CACA_COLOR_BLACK,
CACA_COLOR_DARKGRAY,
CACA_COLOR_LIGHTGRAY,
CACA_COLOR_WHITE,
CACA_COLOR_RED,
CACA_COLOR_LIGHTRED
CUCUL_COLOR_BLACK,
CUCUL_COLOR_DARKGRAY,
CUCUL_COLOR_LIGHTGRAY,
CUCUL_COLOR_WHITE,
CUCUL_COLOR_RED,
CUCUL_COLOR_LIGHTRED
};

char density[] = " -,+:;o&%w$W@#";

int main(void)
{
cucul_t *qq;
caca_t *kk;
int neara, dista, nearb, distb, dist;
int x, y;

caca_init();
qq = cucul_init();
kk = caca_attach(qq);

for(x = 0; x < 100; x++)
for(y = 0; y < 100; y++)
@@ -49,7 +53,7 @@ int main(void)

/* distance to 40% */
dist = XRATIO * (x - 40) * (x - 40) + YRATIO * y * y;
if(caca_rand(-FUZZY, FUZZY) + dist < dista)
if(cucul_rand(-FUZZY, FUZZY) + dist < dista)
{
nearb = neara; distb = dista; neara = 1; dista = dist;
}
@@ -60,22 +64,22 @@ int main(void)

/* check dist to 70% */
dist = XRATIO * (x - 70) * (x - 70) + YRATIO * y * y;
if(caca_rand(-FUZZY, FUZZY) + dist < dista)
if(cucul_rand(-FUZZY, FUZZY) + dist < dista)
{
nearb = neara; distb = dista; neara = 2; dista = dist;
}
else if(caca_rand(-FUZZY, FUZZY) + dist < distb)
else if(cucul_rand(-FUZZY, FUZZY) + dist < distb)
{
nearb = 2; distb = dist;
}

/* check dist to white */
dist = XRATIO * (x - 100) * (x - 100) + YRATIO * y * y;
if(caca_rand(-FUZZY, FUZZY) + dist < dista)
if(cucul_rand(-FUZZY, FUZZY) + dist < dista)
{
nearb = neara; distb = dista; neara = 3; dista = dist;
}
else if(caca_rand(-FUZZY, FUZZY) + dist < distb)
else if(cucul_rand(-FUZZY, FUZZY) + dist < distb)
{
nearb = 3; distb = dist;
}
@@ -84,11 +88,11 @@ int main(void)
/* check dist to dark */
dist = XRATIO * (x - 40) * (x - 40) + YRATIO * (y - 100) * (y - 100);
dist = dist * 12 / 16;
if(caca_rand(-FUZZY, FUZZY) + dist < dista)
if(cucul_rand(-FUZZY, FUZZY) + dist < dista)
{
nearb = neara; distb = dista; neara = 4; dista = dist;
}
else if(caca_rand(-FUZZY, FUZZY) + dist < distb)
else if(cucul_rand(-FUZZY, FUZZY) + dist < distb)
{
nearb = 4; distb = dist;
}
@@ -96,11 +100,11 @@ int main(void)
/* check dist to light */
dist = XRATIO * (x - 100) * (x - 100) + YRATIO * (y - 100) * (y - 100);
dist = dist * 8 / 16;
if(caca_rand(-FUZZY, FUZZY) + dist < dista)
if(cucul_rand(-FUZZY, FUZZY) + dist < dista)
{
nearb = neara; distb = dista; neara = 5; dista = dist;
}
else if(caca_rand(-FUZZY, FUZZY) + dist < distb)
else if(cucul_rand(-FUZZY, FUZZY) + dist < distb)
{
nearb = 5; distb = dist;
}
@@ -111,16 +115,19 @@ int main(void)
ch = density[distb * 2 * 13 / (dista + distb)];
else
ch = density[dista * 2 * 13 / (dista + distb)];
caca_set_color(points[nearb], points[neara]);
cucul_set_color(qq, points[nearb], points[neara]);

caca_putchar(x * caca_get_width() / 100, (100 - y) * caca_get_height() / 100, ch);
cucul_putchar(qq, x * cucul_get_width(qq) / 100,
(100 - y) * cucul_get_height(qq) / 100, ch);
}

caca_refresh();
caca_refresh(kk);

while(!caca_get_event(CACA_EVENT_KEY_PRESS));
while(!caca_get_event(kk, CACA_EVENT_KEY_PRESS));

caca_detach(kk);
cucul_end(qq);

caca_end();
return 0;
}


+ 39
- 30
test/event.c View File

@@ -17,8 +17,12 @@
#include <string.h>
#include <stdlib.h>

#include "cucul.h"
#include "caca.h"

static cucul_t *qq;
static caca_t *kk;

static void print_event(int, int, unsigned int);

int main(int argc, char **argv)
@@ -26,18 +30,22 @@ int main(int argc, char **argv)
int *events;
int i, h, quit;

if(caca_init())
qq = cucul_init();
if(!qq)
return 1;
kk = caca_attach(qq);
if(!kk)
return 1;

h = caca_get_height() - 1;
h = cucul_get_height(qq) - 1;

caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
caca_draw_line(0, 0, caca_get_width() - 1, 0, ' ');
cucul_set_color(qq, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE);
cucul_draw_line(qq, 0, 0, cucul_get_width(qq) - 1, 0, ' ');

caca_draw_line(0, h, caca_get_width() - 1, h, ' ');
caca_putstr(0, h, "type \"quit\" to exit");
cucul_draw_line(qq, 0, h, cucul_get_width(qq) - 1, h, ' ');
cucul_putstr(qq, 0, h, "type \"quit\" to exit");

caca_refresh();
caca_refresh(kk);

events = malloc(h * sizeof(int));
memset(events, 0, h * sizeof(int));
@@ -45,7 +53,7 @@ int main(int argc, char **argv)
for(quit = 0; quit < 4; )
{
static char const * quit_string[] = { "", "q", "qu", "qui", "quit" };
unsigned int event = caca_wait_event(CACA_EVENT_ANY);
unsigned int event = caca_wait_event(kk, CACA_EVENT_ANY);

if(!event)
continue;
@@ -68,30 +76,31 @@ int main(int argc, char **argv)
memmove(events + 1, events, (h - 1) * sizeof(int));
events[0] = event;

event = caca_get_event(CACA_EVENT_ANY);
event = caca_get_event(kk, CACA_EVENT_ANY);
}
while(event);

caca_clear();
cucul_clear(qq);

/* Print current event */
caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
caca_draw_line(0, 0, caca_get_width() - 1, 0, ' ');
cucul_set_color(qq, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE);
cucul_draw_line(qq, 0, 0, cucul_get_width(qq) - 1, 0, ' ');
print_event(0, 0, events[0]);

caca_draw_line(0, h, caca_get_width() - 1, h, ' ');
caca_printf(0, h, "type \"quit\" to exit: %s", quit_string[quit]);
cucul_draw_line(qq, 0, h, cucul_get_width(qq) - 1, h, ' ');
cucul_printf(qq, 0, h, "type \"quit\" to exit: %s", quit_string[quit]);

/* Print previous events */
caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLACK);
cucul_set_color(qq, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLACK);
for(i = 1; i < h && events[i]; i++)
print_event(0, i, events[i]);

caca_refresh();
caca_refresh(kk);
}

/* Clean up */
caca_end();
caca_detach(kk);
cucul_end(qq);

return 0;
}
@@ -103,35 +112,35 @@ static void print_event(int x, int y, unsigned int event)
switch(event & 0xff000000)
{
case CACA_EVENT_NONE:
caca_printf(x, y, "CACA_EVENT_NONE");
cucul_printf(qq, x, y, "CACA_EVENT_NONE");
break;
case CACA_EVENT_KEY_PRESS:
character = event & 0x00ffffff;
caca_printf(x, y, "CACA_EVENT_KEY_PRESS 0x%02x (%c)", character,
(character > 0x20 && character < 0x80) ? character : '?');
cucul_printf(qq, x, y, "CACA_EVENT_KEY_PRESS 0x%02x (%c)", character,
(character > 0x20 && character < 0x80) ? character : '?');
break;
case CACA_EVENT_KEY_RELEASE:
character = event & 0x00ffffff;
caca_printf(x, y, "CACA_EVENT_KEY_RELEASE 0x%02x (%c)", character,
(character > 0x20 && character < 0x80) ? character : '?');
cucul_printf(qq, x, y, "CACA_EVENT_KEY_RELEASE 0x%02x (%c)", character,
(character > 0x20 && character < 0x80) ? character : '?');
break;
case CACA_EVENT_MOUSE_MOTION:
caca_printf(x, y, "CACA_EVENT_MOUSE_MOTION %u %u",
(event & 0x00fff000) >> 12, event & 0x00000fff);
cucul_printf(qq, x, y, "CACA_EVENT_MOUSE_MOTION %u %u",
(event & 0x00fff000) >> 12, event & 0x00000fff);
break;
case CACA_EVENT_MOUSE_PRESS:
caca_printf(x, y, "CACA_EVENT_MOUSE_PRESS %u",
event & 0x00ffffff);
cucul_printf(qq, x, y, "CACA_EVENT_MOUSE_PRESS %u",
event & 0x00ffffff);
break;
case CACA_EVENT_MOUSE_RELEASE:
caca_printf(x, y, "CACA_EVENT_MOUSE_RELEASE %u",
event & 0x00ffffff);
cucul_printf(qq, x, y, "CACA_EVENT_MOUSE_RELEASE %u",
event & 0x00ffffff);
break;
case CACA_EVENT_RESIZE:
caca_printf(x, y, "CACA_EVENT_RESIZE");
cucul_printf(qq, x, y, "CACA_EVENT_RESIZE");
break;
default:
caca_printf(x, y, "CACA_EVENT_UNKNOWN");
cucul_printf(qq, x, y, "CACA_EVENT_UNKNOWN");
}
}


+ 17
- 10
test/hsv.c View File

@@ -21,16 +21,21 @@ typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#endif

#include "cucul.h"
#include "caca.h"

uint32_t buffer[256*256];

int main(void)
{
struct caca_bitmap *bitmap;
cucul_t *qq;
caca_t *kk;

struct cucul_bitmap *bitmap;
int x, y;

caca_init();
qq = cucul_init();
kk = caca_attach(qq);

for(y = 0; y < 256; y++)
for(x = 0; x < 256; x++)
@@ -38,17 +43,19 @@ int main(void)
buffer[y * 256 + x] = ((y * x / 256) << 16) | ((y * x / 256) << 8) | (x<< 0);
}

bitmap = caca_create_bitmap(32, 256, 256, 4 * 256,
0x00ff0000, 0x0000ff00, 0x000000ff, 0x0);
caca_draw_bitmap(0, 0, caca_get_width() - 1, caca_get_height() - 1,
bitmap, buffer);
caca_free_bitmap(bitmap);
bitmap = cucul_create_bitmap(qq, 32, 256, 256, 4 * 256,
0x00ff0000, 0x0000ff00, 0x000000ff, 0x0);
cucul_draw_bitmap(qq, 0, 0,
cucul_get_width(qq) - 1, cucul_get_height(qq) - 1,
bitmap, buffer);
cucul_free_bitmap(qq, bitmap);

caca_refresh();
caca_refresh(kk);

while(!caca_get_event(CACA_EVENT_KEY_PRESS));
while(!caca_get_event(kk, CACA_EVENT_KEY_PRESS));

caca_end();
caca_detach(kk);
cucul_end(qq);

return 0;
}


+ 45
- 45
test/optipal.c View File

@@ -1,5 +1,5 @@
/*
* optipal S-Lang optimised palette generator for libcaca
* optipal S-Lang optimised palette generator for libcucul
* Copyright (c) 2003 Sam Hocevar <sam@zoy.org>
* All Rights Reserved
*
@@ -15,7 +15,7 @@

#include <stdio.h>

#include "caca.h"
#include "cucul.h"

static void base_colors(void);
static void emulated_colors(void);
@@ -24,14 +24,14 @@ static void unused_colors(void);
static int slang_assoc[16*16], palette[16*16];

/* 6 colours in hue order */
static enum caca_color const hue_list[] =
static enum cucul_color const hue_list[] =
{
CACA_COLOR_RED,
CACA_COLOR_BROWN,
CACA_COLOR_GREEN,
CACA_COLOR_CYAN,
CACA_COLOR_BLUE,
CACA_COLOR_MAGENTA
CUCUL_COLOR_RED,
CUCUL_COLOR_BROWN,
CUCUL_COLOR_GREEN,
CUCUL_COLOR_CYAN,
CUCUL_COLOR_BLUE,
CUCUL_COLOR_MAGENTA
};

#define SETPAIR(_fg, _bg, _n) \
@@ -97,14 +97,14 @@ static void base_colors(void)

/* black background colour pairs that are needed for the old renderer */
for(i = 1; i < 16; i++)
SETPAIR(i, CACA_COLOR_BLACK, cur++);
SETPAIR(i, CUCUL_COLOR_BLACK, cur++);

/* gray combinations used for grayscale dithering */
SETPAIR(CACA_COLOR_BLACK, CACA_COLOR_DARKGRAY, cur++);
SETPAIR(CACA_COLOR_DARKGRAY, CACA_COLOR_LIGHTGRAY, cur++);
SETPAIR(CACA_COLOR_LIGHTGRAY, CACA_COLOR_DARKGRAY, cur++);
SETPAIR(CACA_COLOR_WHITE, CACA_COLOR_LIGHTGRAY, cur++);
SETPAIR(CACA_COLOR_LIGHTGRAY, CACA_COLOR_WHITE, cur++);
SETPAIR(CUCUL_COLOR_BLACK, CUCUL_COLOR_DARKGRAY, cur++);
SETPAIR(CUCUL_COLOR_DARKGRAY, CUCUL_COLOR_LIGHTGRAY, cur++);
SETPAIR(CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_DARKGRAY, cur++);
SETPAIR(CUCUL_COLOR_WHITE, CUCUL_COLOR_LIGHTGRAY, cur++);
SETPAIR(CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_WHITE, cur++);

/* white/light, light/dark, lightgray/light, darkgray/dark, dark/black
* combinations often used for saturation/value dithering (the two
@@ -112,15 +112,15 @@ static void base_colors(void)
* not considered here) */
for(i = 1; i < 7; i++)
{
SETPAIR(CACA_COLOR_WHITE, i + 8, cur++);
SETPAIR(i + 8, CACA_COLOR_WHITE, cur++);
SETPAIR(CUCUL_COLOR_WHITE, i + 8, cur++);
SETPAIR(i + 8, CUCUL_COLOR_WHITE, cur++);
SETPAIR(i, i + 8, cur++);
SETPAIR(i + 8, i, cur++);
SETPAIR(CACA_COLOR_LIGHTGRAY, i + 8, cur++);
SETPAIR(i + 8, CACA_COLOR_LIGHTGRAY, cur++);
SETPAIR(CACA_COLOR_DARKGRAY, i, cur++);
SETPAIR(i, CACA_COLOR_DARKGRAY, cur++);
SETPAIR(CACA_COLOR_BLACK, i, cur++);
SETPAIR(CUCUL_COLOR_LIGHTGRAY, i + 8, cur++);
SETPAIR(i + 8, CUCUL_COLOR_LIGHTGRAY, cur++);
SETPAIR(CUCUL_COLOR_DARKGRAY, i, cur++);
SETPAIR(i, CUCUL_COLOR_DARKGRAY, cur++);
SETPAIR(CUCUL_COLOR_BLACK, i, cur++);
}

/* next colour combinations for hue dithering (magenta/blue, blue/green
@@ -145,12 +145,12 @@ static void base_colors(void)

/* black on light gray, black on white, white on dark gray, dark gray
* on white, white on blue, light gray on blue (chosen arbitrarily) */
SETPAIR(CACA_COLOR_BLACK, CACA_COLOR_LIGHTGRAY, cur++);
SETPAIR(CACA_COLOR_BLACK, CACA_COLOR_WHITE, cur++);
SETPAIR(CACA_COLOR_WHITE, CACA_COLOR_DARKGRAY, cur++);
SETPAIR(CACA_COLOR_DARKGRAY, CACA_COLOR_WHITE, cur++);
SETPAIR(CACA_COLOR_WHITE, CACA_COLOR_BLUE, cur++);
SETPAIR(CACA_COLOR_LIGHTGRAY, CACA_COLOR_BLUE, cur++);
SETPAIR(CUCUL_COLOR_BLACK, CUCUL_COLOR_LIGHTGRAY, cur++);
SETPAIR(CUCUL_COLOR_BLACK, CUCUL_COLOR_WHITE, cur++);
SETPAIR(CUCUL_COLOR_WHITE, CUCUL_COLOR_DARKGRAY, cur++);
SETPAIR(CUCUL_COLOR_DARKGRAY, CUCUL_COLOR_WHITE, cur++);
SETPAIR(CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE, cur++);
SETPAIR(CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLUE, cur++);
}

static void emulated_colors(void)
@@ -166,23 +166,23 @@ static void emulated_colors(void)
* dark colour on white: emulate with light colour on white */
for(i = 1; i < 7; i++)
{
if(i != CACA_COLOR_BLUE)
if(i != CUCUL_COLOR_BLUE)
{
SETPAIR(CACA_COLOR_LIGHTGRAY, i, 128 +
SETPAIR(CUCUL_COLOR_LIGHTGRAY, i, 128 +
slang_assoc[i + 8 + 16 * i]);
SETPAIR(CACA_COLOR_WHITE, i, 128 +
slang_assoc[CACA_COLOR_LIGHTGRAY + 16 * (i + 8)]);
SETPAIR(CUCUL_COLOR_WHITE, i, 128 +
slang_assoc[CUCUL_COLOR_LIGHTGRAY + 16 * (i + 8)]);
}
SETPAIR(CACA_COLOR_BLACK, i + 8,
128 + slang_assoc[CACA_COLOR_DARKGRAY + 16 * i]);
SETPAIR(CACA_COLOR_DARKGRAY, i + 8,
SETPAIR(CUCUL_COLOR_BLACK, i + 8,
128 + slang_assoc[CUCUL_COLOR_DARKGRAY + 16 * i]);
SETPAIR(CUCUL_COLOR_DARKGRAY, i + 8,
128 + slang_assoc[i + 16 * (i + 8)]);
SETPAIR(i + 8, CACA_COLOR_DARKGRAY,
128 + slang_assoc[i + 16 * CACA_COLOR_DARKGRAY]);
SETPAIR(i, CACA_COLOR_LIGHTGRAY,
128 + slang_assoc[i + 8 + 16 * CACA_COLOR_LIGHTGRAY]);
SETPAIR(i, CACA_COLOR_WHITE,
128 + slang_assoc[i + 8 + 16 * CACA_COLOR_WHITE]);
SETPAIR(i + 8, CUCUL_COLOR_DARKGRAY,
128 + slang_assoc[i + 16 * CUCUL_COLOR_DARKGRAY]);
SETPAIR(i, CUCUL_COLOR_LIGHTGRAY,
128 + slang_assoc[i + 8 + 16 * CUCUL_COLOR_LIGHTGRAY]);
SETPAIR(i, CUCUL_COLOR_WHITE,
128 + slang_assoc[i + 8 + 16 * CUCUL_COLOR_WHITE]);
}

/* 120 degree hue pairs can be emulated as well; for instance blue on
@@ -216,13 +216,13 @@ static void emulated_colors(void)
for(i = 0; i < 6; i++)
{
SETPAIR(hue_list[i], hue_list[(i + 3) % 6],
128 + slang_assoc[hue_list[i] + 16 * CACA_COLOR_BLACK]);
128 + slang_assoc[hue_list[i] + 16 * CUCUL_COLOR_BLACK]);
SETPAIR(hue_list[i] + 8, hue_list[(i + 3) % 6],
128 + slang_assoc[hue_list[i] + 8 + 16 * CACA_COLOR_BLACK]);
128 + slang_assoc[hue_list[i] + 8 + 16 * CUCUL_COLOR_BLACK]);
SETPAIR(hue_list[(i + 3) % 6], hue_list[i] + 8,
128 + slang_assoc[CACA_COLOR_BLACK + 16 * hue_list[i]]);
128 + slang_assoc[CUCUL_COLOR_BLACK + 16 * hue_list[i]]);
SETPAIR(hue_list[(i + 3) % 6] + 8, hue_list[i] + 8,
128 + slang_assoc[CACA_COLOR_WHITE + 16 * (hue_list[i] + 8)]);
128 + slang_assoc[CUCUL_COLOR_WHITE + 16 * (hue_list[i] + 8)]);
}
}



+ 38
- 28
test/spritedit.c View File

@@ -15,12 +15,16 @@

#include <stdio.h>

#include "cucul.h"
#include "caca.h"

int main(int argc, char **argv)
{
cucul_t *qq;
caca_t *kk;

int quit = 0;
struct caca_sprite *sprite;
struct cucul_sprite *sprite;
int frame = 0;

if(argc < 2)
@@ -29,14 +33,19 @@ int main(int argc, char **argv)
return 1;
}

if(caca_init())
qq = cucul_init();
if(!qq)
return 1;
kk = caca_attach(qq);
if(!kk)
return 1;

sprite = caca_load_sprite(argv[1]);
sprite = cucul_load_sprite(qq, argv[1]);

if(!sprite)
{
caca_end();
caca_detach(kk);
cucul_end(qq);
fprintf(stderr, "%s: could not open `%s'.\n", argv[0], argv[1]);
return 1;
}
@@ -48,7 +57,7 @@ int main(int argc, char **argv)
char buf[BUFSIZ];
int event;

while((event = caca_get_event(CACA_EVENT_KEY_PRESS)))
while((event = caca_get_event(kk, CACA_EVENT_KEY_PRESS)))
{
switch(event & 0x00ffffff)
{
@@ -62,48 +71,49 @@ int main(int argc, char **argv)
frame--;
break;
case '+':
if(frame < caca_get_sprite_frames(sprite) - 1)
if(frame < cucul_get_sprite_frames(qq, sprite) - 1)
frame++;
break;
}
}

caca_clear();
cucul_clear(qq);

caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_BLACK);
caca_draw_thin_box(0, 0, caca_get_width() - 1, caca_get_height() - 1);
cucul_set_color(qq, CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLACK);
cucul_draw_thin_box(qq, 0, 0, cucul_get_width(qq) - 1, cucul_get_height(qq) - 1);

caca_putstr(3, 0, "[ Sprite editor for libcaca ]");
cucul_putstr(qq, 3, 0, "[ Sprite editor for libcaca ]");

sprintf(buf, "sprite `%s'", argv[1]);
caca_putstr(3, 2, buf);
sprintf(buf, "frame %i/%i", frame, caca_get_sprite_frames(sprite) - 1);
caca_putstr(3, 3, buf);
cucul_putstr(qq, 3, 2, buf);
sprintf(buf, "frame %i/%i", frame, cucul_get_sprite_frames(qq, sprite) - 1);
cucul_putstr(qq, 3, 3, buf);

/* Crosshair */
caca_draw_thin_line(57, 2, 57, 18);
caca_draw_thin_line(37, 10, 77, 10);
caca_putchar(57, 10, '+');
cucul_draw_thin_line(qq, 57, 2, 57, 18);
cucul_draw_thin_line(qq, 37, 10, 77, 10);
cucul_putchar(qq, 57, 10, '+');

/* Boxed sprite */
xa = -1 - caca_get_sprite_dx(sprite, frame);
ya = -1 - caca_get_sprite_dy(sprite, frame);
xb = xa + 1 + caca_get_sprite_width(sprite, frame);
yb = ya + 1 + caca_get_sprite_height(sprite, frame);
caca_set_color(CACA_COLOR_BLACK, CACA_COLOR_BLACK);
caca_fill_box(57 + xa, 10 + ya, 57 + xb, 10 + yb, ' ');
caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_BLACK);
caca_draw_thin_box(57 + xa, 10 + ya, 57 + xb, 10 + yb);
caca_draw_sprite(57, 10, sprite, frame);
xa = -1 - cucul_get_sprite_dx(qq, sprite, frame);
ya = -1 - cucul_get_sprite_dy(qq, sprite, frame);
xb = xa + 1 + cucul_get_sprite_width(qq, sprite, frame);
yb = ya + 1 + cucul_get_sprite_height(qq, sprite, frame);
cucul_set_color(qq, CUCUL_COLOR_BLACK, CUCUL_COLOR_BLACK);
cucul_fill_box(qq, 57 + xa, 10 + ya, 57 + xb, 10 + yb, ' ');
cucul_set_color(qq, CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLACK);
cucul_draw_thin_box(qq, 57 + xa, 10 + ya, 57 + xb, 10 + yb);
cucul_draw_sprite(qq, 57, 10, sprite, frame);

/* Free sprite */
caca_draw_sprite(20, 10, sprite, frame);
cucul_draw_sprite(qq, 20, 10, sprite, frame);

caca_refresh();
caca_refresh(kk);
}

/* Clean up */
caca_end();
caca_detach(kk);
cucul_end(qq);

return 0;
}


Loading…
Cancel
Save