1 /* $Id: stage-list.c,v 1.8 2005/07/01 19:24:16 oohara Exp $ */
2
3 #include <stdio.h>
4 /* malloc */
5 #include <stdlib.h>
6 /* strdup, strcmp */
7 #include <string.h>
8
9 #include "stage-list.h"
10
11 static int stage_list_add(stage_list *p, stage_plan *new_plan);
12
13 stage_plan *
stage_plan_new(int stage_id)14 stage_plan_new(int stage_id)
15 {
16 stage_plan *new = NULL;
17 const char *name = NULL;
18 int difficulty;
19
20 new = (stage_plan *) malloc(sizeof(stage_plan));
21 if (new == NULL)
22 {
23 fprintf(stderr, "stage_plan_new: malloc failed\n");
24 return NULL;
25 }
26
27 switch(stage_id)
28 {
29 case 0:
30 name = "dangen tutorial";
31 difficulty = PLAN_TUTORIAL;
32 break;
33 case 1:
34 name = "L";
35 difficulty = PLAN_HARDEST;
36 break;
37 case 2:
38 name = "Senators";
39 difficulty = PLAN_VERY_HARD;
40 break;
41 case 3:
42 name = "Seiron";
43 difficulty = PLAN_HARD;
44 break;
45 case 4:
46 name = "Seiron Fake";
47 difficulty = PLAN_EASY;
48 break;
49 case 5:
50 name = "Perpeki";
51 difficulty = PLAN_VERY_HARD;
52 break;
53 case 6:
54 name = "Empty Wind";
55 difficulty = PLAN_VERY_HARD;
56 break;
57 case 7:
58 name = "cat tail (grep mix)";
59 difficulty = PLAN_HARD;
60 break;
61 case 8:
62 name = "Silver Chimera";
63 difficulty = PLAN_HARD;
64 break;
65 case 9:
66 name = "0x82da3104";
67 difficulty = PLAN_HARD;
68 break;
69 case 10:
70 name = "Tadashi";
71 difficulty = PLAN_NORMAL;
72 break;
73 case 11:
74 name = "Theorem Weapon";
75 difficulty = PLAN_NORMAL;
76 break;
77 case 12:
78 name = "W-KO";
79 difficulty = PLAN_NORMAL;
80 break;
81 case 13:
82 name = "Hell Salvage";
83 difficulty = PLAN_NORMAL;
84 break;
85 case 14:
86 name = "Strikers 1341";
87 difficulty = PLAN_EASY;
88 break;
89 case 15:
90 name = "Watcher Below";
91 difficulty = PLAN_EASY;
92 break;
93 case 16:
94 name = "cat tail";
95 difficulty = PLAN_EASY;
96 break;
97 case 17:
98 name = "Afterdeath";
99 difficulty = PLAN_VERY_EASY;
100 break;
101 case 18:
102 name = "Hugin";
103 difficulty = PLAN_VERY_EASY;
104 break;
105 case 19:
106 name = "Gosanpachi";
107 difficulty = PLAN_VERY_EASY;
108 break;
109 case 20:
110 name = "P-can";
111 difficulty = PLAN_EASIEST;
112 break;
113 default:
114 name = "default";
115 difficulty = PLAN_NORMAL;
116 break;
117 }
118
119 new->stage_id = stage_id;
120 new->name = name;
121 new->difficulty = difficulty;
122
123 return new;
124 }
125
126 void
stage_plan_delete(stage_plan * p)127 stage_plan_delete(stage_plan *p)
128 {
129 if (p == NULL)
130 return;
131
132 /* don't free p->name */
133
134 free(p);
135 }
136
137 /* if match_func (arg 1) is not NULL, an stage_plan *p is
138 * added to the return value only if (*match_func)(p, data)
139 * returns true (non-zero)
140 * set match_func (arg 1) to NULL to get the full list (including the tutorial)
141 */
142 stage_list *
stage_list_new(int (* match_func)(stage_plan *,void *),void * data)143 stage_list_new(int (*match_func)(stage_plan *, void *),
144 void *data)
145 {
146 int i;
147 stage_list *new = NULL;
148 stage_plan *new_plan = NULL;
149
150 new = (stage_list *) malloc(sizeof(stage_list));
151 if (new == NULL)
152 {
153 fprintf(stderr, "stage_list_new: malloc failed\n");
154 return NULL;
155 }
156 new->n = 0;
157 new->p = NULL;
158
159 for (i = 0; i <= NUMBER_PLAN; i++)
160 {
161 new_plan = stage_plan_new(i);
162 if (new_plan == NULL)
163 {
164 fprintf(stderr, "stage_list_new: plan %d is NULL\n", i);
165 continue;
166 }
167
168 if ((match_func != NULL) && (!((*match_func)(new_plan, data))))
169 continue;
170
171 stage_list_add(new, new_plan);
172 }
173
174 return new;
175 }
176
177 /* return 0 on success, 1 on error */
178 static int
stage_list_add(stage_list * p,stage_plan * new_plan)179 stage_list_add(stage_list *p, stage_plan *new_plan)
180 {
181 stage_plan **temp = NULL;
182
183 /* sanity check */
184 if (p == NULL)
185 {
186 fprintf(stderr, "stage_list_add: p is NULL\n");
187 return 1;
188 }
189 if (new_plan == NULL)
190 if (p == NULL)
191 {
192 fprintf(stderr, "stage_list_add: new_plan is NULL\n");
193 return 1;
194 }
195
196 if (p->p == NULL)
197 {
198 p->n = 0;
199 temp = (stage_plan **) malloc(sizeof(stage_plan *));
200 }
201 else
202 {
203 temp = (stage_plan **) realloc(p->p, sizeof(stage_plan *) * (p->n + 1));
204 }
205 if (temp == NULL)
206 {
207 fprintf(stderr, "stage_list_add: cannot allocate memory for p->p\n");
208 return 1;
209 }
210 p->p = temp;
211
212 p->p[p->n] = new_plan;
213 (p->n)++;
214
215 return 0;
216 }
217
218 void
stage_list_delete(stage_list * p)219 stage_list_delete(stage_list *p)
220 {
221 int i;
222
223 if (p == NULL)
224 return;
225 if (p->p != NULL)
226 {
227 for (i = 0; i < p->n; i++)
228 stage_plan_delete(p->p[i]);
229 free(p->p);
230 }
231 free(p);
232 }
233
234 /* don't free the pointer returned by this function */
235 const char *
stage_difficulty_string(int n)236 stage_difficulty_string(int n)
237 {
238 const char *p = NULL;
239
240 switch(n)
241 {
242 case PLAN_TUTORIAL:
243 p = "tutorial";
244 break;
245 case PLAN_EASIEST:
246 p = "easiest";
247 break;
248 case PLAN_VERY_EASY:
249 p = "very easy";
250 break;
251 case PLAN_EASY:
252 p = "easy";
253 break;
254 case PLAN_NORMAL:
255 p = "normal";
256 break;
257 case PLAN_HARD:
258 p = "hard";
259 break;
260 case PLAN_VERY_HARD:
261 p = "very hard";
262 break;
263 case PLAN_HARDEST:
264 p = "hardest";
265 break;
266 default:
267 fprintf(stderr, "stage_difficulty_string: strange n (%d)\n", n);
268 p = "unknown";
269 break;
270 }
271
272 return p;
273 }
274
275 /* for qsort()
276 * return a positive value if a (arg 1) should be after b (arg 2)
277 * a negative value if a (arg 1) should be before b (arg 2)
278 * 0 if a (arg 1) and b (arg 2) are the same
279 */
280 /* this void * should be stage_plan ** */
281 int
stage_compare(const void * a,const void * b)282 stage_compare(const void *a, const void *b)
283 {
284 const stage_plan *a_temp = *((const stage_plan * const *) a);
285 const stage_plan *b_temp = *((const stage_plan * const *) b);
286
287 if (a_temp->difficulty > b_temp->difficulty)
288 return 1;
289 else if (a_temp->difficulty < b_temp->difficulty)
290 return -1;
291
292 if ((a_temp->name != NULL) && (b_temp->name != NULL))
293 {
294 if (strcmp(a_temp->name, b_temp->name) != 0)
295 return strcmp(a_temp->name, b_temp->name);
296 }
297
298 if (a_temp->stage_id > b_temp->stage_id)
299 return 1;
300 else if (a_temp->stage_id < b_temp->stage_id)
301 return -1;
302
303 return 0;
304 }
305