Changeset 842
- Timestamp:
- Apr 22, 2006, 9:11:25 PM (15 years ago)
- Location:
- libcaca/trunk/cucul
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
libcaca/trunk/cucul/cucul.c
r834 r842 54 54 cv->chars = NULL; 55 55 cv->attr = NULL; 56 57 cv->frame = 0; 58 cv->framecount = 1; 59 cv->allchars = malloc(sizeof(uint32_t *)); 60 cv->allattr = malloc(sizeof(uint32_t *)); 61 cv->allchars[0] = NULL; 62 cv->allattr[0] = NULL; 56 63 57 64 /* Initialise to a default size. 80x32 is arbitrary but matches AAlib's … … 170 177 void cucul_free_canvas(cucul_canvas_t *cv) 171 178 { 179 unsigned int f; 180 172 181 _cucul_end_dither(); 173 182 174 free(cv->chars); 175 free(cv->attr); 183 for(f = 0; f < cv->framecount; f++) 184 { 185 free(cv->allchars[f]); 186 free(cv->allattr[f]); 187 } 176 188 177 189 free(cv); … … 197 209 unsigned int height) 198 210 { 199 unsigned int x, y, old_width, old_height, new_size, old_size;211 unsigned int x, y, f, old_width, old_height, new_size, old_size; 200 212 201 213 old_width = cv->width; … … 210 222 if(new_size > old_size) 211 223 { 212 cv->chars = realloc(cv->chars, new_size * sizeof(uint32_t)); 213 cv->attr = realloc(cv->attr, new_size * sizeof(uint32_t)); 224 for(f = 0; f < cv->framecount; f++) 225 { 226 cv->allchars[f] = realloc(cv->allchars[f], 227 new_size * sizeof(uint32_t)); 228 cv->allattr[f] = realloc(cv->allattr[f], 229 new_size * sizeof(uint32_t)); 230 } 214 231 } 215 232 … … 225 242 * copy lines starting from the bottom of the screen otherwise 226 243 * we will overwrite information. */ 227 for(y = height < old_height ? height : old_height; y--; ) 228 { 229 for(x = old_width; x--; ) 244 for(f = 0; f < cv->framecount; f++) 245 { 246 uint32_t *chars = cv->allchars[f]; 247 uint32_t *attr = cv->allattr[f]; 248 249 for(y = height < old_height ? height : old_height; y--; ) 230 250 { 231 cv->chars[y * width + x] = cv->chars[y * old_width + x]; 232 cv->attr[y * width + x] = cv->attr[y * old_width + x]; 251 for(x = old_width; x--; ) 252 { 253 chars[y * width + x] = chars[y * old_width + x]; 254 attr[y * width + x] = attr[y * old_width + x]; 255 } 256 257 /* Zero the end of the line */ 258 for(x = width - old_width; x--; ) 259 chars[y * width + old_width + x] = (uint32_t)' '; 260 memset(attr + y * width + old_width, 0, 261 (width - old_width) * 4); 233 262 } 234 235 /* Zero the end of the line */236 for(x = width - old_width; x--; )237 cv->chars[y * width + old_width + x] = (uint32_t)' ';238 memset(cv->attr + y * width + old_width, 0,239 (width - old_width) * 4);240 263 } 241 264 } … … 246 269 unsigned int lines = height < old_height ? height : old_height; 247 270 248 for(y = 1; y < lines; y++) 249 { 250 for(x = 0; x < width; x++) 271 for(f = 0; f < cv->framecount; f++) 272 { 273 uint32_t *chars = cv->allchars[f]; 274 uint32_t *attr = cv->allattr[f]; 275 276 for(y = 1; y < lines; y++) 251 277 { 252 cv->chars[y * width + x] = cv->chars[y * old_width + x]; 253 cv->attr[y * width + x] = cv->attr[y * old_width + x]; 278 for(x = 0; x < width; x++) 279 { 280 chars[y * width + x] = chars[y * old_width + x]; 281 attr[y * width + x] = attr[y * old_width + x]; 282 } 254 283 } 255 284 } … … 259 288 if(height > old_height) 260 289 { 261 /* Zero the bottom of the screen */ 262 for(x = (height - old_height) * width; x--; ) 263 cv->chars[old_height * width + x] = (uint32_t)' '; 264 memset(cv->attr + old_height * width, 0, 265 (height - old_height) * width * 4); 290 for(f = 0; f < cv->framecount; f++) 291 { 292 uint32_t *chars = cv->allchars[f]; 293 uint32_t *attr = cv->allattr[f]; 294 295 /* Zero the bottom of the screen */ 296 for(x = (height - old_height) * width; x--; ) 297 chars[old_height * width + x] = (uint32_t)' '; 298 memset(attr + old_height * width, 0, 299 (height - old_height) * width * 4); 300 } 266 301 } 267 302 … … 269 304 if(new_size <= old_size) 270 305 { 271 cv->chars = realloc(cv->chars, new_size * sizeof(uint32_t)); 272 cv->attr = realloc(cv->attr, new_size * sizeof(uint32_t)); 273 } 274 } 275 306 for(f = 0; f < cv->framecount; f++) 307 { 308 cv->allchars[f] = realloc(cv->allchars[f], 309 new_size * sizeof(uint32_t)); 310 cv->allattr[f] = realloc(cv->allattr[f], 311 new_size * sizeof(uint32_t)); 312 } 313 } 314 315 /* Reset the current frame shortcut */ 316 cv->chars = cv->allchars[cv->frame]; 317 cv->attr = cv->allattr[cv->frame]; 318 } 319 -
libcaca/trunk/cucul/cucul.h
r832 r842 34 34 /** \e libcucul context */ 35 35 typedef struct cucul_canvas cucul_canvas_t; 36 /** sprite structure */37 typedef struct cucul_sprite cucul_sprite_t;38 36 /** dither structure */ 39 37 typedef struct cucul_dither cucul_dither_t; … … 144 142 /* @} */ 145 143 146 /** \defgroup sprite libcucul sprite handling 147 * 148 * These functions provide high level routines for sprite loading, animation 149 * and rendering. 150 * 151 * @{ */ 152 cucul_sprite_t * cucul_load_sprite(char const *); 153 int cucul_get_sprite_frames(cucul_sprite_t const *); 154 int cucul_get_sprite_width(cucul_sprite_t const *, int); 155 int cucul_get_sprite_height(cucul_sprite_t const *, int); 156 int cucul_get_sprite_dx(cucul_sprite_t const *, int); 157 int cucul_get_sprite_dy(cucul_sprite_t const *, int); 158 void cucul_draw_sprite(cucul_canvas_t *, int, int, cucul_sprite_t const *, int); 159 void cucul_free_sprite(cucul_sprite_t *); 144 /** \defgroup frame libcucul canvas frame handling 145 * 146 * These functions provide high level routines for canvas frame insertion, 147 * removal, copying etc. 148 * 149 * @{ */ 150 unsigned int cucul_get_canvas_frame_count(cucul_canvas_t *); 151 void cucul_set_canvas_frame(cucul_canvas_t *, unsigned int); 152 void cucul_create_canvas_frame(cucul_canvas_t *, unsigned int); 153 void cucul_free_canvas_frame(cucul_canvas_t *, unsigned int); 160 154 /* @} */ 161 155 … … 167 161 * @{ */ 168 162 cucul_dither_t *cucul_create_dither(unsigned int, unsigned int, 169 170 171 163 unsigned int, unsigned int, 164 unsigned int, unsigned int, 165 unsigned int, unsigned int); 172 166 void cucul_set_dither_palette(cucul_dither_t *, 173 167 unsigned int r[], unsigned int g[], -
libcaca/trunk/cucul/cucul_internals.h
r834 r842 28 28 struct cucul_canvas 29 29 { 30 /* C ontextsize */30 /* Canvas size */ 31 31 unsigned int width, height; 32 32 33 /* Shortcut to the active frame */ 33 34 uint32_t *chars; 34 35 uint32_t *attr; 35 36 37 /* Frame information */ 38 unsigned int frame, framecount; 39 uint32_t **allchars; 40 uint32_t **allattr; 41 42 /* Painting context */ 36 43 uint16_t fgcolor; 37 44 uint16_t bgcolor; -
libcaca/trunk/cucul/sprite.c
r811 r842 13 13 14 14 /* 15 * This file contains a small framework for sprite loading and blitting.15 * This file contains a small framework for canvas frame management. 16 16 */ 17 17 … … 27 27 #include "cucul_internals.h" 28 28 29 #if !defined(_DOXYGEN_SKIP_ME) 30 struct cucul_frame 29 /** \brief Get the number of frames in a canvas. 30 * 31 * This function returns the current canvas frame count. 32 * 33 * \param cv A libcucul canvas 34 * \return The frame count 35 */ 36 unsigned int cucul_get_canvas_frame_count(cucul_canvas_t *cv) 31 37 { 32 int w, h; 33 int dx, dy; 34 char *chars; 35 int *color; 36 }; 38 return cv->framecount; 39 } 37 40 38 struct cucul_sprite 41 /** \brief Activate a given canvas frame. 42 * 43 * This function sets the active canvas frame. All subsequent drawing 44 * operations will be performed on that frame. The current painting 45 * context set by cucul_set_color() or cucul_set_truecolor() is inherited. 46 * 47 * If the frame index is outside the canvas' frame range, nothing happens. 48 * 49 * \param cv A libcucul canvas 50 * \param frame The canvas frame to activate 51 */ 52 void cucul_set_canvas_frame(cucul_canvas_t *cv, unsigned int frame) 39 53 { 40 int nf; 41 struct cucul_frame *frames; 42 }; 43 #endif 54 if(frame >= cv->framecount) 55 return; 44 56 45 /** \brief Allocate a sprite loaded from a file. 57 cv->frame = frame; 58 59 cv->chars = cv->allchars[cv->frame]; 60 cv->attr = cv->allattr[cv->frame]; 61 } 62 63 /** \brief Add a frame to a canvas. 46 64 * 47 * \param file The filename. 48 * \return The sprite, or NULL if an error occured. 65 * This function creates a new frame within the given canvas. Its contents 66 * are copied from the currently active frame. 67 * 68 * The frame index indicates where the frame should be inserted. Valid 69 * values range from 0 to the current canvas frame count. If the frame 70 * index is greater the or equals the current canvas frame count, the new 71 * frame is appended at the end of the canvas. 72 * 73 * The active frame does not change, but its index may be renumbered due 74 * to the insertion. 75 * 76 * \param cv A libcucul canvas 77 * \param frame The index where to insert the new frame 49 78 */ 50 cucul_sprite_t *cucul_load_sprite(char const *file)79 void cucul_create_canvas_frame(cucul_canvas_t *cv, unsigned int frame) 51 80 { 52 char buf[BUFSIZ]; 53 cucul_sprite_t *sprite; 54 FILE *fd; 81 unsigned int size = cv->width * cv->height * sizeof(uint32_t); 82 unsigned int f; 55 83 56 fd = fopen(file, "r"); 57 if(fd == NULL) 58 return NULL; 84 if(frame > cv->framecount) 85 frame = cv->framecount; 59 86 60 sprite = malloc(sizeof(cucul_sprite_t));61 if(sprite == NULL)62 goto sprite_alloc_failed;87 cv->framecount++; 88 cv->allchars = realloc(cv->allchars, sizeof(uint32_t *) * cv->framecount); 89 cv->allattr = realloc(cv->allattr, sizeof(uint32_t *) * cv->framecount); 63 90 64 sprite->nf = 0; 65 sprite->frames = NULL; 66 67 while(!feof(fd)) 91 for(f = cv->framecount - 1; f > frame; f--) 68 92 { 69 int x, y; 70 int w = 0, h = 0, dx = 0, dy = 0; 71 struct cucul_frame *frame; 72 73 /* Get width and height */ 74 if(!fgets(buf, BUFSIZ, fd)) 75 break; 76 77 sscanf(buf, "%i %i %i %i", &w, &h, &dx, &dy); 78 if(w <= 0 || h <= 0 || w > BUFSIZ / 2) 79 break; 80 81 if(sprite->nf) 82 { 83 void *tmp = realloc(sprite->frames, 84 (sprite->nf + 1) * sizeof(struct cucul_frame)); 85 if(tmp == NULL) 86 goto frame_failed; 87 sprite->frames = tmp; 88 sprite->nf++; 89 } 90 else 91 { 92 sprite->frames = malloc((sprite->nf + 1) * sizeof(struct cucul_frame)); 93 if(sprite->frames == NULL) 94 goto sprite_failed; 95 sprite->nf++; 96 } 97 98 frame = &sprite->frames[sprite->nf - 1]; 99 100 frame->w = w; 101 frame->h = h; 102 frame->dx = dx; 103 frame->dy = dy; 104 frame->chars = malloc(w * h * sizeof(char)); 105 if(frame->chars == NULL) 106 { 107 sprite->nf--; 108 goto frame_failed; 109 } 110 frame->color = malloc(w * h * sizeof(int)); 111 if(frame->color == NULL) 112 { 113 free(frame->chars); 114 sprite->nf--; 115 goto frame_failed; 116 } 117 118 for(y = 0; y < h; y++) 119 { 120 if(!fgets(buf, BUFSIZ, fd)) 121 goto frame_failed; 122 123 for(x = 0; x < w && buf[x] && buf[x] != '\r' && buf[x] != '\n'; x++) 124 frame->chars[w * y + x] = buf[x]; 125 126 for(; x < w; x++) 127 frame->chars[w * y + x] = ' '; 128 } 129 130 for(y = 0; y < h; y++) 131 { 132 if(!fgets(buf, BUFSIZ, fd)) 133 goto frame_failed; 134 135 for(x = 0; x < w && buf[x] && buf[x] != '\r' && buf[x] != '\n'; x++) 136 frame->color[w * y + x] = buf[x] - 'a'; 137 138 for(; x < w; x++) 139 frame->color[w * y + x] = ' ' - 'a'; 140 } 141 142 continue; 93 cv->allchars[f] = cv->allchars[f - 1]; 94 cv->allattr[f] = cv->allattr[f - 1]; 143 95 } 144 96 145 if(sprite->nf == 0) 146 goto sprite_failed; 97 cv->allchars[frame] = malloc(size); 98 memcpy(cv->allchars[frame], cv->chars, size); 99 cv->allattr[frame] = malloc(size); 100 memcpy(cv->allattr[frame], cv->attr, size); 147 101 148 fclose(fd);149 return sprite;102 if(cv->frame >= frame) 103 cv->frame++; 150 104 151 frame_failed: 152 while(sprite->nf) 153 { 154 free(sprite->frames[sprite->nf - 1].color); 155 free(sprite->frames[sprite->nf - 1].chars); 156 sprite->nf--; 157 } 158 sprite_failed: 159 free(sprite); 160 sprite_alloc_failed: 161 fclose(fd); 162 return NULL; 105 cv->chars = cv->allchars[cv->frame]; 106 cv->attr = cv->allattr[cv->frame]; 163 107 } 164 108 165 /** \brief Re turn the number of frames in a sprite.109 /** \brief Remove a frame from a canvas. 166 110 * 167 * \param sprite The sprite. 168 * \return The number of frames. 111 * This function deletes a frame from a given canvas. 112 * 113 * It is not legal to remove the last frame from a canvas. Such a request 114 * will be ignored by cucul_free_canvas_frame(). 115 * 116 * The frame index indicates the frame to delete. Valid values range from 117 * 0 to the current canvas frame count minus 1. If the frame index is 118 * greater the or equals the current canvas frame count, the last frame 119 * is deleted. 120 * 121 * If the active frame is deleted, frame 0 becomes the new active frame. 122 * Otherwise, the active frame does not change, but its index may be 123 * renumbered due to the deletion. 124 * 125 * \param cv A libcucul canvas 126 * \param frame The index of the frame to delete 169 127 */ 170 int cucul_get_sprite_frames(cucul_sprite_t const *sprite)128 void cucul_free_canvas_frame(cucul_canvas_t *cv, unsigned int frame) 171 129 { 172 if(sprite == NULL) 173 return 0; 130 unsigned int f; 174 131 175 return sprite->nf; 132 if(frame >= cv->framecount) 133 return; 134 135 if(cv->framecount == 1) 136 return; 137 138 free(cv->allchars[frame]); 139 free(cv->allattr[frame]); 140 141 for(f = frame + 1; f < cv->framecount; f++) 142 { 143 cv->allchars[f - 1] = cv->allchars[f]; 144 cv->allattr[f - 1] = cv->allattr[f]; 145 } 146 147 cv->framecount--; 148 cv->allchars = realloc(cv->allchars, sizeof(uint32_t *) * cv->framecount); 149 cv->allattr = realloc(cv->allattr, sizeof(uint32_t *) * cv->framecount); 150 151 if(cv->frame > frame) 152 cv->frame--; 153 else if(cv->frame == frame) 154 cv->frame = 0; 155 156 cv->chars = cv->allchars[cv->frame]; 157 cv->attr = cv->allattr[cv->frame]; 176 158 } 177 159 178 /** \brief Return the width of a sprite.179 *180 * \param sprite The sprite.181 * \param f The frame index.182 * \return The width of the given frame of the sprite.183 */184 int cucul_get_sprite_width(cucul_sprite_t const *sprite, int f)185 {186 if(sprite == NULL)187 return 0;188 189 if(f < 0 || f >= sprite->nf)190 return 0;191 192 return sprite->frames[f].w;193 }194 195 /** \brief Return the height of a sprite.196 *197 * \param sprite The sprite.198 * \param f The frame index.199 * \return The height of the given frame of the sprite.200 */201 int cucul_get_sprite_height(cucul_sprite_t const *sprite, int f)202 {203 if(sprite == NULL)204 return 0;205 206 if(f < 0 || f >= sprite->nf)207 return 0;208 209 return sprite->frames[f].h;210 }211 212 /** \brief Return the X coordinate of a sprite's handle.213 *214 * \param sprite The sprite.215 * \param f The frame index.216 * \return The X coordinate of the given frame's handle.217 */218 int cucul_get_sprite_dx(cucul_sprite_t const *sprite, int f)219 {220 if(sprite == NULL)221 return 0;222 223 if(f < 0 || f >= sprite->nf)224 return 0;225 226 return sprite->frames[f].dx;227 }228 229 /** \brief Return the Y coordinate of a sprite's handle.230 *231 * \param sprite The sprite.232 * \param f The frame index.233 * \return The Y coordinate of the given frame's handle.234 */235 int cucul_get_sprite_dy(cucul_sprite_t const *sprite, int f)236 {237 if(sprite == NULL)238 return 0;239 240 if(f < 0 || f >= sprite->nf)241 return 0;242 243 return sprite->frames[f].dy;244 }245 246 /** \brief Draw a sprite's specific frame at the given coordinates. If the247 * frame does not exist, nothing is displayed.248 *249 * \param cv A libcucul canvas250 * \param x The X coordinate.251 * \param y The Y coordinate.252 * \param sprite The sprite.253 * \param f The frame index.254 * \return void255 */256 void cucul_draw_sprite(cucul_canvas_t *cv, int x, int y,257 cucul_sprite_t const *sprite, int f)258 {259 int i, j;260 unsigned int oldfg, oldbg;261 struct cucul_frame *frame;262 263 if(sprite == NULL)264 return;265 266 if(f < 0 || f >= sprite->nf)267 return;268 269 frame = &sprite->frames[f];270 271 oldfg = cv->fgcolor;272 oldbg = cv->bgcolor;273 274 for(j = 0; j < frame->h; j++)275 {276 for(i = 0; i < frame->w; i++)277 {278 int col = frame->color[frame->w * j + i];279 if(col >= 0)280 {281 cucul_set_color(cv, col, CUCUL_COLOR_BLACK);282 cucul_putchar(cv, x + i - frame->dx, y + j - frame->dy,283 frame->chars[frame->w * j + i]);284 }285 }286 }287 288 cucul_set_color(cv, oldfg, oldbg);289 }290 291 /** \brief Free the memory associated with a sprite.292 *293 * \param sprite The sprite to be freed.294 * \return void295 */296 void cucul_free_sprite(cucul_sprite_t *sprite)297 {298 int i;299 300 if(sprite == NULL)301 return;302 303 for(i = sprite->nf; i--;)304 {305 struct cucul_frame *frame = &sprite->frames[i];306 free(frame->chars);307 free(frame->color);308 }309 310 free(sprite->frames);311 free(sprite);312 }313
Note: See TracChangeset
for help on using the changeset viewer.