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