Переглянути джерело

* src/caca.c src/graphics.c:

+ Moved graphics stuff from caca.c to graphics.c.
    + Added a few kludges: if gnome-terminal or konsole are detected, switch
      to TERM=xterm-16color to benefit from extended colour palette.
tags/v0.99.beta14
Sam Hocevar sam 21 роки тому
джерело
коміт
59b56c31a6
4 змінених файлів з 213 додано та 164 видалено
  1. +1
    -1
      configure.ac
  2. +34
    -163
      src/caca.c
  3. +2
    -0
      src/caca_internals.h
  4. +176
    -0
      src/graphics.c

+ 1
- 1
configure.ac Переглянути файл

@@ -25,7 +25,7 @@ AC_ARG_ENABLE(conio,
[ --enable-conio DOS conio.h graphics support (default disabled)])

AC_CHECK_HEADERS(inttypes.h)
AC_CHECK_FUNCS(vsnprintf)
AC_CHECK_FUNCS(vsnprintf getenv putenv)

USE_SLANG=false
USE_NCURSES=false


+ 34
- 163
src/caca.c Переглянути файл

@@ -46,16 +46,13 @@
#endif

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>

#include "caca.h"
#include "caca_internals.h"

static unsigned int _caca_delay;
static unsigned int _caca_rendertime;
static void caca_init_terminal(void);
char *_caca_empty_line;
char *_caca_scratch_line;

@@ -71,30 +68,9 @@ char *_caca_screen;

int caca_init(void)
{
#if defined(USE_SLANG)
/* See SLang ref., 5.4.4. */
static char *slang_colors[16] =
{
"black",
"blue",
"green",
"cyan",
"red",
"magenta",
"brown",
"lightgray",
"gray",
"brightblue",
"brightgreen",
"brightcyan",
"brightred",
"brightmagenta",
"yellow",
"white",
};

int fg, bg;
caca_init_terminal();

#if defined(USE_SLANG)
/* Initialize slang library */
SLsig_block_signals();
SLtt_get_terminfo();
@@ -121,36 +97,7 @@ int caca_init(void)
SLtt_set_mouse_mode(1, 0);
SLsmg_refresh();

for(bg = 0; bg < 16; bg++)
for(fg = 0; fg < 16; fg++)
{
int i = fg + 16 * bg;
SLtt_set_color(i, NULL, slang_colors[fg], slang_colors[bg]);
}

#elif defined(USE_NCURSES)
static int curses_colors[] =
{
COLOR_BLACK,
COLOR_BLUE,
COLOR_GREEN,
COLOR_CYAN,
COLOR_RED,
COLOR_MAGENTA,
COLOR_YELLOW,
COLOR_WHITE,
/* Extra values for xterm-16color */
COLOR_BLACK + 8,
COLOR_BLUE + 8,
COLOR_GREEN + 8,
COLOR_CYAN + 8,
COLOR_RED + 8,
COLOR_MAGENTA + 8,
COLOR_YELLOW + 8,
COLOR_WHITE + 8
};

int fg, bg, max;
mmask_t newmask;

initscr();
@@ -165,55 +112,14 @@ int caca_init(void)
newmask = ALL_MOUSE_EVENTS;
mousemask(newmask, &oldmask);

/* Activate colour */
start_color();

max = COLORS >= 16 ? 16 : 8;

for(bg = 0; bg < max; bg++)
for(fg = 0; fg < max; fg++)
{
/* Use ((max + 7 - fg) % max) instead of fg so that colour 0
* is light gray on black, since some terminals don't like
* this colour pair to be redefined. */
int col = ((max + 7 - fg) % max) + max * bg;
init_pair(col, curses_colors[fg], curses_colors[bg]);
_caca_attr[fg + 16 * bg] = COLOR_PAIR(col);

if(max == 8)
{
/* Bright fg on simple bg */
_caca_attr[fg + 8 + 16 * bg] = A_BOLD | COLOR_PAIR(col);
/* Simple fg on bright bg */
_caca_attr[fg + 16 * (bg + 8)] = A_BLINK | COLOR_PAIR(col);
/* Bright fg on bright bg */
_caca_attr[fg + 8 + 16 * (bg + 8)] = A_BLINK | A_BOLD | COLOR_PAIR(col);
}
}

#elif defined(USE_CONIO)
gettextinfo(&ti);
_caca_screen = malloc(2 * ti.screenwidth * ti.screenheight);
if(_caca_screen == NULL)
return -1;
_wscroll = 0;
_setcursortype(_NOCURSOR);
clrscr();
# if defined(SCREENUPDATE_IN_PC_H)
ScreenRetrieve(_caca_screen);
# else
/* FIXME */
# endif

#endif
_caca_empty_line = malloc(caca_get_width() + 1);
memset(_caca_empty_line, ' ', caca_get_width());
_caca_empty_line[caca_get_width()] = '\0';

_caca_scratch_line = malloc(caca_get_width() + 1);

_caca_delay = 0;
_caca_rendertime = 0;
if(_caca_init_graphics())
return -1;

return 0;
}
@@ -240,16 +146,6 @@ unsigned int caca_get_height(void)
#endif
}

