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

Last change on this file since 1039 was 1015, checked in by Sam Hocevar, 14 years ago
  • Made features (such as dithering mode) and caca_sqrt work in the legacy 0.x glue code.
  • Property svn:keywords set to Id
File size: 7.0 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 1015 2006-09-09 16:53:13Z 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_COLOR_LIGHTGRAY;
33unsigned char __caca0_bg = CUCUL_COLOR_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 *);
49
50/* Emulation functions */
51int __caca0_init(void)
52{
53    __caca0_cv = cucul_create_canvas(0, 0);
54    if(!__caca0_cv)
55        return -1;
56    __caca0_dp = caca_create_display(__caca0_cv);
57    if(!__caca0_dp)
58    {
59        cucul_free_canvas(__caca0_cv);
60        __caca0_cv = NULL;
61        return -1;
62    }
63    __caca0_fg = CUCUL_COLOR_LIGHTGRAY;
64    __caca0_bg = CUCUL_COLOR_BLACK;
65    return 0;
66}
67
68void __caca0_end(void)
69{
70    caca_free_display(__caca0_dp);
71    __caca0_dp = NULL;
72    cucul_free_canvas(__caca0_cv);
73    __caca0_cv = NULL;
74}
75
76unsigned int __caca0_get_event(unsigned int m, int t)
77{
78    caca_event_t ev;
79    int ret;
80
81    ret = caca_get_event(__caca0_dp, (m >> 24) & 0x7f, &ev, t);
82    if(!ret)
83        return 0x00000000;
84
85    switch(ev.type)
86    {
87        case CACA_EVENT_KEY_PRESS:
88            return 0x01000000 | ev.data.key.ch;
89        case CACA_EVENT_KEY_RELEASE:
90            return 0x02000000 | ev.data.key.ch;
91        case CACA_EVENT_MOUSE_PRESS:
92            return 0x04000000 | ev.data.mouse.button;
93        case CACA_EVENT_MOUSE_RELEASE:
94            return 0x08000000 | ev.data.mouse.button;
95        case CACA_EVENT_MOUSE_MOTION:
96            return 0x10000000 | ((ev.data.mouse.x & 0xfff) << 12)
97                              | (ev.data.mouse.y & 0xfff);
98        case CACA_EVENT_RESIZE:
99            return 0x20000000;
100        default:
101            break;
102    }
103
104    return 0x00000000;
105}
106
107unsigned int __caca0_sqrt(unsigned int a)
108{
109    if(a == 0)
110        return 0;
111
112    if(a < 1000000000)
113    {
114        unsigned int x = a < 10 ? 1
115                       : a < 1000 ? 10
116                       : a < 100000 ? 100
117                       : a < 10000000 ? 1000
118                       : 10000;
119
120        /* Newton's method. Three iterations would be more than enough. */
121        x = (x * x + a) / x / 2;
122        x = (x * x + a) / x / 2;
123        x = (x * x + a) / x / 2;
124        x = (x * x + a) / x / 2;
125
126        return x;
127    }
128
129    return 2 * __caca0_sqrt(a / 4);
130}
131
132static char const *features[] =
133{
134    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
135    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
136
137    NULL, "16", "full16", NULL, NULL, NULL, NULL, NULL,
138    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
139
140    NULL, "none", "prefilter", NULL, NULL, NULL, NULL, NULL,
141    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
142
143    NULL, "none", "ordered2", "ordered4", "ordered8", "random"
144};
145
146static cucul_dither_t **bitmaps = NULL;
147static unsigned int nbitmaps = 0;
148
149static int background = 0x12;
150static int antialiasing = 0x22;
151static int dithering = 0x33;
152
153int __caca0_get_feature(int feature)
154{
155    if(feature == 0x10)
156        return background;
157    if(feature == 0x20)
158        return antialiasing;
159    if(feature == 0x30)
160        return dithering;
161    return 0xffff; /* CACA_FEATURE_UNKNOWN */
162}
163
164void __caca0_set_feature(int feature)
165{
166    unsigned int i;
167
168    switch(feature)
169    {
170        case 0x10: feature = 0x12; /* CACA_BACKGROUND_SOLID */
171        case 0x11: case 0x12:
172            background = feature;
173            for(i = 0; i < nbitmaps; i++)
174                cucul_set_dither_color(bitmaps[i], features[feature]);
175            break;
176
177        case 0x20: feature = 0x22; /* CACA_ANTIALIASING_PREFILTER */
178        case 0x21: case 0x22:
179            antialiasing = feature;
180            for(i = 0; i < nbitmaps; i++)
181                cucul_set_dither_antialias(bitmaps[i], features[feature]);
182            break;
183
184        case 0x30: feature = 0x33; /* CACA_DITHERING_ORDERED4 */
185        case 0x31: case 0x32: case 0x33: case 0x34: case 0x35:
186            dithering = feature;
187            for(i = 0; i < nbitmaps; i++)
188                cucul_set_dither_mode(bitmaps[i], features[feature]);
189            break;
190    }
191}
192
193char const *__caca0_get_feature_name(int feature)
194{
195    switch(feature)
196    {
197        case 0x11: return "black background";
198        case 0x12: return "solid background";
199
200        case 0x21: return "no antialiasing";
201        case 0x22: return "prefilter antialiasing";
202
203        case 0x31: return "no dithering";
204        case 0x32: return "2x2 ordered dithering";
205        case 0x33: return "4x4 ordered dithering";
206        case 0x34: return "8x8 ordered dithering";
207        case 0x35: return "random dithering";
208
209        default: return "unknown";
210    }
211}
212
213cucul_canvas_t *__caca0_load_sprite(char const *file)
214{
215    cucul_buffer_t *buf;
216    cucul_canvas_t *cv;
217
218    buf = cucul_load_file(file);
219    if(!buf)
220        return NULL;
221    cv = cucul_import_canvas(buf, "");
222    cucul_free_buffer(buf);
223    if(!cv)
224        return NULL;
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_mode(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
Note: See TracBrowser for help on using the repository browser.