source: libcaca/trunk/src/caca.c @ 213

Last change on this file since 213 was 213, checked in by Sam Hocevar, 19 years ago
  • src/caca.c: + Mouse initialisation in ncurses.
  • src/io.c: + Mouse support in ncurses.
  • Property svn:keywords set to Id
File size: 7.6 KB
Line 
1/*
2 *   libcaca       ASCII-Art library
3 *   Copyright (c) 2002, 2003 Sam Hocevar <sam@zoy.org>
4 *                 All Rights Reserved
5 *
6 *   This library is free software; you can redistribute it and/or
7 *   modify it under the terms of the GNU Lesser General Public
8 *   License as published by the Free Software Foundation; either
9 *   version 2 of the License, or (at your option) any later version.
10 *
11 *   This library is distributed in the hope that it will be useful,
12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 *   Lesser General Public License for more details.
15 *
16 *   You should have received a copy of the GNU Lesser General Public
17 *   License along with this library; if not, write to the Free Software
18 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 *   02111-1307  USA
20 */
21
22/**  \file caca.c
23 *   \version \$Id: caca.c 213 2003-11-23 03:44:59Z sam $
24 *   \author Sam Hocevar <sam@zoy.org>
25 *   \brief Main \e libcaca functions
26 *
27 *   This file contains the main functions used by \e libcaca applications to
28 *   initialise the library, get the screen properties, set the framerate and
29 *   so on.
30 */
31
32#include "config.h"
33
34#if defined(USE_SLANG)
35#   include <slang.h>
36#elif defined(USE_NCURSES)
37#   include <curses.h>
38#elif defined(USE_CONIO)
39#   include <dos.h>
40#   include <conio.h>
41#   if defined(SCREENUPDATE_IN_PC_H)
42#       include <pc.h>
43#   endif
44#else
45#   error "no graphics library detected"
46#endif
47
48#include <stdlib.h>
49#include <unistd.h>
50#include <string.h>
51#include <sys/time.h>
52#include <time.h>
53
54#include "caca.h"
55#include "caca_internals.h"
56
57static unsigned int _caca_delay;
58static unsigned int _caca_rendertime;
59char *_caca_empty_line;
60char *_caca_scratch_line;
61
62#if defined(USE_NCURSES)
63static mmask_t oldmask;
64int _caca_attr[16];
65#endif
66
67#if defined(USE_CONIO)
68static struct text_info ti;
69char *_caca_screen;
70#endif
71
72int caca_init(void)
73{
74#if defined(USE_SLANG)
75    static char *slang_colors[16] =
76    {
77        "black",
78        "blue",
79        "green",
80        "cyan",
81        "red",
82        "magenta",
83        "brown",
84        "lightgray",
85        "gray",
86        "brightblue",
87        "brightgreen",
88        "brightcyan",
89        "brightred",
90        "brightmagenta",
91        "yellow",
92        "white",
93    };
94
95    int i;
96
97    /* Initialize slang library */
98    SLsig_block_signals();
99    SLtt_get_terminfo();
100
101    if(SLkp_init() == -1)
102    {
103        SLsig_unblock_signals();
104        return -1;
105    }
106
107    SLang_init_tty(-1, 0, 1);
108
109    if(SLsmg_init_smg() == -1)
110    {
111        SLsig_unblock_signals();
112        return -1;
113    }
114
115    SLsig_unblock_signals();
116
117    SLsmg_cls();
118    SLtt_set_cursor_visibility(0);
119    SLkp_define_keysym("\e[M", 1001);
120    SLtt_set_mouse_mode(1, 0);
121    SLsmg_refresh();
122
123    for(i = 0; i < 16; i++)
124        SLtt_set_color(i + 1, NULL, slang_colors[i], "black");
125
126#elif defined(USE_NCURSES)
127    int i;
128    mmask_t newmask;
129
130    initscr();
131    keypad(stdscr, TRUE);
132    nonl();
133    cbreak();
134    noecho();
135    nodelay(stdscr, TRUE);
136    curs_set(0);
137
138    newmask = ALL_MOUSE_EVENTS;
139    mousemask(newmask, &oldmask);
140
141    start_color();
142
143    init_pair(1 + CACA_COLOR_BLACK,        COLOR_BLACK,   COLOR_BLACK);
144    init_pair(1 + CACA_COLOR_BLUE,         COLOR_BLUE,    COLOR_BLACK);
145    init_pair(1 + CACA_COLOR_GREEN,        COLOR_GREEN,   COLOR_BLACK);
146    init_pair(1 + CACA_COLOR_CYAN,         COLOR_CYAN,    COLOR_BLACK);
147    init_pair(1 + CACA_COLOR_RED,          COLOR_RED,     COLOR_BLACK);
148    init_pair(1 + CACA_COLOR_MAGENTA,      COLOR_MAGENTA, COLOR_BLACK);
149    init_pair(1 + CACA_COLOR_BROWN,        COLOR_YELLOW,  COLOR_BLACK);
150    init_pair(1 + CACA_COLOR_LIGHTGRAY,    COLOR_WHITE,   COLOR_BLACK);
151    init_pair(1 + CACA_COLOR_DARKGRAY,     COLOR_BLACK,   COLOR_BLACK);
152    init_pair(1 + CACA_COLOR_LIGHTBLUE,    COLOR_BLUE,    COLOR_BLACK);
153    init_pair(1 + CACA_COLOR_LIGHTGREEN,   COLOR_GREEN,   COLOR_BLACK);
154    init_pair(1 + CACA_COLOR_LIGHTCYAN,    COLOR_CYAN,    COLOR_BLACK);
155    init_pair(1 + CACA_COLOR_LIGHTRED,     COLOR_RED,     COLOR_BLACK);
156    init_pair(1 + CACA_COLOR_LIGHTMAGENTA, COLOR_MAGENTA, COLOR_BLACK);
157    init_pair(1 + CACA_COLOR_YELLOW,       COLOR_YELLOW,  COLOR_BLACK);
158    init_pair(1 + CACA_COLOR_WHITE,        COLOR_WHITE,   COLOR_BLACK);
159
160    for(i = 0; i < 8; i++)
161    {
162        _caca_attr[i] = COLOR_PAIR(1 + i);
163        _caca_attr[i + 8] = A_BOLD | COLOR_PAIR(1 + i);
164    }
165
166#elif defined(USE_CONIO)
167    gettextinfo(&ti);
168    _caca_screen = malloc(2 * ti.screenwidth * ti.screenheight);
169    if(_caca_screen == NULL)
170        return -1;
171    _wscroll = 0;
172    _setcursortype(_NOCURSOR);
173    clrscr();
174#   if defined(SCREENUPDATE_IN_PC_H)
175    ScreenRetrieve(_caca_screen);
176#   else
177    /* FIXME */
178#   endif
179
180#endif
181    _caca_empty_line = malloc(caca_get_width() + 1);
182    memset(_caca_empty_line, ' ', caca_get_width());
183    _caca_empty_line[caca_get_width()] = '\0';
184
185    _caca_scratch_line = malloc(caca_get_width() + 1);
186
187    _caca_delay = 0;
188    _caca_rendertime = 0;
189
190    return 0;
191}
192
193unsigned int caca_get_width(void)
194{
195#if defined(USE_SLANG)
196    return SLtt_Screen_Cols;
197#elif defined(USE_NCURSES)
198    return COLS;
199#elif defined(USE_CONIO)
200    return ti.screenwidth;
201#endif
202}
203
204unsigned int caca_get_height(void)
205{
206#if defined(USE_SLANG)
207    return SLtt_Screen_Rows;
208#elif defined(USE_NCURSES)
209    return LINES;
210#else
211    return ti.screenheight;
212#endif
213}
214
215void caca_set_delay(unsigned int usec)
216{
217    _caca_delay = usec;
218}
219
220unsigned int caca_get_rendertime(void)
221{
222    return _caca_rendertime;
223}
224
225const char *caca_get_color_name(unsigned int color)
226{
227    static const char *color_names[16] =
228    {
229        "black",
230        "blue",
231        "green",
232        "cyan",
233        "red",
234        "magenta",
235        "brown",
236        "light gray",
237        "dark gray",
238        "light blue",
239        "light green",
240        "light cyan",
241        "light red",
242        "light magenta",
243        "yellow",
244        "white",
245    };
246
247    if(color < 0 || color > 15)
248        return "unknown color";
249
250    return color_names[color];
251}
252
253static unsigned int _caca_getticks(void)
254{
255    static unsigned int last_sec = 0, last_usec = 0;
256
257    struct timeval tv;
258    unsigned int ticks = 0;
259
260    gettimeofday(&tv, NULL);
261
262    if(last_sec != 0)
263    {
264        ticks = (tv.tv_sec - last_sec) * 1000000 + (tv.tv_usec - last_usec);
265    }
266
267    last_sec = tv.tv_sec;
268    last_usec = tv.tv_usec;
269
270    return ticks;
271}
272
273void caca_refresh(void)
274{
275#define IDLE_USEC 10000
276    static int lastticks = 0;
277    int ticks = lastticks + _caca_getticks();
278
279#if defined(USE_SLANG)
280    SLsmg_refresh();
281#elif defined(USE_NCURSES)
282    refresh();
283#elif defined(USE_CONIO)
284#   if defined(SCREENUPDATE_IN_PC_H)
285    ScreenUpdate(_caca_screen);
286#   else
287    /* FIXME */
288#   endif
289#endif
290
291    /* Wait until _caca_delay + time of last call */
292    ticks += _caca_getticks();
293    for(; ticks + IDLE_USEC < (int)_caca_delay; ticks += _caca_getticks())
294        usleep(IDLE_USEC);
295
296    /* Update the sliding mean of the render time */
297    _caca_rendertime = (7 * _caca_rendertime + ticks) / 8;
298
299    lastticks = ticks - _caca_delay;
300
301    /* If we drifted too much, it's bad, bad, bad. */
302    if(lastticks > (int)_caca_delay)
303        lastticks = 0;
304}
305
306void caca_end(void)
307{
308#if defined(USE_SLANG)
309    SLtt_set_mouse_mode(0, 0);
310    SLtt_set_cursor_visibility(1);
311    SLang_reset_tty();
312    SLsmg_reset_smg();
313#elif defined(USE_NCURSES)
314    mousemask(oldmask, NULL);
315    curs_set(1);
316    endwin();
317#elif defined(USE_CONIO)
318    _wscroll = 1;
319    textcolor((enum COLORS)WHITE);
320    textbackground((enum COLORS)BLACK);
321    gotoxy(caca_get_width(), caca_get_height());
322    cputs("\r\n");
323    _setcursortype(_NORMALCURSOR);
324#endif
325}
326
Note: See TracBrowser for help on using the repository browser.