source: libcaca/trunk/caca/caca0.c @ 2821

Last change on this file since 2821 was 2821, checked in by Sam Hocevar, 11 years ago

Starting refactoring to get rid of libcucul. The initial reason for the
split is rendered moot by the plugin system: when enabled, binaries do
not link directly with libX11 or libGL. I hope this is a step towards
more consisteny and clarity.

  • Property svn:keywords set to Id
File size: 7.6 KB
Line 
1/*
2 *  libcaca       Colour ASCII-Art library
3 *  Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: caca0.c 2821 2008-09-27 13:12:46Z sam $
7 *
8 *  This library is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15/*
16 *  This file contains glue code for applications using the pre-1.0
17 *  libcaca API.
18 */
19
20#include "config.h"
21
22#if !defined(__KERNEL__)
23#   include <stdlib.h>
24#endif
25
26#include "caca.h"
27#include "caca_internals.h"
28
29/* These variables are needed to emulate old non-thread safe behaviour */
30caca_canvas_t *__caca0_cv = NULL;
31caca_display_t *__caca0_dp = NULL;
32unsigned char __caca0_fg = CACA_LIGHTGRAY;
33unsigned char __caca0_bg = CACA_BLACK;
34char __caca0_utf8[2] = " ";
35
36/* These functions are needed, too */
37int __caca0_init(void);
38void __caca0_end(void);
39unsigned int __caca0_get_event(unsigned int, int);
40unsigned int __caca0_sqrt(unsigned int);
41int __caca0_get_feature(int);
42void __caca0_set_feature(int);
43char const *__caca0_get_feature_name(int);
44caca_canvas_t *__caca0_load_sprite(char const *);
45caca_dither_t *__caca0_create_bitmap(unsigned int, unsigned int,
46          unsigned int, unsigned int, unsigned long int, unsigned long int,
47          unsigned long int, unsigned long int);
48void __caca0_free_bitmap(caca_dither_t *);
49extern char const *__caca0_get_color_name(unsigned char);
50
51/* Emulation functions */
52int __caca0_init(void)
53{
54    __caca0_cv = caca_create_canvas(0, 0);
55    if(!__caca0_cv)
56        return -1;
57    __caca0_dp = caca_create_display(__caca0_cv);
58    if(!__caca0_dp)
59    {
60        caca_free_canvas(__caca0_cv);
61        __caca0_cv = NULL;
62        return -1;
63    }
64    __caca0_fg = CACA_LIGHTGRAY;
65    __caca0_bg = CACA_BLACK;
66    return 0;
67}
68
69void __caca0_end(void)
70{
71    caca_free_display(__caca0_dp);
72    __caca0_dp = NULL;
73    caca_free_canvas(__caca0_cv);
74    __caca0_cv = NULL;
75}
76
77unsigned int __caca0_get_event(unsigned int m, int t)
78{
79    caca_event_t ev;
80    int ret;
81
82    ret = caca_get_event(__caca0_dp, (m >> 24) & 0x7f, &ev, t);
83    if(!ret)
84        return 0x00000000;
85
86    switch(caca_get_event_type(&ev))
87    {
88        case CACA_EVENT_KEY_PRESS:
89            return 0x01000000 | caca_get_event_key_ch(&ev);
90        case CACA_EVENT_KEY_RELEASE:
91            return 0x02000000 | caca_get_event_key_ch(&ev);
92        case CACA_EVENT_MOUSE_PRESS:
93            return 0x04000000 | caca_get_event_mouse_button(&ev);
94        case CACA_EVENT_MOUSE_RELEASE:
95            return 0x08000000 | caca_get_event_mouse_button(&ev);
96        case CACA_EVENT_MOUSE_MOTION:
97            return 0x10000000 | ((caca_get_event_mouse_x(&ev) & 0xfff) << 12)
98                              | (caca_get_event_mouse_y(&ev) & 0xfff);
99        case CACA_EVENT_RESIZE:
100            return 0x20000000;
101        default:
102            break;
103    }
104
105    return 0x00000000;
106}
107
108unsigned int __caca0_sqrt(unsigned int a)
109{
110    if(a == 0)
111        return 0;
112
113    if(a < 1000000000)
114    {
115        unsigned int x = a < 10 ? 1
116                       : a < 1000 ? 10
117                       : a < 100000 ? 100
118                       : a < 10000000 ? 1000
119                       : 10000;
120
121        /* Newton's method. Three iterations would be more than enough. */
122        x = (x * x + a) / x / 2;
123        x = (x * x + a) / x / 2;
124        x = (x * x + a) / x / 2;
125        x = (x * x + a) / x / 2;
126
127        return x;
128    }
129
130    return 2 * __caca0_sqrt(a / 4);
131}
132
133static char const *features[] =
134{
135    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
136    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
137
138    NULL, "16", "full16", NULL, NULL, NULL, NULL, NULL,
139    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
140
141    NULL, "none", "prefilter", NULL, NULL, NULL, NULL, NULL,
142    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
143
144    NULL, "none", "ordered2", "ordered4", "ordered8", "random"
145};
146
147static caca_dither_t **bitmaps = NULL;
148static unsigned int nbitmaps = 0;
149
150static int background = 0x12;
151static int antialiasing = 0x22;
152static int dithering = 0x33;
153
154int __caca0_get_feature(int feature)
155{
156    if(feature == 0x10)
157        return background;
158    if(feature == 0x20)
159        return antialiasing;
160    if(feature == 0x30)
161        return dithering;
162    return 0xffff; /* CACA_FEATURE_UNKNOWN */
163}
164
165void __caca0_set_feature(int feature)
166{
167    unsigned int i;
168
169    switch(feature)
170    {
171        case 0x10: feature = 0x12; /* CACA_BACKGROUND_SOLID */
172        case 0x11: case 0x12:
173            background = feature;
174            for(i = 0; i < nbitmaps; i++)
175                caca_set_dither_color(bitmaps[i], features[feature]);
176            break;
177
178        case 0x20: feature = 0x22; /* CACA_ANTIALIASING_PREFILTER */
179        case 0x21: case 0x22:
180            antialiasing = feature;
181            for(i = 0; i < nbitmaps; i++)
182                caca_set_dither_antialias(bitmaps[i], features[feature]);
183            break;
184
185        case 0x30: feature = 0x33; /* CACA_DITHERING_ORDERED4 */
186        case 0x31: case 0x32: case 0x33: case 0x34: case 0x35:
187            dithering = feature;
188            for(i = 0; i < nbitmaps; i++)
189                caca_set_dither_algorithm(bitmaps[i], features[feature]);
190            break;
191    }
192}
193
194char const *__caca0_get_feature_name(int feature)
195{
196    switch(feature)
197    {
198        case 0x11: return "black background";
199        case 0x12: return "solid background";
200
201        case 0x21: return "no antialiasing";
202        case 0x22: return "prefilter antialiasing";
203
204        case 0x31: return "no dithering";
205        case 0x32: return "2x2 ordered dithering";
206        case 0x33: return "4x4 ordered dithering";
207        case 0x34: return "8x8 ordered dithering";
208        case 0x35: return "random dithering";
209
210        default: return "unknown";
211    }
212}
213
214caca_canvas_t *__caca0_load_sprite(char const *file)
215{
216    caca_canvas_t *cv;
217
218    cv = caca_create_canvas(0, 0);;
219    if(caca_import_file(cv, file, "") < 0)
220    {
221        caca_free_canvas(cv);
222        return NULL;
223    }
224
225    return cv;
226}
227
228caca_dither_t *__caca0_create_bitmap(unsigned int bpp, unsigned int w,
229                                      unsigned int h, unsigned int pitch,
230                                      unsigned long int r, unsigned long int g,
231                                      unsigned long int b, unsigned long int a)
232{
233    caca_dither_t *d;
234
235    d = caca_create_dither(bpp, w, h, pitch, r, g, b, a);
236    if(!d)
237        return NULL;
238
239    caca_set_dither_color(d, features[background]);
240    caca_set_dither_antialias(d, features[antialiasing]);
241    caca_set_dither_algorithm(d, features[dithering]);
242
243    /* Store bitmap in our list */
244    nbitmaps++;
245    bitmaps = realloc(bitmaps, nbitmaps * (sizeof(caca_dither_t *)));
246    bitmaps[nbitmaps - 1] = d;
247
248    return d;
249}
250
251void __caca0_free_bitmap(caca_dither_t *d)
252{
253    unsigned int i, found = 0;
254
255    caca_free_dither(d);
256
257    /* Remove bitmap from our list */
258    for(i = 0; i + 1 < nbitmaps; i++)
259    {
260        if(bitmaps[i] == d)
261            found = 1;
262        if(found)
263            bitmaps[i] = bitmaps[i + 1];
264    }
265
266    nbitmaps--;
267}
268
269char const *__caca0_get_color_name(unsigned char color)
270{
271    static char const *color_names[] =
272    {
273        "black",
274        "blue",
275        "green",
276        "cyan",
277        "red",
278        "magenta",
279        "brown",
280        "light gray",
281        "dark gray",
282        "light blue",
283        "light green",
284        "light cyan",
285        "light red",
286        "light magenta",
287        "yellow",
288        "white",
289    };
290
291    if(color > 15)
292        return "unknown";
293
294    return color_names[(unsigned int)color];
295}
296
Note: See TracBrowser for help on using the repository browser.