@@ -54,6 +54,13 @@ cucul_canvas_t * cucul_create_canvas(unsigned int width, unsigned int height) | |||||
cv->chars = NULL; | cv->chars = NULL; | ||||
cv->attr = NULL; | cv->attr = NULL; | ||||
cv->frame = 0; | |||||
cv->framecount = 1; | |||||
cv->allchars = malloc(sizeof(uint32_t *)); | |||||
cv->allattr = malloc(sizeof(uint32_t *)); | |||||
cv->allchars[0] = NULL; | |||||
cv->allattr[0] = NULL; | |||||
/* Initialise to a default size. 80x32 is arbitrary but matches AAlib's | /* Initialise to a default size. 80x32 is arbitrary but matches AAlib's | ||||
* default X11 window. When a graphic driver attaches to us, it can set | * default X11 window. When a graphic driver attaches to us, it can set | ||||
* a different size. */ | * a different size. */ | ||||
@@ -169,10 +176,15 @@ char const *cucul_get_color_name(unsigned int color) | |||||
*/ | */ | ||||
void cucul_free_canvas(cucul_canvas_t *cv) | void cucul_free_canvas(cucul_canvas_t *cv) | ||||
{ | { | ||||
unsigned int f; | |||||
_cucul_end_dither(); | _cucul_end_dither(); | ||||
free(cv->chars); | |||||
free(cv->attr); | |||||
for(f = 0; f < cv->framecount; f++) | |||||
{ | |||||
free(cv->allchars[f]); | |||||
free(cv->allattr[f]); | |||||
} | |||||
free(cv); | free(cv); | ||||
} | } | ||||
@@ -196,7 +208,7 @@ int cucul_rand(int min, int max) | |||||
void _cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width, | void _cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width, | ||||
unsigned int height) | unsigned int height) | ||||
{ | { | ||||
unsigned int x, y, old_width, old_height, new_size, old_size; | |||||
unsigned int x, y, f, old_width, old_height, new_size, old_size; | |||||
old_width = cv->width; | old_width = cv->width; | ||||
old_height = cv->height; | old_height = cv->height; | ||||
@@ -209,8 +221,13 @@ void _cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width, | |||||
/* Step 1: if new area is bigger, resize the memory area now. */ | /* Step 1: if new area is bigger, resize the memory area now. */ | ||||
if(new_size > old_size) | if(new_size > old_size) | ||||
{ | { | ||||
cv->chars = realloc(cv->chars, new_size * sizeof(uint32_t)); | |||||
cv->attr = realloc(cv->attr, new_size * sizeof(uint32_t)); | |||||
for(f = 0; f < cv->framecount; f++) | |||||
{ | |||||
cv->allchars[f] = realloc(cv->allchars[f], | |||||
new_size * sizeof(uint32_t)); | |||||
cv->allattr[f] = realloc(cv->allattr[f], | |||||
new_size * sizeof(uint32_t)); | |||||
} | |||||
} | } | ||||
/* Step 2: move line data if necessary. */ | /* Step 2: move line data if necessary. */ | ||||
@@ -224,19 +241,25 @@ void _cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width, | |||||
/* New width is bigger than old width, which means we need to | /* New width is bigger than old width, which means we need to | ||||
* copy lines starting from the bottom of the screen otherwise | * copy lines starting from the bottom of the screen otherwise | ||||
* we will overwrite information. */ | * we will overwrite information. */ | ||||
for(y = height < old_height ? height : old_height; y--; ) | |||||
for(f = 0; f < cv->framecount; f++) | |||||
{ | { | ||||
for(x = old_width; x--; ) | |||||
uint32_t *chars = cv->allchars[f]; | |||||
uint32_t *attr = cv->allattr[f]; | |||||
for(y = height < old_height ? height : old_height; y--; ) | |||||
{ | { | ||||
cv->chars[y * width + x] = cv->chars[y * old_width + x]; | |||||
cv->attr[y * width + x] = cv->attr[y * old_width + x]; | |||||
for(x = old_width; x--; ) | |||||
{ | |||||
chars[y * width + x] = chars[y * old_width + x]; | |||||
attr[y * width + x] = attr[y * old_width + x]; | |||||
} | |||||
/* Zero the end of the line */ | |||||
for(x = width - old_width; x--; ) | |||||
chars[y * width + old_width + x] = (uint32_t)' '; | |||||
memset(attr + y * width + old_width, 0, | |||||
(width - old_width) * 4); | |||||
} | } | ||||
/* Zero the end of the line */ | |||||
for(x = width - old_width; x--; ) | |||||
cv->chars[y * width + old_width + x] = (uint32_t)' '; | |||||
memset(cv->attr + y * width + old_width, 0, | |||||
(width - old_width) * 4); | |||||
} | } | ||||
} | } | ||||
else | else | ||||
@@ -245,12 +268,18 @@ void _cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width, | |||||
* the first line, it is already in place. */ | * the first line, it is already in place. */ | ||||
unsigned int lines = height < old_height ? height : old_height; | unsigned int lines = height < old_height ? height : old_height; | ||||
for(y = 1; y < lines; y++) | |||||
for(f = 0; f < cv->framecount; f++) | |||||
{ | { | ||||
for(x = 0; x < width; x++) | |||||
uint32_t *chars = cv->allchars[f]; | |||||
uint32_t *attr = cv->allattr[f]; | |||||
for(y = 1; y < lines; y++) | |||||
{ | { | ||||
cv->chars[y * width + x] = cv->chars[y * old_width + x]; | |||||
cv->attr[y * width + x] = cv->attr[y * old_width + x]; | |||||
for(x = 0; x < width; x++) | |||||
{ | |||||
chars[y * width + x] = chars[y * old_width + x]; | |||||
attr[y * width + x] = attr[y * old_width + x]; | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -258,18 +287,33 @@ void _cucul_set_canvas_size(cucul_canvas_t *cv, unsigned int width, | |||||
/* Step 3: fill the bottom of the new screen if necessary. */ | /* Step 3: fill the bottom of the new screen if necessary. */ | ||||
if(height > old_height) | if(height > old_height) | ||||
{ | { | ||||
/* Zero the bottom of the screen */ | |||||
for(x = (height - old_height) * width; x--; ) | |||||
cv->chars[old_height * width + x] = (uint32_t)' '; | |||||
memset(cv->attr + old_height * width, 0, | |||||
(height - old_height) * width * 4); | |||||
for(f = 0; f < cv->framecount; f++) | |||||
{ | |||||
uint32_t *chars = cv->allchars[f]; | |||||
uint32_t *attr = cv->allattr[f]; | |||||
/* Zero the bottom of the screen */ | |||||
for(x = (height - old_height) * width; x--; ) | |||||
chars[old_height * width + x] = (uint32_t)' '; | |||||
memset(attr + old_height * width, 0, | |||||
(height - old_height) * width * 4); | |||||
} | |||||
} | } | ||||
/* Step 4: if new area is smaller, resize memory area now. */ | /* Step 4: if new area is smaller, resize memory area now. */ | ||||
if(new_size <= old_size) | if(new_size <= old_size) | ||||
{ | { | ||||
cv->chars = realloc(cv->chars, new_size * sizeof(uint32_t)); | |||||
cv->attr = realloc(cv->attr, new_size * sizeof(uint32_t)); | |||||
for(f = 0; f < cv->framecount; f++) | |||||
{ | |||||
cv->allchars[f] = realloc(cv->allchars[f], | |||||
new_size * sizeof(uint32_t)); | |||||
cv->allattr[f] = realloc(cv->allattr[f], | |||||
new_size * sizeof(uint32_t)); | |||||
} | |||||
} | } | ||||
/* Reset the current frame shortcut */ | |||||
cv->chars = cv->allchars[cv->frame]; | |||||
cv->attr = cv->allattr[cv->frame]; | |||||
} | } | ||||
@@ -33,8 +33,6 @@ extern "C" | |||||
/** \e libcucul context */ | /** \e libcucul context */ | ||||
typedef struct cucul_canvas cucul_canvas_t; | typedef struct cucul_canvas cucul_canvas_t; | ||||
/** sprite structure */ | |||||
typedef struct cucul_sprite cucul_sprite_t; | |||||
/** dither structure */ | /** dither structure */ | ||||
typedef struct cucul_dither cucul_dither_t; | typedef struct cucul_dither cucul_dither_t; | ||||
/** data buffer structure */ | /** data buffer structure */ | ||||
@@ -143,20 +141,16 @@ void cucul_draw_thin_triangle(cucul_canvas_t *, int, int, int, int, int, int); | |||||
void cucul_fill_triangle(cucul_canvas_t *, int, int, int, int, int, int, char const *); | void cucul_fill_triangle(cucul_canvas_t *, int, int, int, int, int, int, char const *); | ||||
/* @} */ | /* @} */ | ||||
/** \defgroup sprite libcucul sprite handling | |||||
/** \defgroup frame libcucul canvas frame handling | |||||
* | * | ||||
* These functions provide high level routines for sprite loading, animation | |||||
* and rendering. | |||||
* These functions provide high level routines for canvas frame insertion, | |||||
* removal, copying etc. | |||||
* | * | ||||
* @{ */ | * @{ */ | ||||
cucul_sprite_t * cucul_load_sprite(char const *); | |||||
int cucul_get_sprite_frames(cucul_sprite_t const *); | |||||
int cucul_get_sprite_width(cucul_sprite_t const *, int); | |||||
int cucul_get_sprite_height(cucul_sprite_t const *, int); | |||||
int cucul_get_sprite_dx(cucul_sprite_t const *, int); | |||||
int cucul_get_sprite_dy(cucul_sprite_t const *, int); | |||||
void cucul_draw_sprite(cucul_canvas_t *, int, int, cucul_sprite_t const *, int); | |||||
void cucul_free_sprite(cucul_sprite_t *); | |||||
unsigned int cucul_get_canvas_frame_count(cucul_canvas_t *); | |||||
void cucul_set_canvas_frame(cucul_canvas_t *, unsigned int); | |||||
void cucul_create_canvas_frame(cucul_canvas_t *, unsigned int); | |||||
void cucul_free_canvas_frame(cucul_canvas_t *, unsigned int); | |||||
/* @} */ | /* @} */ | ||||
/** \defgroup dither libcucul bitmap dithering | /** \defgroup dither libcucul bitmap dithering | ||||
@@ -166,9 +160,9 @@ void cucul_free_sprite(cucul_sprite_t *); | |||||
* | * | ||||
* @{ */ | * @{ */ | ||||
cucul_dither_t *cucul_create_dither(unsigned int, unsigned int, | cucul_dither_t *cucul_create_dither(unsigned int, unsigned int, | ||||
unsigned int, unsigned int, | |||||
unsigned int, unsigned int, | |||||
unsigned int, unsigned int); | |||||
unsigned int, unsigned int, | |||||
unsigned int, unsigned int, | |||||
unsigned int, unsigned int); | |||||
void cucul_set_dither_palette(cucul_dither_t *, | void cucul_set_dither_palette(cucul_dither_t *, | ||||
unsigned int r[], unsigned int g[], | unsigned int r[], unsigned int g[], | ||||
unsigned int b[], unsigned int a[]); | unsigned int b[], unsigned int a[]); | ||||
@@ -27,12 +27,19 @@ typedef long unsigned int uintptr_t; | |||||
struct cucul_canvas | struct cucul_canvas | ||||
{ | { | ||||
/* Context size */ | |||||
/* Canvas size */ | |||||
unsigned int width, height; | unsigned int width, height; | ||||
/* Shortcut to the active frame */ | |||||
uint32_t *chars; | uint32_t *chars; | ||||
uint32_t *attr; | uint32_t *attr; | ||||
/* Frame information */ | |||||
unsigned int frame, framecount; | |||||
uint32_t **allchars; | |||||
uint32_t **allattr; | |||||
/* Painting context */ | |||||
uint16_t fgcolor; | uint16_t fgcolor; | ||||
uint16_t bgcolor; | uint16_t bgcolor; | ||||
@@ -12,7 +12,7 @@ | |||||
*/ | */ | ||||
/* | /* | ||||
* This file contains a small framework for sprite loading and blitting. | |||||
* This file contains a small framework for canvas frame management. | |||||
*/ | */ | ||||
#include "config.h" | #include "config.h" | ||||
@@ -26,288 +26,134 @@ | |||||
#include "cucul.h" | #include "cucul.h" | ||||
#include "cucul_internals.h" | #include "cucul_internals.h" | ||||
#if !defined(_DOXYGEN_SKIP_ME) | |||||
struct cucul_frame | |||||
{ | |||||
int w, h; | |||||
int dx, dy; | |||||
char *chars; | |||||
int *color; | |||||
}; | |||||
struct cucul_sprite | |||||
{ | |||||
int nf; | |||||
struct cucul_frame *frames; | |||||
}; | |||||
#endif | |||||
/** \brief Allocate a sprite loaded from a file. | |||||
/** \brief Get the number of frames in a canvas. | |||||
* | * | ||||
* \param file The filename. | |||||
* \return The sprite, or NULL if an error occured. | |||||
*/ | |||||
cucul_sprite_t *cucul_load_sprite(char const *file) | |||||
{ | |||||
char buf[BUFSIZ]; | |||||
cucul_sprite_t *sprite; | |||||
FILE *fd; | |||||
fd = fopen(file, "r"); | |||||
if(fd == NULL) | |||||
return NULL; | |||||
sprite = malloc(sizeof(cucul_sprite_t)); | |||||
if(sprite == NULL) | |||||
goto sprite_alloc_failed; | |||||
sprite->nf = 0; | |||||
sprite->frames = NULL; | |||||
while(!feof(fd)) | |||||
{ | |||||
int x, y; | |||||
int w = 0, h = 0, dx = 0, dy = 0; | |||||
struct cucul_frame *frame; | |||||
/* Get width and height */ | |||||
if(!fgets(buf, BUFSIZ, fd)) | |||||
break; | |||||
sscanf(buf, "%i %i %i %i", &w, &h, &dx, &dy); | |||||
if(w <= 0 || h <= 0 || w > BUFSIZ / 2) | |||||
break; | |||||
if(sprite->nf) | |||||
{ | |||||
void *tmp = realloc(sprite->frames, | |||||
(sprite->nf + 1) * sizeof(struct cucul_frame)); | |||||
if(tmp == NULL) | |||||
goto frame_failed; | |||||
sprite->frames = tmp; | |||||
sprite->nf++; | |||||
} | |||||
else | |||||
{ | |||||
sprite->frames = malloc((sprite->nf + 1) * sizeof(struct cucul_frame)); | |||||
if(sprite->frames == NULL) | |||||
goto sprite_failed; | |||||
sprite->nf++; | |||||
} | |||||
frame = &sprite->frames[sprite->nf - 1]; | |||||
frame->w = w; | |||||
frame->h = h; | |||||
frame->dx = dx; | |||||
frame->dy = dy; | |||||
frame->chars = malloc(w * h * sizeof(char)); | |||||
if(frame->chars == NULL) | |||||
{ | |||||
sprite->nf--; | |||||
goto frame_failed; | |||||
} | |||||
frame->color = malloc(w * h * sizeof(int)); | |||||
if(frame->color == NULL) | |||||
{ | |||||
free(frame->chars); | |||||
sprite->nf--; | |||||
goto frame_failed; | |||||
} | |||||
for(y = 0; y < h; y++) | |||||
{ | |||||
if(!fgets(buf, BUFSIZ, fd)) | |||||
goto frame_failed; | |||||
for(x = 0; x < w && buf[x] && buf[x] != '\r' && buf[x] != '\n'; x++) | |||||
frame->chars[w * y + x] = buf[x]; | |||||
for(; x < w; x++) | |||||
frame->chars[w * y + x] = ' '; | |||||
} | |||||
for(y = 0; y < h; y++) | |||||
{ | |||||
if(!fgets(buf, BUFSIZ, fd)) | |||||
goto frame_failed; | |||||
for(x = 0; x < w && buf[x] && buf[x] != '\r' && buf[x] != '\n'; x++) | |||||
frame->color[w * y + x] = buf[x] - 'a'; | |||||
for(; x < w; x++) | |||||
frame->color[w * y + x] = ' ' - 'a'; | |||||
} | |||||
continue; | |||||
} | |||||
if(sprite->nf == 0) | |||||
goto sprite_failed; | |||||
fclose(fd); | |||||
return sprite; | |||||
frame_failed: | |||||
while(sprite->nf) | |||||
{ | |||||
free(sprite->frames[sprite->nf - 1].color); | |||||
free(sprite->frames[sprite->nf - 1].chars); | |||||
sprite->nf--; | |||||
} | |||||
sprite_failed: | |||||
free(sprite); | |||||
sprite_alloc_failed: | |||||
fclose(fd); | |||||
return NULL; | |||||
} | |||||
/** \brief Return the number of frames in a sprite. | |||||
* This function returns the current canvas frame count. | |||||
* | * | ||||
* \param sprite The sprite. | |||||
* \return The number of frames. | |||||
* \param cv A libcucul canvas | |||||
* \return The frame count | |||||
*/ | */ | ||||
int cucul_get_sprite_frames(cucul_sprite_t const *sprite) | |||||
unsigned int cucul_get_canvas_frame_count(cucul_canvas_t *cv) | |||||
{ | { | ||||
if(sprite == NULL) | |||||
return 0; | |||||
return sprite->nf; | |||||
return cv->framecount; | |||||
} | } | ||||
/** \brief Return the width of a sprite. | |||||
/** \brief Activate a given canvas frame. | |||||
* | * | ||||
* \param sprite The sprite. | |||||
* \param f The frame index. | |||||
* \return The width of the given frame of the sprite. | |||||
*/ | |||||
int cucul_get_sprite_width(cucul_sprite_t const *sprite, int f) | |||||
{ | |||||
if(sprite == NULL) | |||||
return 0; | |||||
if(f < 0 || f >= sprite->nf) | |||||
return 0; | |||||
return sprite->frames[f].w; | |||||
} | |||||
/** \brief Return the height of a sprite. | |||||
* This function sets the active canvas frame. All subsequent drawing | |||||
* operations will be performed on that frame. The current painting | |||||
* context set by cucul_set_color() or cucul_set_truecolor() is inherited. | |||||
* | |||||
* If the frame index is outside the canvas' frame range, nothing happens. | |||||
* | * | ||||
* \param sprite The sprite. | |||||
* \param f The frame index. | |||||
* \return The height of the given frame of the sprite. | |||||
* \param cv A libcucul canvas | |||||
* \param frame The canvas frame to activate | |||||
*/ | */ | ||||
int cucul_get_sprite_height(cucul_sprite_t const *sprite, int f) | |||||
void cucul_set_canvas_frame(cucul_canvas_t *cv, unsigned int frame) | |||||
{ | { | ||||
if(sprite == NULL) | |||||
return 0; | |||||
if(frame >= cv->framecount) | |||||
return; | |||||
if(f < 0 || f >= sprite->nf) | |||||
return 0; | |||||
cv->frame = frame; | |||||
return sprite->frames[f].h; | |||||
cv->chars = cv->allchars[cv->frame]; | |||||
cv->attr = cv->allattr[cv->frame]; | |||||
} | } | ||||
/** \brief Return the X coordinate of a sprite's handle. | |||||
/** \brief Add a frame to a canvas. | |||||
* | * | ||||
* \param sprite The sprite. | |||||
* \param f The frame index. | |||||
* \return The X coordinate of the given frame's handle. | |||||
* This function creates a new frame within the given canvas. Its contents | |||||
* are copied from the currently active frame. | |||||
* | |||||
* The frame index indicates where the frame should be inserted. Valid | |||||
* values range from 0 to the current canvas frame count. If the frame | |||||
* index is greater the or equals the current canvas frame count, the new | |||||
* frame is appended at the end of the canvas. | |||||
* | |||||
* The active frame does not change, but its index may be renumbered due | |||||
* to the insertion. | |||||
* | |||||
* \param cv A libcucul canvas | |||||
* \param frame The index where to insert the new frame | |||||
*/ | */ | ||||
int cucul_get_sprite_dx(cucul_sprite_t const *sprite, int f) | |||||
void cucul_create_canvas_frame(cucul_canvas_t *cv, unsigned int frame) | |||||
{ | { | ||||
if(sprite == NULL) | |||||
return 0; | |||||
unsigned int size = cv->width * cv->height * sizeof(uint32_t); | |||||
unsigned int f; | |||||
if(f < 0 || f >= sprite->nf) | |||||
return 0; | |||||
if(frame > cv->framecount) | |||||
frame = cv->framecount; | |||||
return sprite->frames[f].dx; | |||||
} | |||||
cv->framecount++; | |||||
cv->allchars = realloc(cv->allchars, sizeof(uint32_t *) * cv->framecount); | |||||
cv->allattr = realloc(cv->allattr, sizeof(uint32_t *) * cv->framecount); | |||||
/** \brief Return the Y coordinate of a sprite's handle. | |||||
* | |||||
* \param sprite The sprite. | |||||
* \param f The frame index. | |||||
* \return The Y coordinate of the given frame's handle. | |||||
*/ | |||||
int cucul_get_sprite_dy(cucul_sprite_t const *sprite, int f) | |||||
{ | |||||
if(sprite == NULL) | |||||
return 0; | |||||
for(f = cv->framecount - 1; f > frame; f--) | |||||
{ | |||||
cv->allchars[f] = cv->allchars[f - 1]; | |||||
cv->allattr[f] = cv->allattr[f - 1]; | |||||
} | |||||
cv->allchars[frame] = malloc(size); | |||||
memcpy(cv->allchars[frame], cv->chars, size); | |||||
cv->allattr[frame] = malloc(size); | |||||
memcpy(cv->allattr[frame], cv->attr, size); | |||||
if(f < 0 || f >= sprite->nf) | |||||
return 0; | |||||
if(cv->frame >= frame) | |||||
cv->frame++; | |||||
return sprite->frames[f].dy; | |||||
cv->chars = cv->allchars[cv->frame]; | |||||
cv->attr = cv->allattr[cv->frame]; | |||||
} | } | ||||
/** \brief Draw a sprite's specific frame at the given coordinates. If the | |||||
* frame does not exist, nothing is displayed. | |||||
/** \brief Remove a frame from a canvas. | |||||
* | |||||
* This function deletes a frame from a given canvas. | |||||
* | |||||
* It is not legal to remove the last frame from a canvas. Such a request | |||||
* will be ignored by cucul_free_canvas_frame(). | |||||
* | |||||
* The frame index indicates the frame to delete. Valid values range from | |||||
* 0 to the current canvas frame count minus 1. If the frame index is | |||||
* greater the or equals the current canvas frame count, the last frame | |||||
* is deleted. | |||||
* | |||||
* If the active frame is deleted, frame 0 becomes the new active frame. | |||||
* Otherwise, the active frame does not change, but its index may be | |||||
* renumbered due to the deletion. | |||||
* | * | ||||
* \param cv A libcucul canvas | * \param cv A libcucul canvas | ||||
* \param x The X coordinate. | |||||
* \param y The Y coordinate. | |||||
* \param sprite The sprite. | |||||
* \param f The frame index. | |||||
* \return void | |||||
* \param frame The index of the frame to delete | |||||
*/ | */ | ||||
void cucul_draw_sprite(cucul_canvas_t *cv, int x, int y, | |||||
cucul_sprite_t const *sprite, int f) | |||||
void cucul_free_canvas_frame(cucul_canvas_t *cv, unsigned int frame) | |||||
{ | { | ||||
int i, j; | |||||
unsigned int oldfg, oldbg; | |||||
struct cucul_frame *frame; | |||||
unsigned int f; | |||||
if(sprite == NULL) | |||||
if(frame >= cv->framecount) | |||||
return; | return; | ||||
if(f < 0 || f >= sprite->nf) | |||||
if(cv->framecount == 1) | |||||
return; | return; | ||||
frame = &sprite->frames[f]; | |||||
free(cv->allchars[frame]); | |||||
free(cv->allattr[frame]); | |||||
oldfg = cv->fgcolor; | |||||
oldbg = cv->bgcolor; | |||||
for(j = 0; j < frame->h; j++) | |||||
for(f = frame + 1; f < cv->framecount; f++) | |||||
{ | { | ||||
for(i = 0; i < frame->w; i++) | |||||
{ | |||||
int col = frame->color[frame->w * j + i]; | |||||
if(col >= 0) | |||||
{ | |||||
cucul_set_color(cv, col, CUCUL_COLOR_BLACK); | |||||
cucul_putchar(cv, x + i - frame->dx, y + j - frame->dy, | |||||
frame->chars[frame->w * j + i]); | |||||
} | |||||
} | |||||
cv->allchars[f - 1] = cv->allchars[f]; | |||||
cv->allattr[f - 1] = cv->allattr[f]; | |||||
} | } | ||||
cucul_set_color(cv, oldfg, oldbg); | |||||
} | |||||
cv->framecount--; | |||||
cv->allchars = realloc(cv->allchars, sizeof(uint32_t *) * cv->framecount); | |||||
cv->allattr = realloc(cv->allattr, sizeof(uint32_t *) * cv->framecount); | |||||
/** \brief Free the memory associated with a sprite. | |||||
* | |||||
* \param sprite The sprite to be freed. | |||||
* \return void | |||||
*/ | |||||
void cucul_free_sprite(cucul_sprite_t *sprite) | |||||
{ | |||||
int i; | |||||
if(sprite == NULL) | |||||
return; | |||||
for(i = sprite->nf; i--;) | |||||
{ | |||||
struct cucul_frame *frame = &sprite->frames[i]; | |||||
free(frame->chars); | |||||
free(frame->color); | |||||
} | |||||
if(cv->frame > frame) | |||||
cv->frame--; | |||||
else if(cv->frame == frame) | |||||
cv->frame = 0; | |||||
free(sprite->frames); | |||||
free(sprite); | |||||
cv->chars = cv->allchars[cv->frame]; | |||||
cv->attr = cv->allattr[cv->frame]; | |||||
} | } | ||||