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

Last change on this file since 2049 was 2049, checked in by Sam Hocevar, 12 years ago
  • Made the caca_event_t structure opaque and created a whole bunch of functions to access its real data. This is a big API change that will break your software, sorry :(
  • 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 2049 2007-11-25 11:11:54Z 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#include "common.h"
22
23#if !defined(__KERNEL__)
24#   include <stdlib.h>
25#endif
26
27#include "caca.h"
28#include "caca_internals.h"
29
30/* These variables are needed to emulate old non-thread safe behaviour */
31cucul_canvas_t *__caca0_cv = NULL;
32caca_display_t *__caca0_dp = NULL;
33unsigned char __caca0_fg = CUCUL_LIGHTGRAY;
34unsigned char __caca0_bg = CUCUL_BLACK;
35char __caca0_utf8[2] = " ";
36
37/* These functions are needed, too */
38int __caca0_init(void);
39void __caca0_end(void);
40unsigned int __caca0_get_event(unsigned int, int);
41unsigned int __caca0_sqrt(unsigned int);
42int __caca0_get_feature(int);
43void __caca0_set_feature(int);
44char const *__caca0_get_feature_name(int);
45cucul_canvas_t *__caca0_load_sprite(char const *);
46cucul_dither_t *__caca0_create_bitmap(unsigned int, unsigned int,
47          unsigned int, unsigned int, unsigned long int, unsigned long int,
48          unsigned long int, unsigned long int);
49void __caca0_free_bitmap(cucul_dither_t *);
50extern char const *__caca0_get_color_name(unsigned char);
51
52/* Emulation functions */
53int __caca0_init(void)
54{
55    __caca0_cv = cucul_create_canvas(0, 0);
56    if(!__caca0_cv)
57        return -1;
58    __caca0_dp = caca_create_display(__caca0_cv);
59    if(!__caca0_dp)
60    {
61        cucul_free_canvas(__caca0_cv);
62        __caca0_cv = NULL;
63        return -1;
64    }
65    __caca0_fg = CUCUL_LIGHTGRAY;
66    __caca0_bg = CUCUL_BLACK;
67    return 0;
68}
69
70void __caca0_end(void)
71{
72    caca_free_display(__caca0_dp);
73    __caca0_dp = NULL;
74    cucul_free_canvas(__caca0_cv);
75    __caca0_cv = NULL;
76}
77
78unsigned int __caca0_get_event(unsigned int m, int t)
79{
80    caca_event_t ev;
81    int ret;
82
83    ret = caca_get_event(__caca0_dp, (m >> 24) & 0x7f, &ev, t);
84    if(!ret)
85        return 0x00000000;
86
87    switch(caca_get_event_type(&ev))
88    {
89        case CACA_EVENT_KEY_PRESS:
90            return 0x01000000 | caca_get_event_key_ch(&ev);
91        case CACA_EVENT_KEY_RELEASE:
92            return 0x02000000 | caca_get_event_key_ch(&ev);
93        case CACA_EVENT_MOUSE_PRESS:
94            return 0x04000000 | caca_get_event_mouse_button(&ev);
95        case CACA_EVENT_MOUSE_RELEASE:
96            return 0x08000000 | caca_get_event_mouse_button(&ev);
97        case CACA_EVENT_MOUSE_MOTION:
98            return 0x10000000 | ((caca_get_event_mouse_x(&ev) & 0xfff) << 12)
99                              | (caca_get_event_mouse_y(&ev) & 0xfff);
100        case CACA_EVENT_RESIZE:
101            return 0x20000000;
102        default:
103            break;
104    }
105
106    return 0x00000000;
107}
108
109unsigned int __caca0_sqrt(unsigned int a)
110{
111    if(a == 0)
112        return 0;
113
114    if(a < 1000000000)
115    {
116        unsigned int x = a < 10 ? 1
117                       : a < 1000 ? 10
118                       : a < 100000 ? 100
119                       : a < 10000000 ? 1000
120                       : 10000;
121
122        /* Newton's method. Three iterations would be more than enough. */
123        x = (x * x + a) / x / 2;
124        x = (x * x + a) / x / 2;
125        x = (x * x + a) / x / 2;
126        x = (x * x + a) / x / 2;
127
128        return x;
129    }
130
131    return 2 * __caca0_sqrt(a / 4);
132}
133
134static char const *features[] =
135{
136    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
137    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
138
139    NULL, "16", "full16", NULL, NULL, NULL, NULL, NULL,
140    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
141
142    NULL, "none", "prefilter", NULL, NULL, NULL, NULL, NULL,
143    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
144
145    NULL, "none", "ordered2", "ordered4", "ordered8", "random"
146};
147
148static cucul_dither_t **bitmaps = NULL;
149static unsigned int nbitmaps = 0;
150
151static int background = 0x12;
152static int antialiasing = 0x22;
153static int dithering = 0x33;
154
155int __caca0_get_feature(int feature)
156{
157    if(feature == 0x10)
158        return background;
159    if(feature == 0x20)
160        return antialiasing;
161    if(feature == 0x30)
162        return dithering;
163    return 0xffff; /* CACA_FEATURE_UNKNOWN */
164}
165
166void __caca0_set_feature(int feature)
167{
168    unsigned int i;
169
170    switch(feature)
171    {
172        case 0x10: feature = 0x12; /* CACA_BACKGROUND_SOLID */
173        case 0x11: case 0x12:
174            background = feature;
175            for(i = 0; i < nbitmaps; i++)
176                cucul_set_dither_color(bitmaps[i], features[feature]);
177            break;
178
179        case 0x20: feature = 0x22; /* CACA_ANTIALIASING_PREFILTER */
180        case 0x21: case 0x22:
181            antialiasing = feature;
182            for(i = 0; i < nbitmaps; i++)
183                cucul_set_dither_antialias(bitmaps[i], features[feature]);
184            break;
185
186        case 0x30: feature = 0x33; /* CACA_DITHERING_ORDERED4 */
187        case 0x31: case 0x32: case 0x33: case 0x34: case 0x35:
188            dithering = feature;
189            for(i = 0; i < nbitmaps; i++)
190                cucul_set_dither_algorithm(bitmaps[i], features[feature]);
191            break;
192    }
193}
194
195char const *__caca0_get_feature_name(int feature)
196{
197    switch(feature)
198    {
199        case 0x11: return "black background";
200        case 0x12: return "solid background";
201
202        case 0x21: return "no antialiasing";
203        case 0x22: return "prefilter antialiasing";
204
205        case 0x31: return "no dithering";
206        case 0x32: return "2x2 ordered dithering";
207        case 0x33: return "4x4 ordered dithering";
208        case 0x34: return "8x8 ordered dithering";
209        case 0x35: return "random dithering";
210
211        default: return "unknown";
212    }
213}
214
215cucul_canvas_t *__caca0_load_sprite(char const *file)
216{
217    cucul_canvas_t *cv;
218
219    cv = cucul_create_canvas(0, 0);;
220    if(cucul_import_file(cv, file, "") < 0)
221    {
222        cucul_free_canvas(cv);
223        return NULL;
224    }
225
226    return cv;
227}
228
229cucul_dither_t *__caca0_create_bitmap(unsigned int bpp, unsigned int w,
230                                      unsigned int h, unsigned int pitch,
231                                      unsigned long int r, unsigned long int g,
232                                      unsigned long int b, unsigned long int a)
233{
234    cucul_dither_t *d;
235
236    d = cucul_create_dither(bpp, w, h, pitch, r, g, b, a);
237    if(!d)
238        return NULL;
239
240    cucul_set_dither_color(d, features[background]);
241    cucul_set_dither_antialias(d, features[antialiasing]);
242    cucul_set_dither_algorithm(d, features[dithering]);
243
244    /* Store bitmap in our list */
245    nbitmaps++;
246    bitmaps = realloc(bitmaps, nbitmaps * (sizeof(cucul_dither_t *)));
247    bitmaps[nbitmaps - 1] = d;
248
249    return d;
250}
251
252void __caca0_free_bitmap(cucul_dither_t *d)
253{
254    unsigned int i, found = 0;
255
256    cucul_free_dither(d);
257
258    /* Remove bitmap from our list */
259    for(i = 0; i + 1 < nbitmaps; i++)
260    {
261        if(bitmaps[i] == d)
262            found = 1;
263        if(found)
264            bitmaps[i] = bitmaps[i + 1];
265    }
266
267    nbitmaps--;
268}
269
270char const *__caca0_get_color_name(unsigned char color)
271{
272    static char const *color_names[] =
273    {
274        "black",
275        "blue",
276        "green",
277        "cyan",
278        "red",
279        "magenta",
280        "brown",
281        "light gray",
282        "dark gray",
283        "light blue",
284        "light green",
285        "light cyan",
286        "light red",
287        "light magenta",
288        "yellow",
289        "white",
290    };
291
292    if(color > 15)
293        return "unknown";
294
295    return color_names[(unsigned int)color];
296}
297
Note: See TracBrowser for help on using the repository browser.