/*=======================================*\
| ____ ____ |
| / \ /\ | |
| \____ / \ |____ |
| \ /____\ | |
| \____/prite / \nimation |____ditor |
| |
| Copyleft Vasily_Makarov 2011 |
| |
\*=======================================*/
#include "sae.h"
void kill_timeout(guint tag) {
if (tag > 0)
g_source_remove(tag);
}
Frame *frame_new(int index1, int offsetX, int offsetY, int delay) {
Frame *res = g_new0(Frame, 1);
res->index = index1;
res->offsetX = offsetX;
res->offsetY = offsetY;
res->delay = delay;
return res;
}
Imageset *imageset_new() {
Imageset *res = g_new0(Imageset, 1);
res->width = SPRITE_WIDTH_DEFAULT;
res->height = SPRITE_HEIGHT_DEFAULT;
return res;
}
SAEInfo *sae_info_new() {
SAEInfo *res = g_new0(SAEInfo, 1);
res->ground = sae_info_ground_new();
res->sprite = frame_new(-1, 0, 0, 0);
res->imageset = imageset_new();
return res;
}
GdkPixbuf *sae_info_ground_new() {
GdkPixbuf *ground = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, GRID_SIZE * 3, GRID_SIZE * 3);
gdk_pixbuf_fill(ground, 0x00000000);
return ground;
}
GdkPixbuf* get_sprite_by_index(int index1, SAEInfo *sae_info) {
if (index1 == -1) {
GdkPixbuf *res = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
sae_info->imageset->width,
sae_info->imageset->height);
gdk_pixbuf_fill(res, 0x00000000);
return res;
}
if (index1 >= 0) {
size_t w = sae_info->imageset->spriteset_width/sae_info->imageset->width;
if (sae_info->imageset->spriteset == NULL) return NULL;
return gdk_pixbuf_new_subpixbuf(sae_info->imageset->spriteset,
index1%w*sae_info->imageset->width,
index1/w*sae_info->imageset->height,
sae_info->imageset->width,
sae_info->imageset->height);
}
return NULL;
}
inline void _add_frame(SAEInfo *sae_info, int index1, int offsetX, int offsetY, int delay, int line) {
Frame *sprite = frame_new(index1, offsetX, offsetY, delay);
sprite->line_number = line;
sprite->pixbuf = get_sprite_by_index(index1, sae_info);
if (sae_info->animation != NULL)
sae_info->animation = g_list_append(sae_info->animation, sprite);
else {
sae_info->animation = g_list_alloc();
sae_info->animation->data = sprite;
}
}
gboolean set_up_animation_by_direction(SAEInfo *sae_info, const gchar *direction) {
if (sae_info->imageset->spriteset == NULL)
return FALSE;
sae_info->animation = NULL;
GList *list = g_list_find_custom(sae_info->animations,
xml_attr_new("direction", direction),
(GCompareFunc)xml_node_compare_with_attr_func);
if (list == NULL)
return FALSE;
XMLNode *anode = list->data;
list = anode->sub_nodes;
while (list != NULL) {
XMLNode *node = list->data;
//sequence tag attributes
int offsetX = 0, offsetY = 0,
delay = 0,
start = -1, end = -1,
repeat = 1;
gchar *value = NULL;
gchar *ofX_attr, *ofY_attr;
ofX_attr = xml_node_get_attr_value(node, "offsetX");
if (ofX_attr != NULL)
sscanf(ofX_attr, "%d", &offsetX);
ofY_attr = xml_node_get_attr_value(node, "offsetY");
if (ofY_attr != NULL)
sscanf(ofY_attr, "%d", &offsetY);
gchar *delay_attr = xml_node_get_attr_value(node, "delay");
if (delay_attr != NULL)
sscanf(delay_attr, "%d", &delay);
if (g_str_equal(node->name, "frame")) {
gchar *index_attr = xml_node_get_attr_value(node, "index");
if (index_attr != NULL) {
sscanf(index_attr, "%d", &start);
end = start;
}
} else if (g_str_equal(node->name, "sequence")) {
gchar *start_attr = xml_node_get_attr_value(node, "start");
if (start_attr != NULL)
sscanf(start_attr, "%d", &start);
gchar *end_attr = xml_node_get_attr_value(node, "end");
if (end_attr != NULL)
sscanf(end_attr, "%d", &end);
value = xml_node_get_attr_value(node, "value");
gchar *repeat_attr = xml_node_get_attr_value(node, "repeat");
if (repeat_attr != NULL)
sscanf(repeat_attr, "%d", &repeat);
} else if (g_str_equal(node->name, "pause")) {
value = (gchar *)"p";
gchar *repeat_attr = xml_node_get_attr_value(node, "repeat");
if (repeat_attr != NULL)
sscanf(repeat_attr, "%d", &repeat);
}
if (start >= 0) { //start-end case
int r = 0, i = 0;
for (r = 1; r <= repeat; r++) {
for (i = start; i <= end; i++) {
_add_frame(sae_info, i, offsetX, offsetY, delay, node->line_number);
}
}
} else
if (value != NULL) { //value case
gchar **values = g_strsplit(value, ",", 0);
int r;
for (r = 0; r < repeat; r++) { //TODO: remove multiparsing
gchar **iter = values;
while (*iter != NULL) {
if (g_str_equal(*iter, "p")) { //pause
_add_frame(sae_info, -1, 0, 0, delay, node->line_number);
} else {
unsigned f, s;
if (sscanf(*iter, "%u-%u", &f, &s) == 2) {
int i;
for (i = f; i <= s; i++) {
_add_frame(sae_info, i, offsetX, offsetY, delay, node->line_number);
}
} else if (sscanf(*iter, "%u", &f) == 1) {
_add_frame(sae_info, f, offsetX, offsetY, delay, node->line_number);
}
}
iter++;
}
}
g_strfreev(values);
}
list = g_list_next(list);
}
if (sae_info->animation == NULL)
return FALSE;
return TRUE;
}