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

Last change on this file since 1287 was 1287, checked in by Sam Hocevar, 13 years ago
  • Fix a harmless warning in caca0.c.
  • Property svn:keywords set to Id
File size: 7.5 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 1287 2006-11-05 23:59:06Z sam $
7 *
8 *  This library is free software; you can redistribute it and/or
9 *  modify it under the terms of the Do What The Fuck You Want To
10 *  Public License, Version 2, as published by Sam Hocevar. See
11 *  http://sam.zoy.org/wtfpl/COPYING for more details.
12 */
13
14/*
15 *  This file contains glue code for applications using the pre-1.0
16 *  libcaca API.
17 */
18
19#include "config.h"
20#include "common.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 */
30cucul_canvas_t *__caca0_cv = NULL;
31caca_display_t *__caca0_dp = NULL;
32unsigned char __caca0_fg = CUCUL_LIGHTGRAY;
33unsigned char __caca0_bg = CUCUL_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);
44cucul_canvas_t *__caca0_load_sprite(char const *);
45cucul_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(cucul_dither_t *);
49extern char const *__caca0_get_color_name(unsigned char);
50
51/* Emulation functions */
52int __caca0_init(void)
53{
54    __caca0_cv = cucul_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        cucul_free_canvas(__caca0_cv);
61        __caca0_cv = NULL;
62        return -1;
63    }
64    __caca0_fg = CUCUL_LIGHTGRAY;
65    __caca0_bg = CUCUL_BLACK;
66    return 0;
67}
68
69void __caca0_end(void)
70{
71    caca_free_display(__caca0_dp);
72    __caca0_dp = NULL;
73    cucul_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(ev.type)
87    {
88        case CACA_EVENT_KEY_PRESS:
89            return 0x01000000 | ev.data.key.ch;
90        case CACA_EVENT_KEY_RELEASE:
91            return 0x02000000 | ev.data.key.ch;
92        case CACA_EVENT_MOUSE_PRESS:
93            return 0x04000000 | ev.data.mouse.button;
94        case CACA_EVENT_MOUSE_RELEASE:
95            return 0x08000000 | ev.data.mouse.button;
96        case CACA_EVENT_MOUSE_MOTION:
97            return 0x10000000 | ((ev.data.mouse.x & 0xfff) << 12)
98                              | (ev.data.mouse.y & 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 cucul_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                cucul_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                cucul_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                cucul_set_dither_mode(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
214cucul_canvas_t *__caca0_load_sprite(char const *file)
215{
216    cucul_buffer_t *buf;
217    cucul_canvas_t *cv;
218
219    buf = cucul_load_file(file);
220    if(!buf)
221        return NULL;
222    cv = cucul_import_canvas(buf, "");
223    cucul_free_buffer(buf);
224    if(!cv)
225        return NULL;
226
227    return cv;
228}
229
230cucul_dither_t *__caca0_create_bitmap(unsigned int bpp, unsigned int w,
231                                      unsigned int h, unsigned int pitch,
232                                      unsigned long int r, unsigned long int g,
233                                      unsigned long int b, unsigned long int a)
234{
235    cucul_dither_t *d;
236
237    d = cucul_create_dither(bpp, w, h, pitch, r, g, b, a);
238    if(!d)
239        return NULL;
240
241    cucul_set_dither_color(d, features[background]);
242    cucul_set_dither_antialias(d, features[antialiasing]);
243    cucul_set_dither_mode(d, features[dithering]);
244
245    /* Store bitmap in our list */
246    nbitmaps++;
247    bitmaps = realloc(bitmaps, nbitmaps * (sizeof(cucul_dither_t *)));
248    bitmaps[nbitmaps - 1] = d;
249
250    return d;
251}
252
253void __caca0_free_bitmap(cucul_dither_t *d)
254{
255    unsigned int i, found = 0;
256
257    cucul_free_dither(d);
258
259    /* Remove bitmap from our list */
260    for(i = 0; i + 1 < nbitmaps; i++)
261    {
262        if(bitmaps[i] == d)
263            found = 1;
264        if(found)
265            bitmaps[i] = bitmaps[i + 1];
266    }
267
268    nbitmaps--;
269}
270
271char const *__caca0_get_color_name(unsigned char color)
272{
273    static char const *color_names[] =
274    {
275        "black",
276        "blue",
277        "green",
278        "cyan",
279        "red",
280        "magenta",
281        "brown",
282        "light gray",
283        "dark gray",
284        "light blue",
285        "light green",
286        "light cyan",
287        "light red",
288        "light magenta",
289        "yellow",
290        "white",
291    };
292
293    if(color > 15)
294        return "unknown";
295
296    return color_names[(unsigned int)color];
297}
298
Note: See TracBrowser for help on using the repository browser.