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