1 /* $Id: tenm_object.c,v 1.43 2003/02/11 11:39:35 oohara Exp $ */
2
3 #include <stdio.h>
4 /* malloc */
5 #include <stdlib.h>
6 /* strlen, strncpy */
7 #include <string.h>
8
9 #include "tenm_collision.h"
10 #include "tenm_object.h"
11
12 tenm_mass *
tenm_mass_new(int number_primitive,tenm_primitive ** p)13 tenm_mass_new(int number_primitive, tenm_primitive **p)
14 {
15 tenm_mass *temp;
16
17 /* sanity check */
18 if (number_primitive <= 0)
19 {
20 fprintf(stderr, "tenm_mass_new: number_primitive is non-positive (%d)\n",
21 number_primitive);
22 return NULL;
23 }
24
25 temp = (tenm_mass *) malloc(sizeof(tenm_mass));
26 if (temp == NULL)
27 {
28 fprintf(stderr, "tenm_mass_new: malloc failed\n");
29 return NULL;
30 }
31
32 temp->n = number_primitive;
33 temp->p = p;
34
35 return temp;
36 }
37
38 void
tenm_mass_delete(tenm_mass * p)39 tenm_mass_delete(tenm_mass *p)
40 {
41 int i;
42
43 if (p == NULL)
44 {
45 fprintf(stderr, "tenm_mass_delete: p is NULL\n");
46 return;
47 }
48 if (p->n <= 0)
49 {
50 fprintf(stderr, "tenm_mass_delete: p->n is non-positive (%d)\n", p->n);
51 return;
52 }
53 if (p->p == NULL)
54 {
55 fprintf(stderr, "tenm_mass_delete: p->p is NULL\n");
56 return;
57 }
58
59 for (i = 0; i < p->n; i++)
60 if (p->p[i] != NULL)
61 (*(p->p[i]->delete))(p->p[i]);
62 free(p->p);
63 free(p);
64 }
65
66 /* name (arg 1) is duplicated
67 * count (arg 8), count_d (arg 10), p (arg 12) and the callback functions
68 * (arg 13 -- 16) are passed directly --- you must NOT free them manually
69 * (tenm_object_delete() does not free the callback functions)
70 */
71 tenm_object *
tenm_object_new(const char * name,int attr,int hit_mask,int hit_point,double x,double y,int number_count,int * count,int number_count_d,double * count_d,int number_primitive,tenm_primitive ** p,int (* move)(tenm_object *,double),int (* hit)(tenm_object *,tenm_object *),int (* act)(tenm_object *,const tenm_object *),int (* draw)(tenm_object *,int))72 tenm_object_new(const char *name, int attr, int hit_mask,
73 int hit_point, double x, double y,
74 int number_count, int *count,
75 int number_count_d, double *count_d,
76 int number_primitive, tenm_primitive **p,
77 int (*move)(tenm_object *, double),
78 int (*hit)(tenm_object *, tenm_object *),
79 int (*act)(tenm_object *, const tenm_object *),
80 int (*draw)(tenm_object *, int))
81 {
82 tenm_object *temp;
83
84 temp = (tenm_object *) malloc(sizeof(tenm_object));
85 if (temp == NULL)
86 {
87 fprintf(stderr, "tenm_object_new: malloc(temp) failed\n");
88 return NULL;
89 }
90
91 if (name != NULL)
92 {
93 /* +1 is for the trailing \0 */
94 temp->name = (char *) malloc(sizeof(char) * (strlen(name) + 1));
95 if (temp->name == NULL)
96 {
97 fprintf(stderr, "tenm_object_new: malloc(temp->name) failed\n");
98 free(temp);
99 return NULL;
100 }
101 strncpy(temp->name, name, strlen(name));
102 temp->name[strlen(name)] = '\0';
103 }
104
105 temp->mass = NULL;
106 if (number_primitive >= 1)
107 {
108 if (p == NULL)
109 {
110 fprintf(stderr, "tenm_object_new: p is NULL\n");
111 if (name != NULL)
112 free(temp->name);
113 free(temp);
114 return NULL;
115 }
116 temp->mass = tenm_mass_new(number_primitive, p);
117 if (temp->mass == NULL)
118 {
119 fprintf(stderr, "tenm_object_new: tenm_mass_new failed\n");
120 if (name != NULL)
121 free(temp->name);
122 free(temp);
123 return NULL;
124 }
125 }
126
127 temp->table_index = -1;
128 /* temp->name is set above */
129 temp->attr = attr;
130 temp->hit_mask = hit_mask;
131 temp->hit_point = hit_point;
132 temp->x = x;
133 temp->y = y;
134 temp->n = number_count;
135 temp->count = count;
136 temp->n_d = number_count_d;
137 temp->count_d = count_d;
138 temp->move = (int (*)(void *, double)) move;
139 temp->hit = (int (*)(void *, void *)) hit;
140 temp->act = (int (*)(void *, const void *)) act;
141 temp->draw = (int (*)(void *, int)) draw;
142
143 return temp;
144 }
145
146 void
tenm_object_delete(tenm_object * p)147 tenm_object_delete(tenm_object *p)
148 {
149 if (p == NULL)
150 {
151 fprintf(stderr, "tenm_object_delete: p is NULL\n");
152 return;
153 }
154
155 if (p->name != NULL)
156 free(p->name);
157 if (p->mass != NULL)
158 tenm_mass_delete(p->mass);
159 if (p->count_d != NULL)
160 free(p->count_d);
161 if (p->count != NULL)
162 free(p->count);
163 free(p);
164 }
165
166 /* return 1 (true) or 0 (false) */
167 int
tenm_collided_mass(tenm_mass * p,tenm_mass * q)168 tenm_collided_mass(tenm_mass *p, tenm_mass *q)
169 {
170 int i;
171 int j;
172
173 /* sanity check */
174 if (p == NULL)
175 {
176 fprintf(stderr, "tenm_collided_mass: p is NULL\n");
177 return 0;
178 }
179 if (p->n <= 0)
180 {
181 fprintf(stderr, "tenm_collided_mass: p->n is non-positive\n");
182 return 0;
183 }
184 if (p->p == NULL)
185 {
186 fprintf(stderr, "tenm_collided_mass: p->p is NULL\n");
187 return 0;
188 }
189 if (q == NULL)
190 {
191 fprintf(stderr, "tenm_collided_mass: q is NULL\n");
192 return 0;
193 }
194 if (q->n <= 0)
195 {
196 fprintf(stderr, "tenm_collided_mass: q->n is non-positive\n");
197 return 0;
198 }
199 if (q->p == NULL)
200 {
201 fprintf(stderr, "tenm_collided_mass: q->p is NULL\n");
202 return 0;
203 }
204
205 for (i = 0; i < p->n; i++)
206 for (j = 0; j < q->n; j++)
207 if (tenm_collided_primitive(p->p[i], q->p[j]))
208 return 1;
209 return 0;
210 }
211
212 /* return 0 on success, 1 on error */
213 int
tenm_move_mass(tenm_mass * p,double dx,double dy)214 tenm_move_mass(tenm_mass *p, double dx, double dy)
215 {
216 int i;
217 int status = 0;
218
219 /* sanity check */
220 if (p == NULL)
221 {
222 fprintf(stderr, "tenm_move_mass: p is NULL\n");
223 return 1;
224 }
225 if (p->n <= 0)
226 {
227 fprintf(stderr, "tenm_move_mass: p->n is non-positive\n");
228 return 1;
229 }
230 if (p->p == NULL)
231 {
232 fprintf(stderr, "tenm_move_mass: p->p is NULL\n");
233 return 1;
234 }
235
236 for (i = 0; i < p->n; i++)
237 {
238 if (tenm_move_primitive(p->p[i], dx, dy) != 0)
239 {
240 fprintf(stderr, "tenm_move_mass: tenm_move_primitive(%d) failed\n", i);
241 status = 1;
242 }
243 }
244
245 return status;
246 }
247