1 #include <stdlib.h>
2 #include <string.h>
3
4 #include "shadowdive/animation.h"
5 #include "shadowdive/bkanim.h"
6 #include "shadowdive/error.h"
7
sd_bk_anim_create(sd_bk_anim * bka)8 int sd_bk_anim_create(sd_bk_anim *bka) {
9 if(bka == NULL) {
10 return SD_INVALID_INPUT;
11 }
12 // clear everything
13 memset(bka, 0, sizeof(sd_bk_anim));
14 return SD_SUCCESS;
15 }
16
sd_bk_anim_copy(sd_bk_anim * dst,const sd_bk_anim * src)17 int sd_bk_anim_copy(sd_bk_anim *dst, const sd_bk_anim *src) {
18 int ret;
19 if(dst == NULL || src == NULL) {
20 return SD_INVALID_INPUT;
21 }
22
23 // Clear destination
24 memset(dst, 0, sizeof(sd_bk_anim));
25
26 // Basic stuff
27 dst->null = src->null;
28 dst->chain_hit = src->chain_hit;
29 dst->chain_no_hit = src->chain_no_hit;
30 dst->load_on_start = src->load_on_start;
31 dst->probability = src->probability;
32 dst->hazard_damage = src->hazard_damage;
33
34 // Footer string
35 strcpy(dst->footer_string, src->footer_string);
36
37 // Copy animation (if exists)
38 if(src->animation != NULL) {
39 if((dst->animation = malloc(sizeof(sd_animation))) == NULL) {
40 return SD_OUT_OF_MEMORY;
41 }
42 if((ret = sd_animation_copy(dst->animation, src->animation)) != SD_SUCCESS) {
43 return ret;
44 }
45 }
46
47 return SD_SUCCESS;
48 }
49
sd_bk_anim_free(sd_bk_anim * bka)50 void sd_bk_anim_free(sd_bk_anim *bka) {
51 if(bka->animation != NULL) {
52 sd_animation_free(bka->animation);
53 free(bka->animation);
54 bka->animation = NULL;
55 }
56 }
57
sd_bk_anim_load(sd_reader * r,sd_bk_anim * bka)58 int sd_bk_anim_load(sd_reader *r, sd_bk_anim *bka) {
59 int ret;
60 uint16_t size;
61
62 // BK Specific animation header
63 bka->null = sd_read_ubyte(r);
64 bka->chain_hit = sd_read_ubyte(r);
65 bka->chain_no_hit = sd_read_ubyte(r);
66 bka->load_on_start = sd_read_ubyte(r);
67 bka->probability = sd_read_uword(r);
68 bka->hazard_damage = sd_read_ubyte(r);
69
70 // Footer string
71 size = sd_read_uword(r);
72 if(size >= SD_BK_FOOTER_STRING_MAX) {
73 DEBUGLOG("BK specific animation footer too big! Expected max %d bytes, got %hu bytes.",
74 SD_BK_FOOTER_STRING_MAX, size);
75 return SD_FILE_PARSE_ERROR;
76 }
77 if(size > 0) {
78 sd_read_buf(r, bka->footer_string, size);
79 if(bka->footer_string[size-1] != 0) {
80 return SD_FILE_PARSE_ERROR;
81 }
82 }
83
84 // Initialize animation
85 if((bka->animation = malloc(sizeof(sd_animation))) == NULL) {
86 return SD_OUT_OF_MEMORY;
87 }
88 if((ret = sd_animation_create(bka->animation)) != SD_SUCCESS) {
89 return ret;
90 }
91 if((ret = sd_animation_load(r, bka->animation)) != SD_SUCCESS) {
92 return ret;
93 }
94
95 // Return success
96 return SD_SUCCESS;
97 }
98
sd_bk_anim_save(sd_writer * w,const sd_bk_anim * bka)99 int sd_bk_anim_save(sd_writer *w, const sd_bk_anim *bka) {
100 int ret;
101 uint16_t size;
102
103 if(w == NULL || bka == NULL) {
104 return SD_INVALID_INPUT;
105 }
106
107 // Write BK specific header
108 sd_write_ubyte(w, bka->null);
109 sd_write_ubyte(w, bka->chain_hit);
110 sd_write_ubyte(w, bka->chain_no_hit);
111 sd_write_ubyte(w, bka->load_on_start);
112 sd_write_uword(w, bka->probability);
113 sd_write_ubyte(w, bka->hazard_damage);
114
115 // Save footer string
116 size = strlen(bka->footer_string);
117 if(size > 0) {
118 sd_write_uword(w, size+1);
119 sd_write_buf(w, bka->footer_string, size+1);
120 } else {
121 sd_write_uword(w, 0);
122 }
123
124 // Write animation
125 if((ret = sd_animation_save(w, bka->animation)) != SD_SUCCESS) {
126 return ret;
127 }
128
129 return SD_SUCCESS;
130 }
131
sd_bk_anim_set_animation(sd_bk_anim * bka,const sd_animation * animation)132 int sd_bk_anim_set_animation(sd_bk_anim *bka, const sd_animation *animation) {
133 int ret;
134 if(bka == NULL) {
135 return SD_INVALID_INPUT;
136 }
137 if(bka->animation != NULL) {
138 sd_animation_free(bka->animation);
139 free(bka->animation);
140 bka->animation = NULL;
141 }
142 if(animation == NULL) {
143 return SD_SUCCESS;
144 }
145 if((bka->animation = malloc(sizeof(sd_animation))) == NULL) {
146 return SD_OUT_OF_MEMORY;
147 }
148 if((ret = sd_animation_copy(bka->animation, animation)) != SD_SUCCESS) {
149 return ret;
150 }
151 return SD_SUCCESS;
152 }
153
sd_bk_anim_get_animation(const sd_bk_anim * bka)154 sd_animation* sd_bk_anim_get_animation(const sd_bk_anim *bka) {
155 return bka->animation;
156 }
157
sd_bk_set_anim_string(sd_bk_anim * bka,const char * data)158 int sd_bk_set_anim_string(sd_bk_anim *bka, const char *data) {
159 if(strlen(data) >= SD_BK_FOOTER_STRING_MAX-1) {
160 return SD_INVALID_INPUT;
161 }
162 strcpy(bka->footer_string, data);
163 return SD_SUCCESS;
164 }
165