Changeset 281 for libcaca/trunk/src


Ignore:
Timestamp:
Dec 25, 2003, 10:28:55 PM (16 years ago)
Author:
Sam Hocevar
Message:
  • NOTES BUGS: + Updated information about the S-Lang colour pair shortage bug.
  • src/graphics.c: + Implemented the solution explained in NOTES.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcaca/trunk/src/graphics.c

    r274 r281  
    7272#if defined(USE_NCURSES)
    7373static int ncurses_attr[16*16];
     74#endif
     75
     76#if defined(USE_SLANG)
     77static int slang_assoc[16*16];
    7478#endif
    7579
     
    98102static unsigned int _caca_rendertime;
    99103
     104#if defined(OPTIMISE_SLANG_PALETTE)
     105static int _caca_fgisbg = 0;
     106#endif
    100107static enum caca_color _caca_fgcolor = CACA_COLOR_LIGHTGRAY;
    101108static enum caca_color _caca_bgcolor = CACA_COLOR_BLACK;
     109
     110/*
     111 * Local functions
     112 */
     113#if defined(USE_SLANG)
     114static void slang_init_palette(void);
     115#endif
     116
     117static unsigned int _caca_getticks(void);
    102118
    103119/** \brief Set the default colour pair.
     
    117133    _caca_fgcolor = fgcolor;
    118134    _caca_bgcolor = bgcolor;
     135
    119136    switch(_caca_driver)
    120137    {
    121138#if defined(USE_SLANG)
    122139    case CACA_DRIVER_SLANG:
    123         SLsmg_set_color((bgcolor + 16 * fgcolor) /*% 128*/);
     140
     141#if defined(OPTIMISE_SLANG_PALETTE)
     142        /* If foreground == background, discard this colour pair. Functions
     143         * such as caca_putchar will print spaces instead of characters */
     144        if(fgcolor != bgcolor)
     145            _caca_fgisbg = 0;
     146        else
     147        {
     148            _caca_fgisbg = 1;
     149            switch(fgcolor)
     150            {
     151            case CACA_COLOR_BLACK:
     152                fgcolor = CACA_COLOR_WHITE;
     153                break;
     154            case CACA_COLOR_WHITE:
     155                fgcolor = CACA_COLOR_BLACK;
     156                break;
     157            default:
     158                if(fgcolor <= CACA_COLOR_LIGHTGRAY)
     159                    fgcolor = CACA_COLOR_BLACK;
     160                else
     161                    fgcolor = CACA_COLOR_WHITE;
     162            }
     163        }
     164#endif
     165
     166#if defined(OPTIMISE_SLANG_PALETTE)
     167        SLsmg_set_color(slang_assoc[fgcolor + 16 * bgcolor]);
     168#else
     169        SLsmg_set_color(fgcolor + 16 * bgcolor);
     170#endif
    124171        break;
    125172#endif
     
    193240    case CACA_DRIVER_SLANG:
    194241        SLsmg_gotorc(y, x);
    195         SLsmg_write_char(c);
     242#if defined(OPTIMISE_SLANG_PALETTE)
     243        if(_caca_fgisbg)
     244            SLsmg_write_char(' ');
     245        else
     246#endif
     247            SLsmg_write_char(c);
    196248        break;
    197249#endif
     
    259311    if(x + len >= _caca_width)
    260312    {
    261         memcpy(_caca_scratch_line, s, _caca_width - x);
    262         _caca_scratch_line[_caca_width - x] = '\0';
     313        len = _caca_width - x;
     314        memcpy(_caca_scratch_line, s, len);
     315        _caca_scratch_line[len] = '\0';
    263316        s = _caca_scratch_line;
    264317    }
     
    269322    case CACA_DRIVER_SLANG:
    270323        SLsmg_gotorc(y, x);
    271         SLsmg_write_string((char *)(intptr_t)s);
     324#if defined(OPTIMISE_SLANG_PALETTE)
     325        if(_caca_fgisbg)
     326            SLsmg_write_string(_caca_empty_line + _caca_width - len);
     327        else
     328#endif
     329            SLsmg_write_string((char *)(intptr_t)s);
    272330        break;
    273331#endif
     
    367425    if(_caca_driver == CACA_DRIVER_SLANG)
    368426    {
    369         /* See SLang ref., 5.4.4. */
    370         static char *slang_colors[16] =
    371         {
    372             /* Standard colours */
    373             "black",
    374             "blue",
    375             "green",
    376             "cyan",
    377             "red",
    378             "magenta",
    379             "brown",
    380             "lightgray",
    381             /* Bright colours */
    382             "gray",
    383             "brightblue",
    384             "brightgreen",
    385             "brightcyan",
    386             "brightred",
    387             "brightmagenta",
    388             "yellow",
    389             "white",
    390         };
    391 
    392         int fg, bg;
    393 
    394         for(fg = 0; fg < 16; fg++)
    395             for(bg = 0; bg < 16; bg++)
    396             {
    397                 int i = bg + 16 * fg;
    398                 SLtt_set_color(i, NULL, slang_colors[fg], slang_colors[bg]);
    399             }
     427        slang_init_palette();
    400428
    401429        /* Disable alt charset support so that we get all 256 colour pairs */
     
    802830}
    803831
     832#if defined(USE_SLANG)
     833
     834#if defined(OPTIMISE_SLANG_PALETTE)
     835#endif
     836
     837static void slang_init_palette(void)
     838{
     839    /* See SLang ref., 5.4.4. */
     840    static char *slang_colors[16] =
     841    {
     842        /* Standard colours */
     843        "black",
     844        "blue",
     845        "green",
     846        "cyan",
     847        "red",
     848        "magenta",
     849        "brown",
     850        "lightgray",
     851        /* Bright colours */
     852        "gray",
     853        "brightblue",
     854        "brightgreen",
     855        "brightcyan",
     856        "brightred",
     857        "brightmagenta",
     858        "yellow",
     859        "white",
     860    };
     861
     862#if !defined(OPTIMISE_SLANG_PALETTE)
     863    int fg, bg;
     864
     865    for(bg = 0; bg < 16; bg++)
     866        for(fg = 0; fg < 16; fg++)
     867        {
     868            int i = fg + 16 * bg;
     869            SLtt_set_color(i, NULL, slang_colors[fg], slang_colors[bg]);
     870        }
     871#else
     872    int i, cur = 0;
     873
     874    /* 6 colours in hue order */
     875    static const enum caca_color hue_list[] =
     876    {
     877        CACA_COLOR_RED,
     878        CACA_COLOR_BROWN,
     879        CACA_COLOR_GREEN,
     880        CACA_COLOR_CYAN,
     881        CACA_COLOR_BLUE,
     882        CACA_COLOR_MAGENTA
     883    };
     884
     885#define SETPAIR(_fg, _bg, _n) \
     886    do \
     887    { \
     888        int fg = _fg, bg = _bg, n = _n; \
     889        SLtt_set_color(n, NULL, slang_colors[fg], slang_colors[bg]); \
     890        slang_assoc[fg + 16 * bg] = n; \
     891    } \
     892    while(0);
     893
     894    /*
     895     * XXX: See the NOTES file for what follows
     896     */
     897
     898    /* black background colour pairs that are needed for the old renderer */
     899    for(i = 1; i < 16; i++)
     900        SETPAIR(i, CACA_COLOR_BLACK, cur++);
     901
     902    /* gray combinations used for grayscale dithering */
     903    SETPAIR(CACA_COLOR_BLACK, CACA_COLOR_DARKGRAY, cur++);
     904    SETPAIR(CACA_COLOR_DARKGRAY, CACA_COLOR_LIGHTGRAY, cur++);
     905    SETPAIR(CACA_COLOR_LIGHTGRAY, CACA_COLOR_DARKGRAY, cur++);
     906    SETPAIR(CACA_COLOR_WHITE, CACA_COLOR_LIGHTGRAY, cur++);
     907    SETPAIR(CACA_COLOR_LIGHTGRAY, CACA_COLOR_WHITE, cur++);
     908
     909    /* white/light, light/dark, lightgray/light, darkgray/dark, dark/black
     910     * combinations often used for saturation/value dithering (the two
     911     * other possible combinations, lightgray/dark and darkgray/light, are
     912     * not considered here) */
     913    for(i = 1; i < 7; i++)
     914    {
     915        SETPAIR(CACA_COLOR_WHITE, i + 8, cur++);
     916        SETPAIR(i + 8, CACA_COLOR_WHITE, cur++);
     917        SETPAIR(i, i + 8, cur++);
     918        SETPAIR(i + 8, i, cur++);
     919        SETPAIR(CACA_COLOR_LIGHTGRAY, i + 8, cur++);
     920        SETPAIR(i + 8, CACA_COLOR_LIGHTGRAY, cur++);
     921        SETPAIR(CACA_COLOR_DARKGRAY, i, cur++);
     922        SETPAIR(i, CACA_COLOR_DARKGRAY, cur++);
     923        SETPAIR(CACA_COLOR_BLACK, i, cur++);
     924    }
     925
     926    /* next colour combinations for hue dithering (magenta/blue, blue/green
     927     * and so on) */
     928    for(i = 0; i < 6; i++)
     929    {
     930        SETPAIR(hue_list[i], hue_list[(i + 1) % 6], cur++);
     931        SETPAIR(hue_list[(i + 1) % 6], hue_list[i], cur++);
     932        SETPAIR(hue_list[i] + 8, hue_list[(i + 1) % 6] + 8, cur++);
     933        SETPAIR(hue_list[(i + 1) % 6] + 8, hue_list[i] + 8, cur++);
     934    }
     935
     936    /* next colour combinations for hue/value dithering (blue/lightgreen,
     937     * green/lightblue and so on) */
     938    for(i = 0; i < 6; i++)
     939    {
     940        SETPAIR(hue_list[i], hue_list[(i + 1) % 6] + 8, cur++);
     941        SETPAIR(hue_list[(i + 1) % 6], hue_list[i] + 8, cur++);
     942        SETPAIR(hue_list[i] + 8, hue_list[(i + 1) % 6], cur++);
     943        SETPAIR(hue_list[(i + 1) % 6] + 8, hue_list[i], cur++);
     944    }
     945
     946    /* black on light gray, black on white, white on dark gray, dark gray
     947     * on white, white on blue, light gray on blue (chosen arbitrarily) */
     948    SETPAIR(CACA_COLOR_BLACK, CACA_COLOR_LIGHTGRAY, cur++);
     949    SETPAIR(CACA_COLOR_BLACK, CACA_COLOR_WHITE, cur++);
     950    SETPAIR(CACA_COLOR_WHITE, CACA_COLOR_DARKGRAY, cur++);
     951    SETPAIR(CACA_COLOR_DARKGRAY, CACA_COLOR_WHITE, cur++);
     952    SETPAIR(CACA_COLOR_WHITE, CACA_COLOR_BLUE, cur++);
     953    SETPAIR(CACA_COLOR_LIGHTGRAY, CACA_COLOR_BLUE, cur++);
     954
     955    /*
     956     * Now the possibly emulated pairs
     957     */
     958
     959    /* light gray on dark colour: emulate with light colour on dark colour
     960     * white on dark colour: emulate with light gray on light colour
     961     * black on light colour: emulate with dark gray on dark colour
     962     * dark gray on light colour: emulate with dark colour on light colour
     963     * light colour on dark gray: emulate with dark colour on dark gray
     964     * dark colour on light gray: emulate with light colour on light gray
     965     * dark colour on white: emulate with light colour on white */
     966    for(i = 1; i < 7; i++)
     967    {
     968        if(i != CACA_COLOR_BLUE)
     969        {
     970            SETPAIR(CACA_COLOR_LIGHTGRAY, i, 128 +
     971                    slang_assoc[i + 8 + 16 * i]);
     972            SETPAIR(CACA_COLOR_WHITE, i, 128 +
     973                    slang_assoc[CACA_COLOR_LIGHTGRAY + 16 * (i + 8)]);
     974        }
     975        SETPAIR(CACA_COLOR_BLACK, i + 8,
     976                128 + slang_assoc[CACA_COLOR_DARKGRAY + 16 * i]);
     977        SETPAIR(CACA_COLOR_DARKGRAY, i + 8,
     978                128 + slang_assoc[i + 16 * (i + 8)]);
     979        SETPAIR(i + 8, CACA_COLOR_DARKGRAY,
     980                128 + slang_assoc[i + 16 * CACA_COLOR_DARKGRAY]);
     981        SETPAIR(i, CACA_COLOR_LIGHTGRAY,
     982                128 + slang_assoc[i + 8 + 16 * CACA_COLOR_LIGHTGRAY]);
     983        SETPAIR(i, CACA_COLOR_WHITE,
     984                128 + slang_assoc[i + 8 + 16 * CACA_COLOR_WHITE]);
     985    }
     986
     987    /* 120 degree hue pairs can be emulated as well; for instance blue on
     988     * red can be emulated using magenta on red, and blue on green using
     989     * cyan on green */
     990    for(i = 0; i < 6; i++)
     991    {
     992        SETPAIR(hue_list[(i + 2) % 6], hue_list[i],
     993            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i]]);
     994        SETPAIR(hue_list[(i + 2) % 6] + 8, hue_list[i] + 8,
     995            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 136]);
     996        SETPAIR(hue_list[(i + 2) % 6] + 8, hue_list[i],
     997            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 8]);
     998        SETPAIR(hue_list[(i + 2) % 6], hue_list[i] + 8,
     999            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 128]);
     1000
     1001        SETPAIR(hue_list[(i + 4) % 6], hue_list[i],
     1002            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i]]);
     1003        SETPAIR(hue_list[(i + 4) % 6] + 8, hue_list[i] + 8,
     1004            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 136]);
     1005        SETPAIR(hue_list[(i + 4) % 6] + 8, hue_list[i],
     1006            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 8]);
     1007        SETPAIR(hue_list[(i + 4) % 6], hue_list[i] + 8,
     1008            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 128]);
     1009    }
     1010
     1011    /* dark opposite on dark: emulate with dark opposite on black
     1012     * light opposite on dark: emulate with light opposite on black
     1013     * dark opposite on light: emulate with black on dark
     1014     * light opposite on light: emulate with white on light */
     1015    for(i = 0; i < 6; i++)
     1016    {
     1017        SETPAIR(hue_list[i], hue_list[(i + 3) % 6],
     1018                128 + slang_assoc[hue_list[i] + 16 * CACA_COLOR_BLACK]);
     1019        SETPAIR(hue_list[i] + 8, hue_list[(i + 3) % 6],
     1020                128 + slang_assoc[hue_list[i] + 8 + 16 * CACA_COLOR_BLACK]);
     1021        SETPAIR(hue_list[(i + 3) % 6], hue_list[i] + 8,
     1022                128 + slang_assoc[CACA_COLOR_BLACK + 16 * hue_list[i]]);
     1023        SETPAIR(hue_list[(i + 3) % 6] + 8, hue_list[i] + 8,
     1024                128 + slang_assoc[CACA_COLOR_WHITE + 16 * (hue_list[i] + 8)]);
     1025    }
     1026#endif
     1027}
     1028#endif /* USE_SLANG */
     1029
Note: See TracChangeset for help on using the changeset viewer.