void caca_set_delay(unsigned int usec)
{
_caca_delay = usec;
}

unsigned int caca_get_rendertime(void)
{
return _caca_rendertime;
}

const char *caca_get_color_name(unsigned int color)
{
static const char *color_names[16] =
@@ -278,59 +174,6 @@ const char *caca_get_color_name(unsigned int color)
return color_names[color];
}

static unsigned int _caca_getticks(void)
{
static unsigned int last_sec = 0, last_usec = 0;

struct timeval tv;
unsigned int ticks = 0;

gettimeofday(&tv, NULL);

if(last_sec != 0)
{
ticks = (tv.tv_sec - last_sec) * 1000000 + (tv.tv_usec - last_usec);
}

last_sec = tv.tv_sec;
last_usec = tv.tv_usec;

return ticks;
}

void caca_refresh(void)
{
#define IDLE_USEC 10000
static int lastticks = 0;
int ticks = lastticks + _caca_getticks();

#if defined(USE_SLANG)
SLsmg_refresh();
#elif defined(USE_NCURSES)
refresh();
#elif defined(USE_CONIO)
# if defined(SCREENUPDATE_IN_PC_H)
ScreenUpdate(_caca_screen);
# else
/* FIXME */
# endif
#endif

/* Wait until _caca_delay + time of last call */
ticks += _caca_getticks();
for(; ticks + IDLE_USEC < (int)_caca_delay; ticks += _caca_getticks())
usleep(IDLE_USEC);

/* Update the sliding mean of the render time */
_caca_rendertime = (7 * _caca_rendertime + ticks) / 8;

lastticks = ticks - _caca_delay;

/* If we drifted too much, it's bad, bad, bad. */
if(lastticks > (int)_caca_delay)
lastticks = 0;
}

void caca_end(void)
{
#if defined(USE_SLANG)
@@ -352,3 +195,31 @@ void caca_end(void)
#endif
}

static void caca_init_terminal(void)
{
#if defined(HAVE_GETENV) && defined(HAVE_PUTENV)
char *term, *colorterm, *misc;

term = getenv("TERM");
colorterm = getenv("COLORTERM");

if(term && !strcmp(term, "xterm"))
{
/* If we are using gnome-terminal, it's really a 16 colour terminal */
if(colorterm && !strcmp(colorterm, "gnome-terminal"))
{
(void)putenv("TERM=xterm-16color");
return;
}

/* Ditto if we are using Konsole */
misc = getenv("KONSOLE_DCOP_SESSION");
if(misc)
{
(void)putenv("TERM=xterm-16color");
return;
}
}
#endif
}


+ 2
- 0
src/caca_internals.h Переглянути файл

@@ -30,6 +30,8 @@
#ifndef __CACA_INTERNALS_H__
#define __CACA_INTERNALS_H__

extern int _caca_init_graphics(void);

#if defined(USE_NCURSES)
extern int _caca_attr[];
#endif


+ 176
- 0
src/graphics.c Переглянути файл

@@ -42,11 +42,17 @@
#include <stdio.h> /* BUFSIZ */
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <sys/time.h>
#include <time.h>

#include "caca.h"
#include "caca_internals.h"

static unsigned int _caca_delay;
static unsigned int _caca_rendertime;

static enum caca_color _caca_fgcolor = CACA_COLOR_LIGHTGRAY;
static enum caca_color _caca_bgcolor = CACA_COLOR_BLACK;

@@ -186,3 +192,173 @@ void caca_clear(void)
caca_set_color(oldfg, oldbg);
}

