652 lines
21 KiB
C
652 lines
21 KiB
C
#include "State_Animator.h"
|
|
#include "state.h"
|
|
#include "report.h"
|
|
#include "globals.h"
|
|
#include "render.h"
|
|
|
|
#include "AnimData.h"
|
|
#include "string.h"
|
|
|
|
#include "fifo.h"
|
|
|
|
#include <dirent.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
/*
|
|
+-------------------------------------------+
|
|
|List | anim |list|list |
|
|
| of | box |of |of |
|
|
|Anims |-------+sets+faces |
|
|
| |list |tags |
|
|
| |of |for |
|
|
| |frames |frames |
|
|
| | | |
|
|
|init|rebuild|delete| | |del|insert|apply| |
|
|
+-------------------------------------------+
|
|
*/
|
|
|
|
int openAnimatorState() {
|
|
anim_window = newBox(16, 16, g_v_width-32, g_v_height-32, 0);
|
|
// left-hand
|
|
anim_list = newList(ui_colors);
|
|
anim_list->box.x = anim_window->x;
|
|
anim_list->box.y = anim_window->y;
|
|
anim_list->box.w = anim_window->w/2;
|
|
anim_list->box.h = anim_window->h;
|
|
anim_init = newButton(&g_medium_glyphs, button_colors, "init");
|
|
anim_init->box.x = anim_window->x + 8;
|
|
anim_init->box.y = anim_list->box.h - 8;
|
|
anim_buttons[0] = anim_init;
|
|
anim_rebuild = newButton(&g_medium_glyphs, button_colors, "rebuild");
|
|
anim_rebuild->box.x = anim_init->box.x + anim_init->box.w + 8;
|
|
anim_rebuild->box.y = anim_list->box.h - 8;
|
|
anim_buttons[1] = anim_rebuild;
|
|
anim_delete = newButton(&g_medium_glyphs, button_colors, "delete");
|
|
anim_delete->box.x = anim_rebuild->box.x + anim_rebuild->box.w + 8;
|
|
anim_delete->box.y = anim_list->box.h - 8;
|
|
anim_buttons[2] = anim_delete;
|
|
//
|
|
int offset_x = anim_window->x + anim_window->w/2;
|
|
int offset_y = anim_window->y;
|
|
// right-hand
|
|
anim_box = newBox(offset_x, offset_y, 128, 128, 0);
|
|
// animation save, play, and stop controls
|
|
anim_play = newButton(&g_medium_glyphs, button_colors, "play");
|
|
anim_play->box.x = offset_x + anim_box->w+2;
|
|
anim_play->box.y = offset_y;
|
|
anim_buttons[3] = anim_play;
|
|
offset_y += anim_play->box.h+2;
|
|
anim_stop = newButton(&g_medium_glyphs, button_colors, "stop");
|
|
anim_stop->box.x = offset_x + anim_box->w+2;
|
|
anim_stop->box.y = offset_y;
|
|
anim_buttons[4] = anim_stop;
|
|
offset_y += anim_stop->box.h+12;
|
|
anim_save = newButton(&g_medium_glyphs, button_colors, "save");
|
|
anim_save->box.x = offset_x + anim_box->w;
|
|
anim_save->box.y = offset_y;
|
|
anim_buttons[5] = anim_save;
|
|
|
|
|
|
offset_y = anim_box->h;
|
|
//offset_x += anim_box->w + 2;
|
|
anim_sets = newList(button_colors);
|
|
anim_sets->box.x = offset_x;
|
|
anim_sets->box.y = offset_y;
|
|
anim_sets->box.w = ((anim_window->w/2) - anim_box->w)/4;
|
|
anim_sets->box.h = anim_box->h;
|
|
offset_x += anim_sets->box.w + 2;
|
|
anim_faces = newList(ui_colors);
|
|
anim_faces->box.x = offset_x;
|
|
anim_faces->box.y = offset_y;
|
|
anim_faces->box.w = anim_sets->box.w;
|
|
anim_faces->box.h = anim_box->h;
|
|
offset_x += anim_faces->box.w + 2;
|
|
|
|
anim_frames_box = newBox(offset_x, offset_y, anim_sets->box.w, anim_window->h-anim_box->h, 0);
|
|
anim_frames = malloc(1);
|
|
anim_frames_count = 0;
|
|
anim_frames_offset = 0;
|
|
offset_x += anim_frames_box->w;
|
|
|
|
anim_frames_i_box = newBox(offset_x, offset_y, anim_sets->box.w, anim_frames_box->h, 0);
|
|
anim_frames_input = malloc(1);
|
|
|
|
// NULL out pointers
|
|
anim_button = NULL;
|
|
anim_list_item = NULL;
|
|
anim_sets_item = NULL;
|
|
anim_faces_item = NULL;
|
|
anim_input = NULL;
|
|
anim_input_i = -1;
|
|
l_anim_data = newAnimData();
|
|
// build a list of *.nba files found in the anim dir
|
|
buildAnimList();
|
|
return 0;
|
|
}
|
|
int closeAnimatorState() {
|
|
freeBox(anim_window);
|
|
// left-hand
|
|
freeList(anim_list);
|
|
// right-hand
|
|
freeBox(anim_box);
|
|
freeList(anim_sets);
|
|
freeList(anim_faces);
|
|
// frames list
|
|
freeBox(anim_frames_box);
|
|
freeBox(anim_frames_i_box);
|
|
int i;
|
|
for (i = 0; i < anim_frames_count; i++) {
|
|
freeTextt(anim_frames[i]);
|
|
freeTextInput(anim_frames_input[i]);
|
|
}
|
|
free(anim_frames);
|
|
free(anim_frames_input);
|
|
// buttons
|
|
for (i = 0; i < ANIM_BUTTONS; i++) {
|
|
freeButton(anim_buttons[i]);
|
|
}
|
|
// free loaded anim
|
|
freeAnimData(l_anim_data);
|
|
return 0;
|
|
}
|
|
int handleAnimatorState(SDL_Event event) {
|
|
int i;
|
|
switch(event.type) {
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
if (anim_input != NULL) {
|
|
anim_input->flags &= ~UI_ACTIVE;
|
|
anim_input = NULL;
|
|
SDL_StopTextInput();
|
|
syncFrames();
|
|
}
|
|
// check against buttons
|
|
for (i = 0; i < ANIM_BUTTONS; i++) {
|
|
if (inBox(anim_buttons[i]->box, event.motion.x, event.motion.y)) {
|
|
anim_button = anim_buttons[i];
|
|
anim_button->flags |= UI_ACTIVE;
|
|
}
|
|
}
|
|
// check against list items
|
|
for (i = 0; i < anim_list->count; i++) {
|
|
if (inBox(getListItemBoxAbs(anim_list, i), event.motion.x, event.motion.y)) {
|
|
if (anim_list_item != NULL) {
|
|
if (anim_list_item != anim_list->items[i]) {
|
|
// deselect if not same as before
|
|
anim_list_item->flags &= ~UI_ACTIVE;
|
|
} else {
|
|
// if same item, ignore event
|
|
break;
|
|
}
|
|
}
|
|
anim_list_item = anim_list->items[i];
|
|
anim_list_item->flags |= UI_ACTIVE;
|
|
// build item filename
|
|
char *anim_filename = malloc(1);
|
|
anim_filename[0] = '\0';
|
|
anim_filename = catStringF(anim_filename, "%s%s", ANIM_DIR, anim_list->items[i]->text);
|
|
// free old AnimData
|
|
freeAnimData(l_anim_data);
|
|
l_anim_data = newAnimData();
|
|
anim_frames_offset = 0;
|
|
// load in new AnimData
|
|
if (loadAnimData(l_anim_data, anim_filename) != 0) {
|
|
report(ERROR, "handleAnimatorState", "could not load AnimData from %s", anim_filename);
|
|
}
|
|
updateAnim();
|
|
// free filename
|
|
free(anim_filename);
|
|
}
|
|
}
|
|
// check against set items
|
|
if (inBox(anim_sets->box, event.motion.x, event.motion.y)) {
|
|
for (i = 0; i < anim_sets->count; i++) {
|
|
if (inBox(getListItemBoxAbs(anim_sets, i), event.motion.x, event.motion.y)) {
|
|
// unselect last item
|
|
if (anim_sets_item != NULL) {
|
|
anim_sets_item->flags &= ~UI_ACTIVE;
|
|
}
|
|
// select new set item
|
|
anim_sets_item = anim_sets->items[i];
|
|
anim_sets_item->flags |= UI_ACTIVE;
|
|
set_index = i;
|
|
refreshData();
|
|
updateFaces();
|
|
}
|
|
}
|
|
}
|
|
// check against face items
|
|
if (inBox(anim_faces->box, event.motion.x, event.motion.y)) {
|
|
for (i = 0; i < anim_faces->count; i++) {
|
|
if (inBox(getListItemBoxAbs(anim_faces, i), event.motion.x, event.motion.y)) {
|
|
if (anim_faces_item != NULL) {
|
|
anim_faces_item->flags &= ~UI_ACTIVE;
|
|
}
|
|
// select new face item
|
|
anim_faces_item = anim_faces->items[i];
|
|
anim_faces_item->flags |= UI_ACTIVE;
|
|
face_index = i;
|
|
refreshData();
|
|
updateFrames();
|
|
}
|
|
}
|
|
}
|
|
// GUH, check against frame tag input items
|
|
if (inBox(*anim_frames_i_box, event.motion.x, event.motion.y)) {
|
|
for (i = 0; i < anim_frames_count; i++) {
|
|
if (inBox(anim_frames_input[i]->box, event.motion.x, event.motion.y)) {
|
|
anim_input_i = i;
|
|
anim_input = anim_frames_input[i];
|
|
anim_input->flags |= UI_ACTIVE;
|
|
SDL_Rect rect = { anim_input->box.x, anim_input->box.y, anim_input->box.w, anim_input->box.h };
|
|
SDL_SetTextInputRect(&rect);
|
|
SDL_StartTextInput();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case SDL_MOUSEBUTTONUP:
|
|
if (anim_input != NULL) {
|
|
// unfocus input if mouseup is not within its bounds
|
|
if (!inBox(anim_input->box, event.motion.x, event.motion.y)) {
|
|
anim_input->flags &= ~UI_ACTIVE;
|
|
anim_input = NULL;
|
|
syncFrames();
|
|
}
|
|
}
|
|
if (anim_button != NULL) {
|
|
if (inBox(anim_button->box, event.motion.x, event.motion.y)) {
|
|
if (anim_button == anim_init) {
|
|
initializeAnims();
|
|
buildAnimList();
|
|
} else if (anim_button == anim_rebuild) {
|
|
} else if (anim_button == anim_delete) {
|
|
if (anim_list_item != NULL) {
|
|
// create filename
|
|
char *anim_filename = malloc(1);
|
|
anim_filename[0] = '\0';
|
|
anim_filename = catStringF(anim_filename, "%s%s", ANIM_DIR, anim_list_item->text);
|
|
// delete file!
|
|
deleteFile(anim_filename);
|
|
// remove item from list and free it
|
|
remListItem(anim_list, anim_list_item);
|
|
freeButton(anim_list_item);
|
|
anim_list_item = NULL;
|
|
// free filename
|
|
// BUG: this segfaults on windows... why?
|
|
//if (anim_filename != NULL) free(anim_filename);
|
|
}
|
|
} else if (anim_button == anim_save) {
|
|
if (l_anim_data != NULL) {
|
|
saveAnimData(l_anim_data);
|
|
}
|
|
}
|
|
}
|
|
anim_button->flags &= ~UI_ACTIVE;
|
|
anim_button = NULL;
|
|
}
|
|
break;
|
|
case SDL_MOUSEMOTION:
|
|
mouse_x = event.motion.x;
|
|
mouse_y = event.motion.y;
|
|
break;
|
|
case SDL_MOUSEWHEEL:
|
|
if (inBox(*anim_frames_box, mouse_x, mouse_y)) {
|
|
if (event.wheel.y < 0) {
|
|
syncFrames();
|
|
anim_frames_offset++;
|
|
} else if (event.wheel.y > 0) {
|
|
if (anim_frames_offset > 0) {
|
|
syncFrames();
|
|
anim_frames_offset--;
|
|
}
|
|
}
|
|
updateFrames();
|
|
}
|
|
break;
|
|
case SDL_KEYDOWN:
|
|
if (event.key.keysym.sym == SDLK_ESCAPE) {
|
|
popState(g_state_manager);
|
|
}
|
|
if (anim_input != NULL) {
|
|
switch(event.key.keysym.sym) {
|
|
// otherwise, control our input and stop the event
|
|
case SDLK_LEFT:
|
|
if (anim_input->cursor > 0) {
|
|
anim_input->cursor--;
|
|
}
|
|
break;
|
|
case SDLK_RIGHT:
|
|
if (anim_input->cursor < strlen(anim_input->text)) {
|
|
anim_input->cursor++;
|
|
}
|
|
break;
|
|
case SDLK_BACKSPACE:
|
|
if (anim_input->cursor != 0) {
|
|
deleteTextInput(anim_input, anim_input->cursor-1, 1);
|
|
anim_input->cursor--;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case SDL_TEXTINPUT:
|
|
if (anim_input != NULL) {
|
|
insertTextInput(anim_input, event.text.text);
|
|
}
|
|
break;
|
|
}
|
|
return 1;
|
|
}
|
|
int processAnimatorState() {
|
|
return 1;
|
|
}
|
|
int renderAnimatorState() {
|
|
renderSQuad(anim_window->x, anim_window->y, anim_window->w, anim_window->h, ui_colors->bg);
|
|
renderList(anim_list);
|
|
SDL_Color image_bg = { 0, 0, 0};
|
|
renderSQuad(anim_box->x, anim_box->y, anim_box->w, anim_box->h, image_bg);
|
|
renderList(anim_sets);
|
|
renderList(anim_faces);
|
|
int i;
|
|
// render frames
|
|
for (i = 0; i < anim_frames_count; i++) {
|
|
renderTextt(anim_frames[i]);
|
|
renderTextInput(anim_frames_input[i]);
|
|
}
|
|
// render buttons
|
|
for (i = 0; i < ANIM_BUTTONS; i++) {
|
|
renderButton(anim_buttons[i]);
|
|
}
|
|
return 1;
|
|
}
|
|
// ===
|
|
int refreshData() {
|
|
if (l_anim_data != NULL) {
|
|
if (set_index < 0 || set_index > l_anim_data->count-1) {
|
|
l_set_data = NULL;
|
|
} else {
|
|
l_set_data = l_anim_data->sets[set_index];
|
|
}
|
|
}
|
|
if (l_set_data != NULL) {
|
|
if (face_index < 0 || face_index > l_set_data->count-1) {
|
|
l_face_data = NULL;
|
|
} else {
|
|
l_face_data = l_set_data->faces[face_index];
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
// === update Animation editor view
|
|
int updateAnim() {
|
|
refreshData();
|
|
freeListItems(anim_sets);
|
|
freeListItems(anim_faces);
|
|
if (l_anim_data != NULL) {
|
|
set_index = 0;
|
|
updateSets();
|
|
}
|
|
return 0;
|
|
}
|
|
int updateSets() {
|
|
freeListItems(anim_sets);
|
|
if (l_anim_data != NULL) {
|
|
struct SetData *set_data = NULL;
|
|
int set_i;
|
|
for(set_i = 0; set_i < l_anim_data->count; set_i++) {
|
|
struct Ui_Colors *colors;
|
|
if (set_i%2 == 1) {
|
|
colors = ui_colors;
|
|
} else {
|
|
colors = button_colors;
|
|
}
|
|
set_data = l_anim_data->sets[set_i];
|
|
struct Button *set_item = newButton(&g_small_glyphs, colors, set_data->name);
|
|
addListItem(anim_sets, set_item);
|
|
}
|
|
// if set_data is not NULL, that means we have at least 1 item
|
|
if (set_data != NULL) {
|
|
anim_sets_item = anim_sets->items[0];
|
|
anim_sets_item->flags |= UI_ACTIVE;
|
|
}
|
|
face_index = 0;
|
|
updateFaces();
|
|
}
|
|
return 0;
|
|
}
|
|
int updateFaces() {
|
|
freeListItems(anim_faces);
|
|
if (l_set_data != NULL) {
|
|
struct FaceData *face_data;
|
|
int face_i;
|
|
for(face_i = 0; face_i < l_set_data->count; face_i++) {
|
|
struct Ui_Colors *colors;
|
|
if (face_i%2 == 1) {
|
|
colors = ui_colors;
|
|
} else {
|
|
colors = button_colors;
|
|
}
|
|
face_data = l_set_data->faces[face_i];
|
|
struct Button *face_item = newButton(&g_small_glyphs, colors, face_data->name);
|
|
addListItem(anim_faces, face_item);
|
|
}
|
|
// if face_data is not NULL, we have at least 1 item
|
|
if (face_data != NULL) {
|
|
anim_faces_item = anim_faces->items[0];
|
|
anim_faces_item->flags |= UI_ACTIVE;
|
|
}
|
|
frame_index = 0;
|
|
updateFrames();
|
|
}
|
|
return 0;
|
|
}
|
|
int syncFrames() {
|
|
if (l_face_data != NULL) {
|
|
if (anim_input_i >= 0 && anim_input_i < anim_frames_count) {
|
|
l_face_data->frames[anim_frames_offset+anim_input_i]->tag = copyString(l_face_data->frames[anim_frames_offset+anim_input_i]->tag, anim_frames_input[anim_input_i]->text);
|
|
anim_input_i = -1;
|
|
}
|
|
}
|
|
if (anim_input != NULL) {
|
|
anim_input->flags &= ~UI_ACTIVE;
|
|
anim_input = NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
int updateFrames() {
|
|
if (l_face_data != NULL) {
|
|
syncFrames();
|
|
// free old frames
|
|
int i;
|
|
for (i = 0; i < anim_frames_count; i++) {
|
|
freeTextt(anim_frames[i]);
|
|
freeTextInput(anim_frames_input[i]);
|
|
}
|
|
anim_frames = realloc(anim_frames, 1);
|
|
anim_frames_input = realloc(anim_frames_input, 1);
|
|
anim_frames_count = 0;
|
|
// get new frames
|
|
struct FrameData *frame_data;
|
|
int offset_x = anim_frames_box->x;
|
|
int offset_y = anim_frames_box->y;
|
|
int item_limit = anim_frames_box->h / g_small_glyphs.h;
|
|
int item_count = 0;
|
|
int frame_i;
|
|
for(frame_i = anim_frames_offset; frame_i < l_face_data->count; frame_i++) {
|
|
if (item_count >= item_limit) break;
|
|
struct Ui_Colors *colors;
|
|
if (frame_i%2 == 1) {
|
|
colors = ui_colors;
|
|
} else {
|
|
colors = button_colors;
|
|
}
|
|
frame_data = l_face_data->frames[frame_i];
|
|
// create Text
|
|
struct Textt *frame_item = newTextt(&g_small_glyphs, colors, frame_data->file);
|
|
frame_item->box.x = offset_x;
|
|
frame_item->box.y = offset_y;
|
|
frame_item->box.w = anim_frames_box->w;
|
|
// create TextInput
|
|
// use inverse colors
|
|
if (frame_i%2 == 0) {
|
|
colors = ui_colors;
|
|
} else {
|
|
colors = button_colors;
|
|
}
|
|
struct TextInput *frame_input = newTextInput(&g_small_glyphs, colors, anim_frames_i_box->w);
|
|
setTextInputText(frame_input, frame_data->tag);
|
|
frame_input->box.x = anim_frames_i_box->x;
|
|
frame_input->box.y = offset_y;
|
|
anim_frames_count++;
|
|
// resize anim_frames
|
|
anim_frames = realloc(anim_frames, anim_frames_count*(sizeof(struct Textt*)));
|
|
anim_frames[anim_frames_count-1] = frame_item;
|
|
// now resize input
|
|
anim_frames_input = realloc(anim_frames_input, anim_frames_count*(sizeof(struct Textt*)));
|
|
anim_frames_input[anim_frames_count-1] = frame_input;
|
|
//
|
|
offset_y += frame_item->box.h;
|
|
item_count++;
|
|
}
|
|
if (frame_index < 0 || face_index > l_face_data->count-1) {
|
|
l_frame_data = NULL;
|
|
} else {
|
|
l_frame_data = l_face_data->frames[frame_index];
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
// === AnimData initialization and list building
|
|
int initializeAnims() {
|
|
struct Dir *anim_dir = openDir(ANIM_DIR, SORT_DESCEND);
|
|
if (anim_dir == NULL) return 1;
|
|
|
|
// set up our containing array
|
|
struct AnimArray *anim_array = newAnimArray();
|
|
|
|
struct DirEntry *anim_entry;
|
|
while((anim_entry = readDir(anim_dir)) != NULL) {
|
|
// skip regular files
|
|
if (anim_entry->d_type != F_DIR) continue;
|
|
// skip "."/".."
|
|
if (strcmp(anim_entry->d_name, ".") == 0 || strcmp(anim_entry->d_name, "..") == 0) continue;
|
|
int anim_entry_size = strlen(anim_entry->d_name)+1;
|
|
// create full file path to anim_entry
|
|
int anim_path_size = strlen(ANIM_DIR)+anim_entry_size;
|
|
char anim_path[anim_path_size];
|
|
strcpy(anim_path, ANIM_DIR);
|
|
memcpy(anim_path+strlen(ANIM_DIR), anim_entry->d_name, anim_entry_size);
|
|
// skip anim_entry if a ".anim" file exists for it already
|
|
char anim_file[anim_path_size+strlen(ANIM_EXT)];
|
|
memcpy(anim_file, anim_path, anim_path_size);
|
|
memcpy(anim_file+anim_path_size-1, ANIM_EXT, strlen(ANIM_EXT)+1);
|
|
anim_file[anim_path_size+strlen(ANIM_EXT)] = '\0';
|
|
if (fileExists(anim_file)) continue;
|
|
// okay, seems this is valid, let's create our AnimData
|
|
struct AnimData *anim_data = newAnimData();
|
|
anim_data->name = copyString(anim_data->name, anim_entry->d_name);
|
|
// BEGIN anim traversal
|
|
struct Dir *set_dir = openDir(anim_path, SORT_DESCEND);
|
|
if (set_dir == NULL) break;
|
|
struct DirEntry *set_entry;
|
|
while((set_entry = readDir(set_dir)) != NULL) {
|
|
// skip regular files
|
|
if (set_entry->d_type != F_DIR) continue;
|
|
// skip "."/".."
|
|
if (strcmp(set_entry->d_name, ".") == 0 || strcmp(set_entry->d_name, "..") == 0) continue;
|
|
// create full file path to set_entry
|
|
int set_entry_size = strlen(set_entry->d_name)+1;
|
|
char set_path[strlen(anim_path)+set_entry_size+1];
|
|
strcpy(set_path, anim_path);
|
|
set_path[strlen(anim_path)] = '/';
|
|
memcpy(set_path+strlen(anim_path)+1, set_entry->d_name, set_entry_size);
|
|
// valid so far, create SetData
|
|
struct SetData *set_data = newSetData();
|
|
set_data->fps = 30; // default 60
|
|
set_data->name = copyString(set_data->name, set_entry->d_name);
|
|
// BEGIN set traversel
|
|
struct Dir *face_dir = openDir(set_path, SORT_DESCEND);
|
|
struct DirEntry *face_entry = NULL;
|
|
while((face_entry = readDir(face_dir)) != NULL) {
|
|
// skip regular files
|
|
if (face_entry->d_type != F_DIR) continue;
|
|
// skip "."/".."
|
|
if (strcmp(face_entry->d_name, ".") == 0 || strcmp(face_entry->d_name, "..") == 0) continue;
|
|
// create full file path to face_entry
|
|
int face_entry_size = strlen(face_entry->d_name)+1;
|
|
char face_path[strlen(set_path)+face_entry_size+1];
|
|
strcpy(face_path, set_path);
|
|
face_path[strlen(set_path)] = '/';
|
|
memcpy(face_path+strlen(set_path)+1, face_entry->d_name, face_entry_size);
|
|
// ohhh, it's getting closer, create FaceData
|
|
struct FaceData *face_data = newFaceData();
|
|
face_data->name = copyString(face_data->name, face_entry->d_name);
|
|
// BEGIN face traversal
|
|
struct Dir *frame_dir = openDir(face_path, SORT_DESCEND);
|
|
if (frame_dir == NULL) continue;
|
|
struct DirEntry *frame_entry;
|
|
while((frame_entry = readDir(frame_dir)) != NULL) {
|
|
// skip regular files
|
|
if (frame_entry->d_type != F_REG) continue;
|
|
// skip "."/".."
|
|
if (strcmp(frame_entry->d_name, ".") == 0 || strcmp(frame_entry->d_name, "..") == 0) continue;
|
|
// create full file path to frame_entry
|
|
int frame_entry_size = strlen(frame_entry->d_name)+1;
|
|
char frame_path[strlen(face_path)+frame_entry_size+1];
|
|
strcpy(frame_path, face_path);
|
|
frame_path[strlen(face_path)] = '/';
|
|
memcpy(frame_path+strlen(face_path)+1, frame_entry->d_name, frame_entry_size);
|
|
// hot dogs, we've reached our conclusion
|
|
struct FrameData *frame_data = newFrameData();
|
|
frame_data->file = copyString(frame_data->file, frame_entry->d_name);
|
|
// push onto our face :)
|
|
pushFrameData(face_data, frame_data);
|
|
}
|
|
// push onto our set!
|
|
closeDir(frame_dir);
|
|
pushFaceData(set_data, face_data);
|
|
}
|
|
// push onto anim data! :D
|
|
closeDir(face_dir);
|
|
pushSetData(anim_data, set_data);
|
|
}
|
|
closeDir(set_dir);
|
|
pushAnimData(anim_array, anim_data);
|
|
}
|
|
closeDir(anim_dir);
|
|
// save our AnimData!
|
|
int anim_i;
|
|
for(anim_i = 0; anim_i < anim_array->count; anim_i++) {
|
|
saveAnimData(anim_array->anims[anim_i]);
|
|
}
|
|
// free
|
|
freeAnimArray(anim_array);
|
|
return 0;
|
|
}
|
|
int buildAnimList() {
|
|
int i = 0;
|
|
struct dirent *entry;
|
|
DIR *dir = opendir(ANIM_DIR);
|
|
if (dir == NULL) {
|
|
return 1;
|
|
}
|
|
freeListItems(anim_list);
|
|
while ((entry = readdir(dir)) != NULL) {
|
|
// find extension (reverse search for first '.')
|
|
char *extension;
|
|
if ((extension = strrchr(entry->d_name, '.')) == NULL) {
|
|
continue;
|
|
}
|
|
if (strcmp(extension, ANIM_EXT) != 0) {
|
|
continue;
|
|
}
|
|
int entry_size = strlen(entry->d_name)+1;
|
|
// :S
|
|
char file_path[strlen(MAP_DIR)+entry_size];
|
|
strcpy(file_path, MAP_DIR);
|
|
memcpy(file_path+strlen(MAP_DIR), entry->d_name, entry_size);
|
|
//
|
|
struct stat file_stat;
|
|
stat(file_path, &file_stat);
|
|
// ignore directories
|
|
switch(file_stat.st_mode & S_IFMT) {
|
|
case S_IFDIR:
|
|
continue;
|
|
break;
|
|
}
|
|
// TODO: do something with file_path ?
|
|
struct Ui_Colors *colors;
|
|
if (i%2 == 1) {
|
|
colors = ui_colors;
|
|
} else {
|
|
colors = button_colors;
|
|
}
|
|
struct Button *anim_item = newButton(&g_small_glyphs, colors, entry->d_name);
|
|
addListItem(anim_list, anim_item);
|
|
i++;
|
|
}
|
|
closedir(dir);
|
|
return 0;
|
|
}
|