321 lines
10 KiB
C
321 lines
10 KiB
C
#include "AnimData.h"
|
|
#include "fifo.h"
|
|
#include "string.h"
|
|
#include "globals.h"
|
|
|
|
#include "report.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
struct AnimArray *newAnimArray() {
|
|
struct AnimArray *anim_array = malloc(sizeof(struct AnimArray));
|
|
anim_array->count = 0;
|
|
anim_array->anims = NULL;
|
|
return anim_array;
|
|
}
|
|
int freeAnimArray(struct AnimArray *anim_array) {
|
|
if (anim_array == NULL) return 1;
|
|
if (anim_array->anims != NULL) {
|
|
int i;
|
|
for (i = 0; i < anim_array->count; i++) {
|
|
freeAnimData(anim_array->anims[i]);
|
|
}
|
|
free(anim_array->anims);
|
|
}
|
|
free(anim_array);
|
|
anim_array = NULL;
|
|
return 0;
|
|
}
|
|
int pushAnimData(struct AnimArray *anim_array, struct AnimData *anim_data) {
|
|
if (anim_array == NULL) return 1;
|
|
if (anim_data == NULL) return 2;
|
|
anim_array->count++;
|
|
anim_array->anims = realloc(anim_array->anims, anim_array->count*(sizeof(struct AnimData*)));
|
|
anim_array->anims[anim_array->count-1] = anim_data;
|
|
return 0;
|
|
}
|
|
|
|
struct AnimData *newAnimData() {
|
|
struct AnimData *anim_data = malloc(sizeof(struct AnimData));
|
|
anim_data->count = 0;
|
|
anim_data->sets = NULL;
|
|
anim_data->name = malloc(6);
|
|
memcpy(anim_data->name, "undef", 6);
|
|
return anim_data;
|
|
}
|
|
int freeAnimData(struct AnimData *anim_data) {
|
|
if (anim_data == NULL) return 1;
|
|
if (anim_data->name != NULL) free(anim_data->name);
|
|
if (anim_data->sets != NULL) {
|
|
int i;
|
|
for (i = 0; i < anim_data->count; i++) {
|
|
freeSetData(anim_data->sets[i]);
|
|
}
|
|
free(anim_data->sets);
|
|
}
|
|
free(anim_data);
|
|
anim_data = NULL;
|
|
return 0;
|
|
}
|
|
int pushSetData(struct AnimData *anim_data, struct SetData *set_data) {
|
|
if (anim_data == NULL) return 1;
|
|
if (set_data == NULL) return 2;
|
|
anim_data->count++;
|
|
anim_data->sets = realloc(anim_data->sets, anim_data->count*(sizeof(struct SetData*)));
|
|
anim_data->sets[anim_data->count-1] = set_data;
|
|
return 0;
|
|
}
|
|
|
|
int saveAnimData(struct AnimData *anim_data) {
|
|
if (anim_data == NULL) return 1;
|
|
// create our filename string
|
|
char *anim_filename = NULL;
|
|
anim_filename = setStringF(anim_filename, "%s%s%s", ANIM_DIR, anim_data->name, ANIM_EXT);
|
|
// begin saving
|
|
// open file for output
|
|
FILE *output = fopen(anim_filename, "wb");
|
|
if (output == NULL) {
|
|
report(ERROR, "saveAnimData", "cannot open \"%s\" for writing", anim_filename);
|
|
return 2;
|
|
}
|
|
// data we'll reference
|
|
int set_i, face_i, frame_i;
|
|
struct SetData *set_data;
|
|
struct FaceData *face_data;
|
|
struct FrameData *frame_data;
|
|
char magic[4];
|
|
// write magic number
|
|
magic[0] = 'N';
|
|
magic[1] = 'b';
|
|
magic[2] = 'A';
|
|
magic[3] = 1;
|
|
writeData(output, T_MAGIC, (void*)&magic);
|
|
// write animdata information
|
|
writeData(output, T_STRING, (void*)&anim_data->name);
|
|
// write out set count
|
|
writeData(output, T_INT, (void*)&anim_data->count);
|
|
// write out sets!
|
|
for (set_i = 0; set_i < anim_data->count; set_i++) {
|
|
set_data = anim_data->sets[set_i];
|
|
// write out set name
|
|
writeData(output, T_STRING, (void*)&set_data->name);
|
|
// write out fps
|
|
writeData(output, T_INT, (void*)&set_data->fps);
|
|
// write out face count
|
|
writeData(output, T_INT, (void*)&set_data->count);
|
|
// write out faces!
|
|
for (face_i = 0; face_i < set_data->count; face_i++) {
|
|
face_data = set_data->faces[face_i];
|
|
// write out face name
|
|
writeData(output, T_STRING, (void*)&face_data->name);
|
|
// write out frame count
|
|
writeData(output, T_INT, (void*)&face_data->count);
|
|
// write out frames!
|
|
for (frame_i = 0; frame_i < face_data->count; frame_i++) {
|
|
frame_data = face_data->frames[frame_i];
|
|
// write out frame filename
|
|
writeData(output, T_STRING, (void*)&frame_data->file);
|
|
// write out frame tag
|
|
writeData(output, T_STRING, (void*)&frame_data->tag);
|
|
}
|
|
}
|
|
}
|
|
fclose(output);
|
|
// free filename
|
|
free(anim_filename);
|
|
return 0;
|
|
}
|
|
int loadAnimData(struct AnimData *anim_data, const char *filename) {
|
|
if (anim_data == NULL) return 1;
|
|
if (filename == NULL) return 2;
|
|
// open file for reading binary
|
|
FILE *input = fopen(filename, "rb");
|
|
if (input == NULL) {
|
|
report(ERROR, "loadAnimData", "cannot open \"%s\" for reading", filename);
|
|
return 3;
|
|
}
|
|
void *val = malloc(4);
|
|
// read in magic number
|
|
readData(input, T_MAGIC, val);
|
|
if (((char *)val)[0] != 'N' || ((char *)val)[1] != 'b' || ((char *)val)[2] != 'A' || ((char *)val)[3] != 1) {
|
|
report(ERROR, "loadAnimData", "magic number mismatch, expected %d, got %d", ((char *)val)[3], 1);
|
|
free(val);
|
|
return 5;
|
|
}
|
|
int set_i, face_i, frame_i;
|
|
int set_count, face_count, frame_count;
|
|
struct SetData *set_data;
|
|
struct FaceData *face_data;
|
|
struct FrameData *frame_data;
|
|
// read in anim name
|
|
anim_data->name = readData(input, T_STRING, anim_data->name);
|
|
// read in set count
|
|
readData(input, T_INT, &set_count);
|
|
// okay, let's read in sets
|
|
for(set_i = 0; set_i < set_count; set_i++) {
|
|
set_data = newSetData();
|
|
// read in set name
|
|
set_data->name = readData(input, T_STRING, set_data->name);
|
|
// read in fps
|
|
readData(input, T_INT, &set_data->fps);
|
|
// read in face count
|
|
readData(input, T_INT, &face_count);
|
|
// read in faces
|
|
for (face_i = 0; face_i < face_count; face_i++) {
|
|
face_data = newFaceData();
|
|
// read in face name
|
|
face_data->name = readData(input, T_STRING, face_data->name);
|
|
// read in frame count (non-thread safe)
|
|
readData(input, T_INT, &frame_count);
|
|
// read in frames
|
|
for (frame_i = 0; frame_i < frame_count; frame_i++) {
|
|
frame_data = newFrameData();
|
|
// read in frame filename
|
|
frame_data->file = readData(input, T_STRING, frame_data->file);
|
|
// read in frame tag
|
|
frame_data->tag = readData(input, T_STRING, frame_data->tag);
|
|
// add frame to face
|
|
pushFrameData(face_data, frame_data);
|
|
}
|
|
// add face to set
|
|
pushFaceData(set_data, face_data);
|
|
}
|
|
// add set to anim
|
|
pushSetData(anim_data, set_data);
|
|
}
|
|
// success, we hope
|
|
free(val);
|
|
fclose(input);
|
|
return 0;
|
|
}
|
|
struct AnimData *loadAnimData_res(const char *filename) {
|
|
char *full_path = malloc(1);
|
|
full_path = setStringF(full_path, "%s%s%s", ANIM_DIR, filename, ANIM_EXT);
|
|
struct AnimData *anim_data = newAnimData();
|
|
if (loadAnimData(anim_data, full_path) != 0) {
|
|
printf("it failed!\n");
|
|
freeAnimData(anim_data);
|
|
free(full_path);
|
|
return NULL;
|
|
}
|
|
free(full_path);
|
|
return anim_data;
|
|
}
|
|
|
|
struct FrameData *getAnimFrameData(struct AnimData *anim_data, const char *set, const char *face, int frame) {
|
|
struct SetData *set_data;
|
|
struct FaceData *face_data;
|
|
struct FrameData *frame_data;
|
|
int i, j, k;
|
|
for (i = 0; i < anim_data->count; i++) {
|
|
set_data = anim_data->sets[i];
|
|
if (strcmp(set_data->name, set) == 0) {
|
|
// okay, check if face exists
|
|
for (j = 0; j < anim_data->sets[i]->count; j++) {
|
|
face_data = set_data->faces[j];
|
|
if (strcmp(face_data->name, face) == 0) {
|
|
// check if frame exists
|
|
if (frame < face_data->count) {
|
|
frame_data = face_data->frames[frame];
|
|
return frame_data;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
struct SetData *newSetData() {
|
|
struct SetData *set_data = malloc(sizeof(struct SetData));
|
|
set_data->count = 0;
|
|
set_data->faces = NULL;
|
|
set_data->fps = 0;
|
|
set_data->name = malloc(6);
|
|
memcpy(set_data->name, "undef", 6);
|
|
return set_data;
|
|
}
|
|
int freeSetData(struct SetData *set_data) {
|
|
if (set_data == NULL) return 1;
|
|
free(set_data->name);
|
|
if (set_data->faces != NULL) {
|
|
int i;
|
|
for (i = 0; i < set_data->count; i++) {
|
|
freeFaceData(set_data->faces[i]);
|
|
}
|
|
free(set_data->faces);
|
|
}
|
|
free(set_data);
|
|
set_data = NULL;
|
|
return 0;
|
|
}
|
|
int pushFaceData(struct SetData *set_data, struct FaceData *face_data) {
|
|
if (set_data == NULL) return 1;
|
|
if (face_data == NULL) return 2;
|
|
set_data->count++;
|
|
set_data->faces = realloc(set_data->faces, set_data->count*(sizeof(struct FaceData*)));
|
|
set_data->faces[set_data->count-1] = face_data;
|
|
return 0;
|
|
}
|
|
|
|
struct FaceData *newFaceData() {
|
|
struct FaceData *face_data = malloc(sizeof(struct FaceData));
|
|
face_data->count = 0;
|
|
face_data->frames = NULL;
|
|
face_data->name = malloc(6);
|
|
memcpy(face_data->name, "undef", 6);
|
|
face_data->sheet = NULL;
|
|
return face_data;
|
|
}
|
|
int freeFaceData(struct FaceData *face_data) {
|
|
if (face_data == NULL) return 1;
|
|
free(face_data->name);
|
|
if (face_data->frames != NULL) {
|
|
int i;
|
|
for (i = 0; i < face_data->count; i++) {
|
|
freeFrameData(face_data->frames[i]);
|
|
face_data->frames[i] = NULL;
|
|
}
|
|
free(face_data->frames);
|
|
face_data->frames = NULL;
|
|
}
|
|
if (face_data->sheet != NULL) {
|
|
freeFrameSheet(face_data->sheet);
|
|
}
|
|
free(face_data);
|
|
face_data = NULL;
|
|
return 0;
|
|
}
|
|
int pushFrameData(struct FaceData *face_data, struct FrameData *frame_data) {
|
|
if (face_data == NULL) return 1;
|
|
if (frame_data == NULL) return 2;
|
|
face_data->count++;
|
|
face_data->frames = realloc(face_data->frames, face_data->count*(sizeof(struct FrameData*)));
|
|
if (face_data->frames == NULL) {
|
|
printf("bad error, frame could not resize from %d to %d\n", face_data->count-1, face_data->count);
|
|
return 3;
|
|
}
|
|
face_data->frames[face_data->count-1] = frame_data;
|
|
return 0;
|
|
}
|
|
|
|
struct FrameData *newFrameData() {
|
|
struct FrameData *frame_data = malloc(sizeof(struct FrameData));
|
|
frame_data->file = malloc(6);
|
|
memcpy(frame_data->file, "undef", 6);
|
|
frame_data->tag = malloc(1);
|
|
memcpy(frame_data->tag, "", 1);
|
|
return (frame_data);
|
|
}
|
|
int freeFrameData(struct FrameData *frame_data) {
|
|
if (frame_data == NULL) return 1;
|
|
if (frame_data->file != NULL) free(frame_data->file);
|
|
if (frame_data->tag != NULL) free(frame_data->tag);
|
|
free(frame_data);
|
|
return 0;
|
|
}
|