int _caca_init_graphics(void)
{
#if defined(USE_SLANG)
/* See SLang ref., 5.4.4. */
static char *slang_colors[16] =
{
"black",
"blue",
"green",
"cyan",
"red",
"magenta",
"brown",
"lightgray",
"gray",
"brightblue",
"brightgreen",
"brightcyan",
"brightred",
"brightmagenta",
"yellow",
"white",
};

int fg, bg;

for(bg = 0; bg < 16; bg++)
for(fg = 0; fg < 16; fg++)
{
int i = fg + 16 * bg;
SLtt_set_color(i, NULL, slang_colors[fg], slang_colors[bg]);
}

#elif defined(USE_NCURSES)
static int curses_colors[] =
{
COLOR_BLACK,
COLOR_BLUE,
COLOR_GREEN,
COLOR_CYAN,
COLOR_RED,
COLOR_MAGENTA,
COLOR_YELLOW,
COLOR_WHITE,
/* Extra values for xterm-16color */
COLOR_BLACK + 8,
COLOR_BLUE + 8,
COLOR_GREEN + 8,
COLOR_CYAN + 8,
COLOR_RED + 8,
COLOR_MAGENTA + 8,
COLOR_YELLOW + 8,
COLOR_WHITE + 8
};

int fg, bg, max;

/* Activate colour */
start_color();

max = COLORS >= 16 ? 16 : 8;

for(bg = 0; bg < max; bg++)
for(fg = 0; fg < max; fg++)
{
/* Use ((max + 7 - fg) % max) instead of fg so that colour 0
* is light gray on black, since some terminals don't like
* this colour pair to be redefined. */
int col = ((max + 7 - fg) % max) + max * bg;
init_pair(col, curses_colors[fg], curses_colors[bg]);
_caca_attr[fg + 16 * bg] = COLOR_PAIR(col);

if(max == 8)
{
/* Bright fg on simple bg */
_caca_attr[fg + 8 + 16 * bg] = A_BOLD | COLOR_PAIR(col);
/* Simple fg on bright bg */
_caca_attr[fg + 16 * (bg + 8)] = A_BLINK | COLOR_PAIR(col);
/* Bright fg on bright bg */
_caca_attr[fg + 8 + 16 * (bg + 8)] = A_BLINK | A_BOLD | COLOR_PAIR(col);
}
}

#elif defined(USE_CONIO)
gettextinfo(&ti);
_caca_screen = malloc(2 * ti.screenwidth * ti.screenheight);
if(_caca_screen == NULL)
return -1;
# if defined(SCREENUPDATE_IN_PC_H)
ScreenRetrieve(_caca_screen);
# else
/* FIXME */
# endif

#endif
_caca_empty_line = malloc(caca_get_width() + 1);
memset(_caca_empty_line, ' ', caca_get_width());
_caca_empty_line[caca_get_width()] = '\0';

_caca_scratch_line = malloc(caca_get_width() + 1);

_caca_delay = 0;
_caca_rendertime = 0;

return 0;
}

void caca_set_delay(unsigned int usec)
{
_caca_delay = usec;
}

unsigned int caca_get_rendertime(void)
{
return _caca_rendertime;
}

static unsigned int _caca_getticks(void)
{
static unsigned int last_sec = 0, last_usec = 0;

struct timeval tv;
unsigned int ticks = 0;

gettimeofday(&tv, NULL);

if(last_sec != 0)
{
ticks = (tv.tv_sec - last_sec) * 1000000 + (tv.tv_usec - last_usec);
}

last_sec = tv.tv_sec;
last_usec = tv.tv_usec;

return ticks;
}

void caca_refresh(void)
{
#define IDLE_USEC 10000
static int lastticks = 0;
int ticks = lastticks + _caca_getticks();

#if defined(USE_SLANG)
SLsmg_refresh();
#elif defined(USE_NCURSES)
refresh();
#elif defined(USE_CONIO)
# if defined(SCREENUPDATE_IN_PC_H)
ScreenUpdate(_caca_screen);
# else
/* FIXME */
# endif
#endif

/* Wait until _caca_delay + time of last call */
ticks += _caca_getticks();
for(; ticks + IDLE_USEC < (int)_caca_delay; ticks += _caca_getticks())
usleep(IDLE_USEC);

/* Update the sliding mean of the render time */
_caca_rendertime = (7 * _caca_rendertime + ticks) / 8;

lastticks = ticks - _caca_delay;

/* If we drifted too much, it's bad, bad, bad. */
if(lastticks > (int)_caca_delay)
lastticks = 0;
}


Завантаження…
Відмінити
Зберегти