source: libcaca/trunk/src/sprite.c @ 246

Last change on this file since 246 was 246, checked in by Sam Hocevar, 18 years ago
  • src/graphics.c: + Internally cache screen width and height.
  • src/bitmap.c: + Added alpha support to caca_draw_bitmap(). For now, we only treat 0%

alpha as fully transparent, and any other value as fully opaque.

+ Slightly tuned colour weights in the renderer.
+ caca_set_bitmap_palette() takes unsigned ints.

  • examples/demo.c: + Added a crap render demo.
  • examples/aafire.c: + Set a 20ms delay. + Added alpha values to the palette.
  • examples/view.c: + Draw a gray checkered grid below the image so that transparent images

look a lot nicer.

+ 'f' toggles "fullscreen" mode.

  • Property svn:keywords set to Id
File size: 6.0 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 sprite.c
23 *   \version \$Id: sprite.c 246 2003-12-11 16:31:49Z sam $
24 *   \author Sam Hocevar <sam@zoy.org>
25 *   \brief Sprite loading and blitting
26 *
27 *   This file contains a small framework for sprite loading and blitting.
28 */
29
30#include "config.h"
31
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35
36#include "caca.h"
37#include "caca_internals.h"
38
39struct caca_frame
40{
41    int w, h;
42    int dx, dy;
43    char *chars;
44    int *color;
45};
46
47struct caca_sprite
48{
49    int nf;
50    struct caca_frame *frames;
51};
52
53struct caca_sprite *caca_load_sprite(const char *file)
54{
55    char buf[BUFSIZ];
56    struct caca_sprite *sprite;
57    FILE *fd;
58
59    fd = fopen(file, "r");
60    if(fd == NULL)
61        return NULL;
62
63    sprite = malloc(sizeof(struct caca_sprite));
64    if(sprite == NULL)
65        goto sprite_alloc_failed;
66
67    sprite->nf = 0;
68    sprite->frames = NULL;
69
70    while(!feof(fd))
71    {
72        int x, y;
73        int w = 0, h = 0, dx = 0, dy = 0;
74        struct caca_frame *frame;
75
76        /* Get width and height */
77        if(!fgets(buf, BUFSIZ, fd))
78            break;
79
80        sscanf(buf, "%i %i %i %i", &w, &h, &dx, &dy);
81        if(w <= 0 || h <= 0 || w > BUFSIZ / 2)
82            break;
83
84        if(sprite->nf)
85        {
86            void *tmp = realloc(sprite->frames,
87                                (sprite->nf + 1) * sizeof(struct caca_frame));
88            if(tmp == NULL)
89                goto frame_failed;
90            sprite->frames = tmp;
91            sprite->nf++;
92        }
93        else
94        {
95            sprite->frames = malloc((sprite->nf + 1) * sizeof(struct caca_frame));
96            if(sprite->frames == NULL)
97                goto sprite_failed;
98            sprite->nf++;
99        }
100
101        frame = &sprite->frames[sprite->nf - 1];
102
103        frame->w = w;
104        frame->h = h;
105        frame->dx = dx;
106        frame->dy = dy;
107        frame->chars = malloc(w * h * sizeof(char));
108        if(frame->chars == NULL)
109        {
110            sprite->nf--;
111            goto frame_failed;
112        }
113        frame->color = malloc(w * h * sizeof(int));
114        if(frame->color == NULL)
115        {
116            free(frame->chars);
117            sprite->nf--;
118            goto frame_failed;
119        }
120
121        for(y = 0; y < h; y++)
122        {
123            if(!fgets(buf, BUFSIZ, fd))
124                goto frame_failed;
125
126            for(x = 0; x < w && buf[x] && buf[x] != '\r' && buf[x] != '\n'; x++)
127                frame->chars[w * y + x] = buf[x];
128
129            for(; x < w; x++)
130                frame->chars[w * y + x] = ' ';
131        }
132
133        for(y = 0; y < h; y++)
134        {
135            if(!fgets(buf, BUFSIZ, fd))
136                goto frame_failed;
137
138            for(x = 0; x < w && buf[x] && buf[x] != '\r' && buf[x] != '\n'; x++)
139                frame->color[w * y + x] = buf[x] - 'a';
140
141            for(; x < w; x++)
142                frame->color[w * y + x] = ' ' - 'a';
143        }
144
145        continue;
146    }
147
148    if(sprite->nf == 0)
149        goto sprite_failed;
150
151    fclose(fd);
152    return sprite;
153
154frame_failed:
155    while(sprite->nf)
156    {
157        free(sprite->frames[sprite->nf - 1].color);
158        free(sprite->frames[sprite->nf - 1].chars);
159        sprite->nf--;
160    }
161sprite_failed:
162    free(sprite);
163sprite_alloc_failed:
164    fclose(fd);
165    return NULL;
166}
167
168int caca_get_sprite_frames(const struct caca_sprite *sprite)
169{
170    if(sprite == NULL)
171        return 0;
172
173    return sprite->nf;
174}
175
176int caca_get_sprite_width(const struct caca_sprite *sprite, int f)
177{
178    if(sprite == NULL)
179        return 0;
180
181    if(f < 0 || f >= sprite->nf)
182        return 0;
183
184    return sprite->frames[f].w;
185}
186
187int caca_get_sprite_height(const struct caca_sprite *sprite, int f)
188{
189    if(sprite == NULL)
190        return 0;
191
192    if(f < 0 || f >= sprite->nf)
193        return 0;
194
195    return sprite->frames[f].h;
196}
197
198int caca_get_sprite_dx(const struct caca_sprite *sprite, int f)
199{
200    if(sprite == NULL)
201        return 0;
202
203    if(f < 0 || f >= sprite->nf)
204        return 0;
205
206    return sprite->frames[f].dx;
207}
208
209int caca_get_sprite_dy(const struct caca_sprite *sprite, int f)
210{
211    if(sprite == NULL)
212        return 0;
213
214    if(f < 0 || f >= sprite->nf)
215        return 0;
216
217    return sprite->frames[f].dy;
218}
219
220void caca_draw_sprite(int x, int y, const struct caca_sprite *sprite, int f)
221{
222    int i, j;
223    enum caca_color oldfg, oldbg;
224    struct caca_frame *frame;
225
226    if(sprite == NULL)
227        return;
228
229    if(f < 0 || f >= sprite->nf)
230        return;
231
232    frame = &sprite->frames[f];
233
234    oldfg = caca_get_fg_color();
235    oldbg = caca_get_bg_color();
236
237    for(j = 0; j < frame->h; j++)
238    {
239        for(i = 0; i < frame->w; i++)
240        {
241            int col = frame->color[frame->w * j + i];
242            if(col >= 0)
243            {
244                caca_set_color(col, CACA_COLOR_BLACK);
245                caca_putchar(x + i - frame->dx, y + j - frame->dy,
246                           frame->chars[frame->w * j + i]);
247            }
248        }
249    }
250
251    caca_set_color(oldfg, oldbg);
252}
253
254void caca_free_sprite(struct caca_sprite *sprite)
255{
256    int i;
257
258    if(sprite == NULL)
259        return;
260
261    for(i = sprite->nf; i--;)
262    {
263        struct caca_frame *frame = &sprite->frames[i];
264        free(frame->chars);
265        free(frame->color);
266    }
267
268    free(sprite->frames);
269    free(sprite);
270}
271
Note: See TracBrowser for help on using the repository browser.