1 #include <stdlib.h>
2 #include <string.h>
3
4 #include "shadowdive/error.h"
5 #include "shadowdive/animation.h"
6 #include "shadowdive/move.h"
7
sd_move_create(sd_move * move)8 int sd_move_create(sd_move *move) {
9 if(move == NULL) {
10 return SD_INVALID_INPUT;
11 }
12
13 // Clear everything
14 memset(move, 0, sizeof(sd_move));
15 return SD_SUCCESS;
16 }
17
sd_move_copy(sd_move * dst,const sd_move * src)18 int sd_move_copy(sd_move *dst, const sd_move *src) {
19 int ret;
20 if(dst == NULL || src == NULL) {
21 return SD_INVALID_INPUT;
22 }
23
24 // Clear destination
25 memset(dst, 0, sizeof(sd_move));
26
27 // Copy animation
28 if(src->animation != NULL) {
29 if((dst->animation = malloc(sizeof(sd_animation))) == NULL) {
30 return SD_OUT_OF_MEMORY;
31 }
32 if((ret = sd_animation_copy(dst->animation, src->animation)) != SD_SUCCESS) {
33 return ret;
34 }
35 }
36
37 // Copy move and footer strings
38 strcpy(dst->move_string, src->move_string);
39 strcpy(dst->footer_string, src->footer_string);
40
41 // Everything else
42 dst->unknown_0 = src->unknown_0;
43 dst->unknown_2 = src->unknown_2;
44 dst->unknown_4 = src->unknown_4;
45 dst->unknown_5 = src->unknown_5;
46 dst->unknown_6 = src->unknown_6;
47 dst->unknown_7 = src->unknown_7;
48 dst->unknown_8 = src->unknown_8;
49 dst->unknown_9 = src->unknown_9;
50 dst->unknown_10 = src->unknown_10;
51 dst->unknown_11 = src->unknown_11;
52 dst->next_anim_id = src->next_anim_id;
53 dst->category = src->category;
54 dst->unknown_14 = src->unknown_14;
55 dst->scrap_amount = src->scrap_amount;;
56 dst->successor_id = src->successor_id;
57 dst->damage_amount = src->damage_amount;;
58 dst->unknown_18 = src->unknown_18;
59 dst->unknown_19 = src->unknown_19;
60 dst->points = src->points;
61
62 return SD_SUCCESS;
63 }
64
sd_move_free(sd_move * move)65 void sd_move_free(sd_move *move) {
66 if(move == NULL) return;
67 if(move->animation != NULL) {
68 sd_animation_free(move->animation);
69 free(move->animation);
70 }
71 }
72
sd_move_load(sd_reader * r,sd_move * move)73 int sd_move_load(sd_reader *r, sd_move *move) {
74 int ret;
75 uint16_t size;
76
77 if(r == NULL || move == NULL) {
78 return SD_INVALID_INPUT;
79 }
80
81 // Read animation
82 if((move->animation = malloc(sizeof(sd_animation))) == NULL) {
83 return SD_OUT_OF_MEMORY;
84 }
85 if((ret = sd_animation_create(move->animation)) != SD_SUCCESS) {
86 return ret;
87 }
88 if((ret = sd_animation_load(r, move->animation)) != SD_SUCCESS) {
89 return ret;
90 }
91
92 // Header
93 move->unknown_0 = sd_read_uword(r);
94 move->unknown_2 = sd_read_uword(r);
95 move->unknown_4 = sd_read_ubyte(r);
96 move->unknown_5 = sd_read_ubyte(r);
97 move->unknown_6 = sd_read_ubyte(r);
98 move->unknown_7 = sd_read_ubyte(r);
99 move->unknown_8 = sd_read_ubyte(r);
100 move->unknown_9 = sd_read_ubyte(r);
101 move->unknown_10 = sd_read_ubyte(r);
102 move->unknown_11 = sd_read_ubyte(r);
103 move->next_anim_id = sd_read_ubyte(r);
104 move->category = sd_read_ubyte(r);
105 move->unknown_14 = sd_read_ubyte(r);
106 move->scrap_amount = sd_read_ubyte(r);
107 move->successor_id = sd_read_ubyte(r);
108 move->damage_amount = sd_read_ubyte(r);
109 move->unknown_18 = sd_read_ubyte(r);
110 move->unknown_19 = sd_read_ubyte(r);
111 move->points = sd_read_ubyte(r);
112
113 // move string
114 sd_read_buf(r, move->move_string, 21);
115
116 // Footer string
117 size = sd_read_uword(r);
118 if(size >= SD_MOVE_FOOTER_STRING_MAX) {
119 DEBUGLOG("Move footer too big! Expected max %d bytes, got %hu bytes.",
120 SD_MOVE_FOOTER_STRING_MAX, size);
121 return SD_FILE_PARSE_ERROR;
122 }
123 if(size > 0) {
124 sd_read_buf(r, move->footer_string, size);
125 if(move->footer_string[size-1] != 0) {
126 return SD_FILE_PARSE_ERROR;
127 }
128 }
129
130 // Return success if reader is still ok
131 if(!sd_reader_ok(r)) {
132 return SD_FILE_PARSE_ERROR;
133 }
134 return SD_SUCCESS;
135 }
136
sd_move_save(sd_writer * w,const sd_move * move)137 int sd_move_save(sd_writer *w, const sd_move *move) {
138 int ret;
139 uint16_t size;
140
141 if(w == NULL || move == NULL) {
142 return SD_INVALID_INPUT;
143 }
144
145 // Save animation
146 if((ret = sd_animation_save(w, move->animation)) != SD_SUCCESS) {
147 return ret;
148 }
149
150 // Move header
151 sd_write_uword(w, move->unknown_0);
152 sd_write_uword(w, move->unknown_2);
153 sd_write_ubyte(w, move->unknown_4);
154 sd_write_ubyte(w, move->unknown_5);
155 sd_write_ubyte(w, move->unknown_6);
156 sd_write_ubyte(w, move->unknown_7);
157 sd_write_ubyte(w, move->unknown_8);
158 sd_write_ubyte(w, move->unknown_9);
159 sd_write_ubyte(w, move->unknown_10);
160 sd_write_ubyte(w, move->unknown_11);
161 sd_write_ubyte(w, move->next_anim_id);
162 sd_write_ubyte(w, move->category);
163 sd_write_ubyte(w, move->unknown_14);
164 sd_write_ubyte(w, move->scrap_amount);
165 sd_write_ubyte(w, move->successor_id);
166 sd_write_ubyte(w, move->damage_amount);
167 sd_write_ubyte(w, move->unknown_18);
168 sd_write_ubyte(w, move->unknown_19);
169 sd_write_ubyte(w, move->points);
170
171 // move string
172 sd_write_buf(w, move->move_string, 21);
173
174 // Save footer string
175 size = strlen(move->footer_string);
176 if(size > 0) {
177 sd_write_uword(w, size+1);
178 sd_write_buf(w, move->footer_string, size+1);
179 } else {
180 sd_write_uword(w, 0);
181 }
182
183 return SD_SUCCESS;
184 }
185
sd_move_set_animation(sd_move * move,const sd_animation * animation)186 int sd_move_set_animation(sd_move *move, const sd_animation *animation) {
187 int ret;
188 if(move == NULL) {
189 return SD_INVALID_INPUT;
190 }
191 if(move->animation != NULL) {
192 sd_animation_free(move->animation);
193 free(move->animation);
194 move->animation = NULL;
195 }
196 if(animation == NULL) {
197 return SD_SUCCESS;
198 }
199 if((move->animation = malloc(sizeof(sd_animation))) == NULL) {
200 return SD_OUT_OF_MEMORY;
201 }
202 if((ret = sd_animation_copy(move->animation, animation)) != SD_SUCCESS) {
203 return ret;
204 }
205 return SD_SUCCESS;
206 }
207
sd_move_get_animation(const sd_move * move)208 sd_animation* sd_move_get_animation(const sd_move *move) {
209 return move->animation;
210 }
211
sd_move_set_footer_string(sd_move * move,const char * str)212 int sd_move_set_footer_string(sd_move *move, const char* str) {
213 if(strlen(str) >= SD_MOVE_FOOTER_STRING_MAX-1) {
214 return SD_INVALID_INPUT;
215 }
216 strcpy(move->footer_string, str);
217 return SD_SUCCESS;
218 }
219
sd_move_set_move_string(sd_move * move,const char * str)220 int sd_move_set_move_string(sd_move *move, const char *str) {
221 if(strlen(str) >= SD_MOVE_STRING_MAX-1) {
222 return SD_INVALID_INPUT;
223 }
224 strcpy(move->move_string, str);
225 return SD_SUCCESS;
226 }
227