Skip to content

Commit

Permalink
Add sd_script_encode_frame() and other script utilities.
Browse files Browse the repository at this point in the history
  • Loading branch information
katajakasa committed Nov 10, 2024
1 parent 359b74b commit 513524f
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 31 deletions.
80 changes: 49 additions & 31 deletions src/formats/script.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ int sd_script_create(sd_script *script) {
return SD_SUCCESS;
}

static void sd_script_frame_create(sd_script_frame *frame) {
void sd_script_frame_create(sd_script_frame *frame, int tick_len, int sprite) {
vector_create(&frame->tags, sizeof(sd_script_tag));
frame->tick_len = 0;
frame->sprite = 0;
frame->tick_len = tick_len;
frame->sprite = sprite;
}

int sd_script_frame_clone(sd_script_frame *src, sd_script_frame *dst) {
Expand All @@ -41,16 +41,14 @@ int sd_script_clone(sd_script *src, sd_script *dst) {
vector_iter_begin(&src->frames, &it);
while((frame = iter_next(&it)) != NULL) {
sd_script_frame new_frame;
sd_script_frame_create(&new_frame);
new_frame.sprite = frame->sprite;
new_frame.tick_len = frame->tick_len;
sd_script_frame_create(&new_frame, frame->tick_len, frame->sprite);
sd_script_frame_clone(frame, &new_frame);
vector_append(&dst->frames, &new_frame);
}
return SD_SUCCESS;
}

static void sd_script_frame_free(sd_script_frame *frame) {
void sd_script_frame_free(sd_script_frame *frame) {
if(frame == NULL)
return;
vector_free(&frame->tags);
Expand All @@ -60,6 +58,19 @@ static void sd_script_tag_create(sd_script_tag *tag) {
memset(tag, 0, sizeof(sd_script_tag));
}

bool sd_script_frame_add_tag(sd_script_frame *frame, const char *key, int value) {
sd_script_tag tag;
sd_script_tag_create(&tag);
if(!sd_tag_info(key, &tag.has_param, &tag.key, &tag.desc) == 0) {
return false;
}
if(tag.has_param) {
tag.value = value;
}
vector_append(&frame->tags, &tag);
return true;
}

void sd_script_free(sd_script *script) {
if(script == NULL)
return;
Expand All @@ -78,9 +89,7 @@ int sd_script_append_frame(sd_script *script, int tick_len, int sprite_id) {
}

sd_script_frame frame;
sd_script_frame_create(&frame);
frame.tick_len = tick_len;
frame.sprite = sprite_id;
sd_script_frame_create(&frame, tick_len, sprite_id);
vector_append(&script->frames, &frame);
return SD_SUCCESS;
}
Expand Down Expand Up @@ -324,14 +333,14 @@ int sd_script_decode(sd_script *script, const char *input, int *invalid_pos) {
sd_script_frame frame;
sd_script_tag tag;
str_from_c(&src, input);
sd_script_frame_create(&frame);
sd_script_frame_create(&frame, 0, 0);
sd_script_tag_create(&tag);

int now = 0;
while(now < (int)str_size(&src)) {
if(parse_frame(&frame, &src, &now)) {
vector_append(&script->frames, &frame);
sd_script_frame_create(&frame);
sd_script_frame_create(&frame, 0, 0);
continue;
}
if(parse_tag(&tag, &src, &now)) {
Expand All @@ -352,7 +361,7 @@ int sd_script_decode(sd_script *script, const char *input, int *invalid_pos) {
// There are a couple of cases where uppercase frame letter is lowercase. Try to fix.
if(try_parse_bad_frame(&frame, &src, &now)) {
vector_append(&script->frames, &frame);
sd_script_frame_create(&frame);
sd_script_frame_create(&frame, 0, 0);
continue;
}
goto failed_parse;
Expand Down Expand Up @@ -381,31 +390,40 @@ int sd_script_encode(const sd_script *script, str *output) {
}

// Frames exist. Walk through each, and output tags and ending frame tag + duration
str tmp;
iterator frame_it, tag_it;
iterator it;
sd_script_frame *frame;
sd_script_tag *tag;

vector_iter_begin(&script->frames, &frame_it);
while((frame = iter_next(&frame_it)) != NULL) {
vector_iter_begin(&frame->tags, &tag_it);
while((tag = iter_next(&tag_it)) != NULL) {
str_append_c(output, tag->key);
if(tag->has_param) {
str_from_format(&tmp, "%d", tag->value);
str_append(output, &tmp);
str_free(&tmp);
}
}
str_from_format(&tmp, "%c%d-", sd_script_frame_to_letter(frame->sprite), frame->tick_len);
str_append(output, &tmp);
str_free(&tmp);
vector_iter_begin(&script->frames, &it);
while((frame = iter_next(&it)) != NULL) {
sd_script_encode_frame(frame, output);
str_append_c(output, "-");
}

str_cut(output, 1); // Remove the last '-'
return SD_SUCCESS;
}

int sd_script_encode_frame(const sd_script_frame *frame, str *dst) {
if(frame == NULL || dst == NULL)
return SD_INVALID_INPUT;

str tmp;
iterator tag_it;
sd_script_tag *tag;
vector_iter_begin(&frame->tags, &tag_it);
while((tag = iter_next(&tag_it)) != NULL) {
str_append_c(dst, tag->key);
if(tag->has_param) {
str_from_format(&tmp, "%d", tag->value);
str_append(dst, &tmp);
str_free(&tmp);
}
}
str_from_format(&tmp, "%c%d", sd_script_frame_to_letter(frame->sprite), frame->tick_len);
str_append(dst, &tmp);
str_free(&tmp);
return SD_SUCCESS;
}

const sd_script_frame *sd_script_get_frame_at(const sd_script *script, int ticks) {
if(script == NULL)
return NULL;
Expand Down
35 changes: 35 additions & 0 deletions src/formats/script.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ int sd_script_decode(sd_script *script, const char *str, int *invalid_pos);
*/
int sd_script_encode(const sd_script *script, str *dst);

/*! \brief Encode animation frame string
*
* Encodes the animation frame structure to an animation string.
*
* \retval SD_INVALID_INPUT Script or str parameter was NULL
* \retval SD_SUCCESS Successful operation
*
* \param frame Script frame to encode
* \param dst Target string object. Must be initialized!
*/
int sd_script_encode_frame(const sd_script_frame *frame, str *dst);

/*! \brief Find the total duration of the script
*
* Finds the total duration of the script in game ticks. Essentially
Expand Down Expand Up @@ -424,4 +436,27 @@ int sd_script_letter_to_frame(char letter);
*/
char sd_script_frame_to_letter(int frame_id);

/** Initializes a script frame.
*
* @param frame Frame struct to initialize
* @param tick_len Frame length in ticks
* @param sprite Sprite ID to use
*/
void sd_script_frame_create(sd_script_frame *frame, int tick_len, int sprite);

/** Frees a script frame
*
* @param frame Frame to free
*/
void sd_script_frame_free(sd_script_frame *frame);

/** Add a tag to a frame.
*
* @param frame Frame to add into
* @param key Key name, e.h. "bpp" or "m"
* @param value Value. This is only used if tag supports it.
* @return True if tag was valid, false if not.
*/
bool sd_script_frame_add_tag(sd_script_frame *frame, const char *key, int value);

#endif // SD_SCRIPT_H
19 changes: 19 additions & 0 deletions testing/test_script.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,22 @@ void test_script_encode(void) {
str_free(&dst);
}

void test_script_encode_frame(void) {
str dst;
sd_script_frame frame;

str_create(&dst);
sd_script_frame_create(&frame, 100, 0);
sd_script_frame_add_tag(&frame, "bpn", 1);
sd_script_frame_add_tag(&frame, "m", 12);

CU_ASSERT(sd_script_encode_frame(&frame, &dst) == SD_SUCCESS);
CU_ASSERT(strcmp("bpn1m12A100", str_c(&dst)) == 0);

sd_script_frame_free(&frame);
str_free(&dst);
}

void test_script_get_frame(void) {
CU_ASSERT(sd_script_get_frame(&script, -1) == NULL);
CU_ASSERT(sd_script_get_frame(&script, 0) != NULL);
Expand Down Expand Up @@ -435,6 +451,9 @@ void script_test_suite(CU_pSuite suite) {
if(CU_add_test(suite, "test of sd_script_frame_to_letter", test_frame_to_letter) == NULL) {
return;
}
if(CU_add_test(suite, "test of sd_script_encode_frame", test_script_encode_frame) == NULL) {
return;
}
if(CU_add_test(suite, "testing odd tags", test_script_tag_vars) == NULL) {
return;
}
Expand Down

0 comments on commit 513524f

Please sign in to comment.